VACEの限界を探る: 矩形マスクは絶対なのか?キーフレーム補間のようなタスクは可能か?
今回はいくつかの実験を通じて、VACEの能力の限界と可能性を探りました。
結論から言うと、矩形マスクは必須ではないこと、Outpaintingは1.3Bで厳しいということ、そしてキーフレーム補間はアーキテクチャ上の制約から困難であることがわかりました。
実験1: 矩形マスクは必要か?(鉄骨Inpainting)
背景
前回までで「BBox(矩形マスク)が最強」という結論に至りましたが、それは本当に矩形である必要があるのでしょうか?
実験内容
廃墟動画の中に、かつて屋根の一部だった鉄骨構造が剥き出しになっている部分がありました。これを矩形ではない、鉄骨の形状に沿った不規則なマスクでInpaintingしてみました。
設定:
- マスク: 鉄骨の形に沿った不規則形状(ただし元の構造を想起させないよう工夫)
- リファレンス画像: なし
- ネガティブプロンプト: 積極的に活用
ネガティブプロンプトはデフォルトではハードコードされていて、実行時にユーザーによる入力はそのままではできないようになってます。簡単に argparse などで受け入れるようにすれば使用できます。
結果: 成功
矩形でなくても、元を想起させないマスク形状であれば問題なく機能しました。
考察:
「VAEの1/8空間圧縮」は 細かすぎるマスク(髪の毛の先、指先など)は問題だけど十分な面積がああれば問題ないです。
重要なのは「矩形かどうか」ではなく、**「VAE圧縮後もマスク境界が明確か」**という点です。さらにそこに生み出される形状を想起させないことが重要です。
実験2: 銃の除去(Removal)
実験内容
動画内の男性が手に持っている銃を消してみました。
設定:
- マスク: 銃の領域をカバー
- リファレンス画像: なし
- ネガティブプロンプト:
gun, weaponなど
結果: 成功
銃は綺麗に消え、人物や背景でうまく補完されました。
考察:
ネガティブプロンプトは「念押し」として有効です。ただし、以前述べた通り、基本はVisual Context(映像の文脈)に任せるのが最強。ネガティブプロンプトは補助的な役割です。
実験3: Outpainting(画像拡張)
実験内容
入力画像を80%に縮小し、外側の20%領域を生成させるOutpaintingを試みました。
設定:
- 入力: 80%に縮小した動画(中央配置、外側はグレー)
- マスク: 外側領域がreactiveエリアとなりここで生成されます
- リファレンス画像: あり(重要)
リファレンス画像の工夫
ここで重要な発見がありました。リファレンス画像は全体画像をそのまま渡す必要がないのです。
外側領域っぽい雰囲気になりそうな、適当にクロップした画像を3枚ほど渡しました。なぜこれで機能するのか?
リファレンス画像の内部処理
コードを確認したところ:
# vace/models/wan/wan_vace.py
ref_latent = vae.encode(refs) # VAEを通る
latent = torch.cat([*ref_latent, latent], dim=1) # 時間軸でプリペンド
リファレンス画像は:
- 全てのreferece画像は一旦入力動画サイズにフィットされる
- VAEでエンコードされる
- 動画のlatentの時間軸の先頭に結合される
- Self-Attentionで参照される
つまり、同じレイアウトである必要すらない。モデルはAttentionで「この雰囲気を参考にしろ」という情報として利用するだけです。
結果
| モデル | 結果 |
|---|---|
| 1.3B | 鉄骨のつながりなどに問題あり |
| 14B | 改善が見られた。構造の整合性向上 |
考察:
Outpaintingは「何もない領域から新しいコンテンツを生成する」タスクなので、モデルの表現力が直接影響します。14Bの大きなモデル容量が効いています。
実験4: キーフレーム補間(失敗と分析)
目標
N個のキーフレーム画像(例: フレーム0, 8, 16...)を与え、その間を滑らかに補間した動画を生成する。
方法
-
src_video: キーフレーム位置に画像、他はグレー(0.5) -
src_mask: キーフレーム位置はKEEP(0)、他はGENERATE(1)
理論上、これはFirstframe生成(1フレームから80フレームを生成)よりも簡単なはずです。情報量が多いのですから。
結果: 失敗
観察された現象:
Frame 0: 完璧に保持 ✓
Frame 1-3: 再構成がうまくいかない
Frame 4: KEEPのはずなのに再構成される
...
Frame 25-52: グレーベースで大幅に劣化
Frame 52-80: 最初のパターンに戻る
なぜ失敗したのか?5つの根本原因を特定しました。
キーフレーム補間が失敗する5つの理由
1. VAE時間圧縮による混合
VAEのtemporal strideは4です。つまり、4フレームが1つのlatent timestepに圧縮されます。
1フレームだけKEEPの場合:
入力: [keyframe, gray, gray, gray]
inactive: [image, 0, 0, 0 ]
↓ VAE encode
latent: 「画像 + 黒 + 黒 + 黒」の混合表現
この混合latentから元のkeyframe情報を復元することは困難です。
解決策: 4フレームをブロック単位でKEEP/GENERATEを統一する。
入力: [KEY, KEY, KEY, KEY, gray, gray, gray, gray, ...]
↓ VAE encode
latent: [クリーンな画像情報], [クリーンなグレー], ...
これにより再構成品質が改善されました。
2. マスク圧縮の位置ずれ
マスクはnearest-exactでダウンサンプリングされます:
81フレーム → 21タイムステップ
計算式: frame = floor((t + 0.5) * 81 / 21)
実際のサンプリング位置:
Timestep: 0 1 2 3 4 5 6 ...
Frame: 1 5 9 13 17 21 25 ...
Frame 0はサンプリングされない! Timestep 0はFrame 1を見ます。
4フレームおき(0, 4, 8, 12...)にKEEPを置いても、サンプリング位置(1, 5, 9, 13...)とずれるため、KEEP情報が圧縮後に失われます。
3. 二つの周期の干渉(ビート現象)
観察された「25-52フレームで劣化」は、2つの周期が干渉した結果でした。
キーフレーム周期: 4フレームごと(規則的)
サンプリング間隔:
1→5: 4
5→9: 4
...
21→25: 4
25→28: 3 ← ここで不規則に!
...
48→52: 4
52→55: 3 ← またずれる!
これにより、位相が合う領域(0-24, 52-80)と合わない領域(25-52)が生まれ、sin波の合成のようなパターンが観察されました。
4. Attention均等分布問題
これが核心的な問題です。
全面GENERATE(mask=1)の場合:
inactive = 全ゼロ(画像情報なし)
↓ VAE encode
latent = 均一な値
↓ Self-Attention
Q @ K.T = 均一なスコア
softmax = [1/N, 1/N, 1/N, ...] # 均等分布
Softmaxが均等分布 = 「どこにも注目しない」
Attentionが機能するには、不均一な入力が必要です。全面GENERATEでは、モデルが「どこを見ればいいか」わからなくなります。
5. 空間アンカーの必要性
Firstframeが成功する理由:
Latent: [★実画像, ○空, ○空, ○空, ...]
↑
「ここだけ見ればいい」= 明確
キーフレーム補間の問題:
Latent: [★, ○, ○, ○, ★, ○, ○, ○, ★, ...]
「あちこちに散らばってる...」= 困難
さらに、空間的なアンカーも重要でした。
テスト結果:
| 設定 | 結果 |
|---|---|
| 4ブロック + 全面GENERATE | マシだが不完全 |
| 4ブロック + 上半分だけGENERATE | ほぼ完璧 |
上半分だけGENERATEにすると、下半分のKEEP領域が空間的アンカーとして機能し、Attentionが正しく動作しました。
最低でも16ピクセル程度の空間的KEEP領域(テストでは16x832程度)があると、再構成が安定することがわかりました。
VACEアーキテクチャの設計思想
Firstframeと呼ばれるタスクがあって、1フレーム目だけを見せてあとはテキストプロンプトでドリブンするというのがあります。
ではなぜFirstframeは動くのにキーフレーム補間は動かないのか?
| タスク | アンカー | 学習パターン | 結果 |
|---|---|---|---|
| Inpainting | 空間的に大部分がKEEP | 容易 | ✓ |
| Firstframe | 時間的に1点(先頭) | 「先頭を見る」= 容易 | ✓ |
| Keyframe補間 | 時間的に散在 | 「どこかを探す」= 困難 | ✗ |
VACEは以下のタスクに最適化されています:
- 空間的なInpainting/Outpainting(空間アンカーあり)
- Firstframe/Lastframe生成(明確な時間アンカー)
純粋な時間的補間(空間アンカーなし)は設計上困難です。
DiT Patch Size の影響
余談ですが、DiTのpatch sizeは(1, 2, 2) (t, h, w)です。
- 時間: 1 → 各フレーム独立(VAE後なので実質4元フレーム)
- 空間: 2×2 → ローカル情報がパッチに含まれる
時間方向のパッチサイズが1ということは、時間的一貫性は完全にAttention頼みということ。空間は2×2のパッチに局所情報が含まれるため補間しやすいですが、時間方向はそうではありません。
まとめ
今回の発見
- 矩形マスクは必須ではない: 十分な面積があり境界が明確なら不規則形状でもOK
- Outpaintingは14Bで実用レベル: リファレンス画像は雰囲気を伝えるクロップ画像でOK
- キーフレーム補間は困難: アーキテクチャ上の制約(VAE圧縮、Attention均等分布)
キーフレーム補間への対処法
完全な解決策ではありませんが、以下で改善可能:
- 4フレームブロック方式: VAE strideに合わせてブロック化
- 空間アンカーを残す: 部分的にKEEP領域を残す(最低16ピクセル程度)
- 14Bモデル使用: より高い表現力
最終結論
VACEは**「消す」「埋める」「拡張する」**には強力ではあるが、 「時間的に補間する」 には向いてないかもしれません。
VFX素材提供:ActionVFX(Free Assets)
VFX assets courtesy of ActionVFX










