見出し画像

BREAKの使い方を考察してみた

はじめに

この記事は正確性が保証されるものではなく、あくまで私一個人が限られた実験の結果をもとにまとめた内容です。
また、最初に提案しているBREAKの使い方は間違いであり、私の誤解を踏まえて出した結論は一番最後にあります。


BREAKによるブロック化?

StableDiffusionにおけるBREAKプロンプトの効果はいくつかの解説を読んだのですが、正直いまいち「これが正解」という答えに至っていません。
ただ、概ねの使い方として、トークン(指示詞)を1から75までを一つのブロックとして考える場合、1から離れれば離れるほど、生成結果に与える影響が少ないが、BREAKを入れることで、BREAK直後のトークンがほぼ1の位置として扱われることにできる、というのが私個人の理解です。

では、どういった場合にBREAKを使うのかというと、まずはトークンを入れたのになかなか反映されない場合ですね。そしてそう多くはないかもしれませんが、色移りなど、本来互いに独立していることが想定されたトークンが影響し合う場合です。

こういった問題を解決するのにBREAKを使うことがわかれば、「最初からBREAKで要素をブロック化し、そこにトークンを入れればよくない?」と思い、以下のスタイルシートを作りました。

absurdres, highres, ultra detailed, //品質
BREAK, //視点
BREAK, //人物
BREAK, //言動
BREAK, //服装
BREAK, //背景

ご覧の通り、指定したい要素の間にBREAKを最初から入れて、あとは各要素を指定していくという、甘い発想です。これが有効だと信じて昨日一日嬉々と生成していたのですが、実際どれほど効果があるのか、これから検証していきたいと思います。

BREAKは適当に使うべきものではない

まずは適当に以下のプロンプトを入れてみました。

absurdres, highres, ultra detailed, //品質
BREAK, //視点 cowboy shot,
BREAK, //人物 1 girl, salmon pink hair,
BREAK, //言動
BREAK, //服装 white blouse, black skirt,
BREAK, //背景 blue balloons,


服装こそキレイに反映されましたが、一枚だけ髪色が反映されず、そしてその一枚だけ背景にバルーンがありました。
ここで一つの仮説が提唱できると思います。つまり、合計6行あるプロンプトの中で5行しか反映されておらず、3枚目は反映される部分がズレているから髪色の指定が外れて、バルーンの指定が入ったということになります。
可能性としては、BREAKで区切られたブロックも結局トークンと同じ性質を持ち、後ろに行けば行くほど反映されにくいと考えられます。

ということで、BREAKを下から一つずつ消して生成していくと、

BREAK四つ


BREAK三つ


BREAK2つ


BREAK一つ

という結果になりました。本当にBREAKが減るにつれ、バルーンが生成されやすくなりますね。ここで一つ結論として、強調したいからといって無闇にBREAKを使うべきではない、と言えましょう。とりあえずBREAKすれば強調されるわけではなく、BREAKを使えば使えるほど、あとのトークンが反映されにくい領域に追い出されていくというイメージです。

色移り対策としては無力

上記の生成でわかるように、髪色はわりと色移りの被害者になりがちです。本当は目の色もそうなんですが、生成画像のサイズ的に見づらいのでここで髪色で色移り防止の効果を試してみましょう。

ここで、まず品質プロンプトと色指定のあるプロンプトだけを入れてみたのですが、どうやら1から75の範囲内で50より前にあるトークンであれば、色移りがなかなか起きないようなので、色と関係のないトークンで埋めて、50ぐらい以降になると、以下のプロンプトで顕著な色移りが発生しました。

absurdres, highres, ultra detailed,
cowboy shot, 1 girl, smile, walking, hodding a PET bottle, on street, city street, solo focus, cowboy shot, dynamic lighting, from front, salmon pink hair, black blouse, white skirt,


それでも一番前にある髪の色の影響が見受けられない様子ですね。とりあえずここで髪と服の間にBREAKを入れてみましょう。


あれ、全くと言っていいほど効果がなかったです。ということは、一般的に考えられる影響を断ち切りたい時にBREAKを入れるという使い方も有効とは言い難いですね。
BREAK自身は無意味ではないことが検証済みなので、ここで私が考えた可能性は
1.BREAKがあるにせよ色指定が近すぎるからだめだ
2.強調することで色移りを防止することはそもそも無理
の2つです。

とりあえず、白と黒が互いに干渉しまくっているみたいなので、スカートの白指定だけ上記プロンプトの一番前に移動させて、すぐ後ろにBREAKを入れて違うブロックに分けてみましょう。
absurdres, highres, ultra detailed,
white skirt,BREAK, cowboy shot, 1 girl, smile, walking, hodding a PET bottle, on street, city street, solo focus, cowboy shot, dynamic lighting, from front, salmon pink hair, black blouse,


なんとそれでも白がブラウスに色移りしてしまいました。
ということは距離の問題ではなく、そもそもBREAKは色移りに有効ではない可能性が非常に高いと考えられます。

BREAKのイメージ

色移り対策としては期待できないことがわかってしまったが、今回の実験でBREAKとプロンプト全体に対して新しい認識ができました。
まずBREAKでブロック化したいという最初の発想自体は間違いで、プロンプトはBREAKでブロックに分けることができず、最初から75トークン単位でブロック化されているのです。
ではBREAKってなんだろうというと、最初の検証で得た「後ろを押してしまう」イメージから考えると、プログラミング言語で使うBREAK文と同じで、「今の処理を中断してください」という指示です。プロンプトで言うと「今の75トークン単位のブロックはここで終わりです」、つまり空白でプロンプトのブロックを埋めて、次の75個のトークンを処理するということです。
ところが、同じ75個のトークンを扱うブロックでも、プロンプトが長くなるにつれ効果が薄くなっていく、イメージを図にすれば以下のようなものでしょう。


図は適当で..申し訳ないです

要するに、影響力がまだ強い1から50までで使ってしまうと、反ってその後ろのトークンの影響力を下げてしまう。もっといえば、BREAKが効果を発揮するのは今のブロックの残りはもう少なく、書いても反映されにくい時、いそのこと残りを捨てて次のブロックに書く、という場合だと思います。

結論

ということで、プロンプトを作成する時にはこうしてBREAKを活用すればいいのではないかという個人的な結論を出します。

  1. プロンプトは要素の反映させたい順で書きましょう。

  2. 40~50トークンまで来たらBREAKしましょう。

  3. 四回BREAKを使ったあとは、2の手順でBREAKをしたあと、BREAKの後ろに書くのではなく、まだ埋めていない一番前のブロックに戻って75トークンを埋めたら、最後入れたBREAKの後ろを書き続けましょう。

  4. 色移り対策にBREAKを使わない。

勿論これが正解だとは思っていないので、これからも試し続けていきたいと思います。ただ今の段階ではこの書き方で書いて、また何か発見があったら補足若しくは新しい記事を上げたいと思います。

補足

実際StableDiffusionのプロンプト入力欄の右上に、今のトークン数が表示されていますよね。
例えば1 girlを入れると、3/75という表示になります。その次にBREAKを入れると一瞬で76/150になりますね。どういう仕組で72個のトークンを埋めたのかは正直よくわかりませんが、BREAKの役割が一目瞭然です。
しかし、なぜかトークン数の表示が頻繁に消えたり、止まったり、エラー表示に変わったりします。WebUIを再起動すれば治るのですが、プロンプトを書いてる途中に「今トークン何個目だろう」と思ってみようとしたら正しく表示されていない時のめんどくささがすごいです…

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