本篇重用M2.3導航每 30 秒更新一次:Euler 法與它的誤差·M3.0醉漢一小時後在哪:Random Walk 到 Brownian Motion·M3.1水流加亂流:SDE 是加了噪聲的 ODE·M3.3山谷裡隨機走的人群:Langevin Dynamics 與 Stationary Distribution·M2.2站內人數變化 = 進 − 出:Continuity Equation·M3.2一千片葉子在亂流裡:Fokker–Planck 方程式
照原本的步伐走一步,要付什麼代價?
U1.3 把缺的那一塊補上了:訓好的網路給的就是 score,也就是每個時刻、每個位置「人群往哪邊變密」。所以現在可以回頭問 U1.2 留下的那個問題了。
訓練時我們把路切成一千小步;
生成時,可以自己決定走幾步、每一步走多遠嗎?
先把帳算清楚再談少走幾步。倒著走一步那一行,U1.2 其實已經寫出來了:
xt−1=μ~t(xt, x^θ(xt,t))+β~tz,z∼N(0,I).
問題是這一行只有在「q(xt−1∣xt) 真的是那個 Gaussian」的時候才精確,而它其實不是。所以在問「能不能少走幾步」之前,得先知道照原本的步伐走一步,本身錯多少——因為那個誤差的大小,正好和步長綁在一起。
課堂提問Q1
U1.2 的積分寫著 q(xt−1∣xt)=∫q(xt−1∣xt,x0)p(x0∣xt)dx0——一堆 Gaussian 按後驗權重疊起來,那是一個混合 Gaussian,一般不是 Gaussian。但我們的取樣器只抽一個 N(μ~t(xt,x^0),β~tI)。
這時候很容易這樣想:x^0 已經是後驗平均了,代進去之後抽出來的 xt−1 平均也就會是對的,那還有什麼好擔心的?
這個推理對嗎?如果對,那錯的是什麼?
先想一想,再展開看整理後的答案
那個推理是對的——但它只顧到平均。 把混合的平均與變異數都算出來就看得到(變異數那一條用的是 law of total variance:總變異數=條件變異數的平均 + 條件平均的變異數)。因為 μ~t 對 x0 是 affine 的,記它的 x0 係數為 c0=1−αˉtαˉt−1βt,那麼
E[xt−1∣xt]=μ~t(xt,E[x0∣xt]),Var[xt−1∣xt]=β~tI+c02Var[x0∣xt].
平均值是精確的;錯的只有變異數,而那個錯是 O(βt)。
平均那一半精確,是 affine 的好處。錯的只有變異數:我們用了 β~t,而真值多了一項 c02Var[x0∣xt]——那是「x0 到底是誰」的不確定性漏進來的部分。
大不大?c0 正比於 βt,而 β~t 也正比於 βt,所以丟掉的那一項相對於保留的那一項是 O(βt)——高一階,βt 越小越可以忽略。拿 DDPM 的 linear schedule 實際算(β:10−4→0.02、T=1000,資料的尺度取 1):
| t | 10 | 50 | 100 | 300 | 500 | ≥700 |
|---|
| 丟掉的/保留的 | 17% | 3.7% | 1.8% | 0.4% | 0.09% | < 0.01% |
這就是「把一件難事切成很多小步」真正的數學內容。 不是「每一步比較容易學」這種感覺——而是:每一步的 βt 越小,用一個 Gaussian 代替那個混合分布的誤差就越小。步數換的是這個。反過來,如果只走幾步、每步的 β 很大,這個近似就會壞掉——這也是為什麼 U6 想少步生成的時候,不能只是把同一個取樣器的步數調小。
(t 很小的時候比例看起來變大,但那裡 Var[x0∣xt] 本身已經趨近 0——xt 幾乎就是 x0,沒有什麼不確定性可漏。實作上最後一步通常直接取 β~1=0,不加噪聲。)
DDPM:扣掉一點,再抖一下
把 x^0 代入那個 closed form 的 Gaussian,直接抽樣:
xt−1=μ~t(xt,x^0)+β~tz,z∼N(0,I).
再把 x^0=(xt−σtϵθ)/αˉt 代進去整理,就是 DDPM 原文 [1] 的形式:
xt−1=αt1(xt−1−αˉtβtϵθ(xt,t))+β~tz.
每一步做兩件事:先用網路猜噪聲、扣掉一部分,然後再加回一點新的隨機噪聲。從 xT∼N(0,I) 出發跑 T 步,就得到一張圖——U1.2 最後那一段講的就是這件事,只是還沒給它名字:這種「照著每一步的條件分布一路往下抽」的取樣方式叫 ancestral sampling。
第二件事常常讓人困惑:好不容易去噪,為什麼又要加噪回去?回到 U1.3 那個廣場就看得清楚。每個人都照「周遭的人平均往哪去」移動——但站在附近的人,看到的平均幾乎是同一個方向。照這樣走下去,同一團裡的人只會越靠越近,最後疊在同一個點上:人群還在,但它塌成了幾個點。加回噪聲,就是讓每個人在照平均走完之後再隨機挪一下,人群才維持該有的寬度——也就是當下的 pt−1。
要注意這句話說的是**「朝平均走」會塌**,不是「確定性的取樣器」會塌——下一節的 DDIM 完全不加噪聲,卻不會塌,因為它補回去的是網路預測的噪聲方向 ϵθ 而不是零。確定與隨機的差別留到那裡談。
DDIM:同一個網路,完全不加噪聲
換個角度看同一件事。DDPM 是從「反向的條件分布」推出來的,所以它一定得逐步走。但 U1.1 的 closed form 其實給了更直接的東西:每一個 xs 都可以由 (x0,ϵ) 這一對直接寫出來,
xs=αˉsx0+σsϵ.
網路手上正好有這兩個的估計:x^0 和 ϵθ(xt,t)。那就直接代進去:
xs=αˉsx^0+σsϵθ(xt,t).
這不是「相信」,而是一條構造:如果 x^0 與 ϵθ 正好等於真實的那一對 (x0,ϵ),這一行就會精確落在真實的 xs 上。這就是 DDIM [2](η=0)。它有兩個很不一樣的性質:
- 完全確定:給定 xT,輸出唯一,沒有任何隨機。多樣性全部來自起點 xT——路上不需要再補隨機,也不會因此塌成一團,因為每一步補回去的是 σsϵθ 這個有方向的量。
- 可以跳步:上面那條構造裡 s 從頭到尾是自由的——它用的是 xs 與 (x0,ϵ) 的關係,不是相鄰兩步的 Markov 結構。所以從 t 直接跳到任意 s<t 都行。
第二點就是開頭那個問題的答案:
走幾步、每一步走多遠,是取樣時才決定的事,和訓練無關。
DDPM 之所以非走一千步不可,是因為它的每一步都建在「相鄰兩步的條件分布」上,步長一大 Q1 那個 O(βt) 就撐不住。DDIM 換掉的是依據:它不問「下一步的條件分布長什麼樣」,只問「照現在估出來的 (x0,ϵ),時刻 s 應該在哪裡」——而那個問題對任何 s 都問得出來。這就是 DDIM 能用 50 步、而 DDPM 要 1000 步的原因。
而且它用的是同一個訓好的 ϵθ,沒有重訓。DDIM 的一般式還帶一個 η∈[0,1] 控制每步加回多少噪聲:η=0 是確定版,η=1 就退回 DDPM。
符號DDIM 的一般式(含 η)長什麼樣?
從 t 跳到 s<t:
xs=αˉsx^0+1−αˉs−σ~2ϵθ(xt,t)+σ~z,σ~=η1−αˉt1−αˉs1−αˉsαˉt.η=0 時 σ~=0,第三項消失、第二項補滿 1−αˉs,就是上面的 DDIM。所以這是一整族取樣器,η 控制每一步補回多少隨機。
動手兩行就能驗:為什麼 η=1 會退回 DDPM?
取 η=1、s=t−1,把 σ~ 的平方寫開:
σ~2=1−αˉt1−αˉt−1(1−αˉt−1αˉt).括號裡那一團可以直接化簡——αˉt=αtαˉt−1 是 U1.1 定義 αˉ 時就有的,所以 αˉt/αˉt−1=αt,而 1−αt=βt。代回去:
σ~2=1−αˉt(1−αˉt−1)βt=β~t.正是 U1.2 配出來的那個變異數。所以 η=1 的那一端就是 DDPM,DDPM 與 DDIM 只是同一族的兩個端點。
兩種走法,看得見
互動 demo:DDPM 與 DDIM 的軌跡。 兩邊用同一個 score(這裡直接用資料算出精確的 score,相當於一個訓到最佳的網路)、同一組起點,只有 η 不同。把 η 從 1 拉到 0,軌跡會從抖動變成光滑,但終點都落在資料上——這就是「邊際相同」看起來的樣子。把步數從 200 降到 50、25、10,終點離資料會越來越遠,而 η=0 通常掉得慢一些。另外注意 η=0 的軌跡明顯是彎的,這件事 U2 會再拿出來講。
(要提醒的是:這個 demo 的 score 是精確的,所以看不到「網路有誤差時,加回噪聲能把樣本拉回 pt」那一面——那要真的訓練一個網路才看得到,留到 U1.5。)
如果步長縮到 0 呢?
到這裡取樣器已經可以跑了,所以接下來這一節不是在補救前面的任何東西——它是換一個視角,看同一件事在步長趨近 0 的時候長成什麼樣子。U1.3 最後問的正是這個:那個流動有沒有一個嚴謹的數學模型在描述它?有,而且答案會順便告訴我們「噪聲該加多少」其實是一個旋鈕,不是一個定數。
把步長寫成 Δt=1/T、βt→β(t)Δt,U1.1 那條 xt=1−βtxt−1+βtϵt 的遞迴在連續時間的極限下就是一條 SDE:
dx=−21β(t)xdt+β(t)dWt,t:0→1.
第一項把樣本往原點縮,第二項持續灌噪聲——正是 forward process 在做的事。
Anderson(1982)[3] 證明了一件很漂亮的事:把時間倒過來,它仍然是一條 SDE,而且 drift 裡多出一個 score 項:
dx=[−21β(t)x−β(t)∇logpt(x)]dt+β(t)dWˉt,t:1→0.
Song et al.(2021)[4] 進一步指出:還存在一條完全沒有隨機項的 ODE,它推動的邊際分布與上面那條 SDE 在每個 t 都相同:
dtdx=−21β(t)x−21β(t)∇logpt(x)(probability-flow ODE).
注意 score 前面的係數:SDE 是 β,ODE 只有 21β。
補充少掉的那一半 score 去哪了?
關鍵在 Fokker–Planck 方程(M3.2):噪聲項對分布造成的擴散 21βΔpt 可以改寫成一個散度的形式
21βΔpt=∇⋅(21βpt∇logpt),也就是「擴散」可以被吸進 drift 裡,變成一個沿著 ∇logpt 的移動。所以我們可以拿掉噪聲項,同時從 drift 扣掉那一半 score——分布的演化完全一樣,只是每條軌跡不再隨機。
把這個改寫代回 Fokker–Planck,drift 項與擴散項就併成一項:
∂tpt+∇⋅(ptut)=0,ut(x)=−21β(t)x−21β(t)∇logpt(x).那個 ut 正是上面 PF-ODE 的速度場,而左邊這條方程式有名字:continuity equation(M2.2)。它說的只是東西不會憑空出現或消失——ptut 是「流量」,某一點的密度會上升,只能是因為流進來的比流出去的多。
所以「SDE 與 ODE 的邊際相同」不是巧合:把擴散吸進 drift 之後,兩邊滿足的是同一條 continuity equation。U2.1 會把它反過來用——先指定想要的 pt,再去找推動它的 ut。
這件事之後會被推廣成一整族取樣器(U3):噪聲要注入多少,其實是一個可以調的旋鈕。
三者的關係整理成一張表:
| forward SDE | reverse SDE | PF-ODE |
|---|
| 邊際 pt | 相同 | 相同 | 相同 |
| 單條軌跡 | 隨機 | 隨機 | 確定 |
| 離散版 | 加噪 | DDPM | DDIM |

