使用 Diffusers 實(shí)現(xiàn) ControlNet 高速推理

自從 Stable Diffusion 風(fēng)靡全球以來,人們一直在尋求如何更好地控制生成過程的方法。ControlNet 提供了一個(gè)簡(jiǎn)單的遷移學(xué)習(xí)方法,能夠允許用戶在很大程度上自定義生成過程。通過?ControlNet,用戶可以輕松地使用多種空間語義條件信息 (例如深度圖、分割圖、涂鴉圖、關(guān)鍵點(diǎn)等) 來控制生成過程。
具體來說,我們可以:
將卡通繪圖轉(zhuǎn)化為逼真的照片,同時(shí)保持極佳的布局連貫性。

進(jìn)行室內(nèi)設(shè)計(jì)。

將涂鴉草圖變成藝術(shù)作品。

甚至擬人化著名的 logo 形象。

ControlNet,使一切皆有可能 ??
本文的主要內(nèi)容:
介紹?
StableDiffusionControlNetPipeline
展示多種控制條件樣例
讓我們開啟控制之旅!
ControlNet 簡(jiǎn)述
ControlNet 在 Adding Conditional Control to Text-to-Image Diffusion Models 一文中提被出,作者是 Lvmin Zhang 和 Maneesh Agrawala。它引入了一個(gè)框架,支持在擴(kuò)散模型 (如 Stable Diffusion) 上附加額外的多種空間語義條件來控制生成過程。
訓(xùn)練 ControlNet 包括以下步驟:
克隆擴(kuò)散模型的預(yù)訓(xùn)練參數(shù) (文中稱為?可訓(xùn)練副本, trainable copy。如 Stable Diffusion 的 latent UNet 部分),同時(shí)保留原本的預(yù)訓(xùn)練參數(shù) (文中稱為?鎖定副本, locked copy)。這樣可以實(shí)現(xiàn): a) 讓鎖定副本保留從大型數(shù)據(jù)集中學(xué)到的豐富知識(shí);b) 讓可訓(xùn)練副本學(xué)習(xí)特定任務(wù)的知識(shí)。
可訓(xùn)練副本和鎖定副本的參數(shù)通過 “零卷積” 層 (詳見 此處) 連接?!傲憔矸e” 層是 ControlNet 框架的一部分,會(huì)在特定任務(wù)中優(yōu)化參數(shù)。這是一種訓(xùn)練技巧,可以在新任務(wù)條件訓(xùn)練時(shí)保留已凍結(jié)模型已經(jīng)學(xué)到的語義信息。
訓(xùn)練 ControlNet 的過程如圖所示:

圖片出處:
https://github.com/lllyasviel/ControlNet
ControlNet 訓(xùn)練集中的其中一種樣例如下 (額外的控制條件是 Canny 邊緣圖):

同樣地,如果我們使用的額外控制條件是語義分割圖,那么 ControlNet 訓(xùn)練集的樣例就是這樣:

