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).
39 lines
1.8 KiB
Python
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)
|