9
9

More than 1 year has passed since last update.

Stable Diffusionベストプラクティス考察 txt2img編 Part.1

Last updated at Posted at 2022-09-13

1.はじめに
2.変数の特徴と活用方法
3.まとめ
4.おわりに

TL;DR

基本的な戦略

  1. ランダム×固定seedでのPrompt engineering
  2. ランダムseedでのSeed hunting
  3. 固定SeedでのPrompt engineering

その際の注意点

  • promptの長さは75token以内に
  • step数は20程度まで減らして時短
    • 最後は100以上で清書
  • 大きなサイズでの生成は予期せぬ複製や見切れを生むため注意
  • Scaleはデフォルトでよし

1. はじめに

この記事は、Stable Diffusionへの理解を深め、より効率的に使いこなすための方法を考察したものです。
なんとなくpromptを試してみる状態から、少しステップアップできる内容になっていると思います。

一応シリーズ化の予定です。

この記事で扱うトピック

  1. txt2imgを使う際にユーザーがコントロールできる主な変数は何か
  2. それらの変数の持つ意味・影響など、知っておくべき基礎知識は何か
  3. 上記2つを踏まえた上で、どの様にtxt2imgを使いこなすことができるか

この記事では扱わないトピック

今のところ、どちらもPart.2以降で扱う予定でいます。

  1. Prompt engineering (promptを改良する具体的なテクニック)
  2. sampler

2. 変数の特徴と活用方法

txt2imgにおける主要な変数を、画像への影響が大きいものから整理します。

変数 影響度 ポイント
prompt ★★★★★ 長さに制限がある点に注意
seed ★★★★☆ promptで指定していない要素がどう描かれるかを決定する
steps ★★☆☆☆ 画像の全体的なクオリティーを左右する
height ★☆☆☆☆ 大きな値を設定すると不気味な画像が生まれる要因になる
width ★☆☆☆☆ 同上
scale ★☆☆☆☆ 7~11程度がちょうどいい

公式リポジトリ内のスクリプトを用いた場合、diffusersライブラリを用いた場合の各変数の設定方法です。

python scripts/txt2img.py \
    --prompt "a photograph of an astronaut riding a horse" \
    --seed 1024 \
    --ddim_steps 50 \
    --H 512 \
    --W 512 \
    --scale 7.5

diffusersライブラリの場合は以下の様に設定します

import torch
from diffusers import StableDiffusionPipeline

generator = torch.Generator("cuda").manual_seed(1024) # seed

pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", revision="fp16", torch_dtype=torch.float16, use_auth_token=True)  
image = pipe(
    prompt="a photograph of an astronaut riding a horse",
    generator=generator, # seed
    num_inference_steps=50,
    height=512,
    width=512,
).images[0]

Prompt 【★★★★★】

txt2img.py diffusers
--prompt prompt

特徴

曖昧さ

例えばpromptをfootballにして何枚も画像を生成すると、「アメフト」と「サッカー」両方の画像が現れます。
これは、footballがどちらとも解釈できる曖昧さを持った言葉だからです。
曖昧さの概念は非常に重要で、後述のseedと強く関係しています。

football.png

CLIPによる制約

promptの長さには制限があります。
promptはOpenAIのCLIPを使ってトークン1化されてから処理されます。
このCLIPに制限があり、75トークン以上はカットされてしまいます。

要するに、promptは長すぎてはダメということです。

活用方法

実際にpromptが幾つのトークンになるかはこちらから試すことができます。
75を超える場合は削りましょう。
イメージしやすいようにサンプルを載せておきます(2つ目のpromptはピーチ姫が出てきます)。

token数 prompt
32 anime kyoto animation key by greg rutkowski night, single white hair girl from behind, in abandoned chapel with overgrown flowers and plants
41 Ultra realistic photo, princess peach in the mushroom kingdom, beautiful face, intricate, highly detailed, smooth, sharp focus, art by artgerm and greg rutkowski and alphonse mucha
74 A beautiful neon cyberpunk city street at night, apartment, skyscrapers, by alphonse mucha caravaggio monet ,4K resolution, 8K resolution, a lot of Decoration and embellishments, sci-fi, photorealistic, highly detailed, sharp focus, clean 8k, volumetric lighting, octane render, ceramic