每對(duì) ControlNet 施加一種額外的控制條件,都需要訓(xùn)練一份新的可訓(xùn)練副本參數(shù)。論文中提出了 8 種不同的控制條件,對(duì)應(yīng)的控制模型在 Diffusers 中均已支持!
模型列表:
https://hf.co/lllyasviel?search=controlnet
推理階段需要同時(shí)使用擴(kuò)散模型的預(yù)訓(xùn)練權(quán)重以及訓(xùn)練過的 ControlNet 權(quán)重。如要使用 Stable Diffusion v1-5 以及其 ControlNet 權(quán)重推理,其參數(shù)量要比僅使用 Stable Diffusion v1-5 多大約 7 億個(gè),因此推理 ControlNet 需要消耗更多的內(nèi)存。
Stable Diffusion v1-5 鏈接:
https://hf.co/runwayml/stable-diffusion-v1-5
由于在訓(xùn)練過程中擴(kuò)散模型預(yù)訓(xùn)練參數(shù)為鎖定副本,因此在使用不同的控制條件訓(xùn)練時(shí),只需要切換 ControlNet 可訓(xùn)練副本的參數(shù)即可。這樣在一個(gè)應(yīng)用程序中部署多個(gè) ControlNet 權(quán)重就非常簡(jiǎn)單了,本文會(huì)在后面詳細(xì)介紹。
StableDiffusionControlNetPipeline
在開始之前,我們要向社區(qū)貢獻(xiàn)者 Takuma Mori (@takuma104) 表示巨大的感謝。將 ControlNet 集成到 Diffusers 中,他功不可沒 ??。
類似 Diffusers 中的 其他 Pipeline,Diffusers 同樣為 ControlNet 提供了?StableDiffusionControlNetPipeline
?供用戶使用。StableDiffusionControlNetPipeline
?的核心是?controlnet
?參數(shù),它接收用戶指定的訓(xùn)練過的?ControlNetModel
?實(shí)例作為輸入,同時(shí)保持?jǐn)U散模型的預(yù)訓(xùn)練權(quán)重不變。
Hugging Face 文檔里對(duì)各種 Pipeline 的介紹:
https://hf.co/docs/diffusers/api/pipelines/overviewStableDiffusionControlNetPipeline
https://hf.co/docs/diffusers/main/en/api/pipelines/stable_diffusion/controlnetControlNetModel
https://hf.co/docs/diffusers/main/en/api/models
本文將介紹?StableDiffusionControlNetPipeline
?的多個(gè)不同用例。首先要介紹的第一個(gè) ControlNet 模型是 Canny 模型,這是目前最流行的 ControlNet 模型之一,您可能已經(jīng)在網(wǎng)上見識(shí)過一些它生成的精美圖片。在閱讀到各個(gè)部分的代碼時(shí),也歡迎您使用此 Colab 筆記本 運(yùn)行相關(guān)代碼片段。
Canny 模型鏈接:
https://hf.co/runwayml/stable-diffusion-v1-5Colab 鏈接:
https://colab.research.google.com/github/huggingface/notebooks/blob/main/diffusers/controlnet.ipynb
運(yùn)行代碼之前,首先確保我們已經(jīng)安裝好所有必要的庫:
pip?install?diffusers==0.14.0?transformers?xformers?git+https://github.com/huggingface/accelerate.git
為處理不同 ControlNet 對(duì)應(yīng)的多種控制條件,還需要安裝一些額外的依賴項(xiàng):
OpenCV
https://opencv.org/controlnet-aux - ControlNet 預(yù)處理模型庫
https://github.com/patrickvonplaten/controlnet_aux
我們將以著名的油畫作品《戴珍珠耳環(huán)的少女》為例,首先讓我們下載這張圖像并查看一下:
然后將圖像輸入給 Canny 預(yù)處理器:
如圖可見,Canny 本質(zhì)上是邊緣檢測(cè)器:
接下來,我們加載 runwaylml/stable-diffusion-v1-5 和 Canny 邊緣 ControlNet 模型。設(shè)置參數(shù)?torch.dtype=torch.float16
?可以指定模型以半精度模式加載,可實(shí)現(xiàn)內(nèi)存高效和快速的推理。
Canny 邊緣 ControlNet 鏈接:
https://hf.co/lllyasviel/sd-controlnet-canny
這里我們不使用 Stable Diffusion 默認(rèn)的 PNDMScheduler 調(diào)度器,而使用改進(jìn)的 UniPCMultistepScheduler (目前最快的擴(kuò)散模型調(diào)度器之一),可以極大地加快推理速度。經(jīng)測(cè)試,在保證生成圖像質(zhì)量的同時(shí),我們能將推理階段的采樣步數(shù)從 50 降到 20。更多關(guān)于調(diào)度器的信息可以點(diǎn)擊 此處 查看。
PNDMScheduler 鏈接:
https://hf.co/docs/diffusers/main/en/api/schedulers/pndmUniPCMultistepScheduler 鏈接:
https://hf.co/docs/diffusers/main/en/api/schedulers/unipcDiffusers 調(diào)度器的文檔:
https://hf.co/docs/diffusers/main/en/using-diffusers/schedulers
我們通過調(diào)用?enable_model_cpu_offload
?函數(shù)來啟用智能 CPU 卸載,而不是直接將 pipeline 加載到 GPU 上。
enable_model_cpu_offload
?文檔:
https://hf.co/docs/diffusers/main/en/api/pipelines/stable_diffusion/controlnet
智能 CPU 卸載是一種降低顯存占用的方法。擴(kuò)散模型 (如 Stable Diffusion) 的推理并不是運(yùn)行一個(gè)單獨(dú)的模型,而是多個(gè)模型組件的串行推理。如在推理 ControlNet Stable Diffusion 時(shí),需要首先運(yùn)行 CLIP 文本編碼器,其次推理擴(kuò)散模型 UNet 和 ControlNet,然后運(yùn)行 VAE 解碼器,最后運(yùn)行 safety checker (安全檢查器,主要用于審核過濾違規(guī)圖像)。而在擴(kuò)散過程中大多數(shù)組件僅運(yùn)行一次,因此不需要一直占用 GPU 內(nèi)存。通過啟用智能模型卸載,可以確保每個(gè)組件在不需要參與 GPU 計(jì)算時(shí)卸載到 CPU 上,從而顯著降低顯存占用,并且不會(huì)顯著增加推理時(shí)間 (僅增加了模型在 GPU-CPU 之間的轉(zhuǎn)移時(shí)間)。
注意: 啟用?enable_model_cpu_offload
?后,pipeline 會(huì)自動(dòng)進(jìn)行 GPU 內(nèi)存管理,因此請(qǐng)不要再使用?.to("cuda")
?手動(dòng)將 pipeline 轉(zhuǎn)移到 GPU。
最后,我們要充分利用 FlashAttention/xformers 進(jìn)行注意力層加速。運(yùn)行下列代碼以實(shí)現(xiàn)加速,如果該代碼沒有起作用,那么您可能沒有正確安裝?xformers
?庫,此時(shí)您可以跳過該代碼。
FlashAttention/xformers 倉庫鏈接:
https://github.com/facebookresearch/xformers
基本條件準(zhǔn)備就緒,現(xiàn)在來運(yùn)行 ControlNet pipeline!
跟運(yùn)行 Stable Diffusion image-to-image pipeline 相同的是,我們也使用了文本提示語來引導(dǎo)圖像生成過程。不過有一些不同的是,ControlNet 允許施加更多種類的控制條件來控制圖像生成過程,比如使用剛才我們創(chuàng)建的 Canny 邊緣圖就能更精確的控制生成圖像的構(gòu)圖。
讓我們來看一些有趣的,將 17 世紀(jì)的名作《戴珍珠耳環(huán)的少女》中的少女一角換為現(xiàn)代的名人會(huì)是什么樣?使用 ControlNet 就能輕松做到,只需要在提示語中寫上他們的名字即可!
首先創(chuàng)建一個(gè)非常簡(jiǎn)單的幫助函數(shù)來實(shí)現(xiàn)生成圖像的網(wǎng)格可視化。
然后輸入名字提示語,并設(shè)置隨機(jī)種子以便復(fù)現(xiàn)。
最后運(yùn)行 pipeline,并可視化生成的圖像!
我們還能輕松地將 ControlNet 與微調(diào)結(jié)合使用!例如使用 DreamBooth 對(duì)模型進(jìn)行微調(diào),然后使用 ControlNet 增加控制信息,將其渲染到不同的場(chǎng)景中。
DreamBooth 文檔鏈接:
https://hf.co/docs/diffusers/main/en/training/dreambooth
本文將以我們最愛的土豆先生為例,來介紹怎樣結(jié)合使用 ControlNet 和 DreamBooth。
相較于上文,pipeline 中使用的 ControlNet 部分保持不變,但是不使用 Stable Diffusion 1.5,而是重新加載一個(gè) 土豆先生 模型 (使用 Dreambooth 微調(diào)的 Stable Diffusion 模型) ??。
“土豆先生”模型地址:
https://hf.co/sd-dreambooth-library/mr-potato-head
雖然 ControlNet 沒變,但仍然需要重新加載 pipeline。
現(xiàn)在來讓土豆先生擺一個(gè)《戴珍珠耳環(huán)的少女》的姿勢(shì)吧!
看得出來土豆先生盡力了,這場(chǎng)景著實(shí)不太適合他,不過他仍然抓住了精髓??。
ControlNet 還有另一個(gè)獨(dú)特應(yīng)用: 從圖像提取人體姿態(tài),用姿態(tài)信息控制生成具有相同姿態(tài)的新圖像。因此在下一個(gè)示例中,我們將使用 Open Pose ControlNet 來教超級(jí)英雄如何做瑜伽!
Open Pose ControlNet 模型地址:
https://hf.co/lllyasviel/sd-controlnet-openpose
首先,我們需要收集一些瑜伽動(dòng)作圖像集:
通過?controlnet_aux
?提供的 OpenPose 預(yù)處理器,我們可以很方便地提取瑜伽姿態(tài)。

