LCM-LoRAについて

 学習や生成をいろいろ試して分かったことをまとめます。


LCM-LoRAとは

 ただのLoRAです。サンプラーが変わったりCFG_scaleが1に近い値を設定しないといけなかったりとちょっと特殊ですが、結局LoRAであることは変わりません。

サンプラーについて

LCMサンプラーは意外と直感的に理解できます。Euler ancestralの究極版みたいな感じです。
以下は1ステップ分の図です。左の完全なノイズから、右の完全な画像までを目指していくイメージで図式化しています。

Euler法はノイズ予測に基づき一直線でノイズ除去をします。一方ancestralでは多めにノイズ除去をした後ランダムなノイズを付与します。LCMは完全な画像になるまでノイズ除去をし、その後ランダムなノイズを付与して目標の状態を得ます。
 ということで既存のサンプラーとそこまで挙動は変わりません。実はLCMでないモデルをLCMサンプラーで生成することもできます。ただしぼやけた画像しか出てきませんけどね。逆にLCMモデルに対して既存のサンプラーを適用することもできます。その場合は逆に書き込みが細かすぎて破綻した画像がでてきます。LCMモデルは各時刻でノイズ予測が一貫性を持つようになっているので、ランダムなノイズを付与してもちゃんと生成できるということですね。
 こうなると自然にEuler ancestralとLCMの中間のサンプラーを使ってみたくなりますよね?ComfyUIではそれを実現する拡張ノードがあります。

SamplerLCMAlternativeノードには二つの設定があります。euler_stepは指定した数値以下のステップでこのノードが適用されます。ancestralは0.0にするとEulerに、1.0にするとLCMになります。euler_stepを高く、ancestralを低くするほど書き込みが増えますが、破綻もしやすいです。

CFG_scaleについて

 LCMではcfg_scale(guidance_scale)は1~2くらいを指定するのがよいとありますね。これはLCM自体がcfg_scale=7.5(もしくは8.5?)の生成を再現しようと学習しているからです。論文では7.5で固定したと書いてあるんですが、diffusersのLCM蒸留コードを見ると、cfg_scaleが1ずれているんですよね。だから実質8.5なんじゃねとちょっと思っています。
 LCMの元論文では学習時にcfg_scaleは一定の範囲からランダムに選んでいました。そのためcfg_scaleを調整するための新たなモジュールが追加されています。LCM-LoRAではそのようなユーザーにとって分かりにくい変更を避けて、cfg_scaleを固定することにしたようです。そのため既存のLoRAとほとんど同じ方法で、使えるわけですね。この辺りのユーザー目線に立った実装がhuggingfaceチームの素晴らしい功績なわけですが、こういう話は伝わらないのが悲しいです。

CFG_scale=1か、それ以外か

 実はCFG_scale=1.0は特別で、ネガティブプロンプトの計算が必要なくなります。まあネガティブプロンプトが適用できなくなるのはデメリットでもあるわけですが、計算量が半分になります。バッチサイズ1だとあまり生成時間は変わらないんですけどね。LCM-LoRAでCFG_scale=1.0の生成が微妙な一つの要因として、学習時にネガティブプロンプトを使ってないからかもしれません。そのため私が前に記事出したLoRAが使えるのではと思っています。

ランクは1でいいらしい

そうらしい。すごい。

学習について

 学習だけはめちゃくちゃやっているので色々書いていきます。

既にあるLCM-LoRAから学習させるのが最強

 そりゃそうだろって感じなんですが、私はLCM-LoRAが出る前から学習を試みていたので、今までの努力は何だったんだろうという感じですね。しかもssd-1bのためのLoRAまであるし・・・。alpha=8らしいので、学習率は1e-4くらいをおすすめします。ただ上にあるようにランクは1でいいらしいので、あらかじめresizeしたLoRAを使うのがいいかもね。

EMAいらん

 論文ではEMAを使ってますが、いらんかも。学習が遅くなります。安定感はでるのかもしれないけど、時間かかります。

WD-15難しい

 Waifu-diffusion1.5のLCM-LoRAを作ろうとしたんですが、このモデルは修飾プロンプトの影響が大きすぎて難しいですね。キャプションをちょっと変えただけで画風が変わるのでめんどくさい。SSD-1BまであるのにSD2.1のLCM-LoRAはないなんて、悲しいですね。