圖:同一組邊際,兩種走法。 兩組軌跡從同一批起點出發,上面是 reverse SDE(抖動)、下面是 PF-ODE(光滑);左側兩個 t=0 的邊際分布看起來一樣。差別不在最後停在哪裡,而在路上抖不抖。
DDPM 是 reverse SDE 的一階離散,DDIM 是 PF-ODE 的一階離散。
它們共用同一個 ϵθ,因為兩者需要的都只是 score。
用廣場再說一次「邊際相同」是什麼意思:一千個人從同一批位置出發往資料走,一組人邊走邊隨機晃(SDE),一組人走得筆直(ODE)。每隔一段時間對整個廣場拍一張照,兩組人的分布會一模一樣——不一樣的只有每一個人走出來的那條路。所以「同一組邊際」講的是照片,不是路線。
注意這裡出現了第二套誤差帳。 Q1 算的是「在固定的一步上,用一個 Gaussian 代替混合分布錯多少」——那是模型族的誤差,O(βt)。這一節講的是「這一步是某條連續時間方程式的一階離散」——那是離散化的誤差,O(Δt)。兩者都正比於步長,但量的是不同的東西:前者就算你有精確的 score 也還在,後者就算模型族選得完美也還在。要少步生成,兩筆都得付。
一個留著的問題
課堂提問Q2
DDPM 與 DDIM 用同一個網路,一個隨機、一個確定,數學上都對——因為它們推動的邊際相同。
那它們的取樣結果會一樣嗎?步數少的時候,哪一個比較好?
先想一想,再展開看整理後的答案
「邊際相同」是連續時間、無限步的敘述。真正在跑的是有限步的離散化,而兩者的誤差來源不一樣:
- ODE(DDIM)的誤差來自軌跡本身是彎的,而 Euler 用直線去逼近它——步數越少,割線與曲線的差距越大。
- SDE(DDPM)除了同樣有 drift 的離散誤差,每一步還會注入噪聲;但反過來說,score 項會把偏離的樣本拉回當下的 pt,等於自帶一點修正能力。
所以「哪一個好」沒有一個跟情況無關的答案,它取決於這兩種誤差誰佔上風:
模型誤差大的時候,SDE 的修正有東西可修;模型幾乎沒有誤差的時候,剩下的只有離散化,SDE 的噪聲就只是多餘的抖動。
這個判準是可以驗的,而且它會在課程裡出現兩次、結論方向相反——兩次都對:
- U1.5 與 U3 的 toy 上,速度場是精確算出來的(沒有網路誤差),於是確定性的那一端在幾乎所有步數都不輸。
- 真實模型的文獻上,網路誤差不可忽略,於是在步數多到離散化誤差夠小之後,帶噪聲的取樣器往往品質更好——那個交叉點量的是前一種情況不存在的東西。
要把「拉回」與「彎曲」各自寫成算得出來的量,我們需要先有「路徑」與「速度場」的語言,那是 U2 與 U3 的事。
這是一個方法,不是定律
我們並不是「隨便挑了一個 Gaussian Markov chain」,而是從想要的目標一路倒推並設計:一條每一步只改一點點、並且我們可以計算,而且最後會走向一個好抽的 noise distribution 的路。
但這也意味著,這個單元每一件事都是人挑的:加的是 Gaussian noise、縮放挑成 1−βt、終點挑成 N(0,I)、schedule 挑 linear 還是 cosine。這些選擇讓數學變得非常乾淨——從頭到尾都只有 Gaussian,所以每一個 q(xt∣x0) 都有 closed form。
而乾淨是有代價的,它把幾件事綁在一起了:
- 起點分布只能是 Gaussian,因為 forward process 就是往那裡收斂的。
- 路徑完全被 αˉt 決定:x0 到 xT 之間的分布怎麼變,除了調 schedule 之外沒有別的自由度。
這個單元我們先接受了這些選擇,把整條路走完。U2.0 會回頭問:如果不想被綁住呢?
消化一下
參考文獻
- Ho, J., Jain, A., Abbeel, P. Denoising Diffusion Probabilistic Models. NeurIPS 2020. (ancestral sampling 的形式。)
- Song, J., Meng, C., Ermon, S. Denoising Diffusion Implicit Models. ICLR 2021. (DDIM 與含 η 的一般式、跳步取樣。)
- Anderson, B. D. O. Reverse-time diffusion equation models. Stochastic Processes and their Applications, 1982. (反向 SDE 的來源。)
- Song, Y., Sohl-Dickstein, J., Kingma, D. P., Kumar, A., Ermon, S., Poole, B. Score-Based Generative Modeling through Stochastic Differential Equations. ICLR 2021. (probability-flow ODE 與「同一組邊際」的統一觀點。)