散模型演進(jìn)全史:從熱力學(xué)思想到AIGC生成地基)
擴(kuò)散模型這兩年的存在感強(qiáng)到幾乎成了“生成式AI”的代名詞。從2022年Stable Diffusion開(kāi)源那天起文生圖、圖生視頻、新視角合成、3D生成一股腦涌進(jìn)大眾視野但很多人并不清楚擴(kuò)散模型并不是2022年才冒出來(lái)的。它從最初一個(gè)略帶物理味道的想法到今天變成整個(gè)AIGC領(lǐng)域的地基經(jīng)歷了將近十年的演化。這篇博文我打算按自己的理解把這條路完整捋一遍從2015年那篇奠基論文講起講score-based模型、DDPM、SDE統(tǒng)一視角、引導(dǎo)機(jī)制、潛在擴(kuò)散模型再延伸到新視角合成和3D內(nèi)容生成最后附上我在實(shí)際訓(xùn)練和部署中踩過(guò)的坑。如果你正在學(xué)擴(kuò)散模型、想在項(xiàng)目里用它生成圖像或者只是好奇為什么AI繪圖這么好用這篇內(nèi)容應(yīng)該能幫你建立一條很清晰的技術(shù)時(shí)間線。讀完你會(huì)明白為什么加噪會(huì)被叫做“擴(kuò)散”為什么現(xiàn)在的生成模型都跑到“潛空間”里干活以及你在各類Demo里看到的新視角合成、3D生成效果到底是怎么從擴(kuò)散模型里長(zhǎng)出來(lái)的。1. 一切從一個(gè)熱力學(xué)比喻開(kāi)始擴(kuò)散模型的思想原點(diǎn)1.1 “擴(kuò)散”兩個(gè)字到底在說(shuō)什么不用公式解釋擴(kuò)散模型的話我通常會(huì)打一個(gè)比方你有一杯滴進(jìn)墨水的清水墨水會(huì)慢慢暈開(kāi)最后整杯水變成均勻的灰色這個(gè)過(guò)程就是物理擴(kuò)散。它的逆過(guò)程是把灰色水重新變回“墨水分明”的狀態(tài)幾乎不可能自然發(fā)生。但如果有一個(gè)“神之手”每一步都能預(yù)判顆粒往哪走理論上也能把水復(fù)原。2015年之前生成模型界的主流思路并不是這個(gè)。GAN當(dāng)時(shí)已經(jīng)火了好幾年VAE也有一批擁躉。擴(kuò)散模型的起點(diǎn)是2015年Sohl-Dickstein等人發(fā)表的那篇標(biāo)題很長(zhǎng)的論文《Deep Unsupervised Learning using Nonequilibrium Thermodynamics》。這篇論文最核心的貢獻(xiàn)是把熱力學(xué)里的“擴(kuò)散”翻譯成了機(jī)器學(xué)習(xí)語(yǔ)言定義一條前向路徑把數(shù)據(jù)逐步加噪直到變成純?cè)肼曉儆?xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)去學(xué)習(xí)這條路徑的逆向過(guò)程。訓(xùn)練完成之后你只要從純?cè)肼暢霭l(fā)順著逆向過(guò)程一步一步走就能得到一張新圖。這個(gè)思想今天看很自然但在當(dāng)時(shí)相當(dāng)超前。它不是去“直接生成數(shù)據(jù)”而是去“學(xué)一個(gè)破壞的反過(guò)程”。這等于換了一個(gè)提問(wèn)方式不要問(wèn)模型怎么憑空畫(huà)出一只貓而是問(wèn)它怎么把一堆噪聲一步步“擦”成一只貓。1.2 前向過(guò)程和反向過(guò)程的數(shù)學(xué)骨架具體到數(shù)學(xué)上前向過(guò)程定義一個(gè)馬爾可夫鏈。給定一張干凈圖像x0每一步按一個(gè)預(yù)先設(shè)計(jì)好的方差往里面加一點(diǎn)高斯噪聲經(jīng)過(guò)T步之后得到xT。當(dāng)步數(shù)T足夠大xT基本就是標(biāo)準(zhǔn)高斯噪聲原始信息徹底被淹沒(méi)。反向過(guò)程是訓(xùn)練一個(gè)帶參數(shù)的神經(jīng)網(wǎng)絡(luò)每一步根據(jù)當(dāng)前帶噪圖像和時(shí)間步t預(yù)測(cè)這一步該“去掉”多少噪聲逐步把圖像還原。2015年這篇論文里訓(xùn)練目標(biāo)寫(xiě)得非常復(fù)雜用了變分下界的框架形式上類似VAE。作者推導(dǎo)了ELBO并設(shè)計(jì)了一系列近似。但問(wèn)題在于當(dāng)時(shí)大家發(fā)現(xiàn)直接優(yōu)化這個(gè)目標(biāo)很困難需要非常大的采樣步數(shù)和算力生成質(zhì)量和同時(shí)期的GAN比有明顯差距。所以這篇論文雖然把整個(gè)框架搭起來(lái)了但它在圖像生成上展現(xiàn)出統(tǒng)治力還要再等五年。1.3 為什么它“起了個(gè)大早趕了個(gè)晚集”我2019年回頭看這篇2015年的論文時(shí)心里最大的疑問(wèn)就是為什么這么漂亮的想法沒(méi)有立刻引爆原因其實(shí)很現(xiàn)實(shí)。第一是算力2015年大規(guī)模訓(xùn)練圖像生成模型還很吃力。第二是優(yōu)化目標(biāo)太復(fù)雜當(dāng)時(shí)的實(shí)現(xiàn)包含一連串近似訓(xùn)練不穩(wěn)定。第三是高分辨率生成效果差在ImageNet和LSUN這種大規(guī)模數(shù)據(jù)集上它的表現(xiàn)遠(yuǎn)不如GAN那種眼花繚亂的結(jié)果。公平地說(shuō)沒(méi)有2015年這篇奠基之作就不會(huì)有后面一系列“做減法”式的改進(jìn)。后來(lái)的工作幾乎都在干同一件事把復(fù)雜的訓(xùn)練目標(biāo)簡(jiǎn)化把采樣過(guò)程加速把控制條件加進(jìn)來(lái)。DDPM之所以能成功本質(zhì)上就是因?yàn)樗?015年那套復(fù)雜目標(biāo)化簡(jiǎn)成了“預(yù)測(cè)噪聲”四個(gè)字。2. 現(xiàn)代擴(kuò)散模型的三個(gè)坐標(biāo)NCSN、DDPM與SDE統(tǒng)一2.1 NCSN用score matching估計(jì)“數(shù)據(jù)分布的梯度”2019年Yang Song和Stefano Ermon發(fā)表了NCSNNoise Conditional Score Network。他們的思路和DDPM那條線不同不直接建模數(shù)據(jù)分布p(x)而是估計(jì)數(shù)據(jù)分布的“分?jǐn)?shù)”——也就是對(duì)數(shù)似然關(guān)于輸入的梯度?x log p(x)。這相當(dāng)于告訴模型從當(dāng)前樣本出發(fā)往哪個(gè)方向調(diào)整能更快走到真實(shí)數(shù)據(jù)的高密度區(qū)域。有了這個(gè)分?jǐn)?shù)就可以用郎之萬(wàn)采樣Langevin dynamics從隨機(jī)噪聲開(kāi)始沿著梯度方向一步步“爬”到真實(shí)樣本附近。這里面有個(gè)關(guān)鍵工程細(xì)節(jié)直接估計(jì)高維空間里的分?jǐn)?shù)非常困難因?yàn)榈兔芏葏^(qū)域幾乎沒(méi)有數(shù)據(jù)估計(jì)方差會(huì)爆炸。他們的解法是引入多重噪聲擾動(dòng)。用一系列不同幅度的噪聲把數(shù)據(jù)“抹糊”在每個(gè)噪聲級(jí)別下分別估計(jì)分?jǐn)?shù)訓(xùn)練時(shí)隨機(jī)抽一個(gè)級(jí)別。這樣做的效果是模型先在“糊掉”的數(shù)據(jù)分布上找到大致方向再逐步收緊到真實(shí)分布這就是annealed Langevin dynamics的思路也是“噪聲條件得分網(wǎng)絡(luò)”這個(gè)名字的來(lái)源。NCSN與DDPM看起來(lái)是兩套完全不同的理論但后來(lái)證明它們其實(shí)是同一個(gè)硬幣的兩面。這個(gè)“統(tǒng)一”是2021年才完成的但對(duì)理解擴(kuò)散模型至關(guān)重要。2.2 DDPM把一切簡(jiǎn)化到“預(yù)測(cè)噪聲”2020年Jonathan Ho等人的DDPMDenoising Diffusion Probabilistic Models是整個(gè)擴(kuò)散模型蛻變的分水嶺。我到現(xiàn)在還記得第一次跑通DDPM訓(xùn)練腳本時(shí)的感受訓(xùn)練邏輯簡(jiǎn)單到難以置信。從數(shù)據(jù)里抽一張圖隨機(jī)抽一個(gè)時(shí)間步t隨機(jī)抽一個(gè)高斯噪聲把它加到圖上然后讓U-Net把這個(gè)噪聲預(yù)測(cè)出來(lái)算L2損失。E_t || ε - ε_(tái)θ(x_t, t)||2意思就是給定t時(shí)刻的噪聲圖x_t讓網(wǎng)絡(luò)去預(yù)測(cè)“剛剛加進(jìn)去的那個(gè)噪聲”本身而不是預(yù)測(cè)均值、方差。整個(gè)訓(xùn)練目標(biāo)不再需要復(fù)雜的ELBO近似一句話就能說(shuō)清楚。網(wǎng)絡(luò)結(jié)構(gòu)用了U-Net時(shí)間步t通過(guò)正弦位置編碼輸入配合EMA和混合精度訓(xùn)練。結(jié)果是在CIFAR-10和LSUN數(shù)據(jù)集上FID追平甚至反超同時(shí)期的GAN。這件事的意義非常大。它意味著擴(kuò)散模型不再是一個(gè)“看起來(lái)很理論”的存在而是一個(gè)任何有PyTorch基礎(chǔ)的人都能在幾天內(nèi)復(fù)現(xiàn)的算法。我記得當(dāng)時(shí)社區(qū)里很快出現(xiàn)了各種基于DDPM的改進(jìn)工作訓(xùn)練腳本也從一行行難懂的推導(dǎo)變成了一套標(biāo)準(zhǔn)流水線。從這時(shí)起擴(kuò)散模型正式進(jìn)入了主流實(shí)踐。2.3 SDE統(tǒng)一一轉(zhuǎn)眼兩個(gè)門(mén)派被收進(jìn)同一個(gè)框架2021年Song等人的《Score-Based Generative Modeling through Stochastic Differential Equations》把NCSN和DDPM統(tǒng)一到了一個(gè)連續(xù)時(shí)間視角下。這篇論文我反復(fù)讀過(guò)很多遍它的核心洞見(jiàn)是前向加噪過(guò)程可以看作一個(gè)從數(shù)據(jù)分布漂移到先驗(yàn)分布的隨機(jī)微分方程而逆向過(guò)程是另一個(gè)“時(shí)間反轉(zhuǎn)”的SDE只依賴于每個(gè)時(shí)刻的分?jǐn)?shù)。從這個(gè)視角看NCSN對(duì)應(yīng)的是一類方差爆發(fā)的SDEVE-SDEvariance explodingDDPM對(duì)應(yīng)的則是方差保持的SDEVP-SDEvariance preserving。換句話說(shuō)兩個(gè)看起來(lái)理論淵源不同的模型只是同一個(gè)連續(xù)過(guò)程的兩種不同離散化方式。這個(gè)統(tǒng)一帶來(lái)的實(shí)際價(jià)值有兩層。一是理論工具更強(qiáng)了可以用SDE求解器和概率流ODE來(lái)加速采樣DDIM采樣器可以看作概率流ODE的一種確定性離散化。二是后續(xù)很多改進(jìn)都建立在這個(gè)框架上“擴(kuò)散模型”從此不再特指某一篇論文而是一整個(gè)研究范式的名字。2.1、2.2和2.3這三條線合在一起構(gòu)成了現(xiàn)代擴(kuò)散模型的三個(gè)坐標(biāo)。理解它們之間的異同再看后面的LDM和Stable Diffusion會(huì)輕松很多。3. 從“能生成”到“生成得好”引導(dǎo)機(jī)制與工程技巧3.1 classifier guidance讓擴(kuò)散模型學(xué)會(huì)“指哪打哪”DDPM雖然能生成高質(zhì)量圖像但有一個(gè)致命短板不好控制內(nèi)容。你告訴它“我要一只貓”它不會(huì)聽(tīng)你的。2021年Dhariwal和Nichol那篇《Diffusion Models Beat GANs on Image Synthesis》戳中了這個(gè)痛點(diǎn)。他們?cè)诓蓸訒r(shí)引入一個(gè)分類器的梯度每一步除了按去噪網(wǎng)絡(luò)給出的方向走還額外疊加分類器關(guān)于輸入的梯度把樣本往“屬于目標(biāo)類別”的方向推一步。這個(gè)操作等價(jià)于在采樣過(guò)程中注入目標(biāo)類別的對(duì)數(shù)似然梯度。超參數(shù)guidance scale通常取1到10之間越大類別越一致但太大的話圖像會(huì)出現(xiàn)過(guò)飽和、不自然的偽影。這篇論文的另一個(gè)貢獻(xiàn)是證明只要把模型規(guī)模和訓(xùn)練策略做到位擴(kuò)散模型在FID這類指標(biāo)上能全面超過(guò)GAN。那年之后很多做生成的研究團(tuán)隊(duì)都開(kāi)始扭頭看擴(kuò)散方向。不過(guò)classifier guidance有個(gè)煩惱需要額外訓(xùn)練一個(gè)能在噪聲圖上工作的分類器訓(xùn)練成本不小。我當(dāng)時(shí)試過(guò)在ImageNet上訓(xùn)這個(gè)分類器前處理要處理不同噪聲級(jí)別的輸入工程上相當(dāng)啰嗦。所以沒(méi)過(guò)多久無(wú)分類器引導(dǎo)就把它取代了。3.2 classifier-free guidance把分類器扔掉條件反而更靈活Ho和Salimans提出的classifier-free guidance是擴(kuò)散模型歷史上最優(yōu)雅的一個(gè)小技巧。它的做法簡(jiǎn)單得令人吃驚訓(xùn)練條件擴(kuò)散模型時(shí)以一定概率比如10%把條件置空讓同一個(gè)模型既學(xué)會(huì)“看著條件去噪”又學(xué)會(huì)“不看條件去噪”。采樣時(shí)對(duì)兩種預(yù)測(cè)做外推ε? (1 w) * ε_(tái)cond ? w * ε_(tái)uncond其中ε_(tái)cond是有條件時(shí)的預(yù)測(cè)ε_(tái)uncond是條件置空時(shí)的預(yù)測(cè)w是引導(dǎo)強(qiáng)度。這個(gè)式子用起來(lái)極其靈活可以和文本、類別、布局、深度圖等任意條件組合而且不需要訓(xùn)練額外的分類器。后來(lái)幾乎所有文生圖模型——DALL-E 2、Imagen、Stable Diffusion——的默認(rèn)方案都是它。我自己的體會(huì)是classifier-free guidance讓“條件控制”這件事從“專門(mén)訓(xùn)練一個(gè)判別模型”變成了“同一個(gè)模型里摳出一部分參數(shù)”。工程上省了一大截效果還更好。唯一要注意的是訓(xùn)練時(shí)條件dropout的比例不能太大否則模型會(huì)過(guò)度忽略條件太小則無(wú)條件的預(yù)測(cè)不靠譜外推會(huì)失效。10%是一個(gè)普遍好用的默認(rèn)值。3.3 采樣提速與訓(xùn)練穩(wěn)定性從“1000步”到“幾十步”我最早用DDPM生成一張512x512圖像要跑滿1000步采樣一張圖要幾十秒放到服務(wù)里完全不可用。后來(lái)?yè)Q用DDIM在50步以內(nèi)就能得到幾乎不損失質(zhì)量的結(jié)果推理速度提升了一個(gè)量級(jí)。原理上DDIM對(duì)應(yīng)概率流ODE的確定性離散化去掉了朗之萬(wàn)采樣中的隨機(jī)項(xiàng)因此同樣步數(shù)下更穩(wěn)。再往后DPM-Solver和DPM這類基于ODE的采樣器進(jìn)一步把步數(shù)壓到10到20步。現(xiàn)在你打開(kāi)diffusers庫(kù)scheduler列表里有一堆選項(xiàng)最常用的就是PNDM、DDIM、DPM-Solver和Euler。如果你在部署文生圖服務(wù)我的建議是優(yōu)先用DPM-Solver配10到20步質(zhì)量、速度、穩(wěn)定性綜合最優(yōu)。訓(xùn)練穩(wěn)定方面EMA幾乎必須開(kāi)。EMA相當(dāng)于把歷史權(quán)重做了平滑會(huì)讓訓(xùn)練過(guò)程中的樣本質(zhì)量震蕩明顯下降。我自己在訓(xùn)練UNet時(shí)見(jiàn)過(guò)太多次“上一輪loss在降這一輪突然崩了”的情況開(kāi)EMA之后這種現(xiàn)象少很多。混合精度f(wàn)p16也是標(biāo)配但要注意梯度縮放和某些層在fp16下的數(shù)值穩(wěn)定性后面第6節(jié)我會(huì)把坑寫(xiě)細(xì)。4. 壓縮進(jìn)潛空間LDM與Stable Diffusion的“破圈”之路4.1 像素域擴(kuò)散為什么撐不起大規(guī)模應(yīng)用DDPM在64x64、128x128上很驚艷但要上512x512甚至1024x1024就非常吃力。原因很直接擴(kuò)散模型每一步都在處理“整個(gè)圖像張量”像素域維度高U-Net每一層的計(jì)算極其沉重顯存和算力都吃不消。而且文本條件要注入到每一層到了高分辨率計(jì)算量更是雪上加霜。一個(gè)自然的想法是不要直接在圖像空間做擴(kuò)散先拿一個(gè)自編碼器把圖像壓縮到低維潛空間只在潛空間里做去噪。這就是Latent Diffusion ModelsLDM潛在擴(kuò)散模型的核心思想。它來(lái)自Rombach等人2021年底提交的論文2022年在CVPR發(fā)表。這條路線直接促成了Stable Diffusion的出現(xiàn)。4.2 LDM三個(gè)組件與那個(gè)容易忽視的縮放系數(shù)LDM由三塊組成第一塊是感知壓縮自編碼器把512x512x3的圖像編碼成64x64x4的潛變量第二塊是一個(gè)U-Net擴(kuò)散模型在潛空間里完成加噪去噪第三塊是條件注入機(jī)制文本或其他模態(tài)通過(guò)交叉注意力cross-attention與U-Net的中間特征交互。訓(xùn)練分兩個(gè)階段先訓(xùn)自編碼器再固定編碼器訓(xùn)潛空間擴(kuò)散模型。因?yàn)闈摽臻g維度只有原來(lái)的差不多1/48擴(kuò)散模型跑起來(lái)輕松非常多也更容易擴(kuò)展到高分辨率。但我必須提醒一個(gè)很容易踩的坑潛空間的scale。訓(xùn)練LDM時(shí)一定要讓潛變量的標(biāo)準(zhǔn)差保持在一個(gè)合適范圍否則擴(kuò)散訓(xùn)練會(huì)不穩(wěn)定。官方實(shí)現(xiàn)里會(huì)對(duì)編碼器輸出乘一個(gè)縮放系數(shù)例如Stable Diffusion v1.x里大約是0.18215目的就是讓潛空間分布接近標(biāo)準(zhǔn)正態(tài)。很多復(fù)現(xiàn)LDM的人忘了這一層loss雖然能降但生成的圖總是發(fā)糊。4.3 從LDM到Stable Diffusion再到整個(gè)AIGC生態(tài)Stable Diffusion其實(shí)就是LDM在文本生成圖像場(chǎng)景下的開(kāi)放版本。2022年8月開(kāi)源之后擴(kuò)散模型的能力被釋放到了整個(gè)社區(qū)后面長(zhǎng)出來(lái)一整棵技術(shù)樹(shù)LoRA用少量數(shù)據(jù)微調(diào)風(fēng)格ControlNet用深度圖、邊緣圖做結(jié)構(gòu)控制DreamBooth做個(gè)性化定制以及各種基于SD的插件式工作流??梢哉f(shuō)沒(méi)有LDM把擴(kuò)散模型從像素域搬到潛空間以當(dāng)時(shí)的GPU算力全球用戶“人人能跑文生圖”根本不可能。印象最深的是SD剛開(kāi)源那陣一臺(tái)消費(fèi)級(jí)顯卡用fp16就能出圖這在一年前根本不敢想。這背后是潛空間壓縮、U-Net降采樣、classifier-free guidance三者合力的結(jié)果。你要理解現(xiàn)在的擴(kuò)散模型生態(tài)LDM這條線索是必須吃透的。5. 擴(kuò)散模型的新戰(zhàn)場(chǎng)新視角合成與3D內(nèi)容生成5.1 新視角合成是什么任務(wù)為什么需要擴(kuò)散模型新視角合成粗淺來(lái)說(shuō)就是“給你一張或幾張同一個(gè)物體的照片你幫我畫(huà)出從另一個(gè)角度看它是什么樣子”。傳統(tǒng)做法依賴多視圖幾何和NeRF這類神經(jīng)渲染需要采集大量多視角照片再用體渲染顯式重建3D場(chǎng)景。但如果只給你一張圖怎么猜出背面長(zhǎng)什么樣這是一個(gè)極度不適定的問(wèn)題必須依靠先驗(yàn)知識(shí)。擴(kuò)散模型的價(jià)值正在于它是一個(gè)極其強(qiáng)大的圖像先驗(yàn)。2022年底的Zero-1-to-3做了一件非常直觀的事把輸入圖像和一個(gè)相對(duì)相機(jī)位姿變化旋轉(zhuǎn)矩陣加平移向量一起作為條件訓(xùn)練擴(kuò)散模型去生成新視角下的畫(huà)面。推理時(shí)給定一張圖和一個(gè)目標(biāo)姿態(tài)模型直接輸出對(duì)應(yīng)視角圖像不需要測(cè)試時(shí)的任何優(yōu)化也不需要場(chǎng)景重建。擴(kuò)展到廣義場(chǎng)景時(shí)同一個(gè)物體只要見(jiàn)過(guò)足夠多角度的訓(xùn)練數(shù)據(jù)它就能生硬地“腦補(bǔ)”出背后的樣子。我把這個(gè)例子放在這里是因?yàn)樗抢斫狻皵U(kuò)散模型不只是文生圖”的最好入口。它的條件不是文本而是“相機(jī)變換”它的輸出不是“符合文本的圖”而是“符合視角變化的圖”。同一個(gè)生成底座換一個(gè)條件編碼方式就變成另一個(gè)任務(wù)。5.2 從2D擴(kuò)散到3D生成SDS loss與可微渲染結(jié)合比新視角合成更進(jìn)一步的是直接從文本或單張圖生成完整3D模型。2022年的DreamFusion提出了Score Distillation SamplingSDS。它的思路是用一個(gè)預(yù)訓(xùn)練2D擴(kuò)散模型當(dāng)“視覺(jué)先驗(yàn)”監(jiān)督一個(gè)可微渲染的3D表示通常是NeRF一類。每次迭代從當(dāng)前3D表示渲染一幅圖把圖加噪后丟給擴(kuò)散模型估計(jì)分?jǐn)?shù)得到“渲染圖和目標(biāo)語(yǔ)義之間差異”的梯度再反向傳播去優(yōu)化3D參數(shù)。本質(zhì)上擴(kuò)散模型被當(dāng)成一個(gè)無(wú)所不知的圖像先驗(yàn)用它把2D生成能力“蒸餾”進(jìn)3D表達(dá)。后來(lái)很多工作都沿著這條路走用SD做先驗(yàn)、用LoRA控制風(fēng)格、用SDS加各種正則約束幾分鐘就能從文本生成一個(gè)可以環(huán)繞查看的3D模型。雖然它在幾何精度上不如傳統(tǒng)三維重建但那種“從無(wú)到有創(chuàng)造3D資產(chǎn)”的能力對(duì)游戲、影視、電商行業(yè)的影響是實(shí)打?qū)嵉摹?.3 視角合成與3D生成其實(shí)是同一套零件值得玩味的是這兩個(gè)方向底層用的是同一套零件預(yù)訓(xùn)練擴(kuò)散模型、相機(jī)姿態(tài)表示以及把擴(kuò)散先驗(yàn)和可微渲染結(jié)合的數(shù)學(xué)框架。區(qū)別只在于任務(wù)是“預(yù)測(cè)圖像”還是“優(yōu)化三維表示”。這種“換任務(wù)不換框架”的特性讓擴(kuò)散模型成為通用生成底座。如果你已經(jīng)會(huì)用diffusers、理解了U-Net和cross-attention那再往新視角合成、SDS訓(xùn)練走并沒(méi)有想象中那么高的門(mén)檻。6. 動(dòng)手實(shí)踐把擴(kuò)散模型跑起來(lái)以及我踩過(guò)的那些坑6.1 環(huán)境準(zhǔn)備diffusers一行安裝理論聊完落地才是硬道理。Hugging Face的diffusers是目前最省事的起點(diǎn)。建議環(huán)境是Python 3.10、PyTorch 2.x、CUDA 11.8以上。安裝就一行pip install diffusers transformers accelerate想直接體驗(yàn)Stable Diffusion的話官方代碼少得感人from diffusers import StableDiffusionPipeline import torch pipe StableDiffusionPipeline.from_pretrained( runwayml/stable-diffusion-v1-5, torch_dtypetorch.float16 ).to(cuda) image pipe(a cat sitting on a windowsill, golden hour).images[0] image.save(cat.png)第一次運(yùn)行會(huì)下載權(quán)重建議保留好本地緩存。需要注意的是fp16推理會(huì)比f(wàn)p32快不少顯存占用也少一大截但某些顯卡上輸出會(huì)偶發(fā)黑色圖片多半是精度或緩存問(wèn)題。6.2 自己訓(xùn)練一個(gè)最小DDPM如果不想只當(dāng)使用者可以跑一個(gè)極小的DDPM訓(xùn)練。diffusers官方示例腳本train_unconditional.py就是干這個(gè)的accelerate launch train_unconditional.py \ --dataset_name hf-internal-testing/demo_image_dataset \ --output_dir ddpm-demo \ --train_batch_size 16 \ --num_epochs 50 \ --mixed_precision fp16 \ --learning_rate 1e-4腳本會(huì)自動(dòng)把圖片縮放并歸一化到[-1,1]。默認(rèn)用的線性beta schedule是從0.0001到0.02共1000步。這個(gè)區(qū)間為什么這么選太小的話前向加噪不夠反向?qū)W不到東西太大則一步噪聲就把信號(hào)蓋掉網(wǎng)絡(luò)難以還原。這組數(shù)值是DDPM論文里反復(fù)試出來(lái)的后來(lái)模型喜歡用cosine schedule曲線更平緩實(shí)測(cè)更穩(wěn)。如果你想加classifier-free guidance需要在訓(xùn)練腳本里做兩件事第一把條件用一個(gè)embedding層編碼第二在喂條件時(shí)按照10%的概率隨機(jī)置零。采樣時(shí)再按那個(gè)外推公式算最終預(yù)測(cè)。我自己踩過(guò)一次坑條件dropout概率設(shè)了30%模型學(xué)出來(lái)的無(wú)條件分支過(guò)于強(qiáng)勢(shì)導(dǎo)致帶條件分支被壓制生成圖像和文本對(duì)不上。這個(gè)比例不是越大越好。6.3 常見(jiàn)問(wèn)題排查速查表我把訓(xùn)練和部署擴(kuò)散模型時(shí)最常見(jiàn)的幾個(gè)問(wèn)題整理成了一張表癥狀可能原因解決辦法loss發(fā)散或出現(xiàn)NaN學(xué)習(xí)率過(guò)大或fp16未正確使用梯度縮放把學(xué)習(xí)率降到1e-4以下開(kāi)啟默認(rèn)的GradScaler生成圖像全灰或全是噪聲未開(kāi)EMA或訓(xùn)練步數(shù)太少開(kāi)啟EMA拉長(zhǎng)訓(xùn)練時(shí)間樣本質(zhì)量高但多樣性差guidance scale過(guò)高或采樣步數(shù)太少把w降到7.5附近用DDIM或DPM-Solver跑20步圖像出現(xiàn)紫綠噪點(diǎn)偽影fp16下U-Net的GroupNorm精度不穩(wěn)關(guān)鍵層回退fp32或直接使用bf16512x512訓(xùn)練顯存溢出batch size過(guò)大減小batchsize用梯度累積或改用LDM潛空間路線還有一個(gè)非常實(shí)用的經(jīng)驗(yàn)訓(xùn)練的時(shí)候最好每次驗(yàn)證采樣都使用EMA權(quán)重。帶EMA的權(quán)重通常比當(dāng)前step的權(quán)重穩(wěn)定得多很多官方checkpoint其實(shí)都是EMA版本。我自己跑實(shí)驗(yàn)時(shí)會(huì)在每個(gè)epoch末尾用同一組隨機(jī)種子對(duì)比“當(dāng)前權(quán)重”和“EMA權(quán)重”的輸出效果差距肉眼可見(jiàn)。6.4 一點(diǎn)實(shí)操心得我在剛接觸擴(kuò)散模型時(shí)最痛苦的不是看不懂公式而是“理論框架”和“訓(xùn)練手感”之間總是對(duì)不上。后來(lái)發(fā)現(xiàn)最好的學(xué)習(xí)路徑是倒著來(lái)的先跑通一個(gè)最小demo再一步步把加噪、去噪、引導(dǎo)、潛空間這些概念對(duì)應(yīng)到代碼里。等你把DDPM訓(xùn)練腳本從外到內(nèi)改過(guò)一遍再回頭看LDM、SDS這些進(jìn)階方向基本就是順?biāo)浦?。如果你只是做效果演示我勸你別一上來(lái)就復(fù)刻完整LDM訓(xùn)練——那需要多階段訓(xùn)練和大算力。合適的路徑是先在小數(shù)據(jù)集上把DDPM訓(xùn)通再用diffusers里的SD做微調(diào)。擴(kuò)散模型這十年走過(guò)的路其實(shí)就是在反復(fù)證明一件事把一個(gè)簡(jiǎn)單的想法做到極致比一開(kāi)始就追求復(fù)雜更管用。