💡

Stable Diffusionのプロンプトをチェックするテクニック

2022/09/22に公開

Stable Diffusionのプロンプトの鉄の掟

Stable Diffusionのプロンプトは、CLIPと呼ばれるAIモデルに入力されて、埋め込みベクトルに変換されて、画像を生成するDiffusion Modelの画作りのガイドとして使用されます。

そのCLIPですが、入力された文章をトークナイザで意味のあるトークン(形態素と言ってよいのかな?)に分割するのですが、そのトークンが75個までという鉄の掟があります。75個以上はどうなるかというと後半が容赦なく捨てられます。

要は、Stable Diffusionに頑張って100や200の単語を超える長文プロンプトを入力しても、最初の75個分以降の文章は、バッサリ捨てられてしまうということです。

捨てられたらもったいないですね。事前にチェックする方法を記載したいと思います。

Google Colaboratory(Google Colab)でプロンプトをチェック

簡単にGoogle Colabでチェックする方法です。手軽にチェックできるノートブックを作成しました。

004_prompt_checker.ipynb

これにはふぎりさんのプロンプト長さの限界と調べ方について(StableDiffusion)記事をめちゃ参考にしました。感謝です。

簡単にやっていることを説明します。以下で必要なライブラリをインストールします。

!pip -qq install transformers
!pip -qq install ftfy regex

CLIPのトークナイザを使えるようにするために、インポートとモデルのダウンロードを行います。

from transformers import CLIPTokenizer
tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14") 

プロンプトを入力します。以下は例文です。

prompt = "This is an apple"

以下のコードでサイズをチェックします。。

token_size = len(tokenizer.tokenize(prompt))
if token_size <= tokenizer.model_max_length - 2:
    print('OK: token size is ' + str(token_size))
else:
    print('NG: token size is ' + str(token_size))

上記の例だと以下のように表示されます。サイズは4で75以下なのでOKですね

OK: token size is 4

どのようにトークンが分割されるかを調べます。

print(tokenizer.tokenize(prompt)[0:tokenizer.model_max_length-2])

以下のように分割されています。

['this</w>', 'is</w>', 'an</w>', 'apple</w>']

実際の画像でチェック

単純なプロンプトで確認しましたが、次は実例でチェックしたいと思います。森羊羹さんが素敵な絵を生成できるプロンプトを公開されていたので、これを題材にしたいと思います。

https://twitter.com/Moriyoukan/status/1570728256202248194

念の為ですが、単純に素敵な画像だと思ったので題材としています。駄目な例としてくさす意図はありませんので、ご了承ください。

TwitterのALT情報のプロンプトは以下です。

prompt = "extremely detailed CG unity 8k wallpaper of a loli, alice, elementary school student girl with and white marble glowing skin and dot nose and perfect symmetrical pretty face with blush cheeks, pretty lively eyes, hair ornament, wearing standing in the wanderland with too many flowers,  Genshin_Impact, azur_lane,blue_archive,arknights  jewelry, glint, sparkle, light_rays lens_flare light_particles, hyper detailed, high detail, exquisite detail"

自分も同じプロントで画像を生成してみました。以下の自作のノートブックを使います。

https://karaage.hatenadiary.jp/entry/2022/08/29/073000

waifu-diffusionでseedは100に固定しました。コピペすると、以下の画像が再現できるのではないかと思います。

うん、全然悪くないですね。

ここでプロンプトのトークンのサイズをチェックします。

NG: token size is 96

75をオーバーしていますね。

トークンを調べてみます。

['extremely</w>', 'detailed</w>', 'cg</w>', 'unity</w>', '8</w>', 'k</w>', 'wallpaper</w>', 'of</w>', 'a</w>', 'lo', 'li</w>', ',</w>', 'alice</w>', ',</w>', 'elementary</w>', 'school</w>', 'student</w>', 'girl</w>', 'with</w>', 'and</w>', 'white</w>', 'marble</w>', 'glowing</w>', 'skin</w>', 'and</w>', 'dot</w>', 'nose</w>', 'and</w>', 'perfect</w>', 'sym', 'metrical</w>', 'pretty</w>', 'face</w>', 'with</w>', 'blush</w>', 'cheeks</w>', ',</w>', 'pretty</w>', 'lively</w>', 'eyes</w>', ',</w>', 'hair</w>', 'ornament</w>', ',</w>', 'wearing</w>', 'standing</w>', 'in</w>', 'the</w>', 'wander', 'land</w>', 'with</w>', 'too</w>', 'many</w>', 'flowers</w>', ',</w>', 'gen', 'shin</w>', '_</w>', 'impact</w>', ',</w>', 'az', 'ur</w>', '_</w>', 'lane</w>', ',</w>', 'blue</w>', '_</w>', 'archive</w>', ',</w>', 'ar', 'knights</w>', 'jewelry</w>', ',</w>', 'gl', 'int</w>']

,とか _がカウントされていて、後半のlight raysとかlens flareといった良さそうなプロンプトが完全に消えてしまっています。もったいない気がしますね。

とりあえず,_を削除してプロンプトを作り直してみます。

prompt = "extremely detailed CG unity 8k wallpaper of a loli alice elementary school student girl with and white marble glowing skin and dot nose and perfect symmetrical pretty face with blush cheeks pretty lively eyes hair ornament wearing standing in the wanderland with too many flowers  Genshin Impact azur lane blue archive arknights jewelry glint sparkle light rays lens flare light particles hyper detailed high detail exquisite detail"

これでチェックするとプロンプトのサイズはOK: token size is 75と、ギリギリOKになりました。これで同じSeedで画像を生成してみます。

これまた素敵な画像が生成されました。変更前後で、どちらが良いというのは主観もあるので難しいですが、後の方が、light raysやlens flareといったプロンプトの意図がより入った画像になっているのではないかと思います。

更に詳細の検証

私の記事をベースにさらに深い検証をしてくださっている記事です。私がサボってかかなかったところまで、詳しく検証、説明がされています。より詳しく知りたい方は、この記事と合わせてどうぞ。

https://tech.isid.co.jp/entry/2022/09/27/Stable_Diffusion入門-長い呪文は切り捨てられる

75トークン突破方法

AUTOMATIC1111版のStable Diffusionが、75トークンの制限を突破する実装をしていました。

AUTOMATIC1111が非常に多機能なので、変更量多く見えますが、基本的には埋め込みベクトルの重み付けして、足し合わせることで75トークンの制限を突破しているようです。

https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/2138

まとめ

Stable Diffusionのプロンプトをチェックする方法を記載しました。理屈を知っていると、よりよいプロンプトを練れそうですね。TwitterやDiscordでStable Diffusionに1000文とか入力している人をみかけて度肝抜かれたので思わず記事を書いてみました(笑)。

少しでもこの記事でよりよいStable Diffusionライフを送れる人が増えることを願っております。

参考リンク

https://note.com/hugiri/n/n970f9deb55b2

https://note.com/npaka/n/nb08941a36c8b

https://nakamura001.hatenablog.com/entry/2023/07/17/ChatGPTのトークン(token)について検証

https://acro-engineer.hatenablog.com/entry/2023/08/25/120000

関連記事

https://zenn.dev/karaage0703/articles/946d4566e5f7f6

変更履歴

  • 2022/10/18 75トークン制限突破に関して追記

Discussion