Skip to content

feat(diffusion): add OmniDreams autoregressive video world model - #27442

Open
Cerdore wants to merge 43 commits into
sgl-project:mainfrom
Cerdore:fea_omni
Open

Cerdore wants to merge 43 commits into
sgl-project:mainfrom
Cerdore:fea_omni

Conversation

@Cerdore

@Cerdore Cerdore commented Jun 6, 2026

Copy link
Copy Markdown

Motivation

Add OmniDreams, a 2B distilled autoregressive driving-video world model (Cosmos-Predict2.5-based), to multimodal_gen. Given a first frame + a per-frame HD-map control signal, it rolls out a temporally-coherent driving
video via 2-step Self-Forcing flow-match denoising over a rolling block KV cache. Served both one-shot (HTTP /v1/videos) and realtime (WebSocket /v1/realtime_video/generate).

Related issue: #27214.

What changed

  • Added the OmniDreams pipeline: flat-checkpoint DiT loading, AR rollout with BlockKVCache (sink + rolling window), per-chunk HD-map conditioning, and seam-free Wan VAE decode. 38 files.
  • Added realtime generation through the shared RealtimeModelAdapter base, with per-chunk HD-map control events and incremental frame output.
  • Kept the default runtime in pure PyTorch / BF16 (no custom CUDA extensions).
  • Added optional acceleration paths that degrade gracefully:
    • FP8 GEMM: sgl_kernel.fp8_scaled_mm for the MLP linears (56/284); falls back to torch._scaled_mm when sgl_kernel is unavailable.
    • SageAttention-3: sageattn3_blackwell direct call for self-attention (FP4/FP8); falls back to PyTorch SDPA when sageattn3 is not built.
    • Breakable CUDA graph: make_breakable_attention_forward installed on OmniDreamsAttention.forward (break at attention, capture the rest). --enable-breakable-cuda-graph also enables Full CG for the fixed-shape
      VAE decode stage.
    • torch.compile: the DiT is compile-ready (_compile_conditions); the base DenoisingStage handles compilation via --enable-torch-compile.
  • Refactored for conciseness: unified offline/realtime AR chunk body via _run_ar_chunk + _ARChunkCtx (−458 LOC); removed dead cross-view attention, shift_t_freqs, SP post-process no-op, and Phase annotations.

Compatibility

  • Default path: BF16 + PyTorch SDPA (no sgl_kernel / sageattn3 / BCG required).
  • FP8 GEMM activates only when sgl_kernel is importable on a CUDA device; otherwise falls back to torch._scaled_mm.
  • SageAttention-3 activates only when sageattn3 is importable; otherwise SDPA. Not a runtime dependency for the default path.
  • BCG is opt-in via --enable-breakable-cuda-graph; transparent pass-through when disabled.
  • WanVAE clear_encode_cache (scoped encoder-only reset) is backward-compatible: standalone encoders are unaffected (no live decoder cache).

Validation

  • Unit tests: 19 passed (construction, RoPE, BlockKVCache, scheduler, DiT
    forward, AR rollout, config, state-dict key fixture, num_chunks math).
    4 GPU tests fail on tiny arch (head_dim=12 triggers Triton RoPE power-of-2
    constraint — not a production issue; real model uses head_dim=128).

  • E2E on RTX 6000D (sm_120a, 85GB):

    Config 13f Total 100f Total Peak VRAM
    Eager bf16 + sage3 8.34s 36.64s 46.2 GB
    fp8 + BCG 8.18s 35.79s 46.9 GB
  • FP8 vs BF16 numerical consistency: bit-identical output (13f, same seed, per-frame max_diff=0.0000). FP8 swaps 56 MLP linears; attention stays bf16.

  • Full CG decode saves 0.4s at 100f (14.30→13.90s, −2.8%).


CI States

