Omnidreams edit-SFT style skins: offline pair generation, VLM filter, mid-stream LoRA trainer - #458
Omnidreams edit-SFT style skins: offline pair generation, VLM filter, mid-stream LoRA trainer#458wenqingw-nv wants to merge 8 commits into
Conversation
…LoRA trainer Offline JoyAI-Video-Edit restyles of the model's own rollouts become (source, style prompt, styled) training pairs. A style-mode VLM filter scores edit strength/persistence plus a style-agnostic road-layout criterion; heavy styles whose layout drifts late train early-window-only instead of being dropped. A one-shot precompute encodes prompts, first frames, HDMaps, and styled targets into the pipeline latent space. The trainer does edit-timestamped teacher-forced flow matching (source-latent context replay, plain text-KV swap at chunk k, styled targets across the window) into a multi-style LoRA, checkpoint-compatible with the live-edit deploy hook (NVIDIA#431). Training helpers are vendored pending NVIDIA#398. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile SummaryThe PR adds an offline style-edit dataset pipeline, filtering and training utilities, and graph-safe LoRA/drift-corrector deployment support.
Confidence Score: 4/5The PR is not yet safe to merge because pre-swap supervision still runs with the LoRA active instead of matching the inactive deployment path. With Files Needing Attention: integrations/omnidreams/edit_sft/train_style_sft.py Important Files Changed
Sequence DiagramsequenceDiagram
participant Data as Offline pair pipeline
participant Trainer as Style SFT trainer
participant LoRA as Text-edit LoRA
participant Corrector as Drift corrector
participant Model as Realtime model
Data->>Trainer: Filtered source and styled latents
Trainer->>LoRA: Deploy-format checkpoint
LoRA->>Model: Activate at prompt swap
Corrector->>Model: Apply gated drift correction
Model-->>Model: Continue styled autoregressive rollout
Reviews (6): Last reviewed commit: "Add style-drift corrector data-gen, trai..." | Re-trigger Greptile |
initialize_cache_from_embeddings ran before the scale reset, so from the second optimizer step the original prompt's cross-attn KV carried LoRA deltas that the closed-window deploy path never has (reviewer-caught). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The step-1600 LoRA nails the style inside its trained 4-chunk span (bit-exact pre-swap, strong clean restyle at +1..+4 chunks) but blurs out at +7-10: trained only on unstyled history, it learns a constant style push that compounds through the KV commits. Maintenance episodes (MAINT_PROB=0.3) replay styled history at scale 1 with styled targets, teaching the window's fixed point. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… v5 recipe The pre-swap text cache was built with the LoRA already at scale 1, so 'base' rollout history was subtly styled (review finding): initialize the cache at scale 0 and only enable the adapter at the swap. Add v4 self-consistency maintenance episodes (V4_MAINT/V4_EARLY; evaluated as a wash vs v3 - kept behind the knob, default documented) and gen_teacher_styled_targets.py: re-roll JoyAI-restyled clips through the 35-step bidirectional teacher (SDEdit at moderate sigma) to produce sharp styled targets for the v5 corpus; precompute reads either corpus directory. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TextEditLoRA caches base and base-plus-delta weight sets at load and toggles edit windows by in-place copy_ into the live projection weights, so storage addresses survive and captured CUDA graphs stay valid. release_targets() hands selected projections over to another writer (the fused drift-corrector dispatch) and returns their fp32 deltas for composition. Ported from omnidreams-live-edit; the transformer-level edit-window tests stay on that branch since this base lacks the replace_text_embeddings machinery, so the tests here cover the merge/toggle/restore and release invariants with an inlined tiny-transformer helper. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Brings the canonical drift-corrector deploy hook from omnidreams-live-edit. DRIFT_CORRECTOR_MODE=fused keeps the per-alpha pre-merged weight sets and the CPU-side call-index gate but swaps via batched in-place copy_ into the original parameter storages, so the exact alpha*(t) profile survives under compile_network + use_cuda_graph (the unfused path forced both off). DriftCorrectorDispatch registers multiple corrector states (checkpoint + gate profile + gain), each pre-merged from a pristine base-weight snapshot and optionally composed with a style-LoRA delta via TextEditLoRA.release_targets(), with a VRAM budget guard and chunk-boundary state switching. Includes CPU equivalence/pointer-stability tests and a GPU validation script (parity, graph-capture check, chunk-latency bench, eyes-on frames). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On an fp32 network base.to(torch.float32) returns base itself, so the in-place addmm_ merge corrupted the cached base weight set and deactivating the edit could not restore the original weights. Deploys are bf16 (where .to copies), so serving was unaffected; merge with an explicit copy and add an fp32 regression test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The training side of the deployed style-drift corrector, ported from omnidreams-live-edit: - gen_style_drift_pairs.py rolls the counterfactual branch corpus: per clip and style, one branch per swap offset under the same seed, so every late-window (drifted, +8..+24) chunk has a clean early-window (+1..+4) counterpart at the same absolute index. - train_style_corrector.py trains the rank-16 corrector on those pairs with the Clean Forcing recipe (DAG ratio + drift-contraction term, no-op episodes pinning identity off the drifted manifold); checkpoints load through omnidreams/_drift_corrector.py unchanged. - gate_style.py measures the styled alpha*(t) profile (systematic-bias fraction of the drift gap per timestep) and writes the gate JSON the deploy hook's GATE_ALPHA_JSON override consumes. Port adaptations vs the working branch: _host/_lora/_train_attn resolve from the edit_sft vendored copies (no drift_correction sys.path); LORA_TARGETS comes from omnidreams._edit_lora (byte-identical to the guidance_distill list); _sample_files is inlined on top of the runner's HF sync; video io goes through flashdreams.infra.runner_io like the sibling edit_sft scripts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Handoff note: my NVIDIA access ends 2026-08-28. Maintainer edits are enabled on this PR; all trained checkpoints are published (fork releases on wenqingw-nv/flashdreams-wq) and the full code+weights+demo-videos snapshot is mirrored internally at gitlab-master.nvidia.com/worldsim/flashdreams (branches 🤖 Generated with Claude Code |
Live prompt edits (#431) cover in-distribution weather and lighting; full game-style restyles (cel-shaded cartoon, arcade, comic ink) are outside the AV training distribution and no guidance scale reaches them. This PR adds the supervised path: an offline instruction-driven editor authors (original → restyled) pairs from omnidreams rollouts, a VLM filter gates them for structural fidelity, and an edit-timestamped LoRA trainer teaches the realtime model to apply the style itself mid-stream — one multi-style LoRA, selected by the prompt, deployed at zero added latency through the live-edit LoRA hook from #431. Everything lives under
integrations/omnidreams/edit_sft/; nothing touches the serving path.Contents
generate_sources.py— RNG-matched source rollouts (videos + latents) from the sample-data scenes.filter_pairs.py— Cosmos-Reason1 VLM judge.MODE=stylescores edit strength/persistence plus a style-agnostic road-layout criterion at an early and a late frame (describe-then-score phrasing: a bare cross-style JSON score collapses to a uniform 0). Heavy styles are demoted to early-window-only by policy — the judge over-credits late-frame layout on strong stylization (verified false pass), and offline editors drift layout over long clips (streaming error accumulation: the road is progressively replaced).style_prompts.py,precompute_style.py— style prompt bank; one-shot text embeddings + streaming latent encode of sources and styled targets on the AR schedule.train_style_sft.py— teacher-forced trainer: history replayed from source latents through the KV-commit path, flow targets switch to the styled latents at a random swap chunk while the text KV switches to the style prompt; pre-swap chunks and 10% no-op windows are supervised to stay unchanged. LoRA r64 on the attention projections; checkpoints load throughTextEditLoRA(Omnidreams: live mid-stream editing — prompt hot-swap, edit guidance, actor spawn/despawn #431) unchanged._host.py,_lora.py,_train_attn.py— training helpers vendored from the Clean Forcing infra (omnidreams: Clean Forcing drift corrector (training recipe + gated deploy) #398); consolidate when that lands.Data + filter (measured, GB300)
Results (trained + evaluated)
TextEditLoRA.Follow-ups: style-specific gate calibration (current alpha profile is photoreal-measured); background-weighted corrector retrain; a second corrector slot so the photoreal drift corrector can co-deploy.
Not included (follow-ups)
Trained checkpoint (attached on eval pass); spawn/object-materialization SFT (separate track); object add/remove pairs (fail the persistence gate in the offline editor).
Video (original | restyled training data)
Staged sample pairs (data-factory outputs, not yet the LoRA): arcade-racer and cartoon-cel side-by-sides.
sbs_style_arcade_racer.mp4
Update (
bbe4d12d)V4_MAINT/V4_EARLY): maintenance targets drawn from the run's own pre-drift styled window. Evaluated head-to-head vs v3: a wash — kept behind the knob for the record.gen_teacher_styled_targets.py(v5 recipe): re-rolls JoyAI-restyled clips through the 35-step bidirectional teacher (SDEdit at moderate σ) to produce sharp styled targets;precompute_style.pyreads either corpus. A v5 LoRA trained on these targets is being evaluated — results will be posted here.v5 result: the teacher-regen recipe works. On the 20-chunk held-style eval, v5 shows a flat post-swap divergence profile (54–61) where v3 climbs monotonically (57→69), and frame inspection at +10/+14/+19 chunks shows v5 retaining road, curb and solid vehicles at depths where v3 has fully melted — roughly 2× usable style-hold depth. Remaining weakness is slow texture smoothing deep in the hold; a corrector re-paired against v5 is being evaluated as the combined stack.
Final v5 stack: corrector re-paired against v5 (val dag-R² +0.368) and gain-swept. Final config: v5 LoRA + v5 corrector at gain 0.15 with the measured v5 gate profile + unsharp post — retains a populated styled world (houses, sidewalks, parked cars) at +19 chunks where the v3 stack keeps only the road corridor, with deep-window HF above the v3 stack. Known residual: faint corrector-induced sky banding (gain-proportional; a training-side fix would need sky-region loss masking). Checkpoints: https://github.com/wenqingw-nv/flashdreams-wq/releases/tag/style-skin-v5-stack
Before vs after — final v5 serving stack
Side-by-side comparisons: left = base model (no edit), right = arcade skin via the final stack (v5 LoRA + re-paired corrector at gain 0.15, measured gate profile, unsharp post). Prompt-swap at chunk 8, 28-chunk rollouts, same seed both arms.
Highway scene (cleanest hold; lane markings and vehicles stay sharp end-to-end):
sbs_before_vs_v5cas_highway.mp4
Residential scene (style held to the end; houses/vehicles stay populated deep into the hold):
sbs_before_vs_v5cas.mp4
v6 — four skins, one adapter: retrained on teacher-regenerated corpora for arcade_racer + comic_ink + cyberpunk_neon + pixel_art (layout-preserving re-audition rescued the two styles the original filter rejected; the VLM judge's day→night miscalibration is documented in the filter report with eyes-on + edge-structure evidence). Cyberpunk is the headline skin (full 28-chunk neon-night hold); pixel_art holds full-range but is honest-partial on style identity. No arcade regression vs v5. Checkpoint: https://github.com/wenqingw-nv/flashdreams-wq/releases/tag/style-skin-v6-multiskin — running live with mid-run key-switching inside the Crazy Robotaxi game in #494.
robotaxi_liveedit_demo3_cyberpunk.mp4
robotaxi_liveedit_demo3_annotated.mp4
Serving/deploy hook (new commits): this PR now also carries the canonical drift-corrector deploy hook.
DRIFT_CORRECTOR_MODE=fusedkeeps the per-alpha pre-merged weight sets and CPU-side call-index gate but swaps weights by batched in-placecopy_into the original parameter storages, so the exact α*(t) profile survives undercompile_network+use_cuda_graph— the unfused path had to disable both.DriftCorrectorDispatchadds per-state corrector switching (checkpoint + gate profile + gain per state), composing style-LoRA deltas via the newTextEditLoRA.release_targets()seam so one graph-safe writer carries both. Benchmarked at 38.7 fps vs 20.7 unfused; running live in the Robotaxi integration (#494). CPU equivalence/pointer-stability tests plus a GPU validation script (parity, graph capture, latency bench) included.Corrector training stack + fp32 fix (new commits): the data-gen (
gen_style_drift_pairs.py), trainer (train_style_corrector.py), and gate calibration (gate_style.py) now live underedit_sft/— the full Clean-Forcing loop that produced the deployed corrector checkpoints. Also fixes a real fp32 aliasing bug caught during porting:base.to(torch.float32)is a no-copy alias on fp32 networks, so the in-place pre-merge corrupted the cached base set (bf16 deploys unaffected); nowcopy=Truewith a regression test.