ジャコ Lab

プログラミング関連のメモ帳的ブログです

diffusers で AnimateDiff を初めて使ってみる

github.com

diffusers v0.22.0 でサポートされた AnimateDiffPipeline を使って、 AnimateDiff を使ってみます。

まずは、リリースノートにある通りのプログラムを実行してみます。

はじめに

AnimateDiff とは Text-to-Video の1つで、既存の StableDiffsion モデルにモーションモジュールを差し込むらしいです。

全然わからん。でも IN と OUT の間になにか増えたのはわかる。

何も考えずにやってみる

モデルのロード等 (MotionAdapter, AnimateDiffPipeline, DDIMScheduler)

import torch
from diffusers import MotionAdapter, AnimateDiffPipeline, DDIMScheduler

# モーションアダプターのロード
adapter = MotionAdapter.from_pretrained(
    "guoyww/animatediff-motion-adapter-v1-5-2"
)

# SD 1.5系のモデルを AnimateDiffPipeline でロード
pipe = AnimateDiffPipeline.from_pretrained(
    "SG161222/Realistic_Vision_V5.1_noVAE",
    motion_adapter=adapter
)

# スケジューラの設定
pipe.scheduler = DDIMScheduler.from_config(
    pipe.scheduler.config,
    clip_sample=False,
    timestep_spacing="linspace",
    steps_offset=1
)

# enable memory savings
pipe.enable_vae_slicing()
pipe.enable_model_cpu_offload()

パイプライン実行

import torch

# パイプライン実行
prompt = "masterpiece, bestquality, highlydetailed, ultradetailed, sunset, orange sky, warm lighting, fishing boats, ocean waves seagulls, rippling water, wharf, silhouette, serene atmosphere, dusk, evening glow, golden hour, coastal landscape, seaside scenery"
negative_prompt = "bad quality, worse quality"
frames = pipe(
    prompt,
    negative_prompt = negative_prompt,
    num_frames=16,
    guidance_scale=7.5,
    num_inference_steps=25,
    generator=torch.manual_seed(42),
).frames[0]

実行結果

画像がパラパラ漫画のように frames で返ってきているので gif で保存する
from diffusers.utils import export_to_gif
from datetime import datetime
from zoneinfo import ZoneInfo

# Asia/Tokyo タイムゾーンの現在時刻を YYYYMMDDhhmmss 形式で得る
formattedNow = datetime.now(tz=ZoneInfo("Asia/Tokyo")).strftime("%Y%m%d%H%M%S")

# 実行結果
export_to_gif(frames, f"animation_{formattedNow}.gif")

AnimateDiff チュートリアルを出力した様子
AnimateDiff チュートリアルの出力結果

リリースノート通り!

ToonYou でやってみる

なぜ ToonYou で試すのか?

animatediff.github.io

公式のギャラリーの方で挙がっていたからです。

以下のプロンプトでの実行結果

prompt = "masterpiece, best quality, 1girl, solo, cherry blossoms, hanami, pink flower, white flower, spring season, wisteria, petals, flower, plum blossoms, outdoors, falling petals, white hair, black eyes"
negative_prompt="bad quality, worse quality"

ToonYou のモデルを使って出力した様子
ToonYou の出力結果

うーん。これじゃない。

リリースノートにあったプログラムのモデル部分だけ変えたためか、求めてるような鮮やかな感じではなかったです。

スクリプト全体

スクリプト全体 (折りたたみ)

import torch
from diffusers import MotionAdapter, AnimateDiffPipeline, DDIMScheduler
from diffusers.utils import export_to_gif
from datetime import datetime
from zoneinfo import ZoneInfo

# モーションアダプターのロード
adapter = MotionAdapter.from_pretrained(
    "guoyww/animatediff-motion-adapter-v1-5-2"
)

# SD 1.5系のモデルを AnimateDiffPipeline でロード
pipe = AnimateDiffPipeline.from_pretrained(
    "frankjoshua/toonyou_beta6",
    motion_adapter=adapter
)

# スケジューラの設定
pipe.scheduler = DDIMScheduler.from_config(
    pipe.scheduler.config,
    clip_sample=False,
    timestep_spacing="linspace",
    steps_offset=1
)

# enable memory savings
pipe.enable_vae_slicing()
pipe.enable_model_cpu_offload()

# パイプライン実行
prompt = "masterpiece, best quality, 1girl, solo, cherry blossoms, hanami, pink flower, white flower, spring season, wisteria, petals, flower, plum blossoms, outdoors, falling petals, white hair, black eyes"
negative_prompt="bad quality, worse quality"
frames = pipe(
    prompt,
    negative_prompt = negative_prompt,
    num_frames=16,
    guidance_scale=7.5,
    num_inference_steps=25,
    generator=torch.manual_seed(6520604954829636163),
).frames[0]

# Asia/Tokyo タイムゾーンの現在時刻を YYYYMMDDhhmmss 形式で得る
formattedNow = datetime.now(tz=ZoneInfo("Asia/Tokyo")).strftime("%Y%m%d%H%M%S")

# 実行結果
export_to_gif(frames, f"animation_{formattedNow}.gif")

まとめ

AnimateDiff の触りをやりましたが、かなりの時間が溶けそうな気がしました...