今回の記事では Stable Diffusionの最新モデルであるSDXLの画像生成を高速化するLCMという方法を紹介します。
Google Colabを使用して簡単に実装できますので、ぜひ最後までご覧ください。
今回の内容
・Stable Diffusionとは
・SDXLとは
・LCMとは
・LCMの実装方法
・生成速度の比較
Stable Diffusionとは
Stable Diffusionは、2022年にリリースされた深層学習に基づく革新的なテキストから画像への生成モデルです。これは、スタートアップ企業のStability AIと多くの学術研究者、非営利組織の共同作業により開発されました。このモデルは、テキストの説明に基づいて詳細な画像を生成する主要な用途を持つ一方で、画像の補完(inpainting)、画像の拡張(outpainting)、テキストプロンプトによってガイドされた画像から画像への変換(image-to-image translations)などの他のタスクにも適用可能です。
Stable Diffusionの特性とアーキテクチャ
Stable Diffusionは「潜在拡散モデル」(latent diffusion model)という深層生成型ニューラルネットワークの一種で、そのソースコードとモデルの重みは公開されています。8GB以上のVRAMを持つ一般的なGPU搭載ハードウェアで動作します。これは以前のモデルがクラウドサービスを介してのみアクセス可能だったのとは異なる特性です。
Stable Diffusionのアーキテクチャは三つの主要な部分から構成されています: 変分オートエンコーダ(VAE)、U-Net、そしてオプショナルなテキストエンコーダです。変分オートエンコーダ(VAE): VAEエンコーダは画像をピクセル空間からより小さな次元の潜在空間に圧縮します。これにより、画像の基本的なセマンティックな意味を捉えます。U-Net: U-NetブロックはResNetバックボーンで構成され、前方拡散からの出力をノイズ除去して潜在表現を得ます。テキストエンコーダ: テキストに条件付けするために、CLIP ViT-L/14テキストエンコーダが使用されてテキストプロンプトをエンベディング空間に変換します。
Stable Diffusionの開発
Stable Diffusionの開発は、Stability AIが資金提供し、形成しました。その技術的なライセンスは、ミュンヘンのルートヴィヒ・マクシミリアン大学のCompVisグループによってリリースされました。開発は、RunwayのPatrick EsserとCompVisのRobin Rombachが率い、これらの研究者はStable Diffusionで使用される潜在拡散モデルのアーキテクチャを以前に発明した人々の中にいます。
Stable Diffusionの訓練は、LAION-5Bという公開データセットから取得された画像とキャプションのペアに対して訓練されました。このデータセットは、ウェブからスクレイプしたCommon Crawlデータから派生したもので、50億組の画像-テキストペアが言語に基づいて分類され、解像度、ウォーターマークの含有可能性の予測、および「美的」スコア(例えば、主観的な視覚的品質)の予測によって別々のデータセットに分けられました。
関連情報
https://huggingface.co/blog/stable_diffusion
https://huggingface.co/spaces/stabilityai/stable-diffusion
SDXLとは
Stable Diffusion XL (SDXL)は、実際の顔、画像内の読みやすいテキスト、そしてより良い画像構成を生成できる能力を持っています。このモデルは、より短く簡単なプロンプトを使用してこれらのタスクを実行できる点で注目されています1。SDXLはStability AI社によって開発され、以前のモデルに比べて、細かい部分がより正確に反映され、より高画質なイラストの生成が可能になっています。
SDXLモデルの特定のバージョン、SDXL 0.9は、研究用途に限定されて先行リリースされ、モデルパラメータの数が大幅に増加しています。これは、テキストと画像の関係を理解するCLIPモデルの使用により、高解像度で奥行きのある画像を簡単に生成できるようになったためです。このモデルは、一般的なPC、Windows 10/11、Linux、およびNvidiaなどのグラフィックボードを搭載した環境で動作し、従来のモデルと比較して画像と構図のディテールが大幅に改善され、高性能な画像生成AIモデルとして注目されています。
また、SDXLは以前のStable Diffusionモデルを3つの主要な点で進化させています。UNetが3倍大きくなり、SDXLは2つ目のテキストエンコーダ(OpenCLIP ViT-bigG)をオリジナルのテキストエンコーダと組み合わせて、パラメータの数を大幅に増加させています。そして、SDXLは、短いプロンプトを使用して記述的な画像を作成し、画像内に単語を生成する能力を提供しています。これは画像生成能力の重要な進歩であり、画像構成と顔生成の強化を提供し、驚くべき視覚効果とリアルな美学をもたらしています。
リリース情報:https://ja.stability.ai/blog/sdxl10
解説:https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/stable_diffusion_xl
SDXLの基本実装
こちらの記事で紹介しています。
LCM(Latent Consistency Models)とは
潜在一貫性モデル(LCM)は、通常2~4ステップで高品質な画像生成を実現し、拡散モデルをほぼリアルタイムの設定で使用可能にします。これは、任意の事前訓練済みの安定拡散(SD)からわずか4,000のトレーニングステップ(約32 A100 GPU時間)で抽出でき、2〜4ステップ、あるいは1ステップで768 x 768解像度の高品質画像を生成できることを意味します。これにより、テキストから画像への生成が大幅に加速されます。
潜在拡散モデル(LDM)は高解像度画像の合成において顕著な結果を達成していますが、反復的なサンプリングプロセスは計算集約的で生成が遅いです。これに対し、LCMは事前訓練済みのLDM、特に安定拡散において、わずかなステップで迅速な推論を可能にします。導かれた逆拡散プロセスを拡張確率流ODE(PF-ODE)として解釈し、LCMはこのようなODEの解を潜在空間で直接予測し、多数の繰り返しを不要にし、迅速かつ高忠実度のサンプリングを可能にします。
事前訓練済みの分類器フリーのガイド拡散モデルから効率的に抽出された高品質の768 x 768 2〜4ステップLCMは、トレーニングにわずか32 A100 GPU時間しか必要としません。さらに、LCMをカスタマイズされた画像データセットで微調整するために特別に設計された新しい方法である潜在一貫性微調整(LCF)を導入しました。LAION-5B-Aestheticsデータセットでの評価では、LCMは少ステップ推論で最先端のテキストから画像への生成性能を達成しています。
詳細は以下のリンクからご覧ください。
公式:https://latent-consistency-models.github.io/
解説:https://huggingface.co/docs/diffusers/main/en/using-diffusers/lcm
LCMの実装
ここからはGoogle colabを使用して、SDXL(LCM)による画像生成を実装していきましょう。
Google colabの使い方はこちら
まずはGPUを使用できるように設定をします。
「ランタイムのタイプを変更」→「ハードウェアアクセラレータ」をGPUに変更
モデルの準備
必要なライブラリをインストールします。
!pip install transformers diffusers accelerate
モデルをダウンロードして、読み込みます。こちらでは、UNetを変更してStableDiffusionXLPipelineを使用します。このUNetは、LCMで紹介されたフレームワークを使用してSDXL UNetから抽出されました。もう一つの重要なコンポーネントはスケジューラーであるLCMSchedulerです。抽出されたUNetとスケジューラーと共に、LCMは拡散モデルの遅い反復的な性質を克服する高速な推論ワークフローを可能にします。
from diffusers import DiffusionPipeline, UNet2DConditionModel, LCMScheduler
import torch
unet = UNet2DConditionModel.from_pretrained(
"latent-consistency/lcm-sdxl",
torch_dtype=torch.float16,
variant="fp16",
)
pipe = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0", unet=unet, torch_dtype=torch.float16
).to("cuda")
pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
以上で準備が完了しました。
画像生成
「a photo of an astronaut riding a horse on mars」というプロンプトを与えて画像生成してみます。
num_inference_steps=4と設定します。
デフォルトは50であることを考慮すると、かなり少ないステップで画像生成ができることがわかります。
prompt = "a photo of an astronaut riding a horse on mars"
image = pipe(
prompt=prompt, num_inference_steps=4, guidance_scale=5.0
).images[0]
image
実行結果:
注意事項
分類器フリーガイダンスを行うには、通常、パイプライン内でバッチサイズを倍にします。しかし、LCMはガイダンス埋め込みを使用してガイダンスを適用するため、この場合、バッチサイズを倍にする必要はありません。これにより、推論時間が速くなりますが、デメリットとして、否定的なプロンプトはノイズ除去プロセスに影響を与えません。
UNetは[3., 13.]のガイダンススケール範囲でトレーニングされました。したがって、それがガイダンススケールの理想的な範囲です。ただし、ほとんどの場合、1.0の値を使用してガイダンススケールを無効にすることも効果的です。
(参考)生成速度の比較
GPUのA100を使用した場合
import time
prompt = "a photo of an astronaut riding a horse on mars"
start_time = time.time()
# 画像生成処理
image = pipe(
prompt=prompt, num_inference_steps=4, guidance_scale=5.0
).images[0]
# 処理終了時刻を記録
end_time = time.time()
# 処理時間(秒)を計算
processing_time = end_time - start_time
print("Processing time: {:.2f} seconds".format(processing_time))
image
実行結果:
Processing time: 0.75 seconds
GPUでA100を使用した場合は、1秒以下で1枚の画像を生成することができました。
GPUのT4を使用した場合
import time
prompt = "a photo of an astronaut riding a horse on mars"
start_time = time.time()
# 画像生成処理
image = pipe(
prompt=prompt, num_inference_steps=4, guidance_scale=5.0
).images[0]
# 処理終了時刻を記録
end_time = time.time()
# 処理時間(秒)を計算
processing_time = end_time - start_time
print("Processing time: {:.2f} seconds".format(processing_time))
image
実行結果:
Processing time: 3.51 seconds
まとめ
最後までご覧いただきありがとうございました。