[Stable Diffusion] ControlNetとReference-Only

この記事ではStable Diffusionの派生技術「ControlNet」について解説する。

関連記事

目次

ControlNet

ControlNetは2023年2月にスタンフォード大学の研究者から発表されたStable Diffusionの派生技術。
SDの通常の入力に加えて画像を入力し、生成画像の構図やスタイルを操作することができる。

モデル構造

ソースコードから具体的なモデル構造を調べた。
ControlNet/cldm/cldm.py at main · lllyasviel/ControlNet · GitHub


ControlNetの構造(クリックで拡大)

学習済みのU-NetのIN0からMIDまでのパラメーターをコピーしてControlNetを作り、元のU-Netのパラメーターは固定して学習する。(画像の灰色の層は学習しない)
ControlNetには条件画像(=ヒント画像)が入力され、ControlNetが出力する潜在ベクトルをU-Netの対応するskip connectionに足し合わせる。この際、全てのパラメーターが0で初期化される1x1のZero Convolution層を通すことで、学習初期には元のU-Netと同じ出力になるようにして学習を安定させる。
画像では省略しているが、全てのAttentionブロックはPromptの埋め込みベクトルを受け取る。

学習

学習には教師画像\(x_0\)、教師画像のPrompt\(c_t\)、教師画像に対応するタスク特化の条件画像\(c_i\)が必要となる。
例えば論文では画像\(x_0\)に対して機械的に生成したエッジ画像を\(c_i\)に用いる実験が行われている。この条件で学習すると、ControlNetにエッジ画像を入力することで出力結果の構図を制御することができるようになる。
データセットは5万件もあれば十分学習可能。

モデルは以下の損失関数を最適化することによって学習する。
Prompt \(c_t\)は50%の確率で空の文章に置き換えられる。これにはCFGの無条件モデルを学習する効果もあるが、更にControlNetの場合はPromptの代わりに\(c_i\)から意味を学習するように促進する効果もあると論文では分析されている。

\begin{align} Loss = \mathbb{E}_{(x_0,c_t,c_i),t,\varepsilon}\left( \|\varepsilon - \varepsilon(z_t,t,c_t,c_i)\|^2 \right) \end{align}

Reference-Only

Reference-OnlyはMikubill氏が公開しているAUTOMATIC1111の拡張機能「sd-webui-controlnet」で2023年5月13日に実装された機能。入力画像の画風・スタイルを維持して異なる画像を生成することができる。

ControlNetの拡張機能に含まれているが、モデルが存在せずControlNetとは構造が大きく異なる。

モデル構造

ここからソースコードを解読した。
sd-webui-controlnet/scripts/hook.py at b2f9c7353242162ae66a3453b0c7105aa95d6adc · Mikubill/sd-webui-controlnet · GitHub

ControlNetとは異なり、条件画像はVAEのエンコーダーで潜在ベクトルへと変換される。
その後、各ステップに対応するノイズが加えられ、SDのU-Netそのものに一旦入力される。その際に、U-Netに16個存在する各AttentionBlockに含まれるSelf-Attention部分の入力値を保存しておく。(出力は何にも使われない)
そして、保存された値を以下の図のように生成過程のSelf-AttentionのQ, Vに結合し、Self-Attention部分をCross-Attentionとして利用する。このようにして、条件画像のスタイルを画像生成の過程へと反映させている。


Reference-Onlyの構造

Reference-Onlyの詳細な構造

Reference-Onlyは0から1までの強度を指定することができる。
U-Netが保有する16個のAttentionBlockは以下の図のように順位付け(attn_weight)されており、順位0から強度分の割合のBlockにだけ先述のCross-Attentionが適用される。それ以外のBlockは通常のU-Netと同じように機能する。
例えば強度が0.7のときは先頭から70%分、つまりIN7(順位0)からIN1(順位11 < 11.2 = 16×0.7)までのブロックだけがControlNetと接続される。


AttentionBlockの順位

AUTOMATIC1111での使い方

インストール

AUTOMATIC1111では、Mikubill氏が公開している拡張機能「sd-webui-controlnet」を導入することでControlNetが利用できるようになる。

Extensionsタブ→Install from URLタブで「URL for extension's git repository」の欄に以下のURLを入力して「Install」ボタンを押す。

https://github.com/Mikubill/sd-webui-controlnet

web UIをリロードすると、txt2imgやimg2imgのタブの下部にControlNetの設定欄が追加されている。


ControlNetの画面

パラメーターファイルは別途ダウンロードして配置する必要がある。
以下のページからパラメーターファイルをダウンロードし、「stable-diffusion-webui/models/ControlNet」に配置する。
comfyanonymous/ControlNet-v1-1_fp16_safetensors at main

ControlNet設定画面のModel選択欄の右にある🔄ボタンを押すと、配置したモデルがModelの選択肢に追加されていることが確認できる。


ControlNetのModel選択欄

使用例 (ControlNet)

処理はPreprocessorModelの2段階で行われる。

PreprocessorはControlNetに入力する画像を前処理する。例えばPreprocessorに「lineart_anime」を選び、Modelに「lineart」系を選ぶと、入力されたRGB画像を線画に変換してからControlNetに入力し、ControlNetによって着色される。
元から着色させるための線画を持っている場合は、Preprocessorの処理は不要なのでNoneを選ぶと良い。

画像入力欄の下にある 「Enable」にチェックを入れて生成する。(忘れがちなので注意)

以下の例では、いらすとやから借りてきた画像を用いて、「man, (red hair:1.2), illustration, (anime:1.4), white background, simple background」のPromptを指定することで髪の色を赤に変化させた。中央の画像がPreprocessorの出力で、右の画像がControlNetの出力。


ControlNetのlineart

ControlNetには他にも様々な学習済みモデルがある。論文や公式のGitHubのページにその使用例が掲載されている。

  • canny - エッジから画像生成。
  • depth - 深度情報から画像生成。
  • scribble - 落書きレベルの画像から画像生成。
  • openpose - 人間のポーズを検出して同じポーズの画像を生成。
  • tile - 条件画像を高画質化。

その他の設定項目については、「Control Weight」でControlNetの影響度を調整することができ、「Starting Control Step」・「Ending Control Step」でControlNetが影響を及ぼすStepの範囲を設定することができる。
ControlNetの種類によっては、最後のStepまで影響を及ぼし続けると現実的ではない画像が出力される可能性があり、Ending Control Stepを1より小さい値に設定して調整する必要がある。

使用例 (Reference-Only)

Reference-OnlyはPreprocessorから選択して使用する。
先述のようにReference-Onlyにはパラメーターが存在しないのでModelは指定できない。

条件画像に葛飾北斎の「神奈川沖浪裏」を指定してPromptから画像を生成した。


条件画像(葛飾北斎「神奈川沖浪裏」)

Reference-Onlyで生成した赤い船とクジラの絵

参考

解説

Reference-Only