Omnidreams: live mid-stream editing — prompt hot-swap, edit guidance, actor spawn/despawn - #431
Omnidreams: live mid-stream editing — prompt hot-swap, edit guidance, actor spawn/despawn#431wenqingw-nv wants to merge 10 commits into
Conversation
…che) Rebuild the per-block cross-attention text KV in place at a chunk boundary (storage addresses survive, so captured CUDA graphs stay valid) while the self-attention history carries the scene forward under the new prompt. Optional two-prompt edit guidance runs the cond branch under old and new text against the same history and extrapolates flow_old + s*(flow_new - flow_old) for N chunks after a swap; the KV commit always runs single-branch under the new prompt. ReCache (LongLive / Hunyuan-GameCraft-2) re-commits the previous chunk's KV under the new text via a same-index cache-bracket re-open. GPU-verified: swaps are RNG-clean (zero pre-swap divergence), and weather/lighting edits land convincingly at s=3 with training-caption-style phrasing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Route datachannel event messages to a free-text prompt swap (event_id carries the prompt; clear states restore the scene prompt) and to /spawn <preset> [dist] [speed] [lateral] / /clear-actors commands. Spawned actors follow a constant-velocity world trajectory and enter the conditioning through the same Ludus bbox path as gRPC dynamic actors, so the model materializes grounded vehicles/pedestrians the game shell can track. The web client gains a scene-prompt panel and spawn buttons; WASD typed into text fields no longer drives the car. GPU-verified: a spawned car materializes photorealistically within one chunk and vanishes within one chunk of /clear-actors. Guidance defaults (s=3, 6 chunks) follow the calibration sweep. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
smoke_text_edit rolls RNG-matched control/swap/guided/recache variants and reports per-chunk divergence; sweep_text_edit calibrates an edit prompt bank (incl. the scene bundle's native weather phrasings) against one control; smoke_spawn_actor drives the WebRTC runtime headless and exercises /spawn and /clear-actors. guidance_distill/PLAN.md specifies the Tier-2a LoRA recipe that bakes two-prompt edit guidance into the student (post-swap-gated, premerge-deployed). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile SummaryThe PR adds live prompt replacement, transient edit guidance or distilled-LoRA edit windows, and WebRTC actor controls. It also introduces same-index ReCache for recommitting the previous chunk, but that path still reconstructs history with newly sampled context noise.
Confidence Score: 4/5The PR is not yet safe to merge because ReCache still replaces finalized history with KV derived from a different context-noise realization. ReCache only retains the clean final latent, installs a newly seeded generator, and reruns finalization, so the rewritten KV does not represent the same noisy context used when the prior chunk was rendered. Files Needing Attention: integrations/omnidreams/omnidreams/pipeline.py Important Files Changed
Sequence DiagramsequenceDiagram
participant Event as WebRTC edit event
participant Pipeline
participant Transformer
participant Cache as KV cache
Event->>Pipeline: replace_text(new prompt)
Pipeline->>Transformer: replace_text_embeddings
Transformer->>Cache: overwrite text cross-attention KV
Pipeline->>Cache: start(previous AR index)
Pipeline->>Pipeline: finalize(clean latent, newly seeded noise)
Pipeline->>Cache: overwrite previous chunk KV
Note over Cache: Rewritten history differs from rendered chunk
Reviews (7): Last reviewed commit: "Add /spawnt template spawner: clone real..." | Re-trigger Greptile |
The ego pose is the rig origin (~1.5 m above the road), so spawned boxes floated at eye level — off-distribution for the bbox conditioning, and the model under-rendered them (a moving truck box was ignored entirely). Offset the bbox center by the rig height; verified against the scene's own actor boxes in the rendered conditioning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
/spawn <preset> [dist] [speed] [lateral] [yaw_deg] — box heading relative to the ego (0 = same direction, 180 = oncoming). The rendered box's front/back face colors encode travel direction. Probing found the model paints static boxes in place (parked-vehicle prior) but renders constant-gap moving boxes as a plausible oncoming pass regardless of yaw; the argument stays for scene priors where lead vehicles exist. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Distill the two-prompt text-edit guidance into a LoRA so a plain prompt swap responds at guided strength: on-policy rollouts with a mid-stream swap, teacher = the frozen base running the guidance combine on the same states, student = the LoRA'd single branch under the new prompt (per-term immediate backward under functional attention — the teacher's in-place KV loads would otherwise invalidate the student's checkpoint recompute). Prompt bank reuses the calibration-sweep phrasings plus no-op swaps as a drift regularizer; embeddings precomputed so the 14 GB text encoder is not resident during training. r64 / 1600 steps passes the eval gate on held-out clips: the LoRA'd plain swap reaches 0.854 of guided divergence (bar 0.8; base 0.376), visually clean, generalizing across scene types. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
omnidreams/_edit_lora.py caches base and base-plus-delta weight sets at load and toggles them by in-place copy_ at edit-window boundaries, so weight storage addresses survive and captured CUDA graphs stay valid (the drift corrector's pointer-rebinding swap is not graph-safe). With the hook attached (text_edit_lora_path on the wrapper / WebRTC runtime config, EDIT_LORA on the probe script), replace_text_embeddings builds a use_lora window: single forward per denoise step at guided strength, KV commits included, base weights restored on expiry and on new rollouts. GPU-validated on the rain benchmark: plain swaps stay bit-identical to the hookless run, and the LoRA window's divergence curve tracks the two-branch guided reference (same endpoint) with zero extra forwards — replacing the +84 ms/chunk guidance cost. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review follow-up (PR NVIDIA#431): the ReCache context forward drew its noise from the model RNG, so enabling ReCache shifted every subsequent noise draw relative to a plain-swap rollout. Any noise rendition of the same clean latent is in-distribution for the context forward (each chunk's original commit already uses an independent draw), but drawing from a per-AR-index seeded generator makes the re-commit deterministic and leaves the rollout's noise stream untouched with or without ReCache. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Re the ReCache noise concern: addressed in 5541985, with context on why the behavior was in-distribution either way. The context forward is trained on randomly re-noised latents, and every chunk's original KV commit already uses an independent noise draw — so a ReCache re-commit under a fresh draw produces a valid representation of the same clean latent (our GPU probes showed improved post-swap compliance and no artifacts). The commit that mattered: ReCache previously consumed the model RNG, shifting every subsequent noise draw relative to a no-ReCache rollout. It now draws from a dedicated per-AR-index seeded generator, making the re-commit deterministic and leaving the rollout's noise stream identical with or without ReCache (unit-tested). |
|
/ok to test 5541985 |
Main moved the runner video helpers to flashdreams.infra.runner_io (load_video_tensor / load_first_frame_tensor / write_video_tensor) — port the three GPU probe scripts to the new API. The guidance_distill trainer/eval/precompute scripts import the Clean Forcing training infra (drift_correction/), which is not on main yet — keep PLAN.md here and land the scripts with that stack (NVIDIA#398); the deploy hook (_edit_lora.py) is self-contained and stays. Also satisfy ty: cast the torch.compile unwrap, require the test checkpoint path, annotate the two intentional test monkeypatches; ruff-format the touched files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Synthetic preset boxes render into the conditioning but never materialize (student and 35-step teacher, mask-verified). Bit-for-bit clones of real perception tracks do. /spawnt <fwd|auto> [lateral] [template_idx] extracts parked car-sized tracks from the scene's cube pools and rigidly moves one to the target; auto placement targets the largest actor-free forward gap. Mask-verified across three configs (right/left curb, two-clone): in-box divergence 18-22 vs 6-8 texture noise, coherent vehicles on eyes-on crops. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| diffusion_model._rng = torch.Generator(device=self.device).manual_seed( | ||
| self._RECACHE_NOISE_SEED + final_state.autoregressive_index |
There was a problem hiding this comment.
ReCache resamples finalized history
When a prompt swap runs after a chunk finalized with nonzero context noise, ReCache installs a newly seeded generator and finalizes the retained clean latent again. This overwrites the rendered chunk's KV with a representation derived from different context noise, causing continuity loss or transition artifacts in the next chunk.
Knowledge Base Used: Core Engine (flashdreams/flashdreams/core/)
Squash the ten commits from NVIDIA/flashdreams PR NVIDIA#431, including prompt hot-swap, edit guidance, ReCache, distilled edit-LoRA deployment, actor spawn/despawn commands, template spawning, probes, and CPU coverage. Source-PR: NVIDIA#431 Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Aidan Foster <aidanf@nvidia.com>
Omnidreams fixes the prompt at rollout start — the serving path encodes it once and discards later prompts — so the world can't be edited while driving. This PR adds live mid-stream editing: swap the prompt at any chunk boundary with full scene continuity, optionally amplify the edit with two-prompt guidance, and spawn/despawn grounded actors from user commands. Everything is opt-in at the event layer; a session that never edits runs the untouched hot path.
Contents
core/attention/kvcache.py—clone_kv()/overwrite_kv_(): full-buffer KV overwrite throughcopy_, so storage addresses survive and captured CUDA graphs stay valid across a swap.omnidreams/transformer+pipeline.py—replace_text_embeddings/replace_text: rebuild the per-block text cross-attn KV in place at a chunk boundary; the self-attn history is untouched, so the scene carries forward under the new prompt.TextEditGuidance: for N post-swap chunks, each denoise step runs the cond branch under old and new text against the same history and extrapolatesflow_old + s(flow_new − flow_old)(one captured graph, outputs cloned per replay; the KV commit always runs single-branch under the new prompt).recache_last_chunk: LongLive/GameCraft-2-style ReCache — a same-index cache-bracket re-open re-commits the previous chunk's KV under the new text.omnidreams/webrtc— datachanneleventmessages carry free-text prompts (a clear state restores the scene prompt);/spawn <preset> [dist_m] [speed_mps] [lateral_m]and/clear-actorsplace constant-velocity world-frame actor boxes into the HDMap conditioning through the same converter as the gRPC dynamic-actor path;/spawnt <fwd_m|auto> [lateral_m] [template_idx]clones a real parked-track template to a user target — the first spawn path that materializes anything, though so far only at ghost strength (see below). Client gains a Scene Prompt panel + spawn buttons; typing in text fields no longer drives WASD.tests/— 23ci_cputests: swap reproduces a fresh cache init at stable addresses; guidance combine / countdown / finalize suppression; same-index rewrite semantics; spawn geometry and pool timing; template extraction filters, gap search, and clone rigidity.scripts/— three GPU probes (RNG-matched per-chunk divergence vs control):smoke_text_edit.py,sweep_text_edit.py,smoke_spawn_actor.py(drives the WebRTC runtime headless).guidance_distill/PLAN.md— follow-up recipe to distill the guidance into a post-swap-gated LoRA (guided strength at plain-swap cost).Measured (704×1280, 2-step distilled student, swap at chunk 8, RNG-matched vs control, GB300)
Swaps are bit-clean: 0.000 pre-swap pixel divergence. Post-swap, per-chunk mean |Δ| in uint8 units:
Actor spawn — corrected after a reviewer-caught misattribution, now with a partially materializing path. The
/spawnpreset plumbing verifiably places grounded, correctly-classed boxes into the HDMap conditioning, but synthetic preset boxes do not materialize objects — on the distilled student or on the 35-step bidirectional teacher (mask-level checks against an RNG-matched baseline show empty road at the box locations; earlier "spawned car" observations were the scene's own recorded traffic re-rendered after divergence). The model keys on perception-track statistics that hand-built presets lack, so/spawntclones a real parked-vehicle track out of the scene's own cube pools — per-frame jitter, true dimensions, orientation, colors — and rigidly moves it to the user target;autopicks the largest actor-free gap on the requested lateral line, so a materialized clone provably isn't recorded traffic. Honest quality bar (mask-verified across three configs — right curb auto, left curb auto, two stacked clones): 2 of 3 placements materialize a semi-transparent, blurry vehicle where the RNG-matched control shows empty road — box-interior darkening ~9–10 uint8 vs ~52 for a scene-native parked car, i.e. roughly 20% of full render strength — and the left-curb placement failed to materialize at all (near-zero darkening; in-box divergence 13–16 is texture shift, not an object). Cloning is the existence proof that user boxes can materialize training-free; solid rendering is the open problem. Leading explanation: the context frames and all KV history predate the box, so the 2-step student splits the difference between conditioning and history (scene-native parked cars are in the first-frame pixels; recorded moving traffic materializes solidly from boxes alone, suggesting a fixed-spot history conflict rather than a conditioning limitation). Preset/spawnremains as game world-state (collision logic, gRPC parity); solid materialization is the follow-up (history re-commit on spawn, mild box-axis guidance over the clone signal, moving-track clones, instruction-SFT). Spawned boxes are grounded on the road plane (the ego pose is the rig origin, ~1.5 m up).Overhead
text_edit_guidance=Noneshort-circuits to the existing single-branch forward.Guidance distillation (Tier-2a, later commits)
guidance_distill/PLAN.mddocuments the recipe (the trainer scripts build on the Clean Forcing training infra and land with #398); the deploy hook here is self-contained. The recipe trains a LoRA to reproduce the guided flow from a plain swap — teacher is the frozen base running the guidance combine on the same on-policy states, so no external data or models. The r64 / 1600-step checkpoint passes the eval gate: the LoRA'd plain swap reaches 0.854 of guided divergence on held-out clips (bar 0.8; untrained base 0.376), visually clean. Deployed viaomnidreams/_edit_lora.py: both weight sets pre-merged at load, edit windows toggle by in-placecopy_(CUDA-graph-safe, ~0.2 ms at window boundaries only) — guided-strength edits at plain-swap cost, replacing the +84 ms/chunk two-branch combine. Opt-in viatext_edit_lora_path; without it, plain swaps are bit-identical to the hookless run (GPU-verified). Checkpoint (211 MB, md51fc7b33ea037f745eeb8d5a1bee59371): https://github.com/wenqingw-nv/flashdreams-wq/releases/tag/live-edit-guidance-lora-v1 (fork release, per the drift-corrector precedent; happy to move to HF on maintainer preference).Not included (follow-ups)
gRPC field for mid-stream prompts; the native optimized-DiT (FP8) path raises
NotImplementedErroron swap (default configs unaffected); instruction-SFT for grounded props, object-by-prompt edits, and trajectory-locked moving actors.Video comparison (original | edited)
All clips are RNG-matched: identical seed, controls, and conditioning until the edit; labels burned in. Left: base rollout. Right: same rollout with the live edit.
Prompt swap → heavy rain (guided s=3, swap at 2 s): wet glossy road, streetlight/taillight reflections, windshield droplets — same street, same trajectory.
sbs_rain_edit.mp4
Prompt swap → snowstorm (training-style phrasing, s=3): progressive snow cover on road, trees, and parked cars, artifact-free.
sbs_snow_edit.mp4
/spawn car 16mid-drive (superseded — kept for the correction record): the car visible here is the scene's own traffic re-rendered after divergence, not the commanded box; see the corrected Actor-spawn paragraph above.sbs_spawn_car.mp4
Spawn +
/clear-actors(superseded — kept for the correction record): same confound as above; the appearing/vanishing car tracks the scene's recorded traffic under divergence rather than the commanded box.sbs_spawn_remove.mp4
Props via prompt assist: an oversized "Other"-class cone box alone under-renders, but combined with a construction-zone prompt swap the model paints real orange traffic cones along the road — visual dressing rather than grounded objects, which is the documented props limit.
sbs_cone_prompt_assist.mp4
/spawnttemplate clone (verified, ghost-strength): a real parked-track clone placed in an auto-selected empty gap materializes as a semi-transparent vehicle on the right curb (~20% of a scene-native car's contrast); the RNG-matched control (left) shows empty curb at the same location. Three reliability clips staged inintegrations/omnidreams/scripts/outputs/pr_videos/sbs_spawnt_rel{1,2,3}.mp4— rel1/rel3 show the ghost vehicle, rel2 (left curb) failed to materialize and is kept for the record.