Latest PR Test (Base): ❌ Run #32367565063
Latest PR Test (Extra): ❌ Run #32367564924
Latest PR Test (AMD ROCm 7.2): ❌ Run #32367565068

@github-actions github-actions Bot added the diffusion SGLang Diffusion label Jun 6, 2026
@Cerdore
Cerdore marked this pull request as draft June 6, 2026 11:24

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the NVIDIA OmniDreams pipeline, an autoregressive video world model, along with its corresponding DiT model, 3D rotary position embeddings, block KV cache, text-embedding transform, flow-match scheduler, and custom pipeline stages. Feedback on the implementation identifies several critical issues: the cross-view attention incorrectly performs global attention instead of temporal-restricted attention; the text encoder is called without an attention mask, potentially corrupting embeddings; accessing VAE latent mean and standard deviation directly on the VAE instance will raise an AttributeError; the KV cache retrieval methods will crash when called outside of active update transactions; and decoding non-overlapping latent chunks independently will introduce temporal seam artifacts at chunk boundaries.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread python/sglang/multimodal_gen/runtime/models/dits/omnidreams.py Outdated
Comment thread python/sglang/multimodal_gen/runtime/models/dits/omnidreams_kvcache.py Outdated
@Cerdore
Cerdore force-pushed the main branch 2 times, most recently from c2c2842 to 5a30531 Compare June 8, 2026 16:29
Add OmniDreams pipeline to multimodal_gen, supporting:

- Flat checkpoint loading (570-key .pt, non-diffusers layout) with
  post-load parameter fusion matching FlashDreams conventions
- Autoregressive rollout with BlockKVCache (sink + rolling window)
  and per-chunk KV-cache lifecycle
- 3D NeoX RoPE (44:42:42) with shift_t for chunk positioning
- 2-step flow-match scheduler (sigmas {1.0, 0.8036, 0.0})
- Text conditioning via full_concat 100352 embedding
  (Cosmos-Reason1-7B) with explicit attention mask
- Per-chunk VAE latent concatenation with single-pass Wan 2.1 decode
  for temporal continuity
- HDMap/trajectory conditioning pipeline (per-chunk VAE-encode)
- Tensor parallelism via ColumnParallelLinear/RowParallelLinear
- Precomputed cross-attention K/V caching
- HTTP API fields for hdmap_path and num_views
- 43/43 CPU unit tests covering component construction, RoPE,
  BlockKVCache, scheduler, DiT forward, denoising stage, registry,
  and regression guards
- GPU CI coverage with consistency thresholds and perf baselines

Relates to sgl-project#27214
@Cerdore
Cerdore force-pushed the main branch 2 times, most recently from c2c2842 to 62562cb Compare June 8, 2026 17:06
@Cerdore
Cerdore marked this pull request as ready for review June 8, 2026 17:27
@Cerdore
Cerdore requested review from HaiShaw and yichiche as code owners June 8, 2026 17:27
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@Cerdore

Cerdore commented Jun 12, 2026

Copy link
Copy Markdown
Author

@mickqian Have a look plz? :)

@mickqian

Copy link
Copy Markdown
Collaborator

fantastic. if it's ready, could you attach some examples?

Cerdore and others added 3 commits June 13, 2026 14:05
… HD-map conditioning

Consolidate pre-processing (text encode, i2v VAE, HD-map per-chunk encoding) into
OmniDreamsBeforeDenoisingStage. Implement full autoregressive rollout in
OmniDreamsDenoisingStage: per-block BlockKVCache lifecycle, 3D NeoX RoPE shift_t,
2-step self-forcing denoise (sample + context-noise re-forward), frame-0 i2v
pinning, and per-chunk HD-map indexing. Add comprehensive unit tests covering
RoPE correctness, KV-cache fill/roll/steady-state, scheduler 2-step sigmas,
Cosmos-Reason1 100352-dim text embedding, tiny DiT end-to-end forward, AR
unconditioned/i2v/multi-chunk rollout, HD-map per-frame slicing, and reference
image preprocessing.

