使用 diffusers 訓(xùn)練你自己的 ControlNet

簡(jiǎn)介
ControlNet 這個(gè)神經(jīng)網(wǎng)絡(luò)模型使得用戶可以通過(guò)施加額外條件,細(xì)粒度地控制擴(kuò)散模型的生成過(guò)程。這一技術(shù)最初由 Adding Conditional Control to Text-to-Image Diffusion Models 這篇論文提出,并很快地風(fēng)靡了擴(kuò)散模型的開(kāi)源社區(qū)。作者開(kāi)源了 8 個(gè)不同的模型,使得用戶可以用 8 種條件去控制 Stable Diffusion 模型(包括版本 1 到 5 )。這 8 種條件包括姿態(tài)估計(jì)、深度圖、邊緣圖、素描圖 等等。
ControlNet 博文鏈接:
https://hf.co/blog/zh/controlnetAdding Conditional Control to Text-to-Image Diffusion Models 論文:
https://hf.co/papers/2302.05543作者 Lvmin Zhang 提供的多種條件:
https://hf.co/lllyasviel

在這篇博客中,我們首先介紹訓(xùn)練?Uncanny?Faces model 的步驟。這是一個(gè)基于 3D 合成人臉的人臉姿態(tài)模型(這里的 uncanny faces 只是一個(gè)無(wú)意得到的結(jié)果,后面我們會(huì)講到)。
開(kāi)始著手用 Stable Diffusion 訓(xùn)練你的 ControlNet
訓(xùn)練你自己的 ControlNet 需要 3 個(gè)步驟:
設(shè)計(jì)你想要的生成條件: 使用 ControlNet 可以靈活地“馴服” Stable Diffusion,使它朝著你想的方向生成。預(yù)訓(xùn)練的模型已經(jīng)展示出了大量可用的生成條件,此外開(kāi)源社區(qū)也已經(jīng)開(kāi)發(fā)出了很多其它條件,比如這里 像素化的色彩板。
https://hf.co/thibaud/controlnet-sd21-color-diffusers構(gòu)建你自己的數(shù)據(jù)集: 當(dāng)生成條件確定好后,就該構(gòu)建數(shù)據(jù)集了。你既可以從頭構(gòu)建一個(gè)數(shù)據(jù)集,也可以使用現(xiàn)有數(shù)據(jù)集中的數(shù)據(jù)。為了訓(xùn)練模型,這個(gè)數(shù)據(jù)集需要有三個(gè)維度的信息: 圖片、作為條件的圖片,以及語(yǔ)言提示。
訓(xùn)練模型: 一旦數(shù)據(jù)集建好了,就可以訓(xùn)練模型了。如果你使用 這個(gè)基于 diffusers 的訓(xùn)練腳本,訓(xùn)練其實(shí)是最簡(jiǎn)單的。這里你需要一個(gè)至少 8G 顯存的 GPU。
https://github.com/huggingface/diffusers/tree/main/examples/controlnet
1. 設(shè)計(jì)你想要的生成條件
在設(shè)計(jì)你自己的生成條件前,有必要考慮一下兩個(gè)問(wèn)題:
哪種生成條件是我想要的?
是否已有現(xiàn)存的模型可以把正常圖片轉(zhuǎn)換成我的條件圖片?
舉個(gè)例子,假如我們想要使用人臉特征點(diǎn)作為生成條件。我們的思考過(guò)程應(yīng)該是這樣: 1. 一般基于特征點(diǎn)的 ControlNet 效果都還挺好。2. 人臉特征點(diǎn)檢測(cè)也是一個(gè)很常見(jiàn)的任務(wù),也有很多模型可以在普通圖片上檢測(cè)人臉特征點(diǎn)。3. 讓 Stable Diffusion 去根據(jù)特征點(diǎn)生成人臉圖片也挺有意思,還能讓生成的人臉模仿別人的表情。

2. 構(gòu)建你自己的數(shù)據(jù)集
好!那我們現(xiàn)在已經(jīng)決定用人臉特征點(diǎn)作為生成條件了。接下來(lái)我們需要這樣構(gòu)建數(shù)據(jù)集:
準(zhǔn)備 ground truth 圖片 (
image
): 這里指的就是真實(shí)人臉圖片準(zhǔn)備 條件圖片 (
conditioning_image
): 這里指的就是畫出來(lái)的特征點(diǎn)準(zhǔn)備 說(shuō)明文字 (
caption
): 描述圖片的文字
針對(duì)這個(gè)項(xiàng)目,我們使用微軟的?FaceSynthetics
?數(shù)據(jù)集: 這是一個(gè)包含了 10 萬(wàn)合成人臉的數(shù)據(jù)集。你可能會(huì)想到其它一些人臉數(shù)據(jù)集,比如?Celeb-A HQ
?和?FFHQ
,但這個(gè)項(xiàng)目我們決定還是采用合成人臉。