Seed 【★★★★☆】

txt2img.py diffusers default
--seed generator ランダム

diffusersライブラリでseedを設定するときはtorch.Generatorを用います。

import torch

generator = torch.Generator("cuda").manual_seed(1024) # 1024がseed値
image = pipe(
    prompt="a photograph of an astronaut riding a horse",
    generator=generator
).images[0]

特徴

画像生成に用いられる乱数のようなもので、全く同じpromptでもseedが違えば異なる画像が出力されます。

seedを活用するにあたって重要なのは、次の2つのケースで起きる現象を理解することです。

  1. promptを固定し、複数のランダムなseedで画像を生成する
  2. seedを固定し、複数の僅かに異なるpromptで画像を生成する

こちらは横軸に同じpromptで、縦軸に同じseedで生成した画像を並べたものです。

stars.png

promptを固定し、複数のランダムなseedで画像を生成する

各promptにおいて、promptからは確定できない要素がseedごとの違いに表れていることがわかります。
前述のpromptの曖昧さはこのpromptからは確定できない要素に含まれます。

こうして生成した画像を比較することで、prompt単体がどの程度画像を固定するのか、何がseedに左右されているのかを知ることができます。

prompt seedごとの違い
stars 「写真かイラストか」「全体的な色」「星の見え方」「地上の様子」など
a photo of stars 「写真かイラストか」 「全体的な色」「星の見え方」「地上の様子」など
a photo of stars, purple 「写真かイラストか」 「全体的な色」「星の見え方」「地上の様子」など

seedを固定し、複数の僅かに異なるpromptで画像を生成する

seedを固定した上でpromptを少しずつ変え、画像がどの様に変化するのか検証します。
prompt変更前の画像に存在しなかった要素が変更後のpromptに含まれている場合でのみ、目に見えた変化が起きていることがわかります。

こうして生成した画像を比較することで、promptの微妙な違いが与える影響を知ることができます。

seed stars a photo of stars a photo of stars, purple
1 の星空の写真 ほとんど変化なし ほとんど変化なし
2 星のイラスト 写真に変化 に変化
3 星のイラスト 写真に変化 に変化
4 星のイラスト 写真に変化 に変化
5 星空の写真 ほとんど変化なし に変化

※表内の値は実際のseed値とは異なりますが、便宜上1~5としています。

活用方法

promptの完成度によってseedを固定するかランダムにするかを使い分ける方法です。

完成度Level. 1:ランダム×固定

まずはpromptの持つ特徴を適切に理解することが重要です。
その際、promptのセクションで触れた曖昧さの概念が重要になります。

曖昧な単語や文章を試す際、もしくは曖昧さを検証する際はランダムなseedで複数枚の画像を生成してみましょう。
starsという単語を例に上げると、この単語の持つ特徴には「星空の写真」だけでなく「星のイラスト」がありました。
このことは、複数のseedで検証しなければわからなかったことです。

一方で、それほど曖昧でない単語や文章も存在します。
Greg RutkowskiWLOPなどの作家名や8ktrending on artstationoctane renderなどのリアルさやディティールに影響しやすいpromptなどがこれにあたります。
画像に現れる物質や構図への影響は比較的小さく、加工アプリのフィルターの様に機能するため、固定seedでも十分に検証できます。

双方のケースを踏まえ、この様にseedとpromptのマトリクスを組んで検証することを推奨します。
matrix.png

完成度Level. 2:ランダム

ある程度promptが定まってくると、構図や配置などpromptでは制御しきれない要素がわかってきます。
そこで、それらを固定するためにランダムなseedで狙い通りの画像が出るまで生成し続けます。

この行為は「Seed hunting」と呼ばれているようです。

完成度Level. 3:固定

