Stable Diffusion学習の歴史

 完全に自分目線の歴史です。時系列は適当なこともあるよ。


2022/8

 モデルが公開されましたが、学習を始めた人は一部だけでしょう。

Stable Diffusionリリース 22日

 これまでの画像生成AIと違いモデルがオープンになったことで、誰でも自由に学習できるようになりました。StabilityAIが公開したコードには学習コードも含まれていたので、技術力さえあればこの時点で学習できたのかな。コードやモデルファイルはStabilityAIによるコードと、HuggingfaceのDiffusersライブラリの二つに分かれており、今でも混乱の原因になっている気がします。

Textual Inversion

論文自体はStable Diffusionの公開直前くらいに出たもののようですね。学習方法として最初に流行った方法で、27日には日本語記事が出てますね。はやい。

npakaさんが9月1日ごろ

この頃はStabilityAIベースのコードが使われていたみたいですね。
Textual InversionはテキストエンコーダのEmbedding部分のみが学習対象なので、表現力は小さいですが、必要VRAMもまた小さいです。最初は16GBくらい必要だったっぽい?このときはまだColabのGPUをただ乗りするやつが少なく、T4が使い放題だったので16GBでできれば問題にはならなかったです。ただすぐに8GBくらいでもできるようになってたと思います。

2023/9

 DreamboothやTextual inversionで新しい概念を学習する人が出始めます。わたしもこのころTextual inversionをやってましたが大した成果はあげられてなかったような気がしますね。またWaifu diffusionのような大規模ファインチューニングモデルもでてきました。
 この頃の学習コードは大抵画像を左右反転してかさまししていました。そのせいでAIは左右が分からないなんて言われてましたね。

Dreambooth

 正則化画像を同時に学習することにより、少量の画像で概念を学習できるDreamboothも公開直後に流行りました。論文自体も公開直後くらいに出たようですね。しかしこちらはUNetすべて(あるいはテキストエンコーダ含めて)学習するためハードウェア要件が非常に大きかったです。最初のコードは32GBのGPUが必要だったらしく普通の人間には手が届きません。これもStabilityAIベースのコードですね。
9月12日にはnpakaさんが記事を出しているようだ。

Dreamboothのメモリ効率化

https://github.com/ShivamShrirao/diffusers/tree/main/examples/dreambooth

 ShivamShrirao氏中心に、この時期から様々な工夫により10GB以下に抑えられるようになったようです。
主な工夫点

  • AMP

  • Gradient checkpointing

  • xformersやflash attention

  • VAE出力(Latent)のキャッシュ

  • bitsandbytesのAdamW8bit

gradient checkpointingはStabilityAIのコードではデフォルト実装されていましたけどね。

Waifu Diffusion

 アニメ特化のWaifu Diffusionは今までの方法ではなく純粋なファインチューニングモデルとして公開されました。WDはStabilityAIのコードから、Danbooruをスクレイピングしたデータセットを利用できるように改良したものを使っていたようです。V1.2は56000枚の画像を1エポックという今じゃ考えられないレベルのしょぼい規模ですが、当時はこれくらいの規模でも大変だったと思います。
Waifu Diffusionベースのコードで学習を試してる方も一部いました。

懐かしいですね。私はこの記事を見たあたりから頑張って学習し始めました。

2023/10

 NovelAIモデルのリーク(10月6日らしい)というとんでもないことが起きました。倫理的な問題はどうでもいいので置いといて、周辺技術がもれたことや、質の良いモデルが出たことでみんなのモチベーションが上がったことで、この月を境に一気に成長した感じがします。というわけで正義感のないわたしはリークした人に感謝すらしてますが、当時は学習の効率化に集中していて、リークについて知ったのは1週間後くらいというていたらくでした。

Hypernetwork

 リークによって明るみになった技術です。AUTOMATIC1111氏のwebui上で学習や生成が実装されました。モデルに小さなアダプターを追加するという方法によって、8GBのゴミGPUでも学習できる優れものでした(当時ぼくのPCも3070tiでちた)。Textual Inversionと比べてUNetにも作用するので表現力も高かったです。またアダプターなのでモデル構造を自分で決められるという面白さもありました。この頃は活性化関数何にしよっかなーとかやってましたが、最近始めた子は活性化関数なんて知らないですよね。
 他にもリークによってClip skipやトークン長の拡張(これはWDチームも既に提唱していた気がするけど)などが明るみになりましたが、学習にはそこまで関係ないかな。