這里的?FaceSynthetics
?數(shù)據(jù)集看起來(lái)是個(gè)不錯(cuò)的選擇: 它包含了真實(shí)的人臉圖片,同時(shí)也包含了被標(biāo)注過(guò)的人臉特征點(diǎn)(按照 iBUG 68 特征點(diǎn)的格式),同時(shí)還有人臉的分割圖。

然而,這個(gè)數(shù)據(jù)集也不是完美的。我們前面說(shuō)過(guò),我們應(yīng)該有模型可以將真實(shí)圖片轉(zhuǎn)換到條件圖片。但這里似乎沒(méi)有這樣的模型,把人臉圖片轉(zhuǎn)換成我們特征點(diǎn)標(biāo)注形式(無(wú)法把特征點(diǎn)轉(zhuǎn)換為分割圖)。

所以我們需要用另一種方法:
使用?
FaceSynthetics
?中的真實(shí)圖片 (image
)使用一個(gè)現(xiàn)有的模型把人臉圖片轉(zhuǎn)換為 68 個(gè)特征點(diǎn)的形式。這里我們使用 SPIGA 這個(gè)模型
https://github.com/andresprados/SPIGA使用自己的代碼把人臉特征點(diǎn)轉(zhuǎn)換為人臉?lè)指顖D,以此作為“條件圖片” (
conditioning_image
)把這些數(shù)據(jù)保存為 Hugging Face DatasetAhttps://hf.co/docs/datasets/indexx
這里 是將真實(shí)圖片轉(zhuǎn)換到分割圖的代碼,以及將數(shù)據(jù)保存為 Hugging Face Dataset 的代碼。
https://hf.co/datasets/pcuenq/face_synthetics_spiga
現(xiàn)在我們準(zhǔn)備好了 ground truth 圖片和“條件圖片”,我們還缺少說(shuō)明文字。我們強(qiáng)烈推薦你把說(shuō)明文字加進(jìn)去,但你也可以試試使用空的說(shuō)明文字來(lái)看看效果。因?yàn)?span id="s0sssss00s" class="Apple-converted-space">?FaceSynthetics
?數(shù)據(jù)集并沒(méi)有自帶說(shuō)明文字,我們使用 BLIP captioning 去給圖片加上文字(代碼在這里)。
BLIP captioning 文檔:
https://hf.co/docs/transformers/model_doc/blip代碼地址:
https://hf.co/datasets/multimodalart/facesyntheticsspigacaptioned
至此,我們就完成了數(shù)據(jù)集的構(gòu)建。這個(gè) Face Synthetics SPIGA with captions 數(shù)據(jù)集包含了 ground truth 圖片、條件圖片,以及對(duì)應(yīng)的說(shuō)明文字,總計(jì)有 10 萬(wàn)條數(shù)據(jù)。一切就緒,我們現(xiàn)在可以開(kāi)始訓(xùn)練模型了。
https://hf.co/datasets/multimodalart/facesyntheticsspigacaptioned

3. 模型訓(xùn)練
有了 數(shù)據(jù),下一步就是訓(xùn)練模型。即使這部分很難,但有了 下面的腳本,這個(gè)過(guò)程卻變成了最簡(jiǎn)單的部分。我們用了一個(gè) A100 GPU去訓(xùn)練(在 LambdaLabs 每小時(shí) 1.1 美元租的)。
腳本地址:
https://github.com/huggingface/diffusers/tree/main/examples/controlnetLambdaLabs:
https://lambdalabs.com
我們的訓(xùn)練經(jīng)驗(yàn)
我們以 batch size 為 4 訓(xùn)練了 3 個(gè) epoch。結(jié)果表明此策略有些太激進(jìn),導(dǎo)致結(jié)果出現(xiàn)過(guò)擬合現(xiàn)象。模型有點(diǎn)忘記人臉的概念了,即使提示語(yǔ)中包含“怪物史萊克”或“一只貓”,模型也只會(huì)生成人臉而不是“史萊克”或貓;同時(shí)模型也對(duì)各種風(fēng)格變得不敏感。
如果我們只訓(xùn)練 1 個(gè) epoch (即模型僅學(xué)習(xí)了 10 萬(wàn)張照片),模型倒是能遵循輸入的姿態(tài),同時(shí)也沒(méi)什么過(guò)擬合。看起來(lái)還行,但由于我們用的是合成數(shù)據(jù),模型最終生成的都是些看起來(lái)很 3D 的人臉,而不是真實(shí)人臉。當(dāng)然,基于我們用的數(shù)據(jù)集,生成這樣的效果也正常。這里是訓(xùn)練好的模型 uncannyfaces_25K。
https://hf.co/multimodalart/uncannyfaces_25K

