問題の概要:AnimateDiffで生成される動画のフレーム数が想定と異なる
ComfyUIのAnimateDiffを使用して動画を生成する際、多くのユーザーが以下のような問題に遭遇します。
- 設定したフレーム数(例:16フレーム)で生成したはずなのに、出力される動画が8フレームしかない
- 動画の長さが期待した秒数よりも短い、または長くなりすぎる
- 「ValueError: video_frames must be divisible by context_length」といったエラーメッセージが表示される
- 生成された動画がカクカクして滑らかでない
これらの問題は、AnimateDiffのフレーム制御に関する複数の設定が連動しており、初心者だけでなく中級者でも混乱しやすいポイントです。特に、context_length、frame_number、batch_sizeといったパラメータの関係を理解していないと、意図した通りの動画を生成することが難しくなります。
原因の解説:複数のパラメータが絡み合うフレーム生成の仕組み
AnimateDiffにおける動画生成は、単純に「フレーム数を指定する」だけでは完了しません。主に以下の3つの要素が生成される動画のフレーム数と品質に影響を与えます。
1. コンテキスト長(context_length)の制約
AnimateDiffモデルは、連続するフレームの塊(コンテキスト)を一度に処理するように設計されています。この塊のサイズがcontext_lengthです。多くのAnimateDiffモデル(例:mm_sd_v15_v2.ckpt)のデフォルトcontext_lengthは16です。これは、モデルが16フレームを1つの単位として動きを学習・生成することを意味します。したがって、生成したい総フレーム数はcontext_lengthで割り切れる必要があります。割り切れない数を指定すると、エラーが発生したり、自動的に調整されたりします。
2. バッチサイズ(batch_size)と繰り返し(loop)の影響
ComfyUIのAnimateDiffノードでは、batch_sizeというパラメータで一度に処理するコンテキストの数を指定します。また、closed_loopオプションは、最初と最後のフレームを滑らかにつなげるかどうかを制御します。これらの設定とframe_number(目標総フレーム数)が整合していないと、実際に生成されるフレーム数がずれてしまいます。
3. ワークフロー内の他のノードとの連携
動画生成ワークフローには、Load Images(画像読み込み)ノード、VAE Encode、KSamplerなど、多くのノードが関わります。特に、動画を画像シーケンスとして保存・読み込みする際の設定ミス(フレームレートやインデックス番号の付け方)も、最終的な動画の長さや滑らかさに影響を与える原因となります。
解決方法:ステップバイステップでのフレーム数制御
ここからは、AnimateDiffで正確なフレーム数の動画を生成するための具体的な手順を説明します。
ステップ1:使用するモデルとcontext_lengthの確認
まず、使用するAnimateDiffモデルの仕様を確認します。モデルファイル(.ckpt)によって推奨されるcontext_lengthが異なります。
例:
- mm_sd_v15_v2.ckpt -> context_length: 16 (推奨)
- mm_sd_v14.ckpt -> context_length: 16 (推奨)
- カスタムトレーニングモデル -> トレーニング時の設定を確認
「AnimateDiff Loader」ノードのcontext_length欄には、モデルに合わせた値を入力します。
ステップ2:フレーム数の計算と設定
生成したい動画の総フレーム数(N)を決めます。この数は、ステップ1で確認したcontext_length(C)で割り切れる数である必要があります。
計算式:目標フレーム数 N = C × k (kは正整数)
例えば、context_length=16で24フレームの動画を作りたい場合、16で割り切れないのでエラーになります。代わりに、16フレーム(k=1)または32フレーム(k=2)を目標とします。
この計算されたフレーム数Nを、「Empty Latent Image」ノードのbatch_sizeフィールドに入力します。ここでのbatch_sizeは、生成する画像(フレーム)の枚数を意味します。
例:32フレーム生成したい場合
Empty Latent Image ノード設定:
width: 512
height: 512
batch_size: 32 ← ここに総フレーム数を入力
ステップ3:AnimateDiffノードのパラメータ設定
「AnimateDiff Loader」でモデルを読み込んだ後、「Apply AnimateDiff Model」ノードの設定が重要です。
batch_size: ここでのバッチサイズは「何個のコンテキストを一度に処理するか」を意味します。目標フレーム数Nをcontext_lengthCで割った値(k)を設定します。frame_number: 基本的に空白(デフォルト)のままにします。ここに値を入れると、Empty Latent Imageで設定したbatch_sizeを上書きしてしまう可能性があります。フレーム数はステップ2で設定したbatch_sizeで制御するのが確実です。closed_loop: ループ動画を作りたい場合は有効にします。有効にすると、モデルが最初と最後のフレームのつながりを考慮するようになります。
例:context_length=16, 目標フレーム数=32の場合
Apply AnimateDiff Model ノード設定:
batch_size: 2 (∵ 32 ÷ 16 = 2)
frame_number: (空白)
closed_loop: (好みで選択)
ステップ4:サンプラー(KSampler)の設定
KSamplerのbatch_sizeは1に設定します。AnimateDiffによるフレーム生成のバッチ処理は「Apply AnimateDiff Model」ノードが担当するため、KSampler側では通常の画像生成と同様に1を指定します。
ステップ5:動画の保存と確認
「VAE Decode」と「Save Image」ノードを使用する場合、バッチとして出力された全フレームが連番画像として保存されます。「Preview Image」ノードで確認すると、最初の1枚だけが表示されることがありますが、保存される画像ファイルはバッチ全体(全フレーム)です。
動画ファイルとして出力したい場合は、「ComfyUI-FFmpeg」などの動画エンコードノードを導入し、フレームレート(fps)を設定します。これにより、動画の長さ(秒数)を正確にコントロールできます。
動画の長さ(秒) = 総フレーム数(N) ÷ フレームレート(fps)
例:32フレーム、fps=8の場合 -> 32 ÷ 8 = 4秒の動画
コード例・ワークフロー例
以下は、ComfyUIのAPI(またはワークフローJSONの一部)を想定した、16フレームの動画を生成するための主要ノードの設定例です。
{
"3": { // Empty Latent Image ノード
"inputs": {
"width": 512,
"height": 512,
"batch_size": 16 // 総フレーム数 = 16
},
"class_type": "EmptyLatentImage"
},
"5": { // AnimateDiff Loader ノード
"inputs": {
"model_name": "mm_sd_v15_v2.ckpt",
"context_length": 16 // モデル推奨値
},
"class_type": "AnimateDiffLoaderV1"
},
"7": { // Apply AnimateDiff Model ノード
"inputs": {
"model": ["5", 0], // AnimateDiff Loaderから接続
"latent": ["3", 0], // Empty Latent Imageから接続
"batch_size": 1, // 16 ÷ 16 = 1
"frame_number": null, // 空白(null)
"closed_loop": false
},
"class_type": "AnimateDiffApplyV1"
},
"10": { // KSampler ノード
"inputs": {
"seed": 123456,
"steps": 20,
"cfg": 8,
"sampler_name": "euler",
"scheduler": "normal",
"denoise": 1,
"model": ["1", 0], // 安定拡散モデル
"positive": ["2", 0], // プロンプト
"negative": ["2", 1], // ネガティブプロンプト
"latent": ["7", 0], // Apply AnimateDiff Modelから接続
"batch_size": 1 // 必ず1に設定
},
"class_type": "KSampler"
}
}
まとめ・補足情報
AnimateDiffのフレーム制御で最も重要なポイントは、「総フレーム数は『Empty Latent Image』のbatch_sizeで設定し、それはcontext_lengthの倍数であること」 です。そして、そのフレーム数を実現するためのコンテキストのバッチ数を「Apply AnimateDiff Model」ノードのbatch_sizeで設定します。
トラブルが発生した場合は、次のチェックリストを確認してください。
- エラーメッセージを読む:「divisible by context_length」とあれば、フレーム数が
context_lengthで割り切れていないことが原因です。 - ノードの接続を確認する:「Apply AnimateDiff Model」ノードが「Empty Latent Image」ノードとKSamplerの間に正しく挟まれているか確認します。
- パラメータの上書きを防ぐ:「Apply AnimateDiff Model」の
frame_numberは空白推奨です。複数の場所でフレーム数を設定すると矛盾が生じます。 - モデルと設定の一致:カスタムトレーニングしたAnimateDiffモデルを使用する場合は、そのモデルが学習された
context_lengthを必ず使用してください。
これらの原則を理解し、設定を見直せば、AnimateDiffで思い通りの長さと滑らかさの動画を生成できるようになります。最初は単純なフレーム数(16, 32, 48など)から試し、仕組みに慣れてから複雑なワークフローに挑戦することをおすすめします。