いよいよ最終段階です。
Level.2で特定した「アタリのseed」を元に、promptを少しずつ変えて微調整を行います。
あまりうまくいかなければSeed huntingに戻るのも良いでしょう。

特定のseedに対してpromptを過剰に適応させると、他のseedに合わなくなる点に注意してください。

Steps 【★★☆☆☆】

txt2img.py diffusers default
--ddim_steps num_inference_steps 50

特徴

stepが多いほど基本的により良い結果が得られますが、その分処理に時間がかかります。
なおtxt2imgはデフォルトの50stepsでも十分な結果が得られるように作られています。

stepsの値を上げることによるより良い結果への変化は「構図の変化」と「(非常に広義の)画像クオリティーの向上」にざっくりと分けることができます。
step数1~250までの推移を比べてみましょう。
step数を少しずつ上げていくと、1~15ほどのstep数の時に構図の変化が、それ以上では画像クオリティーの向上が起きやすいということがわかります。

活用方法

少ないstep数で画像を量産する場合と、step数を上げて小数枚を生成する場合を使い分けましょう。
後でstep数を上げて綺麗にする(清書する)前提の場合、「何stepで画像を生成するべきか」という問題は「何stepで構図の変化が収束するか」という問題に置き換えることができます。
それよりも少ないstep数で生成した画像は、のちにstep数を上げて生成し直した時に構図が変化してしまう可能性があります。
一方で、それよりも多いstepで画像を生成すると無駄な時間が生じてしまいます。

promptを組み立てる段階では20程度に設定して高速化確定した後に100以上を用いて清書することを推奨します。

graph.png

構図の変化が1~15stepsで収束しやすいというのはあくまで目安であり、promptseed、特にsamplerなどに左右されることに注意してください。

Height/Width 【★☆☆☆☆】

txt2img.py diffusers default
--H height 512
--W width 512

特徴

txt2imgは512x512での画像生成に最適化されおり、512x512以上の解像度でも「512x512ごとにpromptから画像を生成する」という仕様になっています。2

その結果、512以上のサイズを指定すると頻繁に予期せぬ「複製」や「見切れ」などが発生します。
512x1728で生成したこちらの画像には3人の女性が現れました。
中心に何か(この例では女性の顔)がある様な画像は、高解像度での生成には不向きです。
women.png

一方で、この様な背景メインの画像は崩れにくく、大きなサイズでの生成に向いていると言えます。
bgstars.png

活用方法

サイズを大幅に上げることで違和感のある画像が生まれてしまう場合、超解像やtxt2imghdなどの使用を検討しましょう。

Scale 【★☆☆☆☆】

txt2img.py diffusers default
--scale guidance_scale 7.5

特徴

ScaleまたはCFGは画像のクオリティーとpromptへの忠実度のバランスを表します。
一般的に7~11あたりで最もバランスの取れた画像が生成できます。
scales-256.gif

こちらも、promptseedsamplerなどに左右されることに注意してください。

活用方法

基本的にはデフォルトのままで問題ありません。

3. まとめ

txt2imgにおいて重要な変数は、結局のところpromptseedの2つです。

最適なpromptだけでなく、最適なseedを見つけることが重要であり、そのための方法の骨組みがseedのセクションで紹介したこちらです。

  1. ランダム×固定seedでのPrompt engineering
  2. ランダムseedでのSeed hunting
  3. 固定SeedでのPrompt engineering

そして、この過程における重要なポイントがこちらです。

  • promptの長さは75token以内に
  • step数は20程度まで減らして時短
    • 最後は100以上で清書
  • 大きなサイズでの生成は予期せぬ複製や見切れを生むため注意
  • Scaleはデフォルトでよし

4. おわりに

長々とお付き合いいただきありがとうございました!
ご指摘などありましたらコメントいただけると幸いです。

次回はPrompt engineeringの具体的な手法について書こうと思うのですが、なかなかのボリュームになりそうな気がしています。。

  1. tokenの概念に関する詳しい説明はこちらをご覧ください。

  2. Stable Diffusion Prompt engineering

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9