HuggingFace Diffusers 0.12 : 使用方法 : 様々なスケジューラの使用

HuggingFace Diffusers 0.12 : 使用方法 : ロード & ハブ – 様々なスケジューラの使用 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 02/11/2023 (v0.12.1)

* 本ページは、HuggingFace Diffusers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく 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:

次に入力プロンプトをすべての他のスケジューラで比較します。パイプラインのスケジューラを変更するために 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 パイプラインの実行を試してきました : PNDMSchedulerDDIMScheduler です。多くのより良いスケジューラがリリースされていて、これらは遥かに少ないステップで実行できますので、ここでそれらを比較しましょう :

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

EulerDiscreteSchedulerEulerAncestralDiscreteScheduler はわずか 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.

 

以上