Closed iamwangyabin closed 1 year ago
直接git clone的可以不需要hcpinit,这个是通过pip install之后,你新建工程使用时候运行的。近期会考虑增加对webui的转换脚本。
好的,我已经成功训练一个lora了,但是有个问题,我发现我没法加载nai,只能用sd-1.5,不知道这是配置有啥问题么?
_base_: [cfgs/train/train_base.yaml, cfgs/train/tuning_base.yaml]
lora_unet:
- lr: 1e-4
rank: 8
layers:
- 're:.*\.attn.?$'
- 're:.*\.ff\.net\.0$'
lora_text_encoder:
- lr: 1e-5
rank: 4
layers:
- 're:.*self_attn$'
- 're:.*mlp$'
tokenizer_pt:
train: null
train:
gradient_accumulation_steps: 1
save_step: 100
scheduler:
name: 'constant_with_warmup'
num_warmup_steps: 50
num_training_steps: 600
model:
pretrained_model_name_or_path: 'runwayml/stable-diffusion-v1-5'
tokenizer_repeats: 1
ema_unet: 0
ema_text_encoder: 0
enable_xformers: False
data:
batch_size: 4
prompt_template: 'prompt_tuning_template/caption.txt'
caption_file: "/home/yabin/datasets/custom/enma_ai/image_captions.json"
cache_latents: True
tag_transforms:
transforms:
- _target_: hcpdiff.utils.caption_tools.TagShuffle
- _target_: hcpdiff.utils.caption_tools.TagDropout
p: 0.1
- _target_: hcpdiff.utils.caption_tools.TemplateFill
word_names:
pt1: enma_ai
bucket:
_target_: hcpdiff.data.bucket.RatioBucket.from_files # aspect ratio bucket
img_root: '/home/yabin/datasets/custom/enma_ai/'
target_area: {_target_: "builtins.eval", _args_: ['512*512']}
num_bucket: 10
data_class: null
这个load倒是没问题了,我从sd script改了一些代码进去就可以load了。 但是怎么才能多卡训练?我发现train_ac.py无论我给他指定gpu id是多少,都是用的第一张卡。 accelerator config all gpu也没作用 请问多卡启动指定什么?
这个load倒是没问题了,我从sd script改了一些代码进去就可以load了。 但是怎么才能多卡训练?我发现train_ac.py无论我给他指定gpu id是多少,都是用的第一张卡。 accelerator config all gpu也没作用 请问多卡启动指定什么?
在accelerator config中选multi-gpu,把所有卡选上。记得更新一下,修了一些多卡训练的bug。
word_names: pt1: enma_ai
如果你要使用触发词的话,最好创建一个自定义单词,加到tokenizer_pt.train里面,这样一起训练效果更好一些
word_names: pt1: enma_ai
如果你要使用触发词的话,最好创建一个自定义单词,加到tokenizer_pt.train里面,这样一起训练效果更好一些
很感谢你的回答,我已经可以多卡训练了。感觉这个项目多卡训练确实方便很多,colo我也尝试下。这个多卡启动其实就是让我们batchsize能够变得更多对吧,那关于图片的repeats(对应sd-scripts)是怎么设置的?这个dataset length显示了200,但是我的图片只有38张,我想应该是bucket自动切分图后整合了这样长度的数据集了吧?
2023-04-17 13:12:08.976 | INFO | __main__:build_data:282 - len(train_dataset): 200
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 200/200 [00:03<00:00, 51.02it/s]
2023-04-17 13:12:17.192 | INFO | __main__:train:354 - ***** Running training *****
2023-04-17 13:12:17.193 | INFO | __main__:train:355 - Num batches each epoch = 2
2023-04-17 13:12:17.193 | INFO | __main__:train:356 - Num Steps = 600
2023-04-17 13:12:17.194 | INFO | __main__:train:357 - Instantaneous batch size per device = 4
2023-04-17 13:12:17.194 | INFO | __main__:train:358 - Total train batch size (w. parallel, distributed & accumulation) = 20
2023-04-17 13:12:17.194 | INFO | __main__:train:359 - Gradient Accumulation steps = 1
2023-04-17 13:12:36.718 | INFO | __main__:train:379 - Step [20/600], LR_model: 8.00e-04, LR_word: 0.00e+00, Loss: 1.11199
2023-04-17 13:12:55.212 | INFO | __main__:train:379 - Step [40/600], LR_model: 1.60e-03, LR_word: 0.00e+00, Loss: 0.78624
2023-04-17 13:13:13.901 | INFO | __main__:train:379 - Step [60/600], LR_model: 2.00e-03, LR_word: 0.00e+00, Loss: 0.19678
2023-04-17 13:13:32.539 | INFO | __main__:train:379 - Step [80/600], LR_model: 2.00e-03, LR_word: 0.00e+00, Loss: 0.17637
2023-04-17 13:13:51.563 | INFO | __main__:save_model:507 - Saved state, step: 100
2023-04-17 13:13:51.563 | INFO | __main__:train:379 - Step [100/600], LR_model: 2.00e-03, LR_word: 0.00e+00, Loss: 0.10911
2023-04-17 13:14:10.298 | INFO | __main__:train:379 - Step [120/600], LR_model: 2.00e-03, LR_word: 0.00e+00, Loss: 0.14508
2023-04-17 13:14:29.207 | INFO | __main__:train:379 - Step [140/600], LR_model: 2.00e-03, LR_word: 0.00e+00, Loss: 0.11109
2023-04-17 13:14:48.153 | INFO | __main__:train:379 - Step [160/600], LR_model: 2.00e-03, LR_word: 0.00e+00, Loss: 0.11331
2023-04-17 13:15:06.723 | INFO | __main__:train:379 - Step [180/600], LR_model: 2.00e-03, LR_word: 0.00e+00, Loss: 0.13265
还有就是这里tokenizer_pt.train和sd-script里面哪个参数有对应关系么,我在sd-script里面只是给每张图片一个caption,里面第一个词是这触发词,在这里{pt1}{caption}就应该是实现一样的效果吧。那sd-script里面默认也训练tokenizer了?
这个dataset length显示了200,但是我的图片只有38张,我想应该是bucket自动切分图后整合了这样长度的数据集了吧?
bucket会自动把每个bucket的图片数量变成batch size的整数倍,如果你的图片数量不多,且宽高比比较一致,可以减少num_bucket。
sd-scripts中的repeats是一个很奇怪的选项,图片本身就会被遍历很多次训练,在一个epoch内重复图像没有什么意义,和多训练几个epoch是一样的,我就删掉了这个冗余的选项。
template可以用新加dobject_caption.txt
这个dataset length显示了200,但是我的图片只有38张,我想应该是bucket自动切分图后整合了这样长度的数据集了吧?
bucket会自动把每个bucket的图片数量变成batch size的整数倍,如果你的图片数量不多,且宽高比比较一致,可以减少num_bucket。
sd-scripts中的repeats是一个很奇怪的选项,图片本身就会被遍历很多次训练,在一个epoch内重复图像没有什么意义,和多训练几个epoch是一样的,我就删掉了这个冗余的选项。
template可以用新加dobject_caption.txt
好的,另外我刚发现多卡训练会出一个错误:
2023-04-17 13:21:24.842 | INFO | __main__:save_model:507 - Saved state, step: 600
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/yabin/miniconda3/envs/hcp/lib/python3.10/runpy.py:196 in _run_module_as_main │
│ │
│ 193 │ main_globals = sys.modules["__main__"].__dict__ │
│ 194 │ if alter_argv: │
│ 195 │ │ sys.argv[0] = mod_spec.origin │
│ ❱ 196 │ return _run_code(code, main_globals, None, │
│ 197 │ │ │ │ │ "__main__", mod_spec) │
│ 198 │
│ 199 def run_module(mod_name, init_globals=None, │
│ │
│ /home/yabin/miniconda3/envs/hcp/lib/python3.10/runpy.py:86 in _run_code │
│ │
│ 83 │ │ │ │ │ __loader__ = loader, │
│ 84 │ │ │ │ │ __package__ = pkg_name, │
│ 85 │ │ │ │ │ __spec__ = mod_spec) │
│ ❱ 86 │ exec(code, run_globals) │
│ 87 │ return run_globals │
│ 88 │
│ 89 def _run_module_code(code, init_globals=None, │
│ │
│ /home/yabin/HCP-Diffusion/hcpdiff/train_ac.py:530 in <module> │
│ │
│ 527 │ │
│ 528 │ conf = load_config_with_cli(args.cfg, args_list=sys.argv[3:]) # skip --cfg │
│ 529 │ trainer=Trainer(conf) │
│ ❱ 530 │ trainer.train() │
│ 531 │
│ │
│ /home/yabin/HCP-Diffusion/hcpdiff/train_ac.py:388 in train │
│ │
│ 385 │ │ │ │ break │
│ 386 │ │ │
│ 387 │ │ self.wait_for_everyone() │
│ ❱ 388 │ │ self.save_model() │
│ 389 │ │
│ 390 │ def wait_for_everyone(self): │
│ 391 │ │ self.accelerator.wait_for_everyone() │
│ │
│ /home/yabin/HCP-Diffusion/hcpdiff/train_ac.py:493 in save_model │
│ │
│ 490 │ │
│ 491 │ def save_model(self, from_raw=False): │
│ 492 │ │ unet_raw=self.get_unet_raw() │
│ ❱ 493 │ │ self.ckpt_manager.save_model_with_lora(unet_raw, self.lora_unet, model_ema=getat │
│ 494 │ │ │ │ │ │ │ │ │ │ │ name='unet', step=self.global_step) │
│ 495 │ │ if self.train_TE: │
│ 496 │ │ │ TE_raw = self.get_text_encoder_raw() │
│ │
│ /home/yabin/HCP-Diffusion/hcpdiff/utils/ckpt_manager/ckpt_pkl.py:39 in save_model_with_lora │
│ │
│ 36 │ │ │ if not lora_blocks.empty(): │
│ 37 │ │ │ │ sd_model['lora_ema'] = {sd_ema_lora[k] for k in sd_model['lora'].keys()} │
│ 38 │ │ │
│ ❱ 39 │ │ self._save_ckpt(sd_model, name, step) │
│ 40 │ │
│ 41 │ def _save_ckpt(self, sd_model, name, step): │
│ 42 │ │ save_path = os.path.join(self.save_dir, f"{name}-{step}.ckpt") │
│ │
│ /home/yabin/HCP-Diffusion/hcpdiff/utils/ckpt_manager/ckpt_safetensor.py:20 in _save_ckpt │
│ │
│ 17 class CkptManagerSafe(CkptManagerPKL): │
│ 18 │ │
│ 19 │ def _save_ckpt(self, sd_model, name, step): │
│ ❱ 20 │ │ save_path = os.path.join(self.save_dir, f"{name}-{step}.safetensors") │
│ 21 │ │ sd_unfold = self.unfold_dict(sd_model) │
│ 22 │ │ save_file(sd_unfold, save_path) │
│ 23 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'CkptManagerSafe' object has no attribute 'save_dir'
╭─────────────────────────────── Traceback (most recent call last) ──────
if self.is_local_main_process:
self.save_model()
加上
if self.is_local_main_process: self.save_model()
感谢反馈,已经修复了
- 能原生支持 webui 就好了,我看把model包了一层,为啥呢?DDP 遇到啥问题吗?
- yaml管理思路挺好的,微调部分能直接用 peft 最好,未来主流,huggingface 自家的方便后面适配其它模型
如果不包起来的话,DDP会有很多兼容性问题,比如gradient checkpoint、clip skip之类的。DDP兼容性真的太烂了。
现在通过yaml可以配置各种插件,也可以单独训练部分层,所以像是Adapters, lora, prompt-tuning之类的都是支持的,可以直接用配置文件设置的,使用起来也比较清晰和方便。近期会更新自定义plugin功能,可以自定义特定网络结构插件。
后面可能还会支持基于int8或者int4量化的stable diffuison基础模型训练lora,这样运算量和显存可能可以减少10倍以上
- 能原生支持 webui 就好了,我看把model包了一层,为啥呢?DDP 遇到啥问题吗?
- yaml管理思路挺好的,微调部分能直接用 peft 最好,未来主流,huggingface 自家的方便后面适配其它模型
如果不包起来的话,DDP会有很多兼容性问题,比如gradient checkpoint、clip skip之类的。DDP兼容性真的太烂了。
现在通过yaml可以配置各种插件,也可以单独训练部分层,所以像是Adapters, lora, prompt-tuning之类的都是支持的,可以直接用配置文件设置的,使用起来也比较清晰和方便。近期会更新自定义plugin功能,可以自定义特定网络结构插件。
后面可能还会支持基于int8或者int4量化的stable diffuison基础模型训练lora,这样运算量和显存可能可以减少10倍以上
嗯,其实想基于这个做成通用的微调框架,不仅针对 stable diffuison,只是 huggingface 的模型微调方法想借助 https://github.com/huggingface/peft , 毕竟自家的支持的全面 方法也跟得上,也方便迁移,然后自定义层微调这种可以 HCP 自己搞
新版本已经支持和webui的lora相互转换了
新版本怎么训练lora 几个示例文件都跑不通
好吧,我刚试下第一步没走通: