Files
LTX-2/docs/plan.md
T
indigo 110adc781e Add SCAIL-2 in-context mask channels (Phase 2, plumbing + zero-init surgery)
Port mechanism 2 of SCAIL-2 (arXiv:2606.10804) to LTX-2: extra per-token
in-context conditioning channels (1 environment switch + K=6 character binding
slots) concatenated onto the latent before the first projection.

Faithful temporal encoding for LTX's VAE (temporal factor 8): each latent frame
stacks its 8 pixel sub-frames along the channel dim, giving 8*(K+1)=56 channels
(vs the paper's 4*(K+1)=28 on Wan 2.1).

Plumbing (backward compatible; cond_channels=None leaves every existing pipeline
unchanged):
- LatentState/Modality gain an optional cond_channels field (patchified [B,T,C]).
- LTXModel(mask_conditioning_channels=0) config-gates a widened patchify_proj;
  TransformerArgsPreprocessor concatenates cond_channels (or zero-pads) before it.
- tools.clear_conditioning trims it; token-appending conditioning items
  (reference video/audio, driving, keyframe) extend it via extend_cond_channels.

New:
- VideoConditionByMaskChannels: encodes (K+1) pixel masks -> 56 channels, written
  onto the trailing driving tokens (noisy target stays all-zero, per the paper).
- widen_patchify_proj_for_mask_channels: zero-init checkpoint surgery so a
  converted model reproduces the base output exactly until finetuned.

Verified (CPU, random weights): backward compat, zero-init widened forward is
bit-identical to baseline for any cond_channels, and the driving+mask pipeline
forwards without crashing with correct placement/clipping. Visual quality
requires Phase 3 finetuning; Replacement-mode z_ref height shift still deferred.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 09:50:27 +08:00

63 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SCAIL-2 → LTX-2 移植計畫
將 SCAIL-2arXiv:2606.10804`zai-org/SCAIL-2`)的端到端角色動畫手法移植到 LTX-2。
> **注意**SCAIL-2 原始實作建構於 **Wan 2.1**,非 LTX-2。座標慣例與架構需翻譯到 LTX 的資料流。
## 三個核心機制
1. **Driving latent 直接串接** — 把驅動影片 latent 直接接進 DiT token 序列(不經骨架/pose 中介),用 width 軸座標偏移 ΔW 讓 driving 座標跟主 video 座標分開。
2. **In-context mask channel** — 疊加額外輸入 channel(1 個環境開關 + K=6 個角色綁定槽,展開為 `4(K+1)=28` channel)到模型輸入,讓模型知道背景/角色對應。
3. **Mode-specific RoPE** — Animation Mode 與 Replacement Mode 用不同的座標指派規則。
## LTX-2 對應落點
| 機制 | LTX-2 落點 | 改權重? |
|---|---|---|
| 1. Driving 串接 + ΔW | 新 `ConditioningItem`clone `reference_video_cond.py`),改 `positions` 偏移 | 否 |
| 3. Mode-specific RoPE | 上述 item 加 `DrivingMode` enum | 否 |
| 2. In-context mask channel | 加寬 `patchify_proj` 輸入 channel + `LatentState` 帶額外 channel + 投影前 concat | **是**(需微調) |
**關鍵洞察**LTX 的 `ConditioningItem.apply_to(latent_state, latent_tools) -> LatentState` 就是「串接進序列」的天然注入點,機制 1+3 **完全不用動 transformer / rope.py**。RoPE 由 `LatentState.positions` `[B,3,T,2]`pixel 座標,axis1=(time,h,w))驅動;ΔW = 對 `positions[:,2]`width)加常數。width 正規化上界 `max_pos[2]=2048`,超過會 wrap。
## SCAIL-2 座標規則(論文)
序列 `[z_ref; z_t; z_driv]`driving 永遠在 width 軸帶固定偏移 ΔW:
| | Animation | Replacement |
|---|---|---|
| z_ref | T=0, H=[0,Hv), W=[0,Wv) | T=0, **H=[ΔH_ref, ΔH_ref+Hv)**, W=[0,Wv) |
| z_t | T=[1,Tv], H=[0,Hv), W=[0,Wv) | T=[0,Tv1], H=[0,Hv), W=[0,Wv) |
| z_driv | T=[1,Tv], H=[0,Hv), **W=[ΔW, ΔW+Wv)** | T=[0,Tv1], H=[0,Hv), **W=[ΔW, ΔW+Wv)** |
## 分階段計畫
### Phase 1 — Driving 串接 item(機制 1+3,推論期 PoC)✅ 已完成
- 純推論、不改權重、不動 `patchify_proj`、不碰 ltx-trainer。
- 用現有 checkpoint 驗證資料流正確性(序列長度、座標偏移、attention mask、denoise_mask、不 wrap)。
- **PoC 僅驗證 plumbing**LTX-2 未經此訓練,畫面不會是正確動畫。
### Phase 2 — In-context mask channel(機制 2checkpoint 手術)✅ 已完成(plumbing
- **決策**:時間編碼採忠實堆疊,`8×(K+1)=56` channelLTX 時間因子 8K=6),非 Wan 的 28。
- `LTXModel(mask_conditioning_channels=0)` config-gated 加寬 `patchify_proj`;預設不變。
- `LatentState`/`Modality``cond_channels` 欄位,跟著 clone/clear/append 流動;投影前在 `_apply_patchify_proj` concatNone 補零)。
- 新輸入欄位 **zero-init**`widen_patchify_proj_for_mask_channels` 轉換舊 checkpoint,行為不變、待微調才生效。
- `VideoConditionByMaskChannels`(K+1) 語意 mask → 空間下採樣 + 時間 8× 堆疊 → 寫入尾端 driving tokentarget 保持零,符合論文)。
- 驗證通過(`verify_mask_channels.py`):向後相容、zero-init 加寬 forward == baseline、mask pipeline 不 crash。**僅驗證 plumbing,畫質需 Phase 3 微調。**
### Phase 3 — 訓練整合(ltx-trainer)⬜ 未開始
- dataset 產出 (target, driving, mask),接上 Phase 1/2 conditioning,設微調 loss 與凍結策略。
### Phase 4 — Pipeline + CLI 包裝 ⬜ 未開始
- 仿 `lipdub.py``scail_animation.py` pipeline + arg parser。
## Phase 1 簡化取捨(記錄,Phase 2 需回頭處理)
- (a) driving 時間座標直接複製 target 的(token-wise),故 driving 需與 target 同 F/H/W。
- (b) 單一 frozen driving group 的 `attention_mask` 維持 None(= 全連接,target 完全看得到 driving),與 reference cond 一致。
- (c) **ANIMATION 與 REPLACEMENT 在 Phase 1 產生相同 driving 座標** — mode 差異(z_ref 的 ΔH_ref 高度位移、target 時間原點、mask channel)屬 Phase 2enum 先保留佔位。
## 參考
- 論文:arXiv:2606.10804 — *SCAIL-2: Unifying Controlled Character Animation with End-to-end In-Context Conditioning*
- 官方實作:`zai-org/SCAIL-2`GitHub / HuggingFace),建構於 Wan 2.1
- 藍本檔案:`packages/ltx-core/src/ltx_core/conditioning/types/reference_video_cond.py`