Distillation:讓快的學生學會慢的老師
第 9 章用更好的數值解法加速取樣,但再好的解法也還是要一步一步積分。這一章換一條路:假設手上已經有一個訓練好的 diffusion model(老師),另外訓練一個學生,讓它用一步或幾步就做出老師要幾十、幾百步才做得到的事。學生要學的東西有兩種選擇:學老師的分佈(只要生成的樣本整體像老師的就好,代表方法是 VSD,梯度剛好是兩個 score 的差),或學老師的 flow map(每個雜訊點要送到老師送去的同一個地方,代表方法是 Progressive Distillation,每一輪把兩個老師步併成一個學生步)。
讀完這頁你應該能夠
- 分辨兩種蒸餾目標:老師的分佈,以及老師從一個狀態到另一個狀態的 flow map。
- 說明分佈層級的蒸餾:學生透過 score 的監督,去對齊老師在各個雜訊等級的邊際分佈;推出 VSD 的梯度,並說明為什麼 reverse KL 在這裡特別方便。
- 說明 flow map 層級的蒸餾:學生學老師產生的轉移;推出 Progressive Distillation 的「兩步合一」目標,以及每一輪把步數減半的流程。
- 把 KD 和 PD 放進同一個 flow map 學習的損失框架,看出下一章要處理的問題:能不能不要老師。
前置知識
- B25:DDIM 的資料預測形式 \(\mathbf x_t=\frac{\sigma_t}{\sigma_s}\mathbf x_s+\alpha_s\big(\frac{\alpha_t}{\alpha_s}-\frac{\sigma_t}{\sigma_s}\big)\hat{\mathbf x}_0\)。PD 整套建立在這一行上。
- B16:四種預測(\(\bm\epsilon\)、\(\mathbf x\)、score、速度)的互換,以及 Tweedie 公式 \(\mathbf x_{\bm\phi^\times}(\mathbf x_t,t)\approx\mathbb E[\mathbf x_0\mid\mathbf x_t]\)。
- B06:denoising score matching(DSM),VSD 用它學學生的 score。
- B01:f-divergence 的定義;B21:classifier-free guidance(CFG)。
「書 §」標出原文位置。灰框「轉述者補充」是書裡沒有的內容;藍框「推導」展開書中省略的步驟。
01為什麼要蒸餾書 第 10 章開頭、§10.1
這一章介紹 training-based 的加速方法:訓練新的生成器,讓它只用一步或幾步就產生樣本。核心想法叫 distillation(蒸餾):讓一個快的學生模型,向一個慢的、預訓練好的 diffusion model 取樣器(老師)學習。老師可能要幾百步,學生用幾步就能達到差不多的品質。這裡的「蒸餾」指的是減少取樣步數,不是縮小模型。它和第 9 章的解法不同:解法改進的是數值積分的格式,蒸餾則直接訓練一個會走捷徑的生成器。
diffusion model 的主要瓶頸是取樣慢。為什麼不能直接一步生成?由 Tweedie 公式(B16),diffusion model 可以看成一個「\(\mathbf x\) 預測」模型 \(\mathbf x_{\bm\phi^\times}(\mathbf x_t,t)\),訓練來從帶雜訊的 \(\mathbf x_t\) 還原期望的乾淨資料:
$$\mathbf x_{\bm\phi^\times}(\mathbf x_t,t)\approx\mathbb E[\mathbf x_0\mid\mathbf x_t],$$期望是對 \(p(\mathbf x_0\mid\mathbf x_t)\) 取的,也就是所有和 \(\mathbf x_t\) 相容的乾淨資料。很自然會想直接拿 \(\mathbf x_{\bm\phi^\times}(\mathbf x_t,t)\) 一步生成。但這個 denoiser 是對許多可能的結果取平均,預測會過度平滑;只用幾步去噪,得到的是模糊、低品質的樣本。
另一方面(B08–B10),diffusion 取樣沿著一條 ODE 或 SDE 軌跡走很長一串反覆的步驟。這給出高保真的樣本,但反覆的神經網路計算讓取樣很貴。對 \(n\) 階的確定性 ODE 解法,在標準的正則性假設下,局部截斷誤差是 \(\mathcal O(h^{n+1})\),固定時間區間上的全域離散化誤差是 \(\mathcal O(h^n)\),其中 \(h=\max_i|t_i-t_{i-1}|\)。所以對固定的學到的向量場,格點越粗,數值誤差一般越大;不過樣本品質不一定隨步數單調變化。這就形成取樣準確度和計算成本之間的取捨。
蒸餾是克服這個瓶頸的一條主要路線:假設有一個訓練好的 diffusion model(老師),訓練一個生成器(學生)用一次前向計算或少數幾步重現老師的行為。這樣就把老師的許多取樣步壓縮成一個快速的過程,繞過慢的反覆解法,同時保持高品質。
「取平均」會差到什麼程度(轉述者補充)
看最極端的情況。如果時程在 \(t=T\) 剛好 \(\alpha_T=0\)(例如 Demo C 用的 cosine 時程 \(\alpha_t=\cos(\pi t/2)\)),那 \(\mathbf x_T=\bm\epsilon\) 和資料完全無關,所以 \(\mathbb E[\mathbf x_0\mid\mathbf x_T]=\mathbb E[\mathbf x_0]\):不管起點是哪個雜訊,理想老師的一步 DDIM 都輸出同一個點,也就是資料的平均。Demo C 會量到這件事:學到的老師一步 DDIM,所有樣本都擠在資料平均附近的一小段,而蒸餾過的一步學生可以生成兩個峰。
下面介紹兩種觀點:分佈層級的蒸餾和 flow map 層級的蒸餾。按時間順序,flow map 層級的方法比較早:Knowledge Distillation(KD,Luhman & Luhman 2021)和 Progressive Distillation(PD,Salimans & Ho 2022),分佈層級的方法大約在 2023 年才出現。書為了敘述順暢、也為了接到下一章,先講分佈層級。
02分佈層級的蒸餾書 §10.1.1
目標是訓練一個一步生成器 \(\mathbf G_{\bm\theta}(\mathbf z)\),把雜訊 \(\mathbf z\sim p_{\text{prior}}\) 送到樣本 \(\hat{\mathbf x}=\mathbf G_{\bm\theta}(\mathbf z)\),它誘導的分佈 \(p_{\bm\theta}(\hat{\mathbf x})\) 要近似資料分佈 \(p_{\text{data}}\)。通常的做法是最小化某個統計散度(例如 KL):
$$\min_{\bm\theta}\ \mathcal D\big(p_{\bm\theta},\,p_{\text{data}}\big).$$實務上,分佈層級的方法把生成器的分佈對齊到預訓練 diffusion model 產生的分佈 \(p_{\bm\phi^\times}\),用它當 \(p_{\text{data}}\) 的替身:
$$\min_{\bm\theta}\ \mathcal D\big(p_{\bm\theta},\,p_{\bm\phi^\times}\big).$$這些方法不直接計算這個散度,而是用預訓練的老師,加上從學生當前分佈估出來的量,構造散度梯度的可計算估計。對以 KL 為基礎的分佈匹配,這個梯度的形式是學生 score 和目標 score 的差。這樣就透過分佈對齊,把 diffusion model 的多步生成過程蒸餾成一步模型;第 4–6 節詳述。
03Flow map 層級的蒸餾書 §10.1.2
考慮 PF-ODE。依 B16,它可以用任何一種預測寫出來:
$$\frac{d\mathbf x(\tau)}{d\tau}=f(\tau)\mathbf x(\tau)-\tfrac12g^2(\tau)\nabla_{\mathbf x}\log p_\tau(\mathbf x(\tau))=:\mathbf v^*(\mathbf x(\tau),\tau).$$從時間 \(s\) 的 \(\mathbf x_s\) 出發、反向走到時間 \(t\le s\) 的解映射(flow map)記成 \(\bm\Psi_{s\to t}(\mathbf x_s)\):
積分沿 PF-ODE 的解。直觀地說,\(\bm\Psi_{s\to t}\) 把時間 \(s\) 的雜訊 \(\mathbf x_s\) 運到雜訊較少的狀態(最後在 \(t=0\) 變成資料)。從 diffusion model 取樣就是對 \(\mathbf x_T\sim p_{\text{prior}}\) 計算 \(\bm\Psi_{T\to0}(\mathbf x_T)\)。通常這個積分用反覆的數值解法近似(第 9 章),但需要很多步(即使是 DPM-Solver 也至少要 10–20 次 NFE),比 GAN 這類經典的一步生成模型慢。這引出一個自然的問題:
Trajectory distillation
Trajectory distillation 要訓練一個神經生成器,在個別樣本的層級近似解映射。因為 PF-ODE 的積分很少有閉式,訓練時必須用數值方法近似。記號上用
$$\mathtt{Solver}_{s\to t}(\mathbf x_s;\bm\phi^\times)\quad\text{或簡寫成}\quad\mathtt{Solver}_{s\to t}(\mathbf x_s)$$表示從 \(\mathbf x_s\) 出發、用老師參數 \(\bm\phi^\times\) 把 empirical PF-ODE 從 \(s\) 數值積分到 \(t\)。
早期做法:直接的 Knowledge Distillation
要做到少步甚至一步生成,最直接的方法是訓練生成器 \(\mathbf G_{\bm\theta}(\mathbf x_T,T,0)\) 去模仿數值解法沿整條軌跡得到的輸出:\(\mathbf G_{\bm\theta}(\mathbf x_T,T,0)\approx\mathtt{Solver}_{T\to0}(\mathbf x_T)\),\(\mathbf x_T\sim p_{\text{prior}}\)。這是最早的 trajectory distillation 方法之一 Knowledge Distillation(Luhman & Luhman 2021)的想法,用回歸損失:
$$\mathcal L_{\text{KD}}(\bm\theta):=\mathbb E_{\mathbf x_T\sim p_{\text{prior}}}\big\|\mathbf G_{\bm\theta}(\mathbf x_T,T,0)-\mathtt{Solver}_{T\to0}(\mathbf x_T)\big\|_2^2.$$它直接從預訓練的老師得到監督,但有三個缺點:
- 它用不到原始訓練資料裡的強監督。
- 如果在訓練迴圈裡呼叫 ODE 積分,計算很貴:每次參數更新都要解 ODE 來產生目標。
- 生成器只學了從 \(T\) 到 0 的整體映射,可能失去從中間狀態操控生成的能力,所以第 8 章的大部分可控生成技巧不能直接套用。
Progressive Distillation 預告
Progressive Distillation(PD,Salimans & Ho 2022)用老師片段的局部監督,訓練一個以時間為條件的 \(\mathtt{Student}\)。取固定的時間格點 \(t_0=T>t_1>\cdots>t_N=0\),老師提供單步映射 \(\mathtt{Teacher}_{t_k\to t_{k+1}}\),\(k=0,\dots,N-1\)。PD 不只監督 \(T\to0\) 一跳,而是讓學生的「跳兩格」映射去匹配老師連續兩步:
$$\mathtt{Student}_{t_k\to t_{k+2}}\approx\mathtt{Teacher}_{t_{k+1}\to t_{k+2}}\circ\mathtt{Teacher}_{t_k\to t_{k+1}},\qquad k=0,2,4,\dots$$匹配用簡單的回歸損失(例如均方誤差)。用局部配對的片段訓練完之後,學生不再走原格點的每一格,而是每隔一點前進:\(t_0\to t_2\to t_4\to\cdots\to t_N\),每個學生步等於老師的兩步,用 \(N/2\) 次轉移走完同樣的 \([0,T]\)。這一階段結束後,訓練好的學生取代老師成為新的參考模型,整個程序在更粗的格點上重複,步長加倍(\(N\to N/2\to N/4\to\cdots\)),逐步把軌跡蒸餾成越來越少的步數,直到達到想要的推論步數。這種反覆減半保留了整個時間範圍,同時不斷壓縮生成過程的時間解析度。
Flow map 學習的統一觀點
KD、PD 等各種方法都可以放進同一個損失框架:
\(\bm\Psi_{s\to t}\) 是 oracle 的 flow map,\(w(s,t)\ge0\) 決定不同時間對 \((s,t)\) 的權重,\(d(\cdot,\cdot)\) 是差異度量,例如 \(\|\mathbf x-\mathbf y\|_2^2\) 或 \(\|\mathbf x-\mathbf y\|_1\),\(p_s\) 是正向加噪在時間 \(s\) 的邊際分佈。因為 \(\bm\Psi_{s\to t}\) 沒有閉式,必須靠近似,通常是預訓練的 diffusion model(老師)或其他可計算的替代品。
KD 是只看端點對 \((s,t)=(T,0)\) 的特例,等價於取退化的權重 \(w(s,t)=\delta(s-T)\delta(t)\)。假設 \(p_T=p_{\text{prior}}\)(時程在 \(T\) 剛好到達先驗分佈時成立;否則 \(T\) 夠大時 \(p_T\approx p_{\text{prior}}\)),oracle 目標變成
$$\mathbb E_{\mathbf x_T\sim p_T}\big\|\mathbf G_{\bm\theta}(\mathbf x_T,T,0)-\bm\Psi_{T\to0}(\mathbf x_T)\big\|_2^2\approx\mathcal L_{\text{KD}}(\bm\theta),$$實際的 KD 目標用 \(\mathtt{Solver}_{T\to0}\approx\bm\Psi_{T\to0}\) 取代 oracle 的 flow map。
另一個看法:KD 也可以寫成從任意 \(s\) 出發(書 附錄 D.5.1)
從 oracle KD 損失 \(\mathcal L^{\text{oracle}}_{\text{KD}}(\bm\theta)=\mathbb E_{\mathbf x_T\sim p_T}\|\mathbf G_{\bm\theta}(\mathbf x_T,T,0)-\bm\Psi_{T\to0}(\mathbf x_T)\|_2^2\) 出發,\(p_T=p_{\text{prior}}\)。確定性的 ODE flow map 滿足半群性質,沿軌跡是雙射,所以邊際分佈滿足推前(pushforward)恆等式
$$p_t=\bm\Psi_{0\to t}\sharp\,p_{\text{data}}=\bm\Psi_{T\to t}\sharp\,p_{\text{prior}}.$$因此 \(\bm\Psi_{s\to T}\sharp\,p_s=p_T\),而且 \(\bm\Psi_{T\to0}\circ\bm\Psi_{s\to T}=\bm\Psi_{s\to0}\)。做變數變換 \(\mathbf x_T=\bm\Psi_{s\to T}(\mathbf x_s)\)、\(\mathbf x_s\sim p_s\):
$$\mathcal L^{\text{oracle}}_{\text{KD}}(\bm\theta)=\mathbb E_{\mathbf x_s\sim p_s}\big\|\mathbf G_{\bm\theta}\big(\bm\Psi_{s\to T}(\mathbf x_s),T,0\big)-\bm\Psi_{s\to0}(\mathbf x_s)\big\|_2^2.$$定義「拉回的學生」\(\widetilde{\mathbf G}_{\bm\theta}(\mathbf x_s,s,0):=\mathbf G_{\bm\theta}(\bm\Psi_{s\to T}(\mathbf x_s),T,0)\),同一個損失就寫成統一框架在 \(t=0\) 的形式:\(\mathbb E_{\mathbf x_s\sim p_s}\|\widetilde{\mathbf G}_{\bm\theta}(\mathbf x_s,s,0)-\bm\Psi_{s\to0}(\mathbf x_s)\|_2^2\)。這個推導只用到透過 oracle flow 的變數變換和半群性質。
(轉述者註:「\(\bm\Psi_{s\to T}\)」是把 PF-ODE 往雜訊方向積分;確定性 ODE 可以兩個方向走,這正是它和 SDE 的差別。)
PD 也符合這個模板,但它不只用極端的一對 \((T,0)\),而是用很多相鄰的時間對,並強制一個簡單的局部一致性規則:走一小步再走一小步,應該等於直接走兩步(第 10 節)。
實務上的主要困難是 oracle flow map \(\bm\Psi_{s\to t}\) 一般沒有閉式,無法直接監督。很多方法被發展出來有效率地近似這個目標,但它們的成敗常取決於老師模型的品質。第 11 章(B29 起)會回到這個損失,給出不需要老師的從頭訓練框架。
04VSD 的表述與梯度書 §10.2、§10.2.1
好幾個工作在不同的名字下同時發展了分佈層級的蒸餾,包括 Distribution Matching Distillation(DMD,Yin et al. 2024 兩篇)、Variational Score Distillation(VSD,Poole et al.、Wang et al. 2023、Luo et al. 2023、Lu & Song 2024)和 Score Identity Distillation(SiD,Zhou et al. 2024)。技術細節不同,但原則相同:訓練一個生成器,讓它經過正向加噪後的邊際分佈,和老師的相符。書以 VSD 為代表,其他方法遵循類似的原則。
VSD 和 SDS 的來歷(書的註腳,加上轉述者說明)
歷史上,VSD(Wang et al. 2023,ProlificDreamer)是為了文字轉 3D 提出的:預訓練的 2D diffusion model 透過可微分的渲染器,對 3D 場景提供分佈層級的監督。它的單粒子(Dirac)特例,在對應的時間權重和預測參數化慣例下,還原基本的 SDS(Score Distillation Sampling,Poole et al.,DreamFusion)更新。
轉述者說明:「單粒子」的意思是生成器沒有隨機輸入,整個分佈是一個點(一個 3D 場景)。這時學生分佈加噪後是一個以 \(\alpha_t\mathbf G_{\bm\theta}\) 為中心的高斯,它的 score 可以直接寫出來,不需要另外學 \(\mathbf s_{\bm\zeta}\)。
正向過程
令 \(\{p_t\}_{t\in[0,T]}\) 是正向 diffusion 過程 \(\mathbf x_t=\alpha_t\mathbf x_0+\sigma_t\bm\epsilon\)(\(\bm\epsilon\sim\mathcal N(\mathbf 0,\mathbf I)\)、\(p_0=p_{\text{data}}\))的邊際密度。另一方面,令 \(p^{\bm\theta}_0\) 是確定性的一步生成器 \(\mathbf G_{\bm\theta}(\mathbf z)\)(\(\mathbf z\sim p_{\text{prior}}\))產生的合成樣本分佈,\(\{p^{\bm\theta}_t\}\) 是對 \(p^{\bm\theta}_0\) 套用同一個正向過程得到的邊際密度:
$$\mathbf x^{\bm\theta}_t:=\alpha_t\mathbf G_{\bm\theta}(\mathbf z)+\sigma_t\bm\epsilon,\qquad\mathbf z\sim p_{\text{prior}},\ \bm\epsilon\sim\mathcal N(\mathbf 0,\mathbf I).$$所以 \(p_t\) 和 \(p^{\bm\theta}_t\) 共用同一個高斯擴散核 \(p_t(\mathbf x_t\mid\mathbf x_0)\),差別只在起始分佈(\(p_{\text{data}}\) 對一步合成樣本的 \(p^{\bm\theta}_0\))。
訓練目標與梯度
文獻通常用 KL 散度來匹配 \(p_t\) 和 \(p^{\bm\theta}_t\),最小化
\(\omega(t)\ge0\) 是依時間的權重。第 6 節說明為什麼 KL 在分佈層級的蒸餾裡扮演特別的角色。Wang et al. (2023) 指出,在母體層級,全域最佳解在 \(p^{\bm\theta^*}_0=p_{\text{data}}\) 達成,也就是生成器的分佈等於資料分佈,所以 VSD 目標是學 \(p_{\text{data}}\) 的一個有原則的分佈匹配損失。
但以密度寫的目標缺乏有效率的訓練方式:\(\log p^{\bm\theta}_t\) 根本算不出來(\(\mathbf G_{\bm\theta}\) 是隱式生成器)。幸運的是,對 \(\bm\theta\) 取梯度之後,密度本身消失,只剩 score。記 \(\hat{\mathbf x}_t:=\mathbf x^{\bm\theta}_t\):
證明(鏈鎖律 + score function 恆等式)
把期望寫成對 \((t,\mathbf z,\bm\epsilon)\) 的期望,被積函數 \(\log p^{\bm\theta}_t(\hat{\mathbf x}_t)-\log p_t(\hat{\mathbf x}_t)\) 經由兩條路徑依賴 \(\bm\theta\):密度 \(p^{\bm\theta}_t\) 本身,以及取樣點 \(\hat{\mathbf x}_t=\alpha_t\mathbf G_{\bm\theta}(\mathbf z)+\sigma_t\bm\epsilon\)。全微分是
$$\nabla_{\bm\theta}\mathcal L_{\text{VSD}}=\mathbb E_{t,\mathbf z,\bm\epsilon}\Big[\omega(t)\Big(\underbrace{\partial_{\bm\theta}\log p^{\bm\theta}_t(\hat{\mathbf x}_t)}_{\text{第一項}}+\big(\nabla_{\mathbf x}\log p^{\bm\theta}_t(\hat{\mathbf x}_t)\big)^\top\partial_{\bm\theta}\hat{\mathbf x}_t-\big(\nabla_{\mathbf x}\log p_t(\hat{\mathbf x}_t)\big)^\top\partial_{\bm\theta}\hat{\mathbf x}_t\Big)\Big].$$「第一項」是固定取樣點、只對密度的參數微分。它的期望是零(score function 恆等式):
$$\mathbb E_{\hat{\mathbf x}_t\sim p^{\bm\theta}_t}\big[\partial_{\bm\theta}\log p^{\bm\theta}_t(\hat{\mathbf x}_t)\big]=\int p^{\bm\theta}_t\,\frac{\partial_{\bm\theta}p^{\bm\theta}_t}{p^{\bm\theta}_t}\,d\mathbf x=\partial_{\bm\theta}\int p^{\bm\theta}_t(\mathbf x)\,d\mathbf x=\partial_{\bm\theta}(1)=0.$$(固定 \(t\) 時,\((\mathbf z,\bm\epsilon)\) 推出的 \(\hat{\mathbf x}_t\) 正好服從 \(p^{\bm\theta}_t\),所以可以把對 \((\mathbf z,\bm\epsilon)\) 的期望換成對 \(p^{\bm\theta}_t\) 的期望。)剩下兩項用重參數化 \(\partial_{\bm\theta}\hat{\mathbf x}_t=\alpha_t\,\partial_{\bm\theta}\mathbf G_{\bm\theta}(\mathbf z)\)(\(\bm\epsilon\) 不依賴 \(\bm\theta\)),就得到 Proposition。\(\blacksquare\)
score 在對 \(\bm\theta\) 微分時自然冒出來。所以需要兩個 score 的近似:一步生成器的 \(\nabla_{\mathbf x}\log p^{\bm\theta}_t(\hat{\mathbf x}_t)\),和資料分佈的 \(\nabla_{\mathbf x}\log p_t(\hat{\mathbf x}_t)\)。下一節說明怎麼取得。
轉述者註:上式的 \(\partial_{\bm\theta}\hat{\mathbf x}_t\) 已經含有 \(\alpha_t\),所以和 Proposition 的 \(\omega(t)\alpha_t\,\partial_{\bm\theta}\mathbf G_{\bm\theta}\) 是同一個式子。
直觀:每個樣本被推往哪裡(轉述者補充)
梯度下降讓 \(\hat{\mathbf x}_t\) 往 \(-\big(\nabla\log p^{\bm\theta}_t-\nabla\log p_t\big)=\nabla\log p_t-\nabla\log p^{\bm\theta}_t\) 的方向移動。第一項把樣本拉向老師分佈的高密度區;第二項把樣本推離學生自己的高密度區,也就是把擠在一起的樣本攤開。只有第一項的話,樣本只會一路往老師分佈的峰頂爬,最後擠在一起、失去多樣性;兩項相減,學生分佈和老師分佈一致時推力剛好歸零。
05VSD 的訓練流程書 §10.2.2
現有的工作通常用雙層最佳化處理:在 \(\mathbf G_{\bm\theta}(\mathbf z)\) 的樣本上訓練一個新的 diffusion model 來近似 \(\nabla_{\mathbf x}\log p^{\bm\theta}_t\),並用預訓練的 diffusion model 在合成樣本 \(\hat{\mathbf x}_t\) 上近似不可得的 oracle score \(\nabla_{\mathbf x}\log p_t\)。訓練在兩個階段之間交替:
- Score 估計階段。固定 \(\bm\theta\)。令 \(\hat{\mathbf x}_0=\mathbf G_{\bm\theta}(\mathbf z)\)、\(\hat{\mathbf x}_t=\alpha_t\hat{\mathbf x}_0+\sigma_t\bm\epsilon\)。用已知的高斯擴散核,以 DSM 訓練 \(\mathbf s_{\bm\zeta}\): $$\mathcal L_{\text{DSM}}(\bm\zeta;\bm\theta)=\mathbb E_{t,\mathbf z,\bm\epsilon}\big\|\mathbf s_{\bm\zeta}(\hat{\mathbf x}_t,t)-\nabla_{\mathbf x_t}\log p_t(\hat{\mathbf x}_t\mid\hat{\mathbf x}_0)\big\|^2,$$ 對固定的 \(\bm\theta\),最佳解是 \(\mathbf s_{\bm\zeta}(\cdot,t)\approx\nabla_{\mathbf x}\log p^{\bm\theta}_t(\cdot)\)。
- 生成器更新階段。把 \(\mathbf s_{\bm\zeta}\) 凍結(stop-grad),用 Proposition 的梯度更新 \(\bm\theta\),兩個 score 換成各自的替身:\(\mathbf s_{\bm\zeta}(\hat{\mathbf x}_t,t)\approx\nabla_{\mathbf x}\log p^{\bm\theta}_t(\hat{\mathbf x}_t)\),以及老師 \(\mathbf s_{\bm\phi^\times}(\hat{\mathbf x}_t,t)\approx\nabla_{\mathbf x}\log p_t(\hat{\mathbf x}_t)\): $$\nabla_{\bm\theta}\mathcal L_{\text{VSD}}(\bm\theta)\approx\mathbb E_{t,\mathbf z,\bm\epsilon}\Big[\omega(t)\alpha_t\big(\mathbf s_{\bm\zeta}(\hat{\mathbf x}_t,t)-\mathbf s_{\bm\phi^\times}(\hat{\mathbf x}_t,t)\big)^\top\partial_{\bm\theta}\mathbf G_{\bm\theta}(\mathbf z)\Big].$$
兩個階段在訓練中交替進行。理想上,輔助模型追蹤當前學生的 score \(\mathbf s_{\bm\zeta}(\cdot,t)\approx\nabla_{\mathbf x}\log p^{\bm\theta}_t(\cdot)\),預訓練的老師提供目標 score 的近似 \(\mathbf s_{\bm\phi^\times}(\cdot,t)\approx\nabla_{\mathbf x}\log p_t(\cdot)\)。在母體層級,如果兩個 score 在某個 \(\sigma_t>0\)、\(\alpha_t\ne0\) 的雜訊等級相等,那麼對應的歸一化密度相等,\(p^{\bm\theta}_t=p_t\)。因為 \(\alpha_t\ne0\) 時高斯加噪是單射,這又推得 \(p^{\bm\theta}_0=p_{\text{data}}\)。
實務上兩個 score 都由有限的學到的網路表示,所以這些等式描述的是理想的母體解,不是交替最佳化的保證。
為什麼「score 相等 ⇒ 密度相等」、「加噪是單射」(轉述者補充)
score 相等 ⇒ 密度相等。如果 \(\nabla_{\mathbf x}\log p^{\bm\theta}_t=\nabla_{\mathbf x}\log p_t\) 處處成立,那 \(\log p^{\bm\theta}_t-\log p_t\) 的梯度是零,在連通的 \(\mathbb R^D\) 上是常數 \(c\),所以 \(p^{\bm\theta}_t=e^cp_t\)。兩邊都積分成 1,得 \(e^c=1\)。這裡要求 \(\sigma_t>0\):加過高斯雜訊的密度處處為正而且光滑,「處處」和「連通」才成立。在 \(\sigma_t=0\) 的資料端,分佈可能集中在低維集合上,score 根本沒有定義。
加噪是單射。\(p_t\) 是「先把 \(\mathbf x_0\) 縮放 \(\alpha_t\) 倍,再和 \(\mathcal N(\mathbf 0,\sigma_t^2\mathbf I)\) 摺積」。取特徵函數(Fourier 轉換),摺積變成相乘:\(\varphi_{p_t}(\mathbf k)=\varphi_{p_0}(\alpha_t\mathbf k)\,e^{-\sigma_t^2\|\mathbf k\|^2/2}\)。高斯因子處處不為零,可以除掉;\(\alpha_t\ne0\) 時再把 \(\mathbf k\) 換成 \(\mathbf k/\alpha_t\),就從 \(\varphi_{p_t}\) 唯一決定 \(\varphi_{p_0}\),也就唯一決定 \(p_0\)。所以 \(p^{\bm\theta}_t=p_t\) 推得 \(p^{\bm\theta}_0=p_{\text{data}}\)(以老師為替身時是 \(p_{\bm\phi^\times}\))。
06超越 KL:為什麼 KL 特別書 §10.2.3
KL 散度對 VSD 的分佈匹配原則並不是必要的。原則上可以用一般的 f-divergence(B01):
$$\mathcal D_f(p^{\bm\theta}_t\,\|\,p_t)=\int p_t(\mathbf x)\,f\Big(\frac{p^{\bm\theta}_t(\mathbf x)}{p_t(\mathbf x)}\Big)\,d\mathbf x.$$reverse KL 特別方便的地方在它的梯度結構。定義密度比 \(r_t(\mathbf x):=p^{\bm\theta}_t(\mathbf x)/p_t(\mathbf x)\)。對二次可微的凸函數 \(f\) 和處處為正的密度,路徑式(pathwise)梯度可以寫成
\(r_t\) 都在 \(\hat{\mathbf x}_t\) 取值。第一個因子決定在哪裡、更新多強;第二個給出 score 不匹配的方向;最後一個把這個樣本空間的訊號映回生成器參數。
推導這個梯度(書沒有寫出步驟)
第 1 步:只有 \(p^{\bm\theta}_t\) 依賴 \(\bm\theta\)。\(\nabla_{\bm\theta}\int p_t f(r_t)\,d\mathbf x=\int p_t f'(r_t)\,\frac{\partial_{\bm\theta}p^{\bm\theta}_t}{p_t}\,d\mathbf x=\int f'(r_t)\,\partial_{\bm\theta}p^{\bm\theta}_t\,d\mathbf x\)。
第 2 步:把「對密度微分」換成「對樣本微分」。對任何固定的函數 \(\varphi\),\(\int\varphi\,\partial_{\bm\theta}p^{\bm\theta}_t\,d\mathbf x=\partial_{\bm\theta}\mathbb E_{\mathbf z,\bm\epsilon}[\varphi(\hat{\mathbf x}_t)]=\mathbb E_{\mathbf z,\bm\epsilon}\big[\nabla\varphi(\hat{\mathbf x}_t)^\top\partial_{\bm\theta}\hat{\mathbf x}_t\big]\)(重參數化)。取 \(\varphi=f'(r_t)\),並在微分時把它當成固定的函數(第 1 步的式子裡 \(f'(r_t)\) 本來就不被微分):
$$\int f'(r_t)\,\partial_{\bm\theta}p^{\bm\theta}_t\,d\mathbf x=\mathbb E\big[f''(r_t)\,\nabla r_t^\top\,\partial_{\bm\theta}\hat{\mathbf x}_t\big].$$第 3 步:\(\nabla r_t=r_t\nabla\log r_t=r_t\big(\nabla\log p^{\bm\theta}_t-\nabla\log p_t\big)\),代入就是上面的式子。取 \(f(r)=r\log r\),\(rf''(r)=1\),再用 \(\partial_{\bm\theta}\hat{\mathbf x}_t=\alpha_t\partial_{\bm\theta}\mathbf G_{\bm\theta}\),正好回到第 4 節的 Proposition(每個 \(t\)、權重 \(\omega(t)\))。
這個式子揭露了一個共同結構:所有這類 f-divergence 都用同一個 score 不匹配方向
$$\nabla_{\mathbf x}\log p^{\bm\theta}_t(\mathbf x)-\nabla_{\mathbf x}\log p_t(\mathbf x)=\nabla_{\mathbf x}\log r_t(\mathbf x),$$散度的選擇只改變不同區域透過 \(r_tf''(r_t)\) 得到多少權重。所以對常見的嚴格凸 \(f\),母體層級的分佈匹配條件仍然是 \(p^{\bm\theta}_t=p_t\);散度的選擇改變的是最佳化過程中,不同密度比區間的權重。
對 VSD 用的 reverse KL,\(f(r)=r\log r\),所以 \(rf''(r)=1\):密度比權重消失,還原第 4 節的 score 差梯度。因此只要有學生和目標的 score,reverse KL 訓練就不需要額外的逐點密度比估計器。相反地,一般的 f-divergence 需要 \(r_tf''(r_t)\) 這個因子:score 差提供的是 \(\nabla_{\mathbf x}\log r_t\),但對隱式生成器,\(r_t\) 本身不能直接取得,一般需要另外估計。
例如 forward KL 對應 \(f(r)=-\log r\),\(rf''(r)=1/r\)。所以它在「模型密度相對目標密度很小」的區域放更大的權重。這說明了不同的散度可以共用同一個 score 不匹配方向,卻強調不同的密度比區間。
最後,這個 score 不匹配的觀點直接連到附錄 B.3 的 Wasserstein gradient flow 觀點(B34)。在分佈層級,reverse KL 的梯度流按「目標 score 減模型 score」移動粒子;VSD 的參數梯度含有同一個 score 不匹配,再經由生成器的 Jacobian \(\partial_{\bm\theta}\hat{\mathbf x}_t\) 拉回。所以 Wasserstein 觀點描述理想的分佈空間運動,VSD 則透過一個有限維、共用的生成器的更新去實現這個運動。
Demo A一步生成器的分佈蒸餾轉述者補充
一維資料:\(0.6\,\mathcal N(-1.2,0.25^2)+0.4\,\mathcal N(1.3,0.35^2)\),cosine 時程 \(\alpha_t=\cos\frac{\pi t}2\)、\(\sigma_t=\sin\frac{\pi t}2\)。老師 score 直接用這個混合分佈加噪後的精確 score(等於假設老師完美)。生成器 \(G_{\bm\theta}(z)\) 是 1→32→32→1 的 tanh MLP,\(z\sim\mathcal N(0,1)\)。每次更新抽 32 個 \((z,t,\epsilon)\),\(t\sim\mathcal U[0.05,t_{\max}]\),權重取 \(\omega(t)=\sigma_t^2\)(讓 \(\sigma_t^2\times\) score 差維持有界),共 1,500 次 Adam 更新(最後 30% 學習率降到 0.3 倍)。學生 score 有兩種取法:
- DSM 學(書的流程):另一個 MLP \(s_{\bm\zeta}\),先做 300 次 DSM 暖身,之後每次生成器更新前做 3 次 DSM 更新。
- 樣本批精確算:每次抽 128 個生成器樣本 \(y_j\),用 \(\frac1{128}\sum_j\mathcal N(x;\alpha_ty_j,\sigma_t^2)\) 的精確 score。這是「學生 score 完美」的理想情況;它順便給出密度 \(p^{\bm\theta}_t\),所以也能算 forward KL 需要的 \(r_t\)。
瀏覽器實測(和 Node 原型的數字逐位相同;固定種子,每次重跑結果一樣)。表中是第 1,500 次更新後的 \(W_1\)(對資料)/右峰質量比例(目標 0.40):
| 設定 | VSD,DSM 學 score | VSD,精確 score | forward KL |
|---|---|---|---|
| 一般初始化,\(t_{\max}=0.95\) | 0.131 / 0.41 | 0.065 / 0.41 | 0.069 / 0.41 |
| 只在右峰,\(t_{\max}=0.95\) | 0.106 / 0.40 | 0.109 / 0.40 | 0.114 / 0.40 |
| 只在右峰,\(t_{\max}=0.3\) | 0.247 / 0.47 | 0.174 / 0.46 | 0.120 / 0.43 |
| 只在右峰,\(t_{\max}=0.15\) | 1.417 / 0.96 | 1.491 / 1.00 | 0.211 / 0.46 |
(1) 雜訊範圍完整時,VSD 一步生成器學到兩個峰,比例也對。即使生成器一開始只在右峰,右峰比例最後也是 0.40。DSM 版比精確版差(0.131 對 0.065):學出來的學生 score 在樣本稀少的尾端不準,樣本在兩峰外緣被截斷、堆在邊上(1% 和 99% 分位數是 −1.45 和 1.60,就是最小值和最大值;資料是 −1.73 和 1.99)。實際系統裡 \(\mathbf s_{\bm\zeta}\) 的品質同樣是瓶頸。
(2) 遠方的峰要靠大雜訊才「看得到」。從右峰出發、\(t_{\max}=0.15\) 時,reverse KL 完全回不到左峰(精確版右峰比例 1.00,DSM 版 0.96):雜訊小時,左峰對右峰附近的 score 幾乎沒有影響,老師和學生的 score 在學生的樣本上幾乎相同,梯度就沒有訊號。\(t_{\max}=0.3\) 時 reverse KL 回得來但很慢:第 250 次更新時右峰比例還是 1.00(DSM)和 0.79(精確)。forward KL 在同一時間已經是 0.48,在 \(t_{\max}=0.15\) 也能找回左峰(0.46):權重 \(1/r_t\) 放大了「模型密度相對很小」的區域,正是第 6 節說的效果。
(3) 但 forward KL 不是免費的。這個 demo 能算 \(r_t\),是因為一維時可以從樣本精確寫出學生的加噪密度;書提醒,對一般的隱式生成器 \(r_t\) 拿不到。這裡的權重還截在 20 以內,否則會被少數樣本主導。結果也偏寬:\(t_{\max}=0.15\) 時 1%–99% 分位數是 −2.02 到 2.42,比資料的 −1.73 到 1.99 寬,是 forward KL「寧可蓋住也不要漏掉」的典型樣子。
(4) 峰之間的質量比例也要靠大雜訊修正。一般初始化下右峰比例一開始約 0.5;\(t_{\max}=0.15\) 時精確版停在 0.50(\(W_1\) 0.254),\(t_{\max}=0.3\) 時才降到 0.41。小雜訊只能修局部形狀,在峰之間搬質量需要大雜訊。這是 VSD 在整個時間範圍取 \(t\) 的原因之一。
07Progressive Distillation 概觀書 §10.3
Progressive Distillation(PD,Salimans & Ho 2022)由兩個程序組成,合起來讓 diffusion model 更有效率地學 PF-ODE 軌跡。關鍵想法是逐步減少高品質取樣需要的積分步數,同時忠於老師的軌跡:
- 蒸餾操作:把一個以預訓練老師(一開始是 diffusion model)為基礎的確定性取樣器(例如 DDIM),蒸餾成一個只用一半步數就重現同一條軌跡的學生。
- 漸進操作:反覆進行這個蒸餾,每次步數減半,直到學生能在很小的固定預算內(通常 1–4 步)生成高品質樣本。