在這張可交互表格 (請(qǐng)?jiān)L問(wèn)下面的鏈接) 中,你可以看看不同步數(shù)下模型訓(xùn)練進(jìn)度如何。在訓(xùn)練了大約 15k 步后,模型就已經(jīng)開(kāi)始學(xué)習(xí)姿態(tài)了。最終模型在 25k 步后成熟。
https://wandb.ai/apolinario/controlnet/reports/ControlNet-Uncanny-Faces-Training--VmlldzozODcxNDY0
訓(xùn)練具體怎么做
首先我們安裝各種依賴:
pip?install?git+https://github.com/huggingface/diffusers.git?transformers?accelerate?xformers==0.0.16?wandb
huggingface-cli?login
wandb?login?
然后運(yùn)行 train_controlnet.py 這個(gè)腳本:
https://github.com/huggingface/diffusers/blob/main/examples/controlnet/train_controlnet.py
!accelerate?launch?train_controlnet.py?\
?--pretrained_model_name_or_path="stabilityai/stable-diffusion-2-1-base"?\
?--output_dir="model_out"?\
?--dataset_name=multimodalart/facesyntheticsspigacaptioned?\
?--conditioning_image_column=spiga_seg?\
?--image_column=image?\
?--caption_column=image_caption?\
?--resolution=512?\
?--learning_rate=1e-5?\
?--validation_image?"./face_landmarks1.jpeg"?"./face_landmarks2.jpeg"?"./face_landmarks3.jpeg"?\
?--validation_prompt?"High-quality?close-up?dslr?photo?of?man?wearing?a?hat?with?trees?in?the?background"?"Girl?smiling,?professional?dslr?photograph,?dark?background,?studio?lights,?high?quality"?"Portrait?of?a?clown?face,?oil?on?canvas,?bittersweet?expression"?\
?--train_batch_size=4?\
?--num_train_epochs=3?\
?--tracker_project_name="controlnet"?\
?--enable_xformers_memory_efficient_attention?\
?--checkpointing_steps=5000?\
?--validation_steps=5000?\
?--report_to?wandb?\
?--push_to_hub
我們?cè)敿?xì)看看這些設(shè)置參數(shù),同時(shí)也看看有哪些優(yōu)化方法可以用于 8GB 以下顯存的 GPU 訓(xùn)練。
pretrained_model_name_or_path
: 基礎(chǔ)的 Stable Diffusion 模型,這里我們使用 v2-1 版本,因?yàn)檫@一版生成人臉效果更好output_dir
: 保存模型的目錄文件夾dataset_name
: 用于訓(xùn)練的數(shù)據(jù)集,這里我們使用 Face Synthetics SPIGA with captions
https://hf.co/datasets/multimodalart/facesyntheticsspigacaptionedconditioning_image_column
: 數(shù)據(jù)集中包含條件圖片的這一欄的名稱,這里我們用?spiga_seg
image_column
: 數(shù)據(jù)集中包含 ground truth 圖片的這一欄的名稱,這里我們用?image
caption_column
: 數(shù)據(jù)集中包含文字說(shuō)明的這一欄的名稱,這里我們用?image_caption
resolution
: ground truth 圖片和條件圖片的分辨率,這里我們用?512x512
learning_rate
: 學(xué)習(xí)率。我們發(fā)現(xiàn)設(shè)成?1e-5
?效果很好,但你也可以試試介于?1e-4
和?2e-6
?之間的其它值validation_image
: 這里是讓你在訓(xùn)練過(guò)程中偷窺一下效果的。每隔?validation_steps
?步訓(xùn)練,這些驗(yàn)證圖片都會(huì)跑一下,讓你看看當(dāng)前的訓(xùn)練效果。請(qǐng)?jiān)谶@里插入一個(gè)指向一系列條件圖片的本地路徑validation_prompt
: 這里是一句文本提示,用于和你的驗(yàn)證圖片一起驗(yàn)證當(dāng)前模型。你可以根據(jù)你的需要設(shè)置train_batch_size
: 這是訓(xùn)練時(shí)使用的 batch size。因?yàn)槲覀冇玫氖?V100,所以我們還有能力把它設(shè)成 4。但如果你的 GPU 顯存比較小,我們推薦直接設(shè)成 1。num_train_epochs
: 訓(xùn)練模型使用的輪數(shù)。每一輪模型都會(huì)看一遍整個(gè)數(shù)據(jù)集。我們實(shí)驗(yàn)用的是 3 輪,但似乎最好的結(jié)果應(yīng)該是出現(xiàn)在一輪多一點(diǎn)的地方。當(dāng)訓(xùn)練了 3 輪時(shí),我們的模型過(guò)擬合了。checkpointing_steps
: 每隔這么多步,我們都會(huì)保存一下模型的中間結(jié)果檢查點(diǎn)。這里我們?cè)O(shè)置成 5000,也就是每訓(xùn)練 5000 步就保存一下檢查點(diǎn)。validation_steps
: 每隔這么多步,validation_image
?和?validation_prompt
?就會(huì)跑一下,來(lái)驗(yàn)證訓(xùn)練過(guò)程。report_to
: 向哪里報(bào)告訓(xùn)練情況。這里我們使用 Weights and Biases 這個(gè)平臺(tái),它可以給出美觀的訓(xùn)練報(bào)告。push_to_hub
: 將最終結(jié)果推到 Hugging Face Hub.
但是將?train_batch_size
?從?4
?減小到?1
?可能還不足以使模型能夠在低配置 GPU 上運(yùn)行,這里針對(duì)不同 GPU 的 VRAM 提供一些其它配置信息:
適配 16GB 顯存的 GPU
pip?install?bitsandbytes
--train_batch_size=1?\
--gradient_accumulation_steps=4?\
--gradient_checkpointing?\
--use_8bit_adam
這里 batch size 設(shè)為 1,同時(shí)使用 4 步的梯度累計(jì)等同于你使用原始的 batch size 為 4 的情況。除此之外,我們開(kāi)啟了對(duì)梯度保存檢查點(diǎn),以及 8 bit 的 Adam 優(yōu)化器訓(xùn)練,以此更多地節(jié)省顯存。
適配 12GB 顯存的 GPU
--gradient_accumulation_steps=4?\
--gradient_checkpointing?\
--use_8bit_adam
--set_grads_to_none
適配 8GB 顯存的 GPU
請(qǐng)參考 我們的教程
https://github.com/huggingface/diffusers/tree/main/examples/controlnet
4. 總結(jié)
訓(xùn)練 ControlNet 的過(guò)程非常有趣。我們已經(jīng)成功地訓(xùn)練了一個(gè)可以模仿真實(shí)人臉姿態(tài)的模型。然而這個(gè)模型更多是生成 3D 風(fēng)格的人臉圖片而不是真實(shí)人臉圖片,這是由于我們使用了合成人臉的數(shù)據(jù)執(zhí)行訓(xùn)練。當(dāng)然這也讓生成的模型有了獨(dú)特的魅力。
試試我們的 Hugging Face Space:
https://huggingface.co/spaces/pcuenq/uncanny-faces

