見出し画像

SDプロンプト管理の新境地!Jinja2テンプレートの活用法

下の写真、どれもおなじプロンプトで管理しています。わかる人には「sd-dynamic-promptを使ってるんだよ」と伝えますとああなるほどと納得できると思うのですが、プロンプトをランダム生成するという本来の使い方とは違って、もっと複雑なプロンプト管理を楽にする記述方法について記事にします。

one girl portrait in Coast. age28, flat chest body type. wear biker jacket. Dappled Light.
multiple three woman group portrait in bathroom. age28, small breast body type. wear biker jacket. slanting light of setting sun.

先に書きましたとおり、ひとつのプロンプトで管理しています。こちらです。

{# 年齢 #}
{% set age = '28' %}

{# バストサイズ #}
{% set breast = ['flat', 'small', 'medium', 'large'][0] %}
{% set breast_size = breast + ' chest' if breast == 'flat' else breast + ' breast' %}

{# 人物 #}
{% set human = ['girl', 'woman'][0] %}

{# グループ写真かどうか #}
{% set is_group = false %}
{% set target = 'one ' + human if not is_group else 'multiple ' + choice('two', 'three', 'five') + ' ' + human + ' group' %}

{# ファッション #}
{% set fashion = choice(
'elegant dress',
'biker jacket',
'cute skirt police costume'
) %}

{# 照明と背景 #}
{# 室内かどうか #}
{% set is_room = false %}
{% if is_room %}
  {# 室内の場合 #}
  {% set light = 'slanting light of setting sun' %}
  {% set place = choice('bedroom', 'bathroom') %}
{% else %}
  {# 屋外の場合 #}
  {% set light = choice(
  'Afternoon sun',
  'Dappled Light',
  'Scorching Sunshine'
  ) %}
  {% set place = choice('Coast', 'urban street', 'tourist spot') %}
{% endif %}


{{ target }} portrait in {{ place }}.
age{{ age }},
{{ breast_size }} body type.
wear {{ fashion }}.
{{ light }}.

「これ本当にプロンプト!?」と疑いたくなるような、普段プロンプトに触れている人ほど見慣れない記号がいたるところに登場しています。この一見難解にも感じる書き方が、慣れるととても便利なので説明していきます。


この記法が便利なとき

  • one girlとmultiple five woman groupなど、表現を変えたいけど単純な書き換えでは済まないとき

    • flat chest と medium breastを行き来しないといけないときなども、どうしてもあるよね

  • 室内照明から屋外照明に変わったときなど、プロンプトの全域で書き方が変わるとき

  • 服装によってsee-through skinなどを効かせたいとき、または意味ないときの付け外し

などなど、工夫次第でいろいろ便利になります。

やること

  • ○ sd-dynamic-promptのJinja2テンプレート機能を使った、便利なプロンプトの書き方

    • 試しているうちに見つけた有効な語句を組み合わせしやすくなる

    • 変数やif文が使用でき、プログラム可能なプロンプトが書けるようになる

やらないこと

  • × StableDiffusionの基礎知識やwebuiの導入方法、拡張機能のインストール方法

    • sd-dynamic-prompt拡張機能そのものの有効化、無効化についての方法にも触れません

  • × sd-dynamic-promptそのものの機能についての説明

    • これは後日別記事で行いますのでこの記事では触れません

  • × Jinja2テンプレートについての網羅的なリファレンスやフォロー

    • あくまでStableDiffusion webuiのプロンプトで便利に使っている手法の紹介にとどまります

無料記事部分と有料部分の範囲について

無料記事部分に、この記事の情報価値の全てがあります。有料部分に関しては補足説明を兼ねた実践レシピがあります。無料部分に価値を感じた上で有料部分のちょっとした補足やレシピに価値を感じていただけそうでしたら購入を検討いただけるととても嬉しいです。

前置き

 筆者はプログラマーなので“プロンプトをプログラマブルに書ける方法がある”と知ると「なるほどそりゃ便利だ」と思います。ですがほとんどの人はなんだかよくわからないかもしれません。それに、AIのいいところのひとつとして、“プログラムを書かなくてもコンピューターに仕事をさせることができる”というものがあります。せっかくプログラムを書かなくてもプロンプトでコンピューターに高度な処理をさせることができるようになったのがAIのいいところなのに、なんでわざわざプロンプトをプログラムみたいに書く必要があるのでしょう?確かに、StableDiffusionを導入してwebuiさえ起動できれば、プログラムを書かない多くの人がコンピューターに仕事を与えて高度な絵を出力できるようになります。
 プロンプトの良いところのひとつに、“命令に矛盾や間違いがあってもAIがうまいこと吸収、もしくは解釈してくれる”という点があります。例えば

バラは赤い。青いバラを出力せよ

とプロンプトを(英語で)与えても、AIはエラーにはならずきちんと何かしらの絵を出力してくれます。極端なことを言えば、「5本の足が生えた人魚」をプロンプトに与えても、AIはエラーにはならず必ずなにかしらの解釈をして絵を出力してくれます。
 それに対してそうはいかないのがプログラムの世界です。
 書き方や記号に必ず何かしらの意味があり、省略しても間違った書き方をしてもエラーになります。今回紹介するJinja2テンプレートは、広義のプログラミングと言えますので、今まである程度自由に書けてたプロンプトにプログラム的な窮屈さを追加してしまいます。そんな窮屈なデメリットを追加してしまってもそれでもなお、便利で強力なプロンプトが書けるようになるのがJinja2テンプレート機能になります。

 この記事の対象読者として、プログラマブルなテンプレート機能に理解が深いいわゆるプログラムの知識がある人だけにとどまらず、プログラムは苦手だけどプロンプトに変数を使ったりif文くらいは挑戦してみたいという人も範囲に含んでいます。言い方を変えると、プログラムの知識がある人にとっては少し冗長な説明が多いかもしれません。
 プログラムに苦手意識はあるけど導入してみたいと思っている人は、最終的にはできなければ無効化すればいいだけです。何かしたことで壊れたりはしませんので、ダメでもともとという気持ちで挑戦してみてもいいかもしれません。(※ただしこの記事でお勧めする方法で万が一不具合が起こったとしても、筆者には責任は取れませんのでご了承ください)

前提条件

  • stablediffusion webui か、webui-forgeが立ち上がっている

  • その画面にアクセスできている

  • 拡張機能として最新のsd-dynamic-promptsが導入されていて有効化されている

「拡張機能」タブからsd-dynamic-promptsが有効になっているかチェック
  • txt2imgタブまたはimg2imgタブ内のGenerationタブ内にDynamic Promptsが表示されている

    • なおかつ開いた状態のときに「Dynamic Prompts 有効化」にチェックが入っている

    • (拡張機能導入初期状態でチェックが入っているはず。何らかの理由で外れている人はチェック入れてください)

txt2imgのGenerationタブで開いた時の状態。
筆者の環境は他の拡張も入っているので読者と画面が多少違うかもしれないが、
赤丸のところが似たようになっていればとりあえずヨシ!

はじめてみよう

txt2imgまたはtxt2imgタブ内のGenerationタブにある、Dynamic Promptsを開いた状態で、さらに「Jinja2テンプレート」を開き「Jinja2テンプレートを有効にする」にチェックを入れてください。これで完了です。

赤丸のところに注目

やっぱやめたいとき

 注意したいのが、Jinja2テンプレートを有効にすると、これまでDynamicPromptを使ってきた場合はこれまでの書き方は無効になるということです。つまり素のDynamicPromptの書き方とJinja2テンプレート有効化したときの書き方は共存できません
 ここが導入の最初のハードルになるかもしれません。導入してみてやっぱわからないとかやめたい、となったときは逆の要領で「Jinja2テンプレートを有効にする」のチェックを外せば、もとのDynamicPromptの書き方が有効になります
 言い方を変えれば、今までDynamicPromptを使ってこなかった人は導入することによって失うものが何もないので、その点はもしかしたら安心かもしれません。

あとはコピペするだけ、自分で変えたいときは……?

 小見出しにあるとおり、ここまで準備が済めばあとは記事冒頭にあるプロンプトをコピペするだけです。このあとカスタマイズ方法について無料記事部分でも触れていきます。プログラムに不慣れな人に対して必ず注意してもらいたいのが

  • 半角文字であることを常に意識する

    • 特に半角記号や半角スペース

      • 記号やスペースは常に必ず半角になります

  • 記号やスペースを省略しない

    • 特に記号やスペース、改行位置などは意味があって存在している場合が多いので、なれない内は記号やスペースを省略したり改行位置を変えたりするとうまく動かなくなる場合があります

  • うまく動かないときはそのまま深掘りするのではなく、最初に立ち返ってやり直すように

    • 苦手な人に多いのが、だめだった場合にもとに戻さずだめなまま次に進もうとするのが、問題をより複雑にします。必ず「ここなら動く」地点を作って、だめな場合はそこに戻るようにする癖をつけてください。「ここなら動く」地点を増やしていくイメージです

    • つまり戻り方は常に意識しています。「ここなら動く」地点からどこをどう変えたか把握しながら進めてください

プロンプトの説明

Jinja2テンプレートを使うことで、私はプロンプトに大きくわけて二種類の部分を作っています。設定部分と使用部分です。

おおむね、プロンプトの前半部分に設定部分があります。後半に使用部分を作っています。仕様上の意味もありますが自分の管理が楽だと感じるからです。

年齢

これが設定部分

{% set age = '28' %}

使用部分。最後の方にあります

age{{ age }},

これでプロンプトはこう出力されます。

age28.

バストサイズ

設定部分

{% set breast = ['flat', 'small', 'medium', 'large'][0] %}
{% set breast_size = breast + ' chest' if breast == 'flat' else breast + ' breast' %}

使用部分

{{ breast_size }} body type.

これでこのように出力されます

flat chest body type.
※もしくは
small breast body type.
medium breast body type.
large breast body type.

「※もしくは」と書きました、実際にはこのプロンプトでは "flat chest" だけが必ず出力されます。どういうことなのか、設定部分が2行になっているので、1行ずつ説明していきます。

{% set breast = ['flat', 'small', 'medium', 'large'][0] %}

最後のほうの文字に [0] とあります。ここの半角ゼロの部分を半角数字のゼロから3まで変更してみてください。プロンプトは次のように変化します。

ゼロの場合
flat chest body type.
1の場合
small breast body type.
2の場合
medium breast body type.
3の場合
large breast body type.

つまり
['flat', 'small', 'medium', 'large']
の部分を左から数えてゼロ番目、1番目、2番目、3番目を使用しますというふうに伝えているのが、この行の最後の方の文字
[0]
になります。[0]だと左からゼロ番目、つまり'flat'を使用しますと設定しています。

設定部分の2行目はプログラムが判断して、flatが選ばれていたら "flat chest"に、それ以外なら "small breast" などのように"chest"ではなく"breast"を使うようにしている部分です。

人物

設定部分

{% set human = ['girl', 'woman'][0] %}

ここはもうわかりますね。
['girl', 'woman']を左から数えてゼロ番目を使用しています。
ただし、ここでは使用部分はまだありません。次に書く、グループかどうかを設定してから、まとめて使用します。

グループ写真かどうか

設定部分

{% set is_group = false %}

人物とあわせて判定して再設定

{% set target = 'one ' + human if not is_group else 'multiple ' + choice('two', 'three', 'five') + ' ' + human + ' group' %}

使用部分

{{ target }} portrait in {{ place }}.

グループ写真だった場合は
multiple five girl group
ソロだった場合は
one girl
みたいな出し分けをしたいので、その設定を行えるようにしています。

is_group = false

の場合はソロ写真。

is_group = true

の場合はグループ写真になります。true | false は必ず半角小文字のみで書いてください。
もしくはTrue | False のように頭文字だけ半角大文字でも大丈夫ですが、このへんの細かい仕様を記事内で伝えることは出来ないので、半角小文字とだけ覚えておいてください。
'true' | "true"など、半角シングルクオーテーションや半角ダブルクオーテーションで囲むのも、今はやめておいてください。
true | false に限っては、書き方は、ここでは何も囲まず半角小文字のみと覚えておいてください。

ファッション

設定部分

{% set fashion = choice(
'elegant dress',
'biker jacket',
'cute skirt police costume'
) %}

使用部分

wear {{ fashion }}.

ファッションはchoice()という記述を使って、ランダムに選ぶようにしています。ここを
['elegant dress', 'biker jacket', 'cute skirt police costume'][2]
このように指定すると、今までのような「左をゼロと数えて何番目」という指定の仕方にもできます。
冒頭にも書きました、Jinja2テンプレートを使うとこのあたりの記述がとても強力になります。スカートがあるなら風でなびく様子、学校にいるなら制服、ショートパンツなら明るく活発な雰囲気、といったように服装にあわせて他のプロンプトも変化する書き方が出来るようになるからです。
今回は詰め込みすぎでおなかいっぱいだと思われますので、服装は単に3つからランダムに選ぶようにしていますが、いろいろと工夫が楽しい箇所になります。

背景と照明

背景によって照明のプロンプトを変える、または照明によって背景を変える、もちろん服装によって背景を変えるなど、いろんな変化が出来るようになります。いろんなやり方がありますが、ここでは難しく考えず、室内かどうかだけまず判断して、室内の場合の背景と照明、屋外の場合の背景と照明、というように分岐するやり方で書きました。

設定部分

{% set is_room = false %}
{% if is_room %}
  {# 室内の場合 #}
  {% set light = 'slanting light of setting sun' %}
  {% set place = choice('bedroom', 'bathroom') %}
{% else %}
  {# 屋外の場合 #}
  {% set light = choice(
  'Afternoon sun',
  'Dappled Light',
  'Scorching Sunshine'
  ) %}
  {% set place = choice('Coast', 'urban street', 'tourist spot') %}
{% endif %}

使用部分

{{ target }} portrait in {{ place }}.

の{{ place }}の部分と

{{ light }}.

今回の例はプロンプトが短いのでそこまで複雑になってないので恩恵がわかりにくいかもしれませんが、「室内かそうでないか」によってプロンプトの複数にわたる部分で変化するとき、このJinja2テンプレートは力を発揮します。

今回は
{% set is_room = false %}
という設定部分を一つ作って、true | false で管理するようにしています。trueにしたときは室内だと判断して分岐するようにしています。

まとめ・ポイント

こういったテンプレート記法にはじめて触れる方に向けてポイント解説をしてみます。

  1. 設定部分は {% 〜〜〜 %}で囲む

    1. 括弧は波括弧

    2. 波括弧とパーセント、スペースの並びで囲む

    3. 半角で

  2. 使用部分は{{ 〜〜〜 }}で囲む

    1. 波括弧二つとスペースで囲む

    2. 半角で

  3. 原則、囲んだ部分は改行せず1行で書く

    1. あれ?何カ所か改行してるところあるよね?

      1. どこで改行入れられるか、わからないうちは変なところで改行するとエラーになって意図した通りに動かなくなるから、慣れないうちは改行の使用をひかえたほうがいいかも

  4. 無理に最初から高度なことをしようとせず、最初は変数の設定と使用だけにとどめるなど

    1. 最初は無理にif文やfor文を使わないほうがいいかも

有料記事について

 有料記事は、以上を踏まえての実例画像付きレシピ集5選になります。無料記事部分で解説したことに価値を感じているのが前提の記事になります。特に、無料記事部分でわからなかったところを有料記事でサポートするものではありませんので、無料記事でピンとこなかった方に対して無理やり購入を促すものではありません。
 テンプレート機能は使えば強力な機能ですがあくまでプロンプト作成を支援するための機能ですので、高度な使い方が出来たからといって生成画像の品質が上がるといったものではありません。使えなくて当たり前の機能なので、これがわからなかったから何か品質に悪い影響がある不安になるというようなことは一切ありませんので、気軽に挑戦してみてください。

(※)記事で説明した部分についての個別相談は、有料無料に関わらずできません。

(※)実例画像に過激な表現は一切含まれていません 

ここから先は

8,640字 / 11画像

¥ 1,200

期間限定 PayPay支払いすると抽選でお得に!

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