見出し画像

ChatGPTによるプロンプトの生成

えーっと、note初記事です。つたない内容でしかもメッチャ長文ですがお付き合いください。

今回はタイトルにあるように、Stable DiffusionのプロンプトをChatGPTで生成する、今までとはちょっと違うやり方をご紹介します。

簡単なレクチャーも含むのでかなりのテキスト量ですが、最後まで目を通していただければ良いことがきっとあります。

はじめに

まずこれからお伝えする技法は現時点でGPT4の使用が前提となっています。(追記:Bingでも可能になりました)
3.5では、私の技量が至らず安定した結果が得られていません。

しかしながら、先だってこの手法をお伝えした有志の方々が3.5及びBingでの実現を模索されていることを予めお伝えしておきます。

今回の手法を発見した経緯とネタバレ

ことの発端は遡ること1か月前、プロンプトを自動でジャンル分けしてデータベースに流し込み、逆にそこからプロンプトを生成するPythonプログラムを組もうとしたことです。

その際にデータベースへの入出力にJSON形式が分かりやすいだろうと考えました。

そのプログラムをChatGPT3.5に相談すると、(要約すれば)事前にプロンプトのジャンル項目などをリスト化しておかないとPythonとOpenai APIの組み合わせでも厳しい、とのこと。danbooruタグだけならやれなくもないけど力技と手間が半端じゃないから却下。

次にGPT4に期待し、OpenAIに課金してGPT4にプログラムの相談をしているとき、「これをJSONに書き換えるプログラムは可能ですか?」と聞くところを「これをJSONに書き換えるは可能ですか?」と入力ミス状態で質問を投げかけてしまいました。すると、はい、できますと丁寧な説明付きであっさり変換してくれたのです。

GPT4ならそのままいけるのか!

続いて、じゃあこれはどうだろうとJSONからプロンプトを作ってとお願いしたら、はいわかりましたとあっさりやってくれました。

えっ……マジ?

ということで、これが全てです

ChatGPTを経験されている方ならばこれだけでもう何をやればいいのかわかっちゃったでしょう。

まあ、それじゃあまりにもぶん投げすぎなので具体的なものを紹介します。

実際の入力と出力の例

まず最初に、何がどうなるかを知ってもらうために変換前の入力テキストとその出力結果を以下に示します。(ChatGPTへの命令もプロンプトと呼んでいますから画像生成のと混ざっちゃうので入力とか命令とかお願いと記述します)

入力するプロンプトの例

15歳ぐらいの少女、金髪、青い目、白いワンピースを着ている、草原に立っている、風が吹いている、片手で髪をかき上げている、遠くには山が見える、その手前には川が流れている、夕日が山の上に見える、少女は微笑んでいる、

出力されたプロンプトの例

A 15-year-old girl with blonde hair and blue eyes is standing in a windy meadow. She is wearing a white dress and is smiling as she lifts her hair with one hand. In the distance, mountains can be seen with a river flowing in front of them. The setting sun is visible above the mountains.

出力例をDeepLで翻訳

ブロンドの髪と青い瞳を持つ15歳の少女が、風の吹く草原に立っている。白いワンピースを着た彼女は、片手で髪を持ち上げながら微笑んでいます。遠くには山々が見え、その手前には川が流れています。山の上には夕日が見えています。

ご覧のように、出力されたプロンプトは自然言語となります。
注目すべき点は、入力テキストの一番最後に書いてある「少女は微笑んでいる」が出力テキストの前半に現れることです。これを頭の片隅に留めておいてください。

出力画像の例

使用モデル:NyaFuMix-v4A(未公開)
同プロンプト別シード

出力された自然言語プロンプトに普段使っているクオリティ系のプロンプトなどを足して画像を生成すると不思議とイメージしていたものに近い絵が出力されます。

また、入力に関しては既に皆さんが苦労して書いたプロンプトをそのまま流し込んでも問題なく処理されます。

注意点は自然言語に弱いSDモデルも存在するということで、お使いのチェックポイントで必ず良い結果を得られる、というわけではありません。

これに対する対応は後日、別の記事でお伝えできればと思います。

具体的にどうするの?

冒頭にも書いた通り、現時点ではChatGPT4の使用が前提です。これを執筆している現在、月額20ドルで3時間ごとに25回までしか使えません。だから実験するときは慎重に。

では本題。
前述の出力を得るために記述した命令は以下となります。

これはtext-to-image promptを日本語で表記したものです。最初にこれを英語に翻訳してください。次に、翻訳したテキストをJSONに書き換えてください。次に、そのJSONをもとにtext-to-image promptを英語のまま書いてください。

15歳ぐらいの少女、金髪、青い目、白いワンピースを着ている、草原に立っている、風が吹いている、片手で髪をかき上げている、遠くには山が見える、その手前には川が流れている、夕日が山の上に見える、少女は微笑んでいる、

注意:記事最後の追記を参照してください。

