HuggingFace Diffusers 0.12 : 使用方法 : ロード & ハブ – 様々なスケジューラの使用 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 02/11/2023 (v0.12.1)
* 本ページは、HuggingFace Diffusers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
HuggingFace Diffusers 0.12 : 使用方法 : ロード & ハブ – 様々なスケジューラの使用
拡散パイプラインは本質的には、互いに部分的に独立な拡散モデルとスケジューラのコレクションです。これは、パイプラインをユースケースに合わせてより良くカスタマイズするためにパイプラインの一部を置き換えられることを意味します。この最善の例は スケジューラ です。
拡散モデルが通常はノイズからよりノイズの少ないサンプルへの forward パスを単純に定義している一方で、スケジューラはノイズ除去過程全体を定義します、つまり :
- ノイズ除去ステップは幾つか?
- 確率的 or 決定論的?
- ノイズ除去サンプルを見つけるために使用するのは何のアルゴリズムか
それらは非常に複雑であり、ノイズ除去スピード と ノイズ除去品質 の間のトレードオフを定義することが多いです。与えられた拡散パイプラインに対してどのスケジューラが最善に機能するかを定量的に測定することは極めて困難ですので、どれが最善かを単純に試すことがしばしば勧められます。
以下のパラグラフは 🧨 Diffusers ライブラリでそれを行う方法を示します。
パイプラインのロード
stable diffusion パイプラインをロードすることから始めましょう。stable diffusion を使用するためには貴方は 🤗 Hugging Face で登録ユーザであり、ライセンス を「クリックして承認する」必要があることを忘れないでください。
from huggingface_hub import login
from diffusers import DiffusionPipeline
import torch
# first we need to login with our access token
login()
# Now we can download the pipeline
pipeline = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16)
Next, we move it to GPU:
pipeline.to("cuda")
スケジューラへのアクセス
スケジューラは常にパイプラインのコンポーネントの一つで、通常は “scheduler” と呼ばれます。そのためそれは “scheduler” プロパティでアクセスできます。
pipeline.scheduler
PNDMScheduler { "_class_name": "PNDMScheduler", "_diffusers_version": "0.8.0.dev0", "beta_end": 0.012, "beta_schedule": "scaled_linear", "beta_start": 0.00085, "clip_sample": false, "num_train_timesteps": 1000, "set_alpha_to_one": false, "skip_prk_steps": true, "steps_offset": 1, "trained_betas": null }
このスケジューラは PNDMScheduler のタイプであることがわかります。Cool, それではこのスケジューラを性能の点で別のスケジューラと比較しましょう。最初にプロンプトを定義します、その上ですべての異なるスケジューラをテストします :
prompt = "A photograph of an astronaut riding a horse on Mars, high resolution, high definition."
次に、ランダムシードから generator を作成します、これはパイプラインを実行できることに加えて類似画像を生成できることを保証します :
generator = torch.Generator(device="cuda").manual_seed(8)
image = pipeline(prompt, generator=generator).images[0]
image
スケジューラの変更
ここでパイプラインのスケジューラを変更することがどれほど簡単かを示します。すべてのスケジューラはプロパティ SchedulerMixin.compatibles を持ちます、これはすべての互換なスケジューラを定義しています。Stable Diffusion パイプラインに対するすべての利用可能、互換なスケジューラを以下で見ることができます。
pipeline.scheduler.compatibles
[diffusers.schedulers.scheduling_lms_discrete.LMSDiscreteScheduler, diffusers.schedulers.scheduling_ddim.DDIMScheduler, diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler, diffusers.schedulers.scheduling_euler_discrete.EulerDiscreteScheduler, diffusers.schedulers.scheduling_pndm.PNDMScheduler, diffusers.schedulers.scheduling_ddpm.DDPMScheduler, diffusers.schedulers.scheduling_euler_ancestral_discrete.EulerAncestralDiscreteScheduler]
(訳注 : 実行結果)
[diffusers.schedulers.scheduling_dpmsolver_singlestep.DPMSolverSinglestepScheduler, diffusers.schedulers.scheduling_ddpm.DDPMScheduler, diffusers.schedulers.scheduling_lms_discrete.LMSDiscreteScheduler, diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler, diffusers.schedulers.scheduling_euler_discrete.EulerDiscreteScheduler, diffusers.schedulers.scheduling_pndm.PNDMScheduler, diffusers.schedulers.scheduling_k_dpm_2_ancestral_discrete.KDPM2AncestralDiscreteScheduler, diffusers.schedulers.scheduling_euler_ancestral_discrete.EulerAncestralDiscreteScheduler, diffusers.schedulers.scheduling_k_dpm_2_discrete.KDPM2DiscreteScheduler, diffusers.schedulers.scheduling_ddim.DDIMScheduler, diffusers.schedulers.scheduling_deis_multistep.DEISMultistepScheduler, diffusers.schedulers.scheduling_heun_discrete.HeunDiscreteScheduler]
Cool, lots of schedulers to look at. Feel free to have a look at their respective class definitions:
- LMSDiscreteScheduler
- DDIMScheduler
- DPMSolverMultistepScheduler
- EulerDiscreteScheduler
- PNDMScheduler
- DDPMScheduler
- EulerAncestralDiscreteScheduler
次に入力プロンプトをすべての他のスケジューラで比較します。パイプラインのスケジューラを変更するために ConfigMixin.from_config() 関数と組み合わせて便利な ConfigMixin.config プロパティを利用できます。
pipeline.scheduler.config
はスケジューラの configuration の辞書を返します :
FrozenDict([('num_train_timesteps', 1000), ('beta_start', 0.00085), ('beta_end', 0.012), ('beta_schedule', 'scaled_linear'), ('trained_betas', None), ('skip_prk_steps', True), ('set_alpha_to_one', False), ('steps_offset', 1), ('_class_name', 'PNDMScheduler'), ('_diffusers_version', '0.8.0.dev0'), ('clip_sample', False)])
そしてこの configuration は、パイプラインと互換な別のクラスのスケジューラをインスタンス化するために使用できます。ここでは、スケジューラを DDIMScheduler に変更します。
from diffusers import DDIMScheduler
pipeline.scheduler = DDIMScheduler.from_config(pipeline.scheduler.config)
Cool, now we can run the pipeline again to compare the generation quality.
generator = torch.Generator(device="cuda").manual_seed(8)
image = pipeline(prompt, generator=generator).images[0]
image
スケジューラの比較
ここまで 2 つのスケジューラで stable diffusion パイプラインの実行を試してきました : PNDMScheduler と DDIMScheduler です。多くのより良いスケジューラがリリースされていて、これらは遥かに少ないステップで実行できますので、ここでそれらを比較しましょう :
LMSDiscreteScheduler は通常はより良い結果に繋がります :
from diffusers import LMSDiscreteScheduler
pipeline.scheduler = LMSDiscreteScheduler.from_config(pipeline.scheduler.config)
generator = torch.Generator(device="cuda").manual_seed(8)
image = pipeline(prompt, generator=generator).images[0]
image
EulerDiscreteScheduler と EulerAncestralDiscreteScheduler はわずか 30 ステップで高品質な結果を生成できます。
from diffusers import EulerDiscreteScheduler
pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)
generator = torch.Generator(device="cuda").manual_seed(8)
image = pipeline(prompt, generator=generator, num_inference_steps=30).images[0]
image
そして :
from diffusers import EulerAncestralDiscreteScheduler
pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(pipeline.scheduler.config)
generator = torch.Generator(device="cuda").manual_seed(8)
image = pipeline(prompt, generator=generator, num_inference_steps=30).images[0]
image
この doc を書いている時点で、DPMSolverMultistepScheduler は間違いなく最善のスピード/品質のトレードオフを与え、わずか 20 ステップで実行ができます。
from diffusers import DPMSolverMultistepScheduler
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config)
generator = torch.Generator(device="cuda").manual_seed(8)
image = pipeline(prompt, generator=generator, num_inference_steps=20).images[0]
image
ご覧のように、殆どの画像は非常に類似していて間違いなく非常に類似した品質です。どのスケジューラを選択するかは実際には特定のユースケースに依存することが多いです。A good approach is always to run multiple different schedulers to compare results.
以上