webuiの構文処理
はじめに
webui の構文処理についてまとめたドキュメントがなかったため、本記事ではその概要を整理して紹介します。
なお、記述内容に誤りなどがありましたら、コメント等でご指摘いただけると幸いです。
AUTOMATIC1111/stable-diffusion-webui
Stable Diffusion を比較的簡単に扱えるようにするための GUI(以下、webui)です。
最近はあまりアップデートされていないようですが、ユーザー数は非常に多いツールです。
なお、後継として forge ui なども存在し、こちらはメンテナンスが続いているようです。
この記事の目的
本記事では主に、webui 構文がどのように処理されるかについて解説します。
各構文が持つ意味や効果の詳細については、公式 Wiki をご参照ください。
構文解析の概要
webui の構文解析は、すべての入力を一度に解析して抽象構文木(AST)を生成する方式ではなく、解析と処理を順次繰り返しながら進行します。
そのため、各構文の処理結果が後続の処理に影響を与える場合があります。
各構文の説明
以下、処理される順に各構文について記述します。
コメント
1girl, solo, ...
# これは、とてもすごいプロンプト
#
を付けます。以降、改行までの部分はプロンプトとして無視します。
ただし、Danbooru タグなどに #
を含むタグを使用すると、意図せず改行までが無視されてしまうため注意が必要です。
Extra networks
<networkname:filename:multiplier>
- multiplier は省略可能です。
この構文は処理後、すぐに空文字列に置き換えられます。
例えば、以下のプロンプトの場合:
cat A<lora:spam:0.5>ND dog
Extra network の部分が置き換えられた後、AND 構文の処理前には
cat AND dog
となり、AND 構文が有効となります。
また、この構文の解析時は単に文字列が含まれているかどうかを確認するだけのため、この構文より後に記述された他の構文は、extra network には適用されません(重みの変更やスケジュールなど)。
AND 構文
prompt :weight AND prompt: weight
- weight は省略可能です。
AND 構文で分割された各要素に対して、以降の処理が個別に適用されます。
解析は単純に正規表現パターン \bAND\b
に一致する部分を検索するだけであるため、エスケープはできません。
また、後続で処理される構文との兼ね合いが考慮されないため、構文内に AND
を含めると意図しない解析結果になる可能性があります。
たとえば、後述の Editing 構文において:
[cat AND dog|bard]
というプロンプトは、単に [cat と dog|bard]
という文字列として解釈されます。
Editing 構文(スケジュール)
[first|second]
[from:to:when]
https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#break-keyword)
Lark 記述の仕様上、括弧内で |
が消費されないため、以下のようなプロンプトを書いてしまうと、そのブロック内の Editing 構文がすべて無効になってしまいます。
[:|] or (:|)
ただし、前述の通り、AND 構文で分割された各ブロックごとに解析が行われるため、AND で区切られた範囲外の部分には影響しません。
たとえば、
[cat|dog] bard [:|] AND [cat|dog]
の場合、AND の左側は単に [cat|dog] bard [:|]
という文字列として扱われ、右側では Editing 構文が有効に機能します。
また、逐次的な処理により、解析結果が後続の処理に影響を与える場合があります。
例として、
(cat:[4.3|1.0]) BR[E|]AK dog
は、奇数ステップでは (cat:4.3) BREAK dog
となり Attention/BREAK 構文が有効になりますが、偶数ステップでは (cat:1.0) BRAK dog
となります。
なお、AND 構文はこの前に処理されているため、結果として AND が完成しても、後続の処理で改めて扱われることはありません。
Attention 構文(重み)
(prompt:weight)
[prompt]
- weight は省略可能です。
こちらは /
によるエスケープが可能なため、プロンプト内で記号を文字列として扱いたい場合はエスケープを利用してください。
BREAK 構文
prompt BREAK prompt
たとえば、
(cat BREAK dog)
の場合、内部では (cat :1.1)(BREAK:-1.1)( dog:1.1)
といった具合に解釈され、BREAKを含む文字列がエンコードされます。
A girl holding a sign that reads: (BREAK:-1.1)
カッコ内であっても、重みが 1 であれば問題ありません。
(cat [BREAK] dog)
の場合、[BREAK]
の weight は -1 になるため、cat と dog はそれぞれ CLIP によって別々にエンコードされます。
ただし、あまり多用すると計算誤差が生じる可能性があるため、ネストの深い部分に BREAK を配置するのはおすすめしません。
例:
dog [[[[[[[[[[((((((((((BREAK))))))))))]]]]]]]]]] cat
おわりに
黎明期から徐々に進化してきた経緯もあり、webui 構文の解析は非常に複雑で面倒な部分が多いです。
また、逐次的な処理とステップ数などのパラメータが影響し、プロンプトを見ただけでは最終的な解析結果を予測するのは難しいです。
最近は webui 自体の更新も停滞しているようですが、参考資料としてご活用いただければ幸いです。
Discussion