Kohyaさんがnoteで学習コードを公開し始める

 当時のKohyaさんはShivamShrirao氏のDreamboothをWindows環境で動かすことに注力していたみたいですね。この頃はxformersやbitsandbytesを使える環境をWindowsで構築するのは難しかったです。xformersの代わりにFlash Attentionを使ったりとかそんな工夫です。また勾配までfloat16にするfull_fp16によって8GB以下でDreamboothを行う方法とかやってました。私の人生で一番カエルの絵を見ていた時期です。

俺も学習について記事を書き始める

 剪定事象でしかないですが、自分が書いてるので自分目線の話もするぞ。わたしはWDベースの学習コードに注力してました。当時はDreamboothが一般的でしたが、sks 1girlというプロンプトが受け入れられなかったので、使えませんでした。最初は30GBくらい必要だったので、GCPとかいう意味わからんサービスに金払ってやっていました。その後ShivamShrirao氏のDreamboothを参考に、StabilityAIベースのコードを書き換えてAdamW8bitにしたり、Trainerのtrain()をまるごとautocastしてAMPを実装したり、EMAを無効化することで16GBの学習を成功させました。これによりColabで学習できるようになったのですが、結局Googleに金を払うことに変わりはないですね。

diffusers->ckpt変換スクリプト

https://gist.github.com/jachiam/8a5c0b607e38fcc585168b90c686eb05

 DiffusersベースのモデルからStabilityAIベースへ変換するスクリプトです。その逆はdiffusersが実装していました。このスクリプトにより二つのコード間に完全な互換性が生まれたわけです。地味だけど偉業だと思います。

2022/11

 この時期からメモリ効率化はひとまずおわり、学習の精度を上げる方法をみんな追及していた感じがします。

Aspect ratio bucketing

 11月になるとNovelAIが自身の工夫点を公開します。ほとんどの内容はリークによって既にばれていたんですが、複数アスペクト比に対応できるするこの方法は知られていませんでした。いまやSDXLなど様々な基盤モデルで採用されているすごい手法です。

Waifu Diffusionの学習コードがdiffusersベースに

 WDの学習コードがdiffusersベースに置き換わりました。それとともにAspect ratio bucketingや、他のメモリ効率化方法も実装されて(わたしもxformers対応のPRを出してマージされてたりする)、ずいぶん使いやすくなりました。このコードを使ってた人なんてほとんどいないだろうけどねえ。

WD1.4 Taggerがでぃすこで限定公開

 もっと前かもしれませんが、WD1.4開発のために作られた画像のタグ付けモデルが公開されていました。これによりDanbooruからスクレイピングした画像でなくても、Danbooruタグを付けられるようになり、大きく進展しました。ただしPyTorchを使うことが多いSD界隈でTensorFlowとかいう謎のフレームワークが使われていてちょっと不便ですね。

Stable Diffusion 2.0 リリース 24日

 こんなやついたか・・・?と思うかもしれませんが、Attentionヘッド数やLinear projectionなどSD1系からの変更点がSDXLにも継承されており、こいつの遺伝子はちゃんと残っていますよ。v_predictionやsd2用clipは生き残れなかったみたいですが。

2022/12

 LoRAとsd-scriptsが公開された、激動の時代です。この時期から学習を試す人がいっぱい増えたんじゃないですかね。

sd-scripts公開

 Kohyaさんがnoteとかいうポエムを書きなぐるだけのクソサイトを捨てて、ついにGithubで自身の学習コードを公開するようになりました。まさにSD界で初日の出が起きた瞬間です!ちなみに一つ目のissuesを立ち上げたのはわたしだったりする。

LoRA

 SD学習にとって一番の転換点であることは疑いようがないですね。LoRAは元々LLM向けに提唱された手法ですが、それをSDの学習に利用し始めたのがcloneofsimo氏です。学習対象のパラメータ数が小さく、VRAM6GBくらいでも学習できるようになりました。学習結果のファイル容量も小さく、推論時に生成速度は変わらない、適用強度や複数適用も思いのまま、表現力も通常のファインチューニングとそこまで劣らないと最強の手法ですね。当時のLoRAはAttentionのq, k, v, outにのみ適用されていました。Diffusersベースのコードだったので、WDベースの学習コードに適用するのは簡単でした。

