# FastVideo Runtime — Aggressive Implementation Plan **Companion to** `design.md` (v19) and `design_summary.md` · **Stance:** this plan trades interface stability for speed. Where it deviates from design.md's conservative migration (§10), the deviation is flagged with **⚡**. design.md remains the architectural authority; this is the execution order. --- ## 1. Rules of engagement **We break, freely and early:** - The public Python API: `generate_video(**kwargs)` and `SamplingParam` are **deleted**, not deprecated. - Config schemas: `FastVideoArgs` (1,272 lines, 81 fields) stops being a public or threaded surface. - `fastvideo/api/compat.py` (651 lines): **deleted in M1** ⚡ (design.md §6.6 shrinks it monotonically to Phase 5 — that policy existed only to honor signatures we are now licensed to break). - CLI flags, YAML schemas, package layout, `fastvideo.api` exports, ComfyUI node params, every example. - In-repo dependents (`apps/dreamverse`, `comfyui/`, `examples/`, `scripts/`) get **fixed in the same PR train** — we own them; no deprecation period, no shims. **We never break, at any speed:** - **Numerics.** Bit-identical loop parity and SSIM gates are not "conservative" — they are the definition of correct. Aggression applies to interfaces, never to outputs. - **Model coverage** for the families that matter (tier list in §6 — the tail is a decision, not a casualty). - The frozen legacy `fastvideo/training/` stack (N2) and the bit-exact porting methodology (N3). - External users get **batched breakage**: all user-visible breaks land in at most two releases (R1 = request/config cut, R2 = engine default), each with a migration guide and a `fastvideo migrate` codemod — never a drip. ## 2. The sequencing argument (answering "fix omni request first, then separate the planes?") **Yes to the first half. The second half should not be a project.** The three planes are not separated by moving code into plane-named directories — today's monolithic stages would just get reshuffled and then rewritten when loops invert. The planes are *born* from two cuts, and a third that is really a config change: 1. **The request-plane cut (M1)** — `OmniRequest` becomes the only currency crossing the boundary. Everything behind it is implementation. This is your "fix the omni input and request first," and it goes first because it is low-risk, it defines the vocabulary every later stage consumes, and it gets the user-facing pain over with while the codebase is still familiar. 2. **Loop inversion (M2)** — this *is* the pipeline/execution plane separation. Once families expose `init/step/finalize` step bodies, something other than the family must own iteration; that owner is the executor, and the execution plane exists by construction. Before inversion there is nothing for an execution plane to schedule — "separating" it would be an empty directory. 3. **The config cut (inside M1)** — the real coupling between planes today is `FastVideoArgs`: one 81-field object threaded through entrypoints, pipelines, stages, and executors, mixing deploy-time, model-time, and request-time concerns. Splitting it into `DeployConfig` / `ModelSpec` / `OmniRequest` (design.md §6.6's four layers) is the single highest-leverage "separation" action, and it's schema work, not architecture work. So the order is: **M1 request+config cut → M2 loop inversion (planes now exist) → M3 engine on top.** Plane separation is the *outcome* of M1+M2, not a milestone. ## 3. Milestones Timeline assumes 3–4 engineers on the runtime critical path. Overlap is deliberate; gates are not ⚡-able. ### M0 — Baselines, harness, enforcement (weeks 0–3, overlaps M1) The license for everything aggressive afterward. Not skippable, not shrinkable. M0 does not block M1 (which changes no numerics) — the only hard rule is **no family's M2 migration starts before its baseline exists**. - Merge the `feat/cosmos3-reasoning` chain (design.md sizes this alone at 2–3 engineer-months — it runs as its own track); seed SSIM references for the ~7 uncovered families. - ParityAligner v0: record/compare named taps on *current* pipelines (it must exist before anything changes). - **The enforcement package, on day one** (design.md §10 — the prior freeze was broken 19× for lack of exactly this): CI path gates (reject new `fastvideo/training/` files now; reject new `DenoisingStage` subclasses once the first M2 family lands), CODEOWNERS on the frozen and migrating paths, a named owner per milestone, and the inflow rule — new model families land on the new abstractions from the first Wan/Flux2 landing onward. - Announce the M1 freeze window for in-flight PRs touching `fastvideo/api/`, `fastvideo_args.py`, entrypoints. *Gate: every tier-A family has a recorded SSIM + activation baseline; CI gates live.* ### M1 — The request-plane cut (weeks 1–4) → **breaking release R1** The typed API is partway there: `VideoGenerator.generate(GenerationRequest)` is already the documented primary entrypoint (`generate_video` carries a deprecation warning), and `fastvideo/entrypoints/openai/` already serves `POST /v1/videos` and `POST /v1/images`. But the legacy path is still what's *used*: Dreamverse calls `generate_video(**kwargs)` (`apps/dreamverse/dreamverse/video_generation.py:508`), as do ComfyUI and most examples. M1 finishes the cut instead of bridging it: - **`OmniRequest` / `OmniOutput` / `OmniEvent`**: evolve `api/schema.py`'s `GenerationRequest` in place — typed modality parts, `TaskType`, per-model `ModelOptions` registered blocks (formalizing the `api/matrixgame2.py` pattern), seeds/priority/streaming flags. `api/results.py`'s `Video*Event` types become `OmniEvent`. - **Config: four layers, one owner each** (§6.6): extract `DeployConfig` (placement, parallelism axes, memory/ offload, compile, plugins) from the runtime third of `FastVideoArgs` + `EngineConfig`/`ParallelismConfig`; `ModelSpec` manifest v0 (manifest-first component resolution; today's name-detectors as fallback); `OmniRequest` absorbs every per-call field. CLI flags, OpenAI protocol models, and presets are **generated** from the schema. - **Delete** ⚡: `compat.py` (651), `sampling_param.py` (411), `generate_video()`, the `fastvideo.api` legacy exports, `FastVideoArgs` as a *public* type. Internally it survives as a boundary-constructed shim for as long as anything still receives it: migrated families drop it per-family in M2, but unmigrated tier-B stages (`LegacyPipelineNode`) and the frozen `training/` stack (whose `TrainingArgs` subclasses it) carry it until M6 — it dies as a type with the tail, not before. - **Fix in-train**: ComfyUI nodes (legacy-API callers), all `examples/` (~75 files, mostly mechanical), `scripts/`, docs. Ship `fastvideo migrate` (codemod: old kwargs/YAML → `OmniRequest`/`DeployConfig`). - Internals unchanged: `ForwardBatch` is built *from* `OmniRequest` at the boundary; the executor and stages are untouched in M1. *Gate: all SSIM suites unchanged; Dreamverse + ComfyUI + examples green on the new surface; R1 notes + codemod published.* ### M2 — Loop inversion (weeks 4–10): the pipeline plane is born - `DenoiseLoop` / `ARDecodeLoop` with `init/step/finalize`; runtime owns iteration; custom-step escape hatch from day one (the Cosmos3-port and self-forcing pattern is legitimate, §6.2.3). - **Family order** (each lands step body + policies, and **deletes its legacy stage code in the same PR** ⚡ — continuous deletion, no end-of-plan cliff): **Wan 2.1/2.2 + Flux2 first, jointly** — design.md's rationale stands: together they exercise CFG variants, expert routing, chunk-KV, and the image path, so the step-body contract freezes only after all four are exercised → Wan-causal (self-forcing student) → LTX-2 → HunyuanVideo → Stable Audio → remaining image families. Unmigrated families keep running via `LegacyPipelineNode`. - Policies: `CFGPolicy` (absorbs the 3 CFG copies), `AttnMetadataProvider`, `FlowShiftPolicy`, `PrecisionPolicy`. - Extension core lands with the loop (it's why the loop is being rebuilt): observer bus, ParityAligner promoted to per-request observer, Profiler/NaNWatch, and **cache-dit as the first interceptor** (retiring `enable_teacache`). - `forward_context.py` off the *migrated* inference path (194 references across ~68 files today: ~8 importer files in frozen `training/`, the rest spread across train/ models, tier-B inference stages, quantization, and tests); the module survives as a shim for frozen `training/` **and unmigrated tier-B stages** until M6 — what M2 guarantees is that no migrated family and no new code touches it. - **`train/` migrates per-family, immediately behind inference**: DMD2 and the landed DiffusionNFT (#1450) adopt the shared step functions as each family's body lands — `rl/common/sampling.py`'s loop is deleted, #1396 grad-norm refs extended to the migrated methods (RL included). *Gate, per family: old-vs-new loop bit-identical (ParityAligner) + SSIM + a recorded loop-overhead / batch-of-1 latency measurement (the baseline M3 gates against); for train/: seeded rollout latents identical, reward metrics - grad-norms neutral. No family is ever dual-maintained.* ### M3 — Execution plane: engine + scheduler (weeks 8–14, overlaps M2) → **breaking release R2** - `AsyncEngine` (queue, admission, cancellation-as-common-path, failure isolation); offline `VideoGenerator` keeps its name, becomes a thin sync wrapper that can bypass the queue. - `StepScheduler` v0: multiplexes denoise steps across requests in a pool; budget currency = **predicted GPU-time** from a calibrated per-(model, phase, shape) cost table (the cost *model* matures later; the currency is right from day one). Carries the `ARDecodeLoop` contract; AR batching itself waits for its workload (N5). - CacheManager v0: per-request chunk-KV slabs behind `KVHandle`; CFG-parallel axis (2-branch in practice). - **Dynamo stock worker** (registration, health/drain, cost metrics), retiring the locked `dynamo/examples/diffusers/worker.py` pattern. - **Dreamverse hard-cut** (per design.md Phase 2; the aggressive delta is doing it in one PR): `gpu_pool.py`, queue, warmup, and stream relay deleted and replaced by engine-client calls; the duty-cycle concurrency study runs on the result. - Colocated weight-sync RPC + component-granular sleep/wake + `RolloutClient` (engine-client RL mode for #1450). *Gate: serving load tests; batch-of-1 latency regression ≤ 2% vs the M2-recorded measurement; Dreamverse single-session parity; RL engine-client seeded final-latent parity vs in-process; deploys under stock Dynamo.* ### M4 — Graphs, parallelism, multi-session (weeks 14–20) - `PipelineSpec` graph IR: per-family pipeline classes shrink to **spec + step body + policies** (`create_pipeline_stages()` retires); LTX-2 and Hunyuan15+SR land as real fan-out graphs. - Role pools + connectors (port `multimodal_gen`'s disagg state machine); declarative stacked-parallelism axes compiled to DeviceMesh; general cross-mesh `WeightSyncPlan`. - ComfyUI workflow→spec compiler MVP (tier-1 ~20-node vocabulary) + weight/adapter fleet cache. *Gate (design.md Phase 3's, in full): ≥2 Dreamverse sessions/GPU on the recorded duty-cycle trace, p95 within SLO — this is also where the loop-inversion **falsifier** is evaluated (see §7); LTX-2 A/V full-fan-out end-to-end; disaggregated-vs-colocated throughput benchmark; CPU-only topology validation suite; ComfyUI tier-1 workflows compile and run with equivalence reports; spec-built pipelines SSIM-identical to M2 loop versions.* ### M5 — Omni/MoT native + RL hardening (weeks 20–30) - Cosmos3 re-port onto specs: packed factored sequences, dual-pathway attention, reasoner paged KV, joint denoise, world-model `ChunkRollout`; `/v1/chat/completions`; AR continuous batching arrives **with** this workload (N5). - Consistency ladder enforced end-to-end: C1 default in CI, C2 bitwise mode for goldens, Behavior Record opt-in; first GRPO-class method lands on the engine-client rollout path (log-prob drift becomes the gated metric). *Gate: Cosmos3 150-test parity suite on the new runtime; reasoner pool efficiency — tokens/s/GPU at target concurrent denoise throughput, with the ≥10×-vs-re-prefill sanity floor; C1 drift ≈ 0 on a Wan RL run with the drift dashboard live.* ### M6 — The tail and the precondition (week 30+) Continuous deletion (M1/M2) shrinks the final phase but does not eliminate it: what remains by M5 is the tier-B tail on `LegacyPipelineNode` and the frozen `training/` stack — which is a *live consumer* of `ComposedPipelineBase` and `forward_context`, so its retirement is the precondition, exactly as design.md Phase 5 states. M6 = execute the §6 tail decision (migrate or deprecate each tier-B family), retire `training/` per the checklist, then delete `ComposedPipelineBase`, the legacy `DenoisingStage`, `forward_context.py`, `FastVideoArgs`/`TrainingArgs`, and `RayDistributedExecutor` together. **4 loop copies → 1.** ## 4. Breakage manifest (user-visible) | Release | What breaks | Replacement | Aid | |---|---|---|---| | **R1** (M1) | `generate_video(prompt, **kwargs)`, `SamplingParam`, `FastVideoArgs` as public type, `fastvideo.api` legacy exports, CLI flag names, YAML config schema, streaming event types (`Video*Event` → `OmniEvent`, `schema_version`'d from day one) | `VideoGenerator.generate(OmniRequest)`, `DeployConfig`, generated CLI/protocol, `OmniEvent` | `fastvideo migrate` codemod, migration guide, R0 pinned | | **R2** (M3) | Default execution path becomes the engine (offline bypass preserved); server lifecycle (queue/admission semantics, job states) | `AsyncEngine` | guide; `OmniEvent` schema unchanged from R1 | | after R2 | nothing user-visible — M4/M5 are additive | — | — | ## 5. Deviations from design.md §10, stated honestly | design.md | this plan | why it's safe now | |---|---|---| | Phase 0 keeps `VideoGenerator`/CLI signatures; `compat.py` shrinks to Phase 5 | M1 breaks signatures, deletes `compat.py` ⚡ | the only argument for the shim was signature stability — explicitly revoked | | Legacy code deleted at Phase 5 | per-family deletion at parity, M2 onward ⚡ | parity gate is per-family anyway; carrying dead code to a final phase only invites the 19×-broken-freeze failure mode | | Phases strictly sequential | M2/M3 overlap ⚡ | the engine consumes step bodies, not finished families; the step-body contract freezes at the Wan+Flux2 landing | | Phases −1 through 4 sized at 36–54 engineer-months | ~21–28 engineer-months (3–4 eng × 30 wks) ⚡ | the delta is real deleted work — no compat maintenance, no adapter upkeep, no dual-stack carry — plus M2/M3 overlap; treat 30 weeks as the aggressive case and 36–40 as the planning case | | Unchanged | parity/SSIM gates (restored in full at every milestone), enforcement package (CI path gates, CODEOWNERS, inflow rule — now at M0), train/RL migration timing (design.md Phase 1 already migrates NFT), Dreamverse hard-cut (Phase 2 already prescribes it), N2/N3/N5, cost-model currency, Dynamo asks + fallbacks, schema versioning | aggression budget is spent on interfaces only | ## 6. Decisions needed before M0 1. **Tier the model zoo.** Tier A (migrated, coverage guaranteed): Wan 2.1/2.2, Wan-causal/self-forcing, LTX-2, Flux2, HunyuanVideo, Stable Audio, Cosmos3 (contingent on the M0 merge — it is not on `main` today), image families. Tier B (runs on `LegacyPipelineNode` until someone claims it, candidate for deprecation at M6): gen3c, matrixgame2/3, longcat, the rest. **Approve or edit the split** — it bounds M2. 2. **Release framing.** R1 as `v0.3.0` (pre-1.0 semantics, loud notes) vs holding breaks for a `v1.0` story. Recommendation: `v0.3.0` now — waiting taxes every milestone. 3. **Freeze windows.** M1 freezes `api/`/args/entrypoints PRs ~2 weeks; M2 freezes per-family stage PRs while that family migrates (days each). Needs maintainer sign-off. 4. **Staffing.** Critical path is M2's per-family step bodies — parallelizable per family after the Wan+Flux2 reference lands. 3–4 engineers ≈ 30 weeks to M5 in the aggressive case (design.md's own sizing implies 36–40 weeks at the same staffing — see §5); 2 engineers ≈ stretch ~1.5×. The Cosmos3-chain merge (M0) is its own 2–3 engineer-month track and should be staffed separately from the runtime critical path. ## 7. Risks specific to the aggressive posture - **In-flight PR collisions** with layout/schema moves → freeze windows (above) + landing schema cuts at milestone *starts*, not ends. - **Community churn at R1** (ComfyUI users, script users) → codemod covers the mechanical 90%; the 10% that isn't mechanical (kwargs with changed semantics) is enumerated in the guide; previous version stays pinned and installable. - **Parity harness becomes the bottleneck** — every aggressive deletion is licensed by it. Mitigation: it is the *first* deliverable (M0), and per-family migration PRs are template-driven (record → port → compare → delete). - **Overlap risk (M2/M3)**: the engine team building against a moving step-body contract → the contract (`init/step/finalize` + `StepResult`) freezes at the *first* family (Wan), enforced by the same schema-version discipline as external surfaces. - **The known unknown**: loop inversion at scheduler granularity has no production precedent (design.md §1). The falsifier stands, on design.md §11.6's schedule: the M3 duty-cycle study *publishes the targets*; the falsifier is **evaluated at the M4 gate** — if step-level multiplexing can't beat request-level serialization on real Dreamverse traces, StepScheduler retreats to request-level dispatch and the loop contract keeps only its streaming/preemption seams, with no family code changing — step bodies and the M1/M2 cuts retain full value.