ここまで引っ張った割にはこれだけです(笑)
だって、ホントにこれだけだから最初に書いちゃったらそれで終わっちゃうんだもん!

でもここで、ポイントとなるのは単純に英訳しているわけではなく、中間処理にJSON形式の記述を挟んでいることです。

JSON形式を使うことの意味

JSON(JavaScript Object Notation)とはプログラムやデータベース同士でデータ交換を行うためのシンプルかつ分かりやすいデータの記述方式です。

{
 "人物": {
  "性別": "女性",
  "年齢": "15",
  "髪色": "黒",
  "目の色": "緑",
  "表情": "悲しい"
 },
 "衣服": {
  "種類": "コート",
  "色": "赤"
 },
 "場面": {
  "場所": "森",
  "天候": "雨天",
  ・
  ・
  ・

といった記述方法で、人間にも優しいフォーマットです。

前述のGPT3.5ではこの大項目、小項目への関連付けと振り分けができないよ
、ということでした。でもGPT4ならできる!

JSON形式の各項目は、

{
  "object": {
    "key": "value",
    "key": "value"
  }
}

と、呼びます。

これをSD用のプロンプトに当てはめると、objectはイラストを構成する要素(人物、背景、物体など)、keyは構成要素を特徴付ける部品(人物の場合、目、髪型、年齢など)、valueは具体的な内容(髪型の場合、ポニテ、ロング、ツインテなど)となります。

さて、これを理解した上で先ほどの日本語プロンプトをGPT4で変換したJSONを見てみましょう。

{
  "character": {
    "gender": "female",
    "age": "15",
    "hairColor": "blonde",
    "eyeColor": "blue",
    "emotion": "smiling"
  },
  "clothing": {
    "type": "dress",
    "color": "white"
  },
  "scene": {
    "location": "meadow",
    "weather": "windy",
    "background": {
      "mountains": "visible",
      "river": "visible",
      "sunset": "visible"
     }
  },
  "action": {
    "character": "lifting her hair"
  }
}

いかがでしょう。何となく意味が読み取れますよね?

つまり、今回ご紹介しているこの手法は、GPT4自らが分析し系統ごとに整理整頓した単語群を使い、GPT4自身がアレンジを加えたプロンプトを出力する、というのがキモなのです。

ベースとなるJSONがガイドラインとして存在するおかげで全体の構成からブレることなく、的確な自然言語型のプロンプトを出力してくれるわけです。

ま、偉そうに言ってますが、たまたま偶然見つけただけなんですけどね……。

この手法のメリット・デメリット

メリット・デメリットは多数ありますが、主だったものをここに明記します。

メリット1:日本語メモ書きでいいんです

これ、最大のメリットです。

とにかく単語でも、文章でも、フワッとした内容でも、日本語でも英語でもいいのでメモをしてください。

そしてそれをさっきのGPTへのお願いテキストと一緒にぶち込んでください。

するとGPT君はあなたが書いたテキストの内容を分析し、単語を類別し、単語の関連性を再構築してJSONにまとめます。そしてそのJSONをもとに自然言語型プロンプトを出力してくれるのです。

前述の「少女は微笑んでいる」の記述位置が移動したのも、人物(character)というくくりで関連付けが自動で行われたためです。

とにかく、最終生成物をはっきりイメージしなくとも、モヤっとした印象を思いつくままにテキストで与えればそれを絵にしてくれます。それを基にお願いを書き足してプロンプトの再出力をしても良いし、強調などで調整しても良いし、英語がわかるなら色々と書き足し削除をすれば良いし、普通にプロンプトを追加しても良いのです。

メリット2:イラスト生成ガチャが捗る(ちょっと自信ない)

JSONベースの自然言語型プロンプトはイラスト内の構成要素をきっちり固めようとする働きが強めです。でも、実は揺らぎも多いのです。

今回は研究も足りないので詳細は省きますが、全体の構成や印象などは一定範囲内にまとめてきますが、モデル側の解釈が自然言語に対して過剰に反応したり、逆に反応が鈍かったりすることがあります。

なので、全体の構成は一定範囲に収まった状態でイラスト生成ガチャを楽しめます。まあ、まだ検証が足りていないので本当に?と言われると答えに窮しますが……。

メリット3:プロンプトガチャを楽しめる

ここで以下のようなお願いをGPT君にしてみましょう。

このJSONをobjectとkeyはそのままでvalueだけを任意で変更し、プロンプトを書いてください。ただし、全体の雰囲気は残し、性別と年齢はそのままにしてください。

これでGPT君は許された範囲内で好き勝手やってくれます。

但し書きを書かなければ全部をランダムでやってくれます。しかもJSONのobjectとkeyの強制力が働くので構成要素が消えたり現れたり大きく変化することなくできます。(これの凄さ、伝わるかなぁ……)

でも、これを楽しむのもいいですが、3時間で25回までしか使えないことをお忘れなく。今は。

メリット4:フワッと雰囲気を伝えると変更して整えてくれる

ここで次のようなお願いをしてみましょう。

このJSONをもとにプロンプトを再度出力してください。ただし、年齢と性別はそのままで夜に変更してください。また全体の印象を維持してください。

まあ、今回の例でいえば夕日を月にしてくれたりという程度なのですが、時間帯で変化するものがプロンプト内にあればそれらを夜の状態にしてくれたりします。

もちろん時間だけでなく色々な変更のお願いができます。例えば…

このJSONをobjectとkeyはそのままでvalueだけを任意で変更し、プロンプトを書いてください。ただし、全体の雰囲気は悲しいものに変更し、性別と年齢はそのままにしてください。

ちょっと謎物体が出てます

いかがでしょうか。

仕組みを理解できれば色んなお願いのしかたができるようになります。

また、ご自分でJSONをエディットしてそれを基にプロンプトを生成してもらうということも可能です。

メリット5:プロンプトの勉強になる

この自然言語型への変換を使ってイラストを出力していると「あ、こう書けばこう出してくれるんだ」という気付きがあります。

使用モデルにもよりますが、自然言語ではなく通常のDanbooru型で記述している中にその表現を付け加えると効果的だったりします。
特にBREAKでつないだりしたときなど……(伏線)。

なので、プロンプト記述能力の幅が広がります。広がるといいな。


それではデメリットを。

デメリット1:自分のコントロール下に置きにくい

正直言って自然言語型のプロンプトは後から細かく調整するのは可能ではあっても少々面倒です。なので単語やセンテンスの強調などで対応するのが手っ取り早いでしょう。それで無理なら最初の入力プロンプトを見直しとなります。

デメリット2:今までのスタイルの再現が難しい場合がある

ここで言うスタイルとは皆さんが培ってきた絵柄、プロンプトの記述法を指します。

絵柄に関しては今まで皆さんが培った手法で書かれたプロンプトを生成されたものに書き加えるというのが現実的です。

また、GPT君に教え込ませる、という解決法もありますが、そのためには(難しいものではありませんが)ChatGPTへのお願いのしかたとかそういったものを会得する必要があります。
その時間があったら呪文書いてる方がいいよね。

しかしこれは、いずれ解決できるかもしれません。不確実なことなのでこれはまたいずれ。

デメリット3:ややこしいことわからないよ!

そうですよね。
興味がなければ余計に難しいでしょう。
でも、きっとそれは時間が解決してくれるでしょう。
勉強しろ、ということではありません。
ネットの集合知を私は信じている、ということです。

先だって今回の技法をとある場でお伝えしたところ、あっという間に改良改善されていきました。
それを見て私は思いました。
「ああ、これはもう私の手を離れたな」と(笑)。

きっと誰かが便利で使いやすくしてくれると思いますよ。

まとめ

この手法を見つけてからまだ数週間。私自身、時間も無くてこの手法についてまだまだ研究が足りておりませんし、何より私はこういったことはど素人です。

なので、今後は皆さんと色々と見つけて楽しんでいければいいなと思っています。

ここ数日、ネット上でのやり取りで色々と妄想が捗り、何となく向かう方向などが見えた気もします。まあ、時間も技術も無いので妄想止まりではありますが。いずれその妄想もお伝えしたいと思います。

最期に……

BDさん、これでバトンは渡しました!
あとはよろしくお願いします!

ビッグバードさん、ご協力ありがとうございます!
これでみんなが楽しめます!

ということで、皆さま、BDさんの動向にご注目ください。
そこでBing対応方も公開されます。
しかもわりとすぐ!

それでは良きプロンプティングライフを!

追記:来てますよ~

追記:長文での入力について

上記の命令では長文のテキストでは狙い通りのJSONを出力できないケースが多いということがわかりました。その場合は以下の命令を試してみてください。

最初にこれを英語に翻訳してください。次に、翻訳したテキストを分析し"scene"、"character"などの各カテゴリを必要なら定義しそれらをobjectとしたJSONに書き換えてください。次に、そのJSONをもとに英語のまま画像生成で使用するtext-to-image promptを書いてください。その際には極端に小説的にならず、状況を伝えるのが目的の記述にしてください。

JSONへの出力はとりあえずこれで問題ありません。プロンプトへの出力もここまで調整すれば許容範囲まで落とし込めます。それでも長文の場合はプロンプトの出力が冗長になりがちで全体の構成力が落ちます。かといってもっとシンプルに出力するよう調整すると自然言語型が持つ持ち味を失います。

逆に言えばGPTによるプロンプト出力はこのように柔軟性もあり、皆さんの好みで調整がいくらでも可能だということでもあります。

いずれにせよ、現状としてはなるべくカンマで区切った単語や複数の短文で使用してください。

でも、無理して私のやり方を使わずとも、こういった部分も考慮に入れたBDさんが公開している手法を使えば大丈夫なので、そちらのご利用を推奨します。Bingでも使えるしね!


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