cv.cm

AI · AI 基礎

擴散模型(Diffusion Model)是怎麼運作的?

閱讀約 9 分鐘

簡答

擴散模型學的是去除雜訊。訓練時,真實圖片會被一步步加上隨機雜訊,神經網路則學著預測那些雜訊。生成時,模型從純雜訊出發,在你的文字提示詞引導下,每一步去除一點點雜訊,直到出現乾淨的圖片。大多數圖片和影片生成器都是這樣運作。

一句話說明:先學會清除雜訊,再去清理純雜訊

想像你拿一張照片,加上一點隨機的雜訊,再加一點,一直加下去,經過幾百步之後,畫面只剩下灰色的雪花。這個方向很容易,電腦只要一行數學式就能做到。

擴散模型是一個神經網路,訓練它走相反的方向:看著一張有雜訊的圖片,估計被加進去的雜訊是什麼,好把它減掉。如果網路在每個雜訊程度上都做得夠好,你就能從純隨機雜訊出發,一步步把它清乾淨。最後留下的,是一張從未存在過、卻像是屬於訓練資料的新圖片。

這個概念在 2015 年就被提出,2020 年的論文《Denoising Diffusion Probabilistic Models》(DDPM)才讓它實際應用在高品質圖像上。撰文當下,Stable Diffusion、FLUX、Imagen、DALL·E 一類的模型,以及 Veo、Kling、Runway、Seedance 等多數影片生成器,都是建立在這一類方法或其近親之上。

訓練:前向過程與雜訊預測器

訓練使用數百萬張圖片,每張都配有一段說明文字。對每個訓練範例,系統都做同樣的小練習:

  1. 挑一張真實圖片和它的說明文字,例如一張標註為「靠在磚牆上的紅色腳踏車」的照片。
  2. 隨機挑一個雜訊程度,從幾乎乾淨到幾乎全是雜訊都有可能。
  3. 依照那個程度,把圖片與隨機雜訊混合。這就是前向過程,不需要學習。
  4. 把有雜訊的圖片、雜訊程度和說明文字交給網路,要它預測被加入的雜訊。
  5. 把預測結果與真正的雜訊比較,調整網路的權重來減少誤差。

這樣重複數十億次,網路就學會了圖像在各種模糊程度下一般長什麼樣子:邊緣通常在哪裡、光線如何落在皮膚上、腳踏車和磚牆是什麼模樣。它並不會把訓練照片當成檔案存起來,而是學到關於這些照片的統計規律,這也是它能把從沒見過的概念混搭在一起的原因。

網路本身過去多半是 U-Net,一種圖像網路。許多較新的模型改用 Transformer(常稱為擴散 Transformer)。近期也有些模型用流匹配(flow matching)訓練,這是一種相近的方法,學的是從雜訊到圖像的一條直線路徑。下面談到使用者會接觸的概念,兩者都一樣。

生成:反向過程,一次一步

按下「生成」之後,模型不是在畫線,也不是把零件拼貼起來,而是在跑一個迴圈:

x = random_noise(seed)                  # start: pure static
for t in noise_levels_high_to_low:      # e.g. 30 steps
    predicted_noise = model(x, t, prompt)
    x = remove_some_noise(x, predicted_noise, t)
image = decode(x)                       # latent -> pixels

前期的步驟決定大的形狀:主體在哪裡、地平線、主要色彩。中期的步驟加入形體與光影。後期的步驟加入細緻的質感,例如頭髮、布料和皮膚毛孔。這能解釋幾個實際現象:步數調得太低,圖片會顯得平滑、沒做完;換了種子,起始雜訊不同,整個構圖就會改變。

把雜訊預測變成一張稍微乾淨的圖片的規則,稱為取樣器(sampler)或排程器(scheduler)。DDPM 用的是很多個小步驟;後來的 DDIM 等方法證明,可以走更大步、結果固定的步伐,用少得多的步數得到相近的品質。這就是現代工具只需要幾十步,而不是一千步的原因。

文字提示詞如何引導圖片

提示詞會先由文字編碼器轉成數字,那是一個專門訓練來表示說明文字語意的語言模型。在去噪網路內部,一種叫做交叉注意力(cross-attention)的機制,讓圖像的每個區域在每一步都能「看」提示詞中的字詞。正要變成臉孔的區域,就會注意「雀斑」或「微笑」這類詞。

光靠這樣,引導的力道很弱。無分類器引導(classifier-free guidance)能讓它更強:每一步,模型會預測兩次雜訊,一次帶著你的提示詞,一次用空白提示詞,最後的預測再朝兩者差異的方向多走一段。引導強度(通常稱為 CFG scale)決定多走多遠。數值較高,會更貼近提示詞,但畫面可能顯得生硬、過度飽和;數值較低,看起來更自然,但可能忽略提示詞的某些部分。

負面提示詞(negative prompt,工具有支援的話)通常會取代第二次預測中的空白提示詞,讓圖片遠離這些詞,例如「模糊、浮水印、多餘的手指」。

為什麼大多數模型在潛在空間運作