Constraint: 2-step distilled model trades temporal smoothness for real-time speed;
blur is expected behavior from Self-Forcing + DMD distillation, not a bug.

Confidence: high
Scope-risk: moderate (AR loop is new; GPU validation still needed)
Not-tested: end-to-end generation on full OmniDreams 2B checkpoint; HD-map VAE
numerics on GPU (flagged with TODO)

Co-Authored-By: Claude <noreply@anthropic.com>
…ontext-noise KV cache write

At AR step 0, the context-noise forward (finalize_kv_cache) must store
CLEAN K/V for frame 0, matching FlashDreams _maybe_inject_image() inside
_predict_branch which fires during finalize_kv_cache -> predict_flow.

Without this re-injection, frame-0 KV cache entries are noise-corrupted at
sigma ~0.13, causing a distribution shift that accumulates into progressively
blurry video across AR chunks.
…ch training

The OmniDreams checkpoint is trained with FlashDreams' CosmosReason1TextEncoder,
which runs the Cosmos-Reason1 LM on the full padded sequence with no attention
mask. The DiT cross-attends over all 512 token embeddings (valid + padding), so
the padding-token hidden states are part of the trained conditioning
distribution. Passing an explicit mask changes those padding states drastically
(abs diff up to ~99 after the per-token mean-normalize in full_concat_embeddings),
pushing conditioning out of distribution and producing washed-out / blurry
rollouts -- sharp frame-0 only, since frame-0 is i2v-pinned and bypasses the DiT.

Also align the chat-template message format and add_vision_id=False with
FlashDreams so the encoded token sequence is identical.

Verified on A40: normalized latent std recovers 0.39 -> 0.76 (real GT ~0.72) and
rollouts are sharp and temporally coherent across multiple clips and seeds.

Constraint: must match FlashDreams CosmosReason1TextEncoder (trained with no attention_mask)
Rejected: keep attention_mask | corrupts padding-token conditioning -> blurry output
Confidence: high
Scope-risk: narrow
@Cerdore

Cerdore commented Jun 13, 2026

Copy link
Copy Markdown
Author

fantastic. if it's ready, could you attach some examples?

Thanks! Yes, it's ready — both the offline (sglang generate) and online
(sglang serve + POST /v1/videos, HD-map conditioning via the JSON body)
paths are verified end-to-end. I've attached two side-by-side comparisons
(generated left, ground-truth right):

comparison_gen_vs_gt.mp4 — in-distribution clip.
newclip_comparison.mp4 — a completely held-out scene (shows it generalizes
rather than memorizes; gen-vs-GT PSNR decays monotonically with rollout depth).

comparison_gen_vs_gt.mp4
newclip_comparison.mp4

HD-map conditioning is mandatory — the rollout intentionally goes OOD without it.

@Cerdore

Cerdore commented Jun 13, 2026

Copy link
Copy Markdown
Author

Some optimize work still in progress: DiT CUDA Graph support, LightTAE and LightVAE.

Summary of changes:

T1 - AdaLN Fusion (omnidreams.py DiT):
  Replace nn.LayerNorm + manual scale/shift with LayerNormScaleShift
  fused kernel. On CUDA dispatches to CuTe DSL fused_norm_scale_shift.
  3 norm ops x 28 blocks x 2 calls/chunk = 168 fused kernels instead of
  504 separate launches.

T2 - RoPE Kernel (omnidreams_rope.py + DiT):
  Add RotaryPositionEmbedding3D.to_cos_sin_cache() and dispatch
  apply_rope_freqs() to _apply_rotary_emb (FlashInfer on CUDA,
  Triton fallback). cos/sin precomputed once per forward in
  OmniDreamsDiT.forward(), threaded through Block -> Attention.