瑜伽姿態(tài)提取完成后,我們接著創(chuàng)建一個(gè) Open Pose ControlNet pipeline 來生成一些相同姿態(tài)的超級(jí)英雄圖像。Let's go ??
超級(jí)英雄的瑜伽時(shí)間!

通過以上示例,我們對(duì)?StableDiffusionControlNetPipeline
?的多種用法有了直觀的認(rèn)識(shí),也學(xué)會(huì)了如何使用 Diffusers 玩轉(zhuǎn) ControlNet。不過,還有一些 ControlNet 支持的其他類型的控制條件示例,由于篇幅原因本文不再展開,如想了解更多信息,可以點(diǎn)擊以下鏈接查看相應(yīng)的模型文檔頁面:
lllyasviel/sd-controlnet-depth
https://hf.co/lllyasviel/sd-controlnet-depthlllyasviel/sd-controlnet-hed
https://hf.co/lllyasviel/sd-controlnet-hedlllyasviel/sd-controlnet-normal
https://hf.co/lllyasviel/sd-controlnet-normallllyasviel/sd-controlnet-scribble
https://hf.co/lllyasviel/sd-controlnet-scribblelllyasviel/sd-controlnet-seg
https://hf.co/lllyasviel/sd-controlnet-scribblelllyasviel/sd-controlnet-openpose
https://hf.co/lllyasviel/sd-controlnet-openposelllyasviel/sd-controlnet-mlsd
https://hf.co/lllyasviel/sd-controlnet-mlsdlllyasviel/sd-controlnet-mlsd
https://hf.co/lllyasviel/sd-controlnet-canny
我們非常歡迎您嘗試組合不同的控制組件來生成精美的圖像,并在 Twitter 上與 @diffuserslib 分享您的作品。如果您還沒有運(yùn)行上述代碼段,這里再次建議您查看剛才提到的 Colab 筆記本,親自運(yùn)行代碼體驗(yàn)示例的效果!
在上文中,我們介紹了加速生成過程、減少顯存占用的一些技巧,它們包括: 快速調(diào)度器、智能模型卸載、xformers
。如果結(jié)合使用這些技巧,單張圖像的生成過程僅需要: V100 GPU 上約 3 秒的推理時(shí)間以及約 4 GB 的 VRAM 占用;免費(fèi) GPU 服務(wù) (如 Google Colab 的 T4) 上約 5 秒的推理時(shí)間。如果沒有實(shí)現(xiàn)這些技巧,同樣的生成過程可達(dá) 17 秒!現(xiàn)已集成至 Diffusers 工具箱,來使用 Diffusers 吧,它真的非常強(qiáng)力!??
結(jié)語
本文介紹了?StableDiffusionControlNetPipeline
?的多個(gè)用例,非常有趣!我們也非常期待看到社區(qū)在此 pipeline 的基礎(chǔ)上能構(gòu)建出什么好玩的應(yīng)用。如果您想了解更多 Diffusers 支持的關(guān)于控制模型的其他 pipeline 和技術(shù)細(xì)節(jié),請(qǐng)查看我們的 官方文檔。
StableDiffusionControlNetPipeline
https://hf.co/docs/diffusers/main/en/api/pipelines/stable_diffusion/controlnetDiffusers 控制生成的文檔
https://hf.co/docs/diffusers/main/en/using-diffusers/controlling_generation
如果您想直接嘗試 ControlNet 的控制效果,我們也能滿足!只需點(diǎn)擊以下 HuggingFace Spaces 即可嘗試控制生成圖像:
Canny ControlNet Spaces
https://hf.co/spaces/diffusers/controlnet-cannyOpenPose ControlNet Spaces
https://hf.co/spaces/diffusers/controlnet-openpose
原文鏈接:?https://huggingface.co/blog/controlnet
作者: Sayak Paul、YiYi Xu、Patrick von Platen
譯者: SuSung-boy
審校、排版: zhongdongy (阿東)