要在完整解析度的圖片上去噪幾百次,速度會很慢。潛在擴散(latent diffusion,Stable Diffusion 背後的方法)先訓練一個自編碼器,把圖片壓縮成小得多的數字網格,也能再展開還原。擴散模型接著只處理這個小網格。例如每邊壓縮 8 倍,512×512 的圖片會變成 64×64 的網格,要處理的位置少了 64 倍。

每次生成的最後一步是解碼器,它把清理乾淨的潛在網格轉回像素。當圖片出現奇怪的色塊,或小臉孔看起來糊掉時,解碼器的壓縮往往是原因之一,這也是為什麼主體在畫面中占的比例越大,臉孔和小字就越清楚。

影片擴散用的是相同的概念,再加上時間:潛在空間是一疊影格,網路對它們一起去噪,讓動作在影格之間保持一致。

常見設定實際改變了什麼

大多數生成器都會開放其中一些控制項。名稱各異,機制卻相同:

設定控制的內容實際效果
種子(Seed)起始雜訊相同種子、相同提示詞、相同設定會得到相同圖片。想看新的構圖就換種子。
步數(Steps)去噪的次數太少會顯得柔軟、沒完成。超過某個程度後,增加步數只會多花時間,品質提升有限。
引導強度 / CFG scale提示詞被強制執行的力道越高越貼近提示詞,但可能顯得生硬;越低越自然,但容易偏離。
取樣器 / 排程器每一步的規則改變速度與細緻質感。測試其他設定時,請固定同一個取樣器。
負面提示詞要讓圖片遠離的內容適合用來消除反覆出現的瑕疵。寫很長的清單通常沒有幫助。
強度(圖生圖)對輸入圖片加入多少雜訊低就保留你的版面,高則只保留大概的概念。
解析度 / 長寬比潛在網格的大小和訓練尺寸差太多,可能造成主體重複或身體被拉長。

好的測試方法是固定種子,一次只改一個設定。不然你無法分辨,圖片變好是你調整的結果,還是單純運氣好。

擴散模型與其他生成圖片的方式

擴散並不是唯一的方法。自迴歸模型把圖片當成一串 token,一個接一個生成,就像語言模型寫文字一樣,近期有些多模態模型就採用這種做法。例如 cv.cm 的 ai-image-generator,是透過 WebGPU 在你的瀏覽器裡本機執行 Janus-Pro-1B 這個自迴歸模型,輸出 384 像素的圖片。它的設定用起來感覺不同:沒有擴散模型意義上的步數可以調整。

較早的 GAN(生成對抗網路)一次就能生成一張圖,速度很快,但更難訓練,變化也較少。擴散之所以成為主流,是因為訓練穩定,且涵蓋的圖像範圍廣。它主要的代價是速度,因為每張圖都需要網路運算許多次。蒸餾模型把步數減到寥寥幾步,代價是多樣性有所損失。

常見弱點與因應方式

  • 手與手指:手的姿勢千變萬化,在訓練照片中又常被遮住一部分,模型學到的是一個模糊的平均值。可以要求簡單、清楚可見的手勢,或之後再用局部重繪修補手部。
  • 圖片中的文字:模型學到的是字母的形狀,而不是拼寫。新模型已經好很多,但請讓文字盡量簡短,在提示詞中用引號括起來,並逐字檢查。重要的文字,建議事後在編輯器裡加上。
  • 計數:「五顆蘋果」常常變成四顆或六顆。物件越少越可靠。
  • 提示詞滲漏:顏色與屬性在主體之間互相影響,例如紅色帽子讓襯衫也變紅。請用一個清楚的短句分別描述每個主體,或是分開生成。
  • 複製:模型有時會產生與知名或被大量重複的圖片非常接近的複本。如果需要原創作品,請避免在提示詞中使用藝術家姓名或品牌角色。

常見問題

Stable Diffusion 和擴散模型是同一件事嗎?

不是。擴散模型是通用的方法,Stable Diffusion 則是採用潛在擴散的一個特定的開放模型系列。許多其他生成器也使用擴散。

為什麼同一個提示詞每次生成的圖片都不一樣?

每次生成都從不同的隨機雜訊開始,由種子決定。如果固定種子,並讓其他設定都保持一致,在同一套軟體上就會得到相同的圖片。

擴散模型會儲存訓練圖片的複本嗎?

它儲存的是學習到的權重,而不是圖片檔案。不過研究顯示,部分訓練圖片可以被幾乎完全還原出來,尤其是知名或被大量重複的圖片,所以在少數情況下確實可能出現近似複製。

為什麼 AI 生成圖片需要好幾秒?

擴散模型每一步都要執行一次龐大的網路,每張圖往往要跑幾十次。較快的模型被訓練成只需較少的步數,在壓縮的潛在空間中運作也能節省時間。

CFG scale 設多少比較好?

視模型而定。許多較早期的模型在範圍中段附近效果不錯,有些蒸餾模型則需要非常低的引導強度。建議先用工具的預設值,固定種子,再以小幅度調整。

全部 AI 教學