2023/09/16 # Stable Diffusion コマンドライン引数 \(txt2img.py\) ## ブログの引っ越し 当ブログは[takemi.blog](https://takemi.blog/)に移行しました。 より見やすい[コマンドライン引数(txt2img.py)の調査](https://takemi.blog/748dbfbc5ab04fc6a8765c12e5cd5dfb/)をご利用ください。 ## 作成日時 2023/01/15 ## 概要 Stable Diffusion\(txt2img.py\)で利用できるコマンドライン引数を調査しました。 調査と言っても不明な部分が多いので自分用のメモが主目的です。 インストール方法は[前回記事](/2023/01/12.0005.html)を参照してください。 ## Ubuntuログイン時 筆者の環境の場合は以下を実行します。殆どメモです。 ```sh conda activate ldm cd ~/stablediffusion/ ``` ## -h, --help \(show this help message and exit\) 普通のヘルプ表示ですね。これで利用できるコマンドの一覧が見れます。 ```sh python scripts/txt2img.py -h ``` 実行するとこんな感じ ```sh usage: txt2img.py [-h] [--prompt [PROMPT]] [--outdir [OUTDIR]] [--steps STEPS] [--plms] [--dpm] [--fixed_code] [--ddim_eta DDIM_ETA] [--n_iter N_ITER] [--H H] [--W W] [--C C] [--f F] [--n_samples N_SAMPLES] [--n_rows N_ROWS] [--scale SCALE] [--from-file FROM_FILE] [--config CONFIG] [--ckpt CKPT] [--seed SEED] [--precision {full,autocast}] [--repeat REPEAT] optional arguments: -h, --help show this help message and exit --prompt [PROMPT] the prompt to render --outdir [OUTDIR] dir to write results to --steps STEPS number of ddim sampling steps --plms use plms sampling --dpm use DPM (2) sampler --fixed_code if enabled, uses the same starting code across all samples --ddim_eta DDIM_ETA ddim eta (eta=0.0 corresponds to deterministic sampling --n_iter N_ITER sample this often --H H image height, in pixel space --W W image width, in pixel space --C C latent channels --f F downsampling factor, most often 8 or 16 --n_samples N_SAMPLES how many samples to produce for each given prompt. A.k.a batch size --n_rows N_ROWS rows in the grid (default: n_samples) --scale SCALE unconditional guidance scale: eps = eps(x, empty) + scale * (eps(x, cond) - eps(x, empty)) --from-file FROM_FILE if specified, load prompts from this file, separated by newlines --config CONFIG path to config which constructs model --ckpt CKPT path to checkpoint of model --seed SEED the seed (for reproducible sampling) --precision {full,autocast} evaluate at this precision --repeat REPEAT repeat each prompt in file this often ``` ## --prompt \(\[PROMPT\] the prompt to render\) 生成したい画像を英語の文章で入力する。1番大切な部分で奥が深い。 以下は公式のサンプルとなっており、とりあえず今回もこれを弄って色々試すことにする。 \[例\] ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi41j6S40yLUPao7Taia2X_-_7r06Wkv5vyVnvbkTnn8aWlsiLY3P4UFaPVH2_wbuOadfdryd50fuOTJjI3H8hFy5ySzn9YoALZdjShsKoq_zhMCqsNWtMKQhOC4F4eRP-Df4FzBnvI1CgWyp5jjXcalRkepzr1UioOv_14ejhDtt1SuofhuETgDfWC7Q/s320/20230115.1238.default.png) ## --steps \(\[STEPS\] number of ddim sampling steps\) 画像生成時のサンプリング回数を指定する。Defaultは50で、大きな値ほど処理時間が増えるが精密になる。 \[例\] ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --steps 10 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT3XeuxoFkXNknhpFeI7cqG7Ut5Q6TbfcBbyGwSULYsbpIA5d6TLKse5Wbj6h1JcAPxhDYxicrLJdSx1joLH_r_v0SSAfIhPQrhkJOUkZS0U14WPRSCPL0D1LPPRXmikj2bR0f4miMBgHc1-t270pa6vR51yD7qBW61fDXb1rAT4doQtRN6Vus8k3ybw/s320/20230115.1238.--steps.png) ## --plms \(use plms sampling\) PLMSでサンプリングする場合に指定する。正直、意味不明な画像になって困惑してる。 きっと、「どういう技法で最終的な画像を生成するのか」みたいな感じだと思う。 なお、何も指定しない場合のDefaultはDDIMと思われる。\(画面にDDIMって表示されるので \[例\] ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --plms ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNjrkUXfQCIkXyHkV6lQVKaIrYObaoUgfBHSuc65eBc8UxaCSIxgLp5DlC2ZnnDe7jTVRym30mTXb8VoqHdv_jYHCZ47L6T0sDIWJ-nEcfDvctbXvRua9NYWjpnb0a6a-GZ9-zUUcYRyltBAkbpgYpX1EmoqPxyVHF4V1Ntk_ZWhpKAd-cpYxZdXnmwA/s320/20230115.1238.--plms.png) ## --dpm \(use DPM \(2\) sampler\) DPMでサンプリングする場合に指定する。あまりDDIMとの違いが分からない。 \[例\] ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --dpm ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmcuNMjNg_sZJsOzlPKtRC82SK9rdOziIfy5FRWskjJCSsgGdtRUgoQmiuy60WrC-Yc-Pz20QKQzOq-4hGsTv3zbusat2KIMcnPsul0MtVK9WVP83hF1SLmOKknf4ZemBaolhMkNTBb-Q9QSgPJoqSqkSQ2fo1LNQOOtWWY7NQw9nqWi-8LfYBPkeqzQ/s320/20230115.1238.--dpm.png) ## --fixed_code \(if enabled, uses the same starting code across all samples\) 全く分からん。日本語訳すると、「有効にすると、すべてのサンプルで同じ開始コードを使用します」となり、実行結果も同じ種類の画像が3つ出現している。 そう考えると画像生成にランダム的な要素を利用せず、同じサンプリングから最終結果を得るのだろうか... \[例\] ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --fixed_code ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmVftw82G4i8IcxsP8KHIUtwPYIk1jLXhAkSgyboZWF59Aa2xlP5W-Hja-gPH-XJeE-DXwgRBQ0eKPJoHGBp_vYOmWQG4rQTFiQZtQUxpsv7Xis-RvXucJYkb06D-dW9e3gek2ryM46SapZ0D8LqpLXwITwMSsvw5zxyHM9HRuuCES9UQ_kvasH3qi3A/s320/20230115.1238.--fixed_code.png) ## --ddim_eta \(\[DDIM_ETA\] ddim eta \(eta=0.0 corresponds to deterministic sampling\) 先ほどと同じで何を言っているのか分から...。 たぶん、DDIMでetaってパラメータが使われるので、その値を指定できるやつ。 \[例\] ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --ddim_eta 1.0 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcAOzrKBNHvSyMTjJ-Y566Tbak4ArNiLitGCo91Yr-gQ43DiK7Rj9ltTyw0PPl7e7DA9KdoSbMY5yKJ1HC_duh0cR3Pe-oAec-qYiYq34AxeZudGVfXiLjV8_bNjNIG2s_BHaIv5C70ByIfZjVmtQhG2Oexp_m2Xv0nW-6WTWC83Y4DRjw1bGWZ5yzGw/s320/20230115.1238.--ddim_eta.png) ## --outdir \(\[OUTDIR\] dir to write results to\) 出力ディレクトリ ## --n_iter \(\[N_ITER\] sample this often\) 完成した画像で言うと縦方向の数を指定する。 コマンドプロンプトを見る限り、以下のループ部分の数と思われる。 ```sh Running DDIM Sampling with 50 timesteps DDIM Sampler: 100%|█████████████████████████████████████████████████████████████████████| 50/50 [00:25<00:00, 2.00it/s] data: 100%|███████████████████████████████████████████████████████████████████████████████| 1/1 [00:26<00:00, 26.80s/it] Sampling: 100%|███████████████████████████████████████████████████████████████████████████| 3/3 [01:25<00:00, 28.40s/it] ``` \[例\] ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --n_iter 4 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaCH2bhhq_h0oIK273mqgTe1j-DcMUg2ykbo2elg3-A8RYY7jhzE-37y1oSGibxep3T2k0uK09IDV2GbRQUcYtyGN4dYnoUSXECh0n0BcK7NuSzsTT7nZfrPYoY9Xy3S8ySA2k2fzkWKG3qCM7PsmV8i5X1rNp3EFu4ADbfJzkdYWNltgqPgrdSSrrNw/s320/20230115.1238.--n_iter.png) ## --H H \(image height, in pixel space\) 生成する画像の高さ。256以上で64の倍数のみ設定できます。 大きくすると必要メモリと処理時間が増加するので、現実的には768くらいが限界です。 256,320,384,448,512,576,640,704,768,832,896,960,1024,1088,1152,1216,1280 なお、同じpromptを指定しても違う画像が出力されるので、一概に同じ結果でサイズを変えるものではないと思われる。 ## --W W \(image width, in pixel space\) 生成する画像の横幅。高さと同じく64の倍数のみ。 ## --C C \(latent channels\) 不明。何らかのチャンネル数を指定できると思ったけど、1, 8, 256, 512, 1024あたりを入力したけど全部Errorだった。 ## --f F \(downsampling factor, most often 8 or 16\) ダウンサンプリングの指定らしい。これも違いが分からない。 ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --f 8 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQiqa-_etV1qqsPqc3WzgHY6pT5Tteoq5NSotJU8rRA_m_RXykLPoSTU0MHl59jyU5vzJdW0aa9yhiywYekq__2BrKblSWERCGHhM5er2GReSDUtG4S7s1en0xvp3pzX58qT83IOUvuvN_Gc7eh7iL9lEKuxcPdNvlwhBd3R2S_OOUvRYeRL4TH3WQ-Q/s320/20230115.1238.--f.png) ## --n_samples \(\[N_SAMPLES\] how many samples to produce for each given prompt. A.k.a batch size\) 完成した画像で言うと横方向の数を指定する。つまり、実際に生成される数は前述した--n_iterと--n_samplesを掛けた枚数になる。 ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --n_samples 5 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYsXDREHOiLjmNhT6JDid6QL6XbWOcM7kqP0IzcnC1GBc1sf92qhO4hs9JKPCHm_X0St9ogB4nisVvyUQoD_GqNNLW3336vkM3BW76tBer5iYSLd6hn7iF3c1zn4a_QSTDllVdhq0AcEXDoL8d7KM3wUjXDuyPncGwEudUAlx1dDWUwluqh3QBZwB0OQ/s320/20230115.1238.--n_samples.png) ## --n_rows \(\[N_ROWS\] rows in the grid \(default: n_samples\)\) 意味的には行数なんだけど、前述した--n_samplesと被るので詳細は不明。 Defaultが =n_samplesって書いてるあるし、変更しなくても良いのでは無いか。 ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --n_rows 2 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX2EZtEcQWvrJ41FdnJ-q3CUfeKWkGUQD5PF-f6HQwJJb59xn2W3J90pH4bonTTaq1CY0qme9iGjdlhMJvIHNwwbFclPZm-33ptxEoq9wvBk9mGj_HHM5fLYrHV_M0VH64sfBfb7cAF2SdoKj9XSCU-qKfDcOe97BsBJLUaWyk-fgGkpchl0CNEkgZAw/s320/20230115.1238.--n_rows.png) ## --scale \(\[SCALE\] unconditional guidance scale: eps = eps\(x, empty\) + scale * \(eps\(x, cond\) - eps\(x, empty\)\)\) 不明。書かれている内容的には何らかの計算式で利用する値ですかね。 生成される画像は結構変化しているので、かなり意味がありそうです。 ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --scale 2 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbku1dS3i_4MzsdM_E5K8KYVbi9Rjmo4EDPGrwx9FWbRW6GQ1kJGiOs8i6WBexXPIwFAAXqk2fTdQc_m8IcMX3rHP5JdiYzluUaniv2IjuPY0u-m9NQFkPju1uD3OYEHmYAeJxIXfRVpAdRtxNurCp1r3XJdi9o8b_bd2O-VkOKP4J-G7zk8TVp33HOQ/s320/20230115.1238.--scale.png) ## --from-file \(\[FROM_FILE\] \(if specified, load prompts from this file, separated by newlines\)\) File経由でpromptsを利用する場合に使うのだと思うけど、使ったこと無い。 と言うか、これ必要なのか。bat経由だとしても、そういうpromptsのbat書けば良いのでは。 ## --config \(\[CONFIG\] path to config which constructs model\) モデルを構築する設定ファイルへのパス。 中身の設定の意味は分からないけど、公式記載のコマンドで使われているファイルは以下が書いてある。 ```sh model: base_learning_rate: 1.0e-4 target: ldm.models.diffusion.ddpm.LatentDiffusion params: parameterization: "v" linear_start: 0.00085 linear_end: 0.0120 num_timesteps_cond: 1 log_every_t: 200 timesteps: 1000 first_stage_key: "jpg" cond_stage_key: "txt" image_size: 64 channels: 4 cond_stage_trainable: false conditioning_key: crossattn monitor: val/loss_simple_ema scale_factor: 0.18215 use_ema: False # we set this to false because this is an inference only config unet_config: target: ldm.modules.diffusionmodules.openaimodel.UNetModel params: use_checkpoint: True use_fp16: True image_size: 32 # unused in_channels: 4 out_channels: 4 model_channels: 320 attention_resolutions: [ 4, 2, 1 ] num_res_blocks: 2 channel_mult: [ 1, 2, 4, 4 ] num_head_channels: 64 # need to fix for flash-attn use_spatial_transformer: True use_linear_in_transformer: True transformer_depth: 1 context_dim: 1024 legacy: False first_stage_config: target: ldm.models.autoencoder.AutoencoderKL params: embed_dim: 4 monitor: val/rec_loss ddconfig: #attn_type: "vanilla-xformers" double_z: true z_channels: 4 resolution: 256 in_channels: 3 out_ch: 3 ch: 128 ch_mult: - 1 - 2 - 4 - 4 num_res_blocks: 2 attn_resolutions: [] dropout: 0.0 lossconfig: target: torch.nn.Identity cond_stage_config: target: ldm.modules.encoders.modules.FrozenOpenCLIPEmbedder params: freeze: True layer: "penultimate" ``` ## --ckpt \(CKPT\] path to checkpoint of model\) 利用するモデルのパス。--promptの次くらいに大切だと思う。 ## --seed \(SEED\] the seed \(for reproducible sampling\)\) 同じ画像を生成する場合に指定する。与えるpromptとseedが同じ値の場合は同じ画像が生成されるよう。 -1を指定すると警告は出るけどランダム値として利用できるようです。 ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --seed 1000 ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkdUMLmpy4TSBUsiPLRrqxalNCOwjUQ7xmuqAafIZGxK7LHs-4p4SPqgOx6BE8HQnwDxQ4jaui5wdp3TWSD_RhOveRqzDRttJOaUTcL2kadl4fFzIIJLReUqebcXPTbMYMDcGBDVtExJKc3fsFjvc3_7lJFLVigFKptGKzSG6LEnvDfPC_BR3V32z1mA/s320/20230115.1238.--seed.png) ## --precision \({full,autocast} evaluate at this precision\) 不明。値は--precision fullまたは--precision autocastの指定が可能でfullは筆者環境だとErrorになった。 ```sh python scripts/txt2img.py --prompt "a professional photograph of an astronaut riding a horse" --ckpt ./stable-diffusion-2-1/v2-1_768-ema-pruned.ckpt --config configs/stable-diffusion/v2-inference-v.yaml --H 768 --W 768 --precision autocast ``` ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMW0kOj3DfccjDmHf6YkhnlpMnjg6Oi7g_C56eeqgwiPHsXdt4FE-BO26wdBp9rPLxWj1Hq14y9hSABGoTt5c-kGhGZnn4M6f9VUFMD1GQiif_Arl3KQ9NRfzQH9cT02xHucDozxBMCimuxKGRFYiykQa0uFZ7UHEx70dmtOwWSh3PxR6MvmUHvAnM_A/s320/20230115.1238.--precision.png) ## --repeat \(\[REPEAT\] repeat each prompt in file this often\) 不明。promptをファイル指定する場合の繰り返し設定だと思う。 ![生成画像](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIsRD-9tX1VIAPV85EKnXvYWEm8U54QLB6XP4cuNQ9TdMWiSrP35IR1DqRsfpy1izlq8z7RL_Z1UsYZURjabxqNAJcsGThosq8YH36Vl9f1dIm2mQfgHc90YX7GjQQKNdedLyEcr7l9Pzys6yb402R5O8akqMufS_WmsaJfyBIFzr3ZcMsJZBBaHwRxg/s320/20230115.1238.--repeat.png) ## おわりに 殆ど分かってないので、情報が増えるたびに追記していきたいです。 とりあえず、promptが1番大事だと思うので、英文をしっかりと指定したいところ。