comdoleger commited on
Commit
983db42
·
verified ·
1 Parent(s): e53ce6b

Upload notebooks/FLUX_1_schnell_LoRA_Training.ipynb with huggingface_hub

Browse files
notebooks/FLUX_1_schnell_LoRA_Training.ipynb ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {
6
+ "collapsed": false,
7
+ "id": "zl-S0m3pkQC5"
8
+ },
9
+ "source": [
10
+ "# AI Toolkit by Ostris\n",
11
+ "## FLUX.1-schnell Training\n"
12
+ ]
13
+ },
14
+ {
15
+ "cell_type": "code",
16
+ "execution_count": null,
17
+ "metadata": {
18
+ "id": "3cokMT-WC6rG"
19
+ },
20
+ "outputs": [],
21
+ "source": [
22
+ "!nvidia-smi"
23
+ ]
24
+ },
25
+ {
26
+ "cell_type": "code",
27
+ "execution_count": null,
28
+ "metadata": {
29
+ "collapsed": true,
30
+ "id": "BvAG0GKAh59G"
31
+ },
32
+ "outputs": [],
33
+ "source": [
34
+ "!git clone https://github.com/ostris/ai-toolkit\n",
35
+ "!mkdir -p /content/dataset"
36
+ ]
37
+ },
38
+ {
39
+ "cell_type": "markdown",
40
+ "metadata": {
41
+ "id": "UFUW4ZMmnp1V"
42
+ },
43
+ "source": [
44
+ "Put your image dataset in the `/content/dataset` folder"
45
+ ]
46
+ },
47
+ {
48
+ "cell_type": "code",
49
+ "execution_count": null,
50
+ "metadata": {
51
+ "collapsed": true,
52
+ "id": "XGZqVER_aQJW"
53
+ },
54
+ "outputs": [],
55
+ "source": [
56
+ "!cd ai-toolkit && git submodule update --init --recursive && pip install -r requirements.txt\n"
57
+ ]
58
+ },
59
+ {
60
+ "cell_type": "markdown",
61
+ "metadata": {
62
+ "id": "OV0HnOI6o8V6"
63
+ },
64
+ "source": [
65
+ "## Model License\n",
66
+ "Training currently only works with FLUX.1-dev. Which means anything you train will inherit the non-commercial license. It is also a gated model, so you need to accept the license on HF before using it. Otherwise, this will fail. Here are the required steps to setup a license.\n",
67
+ "\n",
68
+ "Sign into HF and accept the model access here [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev)\n",
69
+ "\n",
70
+ "[Get a READ key from huggingface](https://huggingface.co/settings/tokens/new?) and place it in the next cell after running it."
71
+ ]
72
+ },
73
+ {
74
+ "cell_type": "code",
75
+ "execution_count": null,
76
+ "metadata": {
77
+ "id": "3yZZdhFRoj2m"
78
+ },
79
+ "outputs": [],
80
+ "source": [
81
+ "import getpass\n",
82
+ "import os\n",
83
+ "\n",
84
+ "# Prompt for the token\n",
85
+ "hf_token = getpass.getpass('Enter your HF access token and press enter: ')\n",
86
+ "\n",
87
+ "# Set the environment variable\n",
88
+ "os.environ['HF_TOKEN'] = hf_token\n",
89
+ "\n",
90
+ "print(\"HF_TOKEN environment variable has been set.\")"
91
+ ]
92
+ },
93
+ {
94
+ "cell_type": "code",
95
+ "execution_count": 5,
96
+ "metadata": {
97
+ "id": "9gO2EzQ1kQC8"
98
+ },
99
+ "outputs": [],
100
+ "source": [
101
+ "import os\n",
102
+ "import sys\n",
103
+ "sys.path.append('/content/ai-toolkit')\n",
104
+ "from toolkit.job import run_job\n",
105
+ "from collections import OrderedDict\n",
106
+ "from PIL import Image\n",
107
+ "import os\n",
108
+ "os.environ[\"HF_HUB_ENABLE_HF_TRANSFER\"] = \"1\""
109
+ ]
110
+ },
111
+ {
112
+ "cell_type": "markdown",
113
+ "metadata": {
114
+ "id": "N8UUFzVRigbC"
115
+ },
116
+ "source": [
117
+ "## Setup\n",
118
+ "\n",
119
+ "This is your config. It is documented pretty well. Normally you would do this as a yaml file, but for colab, this will work. This will run as is without modification, but feel free to edit as you want."
120
+ ]
121
+ },
122
+ {
123
+ "cell_type": "code",
124
+ "execution_count": 6,
125
+ "metadata": {
126
+ "id": "_t28QURYjRQO"
127
+ },
128
+ "outputs": [],
129
+ "source": [
130
+ "from collections import OrderedDict\n",
131
+ "\n",
132
+ "job_to_run = OrderedDict([\n",
133
+ " ('job', 'extension'),\n",
134
+ " ('config', OrderedDict([\n",
135
+ " # this name will be the folder and filename name\n",
136
+ " ('name', 'my_first_flux_lora_v1'),\n",
137
+ " ('process', [\n",
138
+ " OrderedDict([\n",
139
+ " ('type', 'sd_trainer'),\n",
140
+ " # root folder to save training sessions/samples/weights\n",
141
+ " ('training_folder', '/content/output'),\n",
142
+ " # uncomment to see performance stats in the terminal every N steps\n",
143
+ " #('performance_log_every', 1000),\n",
144
+ " ('device', 'cuda:0'),\n",
145
+ " # if a trigger word is specified, it will be added to captions of training data if it does not already exist\n",
146
+ " # alternatively, in your captions you can add [trigger] and it will be replaced with the trigger word\n",
147
+ " # ('trigger_word', 'image'),\n",
148
+ " ('network', OrderedDict([\n",
149
+ " ('type', 'lora'),\n",
150
+ " ('linear', 16),\n",
151
+ " ('linear_alpha', 16)\n",
152
+ " ])),\n",
153
+ " ('save', OrderedDict([\n",
154
+ " ('dtype', 'float16'), # precision to save\n",
155
+ " ('save_every', 250), # save every this many steps\n",
156
+ " ('max_step_saves_to_keep', 4) # how many intermittent saves to keep\n",
157
+ " ])),\n",
158
+ " ('datasets', [\n",
159
+ " # datasets are a folder of images. captions need to be txt files with the same name as the image\n",
160
+ " # for instance image2.jpg and image2.txt. Only jpg, jpeg, and png are supported currently\n",
161
+ " # images will automatically be resized and bucketed into the resolution specified\n",
162
+ " OrderedDict([\n",
163
+ " ('folder_path', '/content/dataset'),\n",
164
+ " ('caption_ext', 'txt'),\n",
165
+ " ('caption_dropout_rate', 0.05), # will drop out the caption 5% of time\n",
166
+ " ('shuffle_tokens', False), # shuffle caption order, split by commas\n",
167
+ " ('cache_latents_to_disk', True), # leave this true unless you know what you're doing\n",
168
+ " ('resolution', [512, 768, 1024]) # flux enjoys multiple resolutions\n",
169
+ " ])\n",
170
+ " ]),\n",
171
+ " ('train', OrderedDict([\n",
172
+ " ('batch_size', 1),\n",
173
+ " ('steps', 2000), # total number of steps to train 500 - 4000 is a good range\n",
174
+ " ('gradient_accumulation_steps', 1),\n",
175
+ " ('train_unet', True),\n",
176
+ " ('train_text_encoder', False), # probably won't work with flux\n",
177
+ " ('gradient_checkpointing', True), # need the on unless you have a ton of vram\n",
178
+ " ('noise_scheduler', 'flowmatch'), # for training only\n",
179
+ " ('optimizer', 'adamw8bit'),\n",
180
+ " ('lr', 1e-4),\n",
181
+ "\n",
182
+ " # uncomment this to skip the pre training sample\n",
183
+ " # ('skip_first_sample', True),\n",
184
+ "\n",
185
+ " # uncomment to completely disable sampling\n",
186
+ " # ('disable_sampling', True),\n",
187
+ "\n",
188
+ " # uncomment to use new vell curved weighting. Experimental but may produce better results\n",
189
+ " # ('linear_timesteps', True),\n",
190
+ "\n",
191
+ " # ema will smooth out learning, but could slow it down. Recommended to leave on.\n",
192
+ " ('ema_config', OrderedDict([\n",
193
+ " ('use_ema', True),\n",
194
+ " ('ema_decay', 0.99)\n",
195
+ " ])),\n",
196
+ "\n",
197
+ " # will probably need this if gpu supports it for flux, other dtypes may not work correctly\n",
198
+ " ('dtype', 'bf16')\n",
199
+ " ])),\n",
200
+ " ('model', OrderedDict([\n",
201
+ " # huggingface model name or path\n",
202
+ " ('name_or_path', 'black-forest-labs/FLUX.1-schnell'),\n",
203
+ " ('assistant_lora_path', 'ostris/FLUX.1-schnell-training-adapter'), # Required for flux schnell training\n",
204
+ " ('is_flux', True),\n",
205
+ " ('quantize', True), # run 8bit mixed precision\n",
206
+ " # low_vram is painfully slow to fuse in the adapter avoid it unless absolutely necessary\n",
207
+ " #('low_vram', True), # uncomment this if the GPU is connected to your monitors. It will use less vram to quantize, but is slower.\n",
208
+ " ])),\n",
209
+ " ('sample', OrderedDict([\n",
210
+ " ('sampler', 'flowmatch'), # must match train.noise_scheduler\n",
211
+ " ('sample_every', 250), # sample every this many steps\n",
212
+ " ('width', 1024),\n",
213
+ " ('height', 1024),\n",
214
+ " ('prompts', [\n",
215
+ " # you can add [trigger] to the prompts here and it will be replaced with the trigger word\n",
216
+ " #'[trigger] holding a sign that says \\'I LOVE PROMPTS!\\'',\n",
217
+ " 'woman with red hair, playing chess at the park, bomb going off in the background',\n",
218
+ " 'a woman holding a coffee cup, in a beanie, sitting at a cafe',\n",
219
+ " 'a horse is a DJ at a night club, fish eye lens, smoke machine, lazer lights, holding a martini',\n",
220
+ " 'a man showing off his cool new t shirt at the beach, a shark is jumping out of the water in the background',\n",
221
+ " 'a bear building a log cabin in the snow covered mountains',\n",
222
+ " 'woman playing the guitar, on stage, singing a song, laser lights, punk rocker',\n",
223
+ " 'hipster man with a beard, building a chair, in a wood shop',\n",
224
+ " 'photo of a man, white background, medium shot, modeling clothing, studio lighting, white backdrop',\n",
225
+ " 'a man holding a sign that says, \\'this is a sign\\'',\n",
226
+ " 'a bulldog, in a post apocalyptic world, with a shotgun, in a leather jacket, in a desert, with a motorcycle'\n",
227
+ " ]),\n",
228
+ " ('neg', ''), # not used on flux\n",
229
+ " ('seed', 42),\n",
230
+ " ('walk_seed', True),\n",
231
+ " ('guidance_scale', 1), # schnell does not do guidance\n",
232
+ " ('sample_steps', 4) # 1 - 4 works well\n",
233
+ " ]))\n",
234
+ " ])\n",
235
+ " ])\n",
236
+ " ])),\n",
237
+ " # you can add any additional meta info here. [name] is replaced with config name at top\n",
238
+ " ('meta', OrderedDict([\n",
239
+ " ('name', '[name]'),\n",
240
+ " ('version', '1.0')\n",
241
+ " ]))\n",
242
+ "])\n"
243
+ ]
244
+ },
245
+ {
246
+ "cell_type": "markdown",
247
+ "metadata": {
248
+ "id": "h6F1FlM2Wb3l"
249
+ },
250
+ "source": [
251
+ "## Run it\n",
252
+ "\n",
253
+ "Below does all the magic. Check your folders to the left. Items will be in output/LoRA/your_name_v1 In the samples folder, there are preiodic sampled. This doesnt work great with colab. They will be in /content/output"
254
+ ]
255
+ },
256
+ {
257
+ "cell_type": "code",
258
+ "execution_count": null,
259
+ "metadata": {
260
+ "id": "HkajwI8gteOh"
261
+ },
262
+ "outputs": [],
263
+ "source": [
264
+ "run_job(job_to_run)\n"
265
+ ]
266
+ },
267
+ {
268
+ "cell_type": "markdown",
269
+ "metadata": {
270
+ "id": "Hblgb5uwW5SD"
271
+ },
272
+ "source": [
273
+ "## Done\n",
274
+ "\n",
275
+ "Check your ourput dir and get your slider\n"
276
+ ]
277
+ }
278
+ ],
279
+ "metadata": {
280
+ "accelerator": "GPU",
281
+ "colab": {
282
+ "gpuType": "A100",
283
+ "machine_shape": "hm",
284
+ "provenance": []
285
+ },
286
+ "kernelspec": {
287
+ "display_name": "Python 3",
288
+ "name": "python3"
289
+ },
290
+ "language_info": {
291
+ "name": "python"
292
+ }
293
+ },
294
+ "nbformat": 4,
295
+ "nbformat_minor": 0
296
+ }