しかしサンプラーに関して直感的な資料があまりないうえ、 オイラー法 (Euler), ホイン法 (Heun), 線形マルチステップ法 (LMS) といったごつい名前が並んでいて 何のことだかわかりにくいように思える。
このサンプラーというのはいったい何なのだろうか。
サンプラーは微分方程式を数値的に解くアルゴリズム
拡散モデルでのサンプラーは「画像生成を常微分方程式に帰着し解いてくれる」アルゴリズムである。微分方程式とは、普通の方程式で未知の変数を求めるように、未知の関数を求めるような方程式であって、 しかも方程式中に関数の微分を含むようなケースである。 そのうち未知関数が1変数であるものが常微分方程式と呼ばれる。
常微分方程式を代数的な方法一般的に解くのは難しい一方で、 コンピュータのシミュレーションで近似解を求めることは容易にでき、多くの近似アルゴリズムが発見されている。 このようなアルゴリズムは画像生成以外の分野では ソルバ(solver,解くものという意味)と呼ばれることの方が多い。
しかし画像生成がなぜ微分方程式と関係するのだろうか。 これを説明するには拡散モデルがどのように画像を生成するのかの数理に踏み込む 必要がある。 拡散モデルは「画像が劣化してノイズになっていく過程」を定義し「その逆過程を機械学習によって推定する」 というアイディアに基づいていた。 微分方程式は、特に時間微分を考慮するときは「システムの時間発展を記述する」のにピッタリであるから、 これを使うのは順当なアイディアに思える。 物理現象としての拡散過程も拡散方程式という微分方程式で記述されることからも これは(物理学とからすると)自然な発想であるのだろう。 特に順過程(画像からノイズ)が微分方程式に従うのは理解しやすいが、逆過程はどうなのだろう? と思うかもしれないが、実は 拡散方程式の逆過程はまた拡散方程式になる ことが知られている。
まとめると
- 未知の関数がある:ノイズが画像になる未知の過程がある
- 未知の関数の時間微分が出てくる:ノイズが時間とともに増えていく(逆過程では減っていく)
ただし微分方程式の中でもランダムノイズを等式中に含む 確率的微分方程式(stochastic differential equation, SDE)と呼ばれる 問題のクラスに該当する。とはいえ数値的に解く場合は常微分方程式と 確率常微分方程式に多くのソルバをそのまま使える。

図: ノイズから画像への変換 = 生成過程を表現する確率微分方程式 のイメージ
生成の様子のイメージ
サンプラーが画像を生成する様子は「画像が各点であるようなベクトル空間」を想像すると理解しやすい。 ベクトル空間とは二次元空間とか三次元空間のようなものをより高次元に一般化したものだ。 画像が例えば256×256の解像度をもち、RGBの3色からなるとすると、一枚の画像は 256×256×3 = 196,608次元空間の一点を占めると考えることができる。196,608次元空間のなかから好ましい画像に対応するような一点を探し出すのが画像を生成するということだ。
拡散モデルにおいて画像からノイズを除去するということは、この空間中の一点xを 「自然な画像のなさそうなところ」から「自然な画像のありそうなところ」へ動かす 操作と考えることができる。 画像がなさそうなところはノイズのような見た目の画像がある部分で(図の色の薄い部分) 画像のありそうなところは学習データのあった部分や周辺(図の色の濃い部分)にあることになる。

図: ベクトル空間中で見た画像生成のイメージ。赤が生成される画像の真の値、青の軌跡は遅いサンプラー、 緑の軌跡は速いサンプラーが生成しようとしているところ。
このイメージに基づくとサンプラーは「点をどれぐらい大きく一度に動かすか、動きの勢いを決めるアルゴリズム」 と考えることができる。モデル本体に対してサンプラーは
- 生成途中の画像または初期ノイズ:今いる点x
- 動かす方向:ニューラルネットの出力dx = f(x)によって決める
- 動かす大きさ:サンプラーがこれまでのx, dxの履歴から決める
このサンプラーが適切なステップ幅を決めてくれることは重要で、 小さすぎて生成が遅くなったり、大きすぎて収束しなくなったり することを避けなければいけない。
なお通常の関数自体の推定に興味がある通常のケースとは違い、 画像生成では収束先(= 完成した画像)にしか興味がないことに注意する。 すると基本的にステップ幅は(収束に害のない範囲で)大きいほうが良い。 ステップ幅が大きい = 少ない反復数で生成が終わる、となるからだ。
数学的には発散して壊れたりしない限りは「同じ収束点に違う速度で向かっていく」だけであるから、 同じ初期値・同じモデル・違うサンプラーでは大きく違う生成結果が生まれることはないはずである。 とはいえ実際はどの方向から収束点に落ちていくかなどが変わるので、見た目の印象は 多少違うことがある。そのためサンプラーは基本的には速いものを使う・ いい初期値やプロンプトを見つけた後の「最後の味付け」で変えてみる、 という運用が良いのではないかと思う。
有名なサンプラー
DDPMサンプラー拡散モデルのはしりではDDPMで使われたサンプラー。 このころは拡散モデルが微分方程式と関係があるとか、サンプラーの工夫で サンプリングが高速化できるという発想はなかったことに注意する。 要するに何もしないサンプラー、ニューラルネットの算出した更新値dx をそのまま反映するアルゴリズムである。 遅いが悪さもしないと考えられる。
Eulerスケジューラー
いわゆるオイラー法である。 1次法の一種であり、以前の更新量を参照しないのでコード自体は DDPMサンプラーに近く、実装も簡単である。 少ない違いはステップ幅を時刻差に合わせて動的に決めている点である。 またHeun schedulerはオイラー法の改良版である2次法、ホイン法に基づく。
DPMソルバー
汎用ODEソルバの取り込みではなく、ニューラルネットによる拡散モデル専用のカスタマイズがされているらしい。 パラメータの違うDPMソルバー1/2/3と改良版のDPMソルバー++がある。
"DPM-Solver: A Fast ODE Solver for Diffusion Probabilistic Model Sampling in Around 10 Steps" で提案された。