メインコンテンツへスキップ
見出し画像

Dynamic Prompt はランダムなプロンプトだけじゃなく変数も使える

    2025.5.24追記
    YAML内のキーの重複について追記しました。

    Dynamic Prompt とは?

    StableDiffusion webui A1111 や ComfyUI でプロンプトをランダムにする機能拡張です。

    {red|white|black} bikini
    
    👇 ランダムで1つ選ばれ、下記のいずれかが使われる
    
    red bikini
    white bikini
    black bikini

    インストール方法は上記の配布ページか、ぐぐると沢山出てきます。
    公式な書式はこれです。

    https://github.com/adieyal/sd-dynamic-prompts/blob/main/docs/SYNTAX.md


    プロンプト入力欄での使い方

    ランダムに1つ選択

    {red|white|black} bikini, from {above|below}
    👇
    red bikini, from above
    ...
    white bikini, from below

    重み指定

    `数値::プロンプト` で優先度を指定します。
    合計が「1」になる必要はないみたいです。
    下記の例では `red` の採用率が高くなります。

    {0.5::red|0.1::white|0.2::black} bikini

    複数選択

    `数値$$` を先頭に入れると指定した個数が選択されます。

    {2$$cat|dog|bird|monkey}
    👇
    cat,dog

    複数選択の接続文字を「,」以外にする

    `数値$$ 文字 $$` を先頭に入れると選択されたプロンプトの間の文字を指定できます。

    {2$$ and $$white|black|red} bikini
    👇
    white and red bikini

    選択する個数の範囲を指定する

    `最小値-最大値$$` を先頭に入れると選択する個数の最小、最大を指定できます。
    こちらも `最小値-最大値$$ 文字列 $$` で接続文字も指定できます。

    {1-2$$ and $$dog|cat|bird|monkey}
    👇
    cat
    dog and bird

    最小値、最大値を省略することもできます。

    {-2$$dog|cat|bird|monkey}
    {2-$$dog|cat|bird|monkey}


    ファイルから選択する

    下記フォルダにファイルを置くと、ファイルからプロンプトを読むことができます。
    stable-diffusion-webui/extensions/sd-dynamic-prompts/wildcards

    基本的な使い方

    上記フォルダに color.txt を作り、下記のように記述します。

    red
    blue
    white

    `__ファイル名__` でファイル内から1行選ばれます。

    __color__ bikini
    👇
    white bikini

    個数指定などの書式も使える

    上で記述した `個数$$` などの書式も使えます。

    {2$$__color__}
    👇
    blue, red
    
    {2$$__color__|__color__}
    👇
    blue, red
    
    {2$$ and $$__color__}
    👇
    blue and red

    ファイル内でも書式が使える

    ファイルの中でも個数指定や接続文字指定ができます。

    # costume.txt
    {red|white|pink} bikini
    school uniform, {red|blue} bowtie
    
    
    __costume__
    👇
    black bikini

    ファイルの中からファイルを呼び出す(ネスト)

    color.txt、costume.txt の2つを用意した例です。

    # color.txt
    red
    white
    black
    
    # costume.txt
    __color__ bikini
    __color__ skirt
    
    
    __costume__
    👇
    white bikini

    ファイルをワイルドカードで指定する

    `__ファイル名*__` で指定文字から始まるファイルをランダム選択できます。

    # color_a.txt、color_b.txt がある状態
    __color*__
    👇
    両方のファイルからどれか1つ

    YAML、JSONも使える

    シンプルなテキストファイルの他、YAML、JSONも使えます。
    この記事ではJSONは省略します。

    YAML

    # example.yaml
    color:
      - white
      - black
    costume:
      swimsuit:
        - bikini
        - one-piece swimsuit
      school:
        - bow tie, school uniform
        - buruma, gym uniform

    使用する時は `__ファイル名__` ではなく
    `__キー__` なので注意してください。

    もしYAML内のキーと同じファイル名が存在すると、YAMLのほうが優先されるようです。この場合 color.txt が存在してもYAML内の color から選ばれます。

    下の階層を選ぶ時は `/` で区切ります。

    __color__ __costume/swimsuit__
    👇
    black one-piece swimsuit

    やはりこれまでと同じ書式が使えます。
    ネストもできるし、個数指定もできます。

    color:
      - white
      - black
    costume:
      - __color__ bikini
      - __color__ one-piece swimsuit
    __costume__
    👇
    white bikini

    YAML の便利なところ

    改行を含めることが出来るので便利です。

    color:
      - red
      - black
    costume:
      swimsuit:
        - __color__ bikini
        - __color__ one-piece swimsuit
      school:
        - school uniform, __color__ bowtie
        - gym uniform, __color__ buruma
    situation:
      - |
        __costume/swimsuit__, beach, blue sky, sunbeam,
        jumping, from below
      - |
        __costume/school__, classroom,
        classroom chair, classroom desk,
        window, blue sky
    __situation__
    👇
    black bikini, beach, blue sky, sunbeam,
    jumping, from below

    複数のファイルに同じキーが存在したら?

    hair_color.yaml と hair_style.yaml に同じ `hair` というキーが存在すると仮定します。
    この時は最初に認識したキーが採用されます。
    下の例では何度実行しても `black hair` `silver hair` は採用されません。

    # hair_color.yaml
    hair:
      - twintails
      - ponytail
    
    # hair_style.yaml
    hair:
      - black hair
      - silver hair
    
    # 入力プロンプト
    __hair__
    
    # 結果
    twintails または ponytail 👈 最初に認識した `hair` が採用される

    キーの重複に対応するには先頭のキーをファイル名にする

    ファイル名を先頭のキーにすればその後のキーが他のファイルと重複しても問題ありません。
    呼び出す時は `__{先頭のキー}/{目的のキー}__` という感じに `/` で区切ります。

    # hair_color.yaml
    hair_color:
      hair:
        - twintails
        - ponytail
    
    # hair_style.yaml
    hair_style:
      hair:
        - black hair
        - silver hair
    
    # 入力プロンプト
    __hair_color/hair__, __hair_style/hair__

    変数が使える!!

    `${変数名=値}` で変数を定義できます。

    ${cloth_color=red}
    ${weather=blue sky}
    ${cloth_color} bikini, ${weather}
    👇
    red bikini, blue sky

    変数の値をランダムから選びたい

    値の部分でこれまでの書式が使えます。

    ${color1=__color__}
    ${color2={red|white|black}}

    変数の値を“一度だけ”ランダムから選びたい

    `${変数名=!値}` と「!」を追加すると即座に値を評価して固定します。「!」が付いていないと変数が呼び出されるたびにランダムに選ばれてしまいます。

    # 全部同じ色になる
    ${color=!{black|white}}
    ${color} hair, ${color} bikini
    👇
    black hair, black bikini
    
    # ランダムな色になる
    ${color={black|white}}
    ${color} hair, ${color} bikini
    👇
    black hair, white bikini

    初期値を指定する

    `${変数名:初期値}` で指定します。
    変数が定義されていないとエラーになるので初期値を指定すると安全です。

    # 変数 color が指定されていない状態で color を使う
    # 初期値が無いとエラーになる
    ${color:white} bikini
    👇
    white bikini

    使用例

    color:
      - red
      - black
    angle:
      - from above
      - from below
    costume:
      - ${color:white} bikini
      - ${color:white} one-piece swimsuit
    item:
      - ${color:red} beach ball
      - ${color:red} parasol
    situation:
      - |
        __costume__, beach, blue sky, sunbeam,
        jumping, ${angle:from below}, __item__
    
    ${color=!__color__}
    ${angle=__angle__}
    __situation__
    👇
    red bikini, beach, blue sky, sunbeam,
    jumping, from above, red beach ball

    水着とボールの色を揃えたいので変数colorは「=!」記法で固定しています。変数angleは固定する必要がないので「=」で定義しています。

    ファイルに引数を渡す

    特定のファイル内だけで変数を固定したい時などに使います。

    __situation(color=!__color__,angle=__angle__)__

    コメント行

    テキストファイルの行頭「#」はコメント行になります。

    # ここはコメントなので選択されない
    red
    blue

    YAMLは元々 # がコメントですね。

    situation:
    # 使い方
    # 変数 color: 水着と小物の色
    # 変数 angle: 画角
      - |
        __costume__, beach, blue sky, sunbeam,
        jumping, ${angle:from below}, __item__

    DynamicPrompt構文の中でもコメントが入力できます。
    しかしsd-webui-prompt-all-in-oneのようなプロンプトを自動整形する機能拡張とは相性最悪です。

    __situation(
    # 水着と小道具の色
    color=!__color__,
    # アングル指定
    angle=__angle__
    )__
    
    # しかし sd-webui-prompt-all-in-one によって下記のように整形されてしまった……
    __situation(  # 水着と小道具の色  color=!__color__,  # アングル指定  angle=__angle__ )__,

    他にもいろいろ

    junja2テンプレートも使うと条件分岐や繰り返しなども使えるようです。そこまで行くともうスクリプトですね。

    https://github.com/adieyal/sd-dynamic-prompts/blob/main/jinja2.md

    宣伝

    小さい女の子のイラストを作っています。支援サイトもやってますので良かったら支援お願いします。


    あなたへのおすすめ