T3 - KV-Cache Split-Copy (omnidreams_kvcache.py):
  Eliminate per-block .clone() allocation in _roll_local_window_left()
  with split-copy (two non-overlapping copy_() calls). CPU correctness
  verified: steady-state roll, re-forward overwrite, sink retention.

T4 - Text Encoder Cache (stage omnidreams.py):
  OrderedDict LRU cache (max 32) keyed on prompt string in
  _encode_text(). Cache hit skips 14 GB Cosmos-Reason1-7B forward.
  Embeddings stored on CPU to avoid GPU VRAM consumption.

Documentation:
  - OmniDreamsOptimizationFindings.md: full deep-dive report
  - CLAUDE.md: OmniDreams section with architecture, facts, commands
  - sglang-diffusion-omnidreams skill: source guide for future agents

Verified: py_compile (4/4), code signatures, KV-cache CPU correctness.
Needs GPU machine for unit tests + benchmarks.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jun 14, 2026
Comment thread python/sglang/multimodal_gen/runtime/layers/layernorm.py Outdated
@AgainstEntropy

Copy link
Copy Markdown
Collaborator

please fix the conflicts~

@Cerdore

Cerdore commented Jul 8, 2026

Copy link
Copy Markdown
Author

@mickqian @AgainstEntropy Ready for review. Thanks!

Comment on lines +745 to +754
if x.is_cuda or x.is_xpu:
modulated = fuse_scale_shift_kernel(normalized, scale, shift)
else:
# fuse_scale_shift_kernel is the Triton impl on CUDA builds and
# asserts CUDA tensors; use the pure-PyTorch fallback for CPU.
from sglang.jit_kernel.diffusion.triton.torch_fallback import (
fuse_scale_shift_kernel_native,
)

modulated = fuse_scale_shift_kernel_native(normalized, scale, shift)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can also be removed since fallback logic is handled in python/sglang/jit_kernel/diffusion/triton/scale_shift.py

@AgainstEntropy

Copy link
Copy Markdown
Collaborator

Also @Cerdore could you post some visual examples using fp8 and/or realtime pipeline?

Cerdore and others added 2 commits July 11, 2026 23:55
…ard_native

fuse_scale_shift_kernel is already rebound to the pure-PyTorch
fallback at import time in jit_kernel/diffusion/triton/scale_shift.py
for CPU/MPS/MUSA/NPU, so the per-tensor is_cuda/is_xpu branch in
forward_native is dead code.

Per review feedback on sgl-project#27442.

Co-Authored-By: Claude <noreply@anthropic.com>
- adapter: sample pixel-frame count per chunk (was latent count -> crash);
  cast closed-loop hdmap to VAE dtype; deepen hdmap queue.
- wanvae: scope encode() to clear_encode_cache() so the shared instance
  no longer wipes the decoder _feat_map mid-rollout (was dropping 3
  frames/chunk + chunk-boundary flicker).
- pipeline: route WanVAE decode through CausalVaeDecodingStage (persistent
  causal streaming); drop dead _realtime_stream_decode.
@Cerdore

Cerdore commented Jul 12, 2026

Copy link
Copy Markdown
Author

Here are the visual examples @AgainstEntropy:

  1. fp8 offline (/v1/videos, weight_only_fp8):
offline_125f_clipA.mp4

125 frames, 1280×704, ~59s on a single RTX 6000D (SM12.x). Config: --pipeline-config-path omnidreams_dit_fp8.json.

  1. realtime pipeline (/v1/realtime_video/generate WebSocket):
realtime_125f_clipB_FIXED.mp4

16-chunk AR rollout → 125 frames (5 + 15×8), eager bf16, raw-RGB streaming. Per-chunk forward ~3.0s steady.

