Files
hao-ai-lab-FastVideo/v2/training/methods/self_forcing.py
T
SolitaryThinker 4e331eb7ff [refactor] v2: use absolute imports (v2.*) everywhere instead of relative
Mechanical conversion of every relative import under v2/ to an absolute v2.* path
(from .x / ..x / ...x -> from v2.<pkg>.x) so imports are unambiguous, grep-able, and
stable when code is copied/moved between entrypoints (VideoGenerator, CLI, server).

Surgical prefix-only rewrite: only the 'from <dots><module>' prefix changed — import
names, parentheses, multi-line formatting, comments, and ordering are byte-for-byte
preserved (no collapsing, no reorder, no unrelated reformatting).

- 471 imports across 125 files; v2/tests/ was already absolute (untouched).
- Validated: all 125 files compile, every 'from v2.* import' target resolves to a real
  module/package, zero relative imports remain (full sweep), CPU mini suite green
  (202 passed, 2 skipped).
2026-07-04 17:15:34 +00:00

39 lines
1.8 KiB
Python

"""Self-forcing — causal video distillation (design_v3 §10; repo: self_forcing.py extends DMD2).
> Self-forcing is "train against your own KV-cached causal rollout."
The student rollout is the SHARED ``chunk_rollout`` loop (with the slab-KV cache) — exactly the
loop the engine streams at serve time — so the causal student is distilled under the runtime it
will be served on (the (recipe, runtime) pair, §2.1). The distribution-matching loss is DMD2's,
applied to the causal rollout latents. (The repo uses a dedicated SelfForcingFlowMatchScheduler;
the mini reuses the shared flow-match sampler — the structure being demonstrated is the causal
rollout + KV + DMD loss.)
"""
from __future__ import annotations
import numpy as np
from v2._enums import ConsistencyLevel
from v2.request import DiffusionParams, TaskType, make_request
from v2.training.methods.base import new_instance
from v2.training.methods.dmd2 import DMD2Method
class SelfForcingMethod(DMD2Method):
name = "self_forcing"
consistency = ConsistencyLevel.C1
student_loop_id = "chunk_rollout" # the SHARED causal loop (KV-cached)
def _rollout_sample(self, prompt: str, seed: int) -> np.ndarray:
req = make_request(TaskType.T2V, self.student.card.model_id, prompt,
diffusion=DiffusionParams(seed=seed))
res = self._rollout(req) # drives chunk_rollout + slab-KV
latents = res.outputs["latents"]
return np.asarray(latents, dtype="float32")
def build_self_forcing(causal_card, **kw) -> SelfForcingMethod:
"""Build a self-forcing method over a Wan-causal card (chunk_rollout loop)."""
return SelfForcingMethod(new_instance(causal_card), new_instance(causal_card),
new_instance(causal_card), **kw)