見出し画像

Stable DiffusionでText Encoderの出力を短く切ってみる

先日、Text Encoderの出力の順序を変える実験を行って、順序がStable Diffusionの生成画像に影響を与えないことを確認しました。

その後、さらにコードを読み込んで、Text Encoderの出力の長さが変わっても、画像生成モデル自体は正常に動作するはずだと気づきました。

また、少なくともdiffusersのUNetの実装には、Text Encoderの出力にマスクを付けて渡すことができるようになっていて、Text Encoderの出力のどのトークン位置の状態を使うかを細かく指定することもできるようになっていました。(ただし、xformersを有効にすると、私の環境ではエラーになりました。)

そこで、本記事では、Text Encoderの出力を短く切って生成した画像を比較してみることにします。

他のStable Diffusionの関連記事

実験

実験では、プロンプトとネガティブプロンプトの両方で同じトークン長の入力を使用します。これは、実験に使用したLayered Diffusion Libraryの仕様上、全てのUNet呼び出しをまとめてバッチ処理するため、同一バッチ内のプロンプトのトークン長を同じにする必要があるためです。ただし、マスクについては、個々のプロンプトごとに別々に指定することが可能です。

この制限を考慮し、実験では、次の4つの設定を使用しました。

  1. 全トークンを使用

  2. マスクをありで、前からEOSトークンまでを使用

  3. マスクをなしで、前から50トークン目まで使用

  4. マスクをなしで、後ろから50トークン目以降を使用

使用したプロンプトは、次のものになります。

  1. 1girl

  2. cat maid

  3. 1girl red hair blue eye black skirt

  4. 1boy 1girl in class room

生成画像は次のようになりました。

Text Encoderの出力長を変更

この結果から、EOSトークンまでの情報があれば、プロンプトの内容のかなりの部分は再現でき、破綻の度合いも限定的になるということが分かりました。

しかし、EOSトークン以降の情報も画像の細部までプロンプトの指示通りに破綻なく生成するために必要ということも示されました。前から50トークンまでの画像を見ても、まだ細部に不自然な箇所(例えば、上から3段目の画像の左右の手すりの高さの違い)があることに気が付きます。

逆に、EOSトークン以後の情報だけを使っても(最右列)、意味のある画像は生成されないことも分かりました。

追加実験

EOSトークン以降の情報が必要だとして、どのような情報があればよいかを知るために、追加実験を行いました。

追加実験では、EOSトークン以降のText Encoderの出力を、別のものと置き換えて画像生成をしました。具体的には、以下の設定で画像生成を行いました。

  1. 全トークンを使用(上の実験の1.と同じ)

  2. EOSトークン以降を、マスクを使って無視(上の実験の2.と同じ)

  3. EOSトークン以降を、EOSトークン位置の状態で上書き

  4. EOSトークン以降を、空文字列のText Encoder出力で上書き

  5. EOSトークン以降を、ゼロテンソルで上書き

EOSトークン以降を上書き

この中で、3列目(EOSトークン位置の状態で上書き)と4列目(空文字列の出力で上書き)は、それぞれ異なる形で2列目(マスクで無視)を改善していると考えられます。

それに対し、5列目(ゼロテンソルで上書き)は画像の破綻が増える結果となったようです。

この記事が気に入ったらサポートをしてみませんか?