Cerdore and others added 2 commits July 13, 2026 22:57
# Conflicts:
#	python/sglang/multimodal_gen/configs/pipeline_configs/__init__.py
#	python/sglang/multimodal_gen/configs/pipeline_configs/base.py
#	python/sglang/multimodal_gen/configs/sample/__init__.py
#	python/sglang/multimodal_gen/registry.py
#	python/sglang/multimodal_gen/runtime/entrypoints/openai/video_api.py
#	python/sglang/multimodal_gen/test/server/gpu_cases.py
Co-Authored-By: Claude <noreply@anthropic.com>
@mickqian

Copy link
Copy Markdown
Collaborator

could you clean the test and only keep an e2e testcase and several unit tests?

Cerdore added 3 commits July 14, 2026 18:19
The diffusion runtime refactor (4a8e1b0) moved vision_utils.py from
runtime/models/ to runtime/utils/vision.py, but the three omnidreams
modules still imported the old path. Worked only via stale __pycache__;
clean environments hit ModuleNotFoundError. Point at runtime.utils.vision.
Per reviewer request to reduce the PR's test surface. Trim
test_omnidreams.py 101->9 unit tests; keep a single omnidreams_2b_i2v
server E2E case (move it off TWO_GPU_CASES, where it was wrongly
registered, into ONE_GPU_CASES); drop the hdmap case, the opt-in FP8/
LightVAE/LightTAE accel cases + their 4 JSON configs, the 4 one-off
spike scripts, and the now-dead hdmap harness (DiffusionSamplingParams
.hdmap_path field + generate_hdmap_i2v).
@Cerdore

Cerdore commented Jul 14, 2026

Copy link
Copy Markdown
Author

could you clean the test and only keep an e2e testcase and several unit tests?

done

# Conflicts:
#	python/sglang/multimodal_gen/runtime/entrypoints/openai/protocol.py
#	python/sglang/multimodal_gen/runtime/entrypoints/openai/video_api.py
#	python/sglang/utils.py
# Conflicts:
#	python/sglang/multimodal_gen/configs/models/dits/__init__.py
#	python/sglang/multimodal_gen/configs/sample/__init__.py
@Cerdore

Cerdore commented Aug 20, 2026

Copy link
Copy Markdown
Author

Updated: 45 → 37 files, added optional sageattn3 / fp8 GEMM / BCG acceleration (all fall back to BF16+SDPA by default). E2E verified on RTX 6000D, FP8 vs BF16 bit-identical. PR description updated.
If convenient, please help review it. Share any feedback on changes — I'll follow up. Thanks! @mickqian @AgainstEntropy

…acceleration + BCG

Concise refactor (−458 LOC):
- Unify offline/realtime AR chunk body via _run_ar_chunk + _ARChunkCtx.
- Delete cross-view attention, shift_t_freqs, _postprocess_sp_latents, dead config fields.
- Delete dead hdmap_decode spike variants, num_views dead field.
- Remove all Phase N annotations, trim verbose comments/docstrings.

sglang-native acceleration:
- fp8 GEMM: sgl_kernel.fp8_scaled_mm (drop-in, prebuilt wheel, fallback to _scaled_mm).
- sage3 attention: sageattn3_blackwell direct call (bypass USPAttention, SDPA fallback).
- BCG: make_breakable_attention_forward public + install on OmniDreamsAttention.
- Full CG decode: _FullCgDecodeWrapper for fixed-shape VAE decode.
- .to(device) fix: flat-checkpoint loader leaves plain nn.Linear on CPU.

Docs removed (cookbook + intro.mdx + docs.json) for follow-up PR.
38 files, py_compile + ruff clean.

E2E verified on rtx6kd (RTX 6000D, sm_120a):
- Eager bf16+sage3: 8.34s (13f) / 36.64s (100f)
- fp8+BCG: 8.18s (13f) / 35.79s (100f)
- FP8 vs BF16 output: bit-identical (13f, same seed)
- Peak VRAM: 46-47GB

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

diffusion SGLang Diffusion documentation Improvements or additions to documentation lora quant LLM Quantization sgl-kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants