Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion knowledge/repos/vllm-omni/benchmark/rules.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "vLLM-Omni Benchmark 规则"
created: 2026-09-05
updated: 2026-09-10
updated: 2026-09-18
type: rule
tags: [vllm-omni, benchmark]
sources: ["PR #6817", tests/dfx/perf/scripts/run_benchmark.py, tests/benchmarks/test_omniinteract.py, "PR #7130", "PR #7259"]
Expand Down Expand Up @@ -60,3 +60,10 @@ confidence: high
- 强制:轮询 deadline 来自 per-request `video_job_timeout`(默认 900s,可 CLI 加大),从 job 创建后起算含排队;仅当 status 仍非 `completed`/`failed` 且超时才判失败。progress/latency 在 cleanup 路径更新,使失败请求也推进进度条;报告打印失败数与样例错误,JSON 写入全部 `request_errors`。
- 禁止:硬编码 600s 后删除仍可能完成的 job;成功路径才 `pbar.update`;只报告成功计数而隐藏失败原因。
- 验收:覆盖默认/加大 timeout、deadline 时已 `completed` 仍取回、混合成功/失败时进度与 `failed_requests`/`request_errors` 一致。^[PR #7259]

## BENCH-1f — benchmark 结果必须始终导出样本计数,包括零

- 触发:修改 `benchmarks/patch` 的 result dict,或 DFX 对 `num_tpot_samples` 等计数字段的读取。
- 强制:`calculate_metrics()` 已经产出的 `num_ttft_samples`、`num_tpot_samples`、`num_itl_samples`、`num_audio_ttfp_samples`、`num_audio_rtf_samples` 必须写入结果,包括 0,且与 percentile 是否被选中无关。JSON 往返后字段仍在。缺键是 `None`,不是 0;DFX 在 finite `mean_tpot_ms` 下仍会因 `isinstance(None, int)` 失败。
- 禁止:只在选中 TPOT/ITL percentile 时写出计数;用均值存在代替样本数字段;改 DFX 判定去迁就缺字段的 JSON。
- 验收:真实聚合加 JSON round-trip,分别覆盖 measured/unmeasured TPOT 与选中/未选中 percentile;省略 `num_tpot_samples` 而保留 finite mean 的结果必须被 baseline 拒绝。^[PR #7624]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Diffusion paged cache 与系统运行时规则"
created: 2026-09-03
updated: 2026-09-09
updated: 2026-09-18
type: rule
tags: [vllm-omni, components, diffusion]
sources: ["PR #5255", "PR #5344", "PR #5543", "PR #5838", "PR #6094", "PR #6102", "PR #6385", "PR #6340", "PR #6714", "PR #6814", "PR #6563", "PR #5716", "PR #6786", vllm_omni/diffusion/attention/, vllm_omni/diffusion/attention/parallel/ulysses.py, vllm_omni/diffusion/attention/parallel/ring_kernels.py, vllm_omni/diffusion/diffusion_kv/, vllm_omni/diffusion/distributed/cfg_parallel.py, vllm_omni/diffusion/distributed/parallel_state.py, vllm_omni/diffusion/worker/diffusion_model_runner.py, vllm_omni/platforms/interface.py, vllm_omni/platforms/npu/platform.py, tests/diffusion/diffusion_kv/, tests/diffusion/distributed/test_cfg_parallel.py, tests/diffusion/attention/test_piecewise_attn.py, tests/diffusion/attention/test_ulysses_uaa.py, "PR #5491", "PR #5194", "vllm_omni/diffusion/data.py", "vllm_omni/diffusion/utils/hf_utils.py", "PR #7041", "PR #6463", "PR #6844"]
Expand Down Expand Up @@ -226,3 +226,10 @@ confidence: high
- 强制:一次 `generate()` 驱动整段 rollout:`prepare_encode` 只跑一次,随后多轮 `denoise_step`/`step_scheduler`,由 `post_decode` 产出每个 AR chunk。request-mode 与 stepwise 必须共用同一份 block/DMD math,禁止维护两套可漂移实现。runner 仅为实现该合同的 pipeline 打开 `step_execution`;绑定 runner-owned KV 时 `session_id == request_id`;错误路径 fail-closed 释放 session,完成或 scheduler abort 时退役。持有 AR-Diffusion paged KV 的 stage 必须保持 `max_num_seqs=1`。
- 禁止:用多次 `generate()`/tick 冒充同一 session;在 denoise step 内提交本应属于 `post_decode` 的 clean-x0 KV commit;或把逐步 camera/prompt mid-request interaction 写成已由本合同覆盖。
- 验收:覆盖 stepwise 与 request-mode 的共享 math 边界、session bind/release、abort/completion 退役,以及 `max_num_seqs=1` 拓扑;request-scoped camera script 等模型字段另由模型 owner 验收,不得外推为通用 mid-request interaction。^[PR #6844]

## DIFF-4ad — 无法合成观测的 pipeline 必须退出通用文本 warmup

- 触发:修改 `DiffusionEngine.run_startup_warmup`、`dummy_run_num_frames`,或新增必须携带非文本观测(如 `robot_obs`)的 diffusion pipeline。
- 强制:通用 startup warmup 是文本、两步请求。pipeline 无法从该请求合成所需观测时,必须声明 `dummy_run_num_frames: ClassVar[int] = 0`,使 `run_startup_warmup` 不提交请求、也不因此 `close`。模型自有 warmup(如 AR-Diffusion 的 `ar_diffusion_warmup_requests`)保持可用。能接受文本 dummy 的模型仍走两步通用 warmup。
- 禁止:把 DreamZero/LingBot 的 opt-out 扩成所有模型跳过 warmup;用一步 shortcut 让非法文本请求穿过观测检查;opt-out 后仍断言 engine 被关闭。
- 验收:经真实 registry 查找,DreamZero 与 LingBot 的 startup 不调用 `add_req_and_wait_for_response` 且不 `close`;其余模型的两步 dummy 合同不变。^[PR #7548]
9 changes: 8 additions & 1 deletion knowledge/repos/vllm-omni/models/cosyvoice3/rules.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "CosyVoice3 规则"
created: 2026-09-04
updated: 2026-09-05
updated: 2026-09-18
type: rule
tags: [vllm-omni, models]
sources: ["PR #5673", "PR #6955", vllm_omni/model_executor/models/cosyvoice3/code2wav_core/cfm.py, vllm_omni/model_executor/models/cosyvoice3/flow_estimator_trt.py, tests/model_executor/models/cosyvoice3/test_cosyvoice3_components.py, benchmarks/tts/benchmark_cosyvoice3_trt_streams.py]
Expand Down Expand Up @@ -50,3 +50,10 @@ confidence: high
证明 replace 失败保留旧 plan、cleanup 失败保留 replace error、partial write 清理 owned tmp、
collision 保留 foreign tmp,以及两条同步 publisher 使用不同 source path 且仅留下完整 final plan。
^[PR #6955]

## COSYVOICE3-1c — 流式 HiFT 必须在有界 mel 窗上增量计算并携带相位

- 触发:修改 CosyVoice3 `_stream_hift_from_feat`、`CausalHiFTGenerator`、`SineGen`/`SineGen2` 的 `phase_acc`,或 streaming chunk 的 noise/F0 cache。
- 强制:每个 chunk 只在有界 mel 窗上计算(末 64 帧再加上 F0 感受野历史),不得对累积全谱重跑。谐波相位用共享的边界 `phase_acc` 带入下一窗。noise 必须是固定、按位置索引的 buffer,不能用随 chunk 变化的 `torch.randn_like`。F0 predictor 的左因果卷积要吃 window 左侧的真实历史,不能零填充;这段 margin 属于 `cache_state`,在进入 SineGen/decode 前切掉,且短于感受野的 chunk 不得饿死下一次调用。finalize 除 `conv_pre_look_right` 外还要释放 predictor 自己扣下的 `trim`,否则流末约 3 个 mel 帧丢失。
- 禁止:用 PCM16 逐字节相等当正确性门槛(亚 LSB 的再结合误差会翻边界样本);只测未触发 voiced 的随机权重;把 `scipy`/`s3tokenizer` 放回 dev extra——它们是 base install 的硬依赖,scipy 下限保持 `>=1.11.0`。
- 验收:相对全量重算,float64 应逐位一致;float32 用 `assert_close(atol=1e-6, rtol=1e-5)`。同时覆盖 SineGen(22050 Hz)与 SineGen2(24000 Hz)、强制 voiced,以及均匀 chunk 和单 mel 帧的小块。^[PR #7521]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "MiniCPM-o 4.5 Code2Wav CUDA graph 规则"
created: 2026-09-04
updated: 2026-09-04
updated: 2026-09-18
type: rule
tags: [vllm-omni, models, model-executor]
sources: [vllm_omni/model_executor/models/cosyvoice3/code2wav_core/hifigan.py, vllm_omni/model_executor/models/minicpmo_4_5/batched_token2wav.py, vllm_omni/model_executor/models/minicpmo_4_5/cuda_graph_wrapper.py, tests/model_executor/models/minicpmo_4_5/test_cfm_graph_capture_gating.py, tests/model_executor/models/minicpmo_4_5/test_cuda_graph_wrapper.py, "PR #5869", "PR #6082", "PR #6587"]
Expand All @@ -26,3 +26,11 @@ confidence: high
- 强制:warmup 或 capture 发生异常时,在该 wrapper 的剩余生命周期内保持禁用并退休其自有 generation;不能在可能脏的 capture stream/allocator 状态继续捕获。无法由 key 重建的 dtype 仅标记该 shape eager,不得禁用其他可捕获 shape;capture admission 不得依赖 device free-memory。维护固定字段的 calls/hits/captures/flushes/eager 累计 telemetry。
- 禁止:捕获整个 `_estimator_step` 或手写替代 graph target;使用无界 shape cache、逐图 eviction、跨 owner 的 process-wide cleanup,或在 nested capture 中重放;捕获失败后伪装成功;把 CFM graph 的配置、性能或 parity 结论外推到 HiFT、encoder、TRT 或其他模型。
- 验收:CUDA 测试覆盖 uncached/cached shape 的 graph/eager 数值 parity、`None` cache parity、lazy capture、整代 flush 后 HiFT replay parity、capture/warmup failure 后不再 capture、unsupported dtype shape-local eager 与 `max_graphs <= 0` eager;CPU/mock 覆盖 active capture/non-CUDA、free-memory 非 gating、telemetry 和 inert non-CUDA memory reporting,并确认 deploy 配置值实际到达 estimator。^[PR #6082] ^[PR #6587]

## MCPMO-1k — CFM graph 的变长 chunk 必须先对齐帧桶,padding 不得进入 cache

- 触发:修改 MiniCPM-o 4.5 Code2Wav 的 CFM decode chunk、`cfm_graph_bucket_frames`、reference-audio 长度,或 attention/CNN cache 边界。
- 强制:捕获前把 mel 帧 pad 到 `bucket_frames` 的倍数,输出再裁回有效帧,使 chunk 长度落在同一 grid。每份开启 CFM graph 的 shipping profile 必须显式写 `cfm_graph_bucket_frames`(当前 16),不能靠代码默认。`bucket_frames <= 1`、graphs 已禁用、ragged valid-lengths,或 pad 会越过 decoder noise capacity 时不 pad。
- 强制:padded 列必须被真实 `attn_mask` 排除;零 key 仍会计入 softmax 分母。成为下一 chunk 的 key 或左上下文之前,清零 attention cache 的 padded 列,以及各 block CNN cache 中来自 padding 的尾部。speaker 向量会铺满每一帧,清零必须作用在 clone 上。conditioning pad 复制最后一帧有效值。reference audio 先转 mono、抗混叠重采样到 24 kHz,再按 `ref_audio_max_seconds`(默认 6s)截断或补零,使各请求共享一个 L0;默认 prompt 走同一路径,`soundfile` 的 `(samples, channels)` 先转置。
- 禁止:让首尾 chunk 或 `plan_token2wav_encode_slices` 的任意长度各自成为 graph key;只清零 `x`/`mu`/`cond` 而留下非零 speaker 列;把桶化 parity 外推到 HiFT、TRT 或其他模型。
- 验收:覆盖 pad/trim、noise overflow 不 pad、attn_mask 与 cache 清零、reference 归一化后的单一 L0,以及四份 CFM-graph profile 都带上 `cfm_graph_bucket_frames`。^[PR #7416]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "MiniCPM-o 4.5 native duplex 规则"
created: 2026-09-04
updated: 2026-09-08
updated: 2026-09-18
type: rule
tags: [vllm-omni, models, model-executor]
sources: ["PR #6318", "PR #6346", "PR #6404", "PR #6458", "PR #6619", "PR #6630", "PR #6678", "PR #6626", "PR #6767", "PR #6821", vllm_omni/deploy/minicpmo_4_5.yaml, vllm_omni/model_executor/models/minicpmo_4_5/minicpmo_4_5_omni_tts.py, vllm_omni/model_executor/stage_input_processors/minicpmo_4_5_omni.py, tests/model_executor/models/minicpmo_4_5/test_talker_batching.py, vllm_omni/deploy/minicpmo_4_5_2gpu.yaml, vllm_omni/deploy/minicpmo_4_5_3gpu.yaml, vllm_omni/deploy/minicpmo_4_5_8x4090.yaml, examples/online_serving/minicpmo/realtime_duplex_demo.py, vllm_omni/experimental/fullduplex/client.py, vllm_omni/model_executor/models/minicpmo_4_5/duplex/adapter.py, vllm_omni/model_executor/models/minicpmo_4_5/duplex/session.py, vllm_omni/model_executor/models/minicpmo_4_5/duplex/stage0.py, vllm_omni/entrypoints/duplex/realtime_input.py, vllm_omni/entrypoints/duplex/runtime_adapter.py, vllm_omni/entrypoints/duplex/runtime_bridge.py, vllm_omni/entrypoints/duplex/serving.py, vllm_omni/entrypoints/duplex/session_runner.py, vllm_omni/experimental/fullduplex/video_stacking.py, tests/config/test_config_factory.py, tests/engine/duplex/test_duplex_deploy_config.py, tests/e2e/online_serving/helpers/minicpmo_4_5_duplex.py, tests/e2e/online_serving/test_minicpmo_4_5_duplex_expansion.py, tests/entrypoints/openai_api/test_duplex_handler.py, tests/examples/test_minicpmo_realtime_duplex_simple_demo.py, "PR #6529", vllm_omni/entrypoints/duplex/protocol.py, vllm_omni/entrypoints/duplex/realtime_state.py, tests/entrypoints/openai/test_duplex_protocol.py, "PR #6799"]
Expand Down Expand Up @@ -113,3 +113,10 @@ confidence: high
- 强制:默认遵循 checkpoint 声明的 `full_attention`;在该模式下,只要「下一 condition + codec-generation reserve」仍落在由 runtime `max_model_len` 与 `tts_config.max_position_embeddings` 导出的有效上限内,就必须保留已累积的 Talker KV/history 并追加;仅在严格溢出时才重建受支持的 one-previous-condition 窗口,释放旧 KV/encoder 与 connector watermark,重置异步 replacement state,并让请求重新进入 admission。精确贴合上限时允许 append,之后继续累积直至下次溢出。显式 `sliding_recompute` 仍在每个 condition 边界重算;正整数 `meta.next_stage_prompt_len` 是 scheduler 的权威 placeholder 长度,合法 Talker condition 即使缺少 legacy `ids.prompt` 也必须先 append 真实 prompt 再推进 sequence/lifecycle。
- 禁止:把无条件 per-condition recompute 当作生产默认;硬编码 `4096` 当作有效上限;在未溢出时丢弃可保留的 Talker history;或把本路径写成已支持物理 KV preemption 后的增量 full-attention replay。
- 验收:覆盖 fit/exact-fit/overflow、producer-owned 与 receiver-owned sequencing 兼容、`next_stage_prompt_len` 驱动的 append,以及显式 `sliding_recompute` 仍按边界重算;不得用 capacity-triggered rollover 的通过外推为已修复无关 perf 回归。^[PR #6799]

## MCPMO-4j — shipping profile 不得再写入正的 active_stream_window

- 触发:修改四份 `minicpmo_4_5*.yaml` 的 `active_stream_window`,或 `ChunkTransferAdapter` 的有界 `_promote_active_streams` 路径。
- 强制:这些 profile 省略该键,使默认 `0` 关闭 limiter,adapter 留在 unlimited path。配置测试断言 `active_stream_window == 0`,而不是 `== max_sessions`。8×4090 的并发上限仍由 stage `max_num_seqs=1` 承担,不靠窗口 1。
- 禁止:为恢复 first-packet 并发把正窗口写回这四份 profile;把窗口等于 session capacity 的旧断言写回测试。任何正值都会离开 unlimited path。
- 验收:四份 base profile 展开后窗口为 0,且默认 serve 不进入 K-bounded promote。^[PR #7416]
9 changes: 8 additions & 1 deletion knowledge/repos/vllm-omni/models/qwen-image/rules.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Qwen-Image 实现规则"
created: 2026-09-02
updated: 2026-09-08
updated: 2026-09-18
type: rule
tags: [vllm-omni, models, diffusion]
sources: ["PR #5887", tests/e2e/accuracy/test_qwen_image.py, "PR #6110", "vllm_omni/diffusion/models/qwen_image/qwen_image_transformer.py", "PR #5586"]
Expand Down Expand Up @@ -44,3 +44,10 @@ confidence: high
- 强制:有 negative prompt 且启用 true CFG 时,正负两侧都使用各自 embed width;无 negative prompt 时 negative length 必须是 `None`,不能伪造一个来自正分支 mask 的长度。
- 禁止:在 Edit path 回退到 `mask.sum()`,即使别的 Qwen-Image pipeline 仍正确;或仅以 helper test 证明 RoPE table 正确而不锁定实际 `forward()` call site。
- 验收:以 padded embeds 但较短 valid-token mask 的 request 覆盖 Edit `forward()`,精确断言传入 `diffuse()` 的长度等于 padded width;同时覆盖有/无 negative prompt 的 CFG 分支,防止单侧回归。^[PR #5586]

## QWENIMG-1d — CUDA eager RoPE 必须走激活 dtype 的 RotaryEmbedding

- 触发:修改 Qwen-Image `_qwen_image_qk_norm_rope` 的 CUDA/eager 分支、`RotaryEmbedding` 调用,或把 RoPE 放进 regional compile。
- 强制:所有设备的 eager 路径在 RMSNorm 之后使用 `RotaryEmbedding`;`cos`/`sin` 由 `torch.real`/`torch.imag` 得到并 cast 到激活 dtype(BF16)。这是 pipeline 对 Diffusers 的路径。fused kernel 可以继续对照 FP32 complex multiply,但那不是 eager CUDA 路径。
- 禁止:在 eager CUDA 上恢复 `_apply_qwen_image_rotary_emb` 或其它 FP32 复数乘。该 helper 能在单元测试里对齐 Diffusers `apply_rotary_emb_qwen(..., use_real=False)`,但 Inductor 不能 codegen 复数算子,且会把 Omni↔Diffusers pipeline PSNR 打到门限以下。不要用 `--enforce-eager` 掩盖,也不要为迁就 helper 去降 pipeline gate。
- 验收:`use_fused=False` 对所有设备对照 `RotaryEmbedding`;fused 测试单独对照 FP32 complex reference。eager CUDA 与 fused reference 不得再共用同一个 expected。^[PR #7513]
9 changes: 8 additions & 1 deletion knowledge/repos/vllm-omni/models/qwen-omni/rules.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Qwen-Omni 规则"
created: 2026-09-04
updated: 2026-09-09
updated: 2026-09-18
type: rule
tags: [vllm-omni, models, qwen-omni]
sources: ["PR #5687", "PR #6284", "PR #6449", "PR #4322", "PR #6748", "PR #6886", "PR #7019", vllm_omni/config/pipeline_registry.py, vllm_omni/deploy/qwen3_omni_moe.yaml, vllm_omni/deploy/qwen3_omni_moe_thinking.yaml, vllm_omni/engine/stage_init_utils.py, vllm_omni/model_executor/models/qwen2_5_omni/qwen2_5_omni.py, vllm_omni/model_executor/models/qwen3_omni/quantization.py, vllm_omni/model_executor/models/qwen3_omni/qwen3_omni.py, vllm_omni/model_executor/models/qwen3_omni/qwen3_omni_moe_thinker.py, vllm_omni/quantization/component_config.py, tests/config/test_config_factory.py, tests/diffusion/quantization/test_component_routing.py, tests/engine/test_stage_engine_args.py, tests/model_executor/models/qwen3_omni/test_qwen3_omni_quantization.py, "PR #7228"]
Expand Down Expand Up @@ -86,3 +86,10 @@ confidence: high
- 强制:构造 `inv_freq` 时优先 `config.rope_parameters["rope_theta"]`(若 mapping 存在),否则回退 top-level `rope_theta`,再默认 `10000.0`。Qwen3-Omni(Transformers 5.10+ 常把 checkpoint 的 `1_000_000` 只放在 nested 字段)与仍带 top-level 的 Qwen3-TTS/legacy 必须共用该顺序。
- 禁止:只读 top-level 导致静默回退 `10000`;把 nested 优先写成破坏 TTS top-level 兼容的唯一来源。
- 验收:参数化覆盖 nested-only、nested 优先于冲突 top-level、默认 `10000`,以及 TTS/legacy top-level(含删除 `rope_parameters`)重建正确 `inv_freq`。^[PR #7228]

## QOMNI-1h — Thinker 中间态捕获必须补上延迟相加的 residual

- 触发:修改 Qwen3-Omni Thinker 的 `capture_layer_indices` / `return_hidden_states`,或把 decoder 层输出交给 Talker。
- 强制:vLLM 把 block 更新和 residual 分开,直到下一次 RMSNorm 才相加。有 residual 时捕获 `hidden_states + residual`;residual 为 `None` 时只 clone `hidden_states`。写入前 view 成 `(-1, hidden)`。捕获不得改变最终 Thinker 输出。
- 禁止:只复制 update 张量;把无 residual 的 embedding clone 和有 residual 的层当成同一公式;用捕获开关改变主 forward 数值。
- 验收:单 PP rank 上用会拆开 hidden/residual 的层断言捕获值等于逻辑状态(无 residual 为输入,下一层为 hidden+residual),且开启捕获后的最终输出与不捕获一致。^[PR #7304]
Loading