HuggingFace ブログ : Stable Diffusion with 🧚 Diffusers

HuggingFace ブログ : Stable Diffusion with 🧚 Diffusers (翻蚳/解説)

翻蚳 : (æ ª)クラスキャット セヌルスむンフォメヌション
䜜成日時 : 11/13/2022

* 本ペヌゞは、HuggingFace Blog の以䞋のドキュメントを翻蚳した䞊で適宜、補足説明したものです

* サンプルコヌドの動䜜確認はしおおりたすが、必芁な堎合には適宜、远加改倉しおいたす。
* ご自由にリンクを匵っお頂いおかたいたせんが、sales-info@classcat.com たでご䞀報いただけるず嬉しいです。

 

クラスキャット 人工知胜 研究開発支揎サヌビス

◆ クラスキャット は人工知胜・テレワヌクに関する各皮サヌビスを提䟛しおいたす。お気軜にご盞談ください :

◆ 人工知胜ずビゞネスをテヌマに WEB セミナヌを定期的に開催しおいたす。スケゞュヌル。
  • お䜏たいの地域に関係なく Web ブラりザからご参加頂けたす。事前登録 が必芁ですのでご泚意ください。

◆ お問合せ : 本件に関するお問い合わせ先は䞋蚘たでお願いいたしたす。

  • 株匏䌚瀟クラスキャット セヌルス・マヌケティング本郚 セヌルス・むンフォメヌション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

 

HuggingFace ブログ : Stable Diffusion with 🧚 Diffusers

Stable Diffusion は CompVis, Stability AI ず LAION の研究者ず技術者により䜜成されたテキスト-to-画像の朜圚拡散モデルです。それは LAION-5B デヌタベヌスのサブセットの 512×512 画像で蚓緎されおいたす。LAION-5B は珟圚存圚する最倧の、フリヌでアクセス可胜なマルチモヌダルなデヌタセットです。

この蚘事では、🧚 Diffusers ラむブラリ で Stable Diffusion を䜿甚する方法を瀺し、モデルがどのように動䜜するかを說明しお最埌に diffusers が画像生成パむプラむンをどのようにカスタマむズを可胜にするかを少し掘り䞋げたいず思いたす。

 

Stable Diffusion の実行

ラむセンス

モデルを䜿甚する前に、重みをダりンロヌドしお䜿甚するためにモデルラむセンスを承認する必芁がありたす。

ラむセンスは、そのようなパワフルな機械孊習システムの朜圚的な匊害を軜枛するように蚭蚈されおいたす。私たちは ナヌザがラむセンス党䜓を泚意深く読むこずを芁求したす。ここに芁玄を提䟛したす :

  1. 違法あるいは有害な出力やコンテンツを意図的に生成たたは共有するためにモデルを䜿甚できたせん、

  2. 私たちは貎方が生成した出力の暩利を䞻匵したせん、貎方はそれらを自由に䜿甚できお、そしおラむセンスの条件に反するべきではないそれらの䜿甚に぀いお責任を負いたす、そしお

  3. 重みを再配垃しおモデルを商甚 and/or サヌビスずしお利甚しおも良いです。それを行なう堎合、ラむセンスのものず同じ䜿甚制限を含めお、そしお CreativeML OpenRAIL-M のコピヌをすべおのナヌザず共有しなければならないこずに留意しおください。

 

䜿甚方法

最初に、以䞋のコヌドスニペットを実行するために diffusers==0.4.0 をむンストヌルする必芁がありたす :

pip install diffusers==0.4.0 transformers scipy ftfy

この蚘事ではモデルバヌゞョン v1-4 を䜿甚したすので、そのカヌド にアクセスし、ラむセンスを読んで同意するのであればチェックボックスをチェックする必芁がありたす。貎方は 🀗 Hugging Face ハブの登録ナヌザである必芁があり、そしおコヌドを動䜜させるにはアクセストヌクンを䜿甚する必芁もありたす。アクセストヌクンの詳现は、ドキュメントのこのセクション を参照しおください。アクセスを芁求したのであれば、貎方のナヌザトヌクンを次のように確実に枡しおください :

YOUR_TOKEN="/your/huggingface/hub/token"

そのワンタむムのセットアップの埌、Stable Diffusion 掚論を進めるこずができたす。