sd-scriptsがLoRAに対応 25日

 PRを見る限り、25日にでたっぽい?クリスマスは暇だったんですかね。
(俺も同じ日にLoRAについて記事あげてるやん・・)
 cloneofsimo氏から学習対象をAttention全体に拡張しています。1×1畳み込み層が実質全結合層と同じというのは目からうろことかしっぽとか出てきた記憶があります。またcloneofsimo氏の実装は保存したファイルのkeyが適当で、順番のみに依存している危険な実装でしたが、Kohyaさんはちゃんと適用したモジュールを基準にkeyを付けてましたね。その後Kohyaさん自身がwebuiへの拡張を実装したこともあって、LoRAの形式はKohyaさんのがデファクトになりました。

2023/1

sd-trainer公開

 自前で学習コードをつくりはじめました。公開っていったって他に誰も使っちゃいないですがね。それまではWDベースのコードを使っていましたが、1000行を越えてわけわかんなくなってきたので、一から書くことにしました。

2023/2

ControlNet

 lllyasviel氏は学習についてもチュートリアルを書いてくれており親切でしたね。ただしStabilityAIコードを元にしており、AMPなどがなくて敷居は高かったです。ただしAMPを実装するのはそんな難しくなかったですがね。わたしがWD1.5用のControlNetを作っていたときは、10月ごろまでStabilityコードを使っていた経験が生きてうれしかったです。そもそもlllyasviel氏はControlNetをFloat16で学習することには反対だったようですが。

LoCon

 KohakuBlueleaf氏が提唱しました。これまでAttention層の全結合層+1×1畳み込み層にしか適用されていなかったLoRAを、ResNet層等の3×3畳み込み層まで拡張する方法です。元々cloneofsimo氏も実装済みであり、kohyaさんも実験していたようですが流行させたのはKohakuBlueleaf氏ですね。まあ当時はというかいまでもLoRAより強いけどサイズも大きいナニカくらいにしか思われてなさそう。

2023/3

LyCORIS

 LoConのリポジトリをLoRAの様々な拡張を実装するものに発展させたのがLyCORISです?最初はLoHAが実装されていました。学習時にbackwardを定義するなんて初めてみたのでびっくりしました。

Pytorch 2.0リリース

  SDの学習に関係あるのはscaled_dot_product_attentionとtorch.compileでしょうね。前者はxformersとかいうよく分からないのなしでもAttentionを改善できるようになりました。といってもこれがでたころにはxformersのインストールはずいぶん簡単になりましたが。torch.compileは最近になってやっと使われる動きがあるようです。

2023/5くらい

コピー機学習法

 2chだか3chだかが初出のようで、正確な時期はよく分からないんですが、すごい方法です。この手法自体は学習スクリプトに新たな機能が必要になるわけではないんですが、この手法が出てからLoRAの事前マージなどコピー機学習法にとって便利な機能がでたり、二つのLoRAをマージするときの正確性が議論されるようになるなど、学習スクリプトに大きな影響を与えたと思います。これを越える方法を100年くらい考えてるんですが、思いつきません。

2023/6

Stable Diffusion XL0.9 リリース

 SD1系に比べてモデルが大きく、二つのテキストエンコーダを利用したり、画像サイズの情報をモデルに入力する必要があったりとトリッキーな設計が多く、対応は大変だったような気がします。モデルのサイズも大きくLoRAのおかげでVRAM8GBでもいけるやんみたいな風潮を吹き飛ばしてしまいました。8GBでの学習はかなりきつきつな設定でないと難しいです(と思ってたらFP8使えば余裕そう)。テキストエンコーダもそこそこの大きさなため、テキストエンコーダ出力のキャッシュも導入されました。
 SDXLではコミュニティ内での工夫でしかなかったAspect ratio bucketingやnoise offsetが採用されていたりと、なんだかうれしかったですね。

LECO

 特定の概念を除去したり付与したりするLoRAです。学習用画像データが必要ないという驚きの手法ですね。

こんかいはここまで。