下一步,為了生成真實(shí)的人臉圖片,同時(shí)還不使用真實(shí)人臉數(shù)據(jù)集,我們可以用 Stable Diffusion Image2Image 跑一遍所有的?FaceSynthetics
?圖片,把看起來(lái)很 3D 的人臉轉(zhuǎn)換成真實(shí)人臉圖片,然后再訓(xùn)練 ControlNet。
請(qǐng)繼續(xù)關(guān)注我們,接下來(lái)我們將舉辦 ControlNet 訓(xùn)練賽事。請(qǐng)?jiān)?Twitter 關(guān)注 Hugging Face,或者加入我們的 Discord 以便接收最新消息!
如果您此前曾被 ControlNet 將 Lofi Girl 的動(dòng)畫形象改成寫實(shí)版類真人畫面的能力折服 (使用 ?? Diffusers 實(shí)現(xiàn) ControlNet 高速推理),卻又擔(dān)心自己難以承擔(dān)高昂的訓(xùn)練成本,不妨報(bào)名參加我們近期的提供免費(fèi) TPU 的 ControlNet 微調(diào)活動(dòng)。試試看充滿創(chuàng)造力的你能有什么樣的大作!
?快來(lái)用免費(fèi) TPU,調(diào)出你的 ControlNet!?
英文原文:?https://hf.co/blog/train-your-controlnet
作者: Apolinário from multimodal AI art, Pedro Cuenca
譯者: HoiM Y, 阿東