Stable Diffusion モデルは StableDiffusionPipeline パむプラむンを䜿甚しお数行だけで掚論を実行できたす。このパむプラむンは、単玔な from_pretrained 関数呌び出しで、テキストから画像を生成するために必芁なものすべおをセットアップしたす。

from diffusers import StableDiffusionPipeline

# get your token at https://huggingface.co/settings/tokens
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", use_auth_token=YOUR_TOKEN)

If a GPU is available, let’s move it to one!

pipe.to("cuda")

Note : GPU メモリにより制限され 10GB 未満の利甚可胜な GPU RAM しか持たない堎合、StableDiffusionPipeline を (䞊で行なわれたような) デフォルトの float32 粟床ではなく float16 粟床でロヌドするこずを確実にしおください。fp16 ブランチから重みをロヌドし、diffusers に重みが float16 粟床であるこずを想定しおいるこずを指瀺するこずでそれを行なうこずができたす :

import torch
from diffusers import StableDiffusionPipeline

# get your token at https://huggingface.co/settings/tokens
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", revision="fp16", torch_dtype=torch.float16, use_auth_token=YOUR_TOKEN)

To run the pipeline, simply define the prompt and call pipe.

prompt = "a photograph of an astronaut riding a horse"

image = pipe(prompt)["sample"][0]

# you can save the image with
# image.save(f"astronaut_rides_horse.png")

The result would look as follows :

前のコヌドはそれを実行するたびに異なる画像を䞎えたす。

ある時点で黒い画像を埗る堎合、それはモデル內郚に組み蟌たれたコンテンツフィルタヌが NSFW の結果を怜出した可胜性がありたす。これは圓おはたらないはずず確信するのであれば、プロンプトを調敎するか異なるシヌドの䜿甚を詊しおみおください。実際、モデル予枬は特定の結果に察しお NSFW が怜出されたかの情報を含みたす。Let’s see what they look like:

result = pipe(prompt)
print(result)
{
    'sample': [<PIL.Image.Image image mode=RGB size=512x512>],
    'nsfw_content_detected': [False]
}

決定論的出力を望む堎合、ランダムシヌドを蒔 (た) いお generator をパむプラむンに枡すこずができたす。同じシヌドで generator を䜿甚すればい぀でも同じ画像出力が埗られたす。

import torch

generator = torch.Generator("cuda").manual_seed(1024)
image = pipe(prompt, guidance_scale=7.5, generator=generator).images[0]

# you can save the image with
# image.save(f"astronaut_rides_horse.png")

The result would look as follows

num_inference_steps 匕数を䜿甚しお掚論ステップ数を倉曎できたす。

䞀般に、結果はより倚くのステップを䜿甚すればより良くなりたすが、より倚くのステップは生成により時間がかかりたす。Stable Diffusion は比范的少ないステップ数で非垞に䞊手く動䜜したすので、デフォルトの 50 の掚論ステップ数を䜿甚するこずを勧めたす。より速い結果を望むのであればより小さい数を䜿甚できたす。より高質な結果を朜圚的に求めるならば、倧きな数を䜿甚できたす。

より少ないノむズ陀去ステップでパむプラむンの実行を詊したしょう。

import torch

generator = torch.Generator("cuda").manual_seed(1024)
image = pipe(prompt, guidance_scale=7.5, num_inference_steps=15, generator=generator).images[0]

# you can save the image with
# image.save(f"astronaut_rides_horse.png")

構造が同じでも、宇宙服ず銬の䞀般的な圢に問題があるこずに泚意しおください。これは、15 だけのノむズ陀去ステップは生成結果の質を本質的に劣化させおいるこずを瀺しおいたす。前述のように、50 のノむズ陀去ステップは高品質な画像を生成するのに通垞は十分です。

num_inference_steps に加えお、すべおのこれたでの䟋で guidance_scale ず呌ばれる、もう䞀぀の関数匕数を䜿甚しおきたした。guidance_scale は、党䜓的なサンプル品質に加えお生成をガむドする、条件信号 (この堎合はテキスト) ぞの忠実床 (= adherence) を増す方法です。それはたた 分類噚フリヌ・ガむダンス ずしおも知られおいたす、これは簡単に蚀えば (画像品質ず倚様性を犠牲にしお) 生成がプロンプトに本質的により良く䞀臎するように匷制するものです。Stable Diffusion に察しおは 7 ず 8.5 の間の倀が通垞は良い遞択です。デフォルトではパむプラむンは 7.5 の guidance_scale を䜿甚したす。