下面先介紹 PD 的蒸餾操作(第 8 節),再總結完整的訓練流程(第 9 節),第 11 節介紹 CFG guidance 的延伸。
08PD 的蒸餾操作書 §10.3.1
這一節固定用資料(\(\mathbf x\))預測形式的 DDIM 作為時間步進規則,仍然用 \(\mathtt{Solver}_{s\to t}\) 表示把當前老師的 \(\mathbf x\) denoiser 代進 DDIM 得到的確定性映射。第一輪 PD(老師 = 預訓練的 diffusion model)時,這就是用 DDIM 積分 diffusion PF-ODE;之後的各輪(老師 = 上一輪的學生),\(\mathtt{Solver}_{s\to t}\) 只是當前老師誘導出的 DDIM 轉移,不再是原本的 diffusion PF-ODE。
蒸餾步驟是這樣的:從帶雜訊的輸入 \(\mathbf x_s\)(乾淨資料的擾動版本 \(\mathbf x_s=\alpha_s\mathbf x_0+\sigma_s\bm\epsilon\))出發,訓練學生預測一個目標 \(\tilde{\mathbf x}\),使學生的一步 \(s\to t\) 重現老師連續的兩步 \(s\to u\to t\)。令 \(\mathbf x_{\bm\phi^\times}(\mathbf x,\tau)\) 是這一輪老師的 \(\mathbf x\) 預測 denoiser,把老師誘導的 DDIM 轉移用兩次:
$$\tilde{\mathbf x}_u:=\mathtt{Solver}_{s\to u}(\mathbf x_s;\mathbf x_{\bm\phi^\times}),\qquad\tilde{\mathbf x}_t:=\mathtt{Solver}_{u\to t}(\tilde{\mathbf x}_u;\mathbf x_{\bm\phi^\times}).$$得到 \(\tilde{\mathbf x}\) 的閉式之後,就訓練學生模型 \(\mathbf f_{\bm\theta}(\mathbf x_s,s)\)(這裡也是 \(\mathbf x\) 預測模型)去近似這個「兩步合一」的目標:
DDIM 的規則讓 \(\tilde{\mathbf x}\) 有閉式,只要基本代數(結果對離散和連續時間都成立):
證明
\(\tilde{\mathbf x}_t\) 要和直接用 \(\tilde{\mathbf x}\) 走一步 DDIM \(s\to t\) 的結果 \(\tilde{\mathbf x}'_t\) 相等:
$$s\to t:\quad\tilde{\mathbf x}'_t=\frac{\sigma_t}{\sigma_s}\mathbf x_s+\alpha_s\Big(\frac{\alpha_t}{\alpha_s}-\frac{\sigma_t}{\sigma_s}\Big)\tilde{\mathbf x}.$$令 \(\tilde{\mathbf x}_t=\tilde{\mathbf x}'_t\),解出 \(\tilde{\mathbf x}\):
$$\tilde{\mathbf x}=\frac{\tilde{\mathbf x}_t-\frac{\sigma_t}{\sigma_s}\mathbf x_s}{\alpha_s\big(\frac{\alpha_t}{\alpha_s}-\frac{\sigma_t}{\sigma_s}\big)}=\frac{\sigma_s}{\alpha_t\sigma_s-\alpha_s\sigma_t}\,\tilde{\mathbf x}_t-\frac{\sigma_t}{\alpha_t\sigma_s-\alpha_s\sigma_t}\,\mathbf x_s.$$最後一步是分子分母同乘 \(\sigma_s\):分母 \(\alpha_s\big(\frac{\alpha_t}{\alpha_s}-\frac{\sigma_t}{\sigma_s}\big)\sigma_s=\alpha_t\sigma_s-\alpha_s\sigma_t\)。\(\blacksquare\)
(轉述者註:能這樣解,是因為 DDIM 的一步對 \(\hat{\mathbf x}_0\) 是仿射的,而且係數 \(\alpha_t-\alpha_s\sigma_t/\sigma_s\) 在 \(t\lt s\) 時不為零:它等於 \(\alpha_t(1-e^{\lambda_s-\lambda_t})\)、\(\lambda=\log(\alpha/\sigma)\) 嚴格遞減。這和 Salimans & Ho 論文 Algorithm 2 裡的目標是同一個式子。)
有了這個公式,PD 在時間 \(s\) 算出偽乾淨目標,使它的單一 DDIM 步 \(s\to t\) 正好落在兩步的輸出 \(\tilde{\mathbf x}_t\)。(轉述者註:\(\tilde{\mathbf x}\) 一般不是 \(\mathbb E[\mathbf x_0\mid\mathbf x_s]\),而是「讓一大步走對」的那個值。在 Demo B 的例子裡,它比後驗平均更偏向軌跡實際前往的那一側;步越短,兩者越接近。)
實用的離散格點與損失
實務上固定遞減的格點 \(t_0=T>t_1>\cdots>t_N=0\),簡寫 \(s:=t_k\)、\(u:=t_{k+1}\)、\(t:=t_{k+2}\)。老師提供單步映射 \(\mathtt{Teacher}_{t_k\to t_{k+1}}\),學生學一個跳兩格、匹配老師複合的映射:\(\mathtt{Student}_{t_k\to t_{k+2}}\approx\mathtt{Teacher}_{t_{k+1}\to t_{k+2}}\circ\mathtt{Teacher}_{t_k\to t_{k+1}}\)。對標準的減半時程,假設 \(N\) 是偶數,抽三元組 \((s,u,t)=(t_k,t_{k+1},t_{k+2})\),\(k\in\{0,2,\dots,N-2\}\)。目標變成
$$\min_{\bm\theta}\ \mathbb E_{k\sim\mathcal U\{0,2,\dots,N-2\}}\,\mathbb E_{\mathbf x_{t_k}\sim p_{t_k}}\Big[w(\lambda_{t_k})\,\big\|\mathbf f_{\bm\theta}(\mathbf x_{t_k},t_k)-\tilde{\mathbf x}^{(k)}\big\|_2^2\Big],$$老師的兩步目標 \(\tilde{\mathbf x}^{(k)}\) 由 Lemma 算出。若格點均勻,可以寫 \(t_k=T(1-k/N)\),於是 \(s=T(1-\frac kN)\)、\(u=T(1-\frac{k+1}N)\)、\(t=T(1-\frac{k+2}N)\),時間步長 \(\Delta s=T/N\)。
PD 論文裡的實作細節(轉述者補充,出處:Salimans & Ho 2022)
- 時程:所有實驗用 cosine 時程 \(\alpha_t=\cos(0.5\pi t)\)、\(\sigma_t^2=1-\alpha_t^2\),所以 \(t=1\) 時 \(\alpha=0\)、\(\mathbf x_1\) 是純雜訊,\(p_T=p_{\text{prior}}\) 精確成立。
- 參數化:\(\bm\epsilon\) 預測在蒸餾時不好用。\(\hat{\mathbf x}=(\mathbf z_t-\sigma_t\hat{\bm\epsilon})/\alpha_t\) 要除以 \(\alpha_t\),訊噪比越低誤差放大越多;蒸餾到一步時輸入是純雜訊(\(\alpha_t=0\)),\(\bm\epsilon\) 預測完全不含 \(\mathbf x\) 的資訊。論文試了三種穩定的做法,都可行:直接預測 \(\mathbf x\);同時預測 \(\mathbf x\) 和 \(\bm\epsilon\) 再混合;預測 \(\mathbf v\equiv\alpha_t\bm\epsilon-\sigma_t\mathbf x\),\(\hat{\mathbf x}=\alpha_t\mathbf z_t-\sigma_t\hat{\mathbf v}\)。
- 權重 \(w(\lambda_t)\):標準的 \(\bm\epsilon\) 損失等於 \(\mathbf x\) 損失乘上 SNR,在 SNR = 0 給零權重,不適合蒸餾。論文用「truncated SNR」\(\max(\alpha_t^2/\sigma_t^2,1)\) 或「SNR+1」\(1+\alpha_t^2/\sigma_t^2\)(後者等於 \(\mathbf v\) 空間的均方誤差)。
- 規模:CIFAR-10 從 8,192 步的老師開始,較大的資料集從 1,024 步開始;每一輪 5 萬次參數更新(蒸餾到 2 步和 1 步時 10 萬次)。CIFAR-10 上 4 步達到 FID 3.0,而蒸餾到 4 步的總成本和訓練原模型相當或更少。
Demo B兩步合一的目標轉述者補充
同一個一維資料、cosine 時程。老師的 \(\mathbf x\) 預測用精確的後驗平均 \(\mathbb E[x_0\mid x_s]\)。橫軸是時間(左邊 \(t=0\) 是資料,右邊 \(t=1\) 是雜訊),灰線是精確的 PF-ODE 軌跡。從 \((s,x_s)\) 出發,比較:老師走兩步 \(s\to u\to t\)(\(u\) 取中點);用老師自己的 \(\hat x=\mathbb E[x_0\mid x_s]\) 一步走 \(s\to t\);用 Lemma 的 \(\tilde x\) 一步走 \(s\to t\)。左邊界的兩個刻度標出 \(\hat x\) 和 \(\tilde x\) 的值。
讀數(瀏覽器實測,三組設定):
- 預設(\(x_s=0.4\)、\(s=0.9\)、\(t=0.3\)):老師的 \(\hat x=-0.100\),兩步合一目標 \(\tilde x=0.059\)。用 \(\tilde x\) 走一步正好落在老師兩步的終點 0.2318(差小於 \(10^{-12}\));用 \(\hat x\) 走一步只到 0.102。\(\tilde x\) 比 \(\hat x\) 更偏向軌跡真正前往的那一側。
- \(s=1\)、\(t=0\):這時 \(\alpha_s=0\),不管起點是什麼,\(\hat x\) 都是資料平均 −0.200。\(t=0\) 時 \(\alpha_t=1\)、\(\sigma_t=0\),Lemma 化成 \(\tilde x=\tilde x_t\):目標就是老師兩步的終點本身(0.0027)。這個終點落在兩峰之間的低谷,而精確 PF-ODE 走到 0.92:PD 學的是老師的答案,不是真正的 flow map;老師步數太少,目標本身就不準。這是 PD 要從很多步的老師開始的原因。
- 短步(\(s=0.5\)、\(t=0.46\)):\(\tilde x=0.532\),\(\hat x=0.499\),幾乎相同。步越短,「兩步合一」越接近普通的去噪目標;兩者的差距隨步長變大。
09完整流程與取樣書 §10.3.2
用第 8 節的損失在局部配對的片段上訓練完之後,學生不再走原格點的每一個區間:它學到的每一步涵蓋老師連續兩步,所以每隔一個時間點前進,\(t_0\to t_2\to t_4\to\cdots\to t_N\),用 \(N/2\) 次轉移走完同樣的 \([0,T]\)。這一階段結束後,訓練好的學生取代老師成為新的 denoiser,然後在更粗的格點上(時間步加倍)重複,得到 \(N\to N/2\to N/4\to\cdots\),直到達到想要的推論步數。每一輪的新學生都從更新後的老師初始化。這種反覆減半保留整個時間範圍,同時逐步壓縮生成過程的時間解析度。
取樣。推論時用 DDIM 解法、以當前的學生當 denoiser,在訓練誘導出的較粗格點上前進。第一輪之後是「跳 2」(\(t_0\to t_2\to\cdots\to t_N\)),下一輪之後是「跳 4」(\(t_0\to t_4\to\cdots\to t_N\)),以此類推;每一輪把取樣步數減半,起點和終點時間不變。
重複直到步數夠少:
1. 學生 \(\bm\theta\leftarrow\) 老師的參數。
2. 重複:抽資料 \(\mathbf x_0\)、偶數 \(k\)、\(\bm\epsilon\);令 \(\mathbf x_s=\alpha_s\mathbf x_0+\sigma_s\bm\epsilon\)(\(s=t_k\));老師 DDIM 走 \(s\to u\to t\) 得 \(\tilde{\mathbf x}_t\);用 Lemma 算 \(\tilde{\mathbf x}\);對 \(w(\lambda_s)\|\mathbf f_{\bm\theta}(\mathbf x_s,s)-\tilde{\mathbf x}\|^2\) 做一次梯度步。
3. 老師 \(\leftarrow\) 學生;\(N\leftarrow N/2\)。
10局部半群匹配與其他解法書 §10.3.3
PD 是局部的半群匹配
在第 3 節的統一目標裡,不可得的 oracle 目標 \(\bm\Psi_{s\to0}\) 被換成一個老師誘導的替代品,它利用 ODE flow 的半群性質(第 11 章會詳細講):從 \(s\) 演化到 \(t\),應該等於先從 \(s\) 走到任何中間的 \(u\)、再從 \(u\) 走到 \(t\):
$$\bm\Psi_{s\to t}=\bm\Psi_{u\to t}\circ\bm\Psi_{s\to u}.$$PD 在局部強制這件事:訓練學生的一步映射去匹配老師兩個相鄰單步片段的複合:
當老師解法準確近似底層的 ODE flow 時,這個複合在一段短的遞減格點上(取 \(s>u>t\),\(u=s-\Delta s\)、\(t=s-2\Delta s\))近似對應的半群關係:
$$\bm\Psi_{s\to s-2\Delta s}=\bm\Psi_{s-\Delta s\to s-2\Delta s}\circ\bm\Psi_{s\to s-\Delta s}\approx\mathtt{Solver}_{s-\Delta s\to s-2\Delta s}\circ\mathtt{Solver}_{s\to s-\Delta s},$$所以訓練只需要短的老師片段,不需要從 \(s\) 一路展開到 0。為了接回第 3 節的少步 denoiser 觀點,把學生的少步映射定義成學到的跳躍的複合:
$$\underbrace{\mathbf G_{\bm\theta}(\mathbf x_s,s,0)}_{\text{少步 denoiser}}=\big(\mathbf G_{\bm\theta}(\cdot,2\Delta s,0)\circ\cdots\circ\mathbf G_{\bm\theta}(\cdot,s,s-2\Delta s)\big)(\mathbf x_s).$$概念上,上面的局部損失是下面這個全域回歸的有效率局部替代:
$$\mathbb E_{s,\mathbf x_s}\Big\|\mathbf G_{\bm\theta}(\mathbf x_s,s,0)-(\mathtt{Solver})^{\circ}_{s\to0}(\mathbf x_s)\Big\|_2^2,$$其中 \((\mathtt{Solver})^{\circ}_{s\to0}\) 表示老師在步長 \(\Delta s\) 的格點上從 \(s\) 到 0 的完整複合,作為 \(\bm\Psi_{s\to0}\) 的替身。
這裡的 \(\mathbf G_{\bm\theta}\) 和第 8 節的 \(\mathbf f_{\bm\theta}\) 是什麼關係(轉述者補充)
第 8 節的學生是一個 \(\mathbf x\) 預測網路 \(\mathbf f_{\bm\theta}(\mathbf x_s,s)\);它誘導的一步映射就是 \(\mathbf G_{\bm\theta}(\mathbf x_s,s,t)=\mathtt{DDIM}_{s\to t}(\mathbf x_s;\mathbf f_{\bm\theta}(\mathbf x_s,s))=\frac{\sigma_t}{\sigma_s}\mathbf x_s+(\alpha_t-\alpha_s\frac{\sigma_t}{\sigma_s})\mathbf f_{\bm\theta}(\mathbf x_s,s)\)。這一節的端點損失 \(\|\mathbf G_{\bm\theta}-\tilde{\mathbf x}_t\|^2\) 和第 8 節的 \(\|\mathbf f_{\bm\theta}-\tilde{\mathbf x}\|^2\) 只差一個常數倍 \((\alpha_t-\alpha_s\sigma_t/\sigma_s)^2\),這個倍數可以吸收到權重 \(w\) 裡。
能不能用其他解法?
上面用 \(\mathbf x\) 預測形式的 DDIM 作為具體的 PF-ODE 取樣器。基本的蒸餾原則更一般:幾個細的老師步產生一個目標終點,學生訓練成用一個較粗的步到達同一個終點。
只要粗解法的一步更新可以對學生的網路預測反解,上面推出的閉式偽目標就存在。DDIM 的更新對單一個 \(\mathbf x\) 預測是仿射的,所以反解是解析的;一步更新允許類似反解的其他解法也適用同樣的想法。
對更複雜的解法,這種單一輸出的反解可能不存在:多階段的方法用好幾次網路計算,多步方法依賴之前的解法狀態,隱式方法要解耦合的方程。這時可以改成計算粗的學生步的終點,直接和細的老師步的終點匹配(如上面的局部損失),在可行時對學生的解法反向傳播。因為一個粗步本身可能要好幾次神經網路計算,時間步變少不一定代表 NFE 等比例變少。
對隨機取樣器,固定或耦合老師和學生用的隨機抽樣之後,同樣的逐路徑邏輯適用。沒有這種耦合,個別軌跡不必有相同的終點,合適的目標一般是分佈匹配,而不是逐路徑匹配。
Demo C一路蒸餾到一步轉述者補充
完整跑一次 PD。同一個一維資料、cosine 時程。老師:一個 4→32→32→1 的 tanh MLP,輸入 \((x_t,\alpha_t,\sigma_t,\alpha_tx_t)\),用 \(\mathbf v\) 參數化(\(\hat x=\alpha_tx_t-\sigma_t\hat v\)),以 \(\mathbf v\) 損失(SNR+1 權重)訓練 3,000 次 Adam 更新,就是一般的 diffusion 訓練。PD:從 32 步的老師 DDIM 開始,每輪 1,000 次更新(批次 32),學生從老師初始化、損失同樣用 SNR+1 權重,連續 5 輪:32 → 16 → 8 → 4 → 2 → 1 步。KD 對照:先用老師 32 步 DDIM 產生 2,000 對 \((z,\text{終點})\),再從頭訓練一個 1→32→32→1 的一步生成器 3,000 次更新(批次 32)。評估都用同一組 2,000 個起點雜訊,和資料比 \(W_1\);「路徑誤差」是和老師 32 步 DDIM 從同一個起點走到的終點相比的平均 \(|\Delta x|\)。
瀏覽器實測(和 Node 原型逐位相同;整個流程在 Node 原型約 4 秒,瀏覽器裡視裝置而定,可能更久)。\(W_1\) 對資料;路徑誤差對老師 32 步:
| 步數 | 老師直接 DDIM:\(W_1\)(路徑) | PD 學生:\(W_1\)(路徑) |
|---|---|---|
| 32 | 0.041(0) | (就是老師) |
| 16 | 0.049(0.022) | 0.042(0.0012) |
| 8 | 0.085(0.067) | 0.040(0.0030) |
| 4 | 0.171(0.155) | 0.042(0.0057) |
| 2 | 0.428(0.412) | 0.040(0.0140) |
| 1 | 1.120(1.104) | 0.044(0.0220) |
| 1(KD) | 0.042(0.0102) | |
(1) 老師直接少走幾步,品質很快崩壞:\(W_1\) 從 32 步的 0.041 升到 1 步的 1.120。1 步時所有樣本擠在 \([-0.42,0.16]\),也就是資料平均 −0.20 附近:這就是第 1 節的「取平均」。理想的老師會讓它們全部正好落在 −0.20,學到的網路不完全精確,所以有一點寬度。
(2) PD 學生在每個步數都保持老師 32 步的品質:\(W_1\) 在 0.040–0.044 之間,1 步的右峰比例 0.404。(2,000 個樣本本身就有統計誤差:從真實分佈抽 2,000 個點,\(W_1\) 也有 0.019。)
(3) 誤差一輪一輪累積。路徑誤差 0.0012 → 0.0030 → 0.0057 → 0.0140 → 0.0220:每一輪的老師是上一輪的學生,第 8 節說之後各輪「不再是原本的 PF-ODE」,在這裡看得到。但即使到 1 步,誤差仍只有老師自己 1 步 DDIM 的 1/50。
(4) KD 在這個例子裡反而更貼近老師(路徑誤差 0.0102,PD 是 0.0220)。一維的 \(z\mapsto\) 終點是一條簡單的單調曲線,產生 2,000 對資料只要 6.4 萬次老師計算。書列出的 KD 缺點(大規模時每個目標都要解一次 ODE、用不到資料、失去中途操控)在這種小例子裡都顯現不出來;PD 的優勢在規模大、每次解 ODE 都很貴的時候。
11帶 guidance 的 PD書 §10.3.4
Meng et al. (2023) 提出一個兩階段的流程,用來蒸餾 classifier-free guided(CFG)的 diffusion model:(1) 把 guidance 蒸餾進一個以 guidance 權重為輸入的單一網路;(2) 再用 PD 減少取樣步數。他們在像素空間和潛在空間(例如 Stable Diffusion)都示範了這個流程。
第一階段:蒸餾 guidance。令 \(\mathbf x_{\bm\phi^\times}(\mathbf x_s,s,\mathbf c)\) 是預訓練的條件 diffusion model 在「\(\mathbf x\) 預測」參數化下的輸出(乾淨估計),條件 \(\mathbf c\) 也可以是空的 \(\mathbf c=\varnothing\)(無條件分支)。以 \(\omega\) 加權的 CFG 組合寫成
$$\mathbf x^{\omega}_{\bm\phi^\times}(\mathbf x_s,s,\mathbf c):=(1+\omega)\,\mathbf x_{\bm\phi^\times}(\mathbf x_s,s,\mathbf c)-\omega\,\mathbf x_{\bm\phi^\times}(\mathbf x_s,s,\varnothing),$$其中 \(\omega\sim p_\omega(\omega)\),通常取均勻分佈 \(\mathcal U[\omega_{\min},\omega_{\max}]\)。第一階段引入一個新模型 \(\mathbf x_{\bm\theta_1}(\mathbf x_s,s,\mathbf c,\omega)\),直接把 \(\omega\) 當輸入,用監督式回歸學會重現 CFG 的輸出:
$$\min_{\bm\theta_1}\ \mathbb E_{\omega\sim p_\omega,\,s,\,\mathbf x\sim p_{\text{data}},\,\mathbf x_s\sim p(\mathbf x_s\mid\mathbf x)}\ \lambda(s)\,\big\|\mathbf x_{\bm\theta_1}(\mathbf x_s,s,\mathbf c,\omega)-\mathbf x^{\omega}_{\bm\phi^\times}(\mathbf x_s,s,\mathbf c)\big\|_2^2.$$\(\lambda(s)\) 是標準的、依時程的權重;每次迭代都抽一個 \(\omega\),讓單一網路學會模擬任意 guidance 強度的 CFG。(轉述者註:原本 CFG 每一步要算條件和無條件兩次網路,第一階段的模型一次就給出組合後的結果。)
第二階段:PD。第一階段的模型 \(\mathbf x_{\bm\theta_1}(\mathbf x_s,s,\mathbf c,\omega)\) 當作 PD 的老師,照第 9 節的流程逐步蒸餾成步數更少的學生 \(\mathbf x_{\bm\theta_2}(\mathbf x_s,s,\mathbf c,\omega)\),每一輪步數減半(\(N\to N/2\to N/4\to\cdots\))。
12第 10 章結語書 §10.4
這一章介紹了 training-based 加速的第一個主要範式。用盡數值解法這類 training-free 的改進之後,策略轉向:訓練一個快的學生生成器,學會複製一個慢的、預訓練的老師 diffusion model 的行為。
我們看了兩種主要的蒸餾哲學。第一,分佈層級的蒸餾,以 VSD 之類的方法為代表,訓練學生的輸出分佈去匹配老師的分佈;做法是在不同雜訊等級對齊兩者的 score,得到一個穩定、非對抗式的目標。第二,flow map 蒸餾,看到 PD 之類的方法怎麼訓練學生直接近似老師的解軌跡;PD 每一輪把取樣步數減半的反覆做法,證明是把漫長的反覆過程壓縮成少數幾步的有力、實用方法。
這些蒸餾技巧成功地銜接了反覆式 diffusion model 的高樣本品質和一步生成器的推論速度,為有效率的高保真生成提供了一條有說服力的路。
但依賴預訓練的老師帶來一個兩階段流程:先訓練一個慢但強的老師,再把它蒸餾成快的學生。這引出生成模型研究前沿的一個根本問題:能不能完全繞過老師?能不能設計一個獨立的訓練原則,直接從資料學這些快速的少步生成器?本書最後一章回答這個問題:
- 探討 Consistency Model 這類開創性的方法:它學的是從 ODE 軌跡上任一點到軌跡終點的映射。
- 深入 Consistency Model 的推廣:學會一步就把 ODE 軌跡上任一點映射到另一點。
從「改進解法」或「蒸餾一個解」轉向「學解映射本身」,是朝向一類既有原則、又在設計上就有效率的新生成模型邁出的重要一步。