Compare commits

...
Author SHA1 Message Date
Hongsheng Liu f1abb13958 [Diffusion] Register runtime cache for direct DLO H2D
Avoid recurrent mmap-to-pinned packing in no-AllGather DLO by registering transform-complete runtime-cache mappings under an explicit per-worker budget. Copy mapped tensors directly into the rotating device buffers while preserving bounded-staging fallback and ordered shutdown cleanup.

Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-17 11:50:32 +08:00
Hongsheng Liu b732ad2cea [Diffusion] Document runtime cache hardware tradeoffs
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-17 00:43:06 +08:00
Hongsheng Liu 99347e1ba7 [Diffusion] Tighten runtime cache compatibility guards
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-16 23:26:25 +08:00
Hongsheng Liu db86a6a078 [Diffusion] Add node-local runtime weight cache for DLO
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-16 23:15:48 +08:00
Yukim1andHongsheng Liu baba7d1e2e [Refactor] Remove legacy stage_args YAML loader (#6200)
Signed-off-by: zwhzzz0821 <2831474076@qq.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-16 11:22:28 +08:00
Hongsheng Liu 9d2bb23ff6 [Diffusion] Add loader-owned host-weight plans for DLO (TP=1) (#6213)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-16 11:02:38 +08:00
3875f8ded4 [Core] Add realtime AR-Diffusion tick sessions for LingBot World 2.0 (#5491)
Signed-off-by: zhangbin.327 <zhangbin.327@bytedance.com>
Signed-off-by: Jack47 <scsvip@gmail.com>
Co-authored-by: zhangbin.327 <zhangbin.327@bytedance.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-16 09:11:20 +08:00
Yueqian Lin 9798bc3a8d [Docs] Unify recipe serve commands on vllm serve --omni (#6221)
Signed-off-by: Yueqian Lin <linyueqian@outlook.com>
2026-08-15 21:18:47 +00:00
Anurag 68bf8c2c42 [Bugfix] Prevent DiffusionResultPump crash on cancelled futures (#5793) (#5983)
Signed-off-by: ANURAG KANADE <anuragkanade6@gmail.com>
2026-08-15 16:19:45 +00:00
yiminghub2024andHongsheng Liu 444485650b Add MiniMax-H3 recipe for NPU 950PR (#6120)
Signed-off-by: yiminghub2024 <482890@qq.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-16 00:04:38 +08:00
hurukawa 2a315e1a2d [Perf] Support request-level batching for Wan2.2 pipelines (#5676)
Signed-off-by: nagisa-kun <1434936049@qq.com>
Signed-off-by: nagisa <1434936049@qq.com>
2026-08-15 23:58:36 +08:00
SYLARandHongsheng Liu d1e230c95b [Diffusion][Quantization] Enable MiniMax-H3 global FP8 with DLO (#5910)
Signed-off-by: lishunyang12 <lishunyang12@163.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-15 23:01:26 +08:00
m0g3r 09b6a1604a [Bugfix] Restore per-stage runtime env during launch (#6214)
Signed-off-by: m0g3r <87276771+m0g3r@users.noreply.github.com>
2026-08-15 13:00:27 +00:00
Yueqian Lin 555336e887 [CI] Refresh Voxtral-4B-TTS perf baselines from a clean window (#6032)
Signed-off-by: Yueqian Lin <linyueqian@outlook.com>
2026-08-15 11:51:56 +00:00
Samit 136cb27b05 [Bugfix] Fix lost async diffusion outputs in request-level batching (#6023)
Signed-off-by: samithuang <285365963@qq.com>
2026-08-15 18:27:51 +08:00
SYLAR ce6ab0ca46 [Model] Add LTX-2.5 support (#6070)
Signed-off-by: lishunyang12 <lishunyang12@163.com>
2026-08-15 18:27:23 +08:00
NumberWan f39b8684eb [BugFix][Nightly CI] Adjust Qwen-Image accuracy thresholds for stable FA-deterministic mode (#5963)
Signed-off-by: NumberWan <wantszkin2003@gmail.com>
2026-08-15 09:38:30 +00:00
MrlixiangWE e57574ae29 [Bugfix] Carry ec_transfer_params and num_cache_creation_tokens on OmniRequestOutput (#6152)
Signed-off-by: MrlixiangWE <mrdanaer@gmail.com>
2026-08-15 08:37:27 +00:00
7b76b6446d [Model][Performance] Optimize MiniMax-H3 strict Ulysses boundaries (#6173)
Signed-off-by: mokashliu <mokashliu@tencent.com>
Co-authored-by: mokashliu <mokashliu@tencent.com>
Co-authored-by: WeiQing Chen <40507679+david6666666@users.noreply.github.com>
2026-08-15 16:27:52 +08:00
a70d4d4b3c [codex] Fix diffusion worker timeout for large broadcast payloads (#4845)
Signed-off-by: jiangweifeng.dev <jiangweifeng.dev@bytedance.com>
Co-authored-by: jiangweifeng.dev <jiangweifeng.dev@bytedance.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-15 16:03:04 +08:00
Hongsheng Liu 1260ceaae6 [Docs] Split diffusion attention and CPU offload guides (#6075)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-15 14:41:09 +08:00
Ma1oneZhang 6f36fd3b78 [Bugfix] Preserve object storage URIs during model resolution (#5036)
Signed-off-by: Ziyang Zhang <hafuhafu@qq.com>
2026-08-15 14:11:48 +08:00
35cacf020c [Model] Add Gepard-1.0 native-AR FSQ/NanoCodec TTS (offline inference) (#5666)
Signed-off-by: Mengjie Zhao <zmj0129@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-14 22:06:05 -07:00
wangyu d671e6b0db [CI] Expand E2E source_file_dependencies for shared model code (#5994)
Signed-off-by: wangyu <410167048@qq.com>
Signed-off-by: wangyu <53896905+yenuo26@users.noreply.github.com>
2026-08-15 12:01:20 +08:00
MrlixiangWE b95c73742d [Bugfix] Stop reading the removed OmniRequestOutput.request_output accessor (#6172)
Signed-off-by: MrlixiangWE <mrdanaer@gmail.com>
2026-08-15 07:07:28 +08:00
Alex Brooks fe54ecc388 [Frontend] Loosen Validation for TTS Models with No Uploaded Speakers (#5878)
Signed-off-by: Alex Brooks <albrooks@redhat.com>
2026-08-14 17:05:11 -06:00
4b6d6d5cf7 [Bugfix][XPU][Tests]Scope XPU pytest to explicit paths to fix collection crash (#6175)
Signed-off-by: Joshna Medisetty <joshna.medisetty@intel.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Chendi.Xue <chendi.xue@intel.com>
2026-08-14 15:23:41 -05:00
Alex Brooks f7a5146093 [Feat/Bugfix] Fix API Server model tag <-> model sync & flag normalization (#3805)
Signed-off-by: Alex Brooks <albrooks@redhat.com>
2026-08-14 19:13:00 +00:00
Wenjia Li 8ecd1f6d5c [Perf][NPU] Fuse MiniMax H3 Qwen3-VL SwiGLU (#6167)
Signed-off-by: Wenjia Li <wjialish@gmail.com>
2026-08-14 11:47:17 +00:00
Wenjia Li ffd11c181e [Perf][NPU] Fuse MiniMax H3 Qwen3-VL RoPE (#6061)
Signed-off-by: Wenjia Li <wjialish@gmail.com>
2026-08-14 09:49:26 +00:00
R0CKSTAR 728640f4d9 [Bugfix][MUSA][Qwen Image] Avoid complex RoPE alias guards (#6110)
Signed-off-by: Xiaodong Ye <xiaodong.ye@mthreads.com>
2026-08-14 15:51:23 +08:00
R0CKSTAR 022d7a7695 [Perf][Diffusion] Avoid redundant MiniMax-H3 reference video scans (#6064)
Signed-off-by: Xiaodong Ye <xiaodong.ye@mthreads.com>
2026-08-14 15:49:26 +08:00
baonudesifeizhai b300f66656 [Bugfix] Fix HSDP compatibility with the new online FP8 linear method (#5677)
Signed-off-by: roG0d <baonudesifeizhai@gmail.com>
2026-08-14 15:45:55 +08:00
TJianandHongsheng Liu bc73546c06 [ROCm] [CI] Migrate CI to mi300x for v0.27.x (#5886)
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Signed-off-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-14 15:38:47 +08:00
2b08419d8b [CI] Per-model, per-entry-mode code coverage collection (#5593)
Signed-off-by: Shenglei Fu <sfu@confluent.io>
Signed-off-by: Shenglei Fu <117230642+ShengleiFu@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Alicia <115451386+congw729@users.noreply.github.com>
Co-authored-by: wangyu <53896905+yenuo26@users.noreply.github.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-14 15:36:56 +08:00
zhengjiaandCursor 5d50bdc2ab [Perf] Cap diffusion worker thread count before spawn (#6165)
Signed-off-by: zjli2013 <leezhengjiang@126.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 12:14:55 +08:00
Samit 8a5bf2fb3f [doc]: Update latest news section for verl-omni release (#6187)
Signed-off-by: Samit <285365963@qq.com>
2026-08-14 12:04:15 +08:00
596c16a550 [Kernel] Fuse Q/K RMSNorm and RoPE (#5990)
Signed-off-by: Bo Li <22713281+bobboli@users.noreply.github.com>
Signed-off-by: lishunyang12 <lishunyang12@163.com>
Signed-off-by: Mengjie Zhao <zmj0129@gmail.com>
Co-authored-by: lishunyang12 <lishunyang12@163.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 00:46:59 +00:00
Lucas(Ruijie) 90a08c0eda [Model][TTS][WIP] Add dots.tts (rednote-hilab) — continuous-AR 48kHz TTS (#4765)
Signed-off-by: Moore-Z <zhumoore9661996@gmail.com>
2026-08-13 17:58:33 +00:00
Sy03 dbc0dd6d85 [Bugfix][Higgs-Audio-V3] Disable XQA decode (#6068)
Signed-off-by: Sy03 <1370724210@qq.com>
Signed-off-by: Sysy <1370724210@qq.com>
2026-08-13 10:00:50 -07:00
Mu GuanLin 83d1f11449 [Feat] LTX Standard Two-Stage Pipeline (#5500)
Signed-off-by: mglyn <1203789601@qq.com>
2026-08-14 00:13:14 +08:00
Yukim1andHongsheng Liu 4b66f62e10 [Refactor] Remove internal stage_configs_path plumbing (#5741)
Signed-off-by: zwhzzz0821 <2831474076@qq.com>
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-13 21:29:03 +08:00
Weiming Liao f41451f64c [NPU] Upgrade to v0.27.0 (#6096)
Signed-off-by: Weiming Liao <liaowm5@gmail.com>
2026-08-13 20:01:01 +08:00
Hongsheng Liu bbe6ccc512 [Doc] Refresh community documentation (#6141)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-13 17:04:06 +08:00
Canlin Guo bbb709cfb5 [BugFix] Use MOSS-TTS-Local official sample params (#6156)
Signed-off-by: Canlin Guo <canlinguosdu@gmail.com>
2026-08-13 08:56:26 +00:00
vraitiandClaude Opus 4.6 c98517ce7f [Metrics] Add Diffusion Metrics (#4755)
Signed-off-by: vraiti <vraiti@redhat.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-13 06:59:13 +00:00
NATUREandAlicia d77a35a32b [Bugfix] Scope Bagel FP8 config to diffusion stage (#6085)
Signed-off-by: natureofnature <wzliu@connect.hku.hk>
Co-authored-by: Alicia <115451386+congw729@users.noreply.github.com>
2026-08-13 11:23:47 +08:00
liwenerandamy-why-3459 877beeaa49 [Perf][MiniCPM-O-4.5]Add CUDA Graph For CFM DiT estimator (#6082)
Signed-off-by: liwener <liwener.c@gmail.com>
Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com>
2026-08-13 09:36:17 +08:00
Hongsheng Liu 8b8d3f56db [Misc] Consolidate LingBot text-to-video runner (#6076)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-13 08:42:37 +08:00
Hongsheng Liu c57178c0e1 [Dependency] Upgrade Cache-DiT to 1.5.0 (#6065)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-13 08:41:59 +08:00
mjZhaoElaineandClaude Opus 5 9a59475015 [CI/Build] Fix ReadTheDocs build under RTD's seeded pip 23.1 (#6129)
Signed-off-by: Mengjie Zhao <zmj0129@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 06:52:01 +08:00
Nick Cao 12f8168179 [Tests] Enable tiny model testing for Qwen-Image Edit and EditPlus (#5656)
Signed-off-by: Nick Cao <ncao@redhat.com>
2026-08-12 16:03:49 -04:00
Zhenghan Song 72a02b492a [Bugfix] Fix diffusion TTS adapter lookup in speech serving (#6121)
Signed-off-by: HaningZS <resossr0v0@gmail.com>
2026-08-12 15:20:12 -04:00
Juan Pablo ZuluagaandYueqian Lin 5358f5db01 [Perf][TTS] omnivoice hot path: D2H batching, mask caching, cached text embeddings (#5174)
Signed-off-by: JuanPZuluaga <juanz9312@gmail.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-12 17:15:35 +00:00
MaciejBalaNV e677360168 Add cosmos-guardrail dependency and update error message (#6107)
Signed-off-by: Maciej Bala <mbala@nvidia.com>
2026-08-12 17:04:07 +00:00
Juan Pablo ZuluagaandYueqian Lin 208c6776a8 [Perf][TTS] glm_tts: hoist loop-invariant text embed, RoPE, mask and CFG batch out of Euler loop (#5068)
Signed-off-by: JuanPZuluaga <juanz9312@gmail.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-12 17:02:02 +00:00
fcf1085395 [Refactor][OutputProcessor 2/8]: OmniRequestOutput should inherit RequestOutput and no nested wrap-up (#5146)
Signed-off-by: Boao Shi <aoibosh@connect.hku.hk>
Signed-off-by: bowieshi <aoibosh@connect.hku.hk>
Signed-off-by: princepride <wangzhipeng628@gmail.com>
Signed-off-by: R2-Y <ruiruyang2@gmail.com>
Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
Signed-off-by: Shi Boao Bowie <aoibosh@connect.hku.hk>
Co-authored-by: 汪志鹏 <wangzhipeng628@gmail.com>
Co-authored-by: ruirui(rein) yang <73573651+R2-Y@users.noreply.github.com>
Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com>
Co-authored-by: Gao Han <hgaoaf@connect.ust.hk>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-12 22:58:23 +08:00
Wenjia LiandHongsheng Liu 38a2500bdf [Perf] MiniMax H3 Qwen3-VL support fused RMSNorm on NPU (#5915)
Signed-off-by: Wenjia Li <wjialish@gmail.com>
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-12 19:12:54 +08:00
amy-why-3459 7cd826d28c [Bugfix][MiniCPM-o] Align Daily-Omni offline loading and duplex soft-… (#6095)
Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
2026-08-12 18:36:31 +08:00
wangyuandHongsheng Liu 31384cb39c [CI/Build] Add nightly DockerHub publish and cleanup to release pipeline (#6048)
Signed-off-by: wangyu <410167048@qq.com>
Signed-off-by: [Your Name] [Your Email]
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-12 17:30:55 +08:00
Yuekai ZhangandClaude Fable 5 5be7541d01 [Model] Support NVIDIA-NemotronLabs-VoiceChat-11B offline speech-to-speech (#5842)
Signed-off-by: Yuekai Zhang <zhangyuekai@foxmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 16:25:48 +08:00
9b0df3909a [Feature] timestamps for TTS via a forced-aligner pooling (#4795)
Signed-off-by: wjinxu <1299461899@qq.com>
Co-authored-by: xurui <xurui1@modelbest.onaliyun.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 05:33:34 +00:00
Hongsheng Liu a15b5b4bcd [CI/Build] Add examples policy to PR skills (#6046)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-12 11:37:34 +08:00
Hongsheng Liu 3c3989ed04 docs: align quantization overview with navigation (#6074)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-12 11:37:01 +08:00
Rahul SteigerandRahul Steiger 854bff7fe5 [Bugfix] Fix Wan spatial reshard boundary (#6062)
Signed-off-by: Rahul Steiger <rsteiger@nvl72d106-T18.cm.cluster>
Co-authored-by: Rahul Steiger <rsteiger@nvl72d106-T18.cm.cluster>
2026-08-12 11:36:24 +08:00
amy-why-3459 b792578d89 [CI][MiniCPM-o] Add MiniCPM-o 4.5 perf coverage to the ready gate (#6079)
Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
2026-08-12 11:32:36 +08:00
zzh bdb1d996be [Bugfix] Fix HunyuanImage3 accuracy test (#5981)
Signed-off-by: zzh <943967662@qq.com>
2026-08-12 02:40:05 +00:00
Hongsheng Liu 8b0a6779d4 [Misc] Build canonical image task prompts (#6049)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-12 08:30:34 +08:00
Sy03andYueqian Lin 58007c0084 [New Model] Support IndexTTS 2.5 (#5957)
Signed-off-by: Sysy <1370724210@qq.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-11 23:00:35 +00:00
Hongsheng Liu 1ff2753469 docs: align User Guide feature taxonomy (#6045)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-12 00:20:56 +08:00
SYLAR 4697bd1be0 [Docs] Add MiniMax-H3 recipe for RTX PRO 5000 (#5857)
Signed-off-by: lishunyang12 <lishunyang12@163.com>
2026-08-11 23:53:58 +08:00
Zhou TaichangandClaude Opus 5 2ce15ab7a0 [Rebase] Rebase to vllm 0.27.0 (#5976)
Signed-off-by: tzhouam <tzhouam@connect.ust.hk>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 15:23:46 +00:00
Nick Cao 584d78c673 [Test] Add tiny model builder for FluxKontextPipeline (#5823)
Signed-off-by: Nick Cao <ncao@redhat.com>
2026-08-11 10:59:09 -04:00
Jerry Song 89015d5cad [Feature]: Adds distilled LoRA support for diffusion models (#2783)
Signed-off-by: Songrui625 <songrui625@gmail.com>
2026-08-11 14:23:43 +00:00
amy-why-3459 348cf95a89 [CI][MiniCPM-o] Align MiniCPM-o 4.5 online serving tests with minicpm… (#6056)
Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
2026-08-11 21:11:39 +08:00
R0CKSTAR 22dd96ec5c [Hardware][MUSA] Complete Omni platform interfaces (#6058)
Signed-off-by: Xiaodong Ye <xiaodong.ye@mthreads.com>
2026-08-11 12:46:42 +00:00
e04210d690 [Hardware][MUSA] Enable Qwen3-Omni ModelOpt FP8 inference (#5671)
Signed-off-by: Xiaodong Ye <xiaodong.ye@mthreads.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com>
2026-08-11 17:19:09 +08:00
4ab1b4ff9c [Perf][Flux2][HunyuanVideo1.5] Skip attention-mask to avoid varlen path (#4645)
Signed-off-by: kTorp <Kristoffer.Torp@amd.com>
Signed-off-by: Didan Deng <33117903+wtomin@users.noreply.github.com>
Co-authored-by: Didan Deng <33117903+wtomin@users.noreply.github.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-11 15:31:02 +08:00
06e733d3cd [Model] Add LongCat-Video-Avatar-1.5 ai2v, at2v support (#4099)
Signed-off-by: weiyan <weiyanlin117@gmail.com>
Signed-off-by: Didan Deng <33117903+wtomin@users.noreply.github.com>
Co-authored-by: Didan Deng <33117903+wtomin@users.noreply.github.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-11 15:17:17 +08:00
Wang fuyinandHongsheng Liu af3faa6c1e [Diffusion] Add Worker contracts and RPC plumbing for Scheduler-managed paged KV cache (#5550)
Signed-off-by: Acerak01-fy <wfy2003324@163.com>
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-11 14:55:42 +08:00
322600bfb2 [CI][MiniCPM-o] Add MiniCPM-o 4.5 accuracy and performance coverage (#5524)
Signed-off-by: R2-Y <ruiruyang2@gmail.com>
Signed-off-by: psv666 <2693925048@qq.com>
Co-authored-by: psv666 <2693925048@qq.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com>
2026-08-11 14:53:49 +08:00
Hongsheng Liu c4a14091c9 [Doc] Explain repository skills for agentic contributions (#6029)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-11 14:18:41 +08:00
yiminghub2024 6d4e4ffc7c Add MiniMax-H3 recipe for RTX 4090 setup (#5850)
Signed-off-by: yiminghub2024 <482890@qq.com>
2026-08-11 14:08:51 +08:00
Zhou248 f97af75d1d [Model] Batch MiniCPM-o Talker codec sampling (#5792)
Signed-off-by: Zhou248 <62542847+Zhou248@users.noreply.github.com>
2026-08-11 14:05:02 +08:00
Hongsheng Liu 73a312d5b6 [Bugfix] Normalize NumPy image outputs before saving (#6031)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-11 13:48:03 +08:00
Zijun HuangandWeiQing Chen 1a56953d7a [NPU][Model] Add distilled 4-step sigma schedule support for MiniMax H3 t2va (#5991)
Signed-off-by: Zijun Huang <zijunhua@usc.edu>
Co-authored-by: WeiQing Chen <40507679+david6666666@users.noreply.github.com>
2026-08-11 13:46:10 +08:00
WeiQing Chen 1f65814fab [CI] Align MiniMax H3 Ref2VA inputs and add I2VA/Ref2VA accuracy coverage (#5978)
Signed-off-by: david6666666 <530634352@qq.com>
2026-08-11 13:36:37 +08:00
boatmanandYueqian Lin 4f9b65074d [Perf][Qwen3-TTS]Cached Incremental Decode (#5202)
Signed-off-by: boatman <109857087+sphinxkkkbc@users.noreply.github.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-11 05:24:04 +00:00
Juan Pablo ZuluagaandYueqian Lin 12a5f6fbf3 [Perf][TTS] step_audio2: keep streaming tokens on-device and batch audio-feature length syncs (#5067)
Signed-off-by: JuanPZuluaga <juanz9312@gmail.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-10 21:24:25 -07:00
Juan Pablo ZuluagaandYueqian Lin 53afbf3a0c [Perf][TTS] voxtral_tts hot path: cudagraph opt-out, host-sync removal, kernel caches (#5175)
Signed-off-by: JuanPZuluaga <juanz9312@gmail.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-10 21:03:32 -07:00
ee118ab492 [Bugfix] Per-replica fault isolation: keep API server alive on single-stage death (#4285) (#4583)
Signed-off-by: Shenglei Fu <sfu@confluent.io>
Signed-off-by: Shenglei Fu <117230642+ShengleiFu@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Yueqian Lin <70319226+linyueqian@users.noreply.github.com>
2026-08-10 23:00:18 -04:00
fan2956andFan c27623c29c [Bugfix] rainfusion support all shape video (#6000)
Signed-off-by: Fan <fan@FandeMacBook-Air.local>
Co-authored-by: Fan <fan@FandeMacBook-Air.local>
2026-08-11 05:10:50 +08:00
Yueqian Lin f8fa86fb1f [BugFix] Don't fail the TTS ratchet when the branch count goes down (#6008)
Signed-off-by: Yueqian Lin <linyueqian@outlook.com>
2026-08-11 05:08:31 +08:00
ooooooyeandHongsheng Liu 422d8fd8f9 [Bugfix][Diffusion] Restore supports_packed_mask_free on teacache FakeBackend (#5997)
Signed-off-by: brandneway <gyuan4892@gmail.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-10 22:20:37 +08:00
Hongsheng Liu 62e239bf1e [Docs] Fix broken attention backend link (#5998)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-10 21:55:01 +08:00
ooooooye 740f45abcd [Perf][Diffusion] MiniMax-H3: opt into packed varlen attention on NPU to eliminate quadratic mask materialization (#5891)
Signed-off-by: brandneway <gyuan4892@gmail.com>
2026-08-10 19:47:03 +08:00
5e4b9f8c6e [Misc] Align CODEOWNERS with module/feature design docs (#5958)
Signed-off-by: hsliu_ustc <hsliu_ustc@noreply.gitcode.com>
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
Co-authored-by: hsliu_ustc <hsliu_ustc@noreply.gitcode.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-10 19:25:03 +08:00
Hongsheng Liu ae811043e9 docs: keep shared task examples in navigation (#5987)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-10 19:13:52 +08:00
R0CKSTAR 636d44e272 [Perf][MUSA] Restore MiniMax-H3 dynamic RoPE fusion (#5881)
Signed-off-by: Xiaodong Ye <xiaodong.ye@mthreads.com>
2026-08-10 17:24:46 +08:00
yiminghub2024 8e44e78038 Add Ref2VA measurements to the MiniMax-H3 DGX Spark (GB10) recipe (#5972)
Signed-off-by: yiminghub2024 <482890@qq.com>
2026-08-10 15:51:15 +08:00
Hongsheng Liu b98b7c8529 [Docs] Preserve generated quantization URLs and link recipes in supported models (#5969)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-10 15:45:50 +08:00
bjf-frzandAlicia 1ee2fff532 Update Wan2.2 I2V performance baselines (#5977)
Signed-off-by: bjf-frz <frz123db@gmail.com>
Co-authored-by: Alicia <115451386+congw729@users.noreply.github.com>
2026-08-10 15:24:59 +08:00
Zeyu Huang | 黃澤宇andHongsheng Liu 33dd9a5a3e [Core][Refactor][Diffusion] refactor request scheduler's admission wait policy (#5843)
Signed-off-by: Huang, Zeyu <11222265+fhfuih@users.noreply.github.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-10 15:06:27 +08:00
c588208cc6 [bugfix] Support lora request for non diffusion model (#5374)
Signed-off-by: knlnguyen1802 <knlnguyen1802@gmail.com>
Co-authored-by: Samit <285365963@qq.com>
Co-authored-by: Gao Han <hgaoaf@connect.ust.hk>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-10 11:27:51 +08:00
wangyuandamy-why-3459 e28bf8ff8b [CI] Re-enable bagel shared-memory connector test (#5475) (#5898)
Signed-off-by: wangyu <410167048@qq.com>
Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com>
2026-08-10 11:26:10 +08:00
WeiQing Chen e1aa6eae75 docs: update vLLM-Omni WeChat QR code (#5959)
Signed-off-by: David Chen <530634352@qq.com>
2026-08-10 10:04:24 +08:00
wtz2333andClaude 36135ef09a [diffusion][feature] Add LingBot-Video T2I and TI2V generation modes (#5311)
Signed-off-by: wtz2333 <2955110911@qq.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-08-10 10:02:31 +08:00
boatman 11f633aa83 [Refactor] Add Ming Flash Omni TTS adapter (#5746)
Signed-off-by: boatman <109857087+sphinxkkkbc@users.noreply.github.com>
2026-08-10 01:47:09 +00:00
6ae7ff7846 [Diffusion] Prepare HunyuanImage3 for Scheduler-managed paged KV cache (#5541)
Signed-off-by: zwhzzz0821 <zwhzzz0821@users.noreply.github.com>
Co-authored-by: zwhzzz0821 <zwhzzz0821@users.noreply.github.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-10 08:48:56 +08:00
yiminghub2024 615de4e041 [doc]Add recipe for MiniMax-H3 on RTX PRO 6000 (#5863)
Signed-off-by: yiminghub2024 <482890@qq.com>
2026-08-09 23:52:40 +08:00
yiminghub2024 be48b0797e Add MiniMax-H3 recipe for DGX Spark (GB10) (#5946)
Signed-off-by: yiminghub2024 <482890@qq.com>
2026-08-09 23:15:05 +08:00
Diya Pengandlishunyang12 45629a8e26 [MiniMax-H3] TeaCache support and Cache-DiT validation (#5840)
Signed-off-by: dpeng123 <diyapeng123@gmail.com>
Signed-off-by: lishunyang12 <lishunyang12@163.com>
Co-authored-by: lishunyang12 <lishunyang12@163.com>
2026-08-09 15:07:21 +00:00
boatman fc8946fcf5 [Perf][MiniCPM-O-4.5]Add CUDA Graph For HiFTGenerator (#5869)
Signed-off-by: boatman <109857087+sphinxkkkbc@users.noreply.github.com>
2026-08-09 22:29:49 +08:00
amd-xiaoyu12 f01e4bdddc [Recipe] Document MiniMax H3 ROCm (gfx950) BF16 serving (#5723)
Signed-off-by: Xiao Yu <xiao.yu@amd.com>
Signed-off-by: amd-xiaoyu12 <xiao.yu@amd.com>
2026-08-09 22:18:24 +08:00
Weiming LiaoandHongsheng Liu 592637015f [BugFix][NPU] MiniMax-H3 RoPE crash: add the missing batch dim before the mindiesd kernel (#5896)
Signed-off-by: Weiming Liao <liaowm5@gmail.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-09 14:08:43 +00:00
Yueqian Lin ebe93f5d1e [Refactor][TTS] Derive TTS model detection from adapter metadata (#5682)
Signed-off-by: Yueqian Lin <linyueqian@outlook.com>
2026-08-09 21:30:05 +08:00
linzhenpl07andClaude Opus 4.8 8e2e9b6b53 [Feat] Cosmos3 session-memory port for UND text K/V (RFC #4480 Phase 0) (#4657)
Signed-off-by: linzhenpl07 <linzhenpl07@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-09 20:53:17 +08:00
Hongsheng Liu 9159cedbd7 docs: update vLLM-Omni architecture overview (#5914)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-09 09:16:18 +08:00
Caspian ChenandSYLAR 593b404539 [Quantization][Qwen2.5-Omni] Support thinker-only ModelOpt NVFP4 W4A4 checkpoints (#5073)
Signed-off-by: Caspian443 <scrisis843@gmail.com>
Co-authored-by: SYLAR <125541396+lishunyang12@users.noreply.github.com>
2026-08-09 02:45:57 +08:00
Hongsheng Liu f663d120c7 [Misc] Add vLLM-Omni PR review skill (#5871)
Signed-off-by: Hongsheng Liu <liuhongsheng4@huawei.com>
2026-08-08 22:18:54 +08:00
Shenglei FuandClaude Opus 5 81b48e83ec [Model] Fail MiniMax H3 encoder load when a weight or fused shard is missing (#5824)
Signed-off-by: Shenglei Fu <sfu@confluent.io>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 13:14:00 +08:00
832 changed files with 90752 additions and 10582 deletions

No files matched your search

+91 -141
View File
@@ -1,153 +1,103 @@
#!/bin/bash
# vllm-omni customized version
# Based on: vllm/.buildkite/scripts/hardware_ci/run-amd-test.sh
# Last synced: 2025-12-15
# Modifications: docker image name for vllm-omni
# This script runs test inside the corresponding ROCm docker container.
set -o pipefail
# Run vLLM-Omni ROCm tests directly in the MI300 Kubernetes pod. The pod's
# container image is selected by test-template-amd-omni.j2; MI300 has no DinD.
set -euo pipefail
# Export Python path
export PYTHONPATH=".."
: "${PYTHONFAULTHANDLER:=1}"
: "${HF_HOME:=/home/buildkite-agent/huggingface}"
: "${HF_HUB_DOWNLOAD_TIMEOUT:=300}"
: "${HF_HUB_ETAG_TIMEOUT:=60}"
: "${MIOPEN_DEBUG_CONV_DIRECT:=0}"
: "${MIOPEN_DEBUG_CONV_GEMM:=0}"
: "${VLLM_ROCM_USE_AITER:=0}"
export PYTHONFAULTHANDLER HF_HOME HF_HUB_DOWNLOAD_TIMEOUT HF_HUB_ETAG_TIMEOUT
export MIOPEN_DEBUG_CONV_DIRECT MIOPEN_DEBUG_CONV_GEMM VLLM_ROCM_USE_AITER
export PYTORCH_ROCM_ARCH=""
export PYTHONPATH="${PYTHONPATH:-..}"
if [[ "${VLLM_CI_DOCKER_DISABLED:-0}" != "1" ]]; then
echo "Error: MI300 CI must run natively with Docker disabled." >&2
exit 1
fi
if [[ -n "${TEST_COMMANDS:-}" ]]; then
commands="${TEST_COMMANDS}"
else
commands="$*"
fi
if [[ -z "${commands}" ]]; then
echo "Error: No test commands provided." >&2
exit 1
fi
echo "--- Native in-pod ROCm CI"
job_id="${BUILDKITE_JOB_ID:-${BUILDKITE_PARALLEL_JOB:-local}}"
job_id="${job_id//[^A-Za-z0-9_.-]/_}"
native_cache_root="/tmp/vllm-omni-native-${job_id}"
TMPDIR="${native_cache_root}/tmp"
TORCHINDUCTOR_CACHE_DIR="${native_cache_root}/torchinductor"
TRITON_CACHE_DIR="${native_cache_root}/triton"
VLLM_CACHE_ROOT="${native_cache_root}/vllm"
XDG_CACHE_HOME="${native_cache_root}/xdg"
HF_DATASETS_CACHE="${native_cache_root}/huggingface/datasets"
export TMPDIR TORCHINDUCTOR_CACHE_DIR TRITON_CACHE_DIR VLLM_CACHE_ROOT
export XDG_CACHE_HOME HF_DATASETS_CACHE
mkdir -p "${TMPDIR}" "${TORCHINDUCTOR_CACHE_DIR}" "${TRITON_CACHE_DIR}" \
"${VLLM_CACHE_ROOT}" "${XDG_CACHE_HOME}" "${HF_HOME}" \
"${HF_DATASETS_CACHE}"
if [[ "${VLLM_CI_REQUIRE_PERSISTENT_HF_CACHE:-0}" == "1" ]]; then
if ! command -v findmnt >/dev/null 2>&1; then
echo "Error: findmnt is required to verify the Hugging Face cache mount." >&2
exit 1
fi
hf_mount=$(findmnt -n -T "${HF_HOME}" -o TARGET 2>/dev/null || true)
if [[ -z "${hf_mount}" || "${hf_mount}" == "/" ]]; then
echo "Error: MI300 CI requires a persistent volume at or above ${HF_HOME}." >&2
exit 1
fi
fi
# Print ROCm version
echo "--- ROCm info"
rocminfo
# cleanup older docker images
cleanup_docker() {
# Get Docker's root directory
docker_root=$(docker info -f '{{.DockerRootDir}}')
if [ -z "$docker_root" ]; then
echo "Failed to determine Docker root directory."
exit 1
fi
echo "Docker root directory: $docker_root"
# Check disk usage of the filesystem where Docker's root directory is located
disk_usage=$(df "$docker_root" | tail -1 | awk '{print $5}' | sed 's/%//')
# Define the threshold
threshold=70
if [ "$disk_usage" -gt "$threshold" ]; then
echo "Disk usage is above $threshold%. Cleaning up Docker images and volumes..."
# Remove dangling images (those that are not tagged and not used by any container)
docker image prune -f
# Remove unused volumes / force the system prune for old images as well.
docker volume prune -f && docker system prune --force --filter "until=72h" --all
echo "Docker images and volumes cleanup completed."
else
echo "Disk usage is below $threshold%. No cleanup needed."
fi
}
expected_gpus="${VLLM_CI_EXPECTED_GPU_COUNT:-1}"
python3 - <<'PY'
import os
# Call the cleanup docker function
cleanup_docker
import torch
echo "--- Pulling container"
## Temporary change to use AMD Docker Hub to store the vllm-omni image
# to bypass the rate limit issue with ECR Public Gallery.
# Images are now stored in a separate repository for vllm-omni, instead of vllm-ci.
# TODO: @tjtanaa point back to ECR Public Gallery
# once the amd agents are configured to use ECR Public Gallery.
# image_name="public.ecr.aws/q9t5s3a7/vllm-ci-test-repo:${BUILDKITE_COMMIT}-rocm-omni"
image_name="rocm/vllm-omni:${BUILDKITE_COMMIT}"
container_name="rocm_${BUILDKITE_COMMIT}_$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 10; echo)"
expected = int(os.environ.get("VLLM_CI_EXPECTED_GPU_COUNT", "1"))
assert torch.version.hip, "PyTorch is not a ROCm build"
assert torch.cuda.is_available(), "ROCm GPU is not available to PyTorch"
actual = torch.cuda.device_count()
assert actual == expected, f"Expected {expected} ROCm GPU(s), found {actual}"
PY
# TODO: @tjtanaa uncomment this once the amd agents are configured to use ECR Public Gallery.
# # Install AWS CLI to authenticate to ECR Public Gallery to get higher rate limit for pulling images
# sudo apt-get update && sudo apt-get install -y awscli
## Use safe docker login helper to prevent race conditions
# source "$(dirname "${BASH_SOURCE[0]}")/../../common/scripts/docker_login_ecr_public.sh"
# safe_docker_login_ecr_public
## Pull the container from AMD Docker Hub
docker pull "${image_name}"
remove_docker_container() {
docker ps -aq --filter "name=${container_name}" | xargs -r docker rm -f || true
docker image rm -f "${image_name}" || true
}
trap remove_docker_container EXIT
echo "--- Running container"
HF_CACHE="$(realpath ~)/huggingface"
mkdir -p "${HF_CACHE}"
HF_MOUNT="/root/.cache/huggingface"
if [[ -n "${TEST_COMMAND:-}" ]]; then
commands="$TEST_COMMAND"
else
commands="$@"
fi
echo "Commands:$commands"
PARALLEL_JOB_COUNT=8
MYPYTHONPATH=".."
# Test that we're launching on the machine that has
# proper access to GPUs
render_gid=$(getent group render | cut -d: -f3)
if [[ -z "$render_gid" ]]; then
echo "Error: 'render' group not found. This is required for GPU access." >&2
exit 1
fi
# check if the command contains shard flag, we will run all shards in parallel because the host have 8 GPUs.
# TODO: @tjtanaa reenable to run VLLM_ROCM_USE_AITER=1 when AITER is shipped with prebuilt kernels.
if [[ $commands == *"--shard-id="* ]]; then
# assign job count as the number of shards used
commands=$(echo "$commands" | sed -E "s/--num-shards[[:blank:]]*=[[:blank:]]*[0-9]*/--num-shards=${PARALLEL_JOB_COUNT} /g" | sed 's/ \\ / /g')
for GPU in $(seq 0 $(($PARALLEL_JOB_COUNT-1))); do
# assign shard-id for each shard
commands_gpu=$(echo "$commands" | sed -E "s/--shard-id[[:blank:]]*=[[:blank:]]*[0-9]*/--shard-id=${GPU} /g" | sed 's/ \\ / /g')
echo "Shard ${GPU} commands:$commands_gpu"
echo "Render devices: $BUILDKITE_AGENT_META_DATA_RENDER_DEVICES"
docker run \
--device /dev/kfd $BUILDKITE_AGENT_META_DATA_RENDER_DEVICES \
--network=host \
--shm-size=16gb \
--group-add "$render_gid" \
-e MIOPEN_DEBUG_CONV_DIRECT=0 \
-e MIOPEN_DEBUG_CONV_GEMM=0 \
-e VLLM_ROCM_USE_AITER=0 \
-e HIP_VISIBLE_DEVICES="${GPU}" \
-e HF_TOKEN \
-v "${HF_CACHE}:${HF_MOUNT}" \
-e "HF_HOME=${HF_MOUNT}" \
-e "PYTHONPATH=${MYPYTHONPATH}" \
--name "${container_name}_${GPU}" \
"${image_name}" \
/bin/bash -c "${commands_gpu}" \
|& while read -r line; do echo ">>Shard $GPU: $line"; done &
PIDS+=($!)
done
#wait for all processes to finish and collect exit codes
for pid in "${PIDS[@]}"; do
wait "${pid}"
STATUS+=($?)
done
for st in "${STATUS[@]}"; do
if [[ ${st} -ne 0 ]]; then
echo "One of the processes failed with $st"
exit "${st}"
echo "Commands:${commands}"
if /bin/bash -o pipefail -c '
set -E
test_status=0
trap '\''
command_status=$?
# Keep running subsequent commands, but retain a failure for the final exit.
# Prefer a test failure over pytest "no tests collected" when both occur.
if (( test_status == 0 || (test_status == 5 && command_status != 5) )); then
test_status=${command_status}
fi
done
'\'' ERR
eval "$1"
exit "${test_status}"
' _ "${commands}"; then
exit 0
else
echo "Render devices: $BUILDKITE_AGENT_META_DATA_RENDER_DEVICES"
docker run \
--device /dev/kfd $BUILDKITE_AGENT_META_DATA_RENDER_DEVICES \
--network=host \
--shm-size=16gb \
--group-add "$render_gid" \
-e MIOPEN_DEBUG_CONV_DIRECT=0 \
-e MIOPEN_DEBUG_CONV_GEMM=0 \
-e VLLM_ROCM_USE_AITER=0 \
-e HF_TOKEN \
-v "${HF_CACHE}:${HF_MOUNT}" \
-e "HF_HOME=${HF_MOUNT}" \
-e "PYTHONPATH=${MYPYTHONPATH}" \
--name "${container_name}" \
"${image_name}" \
/bin/bash -c "${commands}"
exit_code=$?
fi
if [[ ${exit_code} -eq 5 && "${VLLM_CI_ALLOW_NO_TESTS:-0}" == "1" ]]; then
echo "Pytest collected no tests; VLLM_CI_ALLOW_NO_TESTS=1, treating exit code 5 as success."
exit 0
fi
exit "${exit_code}"
+45 -34
View File
@@ -7,54 +7,64 @@ steps:
- group: ":card_index_dividers: Simple Test"
steps:
- label: "Simple · Diffusion & Model Executor Test (1/2)"
agent_pool: mi325_1
- label: "Simple · Model Executor Test · Shard %N/%t"
agent_pool: mi300_1
parallelism: 2
depends_on: amd-build
timeout_in_minutes: 70
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- export VLLM_ROCM_USE_AITER=0
# ignore test_teacache_extractors.py because it use rocm gemm kernel from vLLM
# that is not supported on CPU
# CPU tests on ROCm gpu machines are very slow, so we give them more time.
- "timeout 60m pytest -sv tests/diffusion -m 'core_model and cpu' --ignore=tests/diffusion/cache/test_teacache_extractors.py --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- "pytest -sv tests/model_executor -m 'core_model and cpu' --num-shards=$$BUILDKITE_PARALLEL_JOB_COUNT --shard-id=$$BUILDKITE_PARALLEL_JOB --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml:coverage-model-executor-$$BUILDKITE_PARALLEL_JOB.xml"
- label: "Simple · Diffusion & Model Executor Test (2/2)"
agent_pool: mi325_1
- label: "Simple · Diffusion Test · Shard %N/%t"
agent_pool: mi300_1
parallelism: 2
depends_on: amd-build
timeout_in_minutes: 70
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- export VLLM_ROCM_USE_AITER=0
# CPU tests on ROCm gpu machines are very slow, so we give them more time.
- "timeout 60m pytest -sv tests/model_executor -m 'core_model and cpu' --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
# ignore test_teacache_extractors.py because it use rocm gemm kernel from vLLM
# that is not supported on CPU
- "pytest -sv tests/diffusion -m 'core_model and cpu' --ignore=tests/diffusion/cache/test_teacache_extractors.py --num-shards=$$BUILDKITE_PARALLEL_JOB_COUNT --shard-id=$$BUILDKITE_PARALLEL_JOB --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml:coverage-diffusion-$$BUILDKITE_PARALLEL_JOB.xml"
- label: "Simple · Engine&Entrypoints Test"
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- export VLLM_ROCM_USE_AITER=0
- "pytest -sv tests/entrypoints tests/engine -m 'core_model and cpu' --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- label: "Simple · Other Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
timeout_in_minutes: 50
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- export VLLM_ROCM_USE_AITER=0
# ignore test_teacache_extractors.py because it use rocm gemm kernel from vLLM
# that is not supported on CPU
- "timeout 40m pytest -sv tests/diffusion tests/model_executor -m 'core_model and cpu' --ignore=tests/diffusion/cache/test_teacache_extractors.py --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- "pytest -sv tests/ -m 'core_model and cpu' --ignore=tests/diffusion --ignore=tests/model_executor --ignore=tests/entrypoints --ignore=tests/engine --ignore=tests/diffusion/cache/test_teacache_extractors.py --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- group: ":card_index_dividers: Diffusion Test"
steps:
- label: "Diffusion · LoRA Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
artifact_paths:
- lora-server.log
commands:
- timeout 20m pytest -s -v tests/diffusion/lora/test_images_generations_lora.py
- pytest -sv tests/diffusion/lora/ -m 'advanced_model and cuda' --run-level "advanced_model" 2>&1 | tee lora-server.log
- label: "Diffusion Model CPU offloading Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -62,7 +72,7 @@ steps:
- export VLLM_LOGGING_LEVEL=DEBUG
- export VLLM_WORKER_MULTIPROC_METHOD=spawn
- |
timeout 20m bash -c '
bash -c '
set +e
pytest -s -v tests/diffusion/offloader/test_diffusion_cpu_offload.py
EXIT1=\$?
@@ -72,7 +82,7 @@ steps:
'
- label: "Diffusion Sequence Parallelism Test (Need 4 GPUs)"
agent_pool: mi325_4
agent_pool: mi300_4
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -84,7 +94,7 @@ steps:
# merge-only tests
- label: "Diffusion Tensor Parallelism Test"
agent_pool: mi325_2
agent_pool: mi300_2
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -92,7 +102,7 @@ steps:
- pytest -s -v tests/diffusion/distributed/test_tensor_parallel.py
- label: "Diffusion Model Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -100,7 +110,7 @@ steps:
- timeout 30m pytest -s -v tests/e2e/offline_inference/test_z_image.py
- label: "Diffusion GPU Worker Test"
agent_pool: mi325_2
agent_pool: mi300_2
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -108,7 +118,7 @@ steps:
- timeout 20m pytest -s -v tests/diffusion/test_diffusion_worker.py
- label: "Diffusion · Wan22 Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -121,7 +131,7 @@ steps:
## ISSUE depends on `diffusers` package: https://github.com/huggingface/diffusers/issues/13274
# - label: "Audio Generation Model Test"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
@@ -132,7 +142,7 @@ steps:
# - timeout 20m pytest -s -v tests/e2e/offline_inference/test_stable_audio_expansion.py -m "advanced_model and diffusion and L4" --run-level advanced_model
- label: "Engine Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -147,7 +157,7 @@ steps:
- group: ":card_index_dividers: E2E Test"
steps:
- label: "Omni Model Test Qwen2-5-Omni"
agent_pool: mi325_4
agent_pool: mi300_4
depends_on: amd-build
mirror_hardwares: [amdproduction]
commands:
@@ -155,7 +165,7 @@ steps:
- pytest -s -v tests/e2e/*/test_qwen2_5_omni_expansion.py --run-level "core_model"
- label: "Omni Model Test Qwen3-Omni"
agent_pool: mi325_2
agent_pool: mi300_2
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -163,22 +173,23 @@ steps:
- export VLLM_WORKER_MULTIPROC_METHOD=spawn
- pytest -s -v tests/e2e/offline_inference/test_qwen3_omni.py tests/e2e/online_serving/test_qwen3_omni.py -m 'advanced_model and cuda' --run-level 'advanced_model'
- label: "Qwen3-TTS CustomVoice E2E Test"
agent_pool: mi325_1
- label: "Qwen3-TTS CustomVoice E2E Test · Shard %N/%t"
agent_pool: mi300_1
parallelism: 2
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- |
timeout 50m bash -c '
bash -c '
export VLLM_LOGGING_LEVEL=DEBUG
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export VLLM_ALLOW_LONG_MAX_MODEL_LEN="1"
pytest -s -v tests/e2e/online_serving/test_qwen3_tts_customvoice.py tests/e2e/offline_inference/test_qwen3_tts_customvoice.py -m "advanced_model" --run-level "advanced_model"
pytest -s -v tests/e2e/online_serving/test_qwen3_tts_customvoice.py tests/e2e/offline_inference/test_qwen3_tts_customvoice.py -m "advanced_model" --run-level "advanced_model" --num-shards=$$BUILDKITE_PARALLEL_JOB_COUNT --shard-id=$$BUILDKITE_PARALLEL_JOB
'
- label: "Qwen3-TTS Base E2E Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -196,7 +207,7 @@ steps:
# Need to debug before reneable numerical changes across large PRs
# # split Bagel Model Test with H100 (Real Weights) into three tests
# - label: "Bagel Text2Img Model Test (1/3)"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
@@ -208,7 +219,7 @@ steps:
# - timeout 30m pytest -s -v tests/e2e/offline_inference/test_bagel.py -m "advanced_model" --run-level "advanced_model" -k "shared_memory" -k "rocm"
# - label: "Bagel Img2Img Model Test (2/3)"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
@@ -220,7 +231,7 @@ steps:
# - timeout 30m pytest -s -v tests/e2e/offline_inference/test_bagel.py -m "advanced_model" --run-level "advanced_model" -k "rocm"
# - label: "Bagel Online Serving Test (3/3)"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
+47 -34
View File
@@ -7,8 +7,9 @@ steps:
- group: ":card_index_dividers: Simple Test"
steps:
- label: "Simple · Diffusion & Model Executor Test"
agent_pool: mi325_1
- label: "Simple · Model Executor Test · Shard %N/%t"
agent_pool: mi300_1
parallelism: 2
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -16,10 +17,30 @@ steps:
- export VLLM_ROCM_USE_AITER=0
# ignore test_teacache_extractors.py because it use rocm gemm kernel from vLLM
# that is not supported on CPU
- "timeout 40m pytest -sv tests/diffusion tests/model_executor -m 'core_model and cpu' --ignore=tests/diffusion/cache/test_teacache_extractors.py --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- "pytest -sv tests/model_executor -m 'core_model and cpu' --num-shards=$$BUILDKITE_PARALLEL_JOB_COUNT --shard-id=$$BUILDKITE_PARALLEL_JOB --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml:coverage-model-executor-$$BUILDKITE_PARALLEL_JOB.xml"
- label: "Simple · Diffusion Test"
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- export VLLM_ROCM_USE_AITER=0
# ignore test_teacache_extractors.py because it use rocm gemm kernel from vLLM
# that is not supported on CPU
- "pytest -sv tests/diffusion -m 'core_model and cpu' --ignore=tests/diffusion/cache/test_teacache_extractors.py --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- label: "Simple · Engine&Entrypoints Test"
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- export VLLM_ROCM_USE_AITER=0
- "pytest -sv tests/entrypoints tests/engine -m 'core_model and cpu' --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- label: "Simple · Other Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -27,19 +48,19 @@ steps:
- export VLLM_ROCM_USE_AITER=0
# ignore test_teacache_extractors.py because it use rocm gemm kernel from vLLM
# that is not supported on CPU
- "timeout 40m pytest -sv tests/diffusion tests/model_executor -m 'core_model and cpu' --ignore=tests/diffusion/cache/test_teacache_extractors.py --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- "pytest -sv tests/ -m 'core_model and cpu' --ignore=tests/diffusion --ignore=tests/model_executor --ignore=tests/entrypoints --ignore=tests/engine --ignore=tests/diffusion/cache/test_teacache_extractors.py --cov=vllm_omni --cov-report=term-missing:skip-covered --cov-report=xml"
- label: "Custom Pipeline Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- timeout 20m pytest -s -v tests/e2e/features/custom_pipeline/ -m "core_model"
- pytest -s -v tests/e2e/features/custom_pipeline/ -m "core_model"
- label: "Voxtral TTS CUDA Unit Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -49,33 +70,25 @@ steps:
- group: ":card_index_dividers: Diffusion Test"
steps:
- label: "Diffusion · Batch Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- timeout 20m pytest -sv tests/diffusion/batching -m 'core_model and cuda' --run-level "core_model"
- pytest -sv tests/diffusion/batching -m 'core_model and cuda' --run-level "core_model"
- label: "Diffusion · Offloader Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
commands:
- export VLLM_LOGGING_LEVEL=DEBUG
- export VLLM_WORKER_MULTIPROC_METHOD=spawn
- |
timeout 20m bash -c '
set +e
pytest -s -v tests/diffusion/offloader/test_diffusion_cpu_offload.py
EXIT1=\$?
pytest -s -v tests/diffusion/offloader/test_diffusion_layerwise_offload.py
EXIT2=\$?
exit \$((EXIT1 | EXIT2))
'
- pytest -s -v tests/diffusion/offloader -m "core_model and cuda" --run-level "core_model"
- label: "Diffusion · Cache Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -83,10 +96,10 @@ steps:
- export GPU_ARCHS=gfx942
- export VLLM_LOGGING_LEVEL=DEBUG
- export VLLM_WORKER_MULTIPROC_METHOD=spawn
- timeout 15m pytest -s -v -m "core_model and cache and diffusion and not distributed_cuda and L4"
- pytest -sv tests/diffusion/cache -m 'core_model and cuda' --run-level "core_model"
- label: "Diffusion Sequence Parallelism Test"
agent_pool: mi325_2
agent_pool: mi300_2
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -96,7 +109,7 @@ steps:
- timeout 20m pytest -s -v tests/diffusion/distributed/test_sequence_parallel.py -m core_model
- label: "Diffusion GPU Worker Test"
agent_pool: mi325_2
agent_pool: mi300_2
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -104,7 +117,7 @@ steps:
- timeout 20m pytest -s -v tests/diffusion/test_diffusion_worker.py
- label: "Diffusion · Model Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -112,7 +125,7 @@ steps:
- timeout 15m pytest -sv tests/diffusion/models/ -m 'core_model and cuda' --run-level "core_model"
- label: "Diffusion · Wan22 Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -126,7 +139,7 @@ steps:
## ISSUE depends on `diffusers` package: https://github.com/huggingface/diffusers/issues/13274
# - label: "Audio Generation Model Test"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
@@ -137,7 +150,7 @@ steps:
# - timeout 20m pytest -s -v tests/e2e/offline_inference/test_stable_audio_expansion.py -m "advanced_model and diffusion and L4" --run-level advanced_model
- label: "Engine Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -149,7 +162,7 @@ steps:
'
# - label: "Omni Model Test Qwen3-Omni"
# agent_pool: mi325_2
# agent_pool: mi300_2
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
@@ -162,7 +175,7 @@ steps:
- group: ":card_index_dividers: E2E Test"
steps:
- label: "Qwen3-TTS E2E Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -173,7 +186,7 @@ steps:
- timeout 30m pytest -s -v tests/e2e/online_serving/test_qwen3_tts_customvoice.py -m "core_model" --run-level "core_model"
- label: "CosyVoice3-TTS E2E Test"
agent_pool: mi325_1
agent_pool: mi300_1
depends_on: amd-build
mirror_hardwares: [amdproduction]
grade: Blocking
@@ -186,7 +199,7 @@ steps:
# TODO: Bagel test on ROCm is very unstable. @tjtanaa
# Need to debug before reneable numerical changes across large PRs
# - label: "Bagel Text2Img Model Test"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
@@ -198,7 +211,7 @@ steps:
# - timeout 30m pytest -s -v tests/e2e/offline_inference/test_bagel.py -m "core_model" --run-level "core_model" -k "rocm"
# - label: "Bagel Img2Img Model Test"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
@@ -210,7 +223,7 @@ steps:
# - timeout 30m pytest -s -v tests/e2e/offline_inference/test_bagel.py -m "core_model" --run-level "core_model" -k "rocm"
# - label: "Bagel Online Serving Test"
# agent_pool: mi325_1
# agent_pool: mi300_1
# depends_on: amd-build
# mirror_hardwares: [amdproduction]
# grade: Blocking
+104 -8
View File
@@ -1,11 +1,65 @@
{# vllm-omni customized version
Based on: https://github.com/vllm-project/ci-infra/blob/main/buildkite/test-template-amd.j2
Last synced: 2025-12-15
Modifications: Removed unused CUDA/NVIDIA logic, keeping only AMD tests
Last synced: 2026-08-04
Modifications: Use the shared MI300 queues and Omni command-passing contract
#}
{% set docker_image_amd = "rocm/vllm-omni:$BUILDKITE_COMMIT" %}
{% set default_working_dir = "/app/vllm-omni" %}
{# MI300 runs tests natively in Kubernetes; Docker-in-Docker is unavailable. #}
{% macro amd_native_k8s_plugin(indent, step) -%}
{{ indent }}plugins:
{{ indent }} - kubernetes:
{{ indent }} podSpecPatch:
{{ indent }} automountServiceAccountToken: false
{{ indent }} securityContext:
{{ indent }} seccompProfile:
{{ indent }} type: RuntimeDefault
{{ indent }} imagePullSecrets:
{{ indent }} - name: docker-config
{{ indent }} containers:
{{ indent }} - name: container-0
{{ indent }} image: {{ docker_image_amd }}
{{ indent }} imagePullPolicy: Always
{{ indent }} securityContext:
{{ indent }} allowPrivilegeEscalation: false
{{ indent }} capabilities:
{{ indent }} add:
{{ indent }} - IPC_LOCK
{{ indent }} resources:
{{ indent }} limits:
{{ indent }} amd.com/gpu: "{{ step.agent_pool[-1:] }}"
{{ indent }} requests:
{{ indent }} amd.com/gpu: "{{ step.agent_pool[-1:] }}"
{{ indent }} volumeMounts:
{{ indent }} - name: devshm
{{ indent }} mountPath: /dev/shm
{{ indent }} env:
{{ indent }} - name: AMD_CI_RUNTIME
{{ indent }} value: native
{{ indent }} - name: NATIVE_CI
{{ indent }} value: "true"
{{ indent }} - name: VLLM_CI_DOCKER_DISABLED
{{ indent }} value: "1"
{{ indent }} - name: VLLM_CI_EXPECTED_GPU_COUNT
{{ indent }} value: "{{ step.agent_pool[-1:] }}"
{{ indent }} - name: HF_HOME
{{ indent }} value: /home/buildkite-agent/huggingface
{{ indent }} - name: MIOPEN_DEBUG_CONV_DIRECT
{{ indent }} value: "0"
{{ indent }} - name: MIOPEN_DEBUG_CONV_GEMM
{{ indent }} value: "0"
{{ indent }} - name: VLLM_ROCM_USE_AITER
{{ indent }} value: "0"
{{ indent }} - name: PYTORCH_ROCM_ARCH
{{ indent }} value: ""
{{ indent }} volumes:
{{ indent }} - name: devshm
{{ indent }} emptyDir:
{{ indent }} medium: Memory
{{ indent }} sizeLimit: 16Gi
{%- endmacro %}
{% if env %}
env:
{% for name in env %}
@@ -53,19 +107,31 @@ steps:
{% if step.agent_pool %}
queue: amd_{{ step.agent_pool }}
{% else %}
queue: amd_mi325_1
queue: amd_mi300_1
{% endif %}
{{ amd_native_k8s_plugin(" ", step) }}
{% set cmd_body = (step.command or (step.commands | join("\n"))) | trim %}
{% set indented_cmd = cmd_body | replace("\n", "\n ") %}
command: bash .buildkite/amd/scripts/run-amd-test.sh
env:
DOCKER_BUILDKIT: "1"
AMD_CI_RUNTIME: "native"
NATIVE_CI: "true"
VLLM_CI_DOCKER_DISABLED: "1"
VLLM_CI_EXPECTED_GPU_COUNT: "{{ step.agent_pool[-1:] }}"
VLLM_CI_REQUIRE_PERSISTENT_HF_CACHE: "1"
HF_HOME: "/home/buildkite-agent/huggingface"
HF_HUB_DOWNLOAD_TIMEOUT: "300"
HF_HUB_ETAG_TIMEOUT: "60"
MIOPEN_DEBUG_CONV_DIRECT: "0"
MIOPEN_DEBUG_CONV_GEMM: "0"
VLLM_ROCM_USE_AITER: "0"
PYTORCH_ROCM_ARCH: ""
{% if step.env %}
{% for name in step.env %}
{{ name }}: "{{ step.env[name] }}"
{% endfor %}
{% endif %}
TEST_COMMAND: |-
TEST_COMMANDS: |-
(command rocm-smi || true) && cd {{ (step.working_dir or default_working_dir) | safe }}
{% if env %}
{% for name in env %}
@@ -82,6 +148,15 @@ steps:
{% endif %}
{{ indented_cmd | safe }}
priority: 100
{% if step.parallelism %}
parallelism: {{ step.parallelism }}
{% endif %}
{% if step.artifact_paths %}
artifact_paths:
{% for path in step.artifact_paths %}
- "{{ path }}"
{% endfor %}
{% endif %}
{% if step.timeout_in_minutes %}
timeout_in_minutes: {{ step.timeout_in_minutes }}
{% endif %}
@@ -100,19 +175,31 @@ steps:
{% if step.agent_pool %}
queue: amd_{{ step.agent_pool }}
{% else %}
queue: amd_mi325_1
queue: amd_mi300_1
{% endif %}
{{ amd_native_k8s_plugin(" ", step) }}
{% set cmd_body = (step.command or (step.commands | join("\n"))) | trim %}
{% set indented_cmd = cmd_body | replace("\n", "\n ") %}
command: bash .buildkite/amd/scripts/run-amd-test.sh
env:
DOCKER_BUILDKIT: "1"
AMD_CI_RUNTIME: "native"
NATIVE_CI: "true"
VLLM_CI_DOCKER_DISABLED: "1"
VLLM_CI_EXPECTED_GPU_COUNT: "{{ step.agent_pool[-1:] }}"
VLLM_CI_REQUIRE_PERSISTENT_HF_CACHE: "1"
HF_HOME: "/home/buildkite-agent/huggingface"
HF_HUB_DOWNLOAD_TIMEOUT: "300"
HF_HUB_ETAG_TIMEOUT: "60"
MIOPEN_DEBUG_CONV_DIRECT: "0"
MIOPEN_DEBUG_CONV_GEMM: "0"
VLLM_ROCM_USE_AITER: "0"
PYTORCH_ROCM_ARCH: ""
{% if step.env %}
{% for name in step.env %}
{{ name }}: "{{ step.env[name] }}"
{% endfor %}
{% endif %}
TEST_COMMAND: |-
TEST_COMMANDS: |-
(command rocm-smi || true) && cd {{ (step.working_dir or default_working_dir) | safe }}
{% if env %}
{% for name in env %}
@@ -129,6 +216,15 @@ steps:
{% endif %}
{{ indented_cmd | safe }}
priority: 100
{% if step.parallelism %}
parallelism: {{ step.parallelism }}
{% endif %}
{% if step.artifact_paths %}
artifact_paths:
{% for path in step.artifact_paths %}
- "{{ path }}"
{% endfor %}
{% endif %}
{% if step.timeout_in_minutes %}
timeout_in_minutes: {{ step.timeout_in_minutes }}
{% endif %}
+8 -1
View File
@@ -8,7 +8,12 @@
# NPU naming: {queue}_{resource_class}
# a2b3_npu_1 — ascend-a2b3, resource_class npu-1 (A2/B3 CI image)
# a2b3_npu_4 — ascend-a2b3, resource_class npu-4
# a3_npu_2 — ascend-a3, resource_class npu-2 (A3 CI image tag …:$BUILDKITE_COMMIT-a3)
# a3_npu_2 — ascend-a3, resource_class npu-2
#
# The ``l4_*`` presets run under the ``docker`` plugin, which does not put
# ``buildkite-agent`` on PATH inside the container the way the ``kubernetes``
# presets do, so they set ``mount-buildkite-agent: true``; without it any step
# calling ``buildkite-agent`` (artifact upload, annotate, meta-data) fails there.
x-npu-k8s-plugins: &npu_k8s_plugins
- kubernetes:
@@ -26,6 +31,7 @@ mirror_hardwares:
image: public.ecr.aws/q9t5s3a7/vllm-ci-test-repo:$BUILDKITE_COMMIT
always-pull: true
propagate-environment: true
mount-buildkite-agent: true
shm-size: "8gb"
environment:
- HF_HOME=/fsx/hf_cache
@@ -41,6 +47,7 @@ mirror_hardwares:
image: public.ecr.aws/q9t5s3a7/vllm-ci-test-repo:$BUILDKITE_COMMIT
always-pull: true
propagate-environment: true
mount-buildkite-agent: true
shm-size: "8gb"
environment:
- HF_HOME=/fsx/hf_cache
+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/env bash
# Run a model's E2E tests once per entry mode as separate coverage runs and upload
# the reports, so per-mode attribution survives (see vllm-project/vllm-omni#5332).
#
# Usage: run_cov_split.sh --model-id <id> [--offline <paths>] [--online <paths>] \
# -- <pytest args...>
#
# --model-id Names the artifacts: coverage-<id>-{offline,online}-<step id>.xml.gz.
# Use the model's directory name under vllm_omni/*/models/.
# --offline Pytest path(s) for the offline half. Repeatable.
# --online Pytest path(s) for the online half. Repeatable.
# -- Everything after this is forwarded verbatim to every pytest run,
# quoting preserved: the job's own -m expression, --run-level, and
# anything else it needs (e.g. --test-config-file).
#
# At least one of --offline/--online is required, so a job with only one mode runs
# just that half. Total runtime is bounded by the step's timeout_in_minutes.
#
# Exits non-zero if any half or the upload failed.
set -uo pipefail
MODEL_ID=""
OFFLINE=()
ONLINE=()
PYTEST_ARGS=()
while [[ $# -gt 0 ]]; do
case "$1" in
--model-id) MODEL_ID="$2"; shift 2 ;;
--offline) OFFLINE+=("$2"); shift 2 ;;
--online) ONLINE+=("$2"); shift 2 ;;
--) shift; PYTEST_ARGS=("$@"); break ;;
*) echo "run_cov_split.sh: unknown argument: $1" >&2; exit 2 ;;
esac
done
if [[ -z "${MODEL_ID}" ]]; then
echo "run_cov_split.sh: missing --model-id" >&2
exit 2
fi
if ((${#OFFLINE[@]} == 0 && ${#ONLINE[@]} == 0)); then
echo "run_cov_split.sh: need at least one of --offline / --online" >&2
exit 2
fi
# Two steps can test the same model, and artifacts are scoped to the build (a
# nightly one carries the ready, merge and nightly tiers at once), so unsuffixed
# reports would share a path -- a glob download then races to rename onto one file.
# Not BUILDKITE_JOB_ID: the step id survives retries, so attempts collapse under
# Buildkite's latest-attempt lookup instead of accumulating. A parallel step would
# need BUILDKITE_PARALLEL_JOB as well; no pilot is one.
REPORT_SUFFIX="${BUILDKITE_STEP_ID:-local}"
OFFLINE_REPORT="coverage-${MODEL_ID}-offline-${REPORT_SUFFIX}.xml"
ONLINE_REPORT="coverage-${MODEL_ID}-online-${REPORT_SUFFIX}.xml"
run_half() {
local mode="$1"
shift
local report="coverage-${MODEL_ID}-${mode}-${REPORT_SUFFIX}.xml"
echo "--- coverage: ${MODEL_ID} ${mode}"
pytest -s -v "$@" "${PYTEST_ARGS[@]}" --cov=vllm_omni --cov-report="xml:${report}"
local status=$?
# Cobertura lists every statement in vllm_omni whether or not it ran, so the
# report is ~7MB no matter how little the job covers. The repetition is what
# dominates it, and gzip takes that to ~400KB.
gzip -9 -f "${report}" || status=1
return "${status}"
}
# Clear both modes, not just the ones being run: the upload glob matches both, so
# a report left by an earlier run would otherwise be published as if the mode it
# belongs to had run this time.
rm -f "${OFFLINE_REPORT}" "${ONLINE_REPORT}" "${OFFLINE_REPORT}.gz" "${ONLINE_REPORT}.gz"
EXIT=0
((${#OFFLINE[@]})) && { run_half offline "${OFFLINE[@]}" || EXIT=1; }
((${#ONLINE[@]})) && { run_half online "${ONLINE[@]}" || EXIT=1; }
buildkite-agent artifact upload "coverage-${MODEL_ID}-*-${REPORT_SUFFIX}.xml.gz" || EXIT=1
exit "${EXIT}"
+44 -90
View File
@@ -76,6 +76,9 @@ steps:
- tests/e2e/online_serving/test_qwen3_tts_customvoice.py
- tests/e2e/offline_inference/test_qwen3_tts_customvoice.py
- vllm_omni/model_executor/models/qwen3_tts/
- vllm_omni/model_executor/models/common/qwen3_code_predictor.py
- vllm_omni/model_executor/models/common/snake_activation.py
- vllm_omni/model_executor/models/common/alias_free_activation.py
- vllm_omni/model_executor/stage_input_processors/qwen3_tts.py
- vllm_omni/deploy/qwen3_tts.yaml
commands:
@@ -92,31 +95,24 @@ steps:
- tests/e2e/online_serving/test_qwen3_tts_base.py
- tests/e2e/offline_inference/test_qwen3_tts_base.py
- vllm_omni/model_executor/models/qwen3_tts/
- vllm_omni/model_executor/models/common/qwen3_code_predictor.py
- vllm_omni/model_executor/models/common/snake_activation.py
- vllm_omni/model_executor/models/common/alias_free_activation.py
- vllm_omni/model_executor/stage_input_processors/qwen3_tts.py
- vllm_omni/deploy/qwen3_tts.yaml
- .buildkite/common/scripts/run_cov_split.sh
- pyproject.toml
# 40 -> 60: the coverage split runs the model twice.
timeout_in_minutes: 60
commands:
- |
timeout 40m bash -c "
export VLLM_LOGGING_LEVEL=DEBUG
export VLLM_ALLOW_LONG_MAX_MODEL_LEN=1
pytest -s -v tests/e2e/online_serving/test_qwen3_tts_base.py tests/e2e/offline_inference/test_qwen3_tts_base.py -m 'advanced_model and cuda' --run-level 'advanced_model'
"
mirror_hardwares: l4_1
- label: "TTS · Higgs-Audio-V3 Test"
source_file_dependencies:
- tests/e2e/online_serving/test_higgs_audio_v3.py
- vllm_omni/model_executor/models/higgs_audio_v3/
- vllm_omni/model_executor/stage_input_processors/higgs_audio_v3.py
- vllm_omni/deploy/higgs_multimodal_qwen3.yaml
commands:
- |
timeout 20m bash -c "
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export VLLM_USE_DEEP_GEMM=0
export VLLM_MOE_USE_DEEP_GEMM=0
pytest -s -v tests/e2e/online_serving/test_higgs_audio_v3.py -m 'advanced_model' --run-level 'advanced_model'
"
export VLLM_LOGGING_LEVEL=DEBUG
export VLLM_ALLOW_LONG_MAX_MODEL_LEN=1
.buildkite/common/scripts/run_cov_split.sh \
--model-id qwen3_tts \
--offline tests/e2e/offline_inference/test_qwen3_tts_base.py \
--online tests/e2e/online_serving/test_qwen3_tts_base.py \
-- -m 'advanced_model and cuda' --run-level 'advanced_model'
mirror_hardwares: l4_1
- label: "Omni · Qwen3-Omni Test"
@@ -124,6 +120,10 @@ steps:
- tests/e2e/offline_inference/test_qwen3_omni.py
- tests/e2e/online_serving/test_qwen3_omni.py
- vllm_omni/model_executor/models/qwen3_omni/
- vllm_omni/model_executor/models/common/qwen3_code_predictor.py
- vllm_omni/model_executor/models/common/snake_activation.py
- vllm_omni/model_executor/models/qwen2_5_omni/qwen2_5_omni_thinker.py
- vllm_omni/model_executor/models/qwen3_tts/cuda_graph_decoder_wrapper.py
- vllm_omni/model_executor/stage_input_processors/qwen3_omni.py
- vllm_omni/deploy/qwen3_omni_moe.yaml
timeout_in_minutes: 50
@@ -135,10 +135,20 @@ steps:
source_file_dependencies:
- tests/e2e/offline_inference/test_minicpmo_4_5.py
- tests/e2e/online_serving/test_minicpmo_4_5.py
- vllm_omni/model_executor/models/minicpmo_4_5/
- vllm_omni/model_executor/models/step_audio2/
- vllm_omni/model_executor/models/cosyvoice3/code2wav_core/
- vllm_omni/model_executor/models/cosyvoice3/utils.py
- vllm_omni/model_executor/stage_input_processors/minicpmo_4_5_omni.py
- vllm_omni/deploy/minicpmo_4_5.yaml
timeout_in_minutes: 50
commands:
- pytest -s -v tests/e2e/offline_inference/test_minicpmo_4_5.py tests/e2e/online_serving/test_minicpmo_4_5.py -m 'advanced_model and cuda' --run-level 'advanced_model'
# h100_2, not h100_1: advanced_model asserts transcribe every audio
# response with Whisper, and tests/helpers/media.py only uses an
# accelerator for Whisper when a spare GPU exists. On a single card it
# grades on CPU: ~8-10 min per clip vs ~30 s, which alone overruns the
# 50-minute job timeout (build 2956).
mirror_hardwares: h100_2
- label: "Omni · MiniCPM-o 4.5 Duplex Test"
@@ -148,65 +158,38 @@ steps:
- tests/e2e/online_serving/test_minicpmo_4_5_duplex.py
- tests/e2e/online_serving/test_minicpmo_4_5_duplex_expansion.py
- tests/e2e/online_serving/test_minicpmo_realtime_duplex_drivers.py
- tests/e2e/online_serving/minicpmo_realtime_duplex_scenarios.py
- tests/e2e/online_serving/helpers/minicpmo_realtime_duplex_scenarios.py
- tests/e2e/online_serving/run_minicpmo_realtime_duplex_multi_session.py
- tests/e2e/online_serving/run_minicpmo_realtime_duplex_soft_interrupt.py
- tests/helpers/minicpmo_4_5_duplex.py
- vllm_omni/deploy/minicpmo_4_5.yaml
- tests/e2e/online_serving/helpers/minicpmo_4_5_duplex.py
- vllm_omni/deploy/minicpmo_4_5_duplex.yaml
- vllm_omni/experimental/fullduplex/
- vllm_omni/model_executor/models/minicpmo_4_5/
- vllm_omni/model_executor/models/step_audio2/
- vllm_omni/model_executor/models/cosyvoice3/code2wav_core/
- vllm_omni/model_executor/models/cosyvoice3/utils.py
- vllm_omni/model_executor/stage_input_processors/minicpmo_4_5_omni.py
- vllm_omni/core/sched/
- vllm_omni/outputs/multimodal_accumulation.py
- vllm_omni/engine/stage_init_utils.py
- vllm_omni/engine/async_omni_engine.py
- vllm_omni/engine/orchestrator.py
- vllm_omni/entrypoints/cli/serve.py
- vllm_omni/entrypoints/openai/api_server.py
- vllm_omni/entrypoints/openai/duplex_capability.py
- vllm_omni/config/stage_config.py
timeout_in_minutes: 50
commands:
- pytest -s -v tests/e2e/online_serving/test_minicpmo_4_5_duplex.py -m 'advanced_model and cuda' --run-level 'advanced_model'
mirror_hardwares: h100_2
- label: "TTS · VoxCPM2 Test"
source_file_dependencies:
- tests/e2e/offline_inference/test_voxcpm2_tts.py
- tests/e2e/online_serving/test_voxcpm2_tts.py
- vllm_omni/model_executor/models/voxcpm2/
- vllm_omni/deploy/voxcpm2.yaml
timeout_in_minutes: 30
commands:
- |
timeout 30m bash -c "
export VLLM_LOGGING_LEVEL=DEBUG
export VLLM_WORKER_MULTIPROC_METHOD=spawn
pytest -s -v tests/e2e/offline_inference/test_voxcpm2_tts.py tests/e2e/online_serving/test_voxcpm2_tts.py -m 'advanced_model and cuda' --run-level 'advanced_model'
"
mirror_hardwares: l4_1
- label: "Diffusion · Qwen Image Edit Test"
source_file_dependencies:
- tests/e2e/online_serving/test_qwen_image_edit.py
- vllm_omni/diffusion/models/qwen_image/
timeout_in_minutes: 20
commands:
- pytest -s -v tests/e2e/online_serving/test_qwen_image_edit.py -m 'advanced_model and cuda' --run-level 'advanced_model'
mirror_hardwares: h100_1
- label: "Diffusion · Bagel Test"
source_file_dependencies:
- tests/e2e/offline_inference/test_bagel.py
- tests/e2e/online_serving/test_bagel.py
- vllm_omni/model_executor/models/bagel/
- vllm_omni/diffusion/models/bagel/
- vllm_omni/model_executor/stage_input_processors/bagel.py
- vllm_omni/deploy/bagel.yaml
timeout_in_minutes: 20
commands:
- pytest -s -v tests/e2e/offline_inference/test_bagel.py tests/e2e/online_serving/test_bagel.py -m 'advanced_model and cuda' --run-level 'advanced_model'
mirror_hardwares: h100_1
- label: "Diffusion · Qwen Image Test"
source_file_dependencies:
- tests/e2e/online_serving/test_qwen_image.py
- vllm_omni/diffusion/models/qwen_image/
- vllm_omni/diffusion/models/dmd2/
- vllm_omni/diffusion/distributed/autoencoders/autoencoder_kl_qwenimage.py
commands:
- |
timeout 40m bash -c '
@@ -215,23 +198,12 @@ steps:
'
mirror_hardwares: h100_1
- label: "Diffusion · Qwen Image Layered Test"
source_file_dependencies:
- tests/e2e/online_serving/test_qwen_image_layered.py
- vllm_omni/diffusion/models/qwen_image/
commands:
- |
timeout 40m bash -c "
export VLLM_IMAGE_FETCH_TIMEOUT=60
pytest -s -v tests/e2e/online_serving/test_qwen_image_layered.py -m 'advanced_model and cuda' --run-level 'advanced_model'
"
mirror_hardwares: h100_1
- label: "Diffusion · Wan22 Test"
source_file_dependencies:
- tests/e2e/offline_inference/test_wan22_t2v.py
- tests/e2e/online_serving/test_wan22_t2v.py
- vllm_omni/diffusion/models/wan2_2/
- vllm_omni/diffusion/models/dmd2/
commands:
- |
timeout 40m bash -c "
@@ -239,21 +211,3 @@ steps:
pytest -s -v tests/e2e/offline_inference/test_wan22_t2v.py tests/e2e/online_serving/test_wan22_t2v.py -m 'advanced_model and cuda and diffusion' --run-level 'advanced_model'
"
mirror_hardwares: h100_1
- label: "Diffusion · Z Image Test"
source_file_dependencies:
- tests/e2e/offline_inference/test_z_image.py
- tests/e2e/online_serving/test_z_image.py
- vllm_omni/diffusion/models/z_image/
timeout_in_minutes: 30
commands:
- pytest -s -v tests/e2e/offline_inference/test_z_image.py tests/e2e/online_serving/test_z_image.py -m 'advanced_model and cuda and diffusion' --run-level 'advanced_model'
mirror_hardwares: l4_1
- label: "Diffusion · FLUX.2 Klein Test"
source_file_dependencies:
- tests/e2e/offline_inference/test_flux2_klein.py
- vllm_omni/diffusion/models/flux2_klein/
timeout_in_minutes: 30
commands:
- pytest -s -v tests/e2e/offline_inference/test_flux2_klein.py -m 'advanced_model and cuda and diffusion' --run-level 'advanced_model'
mirror_hardwares: l4_1
+69 -11
View File
@@ -22,7 +22,7 @@ steps:
timeout_in_minutes: 50
commands:
- pytest -s -v tests/e2e/online_serving/test_minicpmo_4_5_duplex_expansion.py -m "full_model and cuda and H100 and omni" --run-level "full_model"
mirror_hardwares: h100_2
mirror_hardwares: h100_1
- label: ":full_moon: Omni · Doc Test with L4"
timeout_in_minutes: 90
@@ -50,6 +50,19 @@ steps:
exit $$EXIT
mirror_hardwares: h100_2
- label: ":full_moon: Omni · MiniCPM-o 4.5 · Accuracy Test"
timeout_in_minutes: 180
commands:
- export SEED_TTS_WER_EVAL=1
- export SEED_TTS_EVAL_DEVICE=cuda:1
- |
set +e
pytest -s -v tests/e2e/accuracy/minicpmo_4_5/test_minicpmo_4_5.py -m "full_model and cuda" --run-level full_model
EXIT=$$?
buildkite-agent artifact upload "tests/e2e/accuracy/minicpmo_4_5/results/*.json"
exit $$EXIT
mirror_hardwares: h100_2
- label: ":full_moon: Omni · Perf Test · No Async Chunk"
key: nightly-omni-performance-no-async-chunk
timeout_in_minutes: 300
@@ -102,6 +115,32 @@ steps:
exit $$EXIT
mirror_hardwares: h100_3
- label: ":full_moon: Omni · MiniCPM-o 4.5 · Perf Test"
key: nightly-omni-performance-minicpmo-4-5
timeout_in_minutes: 180
commands:
- export BENCHMARK_DIR=tests/dfx/perf/results
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_benchmark.py --test-config-file tests/dfx/perf/tests/test_minicpmo_4_5.json
EXIT=$$?
buildkite-agent artifact upload "tests/dfx/perf/results/*.json"
exit $$EXIT
mirror_hardwares: h100_1
- label: ":full_moon: Omni · MiniCPM-o 4.5 · Duplex Seed-TTS Perf Test"
key: nightly-omni-performance-minicpmo-4-5-duplex-seed-tts
timeout_in_minutes: 180
commands:
- export BENCHMARK_DIR=tests/dfx/perf/results
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_benchmark.py --test-config-file tests/dfx/perf/tests/test_minicpmo_4_5_duplex_seed_tts.json
EXIT=$$?
buildkite-agent artifact upload "tests/dfx/perf/results/*.json"
exit $$EXIT
mirror_hardwares: h100_1
- label: ":full_moon: Omni · Multi-Replica Startup Test with 4x H100"
timeout_in_minutes: 45
commands:
@@ -306,7 +345,7 @@ steps:
commands:
- export DIFFUSION_BENCHMARK_DIR=tests/dfx/perf/results
- export DIFFUSION_ATTENTION_BACKEND=FLASH_ATTN
- export CACHE_DIT_VERSION=1.3.0
- export CACHE_DIT_VERSION=1.5.0
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_diffusion_benchmark.py --test-config-file tests/dfx/perf/tests/test_qwen_image_vllm_omni.json
@@ -322,7 +361,7 @@ steps:
commands:
- export DIFFUSION_BENCHMARK_DIR=tests/dfx/perf/results
- export DIFFUSION_ATTENTION_BACKEND=FLASH_ATTN
- export CACHE_DIT_VERSION=1.3.0
- export CACHE_DIT_VERSION=1.5.0
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_diffusion_benchmark.py --test-config-file tests/dfx/perf/tests/test_qwen_image_edit_vllm_omni.json
@@ -338,7 +377,7 @@ steps:
commands:
- export DIFFUSION_BENCHMARK_DIR=tests/dfx/perf/results
- export DIFFUSION_ATTENTION_BACKEND=FLASH_ATTN
- export CACHE_DIT_VERSION=1.3.0
- export CACHE_DIT_VERSION=1.5.0
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_diffusion_benchmark.py --test-config-file tests/dfx/perf/tests/test_qwen_image_edit_2511_vllm_omni.json
@@ -354,7 +393,7 @@ steps:
commands:
- export DIFFUSION_BENCHMARK_DIR=tests/dfx/perf/results
- export DIFFUSION_ATTENTION_BACKEND=FLASH_ATTN
- export CACHE_DIT_VERSION=1.3.0
- export CACHE_DIT_VERSION=1.5.0
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_diffusion_benchmark.py --test-config-file tests/dfx/perf/tests/test_qwen_image_layered_vllm_omni.json
@@ -370,7 +409,7 @@ steps:
commands:
- export DIFFUSION_BENCHMARK_DIR=tests/dfx/perf/results
- export DIFFUSION_ATTENTION_BACKEND=FLASH_ATTN
- export CACHE_DIT_VERSION=1.3.0
- export CACHE_DIT_VERSION=1.5.0
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_diffusion_benchmark.py --test-config-file tests/dfx/perf/tests/test_bagel_vllm_omni.json
@@ -404,7 +443,7 @@ steps:
- label: ":full_moon: Diffusion X2V · LingBot Video MoE Function Test"
timeout_in_minutes: 90
commands:
- pytest -s -v tests/e2e/online_serving/test_lingbot_video_moe.py -m "full_model and cuda" --run-level "full_model"
- pytest -s -v tests/e2e/online_serving/test_lingbot_video_moe.py -k "video_generation" -m "full_model and cuda" --run-level "full_model"
mirror_hardwares: h100_1
- label: ":full_moon: Diffusion X2V · Doc Test"
@@ -417,9 +456,15 @@ steps:
timeout_in_minutes: 90
commands:
- pytest -s -v tests/e2e/offline_inference/test_wan22_autoround_w4a16_expansion.py -m "full_model and cuda" --run-level "full_model"
- pytest -s -v tests/e2e/online_serving/test_wan_2_1_vace_expansion.py tests/e2e/online_serving/test_ltx2_expansion.py -m "full_model and cuda" --run-level "full_model"
- pytest -s -v tests/e2e/online_serving/test_wan_2_1_vace_expansion.py tests/e2e/online_serving/test_ltx.py -m "full_model and cuda" --run-level "full_model"
mirror_hardwares: h100_2
- label: ":full_moon: Diffusion X2V · LTX-2.5 Online Test"
timeout_in_minutes: 60
commands:
- pytest -s -v tests/e2e/online_serving/test_ltx25.py -m "full_model and cuda" --run-level "full_model"
mirror_hardwares: h100_1
- label: ":full_moon: Diffusion X2V · Wan2.2 Accuracy Test"
timeout_in_minutes: 180
commands:
@@ -427,10 +472,10 @@ steps:
- pytest -s -v tests/e2e/accuracy/test_diffusers_backend_similarity.py -k '2v_matches_diffusers' -m full_model --run-level full_model
mirror_hardwares: h100_2
- label: ":full_moon: Diffusion X2V · MiniMax H3 T2VA Accuracy Test"
- label: ":full_moon: Diffusion X2V · MiniMax H3 I2VA/Ref2VA Accuracy Test"
timeout_in_minutes: 180
commands:
- pytest -s -v tests/e2e/accuracy/minimax_h3/test_minimax_h3_t2va_similarity.py -m full_model --run-level full_model
- pytest -s -v tests/e2e/accuracy/minimax_h3/test_minimax_h3_i2va_ref2va_similarity.py -m full_model --run-level full_model
mirror_hardwares: h100_4
- label: ":full_moon: Diffusion X2V · Other Accuracy Test"
@@ -438,10 +483,23 @@ steps:
commands:
- pytest -s -v tests/e2e/accuracy/hunyuanvideo15_t2v/test_hunyuanvideo15_t2v_video_similarity.py -m full_model --run-level full_model
- pytest -s -v tests/e2e/accuracy/hunyuanvideo15_i2v/test_hunyuanvideo15_i2v_video_similarity.py -m full_model --run-level full_model
- pytest -s -v 'tests/e2e/accuracy/ltx/test_ltx_official_similarity.py::test_ltx_one_stage_matches_official[ltx2_3_i2v]' -m full_model --run-level full_model
- pytest -s -v tests/e2e/accuracy/test_video_streaming_output_similarity.py -m full_model --run-level full_model
mirror_hardwares: h100_2
- label: ":full_moon: Diffusion X2V · LTX Accuracy Test"
timeout_in_minutes: 180
commands:
- pytest -s -v 'tests/e2e/accuracy/ltx/test_ltx_official_similarity.py::test_ltx_matches_official[ltx2_3_i2v]' -m full_model --run-level full_model
- pytest -s -v 'tests/e2e/accuracy/ltx/test_ltx_official_similarity.py::test_ltx_matches_official[ltx23_two_stage_layer_fused_i2v]' -m full_model --run-level full_model
mirror_hardwares: h100_1
- label: ":full_moon: Diffusion X2V · LTX-2.5 Official Parity Test"
timeout_in_minutes: 180
commands:
- pytest -s -v tests/e2e/accuracy/ltx/test_ltx25_official_similarity.py::test_ltx25_distilled_two_stage_matches_official -m full_model --run-level full_model
- pytest -s -v tests/e2e/accuracy/ltx/test_ltx25_official_similarity.py::test_ltx25_full_matches_official -m full_model --run-level full_model
mirror_hardwares: h100_1
- label: ":full_moon: Diffusion X2V · Perf Test"
key: nightly-diffusion-x2v-performance
timeout_in_minutes: 180
+63 -71
View File
@@ -128,6 +128,21 @@ steps:
image: public.ecr.aws/q9t5s3a7/vllm-ci-test-repo:$BUILDKITE_COMMIT
always-pull: true
propagate-environment: true
# vLLM 0.27 added a pre-flight capacity check in
# distributed/device_communicators/shm_broadcast.py. Without this
# the container gets Docker's 64 MiB default and every test in
# this step dies at engine start with
# RuntimeError: Insufficient space in /dev/shm:
# 240 MiB required, 64 MiB available
# (9 failed in 8.7s on build #2949). vLLM 0.26 had no such check
# and allocated regardless, so this step passed on main while
# being under-provisioned the whole time — 0.27 turned a silent
# risk into an explicit error.
#
# This is the only inline docker plugin block in .buildkite/cuda/;
# every other step inherits common/ci_mirror_hardwares.yml, which
# already sets 8gb. Matching that rather than inventing a value.
shm-size: "8gb"
environment:
- "HF_HOME=/fsx/hf_cache"
volumes:
@@ -154,6 +169,10 @@ steps:
source_file_dependencies:
- tests/e2e/online_serving/test_qwen3_omni.py
- vllm_omni/model_executor/models/qwen3_omni/
- vllm_omni/model_executor/models/common/qwen3_code_predictor.py
- vllm_omni/model_executor/models/common/snake_activation.py
- vllm_omni/model_executor/models/qwen2_5_omni/qwen2_5_omni_thinker.py
- vllm_omni/model_executor/models/qwen3_tts/cuda_graph_decoder_wrapper.py
- vllm_omni/model_executor/stage_input_processors/qwen3_omni.py
- vllm_omni/deploy/qwen3_omni_moe.yaml
commands:
@@ -166,24 +185,34 @@ steps:
- label: "Omni · MiniCPM-o 4.5 Offline Test"
source_file_dependencies:
- tests/e2e/offline_inference/test_minicpmo_4_5.py
- vllm_omni/model_executor/models/minicpmo_4_5/
- vllm_omni/model_executor/models/step_audio2/
- vllm_omni/model_executor/models/cosyvoice3/code2wav_core/
- vllm_omni/model_executor/models/cosyvoice3/utils.py
- vllm_omni/model_executor/stage_input_processors/minicpmo_4_5_omni.py
- vllm_omni/deploy/minicpmo_4_5.yaml
commands:
- |
timeout 20m bash -c "
pytest -s -v tests/e2e/offline_inference/test_minicpmo_4_5.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: h100_2
mirror_hardwares: h100_1
- label: "Omni · MiniCPM-o 4.5 Online Test"
source_file_dependencies:
- tests/e2e/online_serving/test_minicpmo_4_5.py
- vllm_omni/model_executor/models/minicpmo_4_5/
- vllm_omni/model_executor/models/step_audio2/
- vllm_omni/model_executor/models/cosyvoice3/code2wav_core/
- vllm_omni/model_executor/models/cosyvoice3/utils.py
- vllm_omni/model_executor/stage_input_processors/minicpmo_4_5_omni.py
- vllm_omni/deploy/minicpmo_4_5.yaml
commands:
- |
timeout 20m bash -c "
pytest -s -v tests/e2e/online_serving/test_minicpmo_4_5.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: h100_2
mirror_hardwares: h100_1
- label: "Omni · MiniCPM-o 4.5 Duplex Test"
source_file_dependencies:
@@ -192,45 +221,53 @@ steps:
- tests/e2e/online_serving/test_minicpmo_4_5_duplex.py
- tests/e2e/online_serving/test_minicpmo_4_5_duplex_expansion.py
- tests/e2e/online_serving/test_minicpmo_realtime_duplex_drivers.py
- tests/e2e/online_serving/minicpmo_realtime_duplex_scenarios.py
- tests/e2e/online_serving/helpers/minicpmo_realtime_duplex_scenarios.py
- tests/e2e/online_serving/run_minicpmo_realtime_duplex_multi_session.py
- tests/e2e/online_serving/run_minicpmo_realtime_duplex_soft_interrupt.py
- tests/helpers/minicpmo_4_5_duplex.py
- vllm_omni/deploy/minicpmo_4_5.yaml
- tests/e2e/online_serving/helpers/minicpmo_4_5_duplex.py
- vllm_omni/deploy/minicpmo_4_5_duplex.yaml
- vllm_omni/experimental/fullduplex/
- vllm_omni/model_executor/models/minicpmo_4_5/
- vllm_omni/model_executor/models/step_audio2/
- vllm_omni/model_executor/models/cosyvoice3/code2wav_core/
- vllm_omni/model_executor/models/cosyvoice3/utils.py
- vllm_omni/model_executor/stage_input_processors/minicpmo_4_5_omni.py
- vllm_omni/core/sched/
- vllm_omni/outputs/multimodal_accumulation.py
- vllm_omni/engine/stage_init_utils.py
- vllm_omni/engine/async_omni_engine.py
- vllm_omni/engine/orchestrator.py
- vllm_omni/entrypoints/cli/serve.py
- vllm_omni/entrypoints/openai/api_server.py
- vllm_omni/entrypoints/openai/duplex_capability.py
- vllm_omni/config/stage_config.py
commands:
- |
timeout 20m bash -c "
pytest -s -v tests/e2e/online_serving/test_minicpmo_4_5_duplex.py -m 'core_model and cuda' --run-level 'core_model'
"
mirror_hardwares: h100_2
mirror_hardwares: h100_1
- label: "TTS · VoxCPM2 Test"
- label: "Omni · MiniCPM-o 4.5 Perf Test"
timeout_in_minutes: 60
source_file_dependencies:
- tests/e2e/online_serving/test_voxcpm2_tts.py
- vllm_omni/model_executor/models/voxcpm2/
- vllm_omni/deploy/voxcpm2.yaml
timeout_in_minutes: 30
- tests/dfx/perf/tests/test_minicpmo_4_5_ready.json
- vllm_omni/deploy/minicpmo_4_5.yaml
- vllm_omni/model_executor/models/minicpmo_4_5/
- vllm_omni/model_executor/stage_input_processors/minicpmo_4_5_omni.py
commands:
- |
timeout 30m bash -c "
export VLLM_LOGGING_LEVEL=DEBUG
export VLLM_WORKER_MULTIPROC_METHOD=spawn
pytest -s -v tests/e2e/online_serving/test_voxcpm2_tts.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: l4_1
- export BENCHMARK_DIR=tests/dfx/perf/results
- pytest -s -v tests/dfx/perf/scripts/run_benchmark.py --test-config-file tests/dfx/perf/tests/test_minicpmo_4_5_ready.json -m 'core_model and cuda'
mirror_hardwares: h100_1
- label: "TTS · Qwen3-TTS CustomVoice Test"
source_file_dependencies:
- tests/e2e/online_serving/test_qwen3_tts_customvoice.py
- vllm_omni/model_executor/models/qwen3_tts/
- vllm_omni/model_executor/models/common/qwen3_code_predictor.py
- vllm_omni/model_executor/models/common/snake_activation.py
- vllm_omni/model_executor/models/common/alias_free_activation.py
- vllm_omni/model_executor/stage_input_processors/qwen3_tts.py
- vllm_omni/deploy/qwen3_tts.yaml
commands:
@@ -245,6 +282,9 @@ steps:
source_file_dependencies:
- tests/e2e/online_serving/test_qwen3_tts_base.py
- vllm_omni/model_executor/models/qwen3_tts/
- vllm_omni/model_executor/models/common/qwen3_code_predictor.py
- vllm_omni/model_executor/models/common/snake_activation.py
- vllm_omni/model_executor/models/common/alias_free_activation.py
- vllm_omni/model_executor/stage_input_processors/qwen3_tts.py
- vllm_omni/deploy/qwen3_tts.yaml
commands:
@@ -257,52 +297,11 @@ steps:
"
mirror_hardwares: l4_1
- label: "TTS · Higgs-Audio-V3 Test"
source_file_dependencies:
- tests/e2e/online_serving/test_higgs_audio_v3.py
- vllm_omni/model_executor/models/higgs_audio_v3/
- vllm_omni/model_executor/stage_input_processors/higgs_audio_v3.py
- vllm_omni/deploy/higgs_multimodal_qwen3.yaml
commands:
- |
timeout 20m bash -c "
export VLLM_WORKER_MULTIPROC_METHOD=spawn
export VLLM_USE_DEEP_GEMM=0
export VLLM_MOE_USE_DEEP_GEMM=0
pytest -s -v tests/e2e/online_serving/test_higgs_audio_v3.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: l4_1
- label: "Diffusion · Qwen Image Edit Test"
source_file_dependencies:
- tests/e2e/online_serving/test_qwen_image_edit.py
- vllm_omni/diffusion/models/qwen_image/
commands:
- |
timeout 20m bash -c "
pytest -s -v tests/e2e/online_serving/test_qwen_image_edit.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: h100_1
- label: "Diffusion · Bagel Test"
source_file_dependencies:
- tests/e2e/online_serving/test_bagel.py
- vllm_omni/model_executor/models/bagel/
- vllm_omni/diffusion/models/bagel/
- vllm_omni/model_executor/stage_input_processors/bagel.py
- vllm_omni/deploy/bagel.yaml
commands:
- |
timeout 40m bash -c "
export VLLM_IMAGE_FETCH_TIMEOUT=60
pytest -s -v tests/e2e/online_serving/test_bagel.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: h100_1
- label: "Diffusion · Wan22 Test"
source_file_dependencies:
- tests/e2e/online_serving/test_wan22_t2v.py
- vllm_omni/diffusion/models/wan2_2/
- vllm_omni/diffusion/models/dmd2/
commands:
- |
timeout 40m bash -c "
@@ -315,6 +314,9 @@ steps:
source_file_dependencies:
- tests/e2e/online_serving/test_cosmos3.py
- vllm_omni/diffusion/models/cosmos3/
- vllm_omni/diffusion/distributed/autoencoders/autoencoder_kl_wan.py
- vllm_omni/experimental/world_models/
- vllm_omni/model_extras/cosmos3.py
commands:
- |
timeout 40m bash -c "
@@ -327,6 +329,8 @@ steps:
source_file_dependencies:
- tests/e2e/online_serving/test_qwen_image.py
- vllm_omni/diffusion/models/qwen_image/
- vllm_omni/diffusion/models/dmd2/
- vllm_omni/diffusion/distributed/autoencoders/autoencoder_kl_qwenimage.py
commands:
- |
timeout 40m bash -c "
@@ -334,15 +338,3 @@ steps:
pytest -s -v tests/e2e/online_serving/test_qwen_image.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: h100_1
- label: "Diffusion · Qwen Image Layered Test"
source_file_dependencies:
- tests/e2e/online_serving/test_qwen_image_layered.py
- vllm_omni/diffusion/models/qwen_image/
commands:
- |
timeout 40m bash -c "
export VLLM_IMAGE_FETCH_TIMEOUT=60
pytest -s -v tests/e2e/online_serving/test_qwen_image_layered.py -m 'core_model' --run-level 'core_model'
"
mirror_hardwares: h100_1
+16
View File
@@ -108,6 +108,22 @@ steps:
--run-level "full_model"
mirror_hardwares: h100_1
# Own step: the image has no NanoCodec, so this file import-skips out of
# the mark-selected TTS steps above. The overrides keep nemo_toolkit[tts]
# from downgrading transformers; see
# examples/offline_inference/text_to_speech/README.md.
- label: "TTS · Gepard-1.0 · L4"
timeout_in_minutes: 60
commands:
- export VLLM_ALLOW_LONG_MAX_MODEL_LEN="1"
- printf '%s\n' "transformers>=5.5.3" "huggingface-hub>=1.0" > /tmp/gepard-overrides.txt
- uv pip install --python "$(python3 -c 'import sys; print(sys.executable)')" "nemo_toolkit[tts]==2.7.3" --overrides /tmp/gepard-overrides.txt
- >-
pytest -s -v tests/e2e/offline_inference/test_gepard_tts.py
-m "tts and cuda"
--run-level "full_model"
mirror_hardwares: l4_1
- label: "Diffusion · L4"
timeout_in_minutes: 60
commands:
+1 -1
View File
@@ -10,7 +10,7 @@ steps:
DOCKER_BUILDKIT: "1"
# Buildkite will automatically replace this with the actual commit hash
VLLM_IMAGE_TAG: "${BUILDKITE_COMMIT}"
VLLM_VERSION: "v0.26.0"
VLLM_VERSION: "v0.27.0"
priority: 100
timeout_in_minutes: 60
soft_fail: false
+20 -4
View File
@@ -34,8 +34,23 @@ docker_build() {
docker build "${out[@]}" "$@" -f docker/Dockerfile.xpu .
}
build_vllm_base() (
local vllm_source_dir
vllm_source_dir=$(mktemp -d)
trap 'rm -rf "${vllm_source_dir}"' EXIT
git clone --depth 1 --branch "${VLLM_VERSION}" \
https://github.com/vllm-project/vllm "${vllm_source_dir}"
local out=("${export_args[@]/'{{IMAGE}}'/${base_image_name}}")
docker build "${out[@]}" \
--target vllm-openai \
-f "${vllm_source_dir}/docker/Dockerfile.xpu" \
"${vllm_source_dir}"
)
if [ -z "$(docker images -q "${base_image_name}")" ]; then
docker_build "${base_image_name}" --target vllm-base --build-arg "VLLM_VERSION=${VLLM_VERSION}"
build_vllm_base
fi
# Try building the docker image
@@ -72,8 +87,9 @@ time timeout -k 30 30m docker run \
echo $ZE_AFFINITY_MASK
pip install tblib==3.1.0
cd /workspace/vllm-omni
pytest -v -s -m "core_model and xpu and B60"
XPU_TEST_PATHS="tests/diffusion tests/dfx tests/e2e"
pytest -v -s $XPU_TEST_PATHS -m "core_model and xpu and B60"
pytest -v -s tests/diffusion/quantization/test_mxfp8_config.py
pytest -v -s -m "advanced_model and xpu and B60"
pytest -v -s -m "omni and xpu and B60"
pytest -v -s $XPU_TEST_PATHS -m "advanced_model and xpu and B60"
pytest -v -s $XPU_TEST_PATHS -m "omni and xpu and B60"
'
+30 -2
View File
@@ -39,7 +39,7 @@ steps:
EXIT=$$?
buildkite-agent artifact upload "tests/dfx/perf/results/*.json"
exit $$EXIT
- label: ":robot: Omni · MiniCPM-o 4.5 Test"
- label: ":full_moon: Omni · MiniCPM-o 4.5 Test"
mirror_hardwares: a3_npu_2
env:
VLLM_WORKER_MULTIPROC_METHOD: spawn
@@ -47,6 +47,34 @@ steps:
HF_TOKEN: "${HF_TOKEN}"
commands:
- pytest -s -v tests/e2e/offline_inference/test_minicpmo_4_5.py tests/e2e/online_serving/test_minicpmo_4_5.py tests/e2e/online_serving/test_minicpmo_4_5_expansion.py -m 'full_model' --run-level 'full_model'
- label: ":full_moon: Omni · MiniCPM-o 4.5 · Duplex Test"
timeout_in_minutes: 180
mirror_hardwares: a3_npu_2
env:
VLLM_WORKER_MULTIPROC_METHOD: spawn
VLLM_ALLOW_LONG_MAX_MODEL_LEN: "1"
HF_TOKEN: "${HF_TOKEN}"
commands:
- >-
pytest -s -v
tests/e2e/online_serving/test_minicpmo_4_5_duplex.py
tests/e2e/online_serving/test_minicpmo_4_5_duplex_expansion.py
-m "npu and A3 and omni"
--run-level full_model
- label: ":full_moon: Omni · MiniCPM-o 4.5 · Accuracy Test"
timeout_in_minutes: 180
mirror_hardwares: a3_npu_2
env:
VLLM_WORKER_MULTIPROC_METHOD: spawn
VLLM_ALLOW_LONG_MAX_MODEL_LEN: "1"
HF_TOKEN: "${HF_TOKEN}"
commands:
- |
set +e
pytest -s -v tests/e2e/accuracy/minicpmo_4_5/test_minicpmo_4_5.py -m "full_model and npu and A3" --run-level full_model
EXIT=$$?
buildkite-agent artifact upload "tests/e2e/accuracy/minicpmo_4_5/results/*.json"
exit $$EXIT
- group: ":card_index_dividers: TTS Model Test"
key: nightly-tts-test-group
depends_on: upload-nightly-pipeline
@@ -87,7 +115,7 @@ steps:
DIFFUSION_ATTENTION_BACKEND: TORCH_SDPA
commands:
- export DIFFUSION_BENCHMARK_DIR=tests/dfx/perf/results
- export CACHE_DIT_VERSION=1.3.0
- export CACHE_DIT_VERSION=1.5.0
- |
set +e
pytest -s -v tests/dfx/perf/scripts/run_diffusion_benchmark.py -m npu --test-config-file tests/dfx/perf/tests/test_qwen_image_edit_2511_vllm_omni.json
+19 -12
View File
@@ -3,22 +3,29 @@ steps:
key: ready-omni-group
depends_on: upload-ready-pipeline
steps:
- label: ":robot: Omni · MiniCPM-o 4.5 Test"
agents:
queue: "ascend-a3"
resource_class: "npu-2"
image: "swr.cn-southwest-2.myhuaweicloud.com/modelfoundry/vllm-omni-ci-npu:${BUILDKITE_COMMIT}-a3"
plugins:
- kubernetes:
podSpecPatch:
imagePullSecrets:
- name: swr-secret
- label: "Omni · MiniCPM-o 4.5 Test"
mirror_hardwares: a3_npu_2
env:
VLLM_WORKER_MULTIPROC_METHOD: spawn
VLLM_ALLOW_LONG_MAX_MODEL_LEN: "1"
HF_TOKEN: "${HF_TOKEN}"
commands:
- pytest -s -v tests/e2e/offline_inference/test_minicpmo_4_5.py tests/e2e/online_serving/test_minicpmo_4_5.py -m 'core_model' --run-level 'core_model'
- pytest -s -v tests/e2e/offline_inference/test_minicpmo_4_5.py tests/e2e/online_serving/test_minicpmo_4_5.py -m 'core_model and npu and A3 and omni' --run-level 'core_model'
- label: "Omni · MiniCPM-o 4.5 Duplex Test"
mirror_hardwares: a3_npu_2
env:
VLLM_WORKER_MULTIPROC_METHOD: spawn
VLLM_ALLOW_LONG_MAX_MODEL_LEN: "1"
commands:
- pytest -s -v tests/e2e/online_serving/test_minicpmo_4_5_duplex.py -m 'core_model and npu and A3 and omni' --run-level 'core_model'
- label: "Omni · MiniCPM-o 4.5 Perf Test"
timeout_in_minutes: 60
mirror_hardwares: a3_npu_2
env:
VLLM_WORKER_MULTIPROC_METHOD: spawn
VLLM_ALLOW_LONG_MAX_MODEL_LEN: "1"
commands:
- export BENCHMARK_DIR=tests/dfx/perf/results
- pytest -s -v tests/dfx/perf/scripts/run_benchmark.py --test-config-file tests/dfx/perf/tests/test_minicpmo_4_5_ready.json -m 'core_model and npu and A3 and omni'
- group: ":card_index_dividers: TTS Model Test"
key: ready-tts-group
+23 -1
View File
@@ -40,9 +40,11 @@ steps:
commands:
- "bash .buildkite/release/scripts/publish-release-wheels-pypi.sh"
# Auto-skip when NIGHTLY=1 (scheduled); otherwise require manual unblock.
- block: "Unblock to build release Docker images"
depends_on: ~
key: block-build-release-images
if: build.env("NIGHTLY") != "1"
- group: "Build release Docker images"
key: "build-release-images"
@@ -63,7 +65,7 @@ steps:
--progress plain \
-f docker/Dockerfile.cuda .
- "docker push public.ecr.aws/q9t5s3a7/vllm-omni-release-repo:$BUILDKITE_COMMIT-$(uname -m)"
# re-tag to default image tag and push, just in case arm64 build fails
# Fallback default tag (no arch suffix) if arm64 build fails.
- "docker tag public.ecr.aws/q9t5s3a7/vllm-omni-release-repo:$BUILDKITE_COMMIT-$(uname -m) public.ecr.aws/q9t5s3a7/vllm-omni-release-repo:$BUILDKITE_COMMIT"
- "docker push public.ecr.aws/q9t5s3a7/vllm-omni-release-repo:$BUILDKITE_COMMIT"
env:
@@ -86,6 +88,26 @@ steps:
env:
DOCKER_BUILDKIT: "1"
# NIGHTLY=1 only: promote ECR images to DockerHub nightly tags, then prune.
- label: "Publish nightly multi-arch image to DockerHub"
depends_on:
- build-release-image-x86
- build-release-image-arm64
if: build.env("NIGHTLY") == "1"
key: publish-nightly-images-dockerhub
agents:
queue: small_cpu_queue_release
commands:
- "bash .buildkite/release/scripts/publish-release-images.sh nightly"
- "bash .buildkite/release/scripts/cleanup-nightly-builds.sh"
plugins:
- docker-login#v3.0.0:
username: vllmbot
password-env: DOCKERHUB_TOKEN
env:
DOCKER_BUILDKIT: "1"
DOCKERHUB_USERNAME: "vllmbot"
- block: "Publish release images to DockerHub"
key: block-publish-release-images
depends_on:
@@ -0,0 +1,147 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Clean up old nightly builds from DockerHub (vllm/vllm-omni), keeping the
# newest 14 tags with the nightly- prefix.
set -ex
TAG_PREFIX="nightly-"
REPO="vllm/vllm-omni"
REPO_API_URL="https://hub.docker.com/v2/repositories/${REPO}/tags"
echo "Cleaning up tags with prefix: $TAG_PREFIX in repository: $REPO"
if [ -z "$DOCKERHUB_TOKEN" ]; then
echo "Error: DOCKERHUB_TOKEN environment variable is not set"
exit 1
fi
if [ -z "$DOCKERHUB_USERNAME" ]; then
echo "Error: DOCKERHUB_USERNAME environment variable is not set"
exit 1
fi
echo "Getting DockerHub bearer token..."
set +x
BEARER_TOKEN=$(curl -s -X POST \
-H "Content-Type: application/json" \
-d "{\"username\": \"$DOCKERHUB_USERNAME\", \"password\": \"$DOCKERHUB_TOKEN\"}" \
"https://hub.docker.com/v2/users/login" | jq -r '.token')
set -x
if [ -z "$BEARER_TOKEN" ] || [ "$BEARER_TOKEN" = "null" ]; then
echo "Error: Failed to get DockerHub bearer token"
exit 1
fi
get_all_tags() {
local page=1
local all_tags=""
# Hub `name` is a partial match (not a strict prefix). Use it to narrow the
# list, then enforce startswith() client-side. Exhaust API pages; do not
# stop merely because a page has no matching tags after filtering.
local name_query
name_query=$(printf '%s' "$TAG_PREFIX" | jq -sRr @uri)
while true; do
set +x
local response
response=$(curl -s -H "Authorization: Bearer $BEARER_TOKEN" \
"$REPO_API_URL?page=$page&page_size=100&name=${name_query}")
set -x
local page_count
page_count=$(echo "$response" | jq -r '.results | length')
if [ -z "$page_count" ] || [ "$page_count" = "0" ] || [ "$page_count" = "null" ]; then
break
fi
local tags
tags=$(echo "$response" | jq -r --arg prefix "$TAG_PREFIX" \
'.results[] | select(.name | startswith($prefix)) | "\(.last_updated)|\(.name)"')
if [ -n "$tags" ]; then
all_tags="$all_tags$tags"$'\n'
fi
page=$((page + 1))
done
echo "$all_tags" | sort -r | cut -d'|' -f2
}
delete_tag() {
local tag_name="$1"
echo "Deleting tag: $tag_name"
local delete_url="https://hub.docker.com/v2/repositories/${REPO}/tags/$tag_name"
set +x
local response http_code body
response=$(curl -s -w "\n%{http_code}" -X DELETE \
-H "Authorization: Bearer $BEARER_TOKEN" "$delete_url")
set -x
http_code=$(printf '%s\n' "$response" | tail -n1)
body=$(printf '%s\n' "$response" | sed '$d')
if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
echo "Successfully deleted tag: $tag_name (HTTP ${http_code})"
return 0
fi
local detail=""
if echo "$body" | jq -e '.detail' > /dev/null 2>&1; then
detail=$(echo "$body" | jq -r '.detail')
elif [ -n "$body" ]; then
detail="$body"
else
detail="(empty response body)"
fi
echo "Error: Failed to delete tag $tag_name (HTTP ${http_code}): ${detail}"
return 1
}
echo "Fetching all tags from DockerHub..."
all_tags=$(get_all_tags)
if [ -z "$all_tags" ]; then
echo "No tags found to clean up"
exit 0
fi
total_tags=$(echo "$all_tags" | wc -l)
echo "Found $total_tags tags"
tags_to_keep=14
tags_to_delete=$((total_tags - tags_to_keep))
if [ $tags_to_delete -le 0 ]; then
echo "No tags need to be deleted (only $total_tags tags found, keeping $tags_to_keep)"
exit 0
fi
echo "Will delete $tags_to_delete old tags, keeping the newest $tags_to_keep"
tags_to_delete_list=$(echo "$all_tags" | tail -n +$((tags_to_keep + 1)))
if [ -z "$tags_to_delete_list" ]; then
echo "No tags to delete"
exit 0
fi
echo "Deleting old tags..."
delete_failures=0
while IFS= read -r tag; do
if [ -n "$tag" ]; then
if ! delete_tag "$tag"; then
delete_failures=$((delete_failures + 1))
fi
sleep 1
fi
done <<< "$tags_to_delete_list"
if [ "$delete_failures" -gt 0 ]; then
echo "Cleanup finished with ${delete_failures} deletion failure(s)"
exit 1
fi
echo "Cleanup completed successfully"
@@ -1,50 +1,87 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
#
# Publish release Docker images from ECR to DockerHub.
# Pulls per-arch images, tags with `latest` and versioned tags, pushes them,
# then creates and pushes a multi-arch manifest.
# Publish Docker images from ECR staging to DockerHub.
#
# Usage:
# publish-release-images.sh # release mode (default)
# publish-release-images.sh release
# publish-release-images.sh nightly
#
# Release tags: latest, v<version>
# Nightly tags: nightly, nightly-<commit>
set -euo pipefail
RELEASE_VERSION=$(buildkite-agent meta-data get release-version --default "" | sed 's/^v//')
if [ -z "${RELEASE_VERSION}" ]; then
echo "ERROR: release-version metadata not set"
exit 1
fi
MODE="${1:-release}"
COMMIT="$BUILDKITE_COMMIT"
DOCKERHUB_REPO="vllm/vllm-omni"
ECR_REPO="public.ecr.aws/q9t5s3a7/vllm-omni-release-repo"
COMMIT="$BUILDKITE_COMMIT"
PRIMARY_TAGS=()
EXTRA_MANIFEST_TAGS=()
case "${MODE}" in
release)
RELEASE_VERSION=$(buildkite-agent meta-data get release-version --default "" | sed 's/^v//')
if [ -z "${RELEASE_VERSION}" ]; then
echo "ERROR: release-version metadata not set"
exit 1
fi
PRIMARY_TAGS=("latest" "v${RELEASE_VERSION}")
;;
nightly)
# Commit-pinned manifest reuses nightly-{x86_64,aarch64} arch images.
PRIMARY_TAGS=("nightly")
EXTRA_MANIFEST_TAGS=("nightly-${COMMIT}")
;;
*)
echo "Usage: $0 {release|nightly}"
exit 2
;;
esac
echo "========================================"
echo "Publishing release images v${RELEASE_VERSION}"
echo "Publishing ${MODE} images to ${DOCKERHUB_REPO}"
echo " Commit: ${COMMIT}"
echo " Primary tags: ${PRIMARY_TAGS[*]}"
if [ ${#EXTRA_MANIFEST_TAGS[@]} -gt 0 ]; then
echo " Extra manifests: ${EXTRA_MANIFEST_TAGS[*]}"
fi
echo "========================================"
# Login to ECR to pull staging images
aws ecr-public get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin public.ecr.aws/q9t5s3a7
docker pull "${ECR_REPO}:${COMMIT}-x86_64"
docker pull "${ECR_REPO}:${COMMIT}-aarch64"
SRC_X86="${ECR_REPO}:${COMMIT}-x86_64"
SRC_ARM="${ECR_REPO}:${COMMIT}-aarch64"
docker tag "${ECR_REPO}:${COMMIT}-x86_64" "${DOCKERHUB_REPO}:latest-x86_64"
docker tag "${ECR_REPO}:${COMMIT}-x86_64" "${DOCKERHUB_REPO}:v${RELEASE_VERSION}-x86_64"
docker push "${DOCKERHUB_REPO}:latest-x86_64"
docker push "${DOCKERHUB_REPO}:v${RELEASE_VERSION}-x86_64"
docker pull "${SRC_X86}"
docker pull "${SRC_ARM}"
docker tag "${ECR_REPO}:${COMMIT}-aarch64" "${DOCKERHUB_REPO}:latest-aarch64"
docker tag "${ECR_REPO}:${COMMIT}-aarch64" "${DOCKERHUB_REPO}:v${RELEASE_VERSION}-aarch64"
docker push "${DOCKERHUB_REPO}:latest-aarch64"
docker push "${DOCKERHUB_REPO}:v${RELEASE_VERSION}-aarch64"
publish_manifest() {
local tag="$1"
local arch_tag_base="$2"
docker manifest rm "${DOCKERHUB_REPO}:${tag}" || true
docker manifest create \
"${DOCKERHUB_REPO}:${tag}" \
"${DOCKERHUB_REPO}:${arch_tag_base}-x86_64" \
"${DOCKERHUB_REPO}:${arch_tag_base}-aarch64"
docker manifest push "${DOCKERHUB_REPO}:${tag}"
}
docker manifest rm "${DOCKERHUB_REPO}:latest" || true
docker manifest rm "${DOCKERHUB_REPO}:v${RELEASE_VERSION}" || true
docker manifest create "${DOCKERHUB_REPO}:latest" "${DOCKERHUB_REPO}:latest-x86_64" "${DOCKERHUB_REPO}:latest-aarch64"
docker manifest create "${DOCKERHUB_REPO}:v${RELEASE_VERSION}" "${DOCKERHUB_REPO}:v${RELEASE_VERSION}-x86_64" "${DOCKERHUB_REPO}:v${RELEASE_VERSION}-aarch64"
docker manifest push "${DOCKERHUB_REPO}:latest"
docker manifest push "${DOCKERHUB_REPO}:v${RELEASE_VERSION}"
for tag in "${PRIMARY_TAGS[@]}"; do
docker tag "${SRC_X86}" "${DOCKERHUB_REPO}:${tag}-x86_64"
docker tag "${SRC_ARM}" "${DOCKERHUB_REPO}:${tag}-aarch64"
docker push "${DOCKERHUB_REPO}:${tag}-x86_64"
docker push "${DOCKERHUB_REPO}:${tag}-aarch64"
publish_manifest "${tag}" "${tag}"
done
ARCH_BASE="${PRIMARY_TAGS[0]}"
for tag in "${EXTRA_MANIFEST_TAGS[@]}"; do
publish_manifest "${tag}" "${ARCH_BASE}"
done
echo ""
echo "Successfully published release images for v${RELEASE_VERSION}"
echo "Successfully published ${MODE} images"
+60 -55
View File
@@ -220,65 +220,70 @@ See `plan/voxcpm2_native_ar_design.md`.
### Steps
1. **Register in `serving_speech.py`** — add all 5 points in a **single commit**;
partial integration causes hard-to-debug failures. This file is modified by every
model PR and is the most common source of rebase conflicts — see conflict note below.
1. **Write one adapter** under `vllm_omni/entrypoints/openai/tts_adapters/`.
`serving_speech.py` should not need an edit — detection, stage discovery and
dispatch are all derived from what the adapter declares.
**Point 1** — stage constant (near the top, alongside the other `_*_TTS_MODEL_STAGES` sets):
Create `vllm_omni/entrypoints/openai/tts_adapters/your_model.py`:
```python
_YOUR_MODEL_TTS_MODEL_STAGES = {"your_stage_key"}
@register_tts_adapter
class YourModelAdapter(ARTTSAdapter):
name = "your_model" # registry key + log label
stage_keys = frozenset({"your_stage_key"}) # the deploy yaml's model_stage
def validate(self, request) -> str | None:
if not request.input or not request.input.strip():
return "Input text cannot be empty"
return None
async def build(self, request, sampling_params_list, has_inline_ref_audio):
params = {"text": [request.input]}
if request.voice is not None:
params["voice"] = [request.voice]
return PreparedRequest(
prompt={"prompt": request.input},
tts_params=params,
model_type=self.name,
)
```
**Point 2** — union into `_TTS_MODEL_STAGES`:
```python
_TTS_MODEL_STAGES: set[str] = (
...
| _YOUR_MODEL_TTS_MODEL_STAGES
)
```
Then add the module to the import block at the bottom of
`tts_adapters/__init__.py` so it registers. That import line is the only shared
file a new model touches — which is also why the old rebase-conflict hotspot is
gone.
**Point 3** — model type detection in `_detect_tts_model_type()`:
```python
if model_stage in _YOUR_MODEL_TTS_MODEL_STAGES:
return "your_model"
```
> **Pure-diffusion TTS does not go through adapters yet.** Under
> `for_diffusion()`, `create_speech()` routes straight to
> `_create_diffusion_speech()` and never calls `validate()`/`build()`.
> `DiffusionTTSAdapter` is scaffolding with no production subclass, so logic
> placed in one would silently never run. Diffusion-engine models follow the
> existing diffusion path; wiring it through adapters is open work (#4855).
**Point 4** — validation dispatch in `_validate_tts_request()`:
```python
if self._tts_model_type == "your_model":
return self._validate_your_model_request(request)
```
**If a stage key alone cannot identify the model**, declare
`model_archs = frozenset({"YourModelForConditionalGeneration"})`; add
`arch_identifies_entry_stage = True` when the model owns no stage key at all
(Ming dense). For a rule that is not set membership, override `matches()` (see
`covo_audio.py`). For a genuine overlap with another adapter, give one an
explicit `detect_priority` — `test_tts_detection.py` fails on an unordered
overlap. Models that only serve speech in some topologies override
`stage_serves_speech()` (see `audex.py`).
**Point 5** — validation + parameter-builder methods:
```python
def _validate_your_model_request(self, request) -> str | None:
if not request.input or not request.input.strip():
return "Input text cannot be empty"
return None
**Reuse shared helpers via `self.ctx.server`** rather than reimplementing them:
`_resolve_ref_audio`, `_apply_uploaded_speaker`, `_validate_ref_audio_format`,
`_max_instructions_length`. Read a comparable adapter first — `fish_speech.py`
(voice cloning), `higgs_audio_v3.py` (parameter-heavy), `moss_tts.py` (family
sharing a base class).
def _build_your_model_params(self, request) -> dict:
params = {"text": [request.input]}
if request.voice is not None:
params["voice"] = [request.voice]
return params
```
Wire `_build_your_model_params` into `_create_tts_request()` alongside the other
model-specific param builders.
> **Do not add `self._tts_model_type == ...` branches to `serving_speech.py`.**
> Older models predate the adapter framework and still have them; they are being
> migrated out (RFC #4327, #4855). `tools/pre_commit/check_tts_adapter.py` is a
> ratchet on the remaining count and fails the commit if it grows. Behaviour that
> no adapter hook can express is a missing hook — propose it on the RFC.
> **Two dispatch patterns coexist**: Fish Speech uses a `self._is_fish_speech` boolean
> instance attribute checked before `elif self._is_tts`, while all newer models
> (CosyVoice3, MOSS-TTS-Nano) use the `_tts_model_type` string returned by
> `_detect_tts_model_type()`. For new models, always use the `_tts_model_type` string
> pattern — do not add new `_is_*` flags.
> **Unused variable rule**: only extract fields in `_build_your_model_params` that
> are actually forwarded to the model. Unused extractions fail `ruff F841`.
> For voice-cloning fields (`ref_audio` → `prompt_audio_path`, `ref_text` →
> `prompt_text`), add them to the param builder and verify they reach the model call.
**Rebase conflict note**: when rebasing onto `main` after another model was merged,
`serving_speech.py` will conflict. Resolution: always keep *both* the upstream
model's additions and your own — never discard either side.
> **Unused variable rule**: only extract fields in `build()` that are actually
> forwarded to the model. Unused extractions fail `ruff F841`. For voice-cloning
> fields (`ref_audio` -> `prompt_audio_path`, `ref_text` -> `prompt_text`), add
> them to the params and verify they reach the model call.
2. **Handle model-specific parameters**:
- Voice cloning: `ref_audio` encoding and prompt injection
@@ -295,7 +300,7 @@ import base64
from pathlib import Path
def build_voice_clone_prompt(ref_audio_path: str, text: str, codec) -> list:
"""Build prompt with reference audio for voice cloning in serving_speech.py."""
"""Build prompt with reference audio for voice cloning, called from the adapter."""
audio_bytes = Path(ref_audio_path).read_bytes()
codes = codec.encode(audio_bytes) # Encode on CPU using model's codec (e.g., DAC)
token_ids = [code + codec.vocab_offset for code in codes.flatten().tolist()]
@@ -321,7 +326,7 @@ Classify the model's **CI priority** first (high / medium / low). High-priority
| Level | Location | Marker | CI pipeline | Notes |
|-------|----------|--------|-------------|-------|
| **L1** | `tests/model_executor/…`, `tests/entrypoints/openai_api/…`, stage-processor tests | `core_model` + `cpu` | `test-ready.yml` | Prompt assembly, async_chunk helpers, `serving_speech` validation — no GPU |
| **L1** | `tests/model_executor/…`, `tests/entrypoints/openai_api/…`, stage-processor tests | `core_model` + `cpu` | `test-ready.yml` | Prompt assembly, async_chunk helpers, adapter validation — no GPU |
| **L2** | `tests/e2e/online_serving/test_{slug}.py` | **`core_model` + `advanced_model`** (both on baseline smoke) + `tts` + `@hardware_test(...)` | `test-ready.yml` (`ready` label) | Default deploy smoke: single `/v1/audio/speech` or offline `OmniRunner` path |
| **L3** | `tests/e2e/online_serving/test_{slug}.py` **and** `tests/e2e/offline_inference/test_{slug}.py` | Baseline smoke: **`core_model` + `advanced_model`**; heavier cases: `advanced_model` only (+ `tts`) | `test-merge.yml` **or** merged into nightly TTS function job | Streaming, voice clone, batch/queue, async_chunk |
| **L4** | `tests/e2e/online_serving/test_{slug}_expansion.py`, optional offline expansion | `full_model` + `tts` | `test-nightly.yml` (`:full_moon: TTS · Function Test with L4`) | Feature matrix; perf → `tests/dfx/perf/tests/test_tts.json` |
@@ -366,7 +371,7 @@ See [vllm-omni-test skill](../vllm-omni-test/SKILL.md) § **Runtime send helpers
### Deliverables
- Updated `serving_speech.py` with all 5 integration points (single commit)
- One adapter file under `tts_adapters/` plus its line in the package import block
- Client scripts and server launcher under `examples/online_serving/text_to_speech/<model>/`
- Gradio demo with streaming and voice cloning UI in the same dir
- E2E tests per **Test Case Writing (CI Levels)** above (priority tier determines L1–L4 scope)
@@ -514,8 +519,8 @@ Use this checklist when integrating a new TTS model:
- [ ] README.md written
### Phase 3: Online Serving
- [ ] All 5 `serving_speech.py` integration points added in one commit
- [ ] Only extract params in `_build_*_params` that are forwarded to the model call (ruff F841)
- [ ] Adapter written under `tts_adapters/` and registered in the import block
- [ ] Only extract params in `build()` that are forwarded to the model call (ruff F841)
- [ ] Prompt builder handles text input correctly
- [ ] Voice cloning works (if supported)
- [ ] All response formats work (wav, mp3, flac, pcm)
+4 -1
View File
@@ -1,6 +1,6 @@
---
name: precheck-pr
description: Self-check your branch before creating a PR — catch dead code, verify accuracy/perf claims, validate PR title format, and confirm merge readiness. Use when the user says "precheck", "self review", "pre-submit check", or "check my PR before I open it." Never posts to GitHub.
description: Self-check your branch before creating a PR — catch dead code, prevent new model-specific Python examples, verify accuracy/perf claims, validate PR title format, and confirm merge readiness. Use when the user says "precheck", "self review", "pre-submit check", or "check my PR before I open it." Never posts to GitHub.
---
# PR Pre-Check
@@ -65,6 +65,8 @@ Ask: "Quick mode or full mode?" Then walk the checklist for the detected PR type
**Also run the Code-Quality sweep on every PR**, regardless of type or mode: the five diff-scoped checks in [references/code-quality.md](references/code-quality.md) — kwargs fragility, broad-except swallow, `Any`/wrong type hints, hot-path `.clone()`/`deepcopy`, and event-loop blocking — plus the advisory conventions (log level, structured logging, synchronization, cleanup, dependencies, naming) in [checklists.md](references/checklists.md). These count only lines the PR *adds* — the pre-existing backlog across the repo is out of scope.
**Also run the Examples-Policy check on every PR** using [references/examples-policy.md](references/examples-policy.md). Inspect only Python paths introduced by the diff. Treat a new model-, checkpoint-, vendor-, or family-specific Python example as blocking; do not report pre-existing example debt.
### Step 5: Print Report
```
@@ -77,6 +79,7 @@ Pre-check report for <branch>
───────────────── ──────
PR title format ✓
Code quality ⚠ 1 broad except, 2 Any hints
Examples policy ✗ new model-specific Python example
PR desc integrity ✓
Registry/config ✓
Dead code ⚠ 2 warnings
@@ -47,6 +47,19 @@ Diff-scoped sweep for five fragility patterns that are pervasive in the existing
Roll the ⚠/✗ counts into the report as a single **Code quality** dimension row.
---
## All PRs: Examples Policy (run on every PR, quick & full)
Inspect Python files introduced under `examples/` using
[examples-policy.md](examples-policy.md). This is a diff-scoped ratchet: existing
model-specific examples may be edited or removed without triggering the check.
- [ ] **No new model-specific Python examples:** the diff adds, copies, or renames no Python file whose path or behavior is specific to one model, checkpoint, vendor, or model family. ✗ for any violation. Route inference through a shared task/protocol entrypoint, model request behavior through `vllm_omni/model_extras`, and commands through task docs or `recipes/`.
- [ ] **New generic example code is justified:** any new task-neutral Python file under `examples/` is an actual user-facing entrypoint rather than reusable production logic, a benchmark, an app, a setup tool, or a reproducer. ⚠ when the placement is questionable.
Roll the result into the report as a separate **Examples policy** dimension.
### Conventions (eyeball — no grep)
Judgment calls that don't grep cleanly — apply them while reading the diff, not as a mechanical check:
@@ -0,0 +1,68 @@
# Examples Python Policy
Prevent new model-specific Python examples without forcing cleanup of the
existing backlog. Run this check on every PR in quick and full modes.
## Scope
Set the merge base as in the main workflow, then list Python paths introduced
by the PR, including additions, copies, and renames:
```bash
BASE="$(git merge-base HEAD origin/main)"
git diff --name-status --diff-filter=ACR --find-renames --find-copies \
"${BASE}"...HEAD -- 'examples/**/*.py'
```
Inspect destination paths for copies and renames. Existing model-specific files
that are only modified or deleted are grandfathered and must not be reported.
## Blocking classification
Mark ✗ when a newly introduced Python file does any of the following:
- Names or scopes a path to one model, checkpoint, vendor, or model family.
- Hard-codes a model identifier, model-specific prompt, request shape, output
conversion, or launch configuration behind an otherwise generic filename.
- Duplicates an existing task/protocol runner to demonstrate one model.
- Adds a per-model helper below a generic task hub such as `text_to_speech/`.
Do not infer safety from a generic filename alone. For example, a file named
`text_to_audio.py` is still model-specific if it only implements one model's
contract.
## Acceptable additions
A new Python example may pass when it is a genuinely model-neutral,
user-facing task or protocol entrypoint. It must accept model selection through
configuration and keep model-specific behavior out of the script.
Use ⚠ when the file is model-neutral but reusable logic appears misplaced under
`examples/`. Route code by purpose:
| Code purpose | Preferred location |
|---|---|
| Model prompt, defaults, request/output adaptation | `vllm_omni/model_extras/` or production model modules |
| Runnable model command and validation evidence | Task documentation or `recipes/` |
| UI or interactive application | `apps/` |
| Benchmark or evaluator | `benchmarks/` |
| Regression reproducer | `tests/` |
| Download, conversion, or setup utility | `tools/` |
If a model cannot use an existing shared runner, report the missing generic
capability. Do not solve the gap by adding a model-specific Python example.
## Report format
Add one row to the pre-check report:
```text
Examples policy ✓ no new Python example paths
Examples policy ⚠ generic helper belongs in tools/
Examples policy ✗ examples/offline_inference/new_model/end2end.py is model-specific
Examples policy ✗ examples/offline_inference/x_to_y_model_name.py is model-specific
```
For a blocker, name the path, the model-specific behavior, and the appropriate
shared runner or destination. Do not propose deleting unrelated existing
examples as part of the PR.
+38 -28
View File
@@ -1,9 +1,9 @@
# Claude Skills for vLLM-Omni
# Repository Skills for vLLM-Omni
This directory contains Claude Code skills maintained for the `vllm-omni`
repository. These skills capture repeatable workflows for common contributor
tasks such as model integration, pull request review, and release note
generation.
This directory contains repository-scale skills maintained for `vllm-omni`.
They capture repeatable workflows for common contributor and maintainer tasks
such as model integration, CI-aligned testing, performance optimization, and
pull request review.
## Directory Structure
@@ -14,31 +14,41 @@ include:
- `references/`: focused reference material used by the skill
- `scripts/`: small helper scripts used by the skill
## Using the Skills
Coding agents that discover repository skills can invoke the relevant skill by
name. For other agents, point them to the skill's `SKILL.md` and ask them to
read it before changing code. Combine a domain skill with `vllm-omni-test` when
tests or CI coverage change, then use `precheck-pr` for the contributor's final
self-check.
## Available Skills
- `add-diffusion-model`: guides integration of a new diffusion model into
`vllm-omni`
- `diffusion-perf-opt`: guides diffusion model performance optimization,
including profiling traces, parallel strategies, stage timing analysis, and
benchmark-driven tuning
- `quantization`: guides quantization method selection, model integration,
checkpoint loading, and quality/performance validation for vLLM-Omni
- `add-omni-model`: covers addition of new omni-modality model support
- `add-tts-model`: covers integration of new TTS models and related serving
workflows
- `generate-release-note`: helps prepare release notes for repository changes
- `precheck-pr`: self-check a branch before creating a PR — validates PR title
format, catches dead code, verifies accuracy/perf claims, and confirms merge
readiness
- `vllm-omni-test`: guides generation and execution of CI-aligned tests (L1–L4),
pytest marker selection (`core_model` / `advanced_model` / `full_model`,
`omni` / `tts` / `diffusion`), Buildkite wiring (`test-ready.yml`,
`test-merge.yml`, `test-nightly.yml`, `test-weekly.yml`), and copy-paste
local plus CI-like `pytest` commands; see `references/test-routing.md` for
level-to-command mapping
- `review-pr`: provides a structured workflow for reviewing pull requests
- `vllm-omni-npu-model-runner-upgrade`: upgrades NPU model runners to align with the
latest vllm-ascend NPUModelRunner
- [`add-diffusion-model`](add-diffusion-model/SKILL.md): guides integration of
a new diffusion model into `vllm-omni`
- [`add-tts-model`](add-tts-model/SKILL.md): covers integration of new TTS
models and related serving workflows
- [`diffusion-perf-opt`](diffusion-perf-opt/SKILL.md): guides diffusion model
performance optimization, including profiling traces, parallel strategies,
stage timing analysis, and benchmark-driven tuning
- [`precheck-pr`](precheck-pr/SKILL.md): self-checks a branch before creating a
PR by validating title format, dead code, accuracy and performance claims,
and merge readiness
- [`quantization`](quantization/SKILL.md): guides quantization method selection,
model integration, checkpoint loading, and quality/performance validation
for vLLM-Omni
- [`review-pr`](review-pr/SKILL.md): provides a frozen-snapshot, contract-aware
workflow for maintainers and reviewers; contributors should use
`precheck-pr` for self-review
- [`vllm-omni-npu-model-runner-upgrade`](vllm-omni-npu-upgrade/SKILL.md):
upgrades NPU model runners to align with the latest vllm-ascend
`NPUModelRunner`
- [`vllm-omni-test`](vllm-omni-test/SKILL.md): guides generation and execution
of CI-aligned tests (L1–L4), pytest marker selection (`core_model` /
`advanced_model` / `full_model`, `omni` / `tts` / `diffusion`), Buildkite
wiring (`test-ready.yml`, `test-merge.yml`, `test-nightly.yml`,
`test-weekly.yml`), and copy-paste local plus CI-like `pytest` commands; see
`references/test-routing.md` for level-to-command mapping
## Maintenance Guidelines
+239
View File
@@ -0,0 +1,239 @@
---
name: review-pr
description: Review pull requests and local branches for vllm-project/vllm-omni with a frozen snapshot, module-design ownership, feature-design overlays, targeted validation, and concise evidence-backed findings. Use for default, detailed, or repeat maintainer reviews; checking correctness, compatibility, tests, benchmarks, model additions, distributed changes, or breaking behavior; and identifying or explicitly requesting the most relevant code-owner reviewers. Use precheck-pr instead for an author's pre-submit self-check.
---
# Review vLLM-Omni Pull Requests
Review like a maintainer: direct, selective, and focused on issues that CI does
not prove. Prefer a few high-confidence findings over exhaustive commentary.
Zero findings is a valid result.
## Quality contract
Make every finding:
- **Correct:** prove a reachable failure, not a suspicion.
- **Prioritized:** lead with merge blockers and high-impact defects.
- **Actionable:** identify the smallest safe fix direction.
- **Evidence-based:** cite code, tests, docs, CI, or measurements.
- **Concise:** avoid review templates and repeated summaries.
- **Calibrated:** match severity to user and maintainer impact.
Do not report unrelated backlog, style already enforced by pre-commit, or a
missing test that would not protect changed behavior.
## Select the input and depth
Use `vllm-project/vllm-omni` as the base repository. Accept its forks and local
checkouts; use another skill for unrelated repositories.
| Input | Review surface |
| --- | --- |
| PR number or URL | Frozen PR metadata, full diff, and relevant threads. |
| Local branch/worktree | Frozen target-base SHA through committed, staged, unstaged, and in-scope untracked changes. |
| Pre-filled context | Reuse supplied metadata; fetch only missing facts and the full diff. |
Default to maintainer brevity. A detailed or audit request expands coverage and
lists `path:line` findings, but keeps the same confidence and severity bar.
## Reference guide
Load references in review order: process, one primary module contract, matching
feature designs, evidence checks, then delivery. Every file is linked directly
below; do not load unrelated module references.
Each concise reference links to the maintained
[vLLM-Omni documentation](https://docs.vllm.ai/projects/vllm-omni/en/latest/).
For branch-specific behavior, inspect the matching `docs/` file in the reviewed
checkout first; use the published latest docs for current guidance and discovery.
If docs and live code disagree, verify the code/tests and report the drift.
### Review process
| Reference | Read when |
| --- | --- |
| [review-execution.md](references/process/review-execution.md) | Every review; freeze inputs, inspect safely, and deliver against the same snapshot. |
| [general-checks.md](references/process/general-checks.md) | Every review; apply repository-wide correctness and evidence rules. |
| [design-contracts.md](references/process/design-contracts.md) | Every production review; resolve branch-local module and feature design status. |
| [review-routing.md](references/process/review-routing.md) | After the diff census; select one primary module and conditional overlays. |
### Primary module contract
| Reference | Read when |
| --- | --- |
| [entrypoints.md](references/modules/entrypoints.md) | Offline/CLI/API ingress, validation, rendering, streaming, or sessions change. |
| [configuration.md](references/modules/configuration.md) | Config construction, deploy/stage schema, defaults, registry, or topology changes. |
| [input-output-modality.md](references/modules/input-output-modality.md) | Requests, messages, serialization, output types, accumulation, or completion change. |
| [error-contracts.md](references/modules/error-contracts.md) | Error classification, fatality, propagation, sanitization, or rendering changes. |
| [engine-orchestration.md](references/modules/engine-orchestration.md) | Cross-stage routing, request state, output ordering, RPC correlation, or terminal convergence changes. |
| [stage-runtime.md](references/modules/stage-runtime.md) | Placement, startup, readiness, replica identity, affinity, membership, or shutdown changes. |
| [omni-connector.md](references/modules/omni-connector.md) | Cross-stage/process/device/node transport or synchronization changes. |
| [model-integration.md](references/modules/model-integration.md) | Registration, preprocessing, loading, runners, or model-specific execution changes. |
| [ar-runtime.md](references/modules/ar-runtime.md) | AR scheduling, request/cache state, adapters, workers, or upstream vLLM semantics change. |
| [diffusion.md](references/modules/diffusion.md) | Diffusion runtime, models, batching, parallelism, or offload changes. |
| [execution-platforms.md](references/modules/execution-platforms.md) | Hardware selection, capabilities, vendor workers, kernels, or patches change. |
| [cache-management.md](references/modules/cache-management.md) | Cache identity, reuse, validity, reset, eviction, or teardown changes. |
| [quantization.md](references/modules/quantization.md) | Quantization selection, checkpoint metadata, layer mapping, precision, or constraints change. |
| [observability.md](references/modules/observability.md) | Metrics, logs, units, labels, correlation, or lifecycle changes. |
| [profiling.md](references/modules/profiling.md) | Profiling instrumentation, traces, start/stop lifecycle, or overhead changes. |
| [benchmarking.md](references/modules/benchmarking.md) | Benchmark workload, metric calculation, CLI, or result metadata changes. |
### Feature-design overlays
| Reference | Read when |
| --- | --- |
| [runtime-stage-execution.md](references/features/runtime-stage-execution.md) | Disaggregated inference, async chunk/output/materialization, or prefix caching changes. |
| [communication.md](references/features/communication.md) | A concrete OmniConnector backend or its deployment contract changes. |
| [diffusion-acceleration.md](references/features/diffusion-acceleration.md) | Diffusion parallelism, attention, quantization, cache, batching, or offload changes. |
| [infrastructure-performance.md](references/features/infrastructure-performance.md) | Metrics infrastructure or documented speech optimization stacks change. |
### Evidence and quality checks
| Reference | Read when |
| --- | --- |
| [model-addition-checklist.md](references/checks/model-addition-checklist.md) | A model, architecture, loader, processor, registry, or stage config is added. |
| [perf-verification.md](references/checks/perf-verification.md) | The PR makes a latency, throughput, memory, or quality claim. |
| [test-quality-evaluation.md](references/checks/test-quality-evaluation.md) | Tests change, are absent for risky code, or may not exercise production behavior. |
| [tests-docs-checklist.md](references/checks/tests-docs-checklist.md) | Coverage, CI markers, examples, user docs, or PR evidence need review. |
| [verification.md](references/checks/verification.md) | Hardware, a server, or a runnable affected path is available for active verification. |
| [examples-policy.md](../precheck-pr/references/examples-policy.md) | The PR adds, copies, or renames Python under `examples/`; apply the canonical policy shared with `precheck-pr`. |
### Delivery and reviewer coordination
| Reference | Read when |
| --- | --- |
| [maintainer-style-study.md](references/delivery/maintainer-style-study.md) | Findings are ready for concise maintainer-style delivery. |
| [review-requests.md](references/delivery/review-requests.md) | The user asks to identify, suggest, request, or ping code-owner reviewers. |
## Workflow
### 1. Freeze and report the snapshot
Pin the base and head before reading source or running validation. Within 60 seconds,
report the pinned head, CI, mergeability, and preliminary findings in the host
conversation. Do not wait for CI or post this update to GitHub.
If the target changes while fetching, discard the evidence and retry once. If
it changes again, report the churn and wait for a stable target.
For a trusted PR head, materialize the pinned head in an isolated detached
worktree. A worktree freezes identity but is not a security sandbox. Treat fork
heads as untrusted unless the user and environment policy explicitly establish
otherwise: execute them only in a disposable, secret-free sandbox with restricted
filesystem, network, and resources; without one, use static SHA-addressed reads
and CI evidence only. For a local review, freeze the committed, index, worktree,
and NUL-safe in-scope untracked contents. Follow
[review-execution.md](references/process/review-execution.md) for trust gates,
state fingerprints, and byte-for-byte staleness checks.
### 2. Build the diff census
Group files into production code, tests, docs, configuration, build/CI, and
generated artifacts. Map each changed production file and test group to the PR
goal. Compare the title/body claims with the actual diff; use linked issues only
when they define the contract or reproduction.
Mark unrelated scope and unexplained generated artifacts. Do not infer behavior
from the PR description without tracing the live code.
### 3. Route from the live behavior
Trace each claimed behavior through the changed producer to its live consumer,
then use [design-contracts.md](references/process/design-contracts.md) and
[review-routing.md](references/process/review-routing.md) to select one primary
module contract, a second only for a real documented cross-boundary call path,
and every matching feature-design and evidence overlay. Treat titles and paths
as hints; live behavior and the frozen head's current design metadata are
authoritative. For docs-, tests-, or CI-only changes, route to the production
contract they protect or use only the applicable evidence checks.
### 4. Run the blocker scan
Apply every category in [general-checks.md](references/process/general-checks.md) before
lower-priority comments.
If the diff census contains an added, copied, or renamed Python path under
`examples/`, read and apply the canonical
[examples policy](../precheck-pr/references/examples-policy.md). Treat a new
model-specific Python example as blocking. Do not flag model-specific example
debt that the PR only modifies or removes, and do not run the rest of the
author-oriented `precheck-pr` workflow.
For each changed value or behavior, trace:
```text
public ingress -> validation/defaulting -> producer -> transformations
-> stage/worker/connector boundary -> final consumer -> terminal cleanup
```
Cover every applicable offline/online, streaming/non-streaming, sync/async,
feature-on/off, topology, and compatibility path. Search bounded callers and
sibling implementations rather than assuming the changed hunk is the only path.
### 5. Apply module and feature contracts
Apply the reference set selected in step 3 and any matching repo-local skill.
Read the exact module and feature pages in the frozen head, including status,
ownership boundary, dependencies, candidate invariants, safe-change guide, and
promotion gate. Candidate or draft rules are questions, not blockers, unless
current code, tests, or policy enforce them. Inspect both sides of any config,
registry, serialization, connector, cache, or stage boundary.
When a diff adds or expands a helper, class, fallback, compatibility branch, or
public behavior, run a subtraction pass: remove out-of-scope behavior and check
whether each new abstraction can be deleted, merged, moved, or inlined.
### 6. Verify the changed path
Before each validation group, verify the frozen SHA plus the tracked, index,
untracked, and ignored-file fingerprint, or recreate a pristine snapshot. On a
trusted head or inside the required sandbox, run an import/version preflight,
then the narrowest relevant tests and low-cost static checks. Bind every result
to the head SHA, snapshot fingerprint, and environment fingerprint. Never run
imports, tests, builds, hooks, or repo-configurable tooling from an untrusted
head on the reviewer host.
- Treat CI as status evidence; inspect only the first overlapping failure.
- For docs-only changes, use diff hygiene, links/build checks, and bounded live
contract verification instead of dependency setup or pytest.
- For hardware-dependent paths, run available static/CPU checks and name the
exact GPU/NPU gap. Never simulate device evidence.
- For performance or accuracy claims, require comparable base/head runs with
the same environment, workload, warmup, repetitions, and quality criteria.
Stop when each changed semantic path has a supported finding or an explicit
no-issue conclusion. Do not search further only to increase confidence.
### 7. Consolidate and deliver
Verify each finding against the current diff, deduplicate by root cause, and
order by severity.
Re-read the remote head and reverify or recreate the pristine validation
snapshot immediately before delivery. If either changed, mark the review stale
and restart from the new snapshot.
Return findings first. Use
[maintainer-style-study.md](references/delivery/maintainer-style-study.md) to keep them
direct and brief. Each finding must include an exact `path:line`, trigger or
call path, current behavior, impact, and smallest fix direction. If there are
no findings, say so briefly and name material validation gaps.
Keep the review read-only unless the user explicitly authorizes posting. Do not
submit `APPROVE`, `COMMENT`, or `REQUEST_CHANGES`, add labels, edit code, or push
commits as an implied part of review.
### 8. Optionally request focused owner reviews
Only when the user asks to identify or request reviewers, read
[review-requests.md](references/delivery/review-requests.md). Rank path-matched
CODEOWNERS with the frozen module page's owners or required reviewers and
documented governance expertise; propose one to three focused reviewers with an
explicit contract rationale.
Identifying or suggesting reviewers is read-only. Requesting reviewers or
posting `@mention` comments changes external state and requires explicit user
authorization. When authorized, recheck the head, deduplicate existing
requests, and post at most one consolidated comment. Do not infer this
permission from a request to review the code.
@@ -0,0 +1,4 @@
interface:
display_name: "vLLM-Omni PR Review"
short_description: "Review vLLM-Omni PRs and route owner requests"
default_prompt: "Use $review-pr to review this vLLM-Omni pull request with owner-specific rules and evidence-backed findings."
@@ -0,0 +1,121 @@
# Model Addition Checklist
Read this reference when a PR adds or expands a model architecture, pipeline,
loader, processor, registry entry, or stage configuration.
Official docs: [model contribution guides](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/model/),
[adding an omni model](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/model/adding_omni_model/),
[adding a diffusion model](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/model/adding_diffusion_model/),
[adding a TTS model](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/model/adding_tts_model/),
[supported models](https://docs.vllm.ai/projects/vllm-omni/en/latest/models/supported_models/),
[diffusion features](https://docs.vllm.ai/projects/vllm-omni/en/latest/user_guide/diffusion_features/),
and [feature compatibility](https://docs.vllm.ai/projects/vllm-omni/en/latest/user_guide/feature_compatibility/).
## Match claims to the diff
- Reconcile every claimed architecture, modality, variant, feature, and example
with changed files and registry entries.
- Resolve config model types, architecture names, callable paths, exports, and
dependency extras against live symbols.
- Check sibling generations sharing an architecture name are disambiguated by
a stable config predicate rather than import order or an accidental default.
## Close the integration chain
Trace:
```text
public model id -> config/pipeline selection -> registry -> loader/processor
-> stage inputs -> model execution -> stage/public output
```
Verify optional dependencies fail with an actionable message, weight names and
dtypes map correctly, and each advertised serving mode reaches the production
dispatcher. Confirm outputs are non-empty and valid for their modality, shape,
sample rate, or response schema.
## Keep support documentation truthful
- Build an evidence-backed inventory of the new model's exact architecture and
checkpoint identifiers, modalities and tasks, hardware backends, serving
modes, and supported acceleration, parallelism, cache, offload, and
quantization features. Treat untested support as unknown, not supported.
- Update `docs/models/supported_models.md` with the architecture, model family,
example checkpoints, and only the backends validated by the PR.
- For a diffusion model, add it to the applicable ImageGen, VideoGen, or
AudioGen table in `docs/user_guide/diffusion_features.md`. Fill every feature
column according to its legend and document partial support or constraints.
- Update `docs/user_guide/feature_compatibility.md` when the model changes valid
feature combinations, configuration constraints, examples, or limitations,
and update any other branch-local support table affected by the claims.
- Cross-check every documented support mark against the registry, configuration,
production-path tests, and PR evidence; do not copy a sibling model's support
claims without validation.
## Ship the model recipe
- Require every new model PR to add or update one model-family recipe under
`recipes/<vendor>/` and its row in the `recipes/README.md` Available Recipes
table. Follow [`recipes/TEMPLATE.md`](../../../../../recipes/TEMPLATE.md) and
the layout rules in
[`recipes/README.md`](../../../../../recipes/README.md); the
external recipes repository is a structural reference, not a substitute.
- Include only tested task, serving-mode, and hardware configurations. Keep the
exact model identifiers, flags, commands, verification, feature support,
constraints, and limitations consistent with code, tests, examples, and the
support documentation.
- Cover each validated platform in its own hardware section. Use one recipe per
model family by default; justify a split when configurations cannot be kept
clear in one file, and do not add placeholder sections for untested platforms.
## Compare the reference implementation
Require every new model PR to include a head-versus-reference accuracy or
quality and performance comparison:
- Name the canonical implementation and pin its repository revision, package
version, configuration, and checkpoint. If it cannot run, explain why and use
the closest runnable reference; do not silently omit the comparison.
- Match inputs or dataset, seed, output settings, precision or quantization,
hardware, software, warmup, repetitions, synchronization, and timing and
memory scope. Include exact commands and environment details for both sides.
- Compare accuracy or output quality with a task-appropriate metric and explicit
tolerance. When no reliable metric exists, provide paired fixed-input outputs,
artifacts, and evaluation criteria, and explain expected numerical or
qualitative differences.
- Report end-to-end latency, task-appropriate throughput, peak device memory,
run-to-run variability, and head/reference ratios at equivalent output quality.
- Prefer a timing split for preprocessing or encoding, each model stage,
inter-stage transfer or communication, decoding or postprocessing, and output
assembly. Define the boundaries, account for overlap, reconcile the split with
end-to-end time, and explain any unavailable stage measurement.
Use [perf-verification.md](perf-verification.md) for the comparison protocol and
repository benchmark and profiling links.
## Remove accidental surface
Search bounded call sites for:
- inference-dead training `forward()` paths, unused factories/wrappers, never-set
branch keys, and immediately discarded parameters;
- duplicate payload strings, validation, or shape coercion across stages;
- compatibility aliases in brand-new code without an existing caller;
- private symbols re-exported as public API or module-level side effects.
Keep code only when it has a distinct live caller, invariant, or compatibility
contract. Prefer one typed producer-consumer schema to repeated string keys.
## Require proportionate evidence
- Run a representative production-path inference and assert output content, not
only process survival.
- Require profiling or A/B tables when the PR makes performance, memory,
precision, or quality claims, or when a suspected hot-path/device bug needs
that evidence. Do not impose fixed utilization or regression thresholds that
the repository does not define.
- Require focused registry/config/loading tests, a representative E2E path, and
user-facing model/usage documentation.
Use [diffusion.md](../modules/diffusion.md) for diffusion models and
[perf-verification.md](perf-verification.md) for quantitative claims.
@@ -0,0 +1,51 @@
# Performance and Accuracy Verification
Activate this reference when the PR adds a model or claims or intentionally
changes latency, throughput, memory, scaling, precision, or output quality.
Official docs: [profiling](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/profiling/),
[serving benchmarks](https://docs.vllm.ai/projects/vllm-omni/en/latest/cli/bench/serve/),
and [metrics](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/metrics/).
## Comparable A/B contract
Compare frozen base and head for an existing path. For a new model absent from
base, compare head with a pinned canonical reference implementation. Use the same:
- hardware, driver, software versions, model/checkpoint, and dependencies;
- input or dataset, seed, precision, batch/concurrency, topology, and feature
flags;
- warmup, measured repetitions, synchronization, timing scope, and memory
collection method.
Keep exact commands and report variability rather than a cherry-picked run.
Use the repository's benchmark when it covers the claim; otherwise use the
smallest reproducible workload that reaches the changed production path.
## Evidence table
| Dimension | Typical evidence |
| --- | --- |
| Latency | End-to-end latency and, when available, TTFT plus a defined per-stage and transfer-time split. |
| Throughput/scaling | Requests, tokens, frames, or audio duration per second across the claimed concurrency/topology. |
| Memory | Peak allocated/reserved device memory and OOM boundary if relevant. |
| Quality/accuracy | Repository metric or known-good output comparison with an explicit tolerance; paired samples when no metric exists. |
Every optimization needs correctness or quality evidence. A faster result on a
different workload, precision, seed, or topology is not a valid comparison.
## Reviewer verification ladder
1. Run base/head A/B on suitable hardware when affordable.
2. If only one side can run, verify the script and request a comparable pair.
3. If hardware or assets are unavailable, audit methodology, code path, and
contributor evidence; name the exact unverified claim.
Classify discrepancies before reporting: implementation regression, benchmark
bug, environmental drift, noise, or unsupported claim. Explain material
regressions against the PR's stated goal or repository contract; do not invent
universal percentage thresholds.
Report claimed and measured values together, bind them to the frozen SHAs and
environment, and keep unavailable hardware as a validation gap rather than a
fabricated pass.
@@ -0,0 +1,39 @@
# Test Quality Evaluation
Read this reference when tests change, a risky production path has no test, or
a test-only PR may not prove the intended behavior.
Official docs: [test system overview](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/ci/test_system_overview/)
and [test writing guide](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/ci/test_writing_guide/).
## Static proof check
For each changed semantic path, ask whether the test would fail if that behavior
were reverted or broken. Check:
- assertions pin the contract, not only non-null output, logs, or “no crash”;
- the production dispatcher, registry, connector, or scheduler is reached
instead of the changed behavior being mocked away;
- fakes preserve relevant types, MRO, shapes, devices, async behavior, and
lifecycle transitions;
- seeds, ordering, timing, synchronization, external services, and numeric
tolerances are deterministic or explicitly controlled;
- normal, invalid, boundary, feature-off, failure/cancellation, and regression
paths are covered where the diff changes them;
- run-level and domain markers place hardware/model tests in the intended CI
lane without silently skipping the contract.
Map source symbols to tests with bounded `rg` searches; do not assume the test
tree mirrors production paths.
## Runtime check
Run the narrowest affected tests supported by the environment. Record skipped
hardware/model cases as gaps. Classify failures as code, test, infrastructure,
or flaky before turning them into findings; one passing rerun does not erase a
flakiness signal.
Keep grades or matrices internal. Report only concrete code bugs or the one or
two test defects that leave changed behavior materially unprotected. Use
[tests-docs-checklist.md](tests-docs-checklist.md) for CI and documentation
coverage.
@@ -0,0 +1,48 @@
# Tests and Documentation Checklist
Use this reference to connect changed behavior to coverage, CI selection,
examples, documentation, and reproducible PR evidence.
Official docs: [test writing guide](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/ci/test_writing_guide/),
[test execution guide](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/ci/test_execution_guide/),
and [documentation guide](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/DOCS_GUIDE/).
## Coverage packet
For each high-risk change, record a compact internal packet:
```text
change and failure risk -> existing unit/E2E coverage -> uncovered boundary
-> smallest test and stable assertion that closes the gap
```
Prefer a regression test that fails on the frozen base for bug fixes. Check
numeric tolerances, deterministic inputs, realistic mocks, hardware/domain
markers, and Buildkite/CI wiring using the documentation present on the reviewed
branch. A skipped test is not a pass.
## Documentation sync
Require user-facing updates when the diff changes a model, feature, CLI/API,
config key, default, compatibility behavior, or supported platform. Verify:
- the actual docs navigation and support tables used by the branch;
- exact identifiers, defaults, constraints, known limitations, and migration;
- a minimal runnable example for newly exposed behavior;
- examples and docs agree on commands, parameters, output schema, and supported
modes;
- links and the bounded live contract build or resolve correctly.
Do not request docs for internal behavior with no user-visible contract.
## PR evidence
For contributor-run tests or benchmarks, require enough provenance to evaluate
the claim: hardware, relevant software versions, exact commands, inputs/model,
result, and approximate runtime. Performance or accuracy evidence must compare
base and head under equivalent conditions; use
[perf-verification.md](perf-verification.md).
Turn a missing test or document into a finding only when it protects or explains
changed behavior. Name the smallest useful addition rather than requesting a
broad coverage expansion.
@@ -0,0 +1,36 @@
# Active Verification
Read this reference when a runnable affected path and suitable local or remote
hardware are available. Never claim device evidence from static analysis or a
simulated backend.
Official docs: [installation](https://docs.vllm.ai/projects/vllm-omni/en/latest/getting_started/installation/)
and [test execution guide](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/ci/test_execution_guide/).
## Choose the narrowest level
| Available environment | Verification |
| --- | --- |
| Matching accelerator, model/assets, and server | Targeted unit/integration test plus one representative E2E request. |
| Matching accelerator without serving setup | Targeted model/runtime test and output or metric inspection. |
| CPU/static environment only | Import/version preflight, focused CPU tests, config/registry resolution, and static contract checks. |
| Missing dependencies or inaccessible hardware | Record the exact gap and evaluate contributor/CI evidence. |
## Execute safely
1. Bind the run to the frozen head SHA and record Python, platform, dependency,
model, device, and relevant environment fingerprints.
2. Run the smallest affected unit test before an E2E workload.
3. Exercise the changed public or production-dispatch path with bounded inputs.
4. Compare actual output, metrics, cleanup, and exit behavior with the PR claim.
5. For base/head claims, use the equivalent A/B protocol in
[perf-verification.md](perf-verification.md).
Avoid disturbing shared servers, ports, models, or accelerators without user
authorization. Do not install large dependencies, download gated assets, or
start remote workloads merely because hardware might exist.
Report the command, environment, result, and any skipped path. Classify failures
as change-induced, pre-existing, infrastructure, environment, or flaky before
making a finding. A hardware gap lowers confidence; it is not automatic proof
of a defect.
@@ -0,0 +1,105 @@
# Maintainer Review Style
Use this reference only when turning proved findings into comments. The baseline
maintainer samples favor short, direct comments and reserve long explanations
for architecture or non-obvious failure paths.
Official docs: [contributing and review process](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/).
## Evidence basis
This calibration used 928 PRs merged from 2026-05-10 through 2026-08-08.
Candidates were ranked by substantive human inline-review threads, then by
distinct reviewers and review rounds. Author self-comments, bots and AI
reviewers, and bodyless approvals were excluded. Counts selected the sample;
the practices below came from reading root comments and follow-up replies.
The main set contains the six leaders after filtering; three other high-ranked
PRs add core-runtime and benchmark coverage. All were merged.
| PR | Review boundary |
| --- | --- |
| [#2906](https://github.com/vllm-project/vllm-omni/pull/2906) | New TTS model, shared utilities, recipes, and request state. |
| [#3907](https://github.com/vllm-project/vllm-omni/pull/3907) | Full-duplex API, session lifecycle, concurrency, and realtime evidence. |
| [#2162](https://github.com/vllm-project/vllm-omni/pull/2162) | Diffusion world model, OpenPI serving, tests, examples, and docs. |
| [#3454](https://github.com/vllm-project/vllm-omni/pull/3454) | Diffusion model, generic CLI surface, loaders, and configuration scope. |
| [#4425](https://github.com/vllm-project/vllm-omni/pull/4425) | Structured configuration, typing, defaults, and compatibility. |
| [#5397](https://github.com/vllm-project/vllm-omni/pull/5397) | Distributed offload, collectives, failure handling, and load semantics. |
| [#4281](https://github.com/vllm-project/vllm-omni/pull/4281) | Composable parallelism, configuration contracts, and examples. |
| [#3628](https://github.com/vllm-project/vllm-omni/pull/3628) | Stage metrics, benchmark definitions, opt-in API behavior, and cleanup. |
| [#3855](https://github.com/vllm-project/vllm-omni/pull/3855) | Stage runtime, thread safety, startup, and compatibility. |
Historical comments calibrate delivery; they do not create merge policy. Live
code, tests, repository docs, and the current `CODEOWNERS` file remain
authoritative. When refreshing this study, promote a practice only when it
recurs across at least three PRs or is supported by current repository guidance.
## Recurring review behavior
- Start from a changed contract, not a style preference. State the exact
request, configuration, topology, or failure path that triggers the issue.
- Protect repository boundaries. Keep model-specific behavior in its domain,
move genuinely reusable logic to a shared module, and reuse existing loaders,
protocols, definitions, and config sources instead of bypassing them.
- Challenge unrelated scope and abstractions. Ask why a new flag, config, class,
helper, fallback, or file is needed when an existing path appears sufficient.
- Trace concurrency and terminal paths: overlapping requests, disconnect,
cancellation, partial failure, stale replies, collective schedule mismatch,
cleanup, and retry. Prefer an explicit startup error for unsupported
combinations over silently running with incomplete state or wrong weights.
- Preserve user-visible behavior across variants. An accepted CLI/API/config
field must be applied, explicitly rejected, or visibly warned about; compare
normal and headless, offline and online, and streaming and non-streaming paths.
- Ask for evidence at the affected boundary: a regression test using the real
tensor or protocol shape, correct pytest markers so CI runs it, comparable A/B
performance results, or an SLO-oriented latency/quality measurement.
- Keep interfaces explicit: avoid `Any` and opaque strings where a precise
union, enum, or typed envelope exists; remove dead code and duplicated
constants; validate requests before expensive execution.
- Document module scope and non-obvious invariants. Update examples, recipes,
supported-model/feature docs, and hardware assumptions when users rely on
them.
- When expertise crosses an ownership boundary, ask a named owner to inspect a
specific file or contract and explain why. Do not send a generic `PTAL` list.
- Keep non-blocking cleanup in a linked follow-up only after the current PR is
safe. If a revision fixes only part of a failure chain, continue the existing
thread with the remaining trigger instead of opening a duplicate finding.
## Write the finding
- Lead with the issue or decisive question; omit a review preamble.
- Name the concrete trigger and impact, then the smallest fix direction.
- Keep obvious fixes to one sentence. Use more detail only when the call path or
ownership boundary is otherwise unclear.
- Prefer one root-cause comment over repeated symptom comments.
- Hedge only when evidence is genuinely incomplete; mark that item as a
question or validation gap rather than overstating severity.
- Say briefly that no findings were found when the review is clean; zero
comments is a valid outcome when posting is authorized.
Useful forms:
```text
This leaves <state> allocated when <failure/cancellation path>. Release it in
the shared terminal cleanup path.
```
```text
Does this producer also update <consumer>? It still reads the old field here.
```
```text
With <configuration>, this bypasses <existing loader/validator>, so <impact>.
Reuse that path or reject this combination before startup.
```
```text
@<owner>, could you check <specific boundary>? This changes <contract> used by
<consumer>.
```
Use a priority label only for a proved high-impact defect. Avoid generic praise,
routine “Nit:” prefixes, decorative severity labels, audit templates, rule IDs,
comment-count narration, and “I left a few comments.” Keep approvals, review
events, reviewer requests, mentions, and GitHub replies subject to the user's
explicit authorization.
@@ -0,0 +1,99 @@
# Focused Code-Owner Review Requests
Read only when the user asks to identify, suggest, request, add, or ping
reviewers. Finding candidates is read-only; GitHub review requests and
`@mention` comments are external writes.
Owner sources, in order:
1. the reviewed head's
[CODEOWNERS](https://github.com/vllm-project/vllm-omni/blob/main/.github/CODEOWNERS)
for path ownership;
2. the active module design page's `owners` and `required_reviewers` metadata
for contract ownership and mandatory design review; and
3. documented
[governance expertise](https://docs.vllm.ai/projects/vllm-omni/en/latest/community/governance/)
for specialization and tie-breaking.
Resolve all three from the reviewed head when available because ownership
changes over time. Use published docs only to discover a page absent from an
older checkout, never to override the frozen head, and do not copy a static
owner list into review output. CODEOWNERS remains the path authority; module
metadata identifies contract experts and required design reviewers.
## Rank candidates
1. Freeze the PR head and collect changed files, author, requested reviewers,
submitted reviews, and existing comments.
2. Resolve the **last matching CODEOWNERS rule** for each changed file. Do not
union an earlier broad rule with a later specific rule.
3. Resolve the primary module and feature overlays through
[design-contracts.md](../process/design-contracts.md). Read the active module
page's status, `owners`, and `required_reviewers`; do not treat owners on an
archived, superseded, or unrelated page as current authority.
4. Group files by the selected primary owner and the exact module or feature
contract needing review. Weight production owners and live consumers above
tests/docs/CI owners and the repository-wide fallback. Include an applicable
`required_reviewers` entry even when it is not the path owner, and label why.
5. Use documented governance specialties only to choose among matching owners:
for example serving versus configuration, diffusion model versus cache or
parallelism, TTS versus generic model execution, or CI versus tests.
6. Exclude the PR author, bots, users who already completed the needed review,
and duplicate pending requests. Do not infer availability or invent
expertise from a username.
7. Select one reviewer for a single-owner change and at most three for a real
cross-module change. If more are plausible, rank them but do not ping a
broad group; ask the user before exceeding three.
If every specific owner is excluded, consider one repository-wide fallback
owner and label that choice as a fallback rather than a path match. Never fan
out to the full fallback list. Prefer a qualified owner who covers multiple
critical path groups over separate reviewers for each file. If CODEOWNERS is
missing or invalid, state that gap and use governance only as a labeled fallback.
Recent file history may break a tie only when CODEOWNERS and governance remain
ambiguous. Never use commit count alone to override an explicit current owner.
## Preview before writing
Show the user the exact candidate set and rationale:
```text
@owner — <owned paths or module role>; please verify <specific module or feature contract>.
```
Draft one consolidated comment tied to the frozen head:
```text
Requesting focused review for `<short-head-sha>`:
- @owner1: could you check the <module contract> in `<path/group>`?
- @owner2: could you check the <feature or cross-boundary contract> in `<path/group>`?
Relevant validation: <one concise result or exact remaining gap>.
```
Mention only owners being requested. Keep the reason specific enough that each
person knows what decision or invariant needs attention; do not post a generic
“please review” or a generated ownership audit.
## External-write gate
- “Who should review?”, “suggest reviewers”, or “draft a request” authorizes
only the preview.
- “Request/add these reviewers” authorizes the GitHub review-request mutation.
- “Ping/comment/tag the owners” authorizes the consolidated comment.
- When the user explicitly asks to request reviews **with an owner comment**,
both writes are authorized. Obey narrower wording when only one action is
requested.
Immediately before an authorized write, verify the PR is still open, the head
SHA is unchanged, and the candidate is not the author or already satisfied.
Report draft/WIP state and avoid notifications unless the user explicitly wants
reviewers requested before ready-for-review.
Use the GitHub connector for reviewer requests and the single top-level comment;
use `gh` only when connector coverage is unavailable. Do not submit an approval,
request-changes event, label, assignment, or multiple comments as part of this
action. After writing, reread the PR and report the reviewers requested and the
comment URL. If the head changed, discard the draft and rerank before posting.
@@ -0,0 +1,24 @@
# Communication Features
Use with the OmniConnector, stage-runtime, configuration, and I/O module
contracts. Load the concrete backend design from the reviewed head:
| Backend | Design |
| --- | --- |
| Mooncake store | [MooncakeStoreConnector](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/omni_connectors/mooncake_store_connector/) |
| Mooncake transfer engine | [MooncakeTransferEngineConnector](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/omni_connectors/mooncake_transfer_engine_connector/) |
| Mori transfer engine | [MoriTransferEngineConnector](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/omni_connectors/mori_transfer_engine_connector/) |
| Shared memory | [SharedMemoryConnector](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/omni_connectors/shared_memory_connector/) |
| Yuanrong store | [YuanrongConnector](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/omni_connectors/yuanrong_connector/) |
| Yuanrong transfer engine | [YuanrongTransferEngineConnector](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/omni_connectors/yuanrong_transfer_engine_connector/) |
## Feature checks
- Verify dependency, service, device/network, port, memory-pool, and environment
prerequisites with actionable startup errors.
- Match key/metadata construction, sender and receiver roles, allocation,
ownership, completion, and supported fast/serialized paths.
- Exercise timeout, retry, stale sender/buffer reclamation, partial transfer,
cancellation, and connector close semantics.
- Validate the smallest supported same-host or cross-node topology and document
backend limitations and operational diagnostics.
@@ -0,0 +1,26 @@
# Diffusion Acceleration Features
Use with the exact diffusion submodule plus platform, cache, quantization, or
benchmarking contracts selected by the live path.
| Feature family | Designs |
| --- | --- |
| Parallelism | [CFG](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/cfg_parallel/), [Expert](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/expert_parallel/), [HSDP](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/hsdp/), [Pipeline](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/pipeline_parallel/), [Sequence](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/sequence_parallel/), [Tensor](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/tensor_parallel/), [VAE patch](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/vae_parallel/) |
| Attention | [Skip-Softmax](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/skip_softmax/) |
| Quantization | [Quantization](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/quantization/) |
| Cache | [Cache-DiT](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/cache_dit/), [TeaCache](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/teacache/) |
| Batching | [Diffusion Continuous Batching](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/diffusion_continuous_batching/) |
| Offload | [Distributed Layerwise Offload](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/distributed_layerwise_offload/) |
## Feature checks
- Verify feature selection, supported models/platforms/topologies, defaults,
dependencies, and every touched feature combination.
- Preserve feature-off and single-rank correctness; reject unsupported
combinations before collectives, loading, or execution begin.
- Trace shapes, shards, ranks, collectives, precision, cache validity, residency,
and per-request state through the selected runtime hooks.
- Compare output quality or accuracy against the disabled/reference path before
accepting latency or memory improvements.
- Require exact commands, topology, environment, warmup, repetitions, and
measurements for performance claims; update feature compatibility docs.
@@ -0,0 +1,22 @@
# Infrastructure and Performance Features
Load the matching design from the reviewed head:
- [Prometheus Metrics](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/metrics/)
for logger wrapping, gating, lifecycle, stage transfer, and metric definitions.
- [Speech Generation Performance Optimizations](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/qwen3_omni_tts_performance_optimization/)
for stage batching, CUDA graphs, async chunk, streaming, re-prefill, compile,
and deployment evidence.
## Feature checks
- Route instrumentation changes through observability or profiling and result
methodology through benchmarking and the performance evidence check.
- Preserve opt-in/default behavior, units, labels, aggregation, timing scope,
lifecycle resets, and bounded overhead.
- For stacked optimizations, measure each increment against the same baseline
and explain interactions, quality guards, regressions, and limitations.
- Require exact model, checkpoint, hardware, software, workload, topology,
concurrency, warmup, repetitions, and production commands.
- Update the design page when metric meaning, supported optimization stack, or
deployment guidance changes.
@@ -0,0 +1,24 @@
# Runtime and Stage Execution Features
Load the matching design from the reviewed head:
| Feature | Design | Primary module intersections |
| --- | --- | --- |
| Disaggregated inference | [Design](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/disaggregated_inference/) | Configuration, stage runtime, OmniConnector, I/O contracts |
| Async chunk | [Design](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/async_chunk/) | Model integration, orchestration, stage runtime, connector, I/O |
| Async diffusion output | [Design](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/async_diffusion_output/) | Diffusion runtime, I/O contracts, entrypoints |
| Async Omni output materialization | [Design](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/omni_async_output_materialization/) | AR runtime, model integration, I/O contracts, orchestration |
| Automatic prefix caching | [Design](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/feature/prefix_caching/) | AR runtime, cache management, I/O contracts |
## Feature checks
- Confirm the feature's supported models, entrypoints, stage types, topology,
configuration, default, and compatibility limitations.
- Trace enablement from public/config ingress through every participating module
and verify the advertised production dispatch actually selects it.
- Preserve a correct disabled or fallback path and make unsupported combinations
fail or warn as documented.
- Test overlap, ordering, identity, backpressure, cancellation, failure, final
partial output, and cleanup at each asynchronous boundary.
- Update the feature page, support matrices, examples, and recipes when behavior
or coverage changes.
@@ -0,0 +1,22 @@
# Autoregressive Runtime
Primary design: [Autoregressive Runtime](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/ar_runtime/).
Use for AR request queues, scheduling state, token and memory budgets, KV/input
readiness, workers, runners, and upstream vLLM request/cache transitions.
## Contract checks
- Preserve upstream request-state, scheduling, cache, and preemption semantics
unless an Omni-specific difference is documented and tested.
- Convert modality-specific data through explicit input or output adapters; do
not inject it through unrelated scheduler state.
- Keep workers and model runners focused on assigned execution rather than
admission or cross-stage routing.
- Synchronize token, sequence, batch, and memory budgets with worker-visible
state and prevent starvation, double counting, or stale readiness.
- Preserve legal transitions and one terminal cleanup path across completion,
abort, timeout, preemption, worker failure, and shutdown.
Test request lifecycle, scheduling decisions, abort, cache state, adapters, and
every affected worker execution mode against the pinned upstream contract.
@@ -0,0 +1,24 @@
# Benchmarking
Primary design: [Benchmarking](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/benchmarking/).
Use when benchmark code, workloads, metric calculations, CLI benchmark
entrypoints, or result metadata change. Use the performance check separately
when a PR uses benchmark results as evidence.
## Contract checks
- Record model and revision, code SHA, hardware, software, configuration,
workload, precision, topology, concurrency, warmup, repetitions, and
measurement window.
- Validate successful and semantically acceptable outputs before accepting
timing, memory, or scaling results.
- Define every metric's unit, population, aggregation, synchronization, and
timing scope.
- Keep workload parsing and metric computation deterministic and reusable
across base and head.
- Reject comparisons that change material workload or runtime settings without
isolating and explaining that difference.
Test workload parsing and metric calculations with deterministic fixtures and
publish exact commands plus variability for quantitative claims.
@@ -0,0 +1,22 @@
# Cache Management
Primary design: [Cache Management](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/cache_management/).
Use for AR or diffusion cache identity, reusable state, validity, lifecycle,
reset, eviction, and teardown.
## Contract checks
- Include every model, request, input, timestep, precision, device, topology,
and feature property that can change a reused value in cache identity.
- Preserve a correct disabled and miss path; never reuse after validity inputs
change.
- Isolate request-scoped state across concurrent requests and define ownership
for model-scoped state.
- Make reset, invalidation, eviction, capacity, and teardown explicit on
completion, cancellation, failure, model reload, and shutdown.
- Keep cache optimizations behind the owning runtime's hooks rather than adding
a second request lifecycle.
Test hit, miss, invalidation, disabled behavior, concurrency, capacity, reset,
and teardown, with quality comparison when reuse is approximate.
@@ -0,0 +1,24 @@
# vLLM-Omni Configuration
Primary design: [vLLM-Omni Configuration](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/vllm_omni_config/).
Use for config construction, deploy YAML, registries, schema, defaults,
aliases, CLI projection, stage config, and topology. Inspect the reviewed
page's status: while its contract remains deferred or draft, current code and
tests—not proposed precedence rules—are authoritative.
## Contract checks
- Resolve each supported structured, legacy, CLI, environment, default, alias,
and stage-override producer through its actual runtime consumer.
- Reject unknown or owner-mismatched fields explicitly; keep process-local
runtime objects out of transportable configuration.
- Verify default, explicit, and feature-off values reach every live factory and
consumer without silent reinterpretation.
- Treat stage count, placement, connector, parallelism, device, and memory
fields as one topology contract and reject impossible combinations early.
- Preserve supported construction-path parity until a documented migration
removes a path.
Require normalization and schema tests, a live-consumer assertion, and docs for
public keys, defaults, constraints, precedence, or migration behavior.
@@ -0,0 +1,33 @@
# Diffusion Module Family
Primary design: [Diffusion Modules](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/diffusion/).
Use for diffusion-stage behavior, then load the exact submodule page from the
reviewed head:
| Submodule | Signals | Design |
| --- | --- | --- |
| Runtime | Admission, scheduling, execution, progress, outputs, cancellation, hooks, cleanup | [Diffusion Runtime](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/diffusion/diffusion_runtime/) |
| Model Integration | Pipelines, registry, loader, adapters, shared layers, model-specific processing | [Diffusion Model Integration](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/diffusion/diffusion_model_integration/) |
| Continuous Batching | Compatibility, request/step batches, per-request progress, capacity | [Continuous Batching](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/diffusion/continuous_batching/) |
| Parallelism | Rank topology, process groups, sharding, collectives, distributed execution | [Parallelism](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/diffusion/parallelism/) |
| Offloader | Residency, transfers, memory accounting, prefetch, teardown | [Offloader](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/diffusion/offloader/) |
## Family-wide checks
- Keep one scheduler-owned lifecycle from admission through completion,
cancellation, failure, and cleanup; optional features must use defined hooks.
- Select pipelines through registry and loader contracts instead of scattered
model-name conditionals; keep genuine model differences in model directories.
- Trace latent, conditioning, timestep, generator, shape, layout, dtype, device,
batch expansion, and output conversion through the actual consumer.
- Make batch compatibility and per-request isolation explicit; never associate
output by unstable batch position.
- Derive topology from validated configuration, define every sharding boundary,
keep collectives symmetric, and preserve a supported single-rank path.
- Track one residency owner per offloaded component, wait for transfer readiness,
preserve model state, bound retained copies, and clean up deterministically.
Load matching feature designs for cache, quantization, parallelism, continuous
batching, or offload. Require feature-off correctness, representative inference,
terminal-path tests, and quality evidence for optimizations.
@@ -0,0 +1,23 @@
# Engine Orchestration
Primary design: [Engine Orchestration](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/engine_orchestration/).
Use for request-state creation, cross-stage routing, output ordering, companion
tracking, RPC correlation, cancellation propagation, and terminal convergence.
Orchestration does not own replica placement, stage-process startup, public
rendering, connector transport, or payload and error schemas.
## Contract checks
- Keep one owner for cross-stage routing; entrypoints, models, and stage clients
must not independently select the next logical stage.
- Preserve request identity and output order across concurrent stages and
correlate every control or RPC result to the originating request and wave.
- Make terminal state monotonic: no new forwarding after success, abort,
request failure, or fatal engine failure.
- Propagate cancellation and failure to every active stage and release
orchestrator-owned tasks, queues, companions, and request state.
- Preserve shutdown ordering across the orchestrator and stage runtime.
Test representative multi-stage routing, ordering, correlation, cancellation,
failure, and repeated shutdown.
@@ -0,0 +1,25 @@
# Entrypoints and Serving Boundaries
Primary design: [Entrypoints and Serving Boundaries](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/entrypoints/).
Use for offline APIs, CLI and server composition, OpenAI-compatible routes,
request validation, response conversion, streaming, sessions, and engine
handoff. Entrypoints adapt public contracts; they do not own cross-stage
routing, stage lifecycle, configuration precedence, payload schemas, or error
classification.
## Contract checks
- Normalize and validate public values once before engine submission.
- Preserve request identity, modality, ordering, and exactly one terminal event
across streaming, disconnect, cancellation, and failure.
- Translate internal outputs and errors explicitly for each advertised offline,
HTTP, SSE, WebSocket, or asynchronous-job path.
- Keep model-specific behavior behind a common adapter or processor instead of
adding model-name policy to generic entrypoints.
- Require API or CLI changes to explain necessity, alternatives, compatibility,
migration, and the supported route or transport matrix.
Test the affected public protocol, normalization, engine handoff, rendering,
and terminal outcomes. Route orchestration, I/O schema, and semantic error
changes to their module contracts.
@@ -0,0 +1,24 @@
# Error Classification, Propagation, and Rendering
Primary design: [Error Classification, Propagation, and Rendering](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/error_contracts/).
Use when a change classifies failures, crosses process boundaries, decides
fatal versus request-scoped impact, sanitizes context, or renders offline,
HTTP, SSE, WebSocket, or asynchronous-job errors. The I/O module owns the wire
schema; this module owns the meaning of its error fields.
## Contract checks
- Keep request-scoped failure isolated unless the underlying engine is no
longer usable.
- Preserve stable classification and request context across process and
protocol boundaries without exposing prompts, outputs, secrets, or internal
stack details.
- Keep cancellation distinguishable from internal failure.
- Terminate each public transport exactly once with consistent status, body,
event, finish reason, and metrics classification.
- Maintain compatibility across mixed or older producers only when the
reviewed contract defines that behavior.
Test table-driven classification, wire round trips, fatal/request-scoped
propagation, cancellation, sanitization, and every affected public renderer.
@@ -0,0 +1,23 @@
# Execution Platforms
Primary design: [Execution Platforms](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/execution_platforms/).
Use for hardware capability detection, worker selection, patches, kernels,
attention backends, and vendor-specific configuration or connectors.
## Contract checks
- Guard hardware behavior through platform selection or capability detection
and fail clearly when unsupported.
- Keep portable modules free of direct vendor imports when a common selector
exists; verify portable imports without the target accelerator.
- Override only behavior that differs from common or upstream implementations,
and compare sibling worker hooks when inheritance does not provide parity.
- Preserve dtype, layout, rank, stream, synchronization, workspace,
graph-capture, and resource-lifetime contracts.
- Do not let simplified CPU doubles hide platform MRO, initialization, or
dispatch failures.
Run portable checks first, then the smallest matching-device test in a fresh
environment. Report unavailable hardware as a validation gap, never simulated
device evidence.
@@ -0,0 +1,23 @@
# Input, Output, and Modality Contracts
Primary design: [Input, Output, and Modality Contracts](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/input_output_modality_contracts/).
Use for requests, prompt and modality types, message schemas, serialization,
output types, accumulation, completion, and compatibility shims crossing
entrypoint, orchestration, stage, connector, or model boundaries.
## Contract checks
- Give every boundary value an explicit modality and validated typed schema.
- Preserve request and stage identity across conversion, serialization,
streaming updates, batching, cancellation, and errors.
- Distinguish partial, final, empty, and failed output states for every modality.
- Verify producer and consumer agreement on shape, layout, dtype, device,
ownership, metadata, ordering, and optional or unknown fields.
- Keep internal objects out of public protocols; translate them at the owning
entrypoint.
- Preserve wire compatibility deliberately and give deprecated shims a bounded
migration path.
Require construction, round-trip, accumulation, completion, rejection, and
compatibility tests at each changed producer-consumer boundary.
@@ -0,0 +1,25 @@
# Model Integration
Primary design: [Model Integration](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/model_integration/).
Use for model registration, configuration adapters, preprocessing, checkpoint
loading, stage inputs, model-specific hooks, shared layers, runners, and model
execution. Use the diffusion family reference for diffusion models.
## Contract checks
- Declare explicitly how the model class, loader, input processor, stage
configuration, and runtime capabilities are selected.
- Preserve weight-name mapping, dtype/device placement, optional-dependency
errors, and checkpoint-specific loading semantics.
- Trace each typed input and output through preprocessing, runner state, model
call, and its actual consumer.
- Reuse upstream vLLM behavior when sufficient; document and test the precise
difference for every override or patch.
- Keep model code out of admission, cross-stage routing, public policy, and
terminal lifecycle ownership.
- Place reusable behavior in shared modules and test it with more than one
integration.
Require focused registry, loader, processor, runner, and representative model
execution tests. Apply the model-addition check for new or expanded support.
@@ -0,0 +1,21 @@
# Observability
Primary design: [Observability](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/observability/).
Use for metrics, logs, correlation fields, and cross-stage request visibility.
## Contract checks
- Preserve stable request and stage identity across entrypoints, orchestration,
stages, workers, errors, and terminal cleanup.
- Treat metric names, units, labels, aggregation, and lifecycle as public
contracts; document any semantic change.
- Keep labels bounded: never use request IDs, prompts, outputs, paths, or other
unbounded user values.
- Register and reset metrics exactly once across repeated startup and shutdown,
and keep disabled instrumentation inexpensive.
- Align emitted values with their actual timing and lifecycle owner rather than
reconstructing them from ambiguous client strings.
Test registration, label sets, units, resets, error classification, and
representative multi-stage emission.
@@ -0,0 +1,24 @@
# OmniConnector
Primary design: [OmniConnector](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/omni_connector/).
Use for connector contracts and model-agnostic data transfer across stages,
processes, devices, or nodes. Connector implementations transport and
synchronize data; they do not choose the next stage or implement model policy.
## Contract checks
- Prove producer and consumer agreement on request/stage identity, shape,
layout, dtype, placement, ownership, ordering, and completion.
- Keep backend selection and metadata/key construction explicit; do not silently
reinterpret or drop payloads across SHM, store, network, or vendor paths.
- Bound connect, put/get, retry, synchronization, and readiness waits with
backpressure, cancellation, and actionable errors.
- Prevent route, endpoint, port, key, and buffer collisions across repeated
startup, concurrent requests, and replica replacement.
- Release connections, handles, buffers, listener work, and stale sender state
on success, cancellation, failure, and shutdown.
Load the matching communication feature design for a concrete backend. Require
focused producer-consumer tests and the smallest runnable multi-process or
multi-node path.
@@ -0,0 +1,21 @@
# Profiling
Primary design: [Profiling](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/profiling/).
Use for opt-in instrumentation and trace collection across supported profiler
backends.
## Contract checks
- Keep expensive collection disabled by default and bounded by explicit start,
stop, timeout, and cleanup behavior.
- Preserve scheduling, generated outputs, resource ownership, and concurrency
semantics apart from documented synchronization overhead.
- Include stage, rank, worker, operation, and request correlation where useful
without embedding user payloads or secrets.
- Make repeated start/stop and partial failure safe, including multi-rank trace
naming and artifact ownership.
- Measure disabled and enabled overhead before making performance claims.
Test the disabled path, repeated lifecycle, failure cleanup, trace context, and
each affected backend.
@@ -0,0 +1,22 @@
# Quantization
Primary design: [Quantization](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/quantization/).
Use for method registration, checkpoint interpretation, layer replacement,
reduced precision, platform capability, and runtime constraints.
## Contract checks
- Validate checkpoint metadata, selected method, supported layers, device
capability, required dependencies, and parallel layout before loading.
- Preserve loader and weight-name mapping semantics, dtype, scale/granularity,
zero point, padding, and buffer handling through the real kernel consumer.
- Fail clearly for unsupported combinations; do not silently choose a different
method or precision.
- Keep online and pre-quantized checkpoint paths explicit and ensure patches or
fallbacks do not bypass model-owned loaders.
- Require numerical comparison against a defined reference with explicit
tolerance before treating performance results as valid.
Test registration, loading, representative layers, metadata, platform guards,
parallel combinations, and numerical correctness separately from performance.
@@ -0,0 +1,23 @@
# Stage Runtime and Replica Lifecycle
Primary design: [Stage Runtime and Replica Lifecycle](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/module/stage_runtime/).
Use for local or distributed placement, startup, readiness, stage pools,
replica identity and membership, selection, affinity, liveness, draining, and
stage-client or process lifecycle. Cross-stage request policy belongs to engine
orchestration; model scheduling belongs to the owning runtime.
## Contract checks
- Acquire, replace, and retire replicas through one stage-runtime lifecycle.
- Preserve stable replica identity and request affinity until termination or a
declared replica loss.
- Make readiness explicit before admission; surface partial-startup and
membership failures without leaving half-initialized capacity.
- Keep local and distributed semantics aligned for supported modes.
- Make drain, shutdown, and cleanup idempotent across repeated signals and
process failure.
Test startup, readiness, selection, affinity, membership changes, abort,
process loss, draining, and repeated shutdown on affected local/distributed
paths.
@@ -0,0 +1,34 @@
# Resolve Design Contracts
Use after freezing the review head and before selecting module or feature
references. The maintained [design index](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/)
defines two routing axes:
- **Module designs** own code boundaries and invariants. Select one primary
module and a second only when the live producer-consumer path crosses it.
- **Feature designs** describe behavior spanning modules. Load every feature
page whose implementation, default, support, or contract changes.
## Resolution order
1. Open `docs/design/index.md` in the reviewed head, not the reviewer's checkout
or published latest tree.
2. Match changed behavior against each module page's `primary_code_paths`,
`primary_path_exceptions`, ownership boundary, and `depends_on` metadata.
3. Read `status`, `architecture_state`, `last_verified_commit`, and any linked
in-flight work before treating prose as current behavior.
4. Use current code and tests when a page is draft, deferred, stale, absent, or
conflicts with the frozen implementation. Report material documentation
drift separately.
5. Treat candidate invariants and promotion gates as review questions until
repository policy, current code/tests, or owner-approved normative text
makes them enforceable. Do not turn a draft identifier into an automatic
blocker.
6. Use published latest docs only for discovery when the reviewed head lacks a
page; never import a newer contract into an older branch silently.
When behavior changes an active module or feature contract, require the same PR
to update that page. Require a new page only when repository policy, an accepted
RFC/issue, or explicit maintainer acceptance criteria do so; otherwise treat it
as a non-blocking design suggestion. Do not demand a second page when an existing
design already owns the exact contract.
@@ -0,0 +1,129 @@
# General Review Checks
Apply these checks to every PR after freezing the review surface. A pattern is
not a finding until the diff introduces or exposes a reachable trigger, impact,
and smallest safe fix. Do not report unrelated backlog.
Official docs: [contributing guide](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/)
[feature compatibility](https://docs.vllm.ai/projects/vllm-omni/en/latest/user_guide/feature_compatibility/),
and [design documents](https://docs.vllm.ai/projects/vllm-omni/en/latest/design/).
## Contract and scope
- Match the title/body claims to every changed production path, test, config,
dependency, generated artifact, and user-visible document.
- Trace each changed value through public ingress, validation/defaulting,
producer, transformations, process or device boundaries, final consumer, and
terminal cleanup.
- Check every applicable sync/async, offline/online, streaming/non-streaming,
feature-off, topology, and compatibility path without demanding unsupported
modes merely for symmetry.
## Module, API, and class design
Apply these rules to new or materially changed production code; do not require
unrelated cleanup from untouched files.
1. Start each source module with a concise module docstring that defines its
responsibility and boundaries and identifies its primary classes and key
functions. Place it after any required license header and before imports.
2. Give every added or materially changed class and function a clear docstring
covering its responsibility, parameters, return value, raised exceptions,
and non-obvious invariants. Use explicit typed parameters at owned API
boundaries; avoid opaque `**kwargs` and `Any`. Allow them only when an
upstream or compatibility interface requires them, and document and validate
the accepted keys and concrete types.
3. Move stable helpers shared by multiple features into an appropriately scoped
utility module. Do not let feature modules accumulate large collections of
unrelated private utility functions; keep a private helper local only when
it is single-purpose and tightly coupled to that feature.
4. Keep every method on a key class within that class's stated responsibility,
and document non-obvious design decisions and invariants. Before adding a
method, prefer reuse, consolidation, or extension of an existing abstraction;
split the class when new behavior creates a separate responsibility or makes
the class unnecessarily long.
5. Require changes to user-facing behavior to update `docs/`. When an existing
active module or feature design page owns the changed contract, update that
page. Require a new design page only when the reviewed branch's repository
policy, an accepted RFC/issue, or explicit maintainer acceptance criteria do
so; otherwise suggest it as non-blocking. For a major architectural change,
apply the branch's contributing policy for a design RFC or issue; the current
policy uses more than 500 changed production-code lines, excluding kernel,
data, config, and test changes. Resolve page status and authority through
[design-contracts.md](design-contracts.md), and do not demand a duplicate page
when an existing design owns the exact contract. When required, cover scope,
data flow, public contracts, failure behavior, alternatives, validation,
limitations, and rollout.
6. Require every performance PR to provide reproducible base-versus-head A/B
results under the same hardware, software, model, workload, precision,
topology, warmup, repetitions, and measurement scope. Include exact commands,
variability, and a correctness or quality guard; one-sided or non-comparable
numbers are incomplete evidence. For a new model absent from the frozen base,
compare head with its pinned canonical reference implementation under rule 12
instead. Follow
[perf-verification.md](../checks/perf-verification.md) for the full protocol.
7. Require every addition, removal, default change, or semantic change to a
user-facing inference API or CLI to explain why it is necessary, which
alternatives were considered, and why the chosen interface is preferable.
Record compatibility, deprecation or migration behavior, and the rationale
in the PR. Update the corresponding module and feature design documents when
they define the changed interface or workflow, or when policy requires one.
8. Require every bug-fix PR to add an automated regression test that reproduces
the defect on the frozen base and passes on the fixed head. Exercise the
production path or nearest stable boundary and assert the corrected behavior,
not only process survival. Record the exact base/head command and result, and
place hardware- or model-specific coverage in the correct CI lane. A manual
reproduction supplements but does not replace the regression test.
9. Require every new or materially changed recipe to follow
[`recipes/TEMPLATE.md`](../../../../../recipes/TEMPLATE.md) and the naming and
layout conventions in
[`recipes/README.md`](../../../../../recipes/README.md).
Complete every applicable summary, use-case, reference, hardware,
environment, exact-command, verification, and notes section with tested,
reproducible details; explain any intentional deviation in the PR.
10. Require every new model to verify its supported modalities, platforms,
execution modes, and features with production-path evidence. Update
`docs/models/supported_models.md` and every applicable feature support or
compatibility table; do not claim support that the PR does not validate.
Follow
[model-addition-checklist.md](../checks/model-addition-checklist.md) for the
model-specific documentation checks.
11. Require every new model PR to add or update its in-repository model-family
recipe under `recipes/` and its `recipes/README.md` index entry. Apply rule
9, and keep the recipe's model identifiers, tasks, serving modes, hardware,
commands, supported features, and limitations aligned with validated PR
evidence. An external recipe link does not replace the in-repository recipe.
12. Require every new model to compare accuracy or output quality and performance
against a pinned baseline or canonical reference implementation. Match the
checkpoint, inputs, precision, hardware, workload, and measurement method;
provide exact commands, results, and explanations for material differences.
Prefer a detailed timing split for each stage and explain when it is
unavailable. Follow
[model-addition-checklist.md](../checks/model-addition-checklist.md) and
[perf-verification.md](../checks/perf-verification.md) for the evidence
contract.
## Blocking risk scan
| Risk | Prove before reporting |
| --- | --- |
| Correctness | A live input reaches a wrong output, exception, silent drop, shape/dtype/device mismatch, or partially initialized state. |
| Compatibility | A supported API, config key, default, serialization schema, model identifier, or caller breaks without validation, migration, or deprecation. |
| Lifecycle | Allocation or startup lacks cleanup on partial failure, timeout, cancellation, shutdown, or repeated requests. |
| Concurrency/distribution | Ordering, identity, rank, world size, completion, timeout, backpressure, or collective assumptions fail on a supported path. |
| Cache/shared state | Identity omits a correctness-affecting input, or isolation, invalidation, disabled behavior, eviction, or cleanup is incomplete. |
| Async behavior | Blocking I/O, sleep, a lock across `await`, or unnecessary serialization harms a reachable async path. |
| Security/data handling | Secrets, user payloads, unsafe deserialization/eval/shell, unvalidated paths, or unbounded metric labels are reachable. |
| Validation evidence | Tests bypass the production dispatcher, mock away the change, use unrealistic types/MRO, or cannot fail when the defect returns. |
| User contract | User-visible model, feature, API, CLI, config, default, or compatibility behavior changes without accurate docs or examples. |
Search bounded callers and sibling implementations before reporting dead code,
duplication, or a missed consumer. Keep new abstractions only when they have a
distinct live caller, invariant, or compatibility need.
## Finding bar
Anchor each finding to a changed `path:line`; name the trigger or call path,
current behavior, impact, and smallest fix direction. Treat pending CI, missing
hardware, or unsupported measurements as validation gaps unless the repository
contract makes that evidence a merge requirement.
@@ -0,0 +1,191 @@
# Review Execution and Delivery
Use this reference for every review. It defines snapshot collection, gates,
validation records, delivery permissions, maintainer tone, and re-review.
Official docs: [contributing guide](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/)
and [CI failure triage](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/ci/failures/).
## Contents
- [Freeze the review surface](#freeze-the-review-surface)
- [Report status before analysis](#report-status-before-analysis)
- [Apply review gates](#apply-review-gates)
- [Run bounded validation](#run-bounded-validation)
- [Deliver maintainer-style findings](#deliver-maintainer-style-findings)
- [Re-review safely](#re-review-safely)
## Freeze the review surface
For a GitHub PR, read the base/head SHA before and after fetching metadata and
the diff:
```bash
gh api "repos/vllm-project/vllm-omni/pulls/<PR>" \
--jq '{base_sha: .base.sha, head_sha: .head.sha}'
REVIEW_FIELDS="number,url,title,body,isDraft,baseRefName,headRefName,mergeable,mergeStateStatus,statusCheckRollup,files"
gh pr view <PR> --repo vllm-project/vllm-omni \
--json "${REVIEW_FIELDS}"
gh pr diff <PR> --repo vllm-project/vllm-omni
gh api "repos/vllm-project/vllm-omni/pulls/<PR>" \
--jq '{base_sha: .base.sha, head_sha: .head.sha}'
```
Discard the snapshot if either SHA changed. Do not mix comments or validation
from different heads.
After the SHAs stabilize, fetch and materialize a trusted `head_sha` in an
isolated detached worktree. Run every source read, `rg` search, import, and test
from that snapshot, not the caller's checkout. A detached worktree provides
snapshot isolation, not a security boundary.
Treat a fork head as untrusted unless the user and environment policy explicitly
establish trust. Never run its imports, tests, builds, hooks, package setup, or
repo-configurable linters/plugins on the reviewer host. Execute them only in a
disposable sandbox or VM with no credentials or inherited secrets, no host agent
or service sockets, minimal read-only host mounts, disabled or explicitly
allowlisted network, resource/time limits, and destruction after the run. If
that boundary is unavailable, limit the review to the remote diff, SHA-addressed
reads such as `git show <head_sha>:<path>`, and existing CI evidence; report all
executable validation as a gap.
Before the first source read, record a pristine snapshot fingerprint outside
the reviewed worktree. Include `HEAD`, the NUL-delimited index entries and blob
IDs, and a NUL-safe manifest of every worktree entry except Git metadata,
including tracked, untracked, and ignored paths with file type, mode, symlink
target, and content hash. Before each validation group and delivery, recompute
and byte-compare the fingerprint as well as asserting `HEAD == head_sha`. If a
tool changes or creates any entry, discard affected evidence and recreate the
snapshot before another group; do not rely on `HEAD` alone or clean an unknown
worktree in place. If an exact snapshot cannot be created, use SHA-addressed
reads and report filesystem-dependent validation as a gap.
For a local branch/worktree, determine the target ref from the user, current PR,
or configured upstream; never infer it from the branch name. Resolve the target
once and include all task-owned worktree state:
```bash
git status --porcelain=v2 -z
git rev-parse HEAD
git rev-parse <target-ref>
git merge-base <target-base-sha> HEAD
git diff --stat <comparison-commit>
git diff --name-status <comparison-commit>
git diff --binary <comparison-commit>
git diff --cached --binary <comparison-commit>
git diff --binary
git ls-files --others --exclude-standard -z
```
Freeze the exact bytes of every in-scope untracked file from the NUL-delimited
list, plus a NUL-safe path, file-type, mode, and content-hash manifest. Also
fingerprint `HEAD`, the target and merge base, porcelain status, and both binary
index and worktree patches. Recording only untracked names is insufficient.
Keep these snapshots in the evidence packet and do not mutate the reviewed
checkout during a read-only review.
For local changes without PR metadata, mark the title/body as synthetic. Base
them on the user request and commit messages without inventing validation claims.
If no PR, branch, or usable worktree is identifiable, ask for a PR URL/number or
explicit base and head rather than guessing.
## Report status before analysis
Within 60 seconds of starting, and before source searches or tests, send this
host update:
```text
Pinned head: <SHA>
Base/comparison: <ref and SHA>
CI: <pass/fail/pending/not applicable>
Mergeability: <state/not applicable>
Preliminary findings: <brief finding or none yet>
```
Mark early findings as preliminary and continue. This is not a GitHub comment.
## Apply review gates
- Report draft/WIP state. Continue a local review when explicitly requested,
but do not publish review events without separate authorization.
- Record DCO, pre-commit, required CI, and mergeability. Pending or unknown gates
do not block source review.
- Treat a failed gate as its own evidence. Do not restate its formatting/lint
output as a new code-review finding.
- Open CI logs only when the first failing step overlaps the frozen diff or
blocks the verdict. Start with the first error, not the last cascade.
- Treat the PR body as navigation. Commands, benchmark tables, and claimed tests
become evidence only after their provenance and relevance are checked.
## Run bounded validation
Keep one evidence packet for files read, bounded searches, callers, tests, CI,
hardware, routes, and findings. Reuse it rather than refetching facts.
Before pytest, run a short import/version compatibility check. Record each
validation result with:
```text
repo, head SHA, command, result, Python/platform, dependency or lock fingerprint
```
After preflight, run targeted tests and low-cost static checks alongside source
inspection when possible. Imports, tests, builds, and linters may create caches
or rewrite files, so isolate each potentially mutating group in a disposable
snapshot or recreate the pinned snapshot before continuing. Map source symbols
to tests with bounded `rg` searches rather than assuming the test directory
mirrors production paths.
Classify failures as code, test, infrastructure, or flaky before reporting.
Skipped hardware tests are gaps, not passes. For available hardware, verify the
smallest representative unit/E2E path and compare actual output with PR claims.
## Deliver maintainer-style findings
Default to roughly 1-5 short comments, but treat that as calibration rather than
a quota: report every real blocker and report no finding when there is no issue.
Write each finding as:
```text
[P1] Short imperative title — path/to/file.py:<line>
<Trigger or call path>. <Current behavior and impact>. <Smallest fix direction>.
```
Use [maintainer-style-study.md](../delivery/maintainer-style-study.md) for
comment tone.
Keep rule IDs, grades, and audit matrices internal unless the user asks for the
complete audit.
Verify every inline `path:line` against the frozen diff before delivery. For a
PR, re-read the remote head and byte-compare the detached snapshot fingerprint,
or recreate it from `head_sha`, before asserting current lines. For a local
review, recompute and byte-compare the frozen `HEAD`, target, merge base, status,
index patch, worktree patch, and untracked-content manifest. Any mismatch makes
the review stale; discard the affected evidence and restart. Prefer one
root-cause comment to several symptom comments.
Local presentation is the default. Only explicit authorization permits GitHub
posting. When authorized, publish one consolidated final review after
validation; do not post preliminary or incremental comments. Submit a review
event (`APPROVE`, `COMMENT`, or `REQUEST_CHANGES`) only when the user explicitly
chooses that event.
Reviewer requests and owner `@mention` comments are separate external writes;
follow [review-requests.md](../delivery/review-requests.md) when the user asks
for them.
## Re-review safely
Freeze the new head and compare it with the previously reviewed SHA. Then:
1. inspect the delta and every file affected by conflict resolution or rebase;
2. revalidate earlier findings against current lines and behavior;
3. read unresolved, non-outdated threads and the author's evidence;
4. rerun only checks invalidated by the delta;
5. look for new regressions introduced by the fix;
6. do not repeat resolved or outdated comments.
If the target head changes during re-review, discard stale validation and start
again from the new snapshot.
@@ -0,0 +1,76 @@
# Module and Feature Review Routing
Read [design-contracts.md](design-contracts.md) first. Route from the frozen
head's live producer-consumer behavior, then confirm the result against its
`docs/design/` metadata. Titles and paths are evidence, not the deciding rule.
## Primary module contract
Choose one primary module and a second only when the live call path crosses a
documented dependency or primary-path exception.
| Module | Live behavior signals | Read |
| --- | --- | --- |
| Entrypoints | Offline/CLI/API ingress, validation, rendering, streaming, sessions | [entrypoints.md](../modules/entrypoints.md) |
| Configuration | Schema, defaults, deploy/stage construction, registry, topology | [configuration.md](../modules/configuration.md) |
| I/O and Modality | Requests, messages, serialization, output types, accumulation, completion | [input-output-modality.md](../modules/input-output-modality.md) |
| Error Contracts | Classification, fatality, propagation, sanitization, public rendering | [error-contracts.md](../modules/error-contracts.md) |
| Engine Orchestration | Cross-stage routing, request state, ordering, RPC correlation, terminal convergence | [engine-orchestration.md](../modules/engine-orchestration.md) |
| Stage Runtime | Placement, startup, readiness, replicas, affinity, membership, shutdown | [stage-runtime.md](../modules/stage-runtime.md) |
| OmniConnector | Cross-stage/process/device/node transport and synchronization | [omni-connector.md](../modules/omni-connector.md) |
| Model Integration | Registration, preprocessing, loading, runners, model-specific execution | [model-integration.md](../modules/model-integration.md) |
| AR Runtime | Scheduling, request/cache state, adapters, workers, upstream vLLM semantics | [ar-runtime.md](../modules/ar-runtime.md) |
| Diffusion Family | Diffusion runtime, models, batching, parallelism, or offload | [diffusion.md](../modules/diffusion.md) |
| Execution Platforms | Hardware selection, capabilities, vendor workers, kernels, patches | [execution-platforms.md](../modules/execution-platforms.md) |
| Cache Management | Cache identity, validity, reuse, eviction, reset, teardown | [cache-management.md](../modules/cache-management.md) |
| Quantization | Method/metadata selection, layer mapping, reduced precision, constraints | [quantization.md](../modules/quantization.md) |
| Observability | Metrics, logs, labels, units, correlation, lifecycle | [observability.md](../modules/observability.md) |
| Profiling | Opt-in instrumentation, traces, start/stop lifecycle, overhead | [profiling.md](../modules/profiling.md) |
| Benchmarking | Workloads, metric computation, benchmark CLI, result metadata | [benchmarking.md](../modules/benchmarking.md) |
For tests-, docs-, CI-, or recipe-only changes, route to the production module
whose contract they protect. When none exists, use the applicable evidence
check without inventing a production owner.
## Feature-design overlays
Load every category whose documented behavior, enablement, default, support, or
compatibility changes.
| Feature-design section | Read |
| --- | --- |
| Runtime and stage execution | [runtime-stage-execution.md](../features/runtime-stage-execution.md) |
| Communication and concrete connectors | [communication.md](../features/communication.md) |
| Diffusion acceleration | [diffusion-acceleration.md](../features/diffusion-acceleration.md) |
| Infrastructure and performance | [infrastructure-performance.md](../features/infrastructure-performance.md) |
## Evidence and change overlays
| Signal | Read | Optional repo-local skill |
| --- | --- | --- |
| New or expanded model, loader, processor, registry, or stage config | [model-addition-checklist.md](../checks/model-addition-checklist.md) | [`add-tts-model`](../../../add-tts-model/SKILL.md) or [`add-diffusion-model`](../../../add-diffusion-model/SKILL.md) |
| Latency, throughput, memory, scaling, precision, or quality claim | [perf-verification.md](../checks/perf-verification.md) | [`diffusion-perf-opt`](../../../diffusion-perf-opt/SKILL.md) for diffusion |
| Tests changed, absent for risky behavior, or test-only | [test-quality-evaluation.md](../checks/test-quality-evaluation.md) | [`vllm-omni-test`](../../../vllm-omni-test/SKILL.md) |
| CI, examples, docs, public behavior, or contributor evidence | [tests-docs-checklist.md](../checks/tests-docs-checklist.md) | None |
| Suitable hardware/server and runnable affected path | [verification.md](../checks/verification.md) | None |
| User asks who should review or requests owner notification | [review-requests.md](../delivery/review-requests.md) | None |
Use [`quantization`](../../../quantization/SKILL.md) for a quantization module
change and [`$vllm-omni-npu-model-runner-upgrade`](../../../vllm-omni-npu-upgrade/SKILL.md)
for an NPU execution-platform change when those skills are available.
For a bug fix, require a reachable reproduction and regression test. For a
refactor, prove parity and remove obsolete paths. For a feature, verify the
public/config contract, module integration, compatibility/default behavior,
production dispatch, feature design, and docs.
## Calibrate findings
- **P0:** security exposure, data corruption, or broad project unusability.
- **P1:** reachable runtime failure, wrong output, compatibility break, or
unsafe lifecycle in the changed behavior.
- **P2:** real non-blocking defect with a concrete future failure mode.
Treat draft candidate invariants, missing hardware, and unsupported claims as
questions or validation gaps unless current code, tests, or policy makes them a
merge requirement.
+110 -28
View File
@@ -1,6 +1,11 @@
# CODEOWNERS is used to automatically assign PR reviewers
# Format: path pattern @username or @team
# More info: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
#
# The vllm_omni/** source-tree rules below are derived from the `owners` and
# `primary_code_paths` front matter in docs/design/module/*.md. When updating
# ownership, update the design doc first, then regenerate the matching rule here.
# Last-match-wins: more specific rules must come AFTER broader ones.
# Default owners (fallback reviewers for all files)
* @Gaohan123 @hsliuustc0106 @ywang96
@@ -21,25 +26,10 @@
# CI
/.buildkite/ @yenuo26 @congw729 @NickCao
# Engine and model_executor
/vllm_omni/core/ @tzhouam @yinpeiqi @fake0fan @Sy0307
/vllm_omni/engine/ @tzhouam @yinpeiqi @fake0fan @Sy0307
/vllm_omni/entrypoints/ @tzhouam @yinpeiqi @fake0fan @alex-jw-brooks @NickCao
/vllm_omni/model_executor/ @tzhouam @gcanlin
/vllm_omni/worker/ @tzhouam @gcanlin
# ComfyUI / external apps
/apps/ @fhfuih @alex-jw-brooks
# Diffusion
/vllm_omni/diffusion/ @Isotr0py @princepride @SamitHuang @wtomin @ZJY0516 @RuixiangMa @david6666666 @xuechendi
/vllm_omni/lora/ @princepride @SamitHuang @wtomin @ZJY0516 @RuixiangMa @yuanheng-zhao
# Diffusion CPU offloading
/vllm_omni/diffusion/offloader/ @Isotr0py @princepride @SamitHuang @wtomin @ZJY0516 @RuixiangMa @yuanheng-zhao @xuechendi
# Omni and TTS support
/vllm_omni/transformers_utils/ @tzhouam @yuanheng-zhao
/vllm_omni/model_executor/models/ @linyueqian @ZeldaHuang @princepride @yuanheng-zhao @amy-why-3459 @Bounty-hunter @Sy0307 @gcanlin @NickCao
# Benchmarks
# Benchmarks (out-of-tree)
/benchmarks/accuracy/ @david6666666
/benchmarks/build_dataset/ @linyueqian @yuanheng-zhao
/benchmarks/diffusion/ @Isotr0py @princepride @SamitHuang @wtomin @ZJY0516 @RuixiangMa @xuechendi
@@ -47,20 +37,112 @@
/benchmarks/glm_image/ @princepride @JaredforReal
/benchmarks/tts/ @linyueqian @ZeldaHuang @princepride @Sy0307 @gcanlin
# Usability and Observability
/vllm_omni/deploy/ @tzhouam @lishunyang12
/vllm_omni/metrics/ @lishunyang12
/vllm_omni/profiler/ @gcanlin
# =====================================================================
# Module design ownership (docs/design/module/*.md)
# Each section header cites the source design doc.
# =====================================================================
# ComfyUI
/apps/ @fhfuih @alex-jw-brooks
# Autoregressive runtime — docs/design/module/ar_runtime.md
/vllm_omni/core/ @tzhouam @yinpeiqi @fake0fan @Sy0307 @Gaohan123
/vllm_omni/worker/ @tzhouam @yinpeiqi @fake0fan @Sy0307 @Gaohan123
# Large Scale Serving
# Engine orchestration & stage runtime — docs/design/module/engine_orchestration.md, stage_runtime.md
/vllm_omni/engine/ @tzhouam @fake0fan
# File-level overrides: input/output modality contracts own these engine files
# — docs/design/module/input_output_modality_contracts.md
/vllm_omni/engine/messages.py @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
/vllm_omni/engine/serialization.py @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
/vllm_omni/engine/mm_outputs.py @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
/vllm_omni/engine/output_modality.py @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
/vllm_omni/engine/output_processor.py @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
# Input/output modality contracts — docs/design/module/input_output_modality_contracts.md
/vllm_omni/inputs/ @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
/vllm_omni/outputs/ @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
/vllm_omni/request.py @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
/vllm_omni/data_entry_keys.py @Sy0307 @amy-why-3459 @Gaohan123 @alex-jw-brooks
# Entrypoints and serving boundaries — docs/design/module/entrypoints.md
/vllm_omni/entrypoints/ @alex-jw-brooks @linyueqian @NickCao
# File-level overrides within entrypoints/
/vllm_omni/entrypoints/openai/errors.py @alex-jw-brooks @NickCao
/vllm_omni/entrypoints/cli/benchmark/ @alex-jw-brooks @Bounty-hunter
# Error contracts — docs/design/module/error_contracts.md
/vllm_omni/errors.py @alex-jw-brooks @NickCao
# OmniConnector (inter-stage transport) — docs/design/module/omni_connector.md
/vllm_omni/distributed/ @princepride @yuanheng-zhao @xuechendi @natureofnature @fake0fan
# Quantization and configuration
# Model integration — docs/design/module/model_integration.md
/vllm_omni/model_executor/ @tzhouam @gcanlin
/vllm_omni/model_executor/models/ @tzhouam @gcanlin @Sy0307 @amy-why-3459 @linyueqian
/vllm_omni/model_extras/ @tzhouam @gcanlin @princepride
/vllm_omni/plugins/ @gcanlin @tjtanaa @xuechendi
# Config override within model_executor — docs/design/module/vllm_omni_config.md
/vllm_omni/model_executor/stage_configs/ @lishunyang12 @alex-jw-brooks
# Execution platforms (hardware backends) — docs/design/module/execution_platforms.md
/vllm_omni/platforms/ @gcanlin @tjtanaa @xuechendi
/vllm_omni/attention/ @gcanlin @tjtanaa @xuechendi @david6666666 @lishunyang12
# Configuration & deploy — docs/design/module/vllm_omni_config.md
/vllm_omni/config/ @lishunyang12 @alex-jw-brooks
/vllm_omni/deploy/ @lishunyang12 @alex-jw-brooks
# Quantization — docs/design/module/quantization.md
/vllm_omni/quantization/ @david6666666 @Isotr0py @lishunyang12
# Hardware plugins and accelerators
/vllm_omni/platforms/ @gcanlin @tjtanaa @xuechendi
# Observability — docs/design/module/observability.md
/vllm_omni/metrics/ @lishunyang12 @vraiti
# Profiling — docs/design/module/profiling.md
/vllm_omni/profiler/ @gcanlin
# Benchmarking (in-tree) — docs/design/module/benchmarking.md
/vllm_omni/benchmarks/ @alex-jw-brooks @Bounty-hunter
# LoRA (no dedicated design doc; ownership intentionally narrowed)
/vllm_omni/lora/ @SamitHuang @wtomin
# Transformers utils (related path only in design docs; preserves prior ownership)
/vllm_omni/transformers_utils/ @tzhouam @yuanheng-zhao
# =====================================================================
# Diffusion module family — docs/design/module/diffusion/
# Umbrella rule first; sub-module rules after it win via last-match.
# =====================================================================
# Diffusion umbrella (top-level files: data.py, forward_context.py, etc.)
# — docs/design/module/diffusion/index.md
/vllm_omni/diffusion/ @Isotr0py @princepride @SamitHuang @wtomin @ZJY0516 @RuixiangMa @david6666666 @xuechendi
# Cache management — docs/design/module/cache_management.md
/vllm_omni/diffusion/cache/ @Isotr0py @princepride @SamitHuang
# Diffusion quantization — docs/design/module/quantization.md
/vllm_omni/diffusion/quantization/ @david6666666 @Isotr0py @lishunyang12
# Diffusion profiling — docs/design/module/profiling.md
/vllm_omni/diffusion/profiler/ @gcanlin
# Diffusion runtime (scheduler, executor, worker)
# — docs/design/module/diffusion/diffusion_runtime.md, continuous_batching.md
/vllm_omni/diffusion/sched/ @Isotr0py @princepride @SamitHuang @fhfuih
/vllm_omni/diffusion/executor/ @Isotr0py @princepride @SamitHuang @fhfuih
/vllm_omni/diffusion/worker/ @Isotr0py @princepride @SamitHuang @fhfuih
# Diffusion model integration (pipelines, registration, checkpoint loading)
# — docs/design/module/diffusion/diffusion_model_integration.md
/vllm_omni/diffusion/models/ @fhfuih @Bounty-hunter @wtomin
/vllm_omni/diffusion/model_loader/ @fhfuih @Bounty-hunter @wtomin @RuixiangMa
/vllm_omni/diffusion/lora/ @fhfuih @Bounty-hunter @wtomin @RuixiangMa
# Diffusion parallelism (rank topology, TP/SP/PP/VAE patch)
# — docs/design/module/diffusion/parallelism.md
/vllm_omni/diffusion/distributed/ @princepride @yuanheng-zhao @xuechendi @Bounty-hunter
/vllm_omni/diffusion/attention/parallel/ @princepride @yuanheng-zhao @xuechendi @Bounty-hunter
# Diffusion offloader (CPU offloading, DLO)
# — docs/design/module/diffusion/offloader.md
/vllm_omni/diffusion/offloader/ @yuanheng-zhao @david6666666 @lishunyang12
+3
View File
@@ -46,6 +46,8 @@ htmlcov/
.cache
nosetests.xml
coverage.xml
coverage-*.xml
coverage-*.xml.gz
*.cover
*.py,cover
.hypothesis/
@@ -252,6 +254,7 @@ outputs/
results/
generated/
output_*/
/tests/e2e/accuracy/artifacts/
# Configuration overrides
configs/local.yaml
+10
View File
@@ -61,6 +61,16 @@ repos:
types: [python]
files: ^tests/
- id: check-tts-adapter-migration
name: Ratchet TTS per-model branches out of serving_speech.py
entry: python tools/pre_commit/check_tts_adapter.py
language: python
pass_filenames: false
files: ^(vllm_omni/entrypoints/openai/(serving_speech\.py|tts_adapters/__init__\.py)|tools/pre_commit/check_tts_adapter\.py)$
# The budget-is-now-slack reminder is printed on a PASSING run, and
# pre-commit hides output from passing hooks unless the hook is verbose.
verbose: true
# Keep `suggestion` last
- id: suggestion
name: Suggestion
+7 -2
View File
@@ -11,10 +11,15 @@ build:
post_checkout:
- git fetch --unshallow || true
pre_install:
# `pre_install` runs before RTD upgrades pip, and the seeded pip 23.1
# rejects the `typing_extensions` wheel torch needs (fixed in pip 23.2).
- python -m pip install --upgrade pip
# Pre-install CPU torch so the subsequent `pip install .[docs]` does not
# pull ~2 GB of CUDA 13 libs (cuBLAS/cuDNN/NCCL/...) that exceed RTD's
# 1 GB memory cap and time out the mkdocs build.
- python -m pip install --index-url https://download.pytorch.org/whl/cpu torch
# 1 GB memory cap and time out the mkdocs build. Wheel-only: `--index-url`
# replaces PyPI, so an sdist fallback cannot reach its build deps. The
# quotes keep YAML from reading `:all:` as a mapping key.
- "python -m pip install --only-binary=:all: --index-url https://download.pytorch.org/whl/cpu torch"
mkdocs:
configuration: mkdocs.yml
+2 -1
View File
@@ -9,13 +9,14 @@ Easy, fast, and cheap omni-modality model serving for everyone
</h3>
<p align="center">
| <a href="https://vllm-omni.readthedocs.io/en/latest/"><b>Documentation</b></a> | <a href="https://deepwiki.com/vllm-project/vllm-omni"><b>DeepWiki</b></a> | <a href="https://discuss.vllm.ai"><b>User Forum</b></a> | <a href="https://slack.vllm.ai"><b>Developer Slack</b></a> | <a href="docs/assets/WeChat.jpg"><b>WeChat</b></a> | <a href="https://arxiv.org/abs/2602.02204"><b>Paper</b></a> | <a href="https://docs.google.com/presentation/d/111-L8zF7A1j_YI_cR8JsblofdScdRr2f/edit?usp=sharing&ouid=110473603432222024453&rtpof=true&sd=true"><b>Slides</b></a> |
| <a href="https://vllm-omni.readthedocs.io/en/latest/"><b>Documentation</b></a> | <a href="https://deepwiki.com/vllm-project/vllm-omni"><b>DeepWiki</b></a> | <a href="https://discuss.vllm.ai"><b>User Forum</b></a> | <a href="https://slack.vllm.ai"><b>Developer Slack</b></a> | <a href="docs/assets/WeChat.jpg"><b>WeChat</b></a> | <a href="https://arxiv.org/abs/2602.02204"><b>Paper</b></a> | <a href="https://docs.google.com/presentation/d/1aPj0OGl_-ZVoib-Qne5dGDAlrRFB-PdHl6E-EE99g8E/edit?usp=sharing"><b>Slides</b></a> |
</p>
---
*Latest News* 🔥
- [2026/08] [VeRL-Omni](https://github.com/verl-project/verl-omni) `v0.2.0` is released: faster diffusion RL powered by vLLM-Omni (request-level/step-wise batching with FA3), rebuilt Qwen3-Omni multimodal training (DPO & GSPO), plus LTX-2.3, Qwen-Image-Edit support and more. See the [release notes](https://github.com/verl-project/verl-omni/releases/tag/v0.2.0).
- [2026/08] We released [0.26.0](https://github.com/vllm-project/vllm-omni/releases/tag/v0.26.0) - aligned with the vLLM 0.26 release line, featuring [MiniMax H3](recipes/MiniMaxAI/MiniMax-H3.md) joint video/audio generation, an experimental full-duplex realtime runtime for [MiniCPM-o 4.5](recipes/OpenBMB/MiniCPM-o-4_5.md), distributed layerwise diffusion offload, and broader model, hardware, streaming, TTS, and quantization support.
- [2026/07] We released [0.24.0](https://github.com/vllm-project/vllm-omni/releases/tag/v0.24.0) - aligned with the vLLM 0.24 release line, expanding production-ready coverage across TTS, speech, diffusion, image/video generation, and robot-policy serving, with major Omni stage runtime refactoring, diffusion request-level batching, async output materialization, quantization/cache/memory improvements, and broad CUDA/ROCm/XPU/NPU support.
- [2026/06] Starting with [0.14.0](https://github.com/vllm-project/vllm-omni/releases/tag/v0.14.0), vLLM-Omni publishes a stable release aligned with every even-numbered upstream vLLM minor version. [0.16.0](https://github.com/vllm-project/vllm-omni/releases/tag/v0.16.0), [0.18.0](https://github.com/vllm-project/vllm-omni/releases/tag/v0.18.0), [0.20.0](https://github.com/vllm-project/vllm-omni/releases/tag/v0.20.0), and [0.22.0](https://github.com/vllm-project/vllm-omni/releases/tag/v0.22.0) continued this cadence, expanding omni and world-model support with [NVIDIA Cosmos3](recipes/cosmos3/Cosmos3-Nano.md) and DreamZero, adding models such as MiniCPM-o 4.5, MOSS-TTS, and Lance, and advancing TTS, diffusion, distributed execution, quantization, RL integration through [VeRL-Omni](https://github.com/verl-project/verl-omni), and CUDA/ROCm/MUSA/NPU/XPU coverage.
+10 -11
View File
@@ -158,7 +158,6 @@ def _build_omni_kwargs(args, quantization=None):
def _generate_image(omni, args, prompt, seed):
"""Generate a single image and return (PIL.Image, time_seconds, memory_gib)."""
from vllm_omni.inputs.data import OmniDiffusionSamplingParams
from vllm_omni.outputs import OmniRequestOutput
from vllm_omni.platforms import current_omni_platform
generator = torch.Generator(device=current_omni_platform.device_type).manual_seed(seed)
@@ -176,7 +175,7 @@ def _generate_image(omni, args, prompt, seed):
elapsed = time.perf_counter() - start
peak_mem = torch.accelerator.max_memory_allocated() / (1024**3)
req_out = OmniRequestOutput.unwrap_result(outputs)
req_out = outputs[0] if isinstance(outputs, list) else outputs
if not req_out.images:
raise ValueError("Could not extract image output from result.")
img = req_out.images[0]
@@ -206,15 +205,15 @@ def _generate_video(omni, args, prompt, seed):
elapsed = time.perf_counter() - start
peak_mem = torch.accelerator.max_memory_allocated() / (1024**3)
first = outputs[0]
if hasattr(first, "request_output") and isinstance(first.request_output, list):
inner = first.request_output[0]
if isinstance(inner, OmniRequestOutput) and hasattr(inner, "images"):
frames = inner.images[0] if inner.images else None
else:
frames = inner
elif hasattr(first, "images") and first.images:
frames = first.images[0]
if isinstance(outputs, list) and isinstance(outputs[0], OmniRequestOutput):
first = outputs[0]
elif isinstance(outputs, OmniRequestOutput):
first = outputs
else:
raise ValueError("Could not extract video frames from output.")
if hasattr(first, "images"):
frames = first.images[0] if first.images else None
else:
raise ValueError("Could not extract video frames from output.")
+1 -1
View File
@@ -300,7 +300,7 @@ def benchmark(args: argparse.Namespace) -> None:
output_idx = 0
for stage_outputs in omni.generate(all_prompts, sampling_params_list, py_generator=True):
if stage_outputs.final_output_type == "image":
request_output = stage_outputs.request_output
request_output = stage_outputs
request_id = getattr(request_output, "request_id", "")
images = getattr(request_output, "images", [])
@@ -167,9 +167,11 @@ def main() -> None:
]
native_cmd = [
sys.executable,
"examples/offline_inference/text_to_video/text_to_video_lingbot.py",
"examples/offline_inference/text_to_video/text_to_video.py",
"--model",
args.model,
"--model-class-name",
"LingBotVideoPipeline",
"--prompt",
args.prompt,
"--output",
+28
View File
@@ -139,6 +139,34 @@ python benchmarks/tts/bench_tts.py \
--output-dir ./results
```
#### Fixed IndexTTS 2.5 performance sweep
IndexTTS 2.5 is registered in `model_configs.yaml` like the other TTS models.
Use `--served-model-name` when the server was launched from a local native
bundle instead of the registry key. The command below reproduces the acceptance
workload: Seed-TTS Eval EN, `n=500`, concurrency `4/8/16/32`, five warmups, and
dataset seed 0.
```bash
python benchmarks/tts/bench_tts.py \
--model IndexTeam/IndexTTS-2.5 \
--served-model-name /path/to/indextts-2.5 \
--task voice_clone --locale en \
--dataset-path /path/to/seedtts_testset \
--host 127.0.0.1 --port 8092 \
--concurrency 4 8 16 32 \
--num-prompts 500 --num-warmups 5 \
--output-dir ./results/indextts2_5 \
-- \
--tokenizer /path/to/indextts-2.5/qwen0.6bemo4-merge \
--seed 0 --metric-percentiles 50,95,99 --disable-tqdm --save-detailed
```
The wrapper benchmarks an already-running server. For reproducible quality
comparisons, add `--request-seed 42`; production-performance runs should omit
it. The trailing `--seed 0` controls Seed-TTS row selection rather than model
sampling.
### 4. Plot a sweep
```bash
+29 -4
View File
@@ -84,12 +84,17 @@ def build_bench_args(
result_filename: str | None,
extra_cli_args: list[str],
output_len: int | None = None,
served_model_name: str | None = None,
num_warmups: int = 2,
request_seed: int | None = None,
) -> list[str]:
"""Build the ``vllm bench serve --omni`` command for one (task, concurrency) run."""
dataset_name = _TASK_TO_DATASET[task]
backend: str = model_cfg["backend"]
endpoint: str = model_cfg["endpoint"]
task_extra_body: dict[str, Any] = (model_cfg.get("task_extra_body") or {}).get(task) or {}
task_extra_body: dict[str, Any] = dict((model_cfg.get("task_extra_body") or {}).get(task) or {})
if request_seed is not None:
task_extra_body["seed"] = request_seed
# Resolve dataset path
if dataset_path:
@@ -109,7 +114,7 @@ def build_bench_args(
"--port",
str(port),
"--model",
model,
served_model_name or model,
"--backend",
backend,
"--endpoint",
@@ -119,7 +124,7 @@ def build_bench_args(
"--num-prompts",
str(num_prompts),
"--num-warmups",
"2",
str(num_warmups),
"--percentile-metrics",
"ttft,e2el,audio_rtf,audio_ttfp,audio_duration,audio_underrun",
]
@@ -152,7 +157,8 @@ def build_bench_args(
if result_filename:
cmd += ["--result-filename", result_filename]
cmd += extra_cli_args
passthrough = extra_cli_args[1:] if extra_cli_args[:1] == ["--"] else extra_cli_args
cmd += passthrough
return cmd
@@ -225,6 +231,12 @@ def main() -> None:
parser.add_argument(
"--model", required=True, help="HuggingFace model ID (e.g. Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice)"
)
parser.add_argument(
"--served-model-name",
default=None,
help="Model name/path accepted by the running server. Use this when --model selects a registry entry "
"but the server was launched from a local bundle path.",
)
parser.add_argument("--task", default="all", help="Task type: voice_clone | default_voice | voice_design | all")
parser.add_argument("--locale", default="en", choices=["en", "zh"])
parser.add_argument("--concurrency", type=int, nargs="+", default=[1, 4], metavar="N")
@@ -236,6 +248,13 @@ def main() -> None:
metavar="N",
help="Number of prompts per run. If one value, applied to all concurrency levels.",
)
parser.add_argument("--num-warmups", type=int, default=2, help="Warmup requests before each measured run")
parser.add_argument(
"--request-seed",
type=int,
default=None,
help="Optional model sampling seed added to every request body for reproducible quality runs",
)
parser.add_argument(
"--dataset-path", default=None, help="Root of seed-tts-eval dataset (required for voice_clone/default_voice)"
)
@@ -256,6 +275,9 @@ def main() -> None:
parser.add_argument("extra", nargs=argparse.REMAINDER, help="Extra args passed directly to vllm bench serve")
args = parser.parse_args()
if args.num_warmups < 0:
parser.error("--num-warmups cannot be negative")
model_configs = load_model_configs(Path(args.model_configs))
if args.model not in model_configs:
known = "\n ".join(model_configs.keys())
@@ -308,6 +330,9 @@ def main() -> None:
result_filename=result_filename,
extra_cli_args=args.extra or [],
output_len=args.output_len,
served_model_name=args.served_model_name,
num_warmups=args.num_warmups,
request_seed=args.request_seed,
)
result = run_one_benchmark(cmd)
if result is not None:
+11
View File
@@ -7,6 +7,17 @@
# is tracked here.
models:
IndexTeam/IndexTTS-2.5:
supported_tasks: [voice_clone]
backend: openai-audio-speech
endpoint: /v1/audio/speech
trust_remote_code: true
task_extra_body:
voice_clone:
extra_params:
lang: en
text_normalization: true
# -CustomVoice checkpoints lack speaker_encoder weights, so voice_clone is
# NOT supported (an attempt raises ValueError from _extract_speaker_embedding
# at model runtime). Use -Base for voice_clone.
+19 -2
View File
@@ -1,7 +1,24 @@
# Target vllm version: v0.26.0 (releases/v0.26.0 branch).
# Target vllm version: v0.27.0 (releases/v0.27.0 branch).
# Keep VLLM_BASE_TAG aligned with the target vLLM release on every rebase.
#
# Release-boundary form: there is no precompiled-wheel pin here, because the
# base image already ships exactly the target vLLM. Everything the runtime
# needs — torch, flashinfer, nvJitLink, numpy — comes from that image as one
# self-consistent set.
#
# This block reappears only when the rebase targets a vLLM commit that is NOT a
# released tag. During the 0.27 rebase, targeting v0.27.0rc1 on top of the
# v0.26.0 base image required reinstalling vLLM from wheels.vllm.ai and then
# hand-repairing the fallout: pinning torch ahead of flashinfer (installing it
# after bound flashinfer's TVM FFI runtime to the old torch and aborted engine
# core init), registering libnvJitLink.so.13 with ldconfig, and re-pinning numpy
# under numba's ceiling. All of it was compensation for a base image and a vLLM
# that disagreed. At a real release boundary they agree, so none of it is
# needed. If you pin an untagged commit again, restore the reinstall block —
# agent/tasks/20_update_wheel_url.sh fails the run rather than letting the
# Dockerfile silently ship the wrong vLLM.
ARG VLLM_BASE_IMAGE=vllm/vllm-openai
ARG VLLM_BASE_TAG=v0.26.0
ARG VLLM_BASE_TAG=v0.27.0
# We use registry-based layer caching for the dependencies,
# where the tag is determined based on the hash of the contents
+1 -1
View File
@@ -1,5 +1,5 @@
ARG VLLM_ASCEND_IMAGE=quay.io/atlas-ci/vllm-ascend
ARG VLLM_ASCEND_TAG=v0.26.0
ARG VLLM_ASCEND_TAG=v0.27.0
FROM ${VLLM_ASCEND_IMAGE}:${VLLM_ASCEND_TAG}
# WORKDIR /vllm-workspace/vllm
+1 -1
View File
@@ -1,5 +1,5 @@
ARG VLLM_ASCEND_IMAGE=quay.io/atlas-ci/vllm-ascend
ARG VLLM_ASCEND_TAG=v0.26.0-a3
ARG VLLM_ASCEND_TAG=v0.27.0-a3
FROM ${VLLM_ASCEND_IMAGE}:${VLLM_ASCEND_TAG}
# WORKDIR /vllm-workspace/vllm
+2 -1
View File
@@ -1,5 +1,5 @@
ARG VLLM_ASCEND_IMAGE=quay.io/atlas-ci/vllm-ascend
ARG VLLM_ASCEND_TAG=v0.26.0
ARG VLLM_ASCEND_TAG=v0.27.0
FROM ${VLLM_ASCEND_IMAGE}:${VLLM_ASCEND_TAG}
ARG APP_DIR=/vllm-workspace/vllm-omni
@@ -45,6 +45,7 @@ RUN source /usr/local/Ascend/ascend-toolkit/set_env.sh && \
"hyperpyyaml>=1.2.0" \
"onnx>=1.16.0" \
"librosa>=0.10.0" \
"datasets>=3.0.0" \
--index-url http://cache-service.nginx-pypi-cache.svc.cluster.local/pypi/simple \
--trusted-host cache-service.nginx-pypi-cache.svc.cluster.local \
--default-timeout=60 && \
+2 -1
View File
@@ -1,5 +1,5 @@
ARG VLLM_ASCEND_IMAGE=quay.io/atlas-ci/vllm-ascend
ARG VLLM_ASCEND_TAG=v0.26.0-a3
ARG VLLM_ASCEND_TAG=v0.27.0-a3
FROM ${VLLM_ASCEND_IMAGE}:${VLLM_ASCEND_TAG}
ARG APP_DIR=/vllm-workspace/vllm-omni
@@ -46,6 +46,7 @@ RUN source /usr/local/Ascend/ascend-toolkit/set_env.sh && \
"onnx>=1.16.0" \
"librosa>=0.10.0" \
"torchmetrics>=1.9.0" \
"datasets>=3.0.0" \
--index-url http://cache-service.nginx-pypi-cache.svc.cluster.local/pypi/simple \
--trusted-host cache-service.nginx-pypi-cache.svc.cluster.local \
--default-timeout=60 && \
+9 -2
View File
@@ -1,4 +1,4 @@
ARG BASE_IMAGE=vllm/vllm-openai-rocm:v0.26.0
ARG BASE_IMAGE=vllm/vllm-openai-rocm:v0.27.0
FROM ${BASE_IMAGE} AS base
# Declare a variable to know if we want to use the nightly build or the stable build.
@@ -10,7 +10,7 @@ FROM ${BASE_IMAGE} AS base
# we should swap over to use stable release ASAP.
# We should avoid relying on custom commits.
ARG USE_NIGHTLY_BUILD=0
ARG VLLM_VERSION_OR_COMMIT_HASH=v0.26.0
ARG VLLM_VERSION_OR_COMMIT_HASH=v0.27.0
ARG ARG_PYTORCH_ROCM_ARCH
ENV PYTORCH_ROCM_ARCH=${ARG_PYTORCH_ROCM_ARCH:-${PYTORCH_ROCM_ARCH}}
@@ -79,9 +79,16 @@ RUN printf '%s\n' \
' os._exit(_exit_code)' \
> ${COMMON_WORKDIR}/vllm-omni/conftest.py
# Some optional dependencies pull in the CPU ONNX Runtime distribution. The
# CPU and ROCm wheels own the same import path and cannot coexist, so remove
# the CPU wheel and reinstall the ROCm wheel after dependency resolution.
RUN cd ${COMMON_WORKDIR}/vllm-omni && \
uv pip install --python "$(python3 -c 'import sys; print(sys.executable)')" \
--no-cache-dir ".[dev]" --no-build-isolation && \
python3 -m pip uninstall -y onnxruntime && \
python3 -m pip install --no-cache-dir --force-reinstall --no-deps \
"onnxruntime-rocm>=1.22.2" && \
python3 -c "import importlib.metadata as m; import onnxruntime as ort; assert 'ROCMExecutionProvider' in ort.get_available_providers(), ort.get_available_providers(); assert m.version('onnxruntime-rocm'); assert not any(d.metadata['Name'] == 'onnxruntime' for d in m.distributions())" && \
python3 -c "from torchcodec.decoders import VideoDecoder"
RUN ln -sf /usr/bin/python3 /usr/bin/python
+5 -4
View File
@@ -88,7 +88,7 @@ ENV UV_EXTRA_INDEX_URL=${PIP_EXTRA_INDEX_URL}
ENV UV_INDEX_STRATEGY="unsafe-best-match"
ENV UV_LINK_MODE="copy"
ARG VLLM_VERSION=v0.26.0
ARG VLLM_VERSION=v0.27.0
RUN git clone -b ${VLLM_VERSION} https://github.com/vllm-project/vllm
WORKDIR /workspace/vllm
@@ -108,7 +108,7 @@ ENV VLLM_WORKER_MULTIPROC_METHOD=spawn
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip uninstall triton triton-xpu && \
uv pip install triton-xpu==3.7.1 && \
uv pip install triton-xpu==3.7.2 && \
uv pip install --no-build-isolation --no-deps .
CMD ["/bin/bash"]
@@ -144,12 +144,13 @@ WORKDIR /workspace/vllm-omni
COPY . .
ENV VLLM_OMNI_TARGET_DEVICE=xpu
# Keep the upstream oneCCL packages paired with the XPU torch runtime.
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip install --no-build-isolation \
--extra-index-url https://mirrors.ustc.edu.cn/pypi/simple/ \
".[dev]" && \
uv pip uninstall triton oneccl oneccl-devel && \
uv pip install triton-xpu==3.7.1 --reinstall
uv pip uninstall triton && \
uv pip install triton-xpu==3.7.2 --reinstall
FROM vllm-omni AS vllm-omni-openai
+55 -42
View File
@@ -16,31 +16,21 @@ nav:
- Examples:
- examples/README.md
- Offline Inference:
- GLM-Image Multistage End-to-End Inference: user_guide/examples/offline_inference/glm_image.md
- HunyuanImage-3.0 Image-to-Text Inference: user_guide/examples/offline_inference/hunyuan_image3.md
- Image-To-Image: user_guide/examples/offline_inference/image_to_image.md
- Image-To-Video: user_guide/examples/offline_inference/image_to_video.md
- InternVLA-A1: user_guide/examples/offline_inference/internvla_a1.md
- MiMo-Audio: user_guide/examples/offline_inference/mimo_audio.md
- Qwen2.5-Omni: user_guide/examples/offline_inference/qwen2_5_omni.md
- Qwen3-Omni: user_guide/examples/offline_inference/qwen3_omni.md
- Speech-To-Video: user_guide/examples/offline_inference/speech_to_video.md
- Text-To-Audio: user_guide/examples/offline_inference/text_to_audio.md
- Text-To-Image: user_guide/examples/offline_inference/text_to_image.md
- Text-To-Speech: user_guide/examples/offline_inference/text_to_speech.md
- Text-To-Video: user_guide/examples/offline_inference/text_to_video.md
- X-To-Text: user_guide/examples/offline_inference/x_to_text.md
- X-To-Video-Audio: user_guide/examples/offline_inference/x_to_video_audio.md
- Online Serving:
- BAGEL-7B-MoT: user_guide/examples/online_serving/bagel.md
- vLLM-Omni Helm Chart: user_guide/examples/online_serving/chart-helm.md
- Diffusers Backend Adapter: user_guide/examples/online_serving/diffusers_pipeline_adapter.md
- GLM-Image Online Serving: user_guide/examples/online_serving/glm_image.md
- Image-To-Image: user_guide/examples/online_serving/image_to_image.md
- Image-To-Video: user_guide/examples/online_serving/image_to_video.md
- MiMo-Audio: user_guide/examples/online_serving/mimo_audio.md
- Qwen2.5-Omni: user_guide/examples/online_serving/qwen2_5_omni.md
- Qwen3-Omni: user_guide/examples/online_serving/qwen3_omni.md
- Text-To-Speech: user_guide/examples/online_serving/text_to_speech.md
- Speech-To-Video: user_guide/examples/online_serving/speech_to_video.md
- Text-To-Image: user_guide/examples/online_serving/text_to_image.md
- Text-To-Speech: user_guide/examples/online_serving/text_to_speech.md
- Text-To-Video: user_guide/examples/online_serving/text_to_video.md
- General:
- usage/*
@@ -50,30 +40,12 @@ nav:
- Models:
- models/supported_models.md
- Features:
- Sleep Mode: features/sleep_mode.md
- Diffusion Features:
- Overview: user_guide/diffusion_features.md
- Feature Compatibility: user_guide/feature_compatibility.md
- Regional Compilation: user_guide/diffusion/regional_compilation.md
- Cache Acceleration:
- TeaCache: user_guide/diffusion/cache_acceleration/teacache.md
- Cache-DiT: user_guide/diffusion/cache_acceleration/cache_dit.md
- Attention Backends: user_guide/diffusion/attention_backends.md
- Frame Interpolation: user_guide/diffusion/frame_interpolation.md
- Parallelism:
- Overview: user_guide/diffusion/parallelism/overview.md
- CFG Parallel: user_guide/diffusion/parallelism/cfg_parallel.md
- Expert Parallel: user_guide/diffusion/parallelism/expert_parallel.md
- Hybrid Sharded Data Parallel: user_guide/diffusion/parallelism/hsdp.md
- Sequence Parallel: user_guide/diffusion/parallelism/sequence_parallel.md
- Tensor Parallel: user_guide/diffusion/parallelism/tensor_parallel.md
- VAE Parallelism: user_guide/diffusion/parallelism/vae_parallelism.md
- CPU Offloading: user_guide/diffusion/cpu_offload.md
- LoRA: user_guide/diffusion/lora.md
- Custom Pipeline: features/custom_pipeline.md
- Execution Modes: user_guide/diffusion/execution_modes.md
- Overview: features/README.md
- Runtime and Stage Execution:
- Execution Modes and Streaming: user_guide/diffusion/execution_modes.md
- Sleep Mode: features/sleep_mode.md
- Quantization:
- Quantization: user_guide/quantization/overview.md
- Overview: user_guide/quantization/overview.md
- Online Quantization: user_guide/quantization/online.md
- Quantized KV Cache: user_guide/quantization/quantized_kvcache.md
- FP8 W8A8: user_guide/quantization/fp8.md
@@ -82,9 +54,43 @@ nav:
- MXFP8 W8A8: user_guide/quantization/mxfp8.md
- MXFP4 W4A4: user_guide/quantization/mxfp4.md
- ModelOpt: user_guide/quantization/modelopt.md
- GGUF: user_guide/quantization/gguf.md
- AutoRound: user_guide/quantization/autoround.md
- msModelSlim: user_guide/quantization/msmodelslim.md
- Diffusion Acceleration:
- Overview and Compatibility:
- Overview: user_guide/diffusion_features.md
- Feature Compatibility: user_guide/feature_compatibility.md
- CPU Offloading:
- Overview: user_guide/diffusion/cpu_offload.md
- Model-Level: user_guide/diffusion/offloader/cpu_offload.md
- Layerwise: user_guide/diffusion/offloader/layerwise_offload.md
- Distributed Layerwise: user_guide/diffusion/offloader/distributed_layerwise_offload.md
- Cache Acceleration:
- TeaCache: user_guide/diffusion/cache_acceleration/teacache.md
- Cache-DiT: user_guide/diffusion/cache_acceleration/cache_dit.md
- Parallelism:
- Overview: user_guide/diffusion/parallelism/overview.md
- CFG Parallel: user_guide/diffusion/parallelism/cfg_parallel.md
- Expert Parallel: user_guide/diffusion/parallelism/expert_parallel.md
- Hybrid Sharded Data Parallel: user_guide/diffusion/parallelism/hsdp.md
- Sequence Parallel: user_guide/diffusion/parallelism/sequence_parallel.md
- Tensor Parallel: user_guide/diffusion/parallelism/tensor_parallel.md
- VAE Parallelism: user_guide/diffusion/parallelism/vae_parallelism.md
- Attention Backends:
- Overview: user_guide/diffusion/attention_backends.md
- Dense Backends: user_guide/diffusion/attention_backends/dense_backends.md
- TRTLLM: user_guide/diffusion/attention_backends/trtllm.md
- SageAttention: user_guide/diffusion/attention_backends/sage.md
- Hugging Face Hub: user_guide/diffusion/attention_backends/huggingface_hub.md
- RainFusion: user_guide/diffusion/attention_backends/rainfusion.md
- Regional Compilation: user_guide/diffusion/regional_compilation.md
- Frame Interpolation: user_guide/diffusion/frame_interpolation.md
- Startup and Loading: user_guide/diffusion/startup_and_loading.md
- LoRA: user_guide/diffusion/lora.md
- Experimental:
- Session State Manager: features/session_state_manager.md
- Integrations:
- Custom Diffusion Pipeline: features/custom_pipeline.md
- ComfyUI: features/comfyui.md
- Fault Tolerance:
- Failure Modes: user_guide/fault_injection_reliability_matrix.md
@@ -110,6 +116,7 @@ nav:
- Async Diffusion Output: design/feature/async_diffusion_output.md
- Async Omni Output Materialization: design/feature/omni_async_output_materialization.md
- Automatic Prefix Caching: design/feature/prefix_caching.md
- Realtime AR-Diffusion: design/feature/realtime_ar_diffusion.md
- Communication:
- OmniConnector Implementations:
- Mooncake Store Connector: design/feature/omni_connectors/mooncake_store_connector.md
@@ -118,6 +125,7 @@ nav:
- Shared Memory Connector: design/feature/omni_connectors/shared_memory_connector.md
- Yuanrong Store Connector: design/feature/omni_connectors/yuanrong_connector.md
- Yuanrong Transfer Engine Connector: design/feature/omni_connectors/yuanrong_transfer_engine_connector.md
- Quantization: design/feature/quantization.md
- Diffusion Acceleration:
- Parallelism:
- CFG-Parallel: design/feature/cfg_parallel.md
@@ -127,13 +135,17 @@ nav:
- Sequence Parallel: design/feature/sequence_parallel.md
- Tensor Parallel: design/feature/tensor_parallel.md
- VAE Patch Parallelism: design/feature/vae_parallel.md
- Attention Backends:
- Attention Optimization:
- Backend Selection: design/feature/attention_backend_selection.md
- Skip-Softmax: design/feature/skip_softmax.md
- Quantization: design/feature/quantization.md
- CPU Offloading:
- Overview: design/feature/offloader/README.md
- Model-Level: design/feature/offloader/cpu_offload.md
- Layerwise: design/feature/offloader/layerwise_offload.md
- Distributed Layerwise: design/feature/offloader/distributed_layerwise_offload.md
- Cache-DiT: design/feature/cache_dit.md
- TeaCache: design/feature/teacache.md
- Diffusion Continuous Batching: design/feature/diffusion_continuous_batching.md
- Distributed Layerwise Offload: design/feature/distributed_layerwise_offload.md
- Infrastructure and Performance:
- Prometheus Metrics: design/metrics.md
- Speech Generation Performance Optimizations: design/qwen3_omni_tts_performance_optimization.md
@@ -167,7 +179,8 @@ nav:
- CLI Reference: cli
- Community:
- Governance: community/governance.md
- community/*
- Contact Us: community/contact_us.md
- Community Meetings: community/meetings.md
- Slack: https://slack.vllm.ai
- Blog: https://blog.vllm.ai
- Forum: https://discuss.vllm.ai
+1 -1
View File
@@ -63,5 +63,5 @@ vLLM-Omni seamlessly supports most popular open-source models on HuggingFace, in
For more information, checkout the following:
- [vllm-omni architecture design and recent roadmaps](https://docs.google.com/presentation/d/1XJWgv79lORl8rbaVvp2d5Sqs6ZEBgAgj/edit?slide=id.p1#slide=id.p1)
- [vllm-omni architecture design and recent roadmaps](https://docs.google.com/presentation/d/1aPj0OGl_-ZVoib-Qne5dGDAlrRFB-PdHl6E-EE99g8E/edit?usp=sharing)
- [vllm-omni announcement blogpost](https://blog.vllm.ai/2025/11/30/vllm-omni.html)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

After

Width:  |  Height:  |  Size: 260 KiB

+7 -3
View File
@@ -1,5 +1,9 @@
# Contact Us
- For technical questions and feature requests, please use GitHub [Issues](https://github.com/vllm-project/vllm-omni/issues)
- For coordinating contributions and development and discussing with other users and developers, please join `sig-omni` channel in our [Slack](https://slack.vllm.ai/) or use the [vLLM Forum](https://discuss.vllm.ai/)
- For security disclosures, please use GitHub's [Security Advisories](https://github.com/vllm-project/vllm-omni/security/advisories) feature
- For bugs and feature requests, search or open a GitHub [issue](https://github.com/vllm-project/vllm-omni/issues).
- For technical and usage questions, join the `sig-omni` channel in [vLLM Slack](https://slack.vllm.ai/) or use the [vLLM Forum](https://discuss.vllm.ai/).
- For coordinating contributions and development, use `sig-omni`, the forum, or join a [community meeting](meetings.md).
## Security Disclosures
Do not share vulnerability details in public GitHub issues, pull requests, discussions, or Slack channels. To arrange a private report, send a direct message to one of the [lead maintainers](governance.md#lead-maintainers) in [vLLM Slack](https://slack.vllm.ai/). If you cannot send a direct message, you may post a detail-free request in `sig-omni` asking a lead maintainer to contact you privately; do not include any vulnerability details in that request.
+3 -23
View File
@@ -52,31 +52,11 @@ Committers have write access and merge rights. They typically have deep expertis
- [@ZJY0516](https://github.com/ZJY0516): Diffusion attention backend, kernel fusion, and CustomOp
- [@yuanheng-zhao](https://github.com/yuanheng-zhao): Diffusion cache, offload, and Omni Support
## Diffusion Workload Division
## Reviewer Routing
This section breaks down diffusion-related responsibilities. If you have PRs touching these areas, please ping the listed owners for review.
For path-based reviewer routing, consult [`.github/CODEOWNERS`](https://github.com/vllm-project/vllm-omni/blob/main/.github/CODEOWNERS). Detailed subsystem boundaries and safe-change guidance live in the [module design documents](../design/index.md#module-design-documents).
### Runtime-related
- Diffusion models: @RuixiangMa, @wtomin, @xuechendi
### Optimization
- Parallel: @RuixiangMa, @wtomin
- Attention backend: @ZJY0516
- Cache: @yuanheng-zhao, @RuixiangMa, @SamitHuang
- Offload: @yuanheng-zhao
- Intel GPU support: @xuechendi
- Quantization: @lishunyang12, @david6666666
- Kernel fusion / communication-computation: @ZJY0516
### Docs & Test
- Diffusion docs: @RuixiangMa, @wtomin
## Meetings
Committers hold **bi-weekly meetings** to discuss future directions and collaborations of the project.
`CODEOWNERS` is operational routing metadata, not a governance or approval policy. Being listed does not grant committer status or merge rights, and it does not mean every listed reviewer must approve a change. The maintainer roster above is authoritative for project roles and merge rights.
## Committer Nomination Process
+8
View File
@@ -0,0 +1,8 @@
# Community Meetings
vLLM-Omni hosts developer-facing meetings for Chinese- and English-language audiences. Schedules and access details can change, so use these maintained documents as the source of truth:
- [Chinese-language meeting document](https://docs.google.com/document/d/1pdUBiS_7mdOUNDtdwy-9OUf7jsMWN324BIbps5olDME/edit?tab=t.0)
- [English-language meeting document](https://docs.google.com/document/d/19AlD08T8uJ7wqfs8VtYCi0iGMTwlTYVVlAxFZ3S7OIg/edit?tab=t.0)
Each document contains the current schedule, access details, agendas, and past meeting notes. For broader vLLM community events, see the [vLLM events calendar](https://vllm.ai/events/).
-1
View File
@@ -1 +0,0 @@
# Meetups
-12
View File
@@ -1,12 +0,0 @@
# Volunteers for Bugfix and CI
We encourage you to check current docs and [issues](https://github.com/vllm-project/vllm-omni/issues) to find possible solutions for your questions. If non of these can solve it, please propose an issue to describe your questions about bug or CI problems for developing.
If you have urgent need for locating and solving bugfix or CI problems, please find community volunteers below.
| Dec 4-Dec 12 | Dec 15-Dec 19 | Dec 22-Dec 26 | Dec 29- Jan 2, 2026| Jan 5-Jan 9 | Jan 12-Jan 16 |
|----------|----------|----------|----------|----------|----------|
| <a href="https://github.com/congw729">Conw729</a> | <a href="https://github.com/yinpeiqi">yinpeiqi</a> | <a href="https://github.com/tzhouam">tzhouam</a> | <a href="https://github.com/SamitHuang">SamitHuang</a> | <a href="https://github.com/gcanlin">gcanlin</a> | <a href="https://github.com/natureofnature">natureofnature</a> |
| <a href="https://github.com/david6666666">david6666666</a> | <a href="https://github.com/R2-Y">R2-Y</a> | <a href="https://github.com/hsliuustc0106">hsliuustc0106</a> | <a href="https://github.com/Gaohan123">Gaohan123</a> | <a href="https://github.com/ZJY0516">ZJY0516</a> | <a href="https://github.com/qibaoyuan">qibaoyuan</a> |
We kindly welcome more contributors to fix bugs and contribute new features!
+43 -2
View File
@@ -3,7 +3,7 @@
Thank you for your interest in contributing to vLLM-Omni! This document provides guidelines and instructions for contributing.
!!! note
We host weekly developer-facing online meetings to discuss milestones and updates **every Tuesday at 19:30 PDT**. Meeting link as well as the past meeting notes can be found [here](https://tinyurl.com/vllm-omni-meeting).
vLLM-Omni hosts developer-facing meetings for Chinese- and English-language audiences. See [Community Meetings](../community/meetings.md) for current schedules, access details, agendas, and past notes.
## Getting Started
@@ -76,12 +76,53 @@ Please refer to the [test instructions](./ci/test_execution_guide.md) for detail
!!! warning
Currently, not all unit tests pass when run on CPU platforms. If you don't have access to a GPU platform to run unit tests locally, rely on the continuous integration system to run the tests for now.
### Using repository skills with coding agents
vLLM-Omni maintains [repository-scale skills](https://github.com/vllm-project/vllm-omni/tree/main/.claude/skills) for common coding, testing, performance, and review workflows. These skills capture repository-specific structure, validation requirements, and evidence standards that a general coding agent may not know.
If your coding agent discovers repository skills automatically, ask it to use the relevant skill by name. Otherwise, point it to the linked `SKILL.md` and ask it to read the file before changing code. Skills can be combined: use a domain skill for the implementation, `vllm-omni-test` for test and CI decisions, and `precheck-pr` before opening the pull request.
| Task | Repository skill |
| --- | --- |
| Add or extend a diffusion model | [`add-diffusion-model`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/add-diffusion-model/SKILL.md) |
| Add or extend a text-to-speech model | [`add-tts-model`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/add-tts-model/SKILL.md) |
| Add, select, or debug quantization | [`quantization`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/quantization/SKILL.md) |
| Diagnose or optimize diffusion performance | [`diffusion-perf-opt`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/diffusion-perf-opt/SKILL.md) |
| Upgrade an NPU model runner | [`vllm-omni-npu-model-runner-upgrade`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/vllm-omni-npu-upgrade/SKILL.md) |
| Add a regression test, choose L1-L4 coverage, or wire Buildkite | [`vllm-omni-test`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/vllm-omni-test/SKILL.md) |
| Self-check a branch before opening a pull request | [`precheck-pr`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/precheck-pr/SKILL.md) |
| Perform a maintainer or reviewer review of an existing pull request or local branch | [`review-pr`](https://github.com/vllm-project/vllm-omni/blob/main/.claude/skills/review-pr/SKILL.md) |
Use the following workflow when collaborating with a coding agent:
1. **Ground the task.** Provide the issue, RFC, or design document that defines the expected behavior. Ask the agent to state its assumptions and identify the affected module or feature contracts before editing code.
2. **Select the narrowest applicable skills.** Start with the domain skill that owns the change. Add `vllm-omni-test` whenever production behavior or tests change. For a bug fix, ask for the smallest reproducer and a regression test tied to the original symptom.
3. **Require executable evidence.** Ask the agent to run the narrowest relevant checks and report the exact commands and results. It must identify tests it could not run because of unavailable hardware, model weights, credentials, or dependencies; an unrun check is not a pass.
4. **Inspect the resulting diff.** Confirm that the implementation stays within the issue or RFC, does not overwrite unrelated work, and includes the required tests, documentation, and benchmark or accuracy evidence.
5. **Run the pre-submit workflow.** Use `precheck-pr`, then run the applicable local tests and pre-commit hooks before opening the pull request.
For example:
```text
Use add-diffusion-model and vllm-omni-test to implement the linked issue.
Read the relevant design documents first, keep the change within the issue,
and report every test command, result, and hardware validation gap.
```
```text
Use vllm-omni-test to turn this bug reproducer into the smallest deterministic
regression test. Prefer L1 CPU coverage; if the failure requires real weights
or serving, explain the required L2/L3 environment and provide the exact command.
```
Repository skills guide the agent, but they do not replace contributor judgment, the accepted issue or RFC, required test evidence, or maintainer review. Review all generated changes before submitting them.
## Issues
If you encounter a bug or have a feature request, please search existing issues first to see if it has already been reported. If not, please file a new issue, providing as much relevant information as possible.
!!! important
If you discover a security vulnerability, please report it by creating a GitHub issue with the `security` label.
Do not report suspected security vulnerabilities through a public issue, pull request, discussion, or Slack channel. Follow the [security disclosure instructions](../community/contact_us.md#security-disclosures) to arrange a private report.
## Pull Requests & Code Reviews
+93
View File
@@ -327,6 +327,99 @@ On PR builds, `upload_pipeline.py` logs `skip '…' (no changes under …)` for
- Use **groups** for dashboard readability; keep **E2E Test** as the group name CUDA diff filtering expects for `--e2e` nightly runs on main.
- Prefix labels by model domain: **Omni ·**, **TTS ·**, **Diffusion ·**, **Simple ·**, etc., matching existing steps.
### Per-model coverage
Pilot (v1): one Merge-tier (L3) job in `.buildkite/cuda/test-merge.yml` uploads
per-model, per-entry-mode coverage as Buildkite artifacts — "TTS · Qwen3-TTS Base
Test". It runs on a single GPU so the pilot is cheap to reproduce. (A second
diffusion pilot, "Diffusion · Bagel Test", was retired from merge; reintroduce
another diffusion coverage job if a second pilot is needed again.) This is a
pilot, not a rollout: no dashboard/visualization lives in this repo, and nothing
is gated on coverage.
**Naming convention**: `coverage-<model_id>-<mode>-<step_id>.xml.gz`, where
`<model_id>` is the model's directory name under
`vllm_omni/diffusion/models/<model_id>/` or
`vllm_omni/model_executor/models/<model_id>/` (e.g. `z_image`, `qwen3_omni`),
`<mode>` is `online` or `offline`, and `<step_id>` is `BUILDKITE_STEP_ID`
(`local` outside Buildkite). `gunzip` before feeding a report to a Cobertura
consumer.
Reports are gzipped because `--cov=vllm_omni` sets coverage's `source`, which
makes it walk the package and emit one `<line>` element per statement for every
file — including the ones a single model's tests never import. That inventory,
not the coverage, is the size: a Bagel report is 7.1 MB, of which 96.5% is
`<line>` elements and 77% belongs to the 840 of 1169 files that run never
imported. A run covering zero lines produces the same 7 MB. gzip takes it to
roughly 410 KB and changes nothing about the data.
`<step_id>` is what keeps two steps that cover the same model apart. Artifacts are
scoped to the build, and a nightly build carries the ready, merge and nightly tiers
at once, so several same-model steps land in one namespace — `qwen3_tts` already has
both a Base and a CustomVoice job, and `minicpmo_4_5` a base and a duplex one. Two
uploads on one path do not fail loudly: an exact-name download can report the path
as ambiguous, and a glob download fetches every match concurrently and renames each
onto the same destination, so whichever finishes last wins. The step id remains the
logical step identifier across retries, while Buildkite's default artifact lookup
selects only the latest attempt — `BUILDKITE_JOB_ID` would instead give every
attempt its own filename, leaving a failed attempt's partial report to be picked up
alongside the real one. A step using `parallelism`/matrix would need
`BUILDKITE_PARALLEL_JOB` added, since its jobs share a step id; neither pilot is
one.
**Opting in a new model**: replace the job's combined `pytest` command with
[`run_cov_split.sh`](https://github.com/vllm-project/vllm-omni/blob/main/.buildkite/common/scripts/run_cov_split.sh),
which runs each mode, names the reports, uploads them, and fails the step if
either half or the upload failed:
```yaml
commands:
- |
.buildkite/common/scripts/run_cov_split.sh \
--model-id <model_id> \
--offline <offline test path> \
--online <online test path> \
-- <the job's existing pytest flags, e.g. -m '...' --run-level '...'>
```
Everything after `--` is forwarded verbatim to both runs with quoting preserved,
so an expression like `-m 'advanced_model and cuda'` survives intact and a job can
pass anything else it needs. `--offline`/`--online` are repeatable and only one is
required, so a job with tests in a single mode runs just that half. Runtime is
bounded solely by the step's `timeout_in_minutes` — raise it, since the split
loads the model once per mode.
Before splitting, confirm each half actually collects at least one test under the job's forwarded filters — pytest exits with code 5 ("no tests collected") if a half is empty, which the script reports as a failure, red-ing a job that used to pass as one combined invocation.
Also check the tests' `num_cards` against the job's `mirror_hardwares` preset.
`cuda_marks` turns `num_cards > 1` into `skipif(device_count() < num_cards)`, so a
test asking for more GPUs than the preset provides is silently skipped and its
coverage artifact comes back empty. Splitting such a job produces a file that
looks fine and measures nothing — "Diffusion · Z Image Test" is the current
example (online tests want 4 cards, the job runs on `l4_1`), which is why it is
not a coverage pilot.
Online-mode coverage depends on the `[tool.coverage.run]` `patch`/`sigterm`
settings in `pyproject.toml`: online tests launch the server with
`subprocess.Popen` and stop it with SIGTERM, and without those settings the XML
reflects only the pytest parent process, not the server's code paths.
The upload depends on `buildkite-agent` being callable inside the container. The
`kubernetes` presets (`h100_*`, `*_npu_*`) provide it; the `docker` ones (`l4_*`)
only do because they set `mount-buildkite-agent: true`. A new docker preset that
runs a coverage job needs the same.
List both `run_cov_split.sh` and `pyproject.toml` in every opted-in job's
`source_file_dependencies` — both change what the job measures, so without them a
change there is filtered out of normal PR builds and only surfaces in a later
nightly. `tests/buildkite/test_upload_pipeline.py` covers the filter behavior with
a synthetic job (it does not pin real merge labels).
Editing only the surrounding CI YAML still does not schedule them, so a PR that
touches just the wiring needs a full E2E run (or the commands run on a GPU host)
to produce artifacts. When checking a new model's
artifacts, compare `lines-covered` between the online and offline XML rather than
just confirming both files exist.
### Validation checklist
| Check | Command / location |
+110 -63
View File
@@ -672,100 +672,147 @@ down and spawn a new one mid-module. A few rules that save real CI debugging tim
## Online Serving Integration
To expose your model through the `/v1/audio/speech` OpenAI-compatible endpoint, add
**all five** of the following integration points to
`vllm_omni/entrypoints/openai/serving_speech.py` in a **single commit**. Adding them
piecemeal causes partial-integration failures that are hard to debug.
To expose your model through the `/v1/audio/speech` OpenAI-compatible endpoint, write
one adapter under `vllm_omni/entrypoints/openai/tts_adapters/`. The adapter declares
how your model is recognized and owns its request handling; `serving_speech.py` should
not need an edit.
### 1. Stage constant
### 1. Write the adapter
Near the top of the file, alongside the other `_*_TTS_MODEL_STAGES` constants:
Create `vllm_omni/entrypoints/openai/tts_adapters/your_model.py`:
```python
_YOUR_MODEL_TTS_MODEL_STAGES = {"your_model_stage_key"}
# SPDX-License-Identifier: Apache-2.0
"""YourModel serving adapter."""
from typing import TYPE_CHECKING
from vllm_omni.entrypoints.openai.tts_adapters import register_tts_adapter
from vllm_omni.entrypoints.openai.tts_adapters.base import ARTTSAdapter, PreparedRequest
if TYPE_CHECKING:
from vllm_omni.entrypoints.openai.protocol.audio import OpenAICreateSpeechRequest
@register_tts_adapter
class YourModelAdapter(ARTTSAdapter):
# The registry key, and the model-type string used in logs.
name = "your_model"
# The engine ``model_stage`` value(s) your deployment yaml sets. Detection,
# stage discovery and `/v1/audio/speech` routing all derive from this.
stage_keys = frozenset({"your_model_stage_key"})
def validate(self, request: "OpenAICreateSpeechRequest") -> str | None:
"""Return an error string, or None if the request is valid."""
if not request.input or not request.input.strip():
return "Input text cannot be empty"
return None
async def build(
self,
request: "OpenAICreateSpeechRequest",
sampling_params_list: list,
has_inline_ref_audio: bool,
) -> PreparedRequest:
"""Build the engine prompt and per-model parameters."""
params: dict[str, list] = {"text": [request.input]}
if request.voice is not None:
params["voice"] = [request.voice]
return PreparedRequest(
prompt={"prompt": request.input},
tts_params=params,
model_type=self.name,
)
```
### 2. Union into `_TTS_MODEL_STAGES`
Then add it to the import block at the bottom of
`vllm_omni/entrypoints/openai/tts_adapters/__init__.py` so it registers on import.
That import line is the only shared file a new model has to touch.
Add to the `_TTS_MODEL_STAGES` set union:
> **Pure-diffusion TTS does not go through adapters yet.** When the server is built
> by `OmniOpenAIServingSpeech.for_diffusion()`, `create_speech()` routes straight to
> `_create_diffusion_speech()` and never calls `validate()` or `build()`.
> `DiffusionTTSAdapter` is scaffolding for that migration and has no production
> subclass today, so validation or prompt construction placed in one would silently
> never run. If your model is served by the diffusion engine rather than
> `engine_client`, follow the existing diffusion path and say so on #4855 — wiring
> that path through the adapter layer is open work, not something to do inside a
> new-model PR.
### 2. If a stage key alone cannot identify your model
Two escape hatches, in order of preference:
```python
_TTS_MODEL_STAGES: set[str] = (
...
| _YOUR_MODEL_TTS_MODEL_STAGES
)
# The architecture is authoritative (e.g. your model has no dedicated
# model_stage value, or shares one with another model).
model_archs = frozenset({"YourModelForConditionalGeneration"})
# Set this too if your model owns NO stage key, so stage discovery has to find
# your AR entry stage by architecture.
arch_identifies_entry_stage = True
```
### 3. Model type detection
In `_detect_tts_model_type()`, add before the final `return None`:
If your rule is not a set-membership test, override `matches()` — see
`covo_audio.py`, which shares the generic `fused_thinker_talker` stage key with
non-CoVo deployments and confirms with the architecture:
```python
if model_stage in _YOUR_MODEL_TTS_MODEL_STAGES:
return "your_model"
@classmethod
def matches(cls, model_stage: str | None, model_arch: str | None) -> bool:
return super().matches(model_stage, model_arch) and bool(model_arch) and "CovoAudio" in model_arch
```
### 4. Request validation dispatch
If your model can match the same deployment as another adapter, give one of them an
explicit `detect_priority` (lower runs first). `tests/entrypoints/openai_api/
test_tts_detection.py` fails if two same-priority detectors can both match one input,
so an unordered overlap cannot be merged.
In `_validate_tts_request()`, add before the fallback `return`:
Models that are speech-capable only in some deployment topologies override
`stage_serves_speech()` — see `audex.py`, whose omni thinker is text-final unless the
speech decoder is deployed alongside it.
```python
if self._tts_model_type == "your_model":
return self._validate_your_model_request(request)
```
### 3. Reuse the shared helpers
### 5. Validation and parameter-builder methods
Adapters reach shared serving helpers through `self.ctx.server`: reference-audio
resolution (`_resolve_ref_audio`), uploaded-speaker handling
(`_apply_uploaded_speaker`), format validation (`_validate_ref_audio_format`), and
prompt-length limits (`_max_instructions_length`). Read a comparable adapter before
writing your own — `fish_speech.py` for voice cloning, `higgs_audio_v3.py` for
parameter-heavy models, `moss_tts.py` for a family sharing one base class.
Add two new methods:
### 4. Test it
```python
def _validate_your_model_request(
self, request: OpenAICreateSpeechRequest
) -> str | None:
"""Validate YourModel request. Returns an error string or None."""
if not request.input or not request.input.strip():
return "Input text cannot be empty"
return None
`tests/entrypoints/openai_api/test_tts_adapter.py` covers registry invariants and
`test_tts_detection.py` covers detection. Add your model to
`EXPECTED_MODEL_TYPES` in the former, and a case to the latter if you added a
`model_archs` or `matches()` rule.
def _build_your_model_params(
self, request: OpenAICreateSpeechRequest
) -> dict[str, Any]:
"""Build additional_information dict for YourModel."""
params: dict[str, Any] = {"text": [request.input]}
if request.voice is not None:
params["voice"] = [request.voice]
# Add any other model-specific fields here
return params
```
### Do not add branches to `serving_speech.py`
Then wire `_build_your_model_params` into the request-dispatch block in
`_create_tts_request()` (search for the equivalent `_build_*_params` call for an
existing model to find the right location). If the model supports voice cloning
(`ref_audio` → `prompt_audio_path`, `ref_text` → `prompt_text`), add those mappings
here too — follow any existing `_build_<model>_params` in `serving_speech.py` (e.g.
`_build_moss_tts_params` for the voice-cloning variant) for the pattern.
Older models predate the adapter framework and still have per-model branches in
`serving_speech.py`; they are being migrated out (RFC #4327, #4855). Do not copy
that pattern. `tools/pre_commit/check_tts_adapter.py` is a ratchet on the remaining
`self._tts_model_type == ...` comparisons and fails the commit if the count grows.
> **Two dispatch patterns coexist:** Fish Speech uses a `self._is_fish_speech` boolean
> checked *before* `elif self._is_tts`. All newer models use the `_tts_model_type`
> string pattern shown above. For new models, always use the string pattern — do not
> add new `_is_*` boolean flags.
> **Note on unused variables:** Only extract parameters in `_build_your_model_params`
> that you actually pass to the model's generate / `inference_stream` call. Extracting
> a variable without forwarding it will trigger a `ruff F841` pre-commit failure.
If your model genuinely needs behaviour that no adapter hook can express, that is a
missing hook — propose it on the RFC rather than adding a branch.
### Merge conflicts
`serving_speech.py` is modified by every new model PR and is the most common source of
rebase conflicts. When rebasing onto `main` and a conflict appears here, the resolution
is always to **keep both** the upstream model's additions and your own — never discard
either side. After resolving:
Your adapter is a new file, so it cannot conflict. The one shared line is your entry
in the import block at the bottom of `tts_adapters/__init__.py`, which conflicts only
when another model lands at the same time. The resolution is always to **keep both**
imports — never discard either side. After resolving:
```bash
git add vllm_omni/entrypoints/openai/serving_speech.py
git add vllm_omni/entrypoints/openai/tts_adapters/__init__.py
git rebase --continue
```
If you find yourself resolving a conflict inside `serving_speech.py`, something in
your model is still going through the legacy path; see the note above.
## Single-Stage Models
Some TTS models (e.g. MOSS-TTS-Nano) do not use a two-stage pipeline. Instead the
@@ -4,6 +4,9 @@
> `experimental/ar_diffusion` contract. It follows the ownership and lifecycle
> direction in [#5137](https://github.com/vllm-project/vllm-omni/issues/5137),
> but it is not yet part of the stable module-design hierarchy.
>
> The end-to-end request, identity, failure, and memory contracts are documented
> in [Realtime AR-Diffusion sessions](feature/realtime_ar_diffusion.md).
`ARDiffusionEngine` is an opt-in diffusion backend for pipelines that keep
autoregressive attention KV across requests. The engine only selects
@@ -51,14 +54,13 @@ time, and its inherited batch/step entry points also fail explicitly. Supporting
those paths requires a batch-aware state-binding contract rather than silently
bypassing `bind_ar_diffusion_state()`.
The current implementation retains one session per model instance. A request
for a different `session_id` closes the resident session through the same LRU
lifecycle used by explicit close and failure cleanup before allocating the new
one. Self-attention and cross-attention memory are therefore sized for one
resident session even if the pipeline declares a larger `session_capacity`.
This prioritizes rollout throughput and prevents block-pool exhaustion before a
count-based eviction can run. Multi-session residency can be added later with a
memory-backed capacity calculation or allocation-pressure eviction.
The implementation may retain multiple sessions per model instance. It selects
the largest feasible capacity up to the pipeline's `session_capacity`, based on
self-attention pages, cross-attention allocations, scratch, and declared
model-owned state. One session is admitted whenever it fits actual free device
memory; `gpu_memory_fraction` controls additional residency. Requests beyond
that capacity evict the least-recently-used session through the same lifecycle
hook used by explicit close and failure cleanup.
Scratch storage is also capability-driven. `frames_per_block` reserves space for
an uncommitted current video block, while `max_scratch_tokens_per_branch`
+406 -144
View File
@@ -1,6 +1,6 @@
# Architecture Overview
This document outlines the architectural design for vLLM-Omni.
This document outlines the architecture of vLLM-Omni.
<p align="center">
<picture>
@@ -9,194 +9,456 @@ This document outlines the architectural design for vLLM-Omni.
</picture>
</p>
# Goals
## Design goals
The primary goal of the vLLM-Omni project is to build the fastest and easiest-to-use open-source Omni-Modality model inference & serving engine. vLLM-Omni extends the original vLLM, which was created to support large language models for text-based autoregressive (AR) generation tasks. vLLM-Omni is designed to support:
The primary goal of vLLM-Omni is to provide a fast and easy-to-use inference
and serving engine for omni-modality models. vLLM-Omni extends vLLM's
text-oriented autoregressive (AR) runtime with stage-based execution for
non-textual outputs and non-autoregressive model components.
* **Non-textual Output:** Enables the integration, efficient processing and output of various data types, including but not limited to, images, audio, video, and action trajectories, alongside text.
* **Non-Autoregressive Structure:** Support model structure beyond autoregressive, especially Diffusion Transformer (DiT), which is widely used in visual and audio generation.
* **Integration with vLLM Core:** Maintain compatibility and leverage existing vLLM key modules and optimizations where applicable.
* **Extensibility:** Design a modular and flexible architecture that can easily accommodate new modalities, model architectures, and output formats.
The architecture is designed to:
* support text, image, audio, video, and action inputs and outputs;
* compose autoregressive, generation, and diffusion stages in one pipeline;
* reuse vLLM scheduling, cache, distributed-execution, and serving
primitives where they fit; and
* keep model topology, deployment placement, runtime lifecycle, transport,
and public API concerns in separate layers.
# Representative omni-modality models
## Model execution
According to analysis for current popular open-source models, most of them have the combination of AR+DiT. Specifically, they can be further categorized into 3 types below:
These four examples show how vLLM-Omni maps model components to stage-local
execution policies. Each summary covers the model-owned path, batching,
attention, parallelism, quantization, and primary serving targets. The profiles
are representative; a model may support multiple `PipelineConfig` and
`DeployConfig` combinations.
**DiT as a main structure, with AR as text encoder (e.g.: Qwen-Image)**
A powerful image generation foundation model capable of complex text rendering and precise image editing.
| Model | Model-owned path | vLLM-Omni stage view | Primary serving target |
| --- | --- | --- | --- |
| Qwen3-Omni | Thinker → Talker → Code2Wav | Three stages with asynchronous chunk hand-off | TTFT/TTFP, TPOT, E2EL, audio RTF, and concurrent throughput |
| HunyuanImage-3.0 | Multimodal AR understanding/reasoning plus image-generation DiT | AR-only, DiT-only, or split AR → DiT deployment | DiT E2EL/denoising latency and image throughput; TTFT/TPOT for AR tasks |
| MiniMax-H3 | Text encoder → task-specific FL2VA or Ref2VA DiT → video/audio VAE decoder | Three logical component/phase boundaries within one registered diffusion stage | Video/audio E2EL and media throughput; RTF when audio streaming is measured |
| Cosmos3 | Unified MoT reasoner tower plus diffusion generator tower | One diffusion pipeline materializes both towers inside the stage | Image/video/action E2EL and throughput; RTF for synchronized audio |
### Serving metric vocabulary
The target metric follows the output modality, not just the model name.
| Metric | Meaning in this document | Most useful for |
| --- | --- | --- |
| **TTFT** | Time to the first text token | AR reasoning or text output |
| **TPOT** | Time per output token after the first token | AR decode stages |
| **TTFP** | Time to the first streamed media packet, such as audio | Interactive speech and multimodal chat |
| **E2EL** | End-to-end latency from request admission to the final output | Image, video, audio, and action requests |
| **RTF** | Wall-clock processing time divided by generated audio duration; lower is faster than real time | Audio generation |
| **Throughput** | Requests, tokens, or media seconds produced per wall-clock second | Offline and concurrent serving |
### Qwen3-Omni: streaming AR pipeline
Qwen3-Omni illustrates a multi-stage streaming AR pipeline: Thinker → Talker →
Code2Wav. The [technical report](https://arxiv.org/abs/2509.17765) describes
the model components, and the figure shows the stage-level streaming schedule
used by vLLM-Omni.
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/dit-main-architecture.png">
<img alt="Qwen-Image" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/dit-main-architecture.png" width=30%>
</picture>
<a href="https://github.com/vllm-project/vllm-omni/blob/main/docs/source/architecture/qwen3-omni-async-chunk.png">
<img alt="Qwen3-Omni Thinker, Talker, and Code2Wav streaming stages" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/qwen3-omni-async-chunk.png" width="80%">
</a>
</p>
**AR as a main structure, with DiT as multi-modal generator (e.g. BAGEL)**
A unified multimodal comprehension and generation model, with cot text output and visual generation.
#### Model architecture by stage
| Stage | Model component | Stage output |
| --- | --- | --- |
| **Thinker** | AuT audio encoder, SigLIP2 vision encoder, and the 30B-total/3B-active Thinker MoE Transformer | Text tokens and conditioning for the Talker |
| **Talker** | 3B-total/0.3B-active Talker MoE Transformer with the MTP code-prediction path | Text tokens and audio codec tokens |
| **Code2Wav** | Approximately 200M-parameter ConvNet audio decoder | Waveform/audio chunks |
#### Representative stage execution
| Stage | Batching | Attention and execution | Parallelism | Quantization |
| --- | --- | --- | --- | --- |
| **Thinker** | Continuous batching with stage-local `max_num_seqs` and token budgets | vLLM KV-cached AR attention; CUDA Graph execution when the stage is not eager | Independent stage placement; use the AR runtime's configured tensor parallelism | Supported ModelOpt FP8/NVFP4 or AutoRound checkpoint paths target the Thinker; encoders remain BF16 in the documented paths |
| **Talker** | Continuous batching over autoregressive decode requests | KV-cached token decode with async-chunk output to Code2Wav | Independent stage placement; typically a separate GPU or replica from Thinker | BF16 baseline; no generic Talker quantization path is assumed |
| **Code2Wav** | Static/chunk batching for codec-to-waveform decode | Non-AR chunked audio decode; eager execution is commonly retained | Separate stage or colocated placement, depending on the deployment | BF16 baseline; keep codec/vocoder precision model-specific |
For this pipeline, the main serving target is interactive responsiveness:
TTFT for text, TTFP for the first audio packet, TPOT for autoregressive decode,
E2EL for the complete answer, and RTF/throughput for sustained audio serving.
Async chunking and streaming primarily reduce TTFP and improve stage overlap;
batching and CUDA Graphs primarily improve E2EL and throughput. See the
[Qwen3-Omni recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/Qwen/Qwen3-Omni.md)
and [async chunk design](feature/async_chunk.md) for the deployment details.
### HunyuanImage-3.0: shared multimodal model, split deployment choices
HunyuanImage-3.0 illustrates a shared multimodal model with flexible AR, DiT,
and split AR → DiT deployment. The official [technical
report](https://arxiv.org/abs/2509.23951) provides the model view; the tables
below map it to vLLM-Omni stages.
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/ar-main-architecture.png">
<img alt="Bagel" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/ar-main-architecture.png" width=30%>
</picture>
<a href="https://github.com/Tencent-Hunyuan/HunyuanImage-3.0/blob/main/assets/framework.png">
<img alt="HunyuanImage-3.0 framework for understanding, language modeling, and image generation" src="https://raw.githubusercontent.com/Tencent-Hunyuan/HunyuanImage-3.0/main/assets/framework.png" width="95%">
</a>
</p>
**AR+DiT (e.g. Qwen-Omni)**
A natively end-to-end omni-modal LLM for multimodal inputs (text/image/audio/video...) and outputs (text/audio...).
#### Model architecture by stage
| Stage or component | Model component | Stage output |
| --- | --- | --- |
| **AR understanding/reasoning** | Understanding and generation encoders feeding the Hunyuan-A13B decoder-only Transformer and text detokenizer | Text responses or image-generation conditioning |
| **Image generation** | Generation encoder, diffusion prediction path/Gen. Decoder, and the image VAE decode path | Image latents and final images |
The vLLM-Omni deployment may expose the AR path only, the DiT path only, or
both as an AR → DiT pipeline with a connector between them. That is a runtime
decomposition of the model's capabilities; it should not be read as a claim
that the published framework figure contains two unrelated backbones.
#### Representative stage execution
| Stage | Batching | Attention and execution | Parallelism | Quantization |
| --- | --- | --- | --- | --- |
| **AR** | Standard vLLM continuous batching when serving understanding/text tasks | KV-cached causal attention | Tensor/expert parallelism follows the selected AR deployment | Checkpoint-specific; do not infer DiT FP8 settings for the AR checkpoint |
| **DiT + VAE** | Request batching or step-wise batching; Hunyuan step batching with more than one request requires `TORCH_SDPA` | `TORCH_SDPA` is used because the model mixes causal and full attention | Validated profiles include TP4, TP2 + sequence parallelism, TP2 + CFG parallelism, and expert parallelism for MoE weights | Online FP8 and ModelOpt mixed FP8/NVFP4 are documented for the DiT; VAE precision stays separate |
Image generation is therefore measured mainly with per-image E2EL/denoising
latency, peak memory, and images-per-second throughput. TTFT and TPOT remain
meaningful for the optional AR understanding path, but they are not the right
headline metrics for the DiT path. See the
[HunyuanImage-3.0 recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/Tencent/HunyuanImage-3.0-Instruct.md)
for the validated batching, attention, and quantization combinations.
### MiniMax-H3: conditioning, denoising, and decode
MiniMax-H3 illustrates logical component and phase boundaries between text
encoding, task-specific denoising, and media decoding:
`Text Encoder → DiT → VAE Decoder`. The current registered topology co-locates
these components in one diffusion stage. These boundaries are useful for
profiling and offload; independent placement would require a future
multi-stage `PipelineConfig`. The stage mapping follows the implementation and
serving recipe; the [release overview](https://minimaxi.com/blog/minimax-h3)
notes that a detailed technical report is forthcoming.
#### Model architecture by component
| Logical component | Model component | Component output |
| --- | --- | --- |
| **Text Encoder** | Tokenizer/processor and Qwen3-VL text encoder; vision/audio references are prepared alongside the text condition | Packed multimodal conditioning for denoising |
| **DiT** | Task-specific `FL2VA` DiT for text/first-frame generation or `Ref2VA` DiT for mixed references | Video and audio latent tokens |
| **VAE Decoder** | Video VAE and audio VAE decode the generated latents and assemble the synchronized output | Decoded video frames and stereo waveform, with FPS and audio sample rate metadata |
Both DiT partitions remain behind one task-selection point; `task` chooses
which partition runs. In the current implementation, the three logical
components execute inside one diffusion stage. This is different from
Qwen3-Omni's three independently scheduled stages, even though both models
produce synchronized audio and video-like outputs.
#### Representative component execution
| Logical component | Batching | Attention and execution | Parallelism | Quantization |
| --- | --- | --- | --- | --- |
| **Text Encoder** | The current co-located pipeline follows the diffusion request scheduler; independent prompt/reference batching would require a separate multi-stage topology | Qwen3-VL attention and multimodal preprocessing | `--text-encoder-tp-size N` shards the encoder across the first `N` DiT ranks; independent placement is not part of the current topology | BF16/FP32 baseline; the H3 DiT FP8 path does not quantize the text encoder |
| **DiT** | The current H3 implementation executes one generation request per diffusion batch; use concurrency for service-level throughput | cuDNN attention for the validated two-GPU consumer profile; TRTLLM attention or FlashAttention-4 on supported Blackwell profiles | TP2 plus text-encoder TP and Ulysses/VAE parallel groups on multi-GPU profiles; DLO/CPU offload trade memory for transfer time | Online FP8 applies to eligible DiT linears and is incompatible with layerwise offload |
| **VAE Decoder** | Decode follows each generation request; tile/patch work can be distributed even when denoising is not batched | VAE decode kernels rather than DiT attention | VAE patch parallelism and native tiled decode within the diffusion stage | BF16/FP32 baseline; the documented H3 FP8 path leaves both VAEs unchanged |
The primary target is video/audio E2EL and media throughput, with the logical
component boundaries making prompt encoding, denoising, and VAE decode costs
separately measurable. RTF is useful when the audio stream is evaluated
independently. TTFT and TPOT do not describe the main H3 generation path
because the user-visible output is diffusion media rather than a token stream.
The
[MiniMax-H3 recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/MiniMaxAI/MiniMax-H3.md)
contains the hardware-specific profiles and warmup requirements.
### Cosmos3: unified MoT reasoner and generator
Cosmos3 illustrates a unified Mixture-of-Transformers (MoT) reasoner and
diffusion generator. The official [technical
report](https://research.nvidia.com/labs/cosmos-lab/cosmos3/technical-report.pdf)
and NVIDIA's [technical explanation](https://developer.nvidia.com/blog/develop-physical-ai-reasoning-world-and-action-models-with-nvidia-cosmos-3/)
provide the two-tower model view used below.
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/ar-dit-main-architecture.png">
<img alt="Qwen-Omni" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/ar-dit-main-architecture.png" width=30%>
</picture>
<a href="https://developer.nvidia.com/blog/develop-physical-ai-reasoning-world-and-action-models-with-nvidia-cosmos-3/">
<img alt="Cosmos3 autoregressive reasoner and diffusion generator towers" src="https://developer-blogs.nvidia.com/wp-content/uploads/2026/05/image-11-e1780000686151.webp" width="95%">
</a>
</p>
# vLLM-Omni main architecture
#### Model architecture by stage
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/vllm-omni-main-architecture.png">
<img alt="vLLM-Omni Main Architecture" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/vllm-omni-main-architecture.png" width=55%>
</picture>
</p>
| Stage or component | Model component | Stage output |
| --- | --- | --- |
| **Reasoner tower** | Autoregressive VLM path with causal attention over language and optional vision/action context; runs once per generation request | Discrete reasoning/context tokens |
| **Generator tower** | Diffusion path with full attention over the generator tokens and the reasoner K/V context; runs for each denoising step | Image, video, audio, or action tokens |
| **Shared pipeline** | `Cosmos3OmniDiffusersPipeline` plus modality encoders/decoders and VAE paths | Final image/video/audio or action response |
## Key Components
The reasoner and generator are model-owned components, not two independent
vLLM-Omni stages by default. The current Cosmos3 pipeline materializes both
inside one diffusion stage; model-level CPU offload can swap the reasoner and
generator components between their phases.
| Component | Description |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **OmniRouter** | provide an intelligent router for Omni-modality requests dispatch |
| **EntryPoints** | define the APIs for offline/online serving (APIServer, Omni/AsyncOmni), while `AsyncOmniEngine` and `Orchestrator` coordinate multi-stage AR/DiT execution |
| **AR** | adapted for omni-modality models while inheriting efficient features from vLLM, such as cache management |
| **Diffusion** | natively implemented and optimized using acceleration components |
| **OmniConnector** | supports fully disaggregation based on E/P/D/G (Encoding/Processing/Decoding/Generation) disaggregation across stages |
#### Representative stage execution
Disaggregated stages are managed through stage configuration. In Qwen3-Omni, Thinker/Talker/Code2wav are declared as separate configured stages, and runtime routing is handled by `Orchestrator` over `StageEngineCoreClient` / `StageDiffusionClient`.
| Stage | Batching | Attention and execution | Parallelism | Quantization |
| --- | --- | --- | --- | --- |
| **Reasoner + generator pipeline** | Use request batching or step execution only when the selected pipeline advertises that capability; otherwise use `max_num_seqs=1` | Causal attention for reasoner tokens and full attention for diffusion tokens; the validated recipe uses a platform-selected aiter FlashAttention path with `TORCH_SDPA` fallback | Ulysses/context parallelism or tensor parallelism for the transformer; VAE tiling and layerwise/model-level offload address activation and weight memory | Online FP8 is supported for the diffusion pipeline; AutoRound/checkpoint-specific paths and quality validation remain separate from the BF16 baseline |
For Cosmos3, generation E2EL and output throughput are the primary targets.
Action-policy workloads add a control-loop latency target, while synchronized
audio workloads add RTF. TTFT/TPOT are appropriate for a reasoner-only service,
but not for the full diffusion generation path. See the
[Cosmos3 recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/cosmos3/Cosmos3-Nano.md)
and [diffusion execution modes](../user_guide/diffusion/execution_modes.md)
for the current runtime choices.
## Why the stage-based architecture follows from these examples
The four representative pipelines show that omni-modality serving is not one
execution problem. Autoregressive decoding, diffusion denoising, multimodal
encoding, and media decoding have different scheduling, attention, parallelism,
memory, and quantization requirements. The architecture therefore needs a
unit that can be optimized and resourced independently while remaining part of
one request pipeline.
| Observation | Design implication | vLLM-Omni response |
| --- | --- | --- |
| AR, diffusion, encoder, and decoder components have different execution loops | One scheduler and one execution policy cannot fit every component | Specialized AR, generation, and diffusion stage runtimes |
| A model can be deployed as AR-only, DiT-only, or AR → DiT | Model structure must be separate from deployment topology | `PipelineConfig` describes logical stages and relationships; `DeployConfig` describes placement and resources |
| Text encoders, DiTs, and VAE decoders have different batch and memory behavior | Batching, attention, parallelism, and quantization must be stage-local | Each stage carries its own runtime and engine configuration |
| MiniMax-H3 can co-locate or logically split its text encoder and VAE decoder | A stage boundary should be configurable rather than forcing a process boundary | Logical stages can be co-located or assigned independent runtime placement |
| Qwen3-Omni transfers hidden states and codec chunks across stages | Large intermediate data needs typed transport and synchronization | `OmniConnector` transports payloads and KV-cache data without owning model routing |
| Requests span multiple stages and may be cancelled or produce ordered streaming output | Cross-stage request state needs a separate control plane | `Orchestrator` owns correlation, cancellation, routing state, and output ordering |
| Qwen3-Omni optimizes first-packet latency while image/video models optimize E2EL and throughput | Performance objectives must be model- and stage-aware | TTFT/TPOT/TTFP, E2EL, RTF, and throughput are measured according to the output modality |
This leads to a precise definition of a stage: it is a logical execution unit
with its own model component, execution policy, resource ownership, and
performance objectives. A stage is not necessarily a separate process. Cosmos3
keeps its reasoner and generator inside one diffusion pipeline, while
MiniMax-H3 exposes useful logical boundaries between text encoding, denoising,
and VAE decoding. Both are valid mappings of the same abstraction.
The resulting separation can be summarized as:
```text
Model structure What is computed and how components are related
↓
PipelineConfig Which logical stages exist and how they are connected
↓
Stage runtime policy How each stage batches, attends, parallelizes, and quantizes
↓
DeployConfig Where stages run, with which devices, replicas, and connectors
```
`AsyncOmniEngine` and `Orchestrator` coordinate the pipeline, `OmniConnector`
transports stage outputs, and `StageRuntime` materializes the selected
placement. This separation lets one logical model support multiple serving
topologies without coupling model code to process layout or deployment
resources.
## System architecture
The figure shows the main components of the stage-based runtime: entrypoints,
the shared `AsyncOmniEngine`, request orchestration, stage lifecycle
management, AR and diffusion execution modules, model/layer operations,
connector transport, and multimodal outputs. `AsyncOmniEngine` is the
composition root between the entrypoints and the orchestrator.
```mermaid
flowchart TB
subgraph omni["vLLM-Omni"]
subgraph entry["Entry points"]
api["API server"]
client["Omni / AsyncOmni"]
end
engine["AsyncOmniEngine<br/>composition root and background loop"]
orchestrator["Orchestrator<br/>request state and cross-stage routing"]
runtime["StageRuntime<br/>placement, replicas, readiness, and lifecycle"]
ar["AR module<br/>vLLM engine, scheduler, cache, executor, worker, and model runner"]
diffusion["Diffusion module<br/>scheduler, worker, model runner, and pipeline"]
ops["Model / layer / ops<br/>attention, parallelism, and quantization"]
connector["OmniConnector<br/>payload and KV transport plus synchronization"]
outputs["Multimodal outputs<br/>streaming chunks and final artifacts"]
api --> engine
client --> engine
engine --> orchestrator
engine --> runtime
orchestrator --> runtime
runtime --> ar
runtime --> diffusion
ar -. uses .-> ops
diffusion -. uses .-> ops
ar -. transports through .-> connector
diffusion -. transports through .-> connector
ar --> outputs
diffusion --> outputs
end
```
### Key components
| Component | Responsibility |
| --- | --- |
| **Entrypoints** | Translate offline, CLI, OpenAI-compatible, and duplex requests into engine operations and render outputs back to public protocols. |
| **Configuration resolution** | Combines pipeline topology, deployment settings, model metadata, and user overrides into a validated control-plane configuration. |
| **AsyncOmniEngine** | Owns engine composition, the background event loop, stage initialization, request submission, and output collection. |
| **Orchestrator** | Owns cross-stage request state, stage-to-stage routing, request correlation, cancellation, and output ordering. It does not own model selection or deployment placement. |
| **StageRuntime** | Expands logical stages into local or distributed replicas, starts stage clients and processes, and manages readiness, affinity, failure, and shutdown. |
| **AR runtime** | Extends vLLM's scheduler, KV-cache, worker, and model-runner path for omni-modality inputs and inter-stage outputs. |
| **Diffusion runtime** | Schedules and executes denoising workloads through diffusion executors, workers, pipelines, acceleration backends, and output materialization. |
| **OmniConnector** | Transports stage payloads and KV-cache data and provides synchronization. Connectors transport data; they do not choose the next logical stage. |
| **Multimodal outputs** | `MultimodalPayload` separates tensor content from metadata, while `OmniRequestOutput` carries pipeline and diffusion results through the common output path. |
## Configuration and runtime resolution
The control plane has five conceptual layers. Authoring inputs are resolved
once into a complete, transport-safe configuration before runtime processes are
started. This keeps stage topology and model capabilities distinct from
deployment placement and from process-local engine objects.
The figure shows only the primary hand-off object for each layer; the detailed
inputs, fields, and ownership rules are described below.
```mermaid
flowchart TB
layer1["Layer 1 · Authoring inputs<br/>PipelineConfig + DeployConfig"]
layer2["Layer 2 · Resolve once<br/>StageConfigFactory.create_from_model()<br/>VllmOmniConfig.from_pipeline_config()"]
layer3["Layer 3 · Transport-safe control plane<br/>VllmOmniConfig"]
layer4["Layer 4 · Runtime launch planning<br/>StageRuntime"]
layer5["Layer 5 · Engine materialization<br/>VllmConfig / OmniDiffusionConfig"]
layer1 --> layer2 --> layer3 --> layer4 --> layer5
```
The single resolution boundary is implemented by
`StageConfigFactory.create_from_model()` and
`VllmOmniConfig.from_pipeline_config()` in
[`vllm_omni/config`](https://github.com/vllm-project/vllm-omni/tree/main/vllm_omni/config).
The legacy `stage_args` YAML path remains only for models that have not yet
migrated to `PipelineConfig` and `DeployConfig`.
In the typed path, each stage configuration derives from
`BaseVllmOmniStageConfig` and is specialized as
`VllmOmniARStageConfig`, `VllmOmniGenerationStageConfig`, or
`VllmOmniDiffusionStageConfig`. The request and engine-spec fields belong to the
control-plane boundary; the current implementation stores their equivalent
projections in the structured stage configuration and materializes
backend-specific engine objects during stage initialization.
The important ownership rules are:
1. `PipelineConfig` is the source of truth for stage topology, execution type,
model capabilities, and stage relationships.
2. `DeployConfig` describes placement, replicas, devices, connectors, and
deploy-time defaults; it does not redefine the model graph.
3. CLI and Python overrides are applied at the resolution boundary, with
per-stage overrides taking precedence over global values where supported.
4. `StageRuntime` owns launch planning and replica lifecycle. `ReplicaInitPlan`
is runtime-private state, not a user configuration object.
5. `VllmConfig` and the enriched `OmniDiffusionConfig` are materialized in the
process that owns the corresponding engine.
## Main features
vLLM-Omni aims to be fast, flexible, and easy to use with the following features:
The feature surface is grouped to match the
[feature design documents](index.md#feature-design-documents). This page
summarizes each feature's architectural role; the linked design document is
the source for configuration, compatibility, and implementation details.
### Performance and Acceleration
### Runtime and stage execution
The framework achieves high performance through several optimization techniques:
* **Disaggregated inference:** Logical stages can run in separate processes,
devices, or nodes while the orchestrator preserves their declared
relationships. `OmniConnector` implementations transfer stage data and
control-plane metadata. See [Disaggregated Inference](feature/disaggregated_inference.md).
* **Asynchronous stage and output execution:** [Async Chunk](feature/async_chunk.md)
forwards partial stage outputs as they become available. [Async Diffusion
Output](feature/async_diffusion_output.md) overlaps device-to-host output
packing with the next diffusion request, while [Async Omni Output
Materialization](feature/omni_async_output_materialization.md) moves
CPU-side payload construction off the AR decode critical path.
* **Automatic prefix caching:** [Automatic Prefix Caching in Omni Models](feature/prefix_caching.md)
reuses KV-cache-aligned stage outputs and multimodal tensors for requests
with common prefixes.
* **Efficient AR Support:** Leverages efficient KV cache management inherited from vLLM.
* **Pipelined Execution:** Uses pipelined stage execution overlapping to ensure high throughput.
* **Full Disaggregation:** Relies on the OmniConnector and dynamic resource allocation across stages.
* **Diffusion Acceleration:** Includes integrated support for diffusion acceleration. This is managed by the acceleration layer, which handles:
* **Cache:** Includes DBCache, TeaCache and third-party integration(e.g., [cache-dit](https://github.com/vipshop/cache-dit)).
* **Parallelism:** Supports TP, CP, USP, and CFG.
* **Attention:** Provides an interface for third-party integration (e.g., FA3, SAGE, MindIE-SD).
* **Quantization:** Supports various quantization implementations including FP8 and AWQ.
* **FusedOps:** Allows for custom and third-party integration.
### Communication
### Classifier-Free Guidance (CFG) Companion Flow
* **OmniConnector transport:** The connector contract carries tensors, KV-cache
data, and transport metadata across stage boundaries. The available
implementations cover shared memory and multi-node Mooncake, Mori, and
Yuanrong transports; see [Disaggregated Inference](feature/disaggregated_inference.md)
for the connector choices and configuration model.
vLLM-Omni natively models Classifier-Free Guidance (CFG) across disaggregated multi-stage setups via a "companion request" paradigm, eliminating redundant textual/multimodal context computation boundaries:
1. **Prompt Expansion:** In the initial autoregressive (AR) stage, a customized `prompt_expand_func` hook intercepts incoming generation prompts and pairs them directly with negative companion prompts (e.g., a default negative prompt) on the fly, tagging the secondary prompt with a specific internal role (`cfg_text`).
2. **Synchronized KV Cache Transfer:** The AR stage evaluates both the primary and companion sequence batches concurrently. The `OmniConnector` captures these specific structural dependencies and reliably passes the positive and negative outcome KV caches seamlessly across stage boundaries via shared memory or network protocols.
3. **KV Cache Collection & Injection:** Upon reaching the downstream Diffusion (DiT) Engine, an assigned `cfg_kv_collect_func` automatically intercepts the mapped companion caches (`cfg_text_past_key_values`). These auxiliary dependencies are natively gathered and seamlessly bound to the primary generation sequence variables, enabling the DiT Engine to cleanly implement cross-attention CFG guidance over accurate conditioning and unconditioning structures in parallel.
### Diffusion acceleration
### Flexibility and Usability
* **Request and step batching:** [Diffusion Continuous Batching](feature/diffusion_continuous_batching.md)
defines request-batch and step-batch execution, scheduler admission, and the
common streaming output path.
* **Composable parallelism:** Diffusion stages can combine [CFG-Parallel](feature/cfg_parallel.md),
[Expert Parallel](feature/expert_parallel.md), [HSDP](feature/hsdp.md),
[Pipeline Parallel](feature/pipeline_parallel.md), [Sequence Parallel](feature/sequence_parallel.md),
[Tensor Parallel](feature/tensor_parallel.md), and [VAE Patch Parallelism](feature/vae_parallel.md)
according to the pipeline and hardware topology.
* **Attention and cache acceleration:** [Skip-Softmax](feature/skip_softmax.md),
[Cache-DiT](feature/cache_dit.md), and [TeaCache](feature/teacache.md)
provide backend and denoising-step optimizations without changing the
stage contract.
* **Quantization and memory efficiency:** [Quantization](feature/quantization.md)
resolves per-pipeline or per-component quantization configurations, while
[Distributed Layerwise Offload](feature/offloader/distributed_layerwise_offload.md)
streams diffusion blocks from host memory within the existing parallel
topology.
vLLM-Omni is designed to be flexible and straightforward for users:
## Interfaces
* **Heterogeneous Pipeline Abstraction:** Manages complex model workflows effectively.
* **Hugging Face Integration:** Offers seamless integration with popular Hugging Face models.
* **Distributed Inference:** Supports tensor, pipeline, data, and expert parallelism.
* **Streaming Outputs:** Supports streaming outputs.
* **Unified API:** Provides a consistent and unified API interface compatible with vLLM.
* **OpenAI-compatible API Server:** Includes a FastAPI-based server for online serving that is compatible with the OpenAI API.
# Interface design
If you use vLLM, then you know how to use vLLM-Omni from Day 0:
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/vllm-omni-user-interface.png">
<img alt="vLLM-Omni interface design" src="https://raw.githubusercontent.com/vllm-project/vllm-omni/refs/heads/main/docs/source/architecture/vllm-omni-user-interface.png" width=55%>
</picture>
</p>
Taking **Qwen3-Omni** as an example:
## Offline Inference
The **Omni** class provides a Python interface for offline batched inference. Users initialize the Omni class with a Hugging Face model name and use the generate method, passing inputs that include both text prompts and multi-modal data:
The public interfaces map onto the same engine and stage boundaries:
```mermaid
flowchart LR
offline["Offline Python<br/>Omni.generate()"] --> engine["AsyncOmniEngine"]
online["OpenAI-compatible serving<br/>vllm serve ... --omni"] --> engine
duplex["Experimental duplex WebSocket<br/>/v1/duplex or realtime duplex"] --> engine
engine --> stages["Configured AR and diffusion stages"]
stages --> result["Streaming or final multimodal output"]
```
# Create an omni runtime with HF model name.
### Offline inference
The **Omni** class provides a Python interface for offline batched inference:
```python
from vllm_omni.entrypoints.omni import Omni
omni = Omni(model="Qwen/Qwen3-Omni-30B-A3B-Instruct")
# Example prompts.
om_inputs = {"prompt": prompt,
"multi_modal_data": {
"video": video_frames,
"audio": audio_signal,
}}
om_inputs = {
"prompt": prompt,
"multi_modal_data": {
"video": video_frames,
"audio": audio_signal,
},
}
# Generate texts and audio from the multi-modality inputs.
outputs = omni.generate(om_inputs, sampling_params_list)
```
## Online Serving
Similar to vLLM, vLLM-Omni also provides a FastAPI-based server for online serving. Users can launch the server using the vllm serve command with the `--omni` flag:
### Online serving
```
The OpenAI-compatible server uses the same stage configuration and engine
boundaries:
```bash
vllm serve Qwen/Qwen3-Omni-30B-A3B-Instruct --omni --port 8091
```
Users can send requests to the server using curl:
For example, a Qwen3-Omni chat request can contain text, image, audio, or
video content and a `sampling_params_list` for its configured stages. See the
[Qwen3-Omni serving example](../user_guide/examples/online_serving/qwen3_omni.md)
and the [examples](https://github.com/vllm-project/vllm-omni/tree/main/examples)
for complete requests.
```
# prepare user content
user_content='[
{
"type": "video_url",
"video_url": {
"url": "'"$SAMPLE_VIDEO_URL"'"
}
},
{
"type": "text",
"text": "Why is this video funny?"
}
]'
sampling_params_list='[
'"$thinker_sampling_params"',
'"$talker_sampling_params"',
'"$code2wav_sampling_params"'
]'
mm_processor_kwargs="{}"
# send the request
curl -sS -X POST http://localhost:8091/v1/chat/completions \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"model": "Qwen/Qwen3-Omni-30B-A3B-Instruct",
"sampling_params_list": $sampling_params_list,
"mm_processor_kwargs": $mm_processor_kwargs,
"messages": [
{
"role": "system",
"content": [
{
"type": "text",
"text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."
}
]
},
{
"role": "user",
"content": $user_content
}
]
}
```
For more usages, please refer to [examples](https://github.com/vllm-project/vllm-omni/tree/main/examples).
Some pipelines expose additional OpenAI-compatible endpoints, such as joint
video/audio generation. Endpoint support remains model-specific; consult the
relevant model guide before assuming that every OpenAI route applies to every
pipeline.
+17 -1
View File
@@ -117,7 +117,22 @@ After (async D2H):
### Batch Split
When `execute_model_batch` returns a `COMPUTE_DONE` with a single `async_output_id` for the entire batch, the executor splits it into per-request `async_output_id`s (format `{batch_id}/{request_id}`) via `_batch_split_map`. When `OUTPUT_READY` arrives, the pump extracts per-request results from the batch output and resolves each request's output future independently.
When `execute_model_batch` returns a `COMPUTE_DONE` with a single `async_output_id` for the entire batch, the executor splits it into per-request `async_output_id`s (format `{batch_id}/{request_id}`) via `_batch_split_map`. When `OUTPUT_READY` arrives, the pump extracts per-request results from the batch output and resolves each request's output future independently. If `OUTPUT_READY` arrives before `execute_batch` registers the split map, `execute_batch` directly adopts the early output.
### Reliability, Lifecycle & Timeout Behavior
1. **Drain Before Memory Release (`drain_async_outputs` / `_ASYNC_OUTPUT_DRAIN_TIMEOUT_S`)**:
When workers transition into sleep states (`handle_sleep_task`) or invoke memory-releasing methods, `WorkerProc.drain_async_outputs()` blocks up to `_ASYNC_OUTPUT_DRAIN_TIMEOUT_S` (10.0s) until all in-flight background D2H/SHM packing tasks finish. This acts as a synchronization barrier preventing worker sleep cycles from releasing device tensors while the side CUDA stream is still actively reading them. Draining typically completes within 10–50 ms under normal operation.
2. **Timeout Diagnostics (`_ASYNC_OUTPUT_TIMEOUT`)**:
The engine waits for `wait_output_ready()` with a timeout of `_ASYNC_OUTPUT_TIMEOUT` (30.0s). If a timeout occurs, the executor logs detailed diagnostic bookkeeping (pending futures, cached outputs, and batch split maps) to identify whether the stall occurred in the worker, pump, or waiter.
3. **Queue Serialization & Atomic Future Resolution**:
- `result_mq` writes are serialized with `_result_mq_lock` to protect the single-writer `MessageQueue` against concurrent writes from the worker main loop (`COMPUTE_DONE`) and background thread (`OUTPUT_READY`).
- `ResultPumpThread` unpacks shared-memory payloads first, and then atomically resolves waiting futures or populates `_completed_outputs` under `_futures_lock`, avoiding race conditions with concurrent `wait_output_ready()` invocations.
4. **Storage-Aware IPC Packing**:
`pack_diffusion_output_shm()` evaluates `max(view_bytes, storage_bytes)` against `_SHM_TENSOR_THRESHOLD` (1 MB) to ensure that per-request slices sharing a large batch storage are moved to POSIX shared memory rather than serialized through pickle over the MessageQueue inline buffer.
## Model Coverage
@@ -131,6 +146,7 @@ All models running in request-mode (`step_execution=False`, the default) automat
|---|---|---|
| **HunyuanImage-3.0** | Image | `False` |
| **Qwen-Image** | Image | `True` |
| **LTX-2.3** | Video / Audio | `False` |
Other models with `step_execution=False` are also supported but not yet verified.
@@ -0,0 +1,89 @@
# Diffusion Attention Backend Selection
This document defines the selection and extension contract for diffusion
attention backends. User-facing backend choices, installation, and tuning are
in the [attention backend guides](../../user_guide/diffusion/attention_backends.md).
## Scope
The contract applies to DiT and other diffusion attention layers. It is
separate from vLLM's autoregressive attention selector.
The selection path has four responsibilities:
1. normalize user configuration into `AttentionConfig` and `AttentionSpec`;
2. resolve a spec for an attention role;
3. ask the active platform to validate an explicit backend or choose a
hardware default; and
4. load the selected `AttentionBackend` class from the registry path.
## Resolution contract
`get_attn_backend_for_role()` resolves configuration in this order:
1. exact `per_role[role]`;
2. category `per_role[role_category]`;
3. `default`;
4. platform default.
An explicit resolution returns both the backend class and its
`AttentionSpec`. A platform-default resolution returns the class and `None`.
Layers must therefore treat the spec as optional and must not infer that a
missing spec means SDPA.
Class resolution is cached by backend name, head size, and whether TRTLLM may
be selected automatically. Logging is cached separately by role and source so
the startup record identifies why each role received its backend.
## Registry and platform boundary
`DiffusionAttentionBackendEnum` maps stable configuration names to default
qualified class paths. `register_diffusion_backend()` may replace a path at
runtime without changing the public enum value.
The active `OmniPlatform` owns compatibility policy through
`get_diffusion_attn_backend_cls()`. It must:
- validate explicit selections and fail with an actionable error when the
requested kernel cannot run;
- choose only an available, compatible default when no backend is explicit;
- account for head size and other platform-visible constraints; and
- return a qualified class path implementing `AttentionBackend`.
The selector must not duplicate device capability or package-availability
policy that belongs to the platform.
## Typed backend options
Backend-specific settings remain typed fields on `AttentionSpec` rather than
unstructured keyword dictionaries:
- `quant` is consumed by FlashInfer and TRTLLM with backend-specific value
validation;
- `skip_softmax` is consumed by TRTLLM; and
- `block_sparse` is consumed by block-sparse backends such as RainFusion.
A backend reads only the fields it owns and rejects incompatible values. New
options should be added to a shared typed spec only when more than one backend
shares their semantics; otherwise add a dedicated typed block.
## Model integration contract
Each diffusion attention call declares a stable role and, when appropriate, a
broader category. Model-specific roles permit precise overrides; categories
preserve common `self` or `cross` policies. A model also decides whether its
path is compatible with automatic TRTLLM selection, because only the model
knows whether masking and packing satisfy the kernel contract.
## Adding or changing a backend
An implementation change is complete only when it:
1. implements the `AttentionBackend` interface and exposes a stable enum name;
2. adds platform validation and default routing where appropriate;
3. defines and validates any typed configuration;
4. tests explicit selection, default selection, and incompatible paths;
5. documents installation, fallback behavior, and quality implications in the
corresponding user guide; and
6. updates the overview matrix without moving algorithm details back into the
landing page.
@@ -1,156 +0,0 @@
# Distributed Layerwise Offload
This document describes distributed layerwise offload (DLO) for diffusion
models. DLO keeps only a small number of DiT blocks on the accelerator and
streams the remaining blocks from host memory. The distributed backend can
either shard those host-side weights across an existing parallel group or keep
the standard loader's rank-local weights and avoid an additional collective.
For user-facing commands, see the
[distributed layerwise offloading guide](../../user_guide/diffusion/cpu_offload.md)
and the [Cosmos3 recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/cosmos3/Cosmos3-DistOffload.md).
## Status
DLO is implemented for multi-device diffusion execution. The default
AllGather path is the primary path for DP and SP deployments. The
`--dlo-no-use-allgather` path is a rank-local compatibility mode: it is useful
for standard-loader sharding, workstation bring-up, and systems where an
additional DLO collective is undesirable, but it does not reduce host weight
storage across ranks.
The compatibility matrix below describes the current implementation. The
unit-level guards are covered, but not every parallelism combination has a
full model-and-hardware end-to-end test.
## Design
### DLO consumes the existing parallel topology
DLO does not create a new DP, TP, or SP topology. It reads the configured
`DiffusionParallelConfig` and attaches offload hooks to the DiT blocks after the
standard distributed groups have been initialized.
The DLO weight-sharding group is selected as follows:
1. Use the existing DP group when `data_parallel_size > 1`.
2. When DP is one and SP is greater than one, use the SP group.
3. Otherwise, run rank-locally without a DLO process group.
TP is deliberately not used as DLO's AllGather group. HSDP has its own
parameter-sharding lifecycle and is not allowed to be sharded a second time by
DLO's AllGather path.
### AllGather path
With the default `dlo_use_allgather=True`, each rank stores approximately
`1 / group_size` of each streamable block in pinned host memory. The next
block's shard is copied to a device buffer and reconstructed with
`all_gather_into_tensor` on a communication stream while the current block is
executing.
```text
Compute: [Block N] [Block N+1] [Block N+2]
H2D: [shard N+1] [shard N+2]
AllGather: [full N+1] [full N+2]
Buffers: [current slot] [prefetch slot] [current slot]
```
![DLO double-buffer prefetch pipeline](../figures/dlo/dlo_pipeline.gif)
The backend uses two shared device buffers, so accelerator weight residency is
bounded by the largest streamed blocks rather than the complete model.
When DP is greater than one, the engine can process one request per DP rank in
the same denoising wave. Because AllGather is a collective, all participating
requests must take the same execution path at every denoising step.
### Rank-local path without DLO AllGather
With `--dlo-no-use-allgather`, DLO forces its internal offload shard size to
one. The regular model loader remains responsible for preparing each rank's
weights, including TP-local tensors or HSDP-managed parameters. DLO then
streams those rank-local tensors block by block using H2D copies only.
This mode means:
- DP still provides independent replicas, but DLO does not shard weights
across DP ranks.
- SP still performs its normal activation/attention collectives, but DLO does
not shard weights across SP ranks.
- TP/HSDP/SP collectives, if configured, are not disabled by this flag; only
DLO's additional weight AllGather is disabled.
- Pure DP deployments keep a full host-side model copy per rank, subject to
shared OS page-cache behavior.
- The scheduler does not require a synchronized DP request wave for DLO.
This path is intentionally not implemented by reusing the AllGather mmap
loader. It relies on the standard loader so model-specific TP/HSDP transforms
remain intact.
## Parallelism compatibility
| Parallelism | DLO + AllGather | DLO without AllGather |
|---|---|---|
| **DP** | Supported primary path. DLO shards host weights across the DP group and can run DP multi-concurrency. | Supported rank-local path. DP replicas remain independent; no DLO weight sharding or cross-DP DLO collective. |
| **SP** | Supported in the implementation. With DP=1, DLO uses the SP group for host-weight sharding; SP still shards sequence/activation work. | SP remains active, but DLO keeps standard-loader rank-local weights and adds no SP weight collective. |
| **TP > 1** | Unsupported in the DLO mmap path. TP-aware loader callbacks are bypassed, so the backend rejects this configuration when it enters that path. | Standard loading is retained and TP-local tensors can be streamed. This is the intended compatibility path, but it still needs broader model and hardware validation. |
| **HSDP** | Rejected. HSDP has already sharded parameters, so DLO AllGather would double-shard them. | Accepted by configuration. HSDP owns parameter sharding and its own gathers; DLO only stages rank-local parameters. End-to-end coverage is limited. |
### Combined dimensions
- **DP + SP:** DLO uses the DP group for weight sharding when DP is greater
than one; SP continues to use its own sequence-parallel group. If DP is one,
the SP group becomes DLO's sharding group in AllGather mode.
- **DP + TP/SP without AllGather:** standard model loading defines the
rank-local tensor layout. DLO adds no cross-DP, cross-TP, or cross-SP weight
collective.
- **HSDP + SP:** the general parallel configuration permits HSDP over SP, but
DLO must use `--dlo-no-use-allgather`. HSDP remains responsible for weight
materialization and synchronization.
- **HSDP + DP or TP:** rejected independently by the diffusion parallel
configuration.
## Request and loading constraints
AllGather DP multi-concurrency requires:
- explicit `num_inference_steps`;
- the same `num_inference_steps` for all requests in a wave; and
- identical request arguments that affect the collective execution path.
The no-AllGather path does not impose these DLO-specific synchronized-wave
requirements.
The mmap loader is used only by the supported DLO+AllGather path when the
model has a compatible checkpoint layout. Online quantization is incompatible
with that sharded mmap path; use `--dlo-no-use-allgather` or disable online
quantization. Models that do not meet the mmap requirements use the regular
loader path.
## Validation coverage
Current source-level validation includes:
- HSDP + DLO + AllGather rejection;
- HSDP + DLO without AllGather acceptance at configuration level;
- TP rejection in the DLO+AllGather mmap path;
- resident-layer requests requiring no-AllGather;
- DP request-wave validation for denoising-step compatibility;
- sharding, double-buffer, AllGather-size, and heterogeneous-block regression
tests.
The highest-value missing coverage is end-to-end numerical comparison against
ordinary layerwise offload for DP+SP, TP+no-AllGather, and HSDP+SP+no-AllGather
on the target CUDA/NCCL or CANN/HCCL hardware.
## Recommendations
- Use **DP + DLO AllGather** for the supported throughput and host-memory
scaling path.
- Use **SP + DLO AllGather** for long-sequence workloads when DP concurrency is
not the goal.
- Use **no-AllGather** to bring up TP or workstation PCIe configurations, with
the expectation of higher host-memory use and lower validation confidence.
- Prefer **HSDP alone** for production HSDP deployments until the combined
HSDP + DLO no-AllGather path has broader end-to-end coverage.
+80
View File
@@ -0,0 +1,80 @@
# CPU Offloading
This document defines the shared architecture for diffusion CPU offloading.
The three strategies have separate user and design pages:
| Strategy | User guide | Design contract |
| --- | --- | --- |
| Model-level | [Guide](../../../user_guide/diffusion/offloader/cpu_offload.md) | [Design](cpu_offload.md) |
| Layerwise | [Guide](../../../user_guide/diffusion/offloader/layerwise_offload.md) | [Design](layerwise_offload.md) |
| Distributed layerwise | [Guide](../../../user_guide/diffusion/offloader/distributed_layerwise_offload.md) | [Design](distributed_layerwise_offload.md) |
## Strategy selection
`OffloadConfig.from_od_config()` converts diffusion configuration into one
`OffloadStrategy`. If callers set multiple flags, selection is deterministic:
1. `DISTRIBUTED_LAYERWISE`;
2. `LAYERWISE`;
3. `MODEL_LEVEL`; and
4. `NONE`.
The factory logs when a higher-priority strategy disables another. It derives
parallel and HSDP state from `DiffusionParallelConfig`; callers do not provide
a separate offload group size.
`get_offload_backend()` then validates platform offload support, resolves the
device, and creates exactly one backend. Returning `None` means offloading is
disabled or unsupported and must not leave partially installed hooks.
## Shared lifecycle
Every backend implements `OffloadBackend`:
- `enable(pipeline)` discovers modules, establishes initial residency, and
installs hooks;
- `disable()` removes owned hooks and resources; and
- `is_enabled()` reports lifecycle state.
`disable()` does not promise to restore the pipeline's original device
placement. The caller owns any subsequent rematerialization.
Hooks are registered through `HookRegistry` and `ModelHook`; offload backends
must use distinct hook names and remove only hooks they own.
## Discovery and topology
Pipeline component discovery prefers `SupportsComponentDiscovery` declarations:
- `_dit_modules`;
- `_encoder_modules`;
- `_vae_modules`; and
- `_resident_modules`.
Dotted paths are supported. Legacy pipelines may use the fallback scan of
well-known attribute names, but new integrations should declare components
explicitly.
Ordinary layerwise offload obtains topology from declared
`_layerwise_offload_blocks_attrs` (with a deprecated singular-name
compatibility path). Distributed layerwise offload may instead use a pipeline
`OffloadPlan`, then falls back to declared block attributes and its documented
compatibility discovery. Discovery metadata describes structure only; the
backend remains responsible for transfer, synchronization, and storage
ownership.
## Cross-strategy invariants
- At most one strategy owns offload hooks for a pipeline.
- A parameter has one authoritative host representation while offloaded.
- Device storage is not freed until dependent compute or transfer work is
complete.
- Non-persistent and model-specific buffers remain correct after movement or
checkpoint rematerialization.
- Unsupported parallel or loading combinations fail before hooks mutate the
model.
- Platform streams, events, synchronization, and cache management go through
the vLLM-Omni platform abstraction.
The diffusion [Offloader module design](../../module/diffusion/offloader.md)
describes how these feature contracts fit into the larger diffusion runtime.
@@ -0,0 +1,56 @@
# Model-Level Offload
Model-level offload enforces mutual exclusion between pipeline component
groups. For commands and model support, see the
[model-level user guide](../../../user_guide/diffusion/offloader/cpu_offload.md).
## Generic hook path
`ModelLevelOffloadBackend.enable()` discovers DiTs, encoders, and VAEs. It
makes encoders and VAEs device resident for initialization, then installs
`SequentialOffloadHook` instances:
- each DiT hook offloads all encoders and other DiTs before loading itself;
- each encoder hook offloads every DiT before loading itself; and
- VAEs are not part of the mutual-exclusion hook set.
The hook moves parameters and buffers without recursively calling
`module.to()`. This avoids recursion through modules that retain references to
other transformer blocks. Host tensors are pinned when configured; DTensors
are not pinned through the ordinary tensor path.
Before forward returns control to the model, the hook synchronizes the active
platform so compute cannot race the transfer. XPU uses blocking device-to-host
copies because its allocator cannot safely evict storage while an asynchronous
copy is pending.
## Split-model delegation
If a pipeline provides callable `enable_omni_model_cpu_offload`, the backend
delegates instead of installing generic encoder/DiT hooks. This supports models
whose mutually exclusive components are nested inside one transformer, such
as a reasoner and generator.
The delegated pipeline owns its internal contexts, but must preserve the same
contract:
- only the executing component is device resident;
- enable and disable are idempotent;
- transfers use the supplied device, pinning, and HSDP settings; and
- disabling removes all model-local offload hooks or contexts.
The delegation is currently duck typed. If another independent implementation
is added, formalize the enable/disable pair as a protocol rather than expanding
attribute-name heuristics.
## Extension invariants
- New ordinary pipelines declare both DiT and encoder groups through
`SupportsComponentDiscovery`.
- Models with multiple DiTs offload the inactive DiTs as well as encoders.
- Empty or parameterless modules do not trigger transfers.
- Hook removal does not move modules; callers must not assume original
residency is restored.
Shared selection and lifecycle behavior is defined in the
[CPU Offloading design](README.md).
@@ -0,0 +1,472 @@
# Distributed Layerwise Offload
This document describes distributed layerwise offload (DLO) for diffusion
models. DLO keeps only a small number of DiT blocks on the accelerator and
streams the remaining blocks from host memory. The distributed backend can
either shard those host-side weights across an existing parallel group or keep
complete rank-local block sources and avoid an additional collective.
For user-facing commands, see the
[distributed layerwise offloading guide](../../../user_guide/diffusion/offloader/distributed_layerwise_offload.md)
and the [Cosmos3 recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/cosmos3/Cosmos3-DistOffload.md).
## Status
DLO is implemented for multi-device diffusion execution. The default
AllGather path is the primary path for DP and SP deployments. The
`--dlo-no-use-allgather` path streams complete blocks independently and adds no
DLO weight collective.
Host storage is selected separately from the transfer protocol. The loader can
produce a direct-checkpoint mmap plan for a proven-compatible runtime layout;
otherwise it uses the ordinary loader. In no-AllGather mode, an opt-in Phase B
runtime cache can normalize those final ordinary-loader DiT tensors into an
immutable node-local mmap entry. Consequently, replicas can share either
proven-compatible checkpoint pages or equivalent final runtime layouts. An
opt-in CUDA registration budget can make the complete final mapping directly
H2D-copyable, avoiding the recurrent host packing otherwise required by mmap.
The Phase A shared-mmap support boundary is TP1. TP greater than one is an
ordinary-loader compatibility path: DLO can consume the resulting TP-local
tensors. Direct checkpoint mmap still does not cover TP, but the Phase B cache
can share each final TP coordinate among equivalent processes.
The compatibility matrix below describes the current implementation. The
unit-level guards are covered, but not every parallelism combination has a
full model-and-hardware end-to-end test.
## Design
### DLO consumes the existing parallel topology
DLO does not create a new DP, TP, or SP topology. It reads the configured
`DiffusionParallelConfig` and attaches offload hooks to the DiT blocks after the
standard distributed groups have been initialized.
The DLO weight-sharding group is selected as follows:
1. Use the existing DP group when `data_parallel_size > 1`.
2. When DP is one and SP is greater than one, use the SP group.
3. Otherwise, run rank-locally without a DLO process group.
TP is deliberately not used as DLO's AllGather group. HSDP has its own
parameter-sharding lifecycle and is not allowed to be sharded a second time by
DLO's AllGather path.
### The loader owns host-weight planning
Before it decides whether ordinary weight materialization can be skipped, the
diffusion loader builds one `HostWeightPlan`. A direct-checkpoint mmap plan is
accepted only when preflight proves all of the following:
- every required DiT parameter and persistent buffer has exactly one source;
- runtime names, checkpoint keys, shapes, and dtypes match;
- the runtime topology is TP1 without HSDP or online quantization; and
- every custom loader operation is represented by a loader-owned checkpoint
adapter.
The exact plan object is handed to DLO. The backend does not rescan checkpoint
files, repeat the capability decision, or reconstruct names from its block
topology. If preflight fails, the loader materializes weights normally and DLO
consumes those runtime tensors.
The plan owns only dedicated DiT component sources. If a pipeline also exposes
ordinary sources for a text encoder or another non-DiT component, the loader
still consumes those sources and includes their loaded names in its strict
coverage check. Only the source prefixes covered by the plan skip ordinary
materialization. A source that mixes DiT and non-DiT weights fails closed to
the complete ordinary-loader path because it cannot be skipped safely as a
unit.
This boundary keeps checkpoint semantics out of DLO and avoids model-pipeline
flags such as `_supports_mmap_loading` or parameter attributes for mmap-only
transforms. Model-specific direct-layout knowledge, when required, lives in a
checkpoint adapter beside the ordinary loader.
### Post-load runtime cache
The Phase B cache preserves the same ownership boundary. DLO neither derives
cache keys nor interprets model loaders. When enabled with no-AllGather, every
rank first completes the ordinary loader, custom callbacks, post-load
processing, strict validation, and calibration. The loader then:
1. discovers final CPU DiT parameters and persistent buffers;
2. rejects unsupported non-contiguous, aliased, quantized, distributed, or
ambiguous layouts before changing the model;
3. hashes tensor names, metadata, and final bytes;
4. builds or joins one content-addressed entry under a strict POSIX lock; and
5. returns a `HostWeightPlan(backing_kind="runtime_cache")` only after file,
manifest, and remapped-tensor content validation succeeds.
The identity excludes DP size/rank and SP rank. It includes TP world size/rank
and conservative SP implementation/world-size guards. DP replicas and
equivalent SP ranks can therefore share; different TP coordinates cannot.
Final tensor content is authoritative, so an unmodeled loader/config change
that changes bytes creates a different entry instead of risking silent
sharing.
Publication writes sharded safetensors and a JSON manifest into a same-
filesystem temporary directory, flushes them, and atomically renames the
directory. The manifest includes per-file SHA-256 digests and the final tensor
content digest. Kernel `flock` ownership distinguishes a live writer from a
stale lock file: process death releases the lock automatically. Stale temporary
entries are removed only by the next lock owner. A bounded wait or any cache
error retains the already-valid ordinary tensors.
DLO maps this plan without moving the DiT to `meta` and without rerunning any
post-load hook. It changes tensor storage while preserving `Parameter` objects,
then runs the existing `gc.collect()`/`malloc_trim()` cleanup before installing
streaming hooks. The source mappings remain open through DLO disable. With the
default zero registration budget they feed the existing bounded two-slot host
staging path. Every streamed block is first packed from pageable mmap storage
into one of those pinned slots and is then copied to the device. This removes
model-sized private pinned storage, but adds a recurrent host-to-host copy and
can amplify TP synchronization waits when several ranks compete for host
bandwidth.
This version is deliberately opt-in and steady-state-oriented. It requires
roughly one local-disk model copy per runtime identity, has no eviction, and
still performs ordinary loading plus full content-hash passes in every rank.
Skip-load-on-hit is a separate follow-up after loader side effects can be
modeled safely.
### Registered runtime-cache transfer
`dlo_runtime_cache_pin_limit_gib > 0` opts a CUDA worker into complete
runtime-cache registration. It also changes loader selection: no-AllGather
uses the ordinary loader and final runtime cache even when a TP1 direct-
checkpoint plan is available. A checkpoint binding can carry a deferred
adapter such as grouped-QKV reordering. Registering that raw source would not
remove the adapter's recurrent CPU allocation/copy, whereas the runtime cache
contains the transform-complete final tensors.
After mapping and validating every final tensor, DLO groups source storages by
backing file, page-aligns their address ranges, and coalesces overlapping or
adjacent ranges within that mapping. The complete byte count is checked
against the per-worker budget before any CUDA call. It then registers every
range with the read-only CUDA host-registration flag and verifies that PyTorch
recognizes every mapped tensor as pinned. Failure rolls back any ranges already
registered and preserves the existing two-slot staging path. Partial direct
transfer is deliberately unsupported. A rollback failure aborts worker
initialization so a still-registered range is retained until process/context
teardown rather than being unsafely unmapped.
On success, the hooks copy each immutable tensor view directly into its offset
in the existing flattened rotating device buffer on the copy stream. Parameter
repointing, two-block HBM residency, and H2D/compute overlap are unchanged. The
implementation currently issues more H2D copy operations than block packing,
but avoids the much larger recurrent CPU copy. A packed cache schema should be
considered only if launch-count measurements justify its added format and
publication complexity.
Registration is per process and CUDA context; physical file-cache pages remain
shared and are not copied into one private host allocation per worker. The
operator must nevertheless budget page-locked memory and satisfy OS/CUDA
registration limits for every worker. During shutdown, DLO first synchronizes
outstanding device work, unregisters all ranges, and then closes the safetensors
mappings. Worker teardown invokes this cleanup before destroying the
distributed environment and CUDA context.
### AllGather path
With the default `dlo_use_allgather=True`, each rank stores approximately
`1 / group_size` of each streamable block in pinned host memory. The next
block's shard is copied to a device buffer and reconstructed with
`all_gather_into_tensor` on a communication stream while the current block is
executing.
```text
Compute: [Block N] [Block N+1] [Block N+2]
H2D: [shard N+1] [shard N+2]
AllGather: [full N+1] [full N+2]
Buffers: [current slot] [prefetch slot] [current slot]
```
![DLO double-buffer prefetch pipeline](../../figures/dlo/dlo_pipeline.gif)
The backend uses two shared device buffers, so accelerator weight residency is
bounded by the largest streamed blocks rather than the complete model.
When direct checkpoint mmap is selected, the checkpoint mappings are only the
source used to prepare each rank's persistent shard. They can be closed after
shard preparation. Across the AllGather group, those private shards total
approximately one runtime model copy.
An effective DLO group size of one performs no collective, even when
`dlo_use_allgather=True`; it follows the rank-local transfer path described
below.
When DP is greater than one, the engine can process one request per DP rank in
the same denoising wave. Because AllGather is a collective, all participating
requests must take the same execution path at every denoising step.
Fast NVLink/NVSwitch changes collective cost, not this execution contract. For
independently scheduled replicas—even on one NVSwitch baseboard—no-AllGather
plus shared mmap storage avoids coupling their request schedules and failure
domains.
### Rank-local path without DLO AllGather
With `--dlo-no-use-allgather`, DLO forces its internal offload shard size to
one and streams complete blocks using H2D copies only. The host backing may be
a loader-approved checkpoint mapping, a normalized runtime-cache mapping, or
ordinary runtime tensors.
For direct mmap, each process retains immutable safetensors views and uses two
bounded pinned host staging slots. Processes on the same node that map the same
files share physical checkpoint pages through the OS page cache. This removes
the persistent private full-model copy per pure-DP process, but each process
still packs and transfers every complete block. Sharing is node-local; each
node has its own page cache.
For a runtime-cache mapping, a positive registration budget replaces those
host slots with direct copies from the shared final tensor views. A zero budget
or failed registration retains the bounded staging behavior.
When direct mmap preflight fails, the regular model loader remains responsible
for preparing each rank's weights, including TP-local tensors or HSDP-managed
parameters. Supported CPU layouts may then enter the opt-in runtime cache.
Unsupported layouts keep one private runtime copy per process.
This mode means:
- DP still provides independent replicas, but DLO does not shard weights
across DP ranks.
- SP still performs its normal activation/attention collectives, but DLO does
not shard weights across SP ranks.
- TP/HSDP/SP collectives, if configured, are not disabled by this flag; only
DLO's additional weight AllGather is disabled.
- Pure DP deployments share one checkpoint-backed copy per node when direct
mmap is selected. The runtime cache can share equivalent ordinary-loader
outputs; its fallback keeps one private runtime copy per rank.
- The scheduler does not require a synchronized DP request wave for DLO.
## Parallelism compatibility
| Parallelism | DLO + AllGather | DLO without AllGather |
|---|---|---|
| **DP** | Supported primary path. DLO shards host weights across the DP group and can run DP multi-concurrency. | Supported rank-local path. Compatible TP1 replicas can share checkpoint pages; the optional runtime cache shares equivalent final layouts while excluding DP rank from its identity. CUDA workers may register the complete final mapping for direct H2D. |
| **SP** | Supported in the implementation. With DP=1, DLO uses the SP group for host-weight sharding; SP still shards sequence/activation work. | SP remains active without a DLO weight collective. Runtime-cache v1 excludes SP rank and includes conservative SP implementation/world-size guards. Registered transfer does not remove ordinary SP activation/attention collectives. |
| **TP > 1** | Outside the Phase A direct-mmap scope. The loader preserves TP-local layouts and DLO may apply DP/SP host sharding to ordinary runtime tensors. | The ordinary TP-aware loader produces rank-local tensors. Runtime-cache v1 creates one entry per TP coordinate, shareable by equivalent DP/SP processes. Registering those final mappings removes staging-driven TP skew but does not remove ordinary TP collectives. |
| **HSDP** | Rejected. HSDP has already sharded parameters, so DLO AllGather would double-shard them. | Accepted by configuration. HSDP owns parameter sharding and its own gathers; DLO only stages rank-local parameters. End-to-end coverage is limited. |
### Combined dimensions
- **DP + SP:** DLO uses the DP group for weight sharding when DP is greater
than one; SP continues to use its own sequence-parallel group. If DP is one,
the SP group becomes DLO's sharding group in AllGather mode.
- **DP + TP/SP without AllGather:** standard model loading defines the
rank-local tensor layout. DLO adds no cross-DP, cross-TP, or cross-SP weight
collective.
- **HSDP + SP:** the general parallel configuration permits HSDP over SP, but
DLO must use `--dlo-no-use-allgather`. HSDP remains responsible for weight
materialization and synchronization.
- **HSDP + DP or TP:** rejected independently by the diffusion parallel
configuration.
## Request and loading constraints
AllGather DP multi-concurrency requires:
- explicit `num_inference_steps`;
- the same `num_inference_steps` for all requests in a wave; and
- identical request arguments that affect the collective execution path.
The no-AllGather path does not impose these DLO-specific synchronized-wave
requirements.
Direct checkpoint mmap can back either transfer path. It is currently limited
to proven TP1, non-HSDP, non-online-quantized layouts. Other layouts use the
ordinary loader. Online quantization remains incompatible with DLO AllGather;
use `--dlo-no-use-allgather` or disable online quantization. Runtime-cache v1
is no-AllGather only and rejects all quantization configurations, HSDP/DTensor,
expert parallelism, CFG parallelism, PP, non-contiguous tensors, and
tied/shared storage.
## Validation coverage
Current source-level validation includes:
- HSDP + DLO + AllGather rejection;
- HSDP + DLO without AllGather acceptance at configuration level;
- loader preflight fallback for TP, HSDP, online quantization, unknown custom
loaders, missing keys, and shape/dtype mismatches;
- exact loader-to-backend plan transfer and ordinary-loader fallback;
- rank-local mmap source retention, bounded two-slot staging, and adapter
transforms without parameter-side flags;
- runtime-cache content identity, sharded atomic publication, concurrent
writer election, corruption rebuild, lock timeout, and fail-closed layout
rejection;
- loader ordering through final post-load mutation and DLO remapping without
rerunning post-load hooks;
- all-or-nothing page-aligned registration, budget rejection, partial-failure
rollback, direct-copy staging bypass, and explicit shutdown cleanup;
- resident-layer requests requiring no-AllGather;
- DP request-wave validation for denoising-step compatibility;
- sharding, double-buffer, AllGather-size, and heterogeneous-block regression
tests.
### B300 parallel-topology smoke matrix
A four-GPU B300 smoke test covered MiniMax-H3 FL2VA with the same prompt, seed,
CUDNN attention backend, 256x256 output, two denoising steps, and
`dlo_resident_layers=0`. The TP2 rows used DiT DP2xTP2 with the text encoder and
VAEs at TP1. They validate the ordinary-loader fallback only, not direct mmap
or shared-mmap host-memory savings.
| Configuration | Result | Warm E2E | Peak device memory | Host PSS |
|---|---:|---:|---:|---:|
| DP4xTP1 AllGather | Passed, 4 concurrent requests | 2.87 s / 4 requests | 13.84 GiB | 211.99 GiB |
| DP4xTP1 no-AllGather | Passed, 1 request | 15.02 s | 13.23 GiB | 187.77 GiB |
| DP2xTP2 AllGather | Passed, 2 concurrent requests | 4.16 s / 2 requests | 12.50 GiB | 211.97 GiB |
| DP2xTP2 no-AllGather | Passed, 1 request | 3.51 s | 11.88 GiB | 314.01 GiB |
Within each topology, the AllGather and no-AllGather video and audio outputs
were byte-identical. All four runs completed without an `ERROR` or traceback
and released their device allocations. For DP4xTP1, no-AllGather direct mmap
reduced total PSS by 24.22 GiB (11.4%) and `Private_Dirty` from 211.33 to
125.32 GiB (40.7%) relative to AllGather. For DP2xTP2, preflight selected the
ordinary loader as designed; no-AllGather PSS was 314.01 GiB, about 48% above
AllGather, because DP replicas did not share checkpoint-backed runtime
weights. This is a functional and memory smoke test, not a production-quality
performance or output-quality benchmark.
### Host-memory measurement
A two-worker MiniMax-H3 FL2VA measurement on one L20X node compared the
ordinary-loader fallback with direct mmap. Both runs used
DP=2, TP=1, no DLO AllGather, BF16 weights, two denoising steps, and a
256x256 four-second request. The ordinary-loader workers were sampled after
initialization. The mmap workers were sampled after one completed request, so
the checkpoint working set had been faulted into the page cache; this is the
more conservative point for mmap.
The values below come from `/proc/<worker>/smaps_rollup` and include the whole
worker, not only the DiT. The stable rank-to-rank difference comes from other
pipeline components, so each worker should be compared with the same worker in
the other storage mode.
| Worker | Ordinary RSS | mmap RSS | Ordinary PSS | mmap PSS | PSS reduction |
|---|---:|---:|---:|---:|---:|
| DP worker 0 | 168.27 GiB | 132.76 GiB | 167.84 GiB | 101.43 GiB | 66.40 GiB |
| DP worker 1 | 116.19 GiB | 79.97 GiB | 115.73 GiB | 48.64 GiB | 67.09 GiB |
| **Two-worker total** | — | — | **283.56 GiB** | **150.08 GiB** | **133.48 GiB (47.1%)** |
The direct-mmap workers each reported 62.45 GiB `Shared_Clean` but only
31.20 GiB `Pss_File`, which is the proportional charge expected when the same
resident checkpoint pages are mapped by two workers. `Private_Dirty` also fell
from 167.53 to 70.24 GiB for worker 0 and from 115.40 to 17.44 GiB for worker
1, a reduction of about 97–98 GiB per worker. RSS understates this benefit
because it counts a shared physical page in every process that maps it; summed
PSS is the appropriate node-memory comparison.
### L20X runtime-cache smoke matrix
Phase B was also exercised on four L20X GPUs in one NVLink domain with
MiniMax-H3 FL2VA, CUDNN attention, eager execution, 256x256 four-second
outputs, two denoising steps, `dlo_resident_layers=0`, text-encoder TP1, and
VAE TP1. This is a functional, memory, and profiler smoke test rather than a
production-quality performance benchmark. Host values below are node-wide
maxima during request waves from descendant-process `smaps_rollup`; they do
not represent the private startup peak. HBM is the engine-reported request
peak because sampled `nvidia-smi` data can miss short-lived allocations.
One internal DP2xTP2 engine compared the three host-storage/transfer choices.
Each measured wave contained two requests. NVLink TX is the physical per-link
counter delta summed across the four GPUs; RX had the same value and is not
added again here.
| Mode | Two-request wave | Throughput | Host PSS | `Private_Dirty` | Engine peak HBM | NVLink TX / wave |
|---|---:|---:|---:|---:|---:|---:|
| AllGather, ordinary loader | 3.41 s | 0.587 req/s | 210.70 GiB | 209.72 GiB | 12,498 MB | 73.37 GiB |
| no-AllGather, private loader weights | 6.96 s | 0.287 req/s | 312.56 GiB | 311.56 GiB | 11,882 MB | 19.78 GiB |
| no-AllGather, runtime cache (cold publish) | 18.94 s | 0.106 req/s | 178.71 GiB | 116.00 GiB | 11,882 MB | 19.78 GiB |
| no-AllGather, runtime cache (warm reuse) | 24.23 s | 0.083 req/s | 178.29 GiB | 115.58 GiB | 11,882 MB | 19.78 GiB |
The no-AllGather cache preserved the no-AllGather NVLink traffic and HBM
footprint while reducing node PSS by about 134 GiB relative to private loader
weights. Cold and warm labels describe cache publication or reuse during
initialization; both request phases ran after initialization. A warm hit still
performed ordinary loading and full content hashing, so it was not a startup
fast path. All measured no-AllGather private/cache outputs were byte-identical
for matching seeds.
The deployment shape targeted by the cache was tested separately as two
independent DP1xTP2 engines on the same node. Both engines mapped the same two
TP-coordinate entries, including the same file device/inode tuples; the cache
occupied 66,281,995,903 bytes. A start barrier kept all four measured requests
ahead of profiling.
| Storage | Mean request latency, engines A / B | Combined throughput | Host PSS | `Private_Dirty` | Engine peak HBM |
|---|---:|---:|---:|---:|---:|
| Private loader weights | 3.50 / 3.60 s | 0.463 req/s | 366.20 GiB | 365.22 GiB | 11,882 MB |
| Shared runtime cache | 8.96 / 12.30 s | 0.142 req/s | 232.23 GiB | 169.52 GiB | 11,882 MB |
The shared cache reduced request-time PSS by 133.97 GiB (36.6%) and
`Private_Dirty` by 195.70 GiB (53.6%), but reduced combined throughput by
69.3% in this host-contention smoke. Across one profiled request per engine,
aggregate GPU compute was unchanged (1.359 versus 1.357 seconds) and H2D
payload was exactly 264.24 GiB in both modes. Aggregate CPU `aten::copy_` time
rose from 3.75 to 32.49 seconds, while communication-kernel time rose from
3.56 to 5.80 seconds as TP ranks waited on skewed staging. These durations are
summed across ranks and can overlap; they identify the mechanism, not wall
time. Matching private/cache outputs were byte-identical.
The result confirms that zero-budget runtime-cache staging is a host-capacity
option, not a latency-neutral replacement for private pinned weights. Broader
SP, model, platform, and production-quality validation remains tracked in
[issue #6231](https://github.com/vllm-project/vllm-omni/issues/6231). The
historical B300 rows above predate the runtime cache and must not be treated as
Phase B memory validation.
### L20X registered-runtime-cache smoke
The read-only registered path was then tested with the same MiniMax-H3
workload. These are functional and mechanism-validation measurements, not a
production benchmark. The TP1 pair used one request per wave. Both modes moved
exactly 121.86 GiB H2D in the profiled request and produced byte-identical video
and audio for both measured seeds.
| TP1 no-AllGather mode | Mean wave | Throughput | Request-time host PSS | `Private_Dirty` | Engine peak HBM | CPU `aten::copy_` | GPU compute |
|---|---:|---:|---:|---:|---:|---:|---:|
| Checkpoint mmap + bounded staging | 33.87 s | 0.0295 req/s | 133.65 GiB | 71.16 GiB | 13,226 MB | 21.91 s | 419.28 ms |
| Final runtime cache + registered direct H2D | 4.88 s | 0.2055 req/s | 129.41 GiB | 66.93 GiB | 13,226 MB | 1.64 s | 419.05 ms |
Registration covered 61.73 GiB in 13 page-aligned ranges. Mean wave latency
fell by 85.6% and throughput increased 6.94x. GPU compute and H2D payload were
unchanged, identifying recurrent host transform/packing as the removed work.
The direct path issued 2,425 H2D events versus 1,945 for packed staging, but
that launch increase was much smaller than the eliminated CPU cost.
Two independent TP2 engines also registered the same two TP-coordinate cache
entries across four workers. Compared with the zero-budget cache, mean wave
latency improved from 9.21/12.55 seconds to 3.80/3.86 seconds for engines A/B;
the private-loader reference was 3.61/3.72 seconds. Registered request-time
host PSS was 224.26 GiB versus 232.23 GiB staged and 366.20 GiB private.
Aggregate CPU `aten::copy_` time was 3.83 seconds registered, 32.49 seconds
staged, and 3.75 seconds private; aggregate GPU compute and the 264.24 GiB H2D
payload were effectively unchanged. Ordinary TP communication remained, but
the extra wait caused by staging-driven rank skew largely disappeared.
All workers explicitly unregistered before releasing their mappings, the
system's acquired-minus-released pin counter returned to its pre-run value,
and every GPU allocation was released. Cold runtime-cache publication remained
expensive because it still performs ordinary loading and multiple full-content
passes; that startup problem is outside the registered transfer scope.
## Recommendations
- Use **DP + DLO AllGather** for the supported throughput and host-memory
scaling path.
- Use **SP + DLO AllGather** for long-sequence workloads when DP concurrency is
not the goal.
- Use **no-AllGather** when independent replica execution is required. TP1
direct-mmap deployments can share checkpoint pages per node. Enable the
runtime cache only when independent replicas have repeated final layouts and
benchmark the target CPU/memory topology, especially for matching
coordinates across multiple TP engines. On CUDA, provide an explicit
registration budget large enough for the complete final layout when
recurrent staging cost is unacceptable; leave it at zero when page-locking
that layout is not operationally acceptable.
- Prefer **HSDP alone** for production HSDP deployments until the combined
HSDP + DLO no-AllGather path has broader end-to-end coverage.
@@ -0,0 +1,57 @@
# Layerwise Offload
Layerwise offload streams transformer blocks through one accelerator. For
commands and model support, see the
[layerwise user guide](../../../user_guide/diffusion/offloader/layerwise_offload.md).
## Hook ring
`LayerWiseOffloadBackend` discovers every streamable block and registers one
`LayerwiseOffloadHook` per block. Hooks form a ring: each hook owns the pinned
host representation of its registered block and a reference to the next block
it must prefetch; the final hook prefetches the first block for the next
denoising iteration.
During initialization, parameters and buffers are grouped by dtype and copied
into contiguous pinned CPU tensors. Original tensor storage is replaced with
an empty or meta placeholder while identity and module structure are retained.
Metadata records names, offsets, shapes, and dtypes for rematerialization.
## Forward lifecycle
For each block:
1. the previous hook's completion event ensures this block is materialized;
2. the copy stream asynchronously allocates and fills the next block's device
tensors;
3. parameter and buffer storage is rebound to views of those tensors;
4. the current block computes on the normal stream; and
5. its post-forward hook replaces device storage with placeholders after all
dependent work is safe.
The copy stream waits on the compute stream before reusing storage, and the
compute stream waits on the per-block prefetch event before forward. These
dependencies, not incidental global synchronization, define correctness.
## Topology contract
A DiT declares ordered block-container attributes using
`_layerwise_offload_blocks_attrs` or an `OffloadPlan`. Each resolved item must
be an executable `nn.Module`; ordering must match forward execution. Multiple
containers are concatenated in execution order.
Non-block DiT modules, encoders, VAEs, and declared resident modules are not
streamed by this backend.
## Invariants and limitations
- Each offloaded tensor has one pinned host backing store.
- Parameter identity is preserved when storage is rebound.
- Blocks with heterogeneous shapes and dtypes use their recorded metadata;
implementations must not assume identical blocks.
- The ring is initialized before the first forward so block zero is available.
- This backend is single-device; distributed weight reconstruction belongs to
[Distributed Layerwise Offload](distributed_layerwise_offload.md).
Shared selection and lifecycle behavior is defined in the
[CPU Offloading design](README.md).
+12 -4
View File
@@ -76,6 +76,12 @@ equivalent. `auto-round` and `auto_round` use the Omni INC/AutoRound adapter.
ModelOpt checkpoint metadata is detected from its method, producer metadata, or
`quant_algo`, then mapped to the corresponding vLLM ModelOpt configuration.
Unless the input is a per-component dictionary, the resolved configuration is
passed unchanged to every quantization-aware component constructed by the
pipeline. It affects only layers supported by that component's quantization
method; it does not rewrite arbitrary `torch.nn` modules. A per-component
dictionary narrows this global scope through runtime layer-prefix routing.
The factory uses Omni-specific overrides for methods whose diffusion behavior
or platform dispatch is not provided by the vLLM registry. The current override
set includes INT8, BitsAndBytes, MXFP8, MXFP4, MXFP4 dual-scale, and INC/
@@ -154,9 +160,11 @@ quantizable vLLM layers. Each method configuration is responsible for:
Model code must keep precision-sensitive or unsupported modules unquantized.
The shared `safe_quant_config()` helper is used by model integrations for
normalization and modulation layers where a generic FP8 configuration would be
unsafe. Text encoders, audio/vision encoders, VAEs, schedulers, and tokenizers
are not implicitly quantized just because the main transformer is quantized;
they require explicit component routing and method support.
unsafe. Encoders exposed through the quantization factory receive a global
configuration just like the main transformer, but only their supported vLLM
quantizable layers are affected. Ordinary `torch.nn` encoder layers, VAEs,
schedulers, and tokenizers are not rewritten automatically. A component map can
select a narrower scope, but it cannot add quantization support to a layer.
Weight quantization and quantized KV cache are separate paths. The former is
resolved through `quantization_config`; runtime attention/KV-cache quantization
@@ -186,7 +194,7 @@ Distributed layerwise offload has an additional boundary: its sharded mmap
AllGather path is not compatible with online quantization because the path
expects already materialized checkpoint weights. Use the rank-local
`--dlo-no-use-allgather` path or a compatible pre-quantized checkpoint when
combining these features. See the [DLO design document](distributed_layerwise_offload.md)
combining these features. See the [DLO design document](offloader/distributed_layerwise_offload.md)
for the full compatibility matrix.
## Adding a quantization backend
@@ -0,0 +1,213 @@
# Realtime AR-Diffusion sessions
> **Status:** experimental. This document describes the internal execution
> contract implemented under `vllm_omni.experimental.ar_diffusion`. It does not
> define a public HTTP or WebSocket schema.
## Scope
Realtime AR-Diffusion serves world models that generate one autoregressive
latent block per request while retaining model state across requests. The
generic runtime owns identity, event ordering, session lifecycle, routing, and
KV allocation. A model adapter owns model-specific controls and conditioning.
LingBot World v2 is the first single-KV-branch integration. DreamZero uses the
same runner capability with two logical CFG branches.
## Identities
Four identifiers have distinct lifetimes:
| Identifier | Lifetime | Owner | Contract |
| --- | --- | --- | --- |
| `session_id` | One persistent world | Session manager | Selects runner KV and model-owned state. |
| `event_id` | One control/prompt update | Transport adapter | Unique and monotonically increasing within a session, including across reset. |
| `chunk_index` | One committed AR block position | Session | Contiguous from zero; reset starts again at zero. |
| `request_id` | One chunk execution | Session | Correlates the tick with its returned metadata. |
`AsyncOmni` keeps its normal UUID-suffixed engine routing ID. The tick
`request_id` remains inside the immutable AR-Diffusion snapshot and the
standard output metadata, while caller-visible `OmniRequestOutput.request_id`
continues to use AsyncOmni's existing external-ID contract. Protocol identity
therefore does not require a private entrypoint override.
## Request lifecycle
1. `ARDiffusionSession.accept_event()` validates and queues an immutable
`ARDiffusionSessionEvent`. Prompt and opaque control tracks may be updated in
the same event.
2. `ARDiffusionSession.next_chunk()` serializes chunk execution and calls
`_build_tick_locked()`. The resulting `ARDiffusionTickRequest` is a snapshot
of the current prompt, reduced controls, ordered event IDs, and chunk index.
3. `ARDiffusionOmniTickConsumer.execute_tick()` copies the stage sampling
parameters, stores the typed tick in
`sampling_params.extra_args["ar_diffusion_tick"]`, constructs the normal Omni
prompt through its `prompt_provider`, and invokes `AsyncOmni.generate()`.
4. `AsyncOmni` allocates its normal unique engine routing ID and submits one
`OmniDiffusionRequest` through the orchestrator.
5. `ARDiffusionModelRunner._request_session()` parses the typed tick.
`_get_or_create_session()` obtains runner-owned paged KV, and
`bind_ar_diffusion_state()` exposes it to the pipeline only for the duration
of `execute_model()`.
6. The model pipeline validates the tick and generates exactly one latent
block. LingBot interprets camera controls in
`LingBotCameraControlReducer` and
`LingBotWorldCausalDMDPipeline.forward()`; the generic runtime does not parse
camera or action schemas.
7. The pipeline returns one `DiffusionOutput` with the generated payload and an
`ARDiffusionChunkMetadata` mapping under `metadata["ar_diffusion"]`.
`AsyncOmni` exposes it as
`OmniRequestOutput.multimodal_output["metadata"]["ar_diffusion"]`.
8. The consumer parses the standard envelope. The session commits its reducer
state, prompt, controls, event IDs, and next chunk index only when returned
metadata exactly equals the submitted tick snapshot.
The metadata envelope is:
```json
{
"metadata": {
"ar_diffusion": {
"session_id": "world-7",
"request_id": "ar-world-7-3-...",
"chunk_index": 3,
"applied_event_ids": [10, 11]
}
}
}
```
## Transaction and failure semantics
Accepted events are not acknowledged as applied until the model output and
metadata are validated. Reducer `prepare()` is speculative; reducer `commit()`
and the session snapshot form one logical commit. A model, metadata, or reducer
failure leaves the chunk index and queued events uncommitted and transitions the
session to `FAILED`.
After a tick failure, worker state is closed because a forward may have
partially modified or already released KV. The same chunk is not retried in
place. A caller must explicitly reset the session, starting again at chunk
zero, or close it.
Explicit close follows this state machine:
```text
ACTIVE or FAILED
|
v
CLOSING ---- worker cleanup succeeds ----> CLOSED
|
+------- worker cleanup fails --------> CLEANUP_FAILED
|
+-- close retry --> CLOSING
```
`CLEANUP_FAILED` is a local tombstone. The session manager retains it, rejects
creation of the same `session_id`, and rejects reset. Only an idempotent close
retry that succeeds removes the session. Transport disconnect uses the same
path.
## KV ownership and capacity
`ARDiffusionKVCacheSpec` is the pipeline-owned immutable geometry contract. It
declares:
- TP-local self-attention geometry, AR block size, sink, and recent window;
- logical KV branches and their worker-local slots;
- fixed-length cross-attention caches;
- scratch tokens required by an uncommitted forward;
- persistent model-owned CUDA bytes per resident session; and
- the requested resident-session capacity.
The runner computes:
```text
required(capacity) =
scratch
+ managed_self_attention_pages(capacity)
+ capacity * cross_attention_bytes_per_session
+ capacity * model_owned_state_bytes_per_session
```
`gpu_memory_fraction` is a soft expansion budget:
```text
configured_budget = available_device_bytes * gpu_memory_fraction
effective_budget = max(configured_budget, required(1))
```
If `required(1)` exceeds actual available device memory, initialization fails.
Otherwise the runner always admits one viable session and uses the configured
fraction to select additional resident sessions up to the model-declared cap.
All model-owned reservations are deducted before the paged self-attention pool
is allocated.
LingBot reports its persistent full-horizon image-condition tensor. DreamZero
reports the measured 603 MiB per-session Wan VAE causal-convolution state.
## Concurrency and routing limits
The current runner executes one request at a time:
- `max_num_seqs` must be one;
- request batching and diffusion step execution are rejected;
- one AR block is generated per engine request; and
- an AR-Diffusion stage must have exactly one replica.
The single-replica restriction is intentional. Multi-replica support requires
session-affine routing so every tick, reset, and close reaches the worker that
owns the session. Random or round-robin routing is not correct.
Multiple resident sessions may share one runner. Capacity selection accounts
for all persistent pools, and the runner performs LRU eviction through the same
model lifecycle hook used by explicit close.
## Model boundary
The generic runtime transports controls as opaque
`ARDiffusionControlInput(track, schema, data)` values. Model adapters validate
and reduce those values. This keeps target/velocity, key state, pose,
intrinsics, and other model-specific conventions out of the session protocol.
For LingBot World v2:
- `lingbot_world/actions.py` parses key-state and trajectory controls;
- `lingbot_world/camera.py` loads or constructs camera trajectories and Plücker embeddings;
- `lingbot_world/transformer.py` implements checkpoint-compatible causal attention; and
- `lingbot_world/pipeline.py` constructs conditioning, owns small non-KV session state, and
produces one block plus the standard metadata envelope.
## Non-goals
This contract does not currently provide:
- a public HTTP or WebSocket request schema (the structured-interaction
frontend is tracked separately in
[#5527](https://github.com/vllm-project/vllm-omni/pull/5527));
- camera/action semantics shared by every world model;
- session migration or replication across workers;
- retry of an ambiguous partially executed chunk;
- cross-stage KV transfer; or
- stateful streaming VAE decode.
Those features can be layered on top without adding LingBot-specific identity
or lifecycle fields to the generic runtime.
## Required regression coverage
CPU contract tests cover:
- separation of tick correlation IDs from internal engine routing IDs;
- event ordering, metadata equality, and reducer fail-closed commit;
- close/disconnect failure tombstones and cleanup retry;
- capacity one under the default fraction for shipped LingBot geometry;
- capacity expansion under a tuned fraction;
- DreamZero model-owned state accounting;
- runner session reuse, reset, close, LRU eviction, and forward cleanup; and
- LingBot model registration, imports, camera/action reduction, and one-block
output metadata.
GPU validation must additionally exercise real model loading, action input,
prompt switching, rolling-window replacement, reset, close, finite output
latents, and exact metadata/request identity.
+4 -2
View File
@@ -2,8 +2,10 @@
Skip-Softmax is the sparse-attention mode of the `TRTLLM_ATTN` backend. Usage — the config keys
and how to pick an operating point — is in
[Diffusion Attention Backends](../../user_guide/diffusion/attention_backends.md). This page explains
the algorithm.
[TRTLLM Attention](../../user_guide/diffusion/attention_backends/trtllm.md#skip-softmax).
The shared selector contract is documented in
[Diffusion Attention Backend Selection](attention_backend_selection.md). This
page explains the algorithm.
## Motivation
+20 -4
View File
@@ -11,6 +11,10 @@ in the active navigation.
## Feature Design Documents
For user-facing configuration and current compatibility, see the
[Features overview](../features/README.md). A design document defines an
implementation contract; it is not, by itself, a general support claim.
### Runtime and stage execution
- [Disaggregated Inference](feature/disaggregated_inference.md)
@@ -18,6 +22,7 @@ in the active navigation.
- [Async Diffusion Output](feature/async_diffusion_output.md)
- [Async Omni Output Materialization](feature/omni_async_output_materialization.md)
- [Automatic Prefix Caching in Omni Models](feature/prefix_caching.md)
- [Realtime AR-Diffusion Sessions](feature/realtime_ar_diffusion.md)
### Communication
@@ -30,6 +35,10 @@ in the active navigation.
- [Yuanrong Store Connector](feature/omni_connectors/yuanrong_connector.md)
- [Yuanrong Transfer Engine Connector](feature/omni_connectors/yuanrong_transfer_engine_connector.md)
### Quantization
- [Quantization](feature/quantization.md)
### Diffusion acceleration
#### Parallelism
@@ -42,18 +51,25 @@ in the active navigation.
- [Tensor Parallel](feature/tensor_parallel.md)
- [VAE Patch Parallelism](feature/vae_parallel.md)
#### Attention Backends
#### Attention optimization
The [Diffusion Attention Backends](../user_guide/diffusion/attention_backends.md)
guides list selectable backends, platform defaults, installation, and tuning.
The design contracts separate selection mechanics from backend algorithms:
- [Attention Backend Selection](feature/attention_backend_selection.md)
- [Skip-Softmax](feature/skip_softmax.md)
#### Quantization
#### CPU offloading
- [Quantization](feature/quantization.md)
- [Overview and Shared Contracts](feature/offloader/README.md)
- [Model-Level Offload](feature/offloader/cpu_offload.md)
- [Layerwise Offload](feature/offloader/layerwise_offload.md)
- [Distributed Layerwise Offload](feature/offloader/distributed_layerwise_offload.md)
- [Cache-DiT](feature/cache_dit.md)
- [TeaCache](feature/teacache.md)
- [Diffusion Continuous Batching](feature/diffusion_continuous_batching.md)
- [Distributed Layerwise Offload](feature/distributed_layerwise_offload.md)
## Infrastructure and Performance
+1 -1
View File
@@ -1,6 +1,6 @@
# Prometheus Metrics Design
This document describes how vLLM-Omni exposes Prometheus metrics for multi-stage pipelines, the constraints that shaped the design, and how the pipeline-level metrics coexist with upstream vLLM per-engine metrics. This iteration covers the text and audio surface; diffusion / image / video families land in a follow-up.
This document describes how vLLM-Omni exposes Prometheus metrics for multi-stage pipelines, the constraints that shaped the design, and how the pipeline-level metrics coexist with upstream vLLM per-engine metrics.
## Objectives
+1
View File
@@ -7,6 +7,7 @@ owners:
- "@yinpeiqi"
- "@fake0fan"
- "@Sy0307"
- "@Gaohan123"
primary_code_paths:
- vllm_omni/core/**
- vllm_omni/worker/**
+1
View File
@@ -4,6 +4,7 @@ kind: module
status: draft
owners:
- "@alex-jw-brooks"
- "@Bounty-hunter"
primary_code_paths:
- vllm_omni/benchmarks/**
- vllm_omni/entrypoints/cli/benchmark/**
Loaded 100 of 832 files, more files were not shown because too many files have changed in this diff. Show more