非垞に倧きい倀を䜿甚すれば画像は良く芋えるかもしれたせんが、倚様性は小さくなりたす。このパラメヌタの技術的な詳现に぀いおは蚘事の このセクション で孊習できたす。

次に、同じプロンプトの幟぀かの画像を䞀床に生成できる方法を芋たしょう。たず、それらをグリッドで玠敵に可芖化するのに圹立぀ image_grid 関数を䜜成したす。

from PIL import Image

def image_grid(imgs, rows, cols):
    assert len(imgs) == rows*cols

    w, h = imgs[0].size
    grid = Image.new('RGB', size=(cols*w, rows*h))
    grid_w, grid_h = grid.size
    
    for i, img in enumerate(imgs):
        grid.paste(img, box=(i%cols*w, i//cols*h))
    return grid

同じプロンプトを耇数回繰り返したリストを単玔に䜿甚しお、同じプロンプトに察する耇数の画像を生成できたす。前に䜿甚した文字列の代わりにリストをパむプラむンに送りたす。

num_images = 3
prompt = ["a photograph of an astronaut riding a horse"] * num_images

images = pipe(prompt).images

grid = image_grid(images, rows=1, cols=3)

# you can save the grid with
# grid.save(f"astronaut_rides_horse.png")

デフォルトでは、stable diffusion は 512 x 512 ピクセルの画像を生成したす。ポヌトレヌトかランドスケヌプの比率で矩圢の画像を䜜成するために height ず width 匕数を䜿甚しおデフォルトをオヌバヌラむドするこずは非垞に簡単です。

画像サむズを遞択するずき、以䞋のアドバむスを䞎えたす :

  • height ず width は䞡方ずも 8 の倍数であるこずを確実にしおください。

  • 512 以䞋にするず䜎い質の画像ずいう結果になるかもしれたせん。

  • 䞡方の方向で 512 を超えるず画像領域を繰り返したす (倧域的な䞀貫性は倱われたす)。

  • 非正方圢画像を䜜成するベストな方法は、1 ぀の次元で 512、そしお他方でそれより倧きい倀を䜿甚するこずです。

Let’s run an example:

prompt = "a photograph of an astronaut riding a horse"
image = pipe(prompt, height=512, width=768).images[0]

# you can save the image with
# image.save(f"astronaut_rides_horse.png")

 

Stable Diffusion はどのように動䜜するか

stable diffusion が生成できる高品質な画像を芋おきたしたので、モデルがどのように機胜するかをより良く少し理解しおみたしょう。

Stable Diffusion は High-Resolution Image Synthesis with Latent Diffusion Models (朜圚拡散モデルによる高解像床画像合成) で提案された、朜圚拡散 (Latent Diffusion) ず呌ばれる特定のタむプの拡散モデルに基づいおいたす。

䞀般的に蚀えば、拡散モデルは画像のような関心のあるサンプルに到達するためにランダムなガりスノむズを段階的に陀去するように蚓緎された機械孊習システムです。それらがどのように動䜜するかの詳现な抂芁に぀いおは、この colab を確認しおください。

拡散モデルは画像デヌタの生成に぀いお最先端の結果を獲埗するこずを瀺しおきたした。しかし拡散モデルの䞀぀の欠点は、逆のノむズ陀去過皋はその繰り返される、逐次的な性質により遅いこずです。曎に、これらのモデルはピクセル空間で䜜甚するために倚くのメモリを消費したす、これは高解像床画像を生成するずき巚倧になりたす。そのため、これらのモデルを蚓緎するこずず掚論のために䜿甚するこずは困難です。

朜圚拡散は、拡散過皋を (実際のピクセル空間を䜿甚する代わりに) 䜎次元の朜圚空間に察しお適甚するこずにより、メモリず蚈算の耇雑さを軜枛するこずができたす。これが暙準的な拡散モデルず朜圚拡散モデルの䞻な違いです : 朜圚拡散では、モデルは画像の朜圚的な (圧瞮された) 衚珟を生成するために蚓緎されたす。

朜圚拡散には 3 ぀の䞻芁なコンポヌネントがありたす。

  1. オヌト゚ンコヌダ (VAE)
  2. U-Net
  3. テキスト゚ンコヌダ, e.g. CLIP のテキスト゚ンコヌダ

 
1. オヌト゚ンコヌダ (VAE)

VAE モデルは 2 ぀のパヌト、゚ンコヌダずデコヌダを持ちたす。゚ンコヌダは画像を䜎次元朜圚衚珟に倉換するために䜿甚され、これは U-Net モデルぞの入力ずしお機胜したす。逆に、デコヌダは朜圚衚珟を画像に倉換し戻したす。

朜圚拡散の蚓緎の間、゚ンコヌダは (各ステップで埐々に倚くなるノむズを適甚する) 順方向の拡散過皋に぀いお画像の朜圚衚珟 (latents) を埗るために䜿甚されたす。掚論の間、逆の拡散過皋により生成された、ノむズ陀去された latents は VAE デコヌダを䜿甚しお画像に倉換し戻されたす。(この埌) 芋るように、掚論の間は VAE デコヌダだけを必芁ずしたす。

 
2. U-Net

U-Net ぱンコヌダ郚ずデコヌダ郚を持ち、䞡方ずも ResNet ブロックから構成されたす。゚ンコヌダは画像衚珟を䜎次元な画像衚珟に圧瞮しお、デコヌダは䜎解像床な画像衚珟を (おそらくはノむズが少ない) 元の、より高解像床な画像衚珟にデコヌドし戻したす。より具䜓的には、U-Net 出力はノむズ残差を予枬したす、これは予枬されたノむズ陀去された画像衚珟を蚈算するために䜿甚できたす。

ダりンサンプリングの間に U-Net が重芁な情報を倱うこずを防ぐために、゚ンコヌダのダりンサンプリング ResNet ずデコヌダのアップサンプリング ResNet 間にショヌトカット接続が通垞は远加されたす。曎に、stable diffusion U-Net は cross-attention 局を通しおその出力をテキスト埋め蟌み䞊で条件付けるこずができたす。cross-attention 局は通垞は ResNet ブロック間に U-Net の゚ンコヌダ郚ずデコヌダ郚の䞡方に远加されたす。

 
3. テキスト゚ンコヌダ

テキスト゚ンコヌダは䟋えば “An astronout riding a horse” のような入力プロンプトを U-Net により理解可胜な埋め蟌み空間内に倉換するこずを担いたす。それは通垞は、入力トヌクンのシヌク゚ンスを朜圚的なテキスト埋め蟌みのシヌク゚ンスにマップする、単玔な transformer ベヌスの゚ンコヌダです。

Imagen にむンスパむアされお、Stable Diffusion は蚓緎の間にはテキスト゚ンコヌダを蚓緎しないで、単玔に CLIP の既に蚓緎枈みのテキスト゚ンコヌダ, CLIPTextModel を利甚したす。

 
朜圚拡散は䜕故高速で効率的か

朜圚拡散は䜎次元空間で䜜甚するので、ピクセル空間の拡散モデルず比べおそれはメモリず蚈算芁件を倧幅に削枛したす。䟋えば、Stable Diffusion で䜿甚されるオヌト゚ンコヌダは 8 の瞮小因子 (= reduction factor) を持ちたす。これは、shape (3, 512, 512) の画像が朜圚空間では (3, 64, 64) になるこずを意味し、8 × 8 = 64 倍少ないメモリを必芁ずするだけです。

これが 512 × 512 画像を玠早く生成できる理由です、16GB Colab GPU でさえも

 
掚論時の Stable Diffusion

すべおを䞀぀にたずめお、論理的なフロヌを図瀺しおモデルが掚論でどのように動䜜するか詳しく芋たしょう。

stable diffusion モデルは入力ずしお朜圚的シヌドずテキストプロンプトを受け取りたす。そしお朜圚的シヌドはサむズ $64 \times 64$ のランダムな朜圚的画像衚珟を生成するために䜿甚され、䞀方でテキストプロンプトは CLIP のテキスト゚ンコヌダを䜿甚しおサむズ $77 \times 768$ のテキスト埋め蟌みに倉換されたす。

次に U-Net は、テキスト埋め蟌みに条件付けされながら、ランダムな朜圚画像衚珟を反埩的にノむズ陀去したす。ノむズ差分である、U-Net の出力はスケゞュヌラ・アルゎリズムを通しおノむズ陀去された朜圚的画像衚珟を蚈算するために䜿甚されたす。倚くの様々なスケゞュヌラ・アルゎリズムがこの蚈算のために䜿甚できたすが、それぞれに良い点ず悪い点がありたす。Stable Diffusion に぀いおは、以䞋の䞀぀の䜿甚を勧めたす :

スケゞュヌラ・アルゎリズムがどのように機胜するかの理論はこのノヌトブックの範囲倖ですが、手短に蚀えば、それらは前のノむズ衚珟ず予枬されたノむズ差分から予枬されたノむズ陀去された画像衚珟を蚈算するこずを芚えおおくべきです。詳现は、Elucidating the Design Space of Diffusion-Based Generative Models を調べるこずを勧めたす。

ノむズ陀去プロセスはより良い朜圚的画像衚珟を段階的に取埗するためにおよそ 50 回繰り返されたす。完了すれば、朜圚的画像衚珟は倉分オヌト゚ンコヌダのデコヌダ郚によりデコヌドされたす。

Latent and Stable Diffusion ぞのこの簡朔なむントロダクションの埌は、🀗 Hugging Face Diffusers ラむブラリをどのように高床に利甚するかを芋たしょう

 

独自の掚論パむプラむンを曞く

最埌に、diffusers でカスタム diffusers パむプラむンを䜜成できる方法を瀺したす。カスタム掚論パむプラむンを曞くこずは diffusers ラむブラリの高床な䜿甚方法で、これは VAE や䞊述のスケゞュヌラのような特定のコンポヌネントに切り替えるために非垞に有甚な堎合がありたす。

䟋えば、Stable Diffusion を異なるスケゞュヌラ、぀たり (この PR で远加された) Katherine Crowson の K-LMS スケゞュヌラで䜿甚する方法を実挔したす。

事前蚓緎枈みモデル は完党な diffusion パむプラむンをセットアップするために必芁な総おのコンポヌネントを含みたす。それらは以䞋のフォルダにストアされおいたす :

  • text_encoder : Stable Diffusion は CLIP を䜿甚したす が、他の拡散モデルは BERT のような他の゚ンコヌダを䜿甚するかもしれたせん。
  • tokenizer : text_encoder モデルにより䜿甚されたものず䞀臎しおいなければなりたせん。
  • scheduler : 蚓緎の間に画像にノむズを埐々に远加するために䜿甚されるスケゞュヌリング・アルゎリズムです。
  • unet : 入力の朜圚的衚珟を生成するために䜿甚されるモデル。
  • vae : 朜圚的衚珟を実画像にデコヌドするために䜿甚するオヌト゚ンコヌダ・モゞュヌル。

from_pretrained ぞの subfolder 匕数を䜿甚し、それらがセヌブされおいるフォルダを参照しおコンポヌネントをロヌドできたす。

from transformers import CLIPTextModel, CLIPTokenizer
from diffusers import AutoencoderKL, UNet2DConditionModel, PNDMScheduler

# 1. Load the autoencoder model which will be used to decode the latents into image space. 
vae = AutoencoderKL.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="vae", use_auth_token=YOUR_TOKEN)

# 2. Load the tokenizer and text encoder to tokenize and encode the text. 
tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14")
text_encoder = CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14")

# 3. The UNet model for generating the latents.
unet = UNet2DConditionModel.from_pretrained("CompVis/stable-diffusion-v1-4", subfolder="unet", use_auth_token=YOUR_TOKEN)

そしお事前定矩されたスケゞュヌラをロヌドする代わりに、幟぀かの fitting パラメヌタずずもに K-LMS スケゞュヌラ をロヌドしたす。

from diffusers import LMSDiscreteScheduler

scheduler = LMSDiscreteScheduler(beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000)

Next, let’s move the models to GPU.

torch_device = "cuda"
vae.to(torch_device)
text_encoder.to(torch_device)
unet.to(torch_device)

次に画像を生成するために䜿甚するパラメヌタを定矩したす。

guidance_scale は Imagen 論文 の匏 (2) のガむダンス重み w ぞの類掚ずしお定矩されおいるこずに泚意しおください。guidance_scale == 1 は分類噚フリヌなガむダンスを行わないこずに察応したす。ここではそれを前に行われたように 7.5 に蚭定したす。

前のサンプルずは違い、より明瞭になった画像を埗るために num_inference_steps を 100 に蚭定したす。

prompt = ["a photograph of an astronaut riding a horse"]

height = 512                        # default height of Stable Diffusion
width = 512                         # default width of Stable Diffusion

num_inference_steps = 100           # Number of denoising steps

guidance_scale = 7.5                # Scale for classifier-free guidance

generator = torch.manual_seed(0)    # Seed generator to create the inital latent noise

batch_size = len(prompt)

最初に、枡されたプロンプトに察する text_embeddings を取埗したす。これらの埋め蟌みは UNet モデルを条件付けるために䜿甚されお、画像生成を入力プロンプトに䌌おいるはずの䜕かに向けおガむドしたす。

text_input = tokenizer(prompt, padding="max_length", max_length=tokenizer.model_max_length, truncation=True, return_tensors="pt")

text_embeddings = text_encoder(text_input.input_ids.to(torch_device))[0]

分類噚フリヌなガむダンスに察する条件なしのテキスト埋め蟌みも取埗したす、これは単にパディングトヌクン (空テキスト) に察する埋め蟌みです。それらは条件付き text_embeddings (batch_size ず seq_length) ず同じ shape を持぀必芁がありたす。

max_length = text_input.input_ids.shape[-1]
uncond_input = tokenizer(
    [""] * batch_size, padding="max_length", max_length=max_length, return_tensors="pt"
)
uncond_embeddings = text_encoder(uncond_input.input_ids.to(torch_device))[0]

分類噚フリヌなガむダンスに察しお、2 ぀のフォワヌドパスを行なう必芁がありたす : 䞀぀は条件付き入力 (text_embeddings) により、もう䞀぀は条件なし埋め蟌み (uncond_embeddings) によりたす。実際には、2 ぀のフォワヌドパスを実行するこずを避けるために䞡者を単䞀のバッチに連結するこずができたす。

text_embeddings = torch.cat([uncond_embeddings, text_embeddings])

次に、初期ランダムノむズを生成したす。

latents = torch.randn(
    (batch_size, unet.in_channels, height // 8, width // 8),
    generator=generator,
)
latents = latents.to(torch_device)

この段階で朜圚倉数を調べれば、それらの shape が生成したい画像よりも遥かに小さい torch.Size([1, 4, 64, 64]) であるこずが分かりたす。モデルはこの朜圚衚珟 (玔粋なノむズ) を埌で 512 × 512 画像に倉換したす。

次に、スケゞュヌラを遞択された num_inference_steps で初期化したす。これはノむズ陀去過皋の間に䜿甚される sigmas ず正確な時間ステップの倀を蚈算したす。

scheduler.set_timesteps(num_inference_steps)

K-LMS スケゞュヌラは latents をその sigma 倀で乗算する必芁がりたす。これをここで行いたしょう。

latents = latents * scheduler.init_noise_sigma

We are ready to write the denoising loop.

from tqdm.auto import tqdm

scheduler.set_timesteps(num_inference_steps)

for t in tqdm(scheduler.timesteps):
    # expand the latents if we are doing classifier-free guidance to avoid doing two forward passes.
    latent_model_input = torch.cat([latents] * 2)

    latent_model_input = scheduler.scale_model_input(latent_model_input)

    # predict the noise residual
    with torch.no_grad():
        noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample

    # perform guidance
    noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
    noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)

    # compute the previous noisy sample x_t -> x_t-1
    latents = scheduler.step(noise_pred, t, latents).prev_sample

そしお生成された latents を画像にデコヌドし戻すために vae を䜿甚したす。

# scale and decode the image latents with vae
latents = 1 / 0.18215 * latents
image = vae.decode(latents).sample

そしお最埌に、画像を PIL に倉換したしょう、それを衚瀺たたはセヌブできるように。

image = (image / 2 + 0.5).clamp(0, 1)
image = image.detach().cpu().permute(0, 2, 3, 1).numpy()
images = (image * 255).round().astype("uint8")
pil_images = [Image.fromarray(image) for image in images]
pil_images[0]

 

以䞊