diff --git a/README.md b/README.md index d764a4c..64fd7e9 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,12 @@ Agent 按该入口已有的目录地图和落盘规范,自行选择 owner、 ## 默认 MCP 工具 -- `review(target, repo?, mode?, post?)`:Direct 返回审查知识入口、首轮简明 - checklist、60 秒宿主对话进度合同和单评论完成门禁;显式指定 +- `review(target, repo?, mode?, post?, title?, body?, changed_files?)`:Direct + 在宿主先固定快照并发出进度后,按 PR title/body 直接返回至多 3 个精确 + `knowledge_routes`,每项内嵌裁剪后的 `quick_map`;changed files 只校验 + 范围,不再打开整篇规则或从 `AGENTS.md`、索引和 catalog 逐层导航。它同时 + 返回按 docs/code 区分的命令与验证预算、首轮简明 checklist、60 秒宿主对话进度合同 + 和单评论完成门禁;显式指定 `mode="strict"` 时运行旧 Eco 审查工作流。进度只显示在当前对话,不会发布 GitHub 初稿评论。 - `validate_direct_review(subtraction_signal, subtraction?, minimality_proof?, @@ -129,7 +133,7 @@ Agent 按该入口已有的目录地图和落盘规范,自行选择 owner、 | 模式 | 适合场景 | 说明 | |---|---|---| -| Direct(默认) | 日常 PR 和本地审查 | Agent 自己完成一次审查;MCP 提供知识入口、首轮 checklist 和触发式减法检查 | +| Direct(默认) | 日常 PR 和本地审查 | Agent 先报告固定快照状态,再只读 title/body 命中的精确规则,随后并行审查源码和验证;MCP 提供首轮 checklist 和触发式减法检查 | | Strict | 需要旧版完整审查工作流 | Strict 只是旧 Eco 的新名称,继续使用原 playbook、模型和运行状态 | | Autonomous | 需要独立执行器 | 使用单独配置的模型和工作流 | diff --git a/doc/EXTENDING-KNOWLEDGE.md b/doc/EXTENDING-KNOWLEDGE.md index 1353b52..fef41cd 100644 --- a/doc/EXTENDING-KNOWLEDGE.md +++ b/doc/EXTENDING-KNOWLEDGE.md @@ -69,7 +69,7 @@ symptom appeared. |---|---|---| | A rule that must change the **next** run (trigger → do → don't → how to verify) | `rules.md` in the nearest owner dir | The default product of a retrospective. Always-on (see §2) — keep it tight. | | A **stable** data-flow / responsibility / boundary description | `architecture.md` | No title-only stubs. | -| A longer method that isn't a hard gate | a page in `guides/` | Pulled on demand, so depth is welcome here. | +| A longer method that isn't a hard gate | a feature page in the owner root; work-topic collections may use `guides/` | Component/model owners stay flat; all deeper pages are pulled on demand. | | **Complex reproducible history** a rule can't carry | `incidents/YYYY-MM-DD-short-name.md` | Optional. Only when the repro chain / evidence still has independent lookup value. | **Retrospective rule of thumb:** the default output of "复盘 / record a lesson" is a @@ -88,8 +88,8 @@ Wiring lives in `src/infermatrix_copilot/engine/agent_runtime/knowledge.py` + - the adapter's `briefing_docs` — for vllm-omni: `repos/vllm-omni/rules.md` + `repos/vllm-omni/_index.md`; - `performance_briefing_docs` for strong models (compact review patterns). -- **On demand** — the `doc_search` / `doc_read` tools reach every deeper `guides/`, - `incidents/`, `components/`, and `models/` page in `general/` **plus the active +- **On demand** — the `doc_search` / `doc_read` tools recursively reach every + deeper Markdown page in `general/` **plus the active adapter's `repo_subdir` only** (other repos' slices are refused; path traversal is blocked; `doc_read` windows 24k chars and pages with an offset). - **MCP** — the same repo-scoped `doc_search` / `doc_read` are exposed read-only @@ -97,7 +97,7 @@ Wiring lives in `src/infermatrix_copilot/engine/agent_runtime/knowledge.py` + **Practical implication for authors:** `rules.md` and `_index.md` are *budget* — they load on every task. Keep them to triggers + gates + navigation. Push -narrative, long repros, and step-by-step method into `guides/` / `incidents/`, +narrative, long repros, and step-by-step method into on-demand feature pages or `incidents/`, which are pulled only when a run actually needs them. To register a **new repo's** slice, point its adapter manifest at it @@ -213,7 +213,7 @@ sources: [] | 用户提到 | 必读 | 硬约束 | |---|---|---| -| | [](guides/.md) | | +| | [](.md) | | ## 规则(每条给稳定 ID) @@ -262,7 +262,7 @@ Model variant (same frontmatter, `type: architecture`): ## 怎样验证功能、精度和性能 ``` -### 3.6 An ordinary `guides/` page +### 3.6 An ordinary method page ```markdown --- @@ -286,7 +286,9 @@ sources: [] - ``` -Then add a row for it in the sibling `guides/_index.md`. +For a component/model, put the page directly in the owner root and link it from +the owner's `_index.md`. Work-topic collections may place it in `guides/` and +register it in `guides/_index.md`. ### 3.7 An `incidents/` page (validator-checked fields) diff --git a/doc/KNOWLEDGE.md b/doc/KNOWLEDGE.md index 3c6bb3b..2d66647 100644 --- a/doc/KNOWLEDGE.md +++ b/doc/KNOWLEDGE.md @@ -65,8 +65,8 @@ capabilities, push policy) is human-authored and stays — the code depends on i - **Briefing (always-on):** the general slice `settings.knowledge_general_docs` + the adapter's repo-specific `briefing_docs` (`repos//rules.md` + `_index.md`), each capped. -- **On demand:** the cross-platform `doc_search` / `doc_read` tools reach every - deeper guide, incident, component, and model page in the shared `general/` +- **On demand:** the cross-platform `doc_search` / `doc_read` tools recursively + reach every deeper Markdown page in the shared `general/` slice plus the active adapter's `knowledge.repo_subdir`. Other repos' slices are refused. Search is implemented in Python (no host `grep` dependency), and title/frontmatter/heading hits rank first. @@ -82,12 +82,13 @@ capabilities, push policy) is human-authored and stays — the code depends on i Edit `knowledge/` in place like any other tracked content; every change goes through normal PR review plus the tree's own gates: -1. Read `doc/PLAN-knowledge-reorg.md`, `knowledge/CONTRIBUTING.md`, and exactly - one linked contribution topic. Preserve the plan's owner-scoped inventory, - union-first curation, and raw/synthesized split. -2. Route content by role and owner: rules for auditable invariants, guides for - procedures, architecture for stable boundaries, and the existing raw layer - for complex evidence. Do not create a catch-all review page. +1. Read `knowledge/CONTRIBUTING.md`, `knowledge/SCHEMA.md`, and exactly one + linked contribution topic. The reorganization plan is historical, not an + active directory contract. +2. Route content by role and owner: rules for auditable invariants, direct + feature pages for component/model procedures, architecture for stable + boundaries, and the existing raw layer for complex evidence. Do not create + a catch-all review page or a `guides/` layer under a source owner. 3. Treat `knowledge/SCHEMA.md` only as an additive metadata overlay. Evaluation cases, hidden labels, predictions, judgments, and generated reports stay in `eval/` and outside always-on briefing documents. diff --git a/doc/PLAN-knowledge-reorg.md b/doc/PLAN-knowledge-reorg.md index 5e30102..b77a0e9 100644 --- a/doc/PLAN-knowledge-reorg.md +++ b/doc/PLAN-knowledge-reorg.md @@ -1,5 +1,9 @@ # Knowledge reorganization v2 — vendored, code-mirrored, detail-preserving +> Historical migration plan. Its `_archive/`-never-delete rule is superseded by +> `knowledge/SCHEMA.md`: merge unique live content into the surviving owner, +> delete the duplicate, and use Git history for recovery. + ## Context The copilot's knowledge base is currently a git submodule `knowledge/` = `zuiho-kai/claude-workflow-starter` @ `f2dc824`, consumed unmodified. The author has **authorized copying the content** into this repo, so the submodule indirection (and everything it forced: upstream PRs, pin bumps, lockstep commits, cryptographic authorization) is dropped. The tree becomes ordinary tracked files we edit directly, delivered as normal copilot PRs. diff --git a/doc/knowledge-templates/README.md b/doc/knowledge-templates/README.md index 575b783..a56ce36 100644 --- a/doc/knowledge-templates/README.md +++ b/doc/knowledge-templates/README.md @@ -17,7 +17,7 @@ comment, register the page in the nearest `_index.md`, then validate. | [`rules.md`](rules.md) | an always-on gate page | nearest owner dir | | [`architecture-component.md`](architecture-component.md) | a shared-module architecture page | `repos//components//architecture.md` | | [`architecture-model.md`](architecture-model.md) | a model architecture page | `repos//models//architecture.md` | -| [`guide.md`](guide.md) | a method/how-to page | a `guides/` dir | +| [`guide.md`](guide.md) | a method/how-to page | component/model owner root; work-topic collections may use `guides/` | | [`incident.md`](incident.md) | a retro / historical write-up | an `incidents/` dir — **rename to `YYYY-MM-DD-short-name.md`** | ## Copy + register + validate diff --git a/doc/knowledge-templates/guide.md b/doc/knowledge-templates/guide.md index b7a1433..6375859 100644 --- a/doc/knowledge-templates/guide.md +++ b/doc/knowledge-templates/guide.md @@ -1,6 +1,6 @@ - + --- title: "" created: diff --git a/doc/knowledge-templates/rules.md b/doc/knowledge-templates/rules.md index b3ba7ee..2cfe07b 100644 --- a/doc/knowledge-templates/rules.md +++ b/doc/knowledge-templates/rules.md @@ -18,7 +18,7 @@ sources: [] | 用户提到 | 必读 | 硬约束 | |---|---|---| -| | [](guides/.md) | | +| | [](.md) | | ## 规则 diff --git a/docs/codex/README.md b/docs/codex/README.md index c40c409..b202794 100644 --- a/docs/codex/README.md +++ b/docs/codex/README.md @@ -32,9 +32,17 @@ The plugin also adds the `imreview` skill, so the short form is: Codex calls `review`, receives the local `knowledge/AGENTS.md` path plus a compact first-review checklist, and follows that document's routing map itself. The MCP does not guess which owner applies and does not inject complete rule -pages. Within 60 seconds, Codex reports the pinned head SHA, current CI, -mergeability, and preliminary findings in the host conversation, then continues -the same review without posting an interim GitHub comment. Before the only final review comment, Codex calls +pages. After pinning the snapshot, Codex immediately reports the pinned head SHA, +current CI, mergeability, and preliminary findings in the host conversation. +It does this before reading knowledge, searching source, or running tests and +does not wait for CI completion or resolved mergeability. Codex then calls +Direct once with the collected title, body, and changed files, uses the embedded +`quick_map` in each exact route without opening the full rule page, and runs +knowledge/source and validation tracks concurrently. It reuses one in-review +evidence packet and runs an import/version +compatibility preflight before pytest. Validation results are bound to the head +SHA and an environment fingerprint. The progress update is not an interim +GitHub comment. Before the only final review comment, Codex calls `validate_direct_review`. A normal small fix uses `subtraction_signal="none"` without a minimality proof. Only a diff that adds or expands a helper, class, fallback, compatibility branch, or public behavior uses `"triggered"` and @@ -45,7 +53,31 @@ The tool response is intentionally small: ```json { "mode": "direct", - "knowledge_entry": "C:\\...\\InferMatrixCopilot\\knowledge\\AGENTS.md", + "knowledge_entry": "C:\\...\\knowledge\\repos\\vllm-omni\\components\\serving\\rules.md", + "knowledge_routes": [ + { + "owner": "serving", + "path": "C:\\...\\knowledge\\repos\\vllm-omni\\components\\serving\\rules.md", + "reason": "title/body: endpoint, request", + "quick_map": "## Direct 代码快速入口\n...", + "read_required": false + } + ], + "navigation_policy": { + "progress_before_knowledge": true, + "use_embedded_quick_maps": true, + "open_route_file_only_for_concrete_ambiguity": true, + "max_routes": 3, + "stop_after_routes": true + }, + "execution_budget": { + "profile": "code", + "knowledge_file_reads": 0, + "validation_commands": 4, + "total_command_calls": 20, + "hard_ceiling": true, + "extension_command_calls": 4 + }, "first_review_checklist": ["...", "Run subtraction only when the diff has a subtraction signal ..."], "progress_update": { "deadline_seconds": 60, @@ -92,9 +124,14 @@ confirm that `infermatrix-copilot` is connected. ## What the default MCP exposes -- `review(target, repo?, mode="direct", post=false)`: Direct ignores `repo` - and returns `knowledge/AGENTS.md`, the first-review checklist, the 60-second - host-conversation update contract, and the single-comment completion contract. +- `review(target, repo?, mode="direct", post=false, title="", body="", + changed_files=[])`: after the host progress update, Direct uses title/body to + return at most three exact owner/model routes with compact embedded + `quick_map` excerpts. Changed files only validate scope. The host does not + open full rule files unless a concrete ambiguity blocks source review and + treats the returned docs/code `execution_budget` as a hard ceiling. A single + bounded extension is reserved for one stated unresolved P1/high-risk + contract. Strict maps to the previous Eco workflow. - `validate_direct_review(subtraction_signal, subtraction?, minimality_proof?, final_comment_count=1)`: `none` completes an ordinary small fix without a @@ -108,9 +145,10 @@ confirm that `infermatrix-copilot` is connected. - `doc_search(query, repo?)`: finds deeper model/component rules. - `doc_read(path, repo?)`: reads a selected knowledge page. -Direct mode does not run another model, choose a knowledge owner, edit knowledge -inside the MCP, post comments, or push code. The completion validator checks -review structure; Codex still owns the truth of the cited code evidence. +Direct mode does not run another model, edit knowledge, post comments, or push +code. Its deterministic router selects bounded knowledge owners from the PR +description; Codex still owns scope validation and the truth of cited code +evidence. The completion validator checks review structure. ## Optional autonomous BYOK workflow diff --git a/docs/knowledge-maintainer.zh-CN.md b/docs/knowledge-maintainer.zh-CN.md index cc42441..542966b 100644 --- a/docs/knowledge-maintainer.zh-CN.md +++ b/docs/knowledge-maintainer.zh-CN.md @@ -131,7 +131,9 @@ 2. 创建 `_index.md`,写清源码路径、职责边界、测试入口和依赖关系。 3. 有稳定架构信息时创建 `architecture.md`。 4. 第一条真实规则出现时才创建 `rules.md`,不要提交空页面。 -5. 在父级 `components/_index.md` 或 `models/_index.md` 增加入口。 +5. 新增 component 时在 `components/_index.md` 增加入口;新增 model 时不用维护 + 父级长表,目录会由 `models/` 文件系统清单自动发现。新增别名或 registry key + 时才更新 `models/catalog.md`。 模块与模型的区别: diff --git a/docs/samples/add-new-model-owner.zh-CN.md b/docs/samples/add-new-model-owner.zh-CN.md index 1f20986..de8ae91 100644 --- a/docs/samples/add-new-model-owner.zh-CN.md +++ b/docs/samples/add-new-model-owner.zh-CN.md @@ -101,12 +101,14 @@ sources: [<源码路径、设计文档或 PR URL>] - 验收:<可检查的完成标准> ^[] ``` -## 文件 4:登记模型入口 +## 文件 4:需要别名时才更新 catalog -在 `knowledge/repos/vllm-omni/models/_index.md` 的模型表格增加: +`models/` 目录本身就是模型清单,不修改父级 `_index.md`。只有正式名称之外还需要 +别名或 registry key 路由时,才在 +`knowledge/repos/vllm-omni/models/catalog.md` 增加对应关系。 ```markdown -| <模型正式名称和常见别名> | [<模型正式名称>](/_index.md) | <一句话适用范围> | +| <别名或 registry key> | | <源码目录或定位信号> | ``` ## 提交前复制 diff --git a/integrations/cursor/imreview.md b/integrations/cursor/imreview.md index 83803b6..a325ae7 100644 --- a/integrations/cursor/imreview.md +++ b/integrations/cursor/imreview.md @@ -1,14 +1,39 @@ Use the InferMatrixCopilot MCP server to review the target supplied with this command. If no target is supplied, review the current PR or working tree. -Call `review` with `mode="direct"`, read the returned `knowledge_entry`, follow -its routing instructions, inspect the live target, and return only -evidence-backed findings with file and line references. +First pin one snapshot and collect title, body, changed files, head SHA, CI, and +mergeability. Immediately report the pinned head SHA, current CI status, +mergeability, and any early findings in the host conversation before reading +knowledge, searching source, or running tests. Within 60 seconds, do this. Then +call `review` once with +`mode="direct"` plus `title`, `body`, and `changed_files`. Use the embedded +`quick_map` in each returned `knowledge_routes` item. Do not open the full route +file unless a concrete ambiguity blocks source review, and do not walk +`AGENTS.md`, `CLAUDE.md`, repository indexes, or model catalogs. Inspect the +live target and return only evidence-backed findings with file and line +references. +Follow the returned `execution_budget`. Extend it once only when a concrete +unresolved P1/high-risk contract remains, and state that question before +extending. -Within 60 seconds, first update the host conversation with the pinned head SHA, -current CI status, mergeability, and any early findings. Mark early findings as -preliminary and continue the review. This update is not a GitHub comment; do not -post an interim review. +After the progress update, run independent knowledge/source and validation +tracks concurrently. Keep one in-review evidence packet and reuse +files, bounded `rg` searches, callers, tests, repo-map, routing, and findings. +Treat CI as status unless its first failure overlaps the frozen diff or blocks +the verdict; do not open unrelated CI logs. For docs-only changes, skip the +dependency preflight and pytest, and use diff hygiene plus bounded checks of the +referenced live contract. +Before pytest, run a short import/version compatibility preflight. Bind every +validation command and result to the head SHA and an environment fingerprint; +reuse an environment only when its dependency fingerprint matches. After the +preflight passes, run targeted tests and low-cost static checks alongside the +source review. +Stop when every changed semantic path has a supported finding or an explicit +no-issue conclusion; do not add searches only for confidence. + +Do not wait for CI completion or resolved mergeability before the progress +update. Mark early findings as preliminary and continue the review. This update +is not a GitHub comment; do not post an interim review. Before finalizing, classify `subtraction_signal`. Use `none` without a minimality proof when the diff does not add or expand a helper, class, fallback, diff --git a/knowledge/AGENTS.md b/knowledge/AGENTS.md index 387bf8a..c4aa617 100644 --- a/knowledge/AGENTS.md +++ b/knowledge/AGENTS.md @@ -13,8 +13,10 @@ Before adding or moving knowledge, read the short `CONTRIBUTING.md` entry and on Before committing or pushing, follow the target repository's own Git and identity rules. Do not inherit a commit identity, SSH host, remote, DCO requirement, or PR format from an unrelated repository entry. -Any PR review, including a request containing only a PR link, must follow the single-review Direct routing in `CLAUDE.md`. The host review resolves the pinned diff once, selects exact owner/model rule groups from the PR title and body, and reuses one evidence packet for correctness and design/subtraction checks. Do not start a second generic review or publish separate review comments. A bounded specialist is allowed only for a novel, contradictory, or still-uncovered high-risk contract; it extends the same evidence packet and returns to the host for one consolidated comment. +Any PR review, including a request containing only a PR link, must follow the single-review Direct routing in `CLAUDE.md`. The host resolves the pinned diff and metadata once, reports snapshot status before reading knowledge, then passes title/body/changed files to Direct and uses only the compact `quick_map` embedded in each returned exact owner/model route. Open a full route file only when one concrete ambiguity blocks source review, and follow the returned docs/code `execution_budget`; extend it once only for a stated unresolved P1/high-risk contract. Do not reopen this file, `CLAUDE.md`, repo indexes, or model catalogs after exact routes are returned. Reuse one evidence packet for correctness and design/subtraction checks. Do not start a second generic review or publish separate review comments. A bounded specialist is allowed only for a novel, contradictory, or still-uncovered high-risk contract; it extends the same evidence packet and returns to the host for one consolidated comment. -Within 60 seconds of starting a Direct review, update the host conversation with the pinned head SHA, current CI status, mergeability, and any early findings. Mark early findings as preliminary, continue the same review, and do not publish this progress update as a GitHub comment. +After pinning the snapshot, finish the first host progress update before starting knowledge/source and validation tracks. Then run those independent tracks concurrently. Reuse one in-review packet for files, bounded `rg` searches, callers, tests, repo-map, routing, and findings. Before pytest, run a short import/version compatibility preflight; bind validation evidence to the head SHA and an environment fingerprint, and reuse an environment only when its dependency fingerprint matches. + +Within 60 seconds of starting a Direct review, update the host conversation with the pinned head SHA, current CI status, mergeability, and any early findings. Emit this immediately after snapshot metadata returns and before knowledge reads, source searches, or tests; do not wait for CI completion or resolved mergeability. Mark early findings as preliminary, continue the same review, and do not publish this progress update as a GitHub comment. When the Direct MCP exposes `validate_direct_review`, call it before treating the review as complete or publishing the only final comment. Mark `subtraction_signal=none` when the diff does not add or expand a helper, class, fallback, compatibility branch, or public behavior; this needs no minimality proof. Mark `subtraction_signal=triggered` for those changes and then supply concrete subtraction items or a minimality proof. If it returns `partial_review`, reuse the existing evidence packet; do not invent deletion work just to satisfy the gate. diff --git a/knowledge/CLAUDE.md b/knowledge/CLAUDE.md index 39554aa..57df6e5 100644 --- a/knowledge/CLAUDE.md +++ b/knowledge/CLAUDE.md @@ -19,9 +19,13 @@ ### Direct PR review 单次路由 -默认 Direct review 只执行一篇 Codex 审查。先固定 base/head,再一次性获取 PR title/body、changed files、diff、mergeability 和 CI;用 title/body 的声明目标选择精确 owner/model 规则组和第一批源码函数,changed files 只校验并补全真实范围。把已读文件、caller 搜索、测试结果和 findings 放进同一份证据包,correctness 与 design/subtraction 在这次审查中共用,不能各自重新导航或重复采集。 +默认 Direct review 只执行一篇 Codex 审查。先固定 base/head,再一次性获取 PR title/body、changed files、diff、mergeability 和 CI;元数据返回后先在宿主对话发进度,再把 title/body/changed files 一次传给 Direct。使用返回的至多 3 个精确 owner/model `knowledge_routes` 内嵌 `quick_map`,随后停止知识导航;只有一个具体歧义阻塞源码审查时才打开对应完整规则文件,不得再从 `AGENTS.md`、本页、repo index 或 model catalog 逐层展开。执行返回的 docs/code `execution_budget`;只有明确未解决的 P1/高风险合同可追加一次有界调查。changed files 只校验并补全真实范围。把已读文件、caller 搜索、测试结果和 findings 放进同一份证据包,correctness 与 design/subtraction 在这次审查中共用,不能各自重新导航或重复采集。 -审查开始后 60 秒内,先在宿主对话中报告固定的 head SHA、当前 CI、可合并性和已有早期 finding;早期 finding 明确标记为“初步”,然后继续同一次审查。没有早期 finding 就明确写“暂未发现”,不能为了进度硬凑问题。该状态不是 GitHub 评论,不发布“初稿评论”。 +固定快照后先完成状态轨并发出宿主进度;不要让知识读取、源码搜索或测试挡住这条消息。随后知识/源码轨与验证轨并行:前者只读 Direct 返回的精确规则和命中源码,后者先做简短 import/version 兼容性预检,通过后运行目标测试与低成本静态检查。全程只维护当前审查的一份证据包,复用文件、限定目录/glob/输出量的 `rg`、caller、测试、repo-map、知识路由和 findings;不为 Direct 新建持久缓存或调度服务。 + +每条验证命令和结果绑定当前 head SHA,并记录依赖锁摘要、Python 和平台组成的环境指纹。只有依赖指纹匹配才复用现有环境;head 变化时旧测试结果失效,但依赖未变化不重复建环境。预检失败时报告真实缺口,不运行或声称 pytest 已验证。 + +审查开始后 60 秒内,元数据一返回就先在宿主对话中报告固定的 head SHA、当前 CI、可合并性和已有早期 finding;不要等待 CI 完成或可合并性从 unknown 变为确定,也不要先读知识、搜源码或跑测试。早期 finding 明确标记为“初步”,然后继续同一次审查。没有早期 finding 就明确写“暂未发现”,不能为了进度硬凑问题。该状态不是 GitHub 评论,不发布“初稿评论”。 减法检查先看信号:只有 diff 新增或扩张 helper、class、fallback、兼容分支或公共行为时才标记 `triggered`,并完成有界减法检查。普通小修直接标记 `none`,不写 scope ledger、abstraction census 或完整最小性证明。不能为了通过门禁硬凑减法。 @@ -74,7 +78,7 @@ |---|---|---| | 写代码或修改公开接口 | [code taste](general/review/guides/code-taste.md) | 先理解现有 owner、调用链、测试和用户可见行为 | | 开发完成、准备交给 reviewer 或项目 owner | [维护者审查闭环](general/agents/guides/agent-loop-workflow.md#开发交付的维护者审查闭环) | 先确认唯一审查负责人;被委派的开发默认交回父 agent 统一 review,不嵌套重复审查 | -| code review、reviewer follow-up,或用户只给 PR 链接让你“审核一下” | [独立审查执行合同](general/review/guides/review-execution-contract.md) | 一次 Direct 审查复用同一份路由与证据,同时完成 correctness 和 design/subtraction;只在未覆盖的高风险合同上做专项追问,最终只发一篇评论 | +| code review、reviewer follow-up,或用户只给 PR 链接让你“审核一下” | [独立审查执行合同](general/review/guides/review-execution-contract.md) | 一次 Direct 审查并行获取状态、源码和验证证据;correctness 必查,减法按信号触发;最终只发一篇评论 | | UI、CLI、文档或其他用户可见改动 | [用户可见验收](general/docs/guides/user-visible-acceptance.md) | 绿测之外还要跑普通用户真实路径 | | benchmark 或性能结论 | [benchmark contract](general/benchmark/guides/benchmark-contract.md) | 先固定版本、工作负载、指标和证据来源 | | SSH、容器、远端服务或长跑 | [远端入口](general/remote/_index.md) | 先验证目标、环境、超时、状态文件和清理边界 | diff --git a/knowledge/README.md b/knowledge/README.md index 35bad5a..cd9a4da 100644 --- a/knowledge/README.md +++ b/knowledge/README.md @@ -1,147 +1,58 @@ -# Workflow Starter +# Knowledge -这是一套可以直接用 Markdown 手工维护的项目知识框架。它把跨仓库通用方法、仓库专有规则、代码模块、模型和可选历史案例放在一棵目录树中,避免每次任务把无关内容全部加载。 +这里存放可复用规则,不是需要整棵读取的文档站。 -## 开始使用 +## 默认入口 -```bash -git clone https://github.com/zuiho-kai/claude-workflow-starter.git -cd claude-workflow-starter -``` - -如果还需要项目代码,可以把目标仓库克隆到旁边或按自己的 worktree 规则管理。知识仓库用 `repos/<仓库>/` 表示经验归属,不要求把项目代码塞进这个目录。 - -## 在其他仓库接入 - -推荐把框架入口放到目标仓库根目录,这样 agent 会自动发现 `AGENTS.md`,人类也能从 README 进入。如果只把本项目放在目标仓库旁边,目标仓库自己的 `AGENTS.md` 必须显式要求读取这个知识仓库;否则两边不会自动关联。 - -最短接入流程: - -1. 把 `AGENTS.md`、`CLAUDE.md`、`README.md`、`CONTRIBUTING.md`、`contributing/`、`general/` 和 `tools/check_knowledge_tree.py` 复制或合并到目标仓库根目录。已有同名规则时先合并,不要直接覆盖。 -2. 在目标仓库的 `.gitignore` 中加入 `local/`;机器地址、账号、cache 和 venv 只写 `local/`。 -3. 新建 `repos/_index.md` 和 `repos/<你的仓库>/_index.md`。如果 fork 了本仓,删除与你无关的 `repos/vllm-omni/`、`repos/jianghan-roleplay-data-pipeline/`,并同步 `repos/_index.md`。 -4. 只有该仓库确实有每次开工都必须执行的专属门禁时,才新建 `repos/<你的仓库>/rules.md`,并从仓库 `_index.md` 链接它。 -5. 按实际需要增加主题、`components/<模块>/`、`models/<模型>/` 和规则;只有复杂历史证据需要长期保留时才增加 `incidents/`,不要预建空目录。 -6. 运行 `python tools/check_knowledge_tree.py`,确认索引、链接和目录结构完整。 - -根 `AGENTS.md` 和 `CLAUDE.md` 必须保持仓库中性。模型、GPU、工作目录、Git 身份、专用 remote 和 PR 格式等规则只能放到对应 `repos/<仓库>/` 或 ignored `local/`,不能重新堆回根入口。 - -## 从哪里查 - -- [通用经验](general/_index.md):review、CI、docs、Git、debug、benchmark、环境、远端、agent 和规划。 -- [仓库经验](repos/_index.md):从仓库列表进入当前实际保留的仓库、代码模块和模型;第三方接入后以自己的列表为准。 -- [贡献与目录维护](CONTRIBUTING.md):短入口会按任务带你进入归属、页面、复盘、拆分或校验规范,不要求整套通读。 - -### 按任务找入口 - -| 你正在做什么 | 先看通用入口 | 识别仓库后必须检查 | +| 任务 | 入口 | 什么时候停止 | |---|---|---| -| code review 和 reviewer follow-up | [review](general/review/_index.md) | `repos/<仓库>/review/` | -| 测试和 CI | [ci](general/ci/_index.md) | `repos/<仓库>/ci/` | -| 文档、RFC 和公开说明 | [docs](general/docs/_index.md) | `repos/<仓库>/docs/` | -| Git、commit、rebase 和 PR | [git](general/git/_index.md) | `repos/<仓库>/git/` | -| 调试和根因收敛 | [debug](general/debug/_index.md) | `repos/<仓库>/debug/` | -| benchmark 和性能证据 | [benchmark](general/benchmark/_index.md) | `repos/<仓库>/benchmark/` | -| Windows、WSL 和本地环境 | [environment](general/environment/_index.md) | 通常不需要仓库补充 | -| SSH、容器、GPU 和远端任务 | [remote](general/remote/_index.md) | `repos/<仓库>/remote/` | -| 多 agent 分工 | [agents](general/agents/_index.md) | 通常不需要仓库补充 | -| 需求拆分和执行计划 | [planning](general/planning/_index.md) | 仓库入口中的业务主题 | - -实际顺序以 `CLAUDE.md` 的场景触发器为准:直接命中具体 guide 时跳过通用主题索引。只有 canonical `repos//` 未经验证时才用 [仓库列表](repos/_index.md) 把 upstream、URL、显示名或本地目录映射到 slug;不凭名字猜目录。随后先读当前仓库 `rules.md`,规则精确命中 owner 就停止导航;未命中才读仓库 `_index.md`、一个由任务目的选中的仓库主题,再从 `components/_index.md` 或 `models/_index.md` 选择主要 owner。读完 owner 已有规则后停止横向展开,只有 live 调用链证明跨模块时才打开第二个目录。 +| PR review | Direct 根据 PR title/body 返回精确 owner/model `quick_map` | 路由返回后停止知识导航 | +| 通用方法 | [general](general/_index.md) | 命中一个当前任务 guide 后停止 | +| 仓库规则和代码地图 | [repos](repos/_index.md) | 命中主要 owner 后停止横向展开 | +| 写入或整理知识 | [CONTRIBUTING](CONTRIBUTING.md) | 选择最近 owner 后再写 | -已有完整日志和可读源码的窄 bug 例外:先按仓库规则完成诊断路由和首次根因,真正编辑前再读 code taste。 +vLLM-Omni 的直接入口是 +[仓库地图](repos/vllm-omni/_index.md)。已知 owner 时不要从根目录逐层点击: -路由时先只读索引和命中的规则,写出用户入口、主要 owner 和准备核对的源码边界;具体 guide 在 owner 确定后按需读取,一次不要预加载多篇方法正文。 +- 配置:[`components/configuration/rules.md`](repos/vllm-omni/components/configuration/rules.md) +- 在线服务:[`components/serving/rules.md`](repos/vllm-omni/components/serving/rules.md) +- 模型执行:[`components/model-executor/rules.md`](repos/vllm-omni/components/model-executor/rules.md) +- Diffusion:[`components/diffusion/rules.md`](repos/vllm-omni/components/diffusion/rules.md) +- 调度:[`components/scheduler/rules.md`](repos/vllm-omni/components/scheduler/rules.md) +- 模型专属:直接查看 [`models/`](repos/vllm-omni/models/_index.md) 下对应目录 -不知道归属时,可以先全文搜索: - -```powershell -rg "SSH timeout|shape mismatch" general repos -g "*.md" -``` - -## 目录怎样理解 +## 目录分层 ```text -general/<主题>/ # 换仓库仍然成立 -repos/<仓库>/<主题>/ # 某仓库专有流程 -repos/<仓库>/components/<代码模块>/ # 前端、后端、diffusion 等共享代码 -repos/<仓库>/models/<模型>/ # 模型专有实现和配置 -<最近目录>/incidents/ # 可选的复杂历史证据,不是默认规则入口 -local/ # 当前机器信息,Git 忽略 +general/ 跨仓库方法 +repos//rules.md 仓库硬规则 +repos//components// 共享代码 owner +repos//models// 模型 owner +repos/// CI、benchmark、Git 等工作主题 +contributing/ 知识维护规范 ``` -每个正式目录都有 `_index.md`,说明什么时候查、什么不放这里,以及每个页面的入口。普通维护者不需要编辑 YAML 或修改检查脚本。 - -## 新增普通经验 - -1. 判断内容属于通用主题、仓库、代码模块还是模型。 -2. 在最接近的目录中新建 Markdown。 -3. 在同目录 `_index.md` 增加一行“遇到什么 → 查看哪里”。 -4. 运行: +下面这些不是默认知识入口: - ```powershell - python tools/check_knowledge_tree.py - ``` +- `incidents/`、`history/`、`results/`:历史证据,只在规则指向或问题高度相似时查; +- `skills/`、`.claude/`:运行扩展; +- `tools/`:校验和维护脚本; +- 启动脚本:本地辅助材料。 -具体的 `_index.md` 写法和目录示例见 [页面写法](contributing/page-rules.md)。也可以直接参考现有同类目录。 +## 找不到时 -## 复盘和沉淀 +先查目录名,再做一次有界搜索: -复盘的默认产物是最近 owner 的 `rules.md`。先回答为什么发生、为什么以前没发现、怎样提前阻止、怎样验收,再把可重复执行的结论写成规则。只有复现链、日志证据或历史背景很复杂,规则无法承载且以后仍可能重新取证时,才额外新增错题。 - -确实需要错题时,按根因放在最近的 `incidents/`: - -- 通用 SSH、WSL、PowerShell 或 Git 错误 → `general/<主题>/incidents/` -- 仓库 CI、benchmark、review 或 remote 错误 → `repos/<仓库>/<主题>/incidents/` -- 多模型共享代码错误 → `repos/<仓库>/components/<模块>/incidents/` -- 模型专有错误 → `repos/<仓库>/models/<模型>/incidents/` - -按已经验证的根因归属,不按用户最先看到现象的位置归属。例如前端看到 API 404,不等于根因一定在 frontend。根因未明时默认继续调查;只有用户要求保留过程记录时,才暂放仓库对应工作主题并标记“待归类”。 - -文件名使用 `YYYY-MM-DD-short-name.md`,正文按 [错题页面格式](contributing/incidents.md#正文模板) 编写。一件事故只保留一篇完整正文,并链接已经提炼的规则;正常任务仍从规则开始,不要求先找到事故文件。 - -## 内容多了怎样拆 - -- 单文件达到 300 个非空行或 16 KiB:检查是否已经混入多个主题。 -- 单文件达到 500 个非空行或 32 KiB:必须拆分,或在 `_index.md` 写明暂不拆的原因和复核日期。 -- 一个目录直接放到第 8 个普通页面:按 `guides/`、`incidents/` 或明确业务主题分类。 -- 一个分类目录超过 20 篇当前有效页面:继续按稳定问题主题分类。 - -检查工具只报告可以机械判断的问题,不会生成目录、静默决定语义归属或在后台移动文件。 - -## 当前机器信息 - -真实服务器地址、账号、token、私钥、cache 和 venv 路径只放 Git 忽略的 `local/`。需要时直接创建 `local/remote.md`,按机器或完整 `user@host:port` 分段记录;该文件不能被 Git 跟踪。 +```powershell +Get-ChildItem repos/vllm-omni/models -Directory +rg -n "关键词" repos/vllm-omni/components repos/vllm-omni/models -g "*.md" +``` -正式知识页面不得包含私人 host、凭据或用户绝对路径。去除敏感信息后仍有复用价值的教训,再写入 `general/` 或 `repos/`。 +不要默认递归读取所有 `_index.md`、事故记录或同级 owner。 -## 自动检查 +## 校验 ```powershell python tools/check_knowledge_tree.py +python tools/check_wiki_lint.py ``` - -它会检查: - -- 每个目录是否有 `_index.md`; -- 页面和子目录是否登记到最近索引; -- 相对链接是否存在; -- 错题的文件名、编号、归属、状态和入口是否完整; -- 文件和目录是否超过拆分限制; -- `local/` 是否意外进入 Git。 - -脚本不会判断两篇文章是否语义重复,也不会替人决定问题属于哪个代码模块或模型。 - -## 主要入口 - -| 内容 | 路径 | -|---|---| -| 开工硬规则 | `CLAUDE.md` | -| 通用经验 | `general/` | -| 仓库、代码模块、模型和错题 | `repos/` | -| 当前机器信息 | `local/`(Git ignored) | -| 贡献与目录维护 | `CONTRIBUTING.md` | -| 贡献专题规范 | `contributing/` | -| 索引检查 | `tools/check_knowledge_tree.py` | - -框架目标只有一个:让人和 agent 都能沿清晰入口找到需要的最少内容,并且让新经验在下一次任务中真正可查。 diff --git a/knowledge/SCHEMA.md b/knowledge/SCHEMA.md index 8561cdb..d8aa866 100644 --- a/knowledge/SCHEMA.md +++ b/knowledge/SCHEMA.md @@ -1,6 +1,6 @@ # SCHEMA — 页面元数据与生命周期 -规定 `general/` 与 `repos/` 下**沉淀层**页面的 YAML frontmatter、标签分类法和归档 +规定 `general/` 与 `repos/` 下**沉淀层**页面的 YAML frontmatter、标签分类法和生命周期 规则(LLMWiki 机制)。目录归属与页面写法仍以 [贡献规范](contributing/_index.md) 为准;本文件只补充元数据机制,不重复目录规范。`repos/jianghan-roleplay-data-pipeline/` 整棵子树暂不适用(保持原样)。 @@ -47,10 +47,10 @@ contradictions: [相对路径] # 可选:与本页冲突的页面 页面级证据在 frontmatter `sources:` 列出。每个沉淀层页面至少链接 2 个相关页面 (相对 Markdown 链接,不用 wikilink)。 -## 归档(永不删除) +## 被取代页面 -被取代或重复的页面移入根 `_archive/<原路径>`:从所在 `_index.md` 注销、入链标注 -"(已归档)"、幸存页面链接归档页。`_archive/` 不参与索引/链接校验。 +先把仍然有效的独有结论合入最近 owner 的幸存页面,再删除被取代或重复页面并修复 +入链。Git 历史负责追溯旧版本;`knowledge/` 内不再维护 `_archive/` 副本。 ## 校验 diff --git a/knowledge/_archive/repos/vllm-omni/components/config/_index.md b/knowledge/_archive/repos/vllm-omni/components/config/_index.md deleted file mode 100644 index 58a65b0..0000000 --- a/knowledge/_archive/repos/vllm-omni/components/config/_index.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "Config(pipeline 与 deploy 配置系统)" -created: 2026-07-16 -updated: 2026-07-16 -type: index -tags: [vllm-omni, components, config] -sources: [vllm_omni/config/stage_config.py, vllm_omni/config/config_factory.py, docs/configuration/stage_configs.md] ---- - -# Config(pipeline 与 deploy 配置系统) - -- 源码入口:`vllm_omni/config/`(`stage_config.py`、`config_factory.py`、 - `pipeline_registry.py`、`omni_config.py`、`endpoint_policy.py`、`server_settings.py`、 - `yaml_util.py`、`composable_parallel/`)与逐模型 deploy YAML `vllm_omni/deploy/*.yaml` -- 源码校验:以上路径与下列锚点均已在 `main @ 5c390096` 验证存在: - `build_stage_runtime_overrides`(stage_config.py:48)、`strip_parent_engine_args`(:93)、 - `resolve_deploy_yaml`(:576)、`load_deploy_config`(:602)、`merge_pipeline_deploy`(:831)、 - `StageConfigFactory`(config_factory.py:47)、`OmniServingCapability` - (endpoint_policy.py:21);`vllm_omni/deploy/` 含 58 个 YAML -- 官方配置 spec:`docs/configuration/stage_configs.md`、`composable_parallel.md`、 - `pd_disaggregation.md`、`gpu_memory_utilization.md` -- 测试入口:`tests/config/`、`tests/test_config_factory.py` - -## 什么时候查这里 - -- 排查 CLI / deploy YAML / per-stage override 的合并语义与最终生效配置。 -- 新模型接 pipeline registry、deploy YAML 或 endpoint 限制。 -- stage 显存预算(`gpu_memory_utilization`、`kv_cache_memory_bytes`)类 OOM。 - -## 不放什么 - -- runner 侧 stage 并行度与设备容量的验收规则在 - [Model Executor 规则](../model-executor/rules.md)(这里管配置语义,那里管启动验收)。 -- 配置审计的"说人话"工作法在 [dev 配置审计](../../dev/guides/config-audit-plain-language.md)。 - -## 目录内容 - -| 遇到什么 | 查看哪里 | -|---|---| -| 理解 PipelineConfig/DeployConfig 双层 schema 与解析链 | [architecture](architecture.md) | -| stage 显存预算与配置合并的硬规则 | [rules](rules.md) | diff --git a/knowledge/_archive/repos/vllm-omni/components/config/architecture.md b/knowledge/_archive/repos/vllm-omni/components/config/architecture.md deleted file mode 100644 index d741e55..0000000 --- a/knowledge/_archive/repos/vllm-omni/components/config/architecture.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: "Config 共享架构" -created: 2026-07-16 -updated: 2026-07-16 -type: architecture -tags: [vllm-omni, components, config] -sources: [docs/configuration/stage_configs.md, docs/configuration/composable_parallel.md, vllm_omni/config/stage_config.py, vllm_omni/config/config_factory.py, vllm_omni/config/omni_config.py] ---- - -# Config 共享架构 - -以下事实在 `main @ 5c390096` 复核;官方 spec 见 `docs/configuration/stage_configs.md` -(schema 全表)与 `composable_parallel.md`。 - -## 双层 schema:PipelineConfig vs deploy YAML - -- **`PipelineConfig`**(模型的冻结 stage 拓扑)由模型的 `pipeline.py` 注册; - **deploy YAML**(`vllm_omni/deploy/*.yaml`,58 个)只描述"这些 stage 怎么跑"。 - 未迁移模型仍走 legacy `--stage-configs-path` + `stage_args` schema - (`vllm_omni/model_executor/stage_configs/*.yaml`)。 -- 未显式给 `--deploy-config`/`--stage-configs-path` 时,registry 按 `model_type` - 自动解析 pipeline + bundled deploy YAML(如 `qwen2_5_omni.yaml` 在 1×H100、 - `qwen3_omni_moe.yaml` 在 2×H100 验证过)。 -- deploy 顶层字段:`base_config`(overlay 父配置,`stages:`/`platforms:` 按 stage_id - 深合并、标量 overlay 胜)、`async_chunk`(默认 true)、`connectors`/`edges`(KV - 传输图;省略时由 stage 输入自动推导)、`stages`(必填)、`platforms` - (npu/rocm/xpu 覆盖,叠在 CUDA 默认之上)、`pipeline`(覆盖 registry key,用于 - `qwen2_5_omni_thinker_only` 这类结构变体)以及 pipeline-wide 标量 - (`trust_remote_code` 默认 true、`dtype`、`quantization`、`enable_prefix_caching` - 默认 false、`data_parallel_size`/`pipeline_parallel_size` 默认 1 等)。 -- per-stage `StageDeployConfig` 字段直接平铺(无嵌套 `engine_args:`):`stage_id` - (必填,对齐 `PipelineConfig.stages[*].stage_id`)、`max_num_seqs`(默认 64)、 - `gpu_memory_utilization`(**默认 0.9**——多 stage 共卡时必须显式设,见 - [rules](rules.md) `CONF-1a`)、`tensor_parallel_size`、`enforce_eager`、 - `max_num_batched_tokens`(默认 32768)、`max_model_len`、`devices`(默认 "0")、 - `input_connectors`/`output_connectors`(`from_stage_`/`to_stage_` 键引用顶层 - `connectors:` 注册名)、`default_sampling_params`、`engine_extras`(未知键兜底, - 也承载 stage 级覆盖 pipeline-wide 值)。 - -## 解析链(函数级) - -`resolve_deploy_yaml`(stage_config.py:576,处理 base_config overlay)→ -`load_deploy_config`(:602)→ `merge_pipeline_deploy`(:831,冻结拓扑 + 部署参数 -合并,平台覆盖在此叠加)→ `build_stage_runtime_overrides`(:48,产出逐 stage -运行时 override);`strip_parent_engine_args`(:93)决定哪些父 EngineArgs 字段 -进入/剥离每个 stage(消费端在 `engine/async_omni_engine.py`)。 - -## StageConfigFactory 与 pipeline registry - -`StageConfigFactory`(config_factory.py:47)按 `model_type` 从 -`pipeline_registry.OMNI_PIPELINES`(~44 个 key)解析出 `PipelineConfig` 或 resolver -callable(如 `resolve_qwen3_omni_pipeline`);HF `model_type` 冲突用 -`hf_architectures` 消歧(如 MiMo Audio 的 HF model_type 是 qwen2);未注册模型报错 -并列出可用 key(:360)。单 stage diffusion 模型**不在**该 registry(走 -`async_omni_engine.py` 的 `_create_default_diffusion_stage_cfg` 兜底)。 -`register_pipeline(...)` 支持 out-of-tree 注册。 - -## 结构化配置与 endpoint 策略 - -- `omni_config.py`:RFC #4021 Phase 2 的结构化配置——`VllmOmniConfig.from_registry` - 组装逐 stage 投影(`OmniStageModelConfig`/`CacheConfig`/`SchedulerConfig`/ - `ConnectorConfig`/`ParallelConfig`/`DiffusionParallelConfig` 等)。 -- `endpoint_policy.py`:`OmniServingCapability`(:21,`RouteTarget` 枚举)+ - `shutdown_unsupported_routes`(:65)——pipeline 可关闭自己不支持的 serving 路由。 -- `composable_parallel/`:`--strategy-config` 把逐 stage 并行轴栈 - (tp/dp/pp/ep/stage_replica 已接线;sp/cfg/vae_pp/hsdp 等保留位)以声明式 overlay - 叠加到合并后的 stage 上、先于 CLI override;**不能**与 legacy - `--stage-configs-path` 组合。 - -源码会变化,具体函数与行号在改代码前必须以目标仓库当前版本为准。 diff --git a/knowledge/_archive/repos/vllm-omni/components/config/rules.md b/knowledge/_archive/repos/vllm-omni/components/config/rules.md deleted file mode 100644 index 4c139b4..0000000 --- a/knowledge/_archive/repos/vllm-omni/components/config/rules.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: "Config 规则" -created: 2026-07-16 -updated: 2026-07-20 -type: rule -tags: [vllm-omni, components, config] -sources: ["vllm-omni-rebase-agent@122a9468:agent/skills/fix-missing-gpu-memory-utilization-diffusion-stage/SKILL.md", "vllm-omni-rebase-agent@122a9468:agent/skills/fix-voxcpm2-l4-oom-after-rebase/SKILL.md", docs/configuration/stage_configs.md, "PR #4281", "PR #5031"] ---- - -# Config 规则 - -只有 `CONF-数字字母` 是可审计规则 ID。运营 runbook 以 rebase-agent 仓库为准, -本页是知识树沉淀快照(2026-07-16,agent @122a9468;skills 工作树含未提交遥测更新, -快照以工作树为准)。 - -## CONF-1a — 多 stage 共卡时 diffusion stage 必须显式设 gpu_memory_utilization - -skill 元数据:`fix-missing-gpu-memory-utilization-diffusion-stage`, -modules=[input_output, model_config],status=active,run_count=32, -2026-06-16 创建 / 07-11 最后使用。 - -- 触发:多 stage 模型(如 Bagel)stage 共卡时分布式测试在模型加载期 CUDA OOM, - 栈在 `MergedColumnParallelLinear.create_weights` 一类权重分配处 - (`torch.OutOfMemoryError`)。 -- 诊断:检查 CI 配置是否给**所有** stage 都设了 `gpu_memory_utilization`—— - stage 1(diffusion)缺省时按默认 0.92 计;stage 0 用 45% + stage 1 用 92% 同卡 - 合计 >100% 即 OOM。注意 diffusion stage 内部同时加载 diffusion 模型**和**一个 - LLM(如 Qwen2MoT),仅权重就 ~27.5 GiB。核对点:`tests/.ci_generated/bagel.yaml` - 与 `tests/helpers/stage_config.py` 的 `_CI_OVERLAYS["bagel"]`。 -- 修法:两处同时给 stage 1 加 `gpu_memory_utilization: 0.5`—— - `_CI_OVERLAYS["bagel"]`(源模板)与 `tests/.ci_generated/bagel.yaml` - (重新生成或直接改),skill 原文示例: - - ```python - # In _CI_OVERLAYS["bagel"]: - { - "stage_id": 1, - "max_num_seqs": 1, - "gpu_memory_utilization": 0.5, # ADD THIS - }, - ``` - - ```yaml - # In generated YAML: - - stage_id: 1 - max_num_seqs: 1 - gpu_memory_utilization: 0.5 # ADD THIS - ``` -0.5 的依据:L20X 总显存 ~140 GiB;stage 0 的 45% ≈ 63 GiB; - stage 1 权重 ~27.5 GiB;50% ≈ 70 GiB 在权重基线之上留足余量,且对任何 GPU 都给 - stage 0 留出空间。 -- 验证:`python -m pytest - tests/distributed/omni_connectors/test_bagel_shared_memory_connector.py -x -q - --no-header`。^[SK-fix-missing-gpu-memory-utilization-diffusion-stage] - -## CONF-2a — 小显存机型对 KV 外分配模型 pin kv_cache_memory_bytes,不搞比例棘轮 - -skill 元数据:`fix-voxcpm2-l4-oom-after-rebase`(canonical), -modules=[worker_runner],status=active,run_count=30,2026-06-07 创建 / 07-11 最后使用。 - -- 触发:`test_voxcpm2_*` 在 L4(24GB)exit -1(信号杀/Docker OOM,**无** Python - 栈);日志可见 `CUDA Graph captured for scaffold (batch_size=N)`、prefill 全部完成, - 随后 decode 期 30–60s 静默,最后 `Received cancellation signal, interrupting`。 -- 机制:VoxCPM2 的 diffusion 侧路径(CFM solver、batched VAE decode、LocDiT)在 - decode 期在 vLLM KV-cache 记账**之外**分配显存。 -- 现行修复状态(动手前先读):`vllm_omni/deploy/voxcpm2.yaml` 直接 pin KV cache: - `kv_cache_memory_bytes: 6442450944`(6 GiB,按 max_num_seqs(2)×max_model_len(4096) - 恰好配足(right-sized),其余显存留给 diffusion 侧路径;任何卡峰值 ~13 GiB)+ `max_num_seqs: 2`、 - `gpu_memory_utilization: 0.70`、`vae_decode_every: 1`、`enforce_eager: true`、 - prefix caching 关。这**取代**了 2026-06-04..06-09 间每次 rebase 递减 - `gpu_memory_utilization`(0.90→0.85→0.80→0.75→0.70→0.65 及回调)的棘轮——pin 了 - `kv_cache_memory_bytes` 后该比例不再控制 KV 大小,再减没有意义。 -- 若 pin 后仍 OOM(按序):1) 确认 YAML 里 `kv_cache_memory_bytes` 没被 rebase 冲突 - 丢掉,丢了先恢复;2) 对比上次通过 run 的 - `Model loading took N GiB` 与 free-VRAM 行 - (`rebase_logs/runs//tests/00_tts_voxcpm2_test.log`),判断 vLLM bump 是否抬高 - 了权重/激活基线;3) diffusion 侧路径确实变大时的杠杆(按序):`max_num_seqs` - 2→1、关 `enable_batched_vae_decode`、降 `kv_cache_memory_bytes`——每项都换吞吐, - 实测记录进 debug memory 而不是猜;4) 查历史 - `search_debug_memory(keyword="voxcpm2_l4_oom")`。 -- 禁止:再"顺手减 0.05"`gpu_memory_utilization`——该棘轮跑了 5+ 轮没修根因, - 已被 KV pin 取代。^[SK-fix-voxcpm2-l4-oom-after-rebase] - -## CONF-3a — 争议以展开后的最终配置为准 - -- 触发:CLI、deploy YAML、`base_config` overlay、platform 覆盖、per-stage override - 或 `engine_extras` 各层说法不一致。 -- 强制:以 `resolve_deploy_yaml → load_deploy_config → merge_pipeline_deploy → - build_stage_runtime_overrides` 展开后的**最终逐 stage 配置**为唯一事实,逐字段 - 打印核对(工作法见 [dev 配置审计](../../dev/guides/config-audit-plain-language.md)); - 合并语义见 [architecture](architecture.md)。 -- 禁止:拿某一层 YAML 原文当生效值;用默认值脑补缺失字段(`gpu_memory_utilization` - 缺省=0.9、`async_chunk` 缺省=true 这类默认正是事故来源)。 - -## CONF-4a — composable strategy 只暴露已经接通的 axis - -- 触发:新增 composable parallel strategy、axis、routing/LB policy 或 stage override。 -- 强制:schema 明确区分 wired 与 reserved;translator 对 unsupported/reserved 值显式 - 失败。routing 与 load-balancing policy 只能有一个 owner,不能同时由 strategy 和 CLI - 冲突配置。 -- 禁止:接受但静默忽略 axis;关键 strategy/deploy 文件缺失时 conditional skip;以 - 可漂移的 stage index 作为长期 identity。 -- 验收:每个公开 axis 都有 spec → translator → final stage config 的正向测试和不支持 - 值的 fail-fast 测试;stage 使用必填、可读的稳定名称。 ^[PR #4281] - -## CONF-4b — 标准与 headless 启动必须解析出同一拓扑 - -- 触发:CLI、headless serve、offline entrypoint 或 engine factory 新增/转发配置字段。 -- 强制:同一命令语义在所有入口转发相同 override,并比较展开后的逐 stage 配置。 -- 禁止:只测 parser 输出,未证明值到达 engine/config consumer。 -- 验收:标准与 headless 路径对同一 stage override 生成等价 topology;缺字段时测试直接 - 失败,不允许用 skip 隐藏路径漂移。 ^[PR #4281] - -## CONF-5a — 冻结 topology 只保留一份,部署开关决定 wiring - -- 触发:同一模型的 sync/async processor、普通/async chunk 或部署加速出现多份近似 - pipeline/stage YAML。 -- 强制:相同冻结拓扑共用一份 pipeline config,同时声明可选 processor;由 deploy flag - 决定 wiring。模型 package `__init__` 保持轻量,FP8 等部署加速留在 deploy 层。 -- 禁止:为一个 runtime flag 复制整套 topology;把无关 payload bug 或平台 cleanup - 混入 config migration。 -- 验收:两种 wiring 都从同一 topology 展开,配置 diff 只包含预期 deploy 字段;同卡 - 多 stage 的 `gpu_memory_utilization` 总预算在最终配置中不超过可用容量。 ^[PR #5031] - -## 相关 - -- schema 与解析链见 [architecture](architecture.md);启动期并行度×设备容量验收在 - [Model Executor 规则](../model-executor/rules.md)。 diff --git a/knowledge/_archive/repos/vllm-omni/dev/_index.md b/knowledge/_archive/repos/vllm-omni/dev/_index.md deleted file mode 100644 index 74917e1..0000000 --- a/knowledge/_archive/repos/vllm-omni/dev/_index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "vLLM-Omni 开发与配置" -created: 2026-07-10 -updated: 2026-07-23 -type: index -tags: [vllm-omni, dev] -sources: [] ---- - -# vLLM-Omni 开发与配置 - -## 什么时候查这里 - -- 理解 vLLM-Omni 配置入口、初始化参数和全仓开发约定。 - -## 不放什么 - -- 某个模型独有的配置;这些放模型目录。 - -## 目录内容 - -| 遇到什么 | 查看哪里 | -|---|---| -| 修改配置字段、归一化或新老入口 | [配置开发门禁](rules.md) | -| 审计配置来源和多层加工 | [dev guides](guides/_index.md) | diff --git a/knowledge/_archive/repos/vllm-omni/dev/guides/_index.md b/knowledge/_archive/repos/vllm-omni/dev/guides/_index.md deleted file mode 100644 index ea87aef..0000000 --- a/knowledge/_archive/repos/vllm-omni/dev/guides/_index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: "vLLM-Omni 开发指南" -created: 2026-07-10 -updated: 2026-07-23 -type: index -tags: [vllm-omni, dev] -sources: [] ---- - -# vLLM-Omni 开发指南 - -| 遇到什么 | 查看哪里 | -|---|---| -| 用人话解释配置问题 | [config audit](config-audit-plain-language.md) | -| 设计配置归一化与 parity 验证 | [config normalization parity](config-normalization-parity.md) | -| 查询 Omni 初始化参数 | [Omni init args](omni-init-args.md) | -| 写/改模型部署 YAML | [deploy YAML 实操](deploy-yaml.md) | -| 加新模型的路径与注册点 | [adding a model](adding-a-model.md) | diff --git a/knowledge/_archive/repos/vllm-omni/dev/guides/config-audit-plain-language.md b/knowledge/_archive/repos/vllm-omni/dev/guides/config-audit-plain-language.md deleted file mode 100644 index b8727a3..0000000 --- a/knowledge/_archive/repos/vllm-omni/dev/guides/config-audit-plain-language.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "vLLM-Omni config audit 说人话规则" -created: 2026-07-10 -updated: 2026-07-10 -type: guide -tags: [vllm-omni, dev] -sources: [] ---- - -# vLLM-Omni config audit 说人话规则 - -## 什么时候用 - -用户讨论 vLLM-Omni `config/deploy/pipeline/cli` cleanup、Unified `VllmOmniConfig`、diffusion config owner、deploy config / stage config 迁移时,先用会议室里所有人都能听懂的话解释问题,再补函数名和文件证据。 - -## 先说核心问题 - -不要先说“字段归属矩阵”“source of truth”“runtime payload”。 - -先说: - -> 配置现在不是一个地方说了算,而是好几个地方都在改配置。 - -## 围绕五个问题展开 - -1. 入口太多。 - - 新入口是 `--deploy-config`。 - - 老入口是 `--stage-configs-path`。 - - 还有不传配置时的 diffusion fallback。 - -2. 默认 diffusion 配置有好几处在造。 - - factory 有逻辑。 - - engine 有逻辑。 - - CLI wrapper 也有逻辑。 - - 讲清楚问题是“以后默认值要改,到底改谁”。 - -3. 配置中途会被反复加工。 - - 用户写的配置不是直接拿去跑。 - - 中间会合并、转格式、补字段、规范化。 - - 所以光看 yaml 不知道最后 runtime 真正用了什么。 - -4. 新老配置路径混在一起。 - - `--deploy-config` 是新方向。 - - `--stage-configs-path` 还没死。 - - 文档里出现 stage config 不一定都是错的,要区分过时写法和 legacy-required。 - -5. 模型迁移和 runtime bugfix 容易混在一起。 - - pipeline registry 迁移应该讲 topology。 - - runtime bugfix 应该单独说明。 - - 不要让 reviewer 分不清这是配置清理还是模型行为修复。 - -## 术语必须翻译 - -- 字段归属 = 这个配置字段到底谁管。 -- source of truth = 最终配置到底谁说了算。 -- runtime config = 最后真正拿去跑的配置。 -- topology = 模型有几个 stage、stage 怎么连。 -- legacy-required = 现在还不能删,因为还有模型或测试真的靠它跑。 - -## P0 的人话表达 - -不要说“先产出字段归属矩阵”。 - -说: - -> Stage 1 先不急着改代码。先搞清楚配置从哪里来、最后在哪里生效、哪些 legacy 还不能删。否则 cleanup 很容易删错字段,或者把模型运行行为改掉。 - - -配置语义(schema、合并链、默认值)的 owner 见 [Config 组件](../../components/config/_index.md);本页只管审计工作法。 diff --git a/knowledge/_archive/repos/vllm-omni/dev/guides/config-normalization-parity.md b/knowledge/_archive/repos/vllm-omni/dev/guides/config-normalization-parity.md deleted file mode 100644 index 34fbdef..0000000 --- a/knowledge/_archive/repos/vllm-omni/dev/guides/config-normalization-parity.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "Config normalization parity" -created: 2026-07-23 -updated: 2026-07-23 -type: guide -tags: [vllm-omni, dev, config] -sources: ["claude-workflow-starter-private@e423b8d"] ---- - -# Config normalization parity - -## 什么时候用 - -实现 [配置开发门禁](../rules.md) 时使用。本页只说明怎样收集最小证据,不扩大审查范围。 -字段所有权的解释方法见 [config audit](config-audit-plain-language.md),stage runtime 的严格 -配置约束见 [Model Executor 规则](../../components/model-executor/rules.md)。 - -## 先写最小矩阵 - -只填写当前 diff 会改变的行,再加一个默认或相邻 control。入口、值状态和检查点是候选维度,不要求全部组合: - -| 入口 | 本轮相关值状态 | 实际对象与 copy 边界 | 第一位 consumer | 最终 consumer | 期望 | -|---|---|---|---|---|---| -| deploy、`engine_extras`、nested config、CLI/runtime、direct factory 或默认 fallback 中受影响的一条 | 缺失、`null`、非默认值、冲突值或可转换标量中会改变分支的一项 | 哪个 dict/config 被原地修改,哪里复制 | preflight、validator 或 dispatcher | final config 或 worker | 保留值、派生值或错误 | -| 默认或相邻 control | 未受影响值 | 同上 | 同上 | 同上 | 行为不变 | - -## 执行顺序 - -1. 先搜索 changed field 的现有字段集合、精确 schema 测试、constructor/factory 和 legacy/direct 入口。 -2. 从入口追到第一位 consumer,记录每次 merge、copy、flat→nested 和类型转换;不要从最终 config 反推上游已经正确。 -3. 在最早的共同边界实现归一化。ownership 校验先看 key 是否已知,再决定已知 `None` 是否丢弃;未知 `None` 仍按 strict contract 处理。 -4. 回归测试至少穿过本轮真实入口和第一位 consumer,并再断言最终 config。helper 测试可以精确覆盖分支,但不能单独作为生产路径证据。 -5. public dataclass/config schema 发生变化前,先检查现有精确字段集合、序列化和兼容测试。 -6. 最后一次修改后实跑目标测试文件;本机缺 `vllm` 时立即切到已验证远端或 CI-like 环境,不能用 lint/compile 代替。 diff --git a/knowledge/_archive/repos/vllm-omni/dev/guides/deploy-yaml.md b/knowledge/_archive/repos/vllm-omni/dev/guides/deploy-yaml.md deleted file mode 100644 index cfa3031..0000000 --- a/knowledge/_archive/repos/vllm-omni/dev/guides/deploy-yaml.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: "Deploy YAML 写作实操" -created: 2026-07-16 -updated: 2026-07-16 -type: guide -tags: [vllm-omni, dev] -sources: [docs/configuration/stage_configs.md, vllm_omni/deploy/] ---- - -# Deploy YAML 写作实操 - -面向"要给模型写/改部署配置"的场景;schema 语义 owner 是 -[Config 组件](../../components/config/architecture.md)(本页不复制字段表)。 -`main @ 5c390096` 复核。 - -## 何时需要 YAML,何时 CLI 就够 - -- bundled 默认:registry 按 `model_type` 自动加载 `vllm_omni/deploy/.yaml` - ——不给 `--deploy-config`/`--stage-configs-path` 时就用它;只调个别 stage 参数时 - 优先 CLI/per-stage override,不新写 YAML。 -- 需要新 YAML 的信号:新模型/新 stage 拓扑变体(参照 bagel 的三形态)、平台覆盖 - (`platforms: npu/rocm/xpu`)、connector 拓扑改变、或要固化一组经过验证的资源 - 参数(如 voxcpm2 的 KV pin)。 -- legacy 未迁移模型仍走 `--stage-configs-path` + `stage_args` schema - (`model_executor/stage_configs/*.yaml`,如 mimo_audio、step_audio_2、 - hunyuan_video_15、wan2_2 的 dit_fp8 配置)。 - -## 写作时必查的字段(事故来源) - -- **每个共卡 stage 显式 `gpu_memory_utilization`**(缺省 0.9/0.92 是 OOM 事故源, - [CONF-1a](../../components/config/rules.md))。 -- **单 stage/端到端 pipeline pin `async_chunk: false`** - ([ci-gotchas](../../ci/guides/ci-gotchas.md) 第 2 条)。 -- KV 记账外分配的模型考虑 `kv_cache_memory_bytes` pin([CONF-2a](../../components/config/rules.md))。 -- 争议以展开后最终配置为准([CONF-3a](../../components/config/rules.md))。 - -## 代表样例(58 份 YAML 中的三类拓扑) - -- 单 stage diffusion:不进 `OMNI_PIPELINES`,通常无需 YAML(引擎默认兜底),需要 - 固化参数时才写。 -- AR+DiT 两 stage:`glm_image.yaml`、`hunyuan_image3_{ar,dit,_moe}.yaml`。 -- thinker/talker(+code2wav) 多 stage:`qwen2_5_omni.yaml`(1×H100 验证)、 - `qwen3_omni_moe.yaml`(2×H100 验证)、`qwen3_tts.yaml`(+ 高并发/对齐器变体)。 - -## 相关 - -- 字段语义/合并链:[Config architecture](../../components/config/architecture.md); - connector 声明:[connector-backends](../../components/distributed/guides/connector-backends.md)。 diff --git a/knowledge/_archive/repos/vllm-omni/dev/guides/omni-init-args.md b/knowledge/_archive/repos/vllm-omni/dev/guides/omni-init-args.md deleted file mode 100644 index e16eb9c..0000000 --- a/knowledge/_archive/repos/vllm-omni/dev/guides/omni-init-args.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "Omni() 初始化参数语义" -created: 2026-07-10 -updated: 2026-07-16 -type: guide -tags: [vllm-omni, dev] -sources: [] ---- - -# Omni() 初始化参数语义 - -vllm-omni 是多 stage 架构,每个 stage 在 yaml 的 `engine_args` 字段单独配 `tensor_parallel_size` / `pipeline_parallel_size` / `enable_prefix_caching` 等。但 vllm 的 `EngineArgs` **顶层**也有这些字段的默认值(tp=1 等)。 - -**`end2end.py` 这类官方 example script 里有一句关键调用**: - -```python -from vllm_omni.engine.arg_utils import nullify_stage_engine_defaults -nullify_stage_engine_defaults(parser) -args = parser.parse_args() # EngineArgs 顶层字段全变 None -omni = Omni(**vars(args)) # 顶层 None → stage_config yaml 是唯一来源 -``` - -`nullify_stage_engine_defaults` 把 EngineArgs **顶层** 8-10 个字段(tp / pp / prefix_caching / max_num_batched_tokens / dtype 等)默认值全清成 `None`。这样 Omni() 看到顶层 None 就走 stage_config yaml 配置,不会冲突。 - -**Why:** 直接绕过 argparse 写 `Omni(model=..., stage_configs_path=..., enforce_eager=True, mode="text-to-image")` 这种调用方式,**EngineArgs 顶层 `tensor_parallel_size` 默认 1**。yaml 里 stage 0 / stage 1 各 `tensor_parallel_size: 2`,每 stage 期望 2 GPU。但 launcher 按顶层 tp=1 切分 CUDA_VISIBLE_DEVICES,每 stage 只给 1 个可见 GPU。Stage 1 worker 实际只看到 `['0','1']`(被错切的子集),yaml 说要 logical `['2','3']`,跟 visible 不匹配 → `Stage 1 has logical IDs ['2', '3'], none of which map to the visible devices ['0', '1']` AssertionError 启动失败。painterly debug 时实测踩坑。 - -**How to apply:** -- 写测试 / probe / 一次性 script 直接 `Omni(...)` 实例化时,必须**显式传** `tensor_parallel_size=None, pipeline_parallel_size=None, enable_prefix_caching=None` 等所有 stage_config 已配的字段——告诉 Omni "走 yaml,别用顶层默认" -- 或者:拷贝 `end2end.py` 的 argparse + `nullify_stage_engine_defaults(parser)` 模板,在它基础上加自己的逻辑 -- 探针 / 注入测试推荐做法:**直接 patch `end2end.py`** 加 env-gated 行为,复用它已经处理过的 nullify 逻辑,比重写 script 安全 - -具体踩坑案例:painterly debug session 写 inject HF cot script,绕过 argparse 直接 `Omni()` 启动 → 启动 300s 后 timeout,stage 1 设备分配 AssertionError。改成 patch `end2end.py:158` 加 env-gated cot inject,2 分钟跑通。 diff --git a/knowledge/_archive/repos/vllm-omni/dev/rules.md b/knowledge/_archive/repos/vllm-omni/dev/rules.md deleted file mode 100644 index 5eef47e..0000000 --- a/knowledge/_archive/repos/vllm-omni/dev/rules.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: "vLLM-Omni 配置开发门禁" -created: 2026-07-23 -updated: 2026-07-23 -type: rule -tags: [vllm-omni, dev, config] -sources: ["claude-workflow-starter-private@e423b8d"] -confidence: high ---- - -# vLLM-Omni 配置开发门禁 - -只在修改 vLLM-Omni 的 config、deploy、pipeline、CLI 字段归属、alias、unknown-field -校验、flat→nested 归一化或默认 factory 时使用。具体矩阵和操作顺序见 -[config normalization parity](guides/config-normalization-parity.md),共享配置 owner 见 -[Config 组件](../components/config/_index.md)。 - -## 配置归一化与新老路径一致性 - -- **VOMNI-CFG-1a — 编码前冻结受影响合同。** 第一次业务代码修改前,只列当前 diff 会改变的入口和值状态,再加一个默认或相邻 control;不得做所有入口和值的笛卡尔积,也不得省略仍可调用的 legacy/direct 入口。 -- **VOMNI-CFG-1b — 在第一位 consumer 前归一化。** 对 changed value 标出实际对象、copy/转换边界和第一位 consumer;归一化必须在该 consumer 之前完成。从 unknown 集合排除字段时,必须证明值进入明确 owner 且能从结果读回。 -- **VOMNI-CFG-1c — 用同路径行为证据验收。** 受影响 legacy/structured 路径必须对相关 `null`、有效值、冲突值或可转换标量得到相同结果;至少一个非默认值走到第一位 consumer 和最终 config。helper 单测只能补充,最后必须在含 `vllm` 的兼容环境实跑目标测试。 diff --git a/knowledge/contributing/layout.md b/knowledge/contributing/layout.md index 92cb759..3b37425 100644 --- a/knowledge/contributing/layout.md +++ b/knowledge/contributing/layout.md @@ -120,6 +120,22 @@ skills/ 默认只有 `_index.md` 和 `architecture.md`。checkpoint、尺寸和量化版本先作为同一模型入口的别名和差异;只有源码、配置语义或完整流程真正不同才建新模型目录。 +`models/_index.md` 使用 ``,模型目录本身就是清单。 +新增模型 owner 不再手工维护父级长表;创建目录和自己的 `_index.md` 后,由 +`Get-ChildItem models -Directory` 发现。别名和 registry key 只维护在 +`models/catalog.md`。 + +### Component / model owner 保持扁平 + +`components//` 和 `models//` 下不再创建通用 `guides/` 中转层。稳定特性 +文档使用有意义的文件名直接放在 owner 根目录,例如 +`components/diffusion/parallelism.md`。`_index.md` 必须直接写 +“问题 → 正文”,不能把读者先送到另一个索引。 + +`general//`、`repos///` 这类方法集合仍可使用 `guides/`; +但父级已能确定具体问题时也应直接链接正文。只有需要浏览整个集合时才链接 +`guides/_index.md`。 + ### `local/` `local/` 只放当前机器事实,不被正式 `_index.md` 链接,不能有被 Git 跟踪的文件。需要记录远端环境时可以创建 `local/remote.md`: diff --git a/knowledge/contributing/page-rules.md b/knowledge/contributing/page-rules.md index 6a899e7..94c06ad 100644 --- a/knowledge/contributing/page-rules.md +++ b/knowledge/contributing/page-rules.md @@ -57,6 +57,10 @@ - 依赖哪些共享代码模块; - checkpoint、尺寸和量化版本的差异。 +父级 `models/_index.md` 是例外:它用 `` 声明模型 +子目录由文件系统发现,不逐个复制链接。新增模型时只创建模型目录和该目录自己的 +`_index.md`;只有新增别名或 registry key 时才更新 `models/catalog.md`。 + ## `architecture.md` 写稳定边界 代码模块的 `architecture.md` 至少包含: @@ -126,6 +130,10 @@ `guides/`、`incidents/`、`rfcs/` 等只用来组织同类页面。创建时必须同时创建 `_index.md`,并在上一层 `_index.md` 增加入口。 +`components//` 和 `models//` 不使用 `guides/`;特性文档直接放 owner +根目录。工作主题下允许使用 `guides/`,但父级索引应直接链接常见问题对应的正文, +不要强迫读者再读一层 guides 索引。 + 分类 `_index.md` 必须列出里面的每篇当前有效页面。过期但仍有历史价值的页面单独分组,不与当前规则混在一起。 ## 人类手工新增内容 @@ -134,7 +142,8 @@ 1. 参考一个现有同类目录的最小结构,不复制整棵模板。 2. 创建 `_index.md`,写清“什么时候查”、“不放什么”和“目录内容”。 -3. 在上一层 `_index.md` 增加入口。 +3. 在上一层 `_index.md` 增加入口;新增模型 owner 时由 `models/` 目录自动发现, + 不修改父级 `models/_index.md`。 4. 添加真实内容,不提交空目录。 5. 运行 `python tools/check_knowledge_tree.py`。 diff --git a/knowledge/general/_index.md b/knowledge/general/_index.md index 5f6ccf2..e6b5660 100644 --- a/knowledge/general/_index.md +++ b/knowledge/general/_index.md @@ -34,5 +34,5 @@ sources: [] | 判断何时使用多个 agent | [agents](agents/_index.md) | agent 分工和交接 | | 拆需求、产品闭环和执行计划 | [planning](planning/_index.md) | 通用规划方法 | -页面元数据(frontmatter、标签分类法、`_archive/` 归档)规范见 [SCHEMA](../SCHEMA.md); +页面元数据(frontmatter、标签分类法、页面生命周期)规范见 [SCHEMA](../SCHEMA.md); 目录归属与页面写法见 [贡献规范](../contributing/_index.md)。 diff --git a/knowledge/general/review/guides/review-execution-contract.md b/knowledge/general/review/guides/review-execution-contract.md index 1f5bcfa..7d73545 100644 --- a/knowledge/general/review/guides/review-execution-contract.md +++ b/knowledge/general/review/guides/review-execution-contract.md @@ -13,7 +13,7 @@ sources: ["InferMatrixCopilot Issue #17", "InferMatrixCopilot Issue #24", "zuiho ## 单次输入与简明检查单 -主审查只采集一次 `{base_sha, head_sha, PR title/body, changed files, diff, mergeability, CI}`。先用 title/body 的声明目标选择精确 owner/model 规则组和第一批源码函数,再用 changed files 验证和补全范围;PR 描述只负责导航,不能作为 finding 证据。 +主审查只采集一次 `{base_sha, head_sha, PR title/body, changed files, diff, mergeability, CI}`。元数据返回后先发宿主进度,再把 title/body/changed files 一次传给 Direct;使用返回的至多 3 个精确 owner/model `knowledge_routes` 内嵌 `quick_map`,只有具体歧义阻塞源码审查时才打开完整规则文件,不得从总入口和索引重新导航。changed files 只验证和补全范围;PR 描述只负责导航,不能作为 finding 证据。 同一份证据包持续追加已读文件、caller 搜索、测试结果和 findings,后续步骤必须复用,不能重新抓取或重复调查。第一次 Codex review 使用这份简明检查单: @@ -25,14 +25,28 @@ sources: ["InferMatrixCopilot Issue #17", "InferMatrixCopilot Issue #24", "zuiho ## 60 秒渐进状态 -审查开始后 60 秒内,宿主先在当前对话报告: +审查开始后 60 秒内,快照元数据一返回,宿主就在任何知识读取、源码搜索或测试之前报告: - 固定的 head SHA; - 当前 CI 状态; - 当前可合并性; - 已有早期 finding,或明确写“暂未发现”。 -早期 finding 必须标记为“初步”,宿主随后继续同一次审查。该状态只用于避免用户长时间看不到进展,不是完整 review,也不是 GitHub 评论;不能发布“初稿评论”,最终仍只有一篇合并后的 review comment。CI 未完成或可合并性未知时报告真实状态,不等待它们完成才发进度。 +早期 finding 必须标记为“初步”,宿主随后继续同一次审查。该状态只用于避免用户长时间看不到进展,不是完整 review,也不是 GitHub 评论;不能发布“初稿评论”,最终仍只有一篇合并后的 review comment。CI 未完成或可合并性未知时报告真实状态,不等待它们完成,也不能先做知识导航再发进度。 + +## Direct 并行与可预测验证 + +固定快照后先让状态轨完成首次宿主进度,再并行推进其余证据轨: + +- **状态轨:** head SHA、CI、可合并性;首次元数据返回就发进度; +- **知识/源码轨:** 只读 Direct 返回的精确 owner/model routes,然后进入首批源码、限定范围的 `rg` 和 caller; +- **验证轨:** 先做 import/version 兼容性预检,通过后运行目标测试和低成本静态检查。 + +三条轨共用当前审查的一份证据包。已读文件、搜索结果、caller、测试、repo-map、知识路由和 finding 不重复获取;搜索必须限定目录、glob 或输出量,不用无边界全仓递归扫描。Direct 不新增持久缓存、后台调度器或 progress API。 + +CI 默认只作为状态证据;只有首个失败异常与 frozen diff 重叠或阻塞判决时才打开日志。纯文档改动跳过依赖预检和 pytest,只做 diff hygiene、链接/构建检查以及对被引用 live contract 的有界核对。 + +验证记录必须包含 `{repo, head_sha, command, result, environment_fingerprint}`。环境指纹至少覆盖依赖锁摘要、Python 和平台;只有依赖指纹匹配才复用环境。head 变化使旧测试结果失效,但依赖没有变化时不重建环境。预检失败就报告具体不兼容项,不继续运行或声称 pytest 已验证。预检通过后,目标测试和静态检查应与源码审查并行,不能等模型审完才启动。每条变化语义已有 finding 或明确 no-issue 结论后停止,不为增加信心继续追加搜索。 ## 完成条件 diff --git a/knowledge/general/review/guides/upstream-first-for-algorithm.md b/knowledge/general/review/guides/upstream-first-for-algorithm.md index 8a80d23..3180b0c 100644 --- a/knowledge/general/review/guides/upstream-first-for-algorithm.md +++ b/knowledge/general/review/guides/upstream-first-for-algorithm.md @@ -132,5 +132,5 @@ PR #3474 的教训是:新模型接入时,shape / state dict / stub smoke 都 - PR #3444 review iteration:[Hunyuan KV reuse 错题](../../../repos/vllm-omni/models/hunyuan-image3/incidents/2026-05-13-kv-reuse-orchestrator.md)(review iteration 段) - PR #3626 review iteration:[reviewer_lens_audit](reviewer-lens-audit.md)(4 条评论同一根因) - PR #3474 review iteration:GO-1-Air shape-compatible semantic mismatch -- 相邻:[hf_alignment_pitfalls](../../../repos/vllm-omni/models/hunyuan-image3/guides/hf-alignment-pitfalls.md)(HF model 接入时 grep README/demo) +- 相邻:[hf_alignment_pitfalls](../../../repos/vllm-omni/models/hunyuan-image3/hf-alignment-pitfalls.md)(HF model 接入时 grep README/demo) - 派生硬规则:CLAUDE.md B30 diff --git a/knowledge/general/review/rules.md b/knowledge/general/review/rules.md index 6dd106c..6af4b6e 100644 --- a/knowledge/general/review/rules.md +++ b/knowledge/general/review/rules.md @@ -1,7 +1,7 @@ --- title: "通用设计审查规则" created: 2026-07-30 -updated: 2026-07-30 +updated: 2026-07-31 type: rule tags: [general, review] sources: ["InferMatrixCopilot Issue #17", "InferMatrixCopilot Issue #24", "vllm-project/vllm-omni PR #5394", "zuiho-kai/claude-workflow-starter@c217fc6"] @@ -41,37 +41,38 @@ confidence: high ## 审查角色与减法 -### REV-2a — 一次 Direct 审查必须同时完成 correctness 与 design/subtraction +### REV-2a — 一次 Direct 审查复用同一份证据 -- 触发:用户要求审核 PR,包括只提供 PR 链接;或交付前审查发现新增 public behavior、 - owner、abstraction、兼容路径或跨模块数据流。 +- 触发:用户要求审核 PR,包括只提供 PR 链接。 - 强制:冻结 base/head 和授权合同;一次获取 PR 描述、changed files、diff、caller、 tests 与已有 findings,并把精确 owner/model 规则组加入同一个 Codex review。主审查 - 同时追行为和 producer→consumer,并完成项目级与模块级减法。 + 始终追行为和 producer→consumer;只有 REV-2b 信号触发时才继续减法检查。 - 禁止:为 correctness 和 subtraction 各跑一篇通用审查;让不同 reviewer 重复读取 同一文件、搜索 caller 或运行同一测试;分别发布多篇 review comment。 -- 验收:一份内部报告覆盖 correctness 与 subtraction,一篇对外评论给出合并后的 - findings 和 verdict;任一维度缺失只能报 `partial review`。 ^[InferMatrixCopilot Issue #24] +- 验收:一份内部报告覆盖 correctness 和减法信号分类;触发时补减法结果,未触发时 + 记录 `subtraction_signal=none`。一篇对外评论给出合并后的 findings 和 verdict。 + ^[InferMatrixCopilot Issue #24] ### REV-2b — 减法先删越界 scope,再压缩模块设计 -- 触发:PR 新增 production behavior、文件、测试、helper、class、normalizer、validator、 - allowlist、owner projection、中间 artifact 或末端补偿。 +- 触发:PR 新增或扩张 public behavior、helper、class、fallback 或兼容分支。 - 强制:先把每项变化映射到用户目标或当前 RFC/mini spec slice,未映射项 `DELETE / DEFER`;再枚举保留 abstraction,写出不依赖当前实现的最小 owner 设计, 逐项标记 `KEEP / INLINE / MERGE / MOVE / DELETE`,优先最小修改和复用既有 owner。 - 禁止:把字段丢失、默认值错误等 correctness bug 算作减法;用删局部变量、改名、 换文件或多 caller 证明设计已经最简;让后续 RFC slice 因为已写完而混入当前 PR。 -- 验收:报告先给 scope 删除项,再给模块 abstraction/owner/分支的净减少;没有可删项时, - 必须用完整 scope ledger、census 和最小设计证明当前已经最小。 +- 验收:触发时报告 scope 删除项和模块 abstraction/owner/分支的净减少;没有可删项时 + 给出最小设计证据。未触发时直接记录 `subtraction_signal=none`,不要求 ledger、 + census 或最小性证明。 ^[zuiho-kai/claude-workflow-starter@c217fc6] ### REV-2c — 交互式 PR review 必须按时返回最小可用结论 - 触发:用户未指定深审或更长预算,只要求审核 PR。 -- 强制:默认端到端预算 10 分钟;主审查先完成合并/CI/diff 快速检查并复用同一证据包。 +- 强制:默认端到端预算 10 分钟;60 秒内先在宿主对话报告 head、CI、可合并性和早期 + finding。固定快照后并行推进状态、知识/源码、验证三条证据轨并复用同一证据包。 只有新颖、矛盾或未覆盖的高风险合同才允许在剩余预算内追加有边界的专项追问;截止时 - 停止新工具调用,返回当前 finding、减法账本和未验证边界。 + 停止新工具调用,返回当前 finding、已触发的减法结果和未验证边界。 - 禁止:为了补齐外围 CI、全量测试、历史 thread 或额外专项无限延长;在 reviewer 已超时 后继续无上限等待“完整结果”。 - 验收:10 分钟内给用户 actionable findings 或明确的 `partial review`;更深验证作为 diff --git a/knowledge/repos/vllm-omni/_index.md b/knowledge/repos/vllm-omni/_index.md index 59309a2..27c5088 100644 --- a/knowledge/repos/vllm-omni/_index.md +++ b/knowledge/repos/vllm-omni/_index.md @@ -1,7 +1,7 @@ --- -title: "vLLM-Omni" +title: "vLLM-Omni 入口" created: 2026-07-10 -updated: 2026-07-30 +updated: 2026-07-31 type: index tags: [vllm-omni] sources: [] @@ -9,33 +9,35 @@ sources: [] # vLLM-Omni -- 上游仓库:`vllm-project/vllm-omni` -- 常用分支:默认分支 `main`;对齐 upstream vLLM 的重构分支 `dev/vllm-align` -- 适用范围:vLLM-Omni 的开发、测试、文档、模型、性能和远端验证 -- 组件源码映射需在使用前按目标仓库当前 `main` 重新验证 - -## 什么时候查这里 - -- 当前 Git 仓库或用户明确目标是 vLLM-Omni。 - -## 不放什么 - -- 跨仓库通用的方法。 -- Jianghan 或其他仓库的规则。 - -## 当前入口 - -| 遇到什么 | 查看哪里 | 说明 | -|---|---|---| -| 开始任何 vLLM-Omni 修改、测试、远端或发布任务 | [硬门禁](rules.md) | 仅适用于 vLLM-Omni 的仓库规则 | -| 审查 PR、模型适配和仓库专有改动 | [review](review/_index.md) | 先按 PR 声明目标命中 owner 快速入口;changed files 用于闭合 scope | -| 查看 CI 规则和测试配置 | [ci](ci/_index.md) | vLLM-Omni CI | -| 查看文档和 RFC 状态 | [docs](docs/_index.md) | 仓库文档入口 | -| 调查仓库专有 bug、crash 或行为异常 | [debug](debug/_index.md) | 完成通用调试后的仓库二次路由 | -| 查看配置入口、字段归属和构造链路 | [Configuration 规则](components/configuration/rules.md) | 直接进入共享配置 owner 规则;owner 不明时才看组件职责地图 | -| 处理分支、PR 和公开证据 | [git](git/_index.md) | 仓库专有 Git/PR 规则 | -| 跑 benchmark、profiling 或查历史结果 | [benchmark](benchmark/_index.md) | 性能入口 | -| 在远端验证仓库改动 | [remote](remote/_index.md) | 仓库专有远端策略 | -| 对齐 upstream vLLM(rebase、API 漂移、波次) | [rebase](rebase/_index.md) | 上游对齐工作流与漂移登记 | -| 查看共享代码模块 | [components](components/_index.md) | configuration、diffusion、distributed、model-executor、scheduler、serving | -| 查看支持模型 | [models](models/_index.md) | 模型架构与经验 | +上游:`vllm-project/vllm-omni`。开始任何任务先遵守 +[仓库硬规则](rules.md)。 + +## Review 最短路径 + +PR title/body 先选择 owner;changed files 只校验实际范围。Direct 已返回精确 +`quick_map` 时,不再读取本页、组件总表或模型总表。 + +| PR 声明目标 | 直接 owner | +|---|---| +| PipelineConfig、YAML、registry、default、endpoint policy | [configuration rules](components/configuration/rules.md) | +| HTTP/OpenAI request、response、endpoint、engine lifecycle | [serving rules](components/serving/rules.md) | +| checkpoint、tokenizer、processor、stage input/handoff | [model-executor rules](components/model-executor/rules.md) | +| diffusion pipeline、denoise、VAE/DiT、图像生成 | [diffusion rules](components/diffusion/rules.md) | +| connector、collective、跨 stage 通信 | [distributed](components/distributed/_index.md) | +| queue、token budget、prefix cache、调度 | [scheduler rules](components/scheduler/rules.md) | +| 明确模型名或 registry key | 直接查看 [models 目录](models/_index.md) | + +owner 仍不明确时才看 [components 职责表](components/_index.md);模型别名不确定时才查 +[`models/catalog.md`](models/catalog.md)。 + +## 工作主题 + +| 任务 | 入口 | +|---|---| +| PR 审查专项 | [review](review/_index.md) | +| CI 和测试配置 | [ci](ci/_index.md) | +| 文档和 RFC | [docs](docs/_index.md) | +| bug 和行为异常 | [debug](debug/_index.md) | +| Git、PR、rebase | [git](git/_index.md)、[upstream rebase](rebase/_index.md) | +| benchmark / profiling | [benchmark](benchmark/_index.md) | +| 远端验证 | [remote](remote/_index.md) | diff --git a/knowledge/repos/vllm-omni/components/_index.md b/knowledge/repos/vllm-omni/components/_index.md index 63c60a8..590a849 100644 --- a/knowledge/repos/vllm-omni/components/_index.md +++ b/knowledge/repos/vllm-omni/components/_index.md @@ -1,35 +1,25 @@ --- -title: "vLLM-Omni 代码模块" +title: "vLLM-Omni 组件 owner" created: 2026-07-10 -updated: 2026-07-29 +updated: 2026-07-31 type: index tags: [vllm-omni, components] sources: [] --- -# vLLM-Omni 代码模块 +# 组件 owner -本目录是知识树对 `vllm_omni/` 源码空间的镜像(code-owner 轴)。每个模块页的 -"源码入口"列出它拥有的真实源码路径;所有模块页的路径均已验证存在——建目录时 -已有的 diffusion/model-executor/serving 在 `main @ 238fc0a6`(此前亦在 -`dev/vllm-align @ 4f2b32c` 验证,结果一致),2026-07-16 新增的 -scheduler/distributed/configuration 在当日 `main @ 5c390096`。只有确有知识沉淀的模块才 -建目录,不预建空目录(此前预告的 scheduler、configuration 已在第一条稳定结论落盘时建立; -attention、lora、quantization 等同理,等第一条稳定结论落盘时再建)。 +仅在 PR 描述和 Direct 路由都不能确定 owner 时查本页。选中一个主要 owner 后直接进入 +其 `rules.md`;只有真实调用链跨边界时才打开第二个 owner。 -注意:这里的模块划分服务于**知识归属**(一个 owner 覆盖一条职责链),与 -copilot `adapters/vllm_omni/manifest.yaml` 的 `modules:`(服务于运行时 -`module_for_path()` 路由与 PR 验证分片)粒度不同,属有意为之——例如 -Model Executor 在这里同时拥有 `worker/`,而 manifest 将其拆为 -`model_executor` 与 `worker_runner` 两个运行时模块。 - -| 代码模块 | 查看哪里 | 负责什么 | +| Owner | 负责范围 | 直接入口 | |---|---|---| -| Configuration | [configuration rules](configuration/rules.md) | PipelineConfig/deploy YAML、pipeline registry、endpoint 策略、CLI/default/direct factory 的配置归一化、字段归属、严格校验与构造 | -| Diffusion | [diffusion](diffusion/_index.md) | 多模型共享的 diffusion pipeline、denoise 和执行机制 | -| Distributed | [distributed](distributed/_index.md) | 跨 stage 通信、connector 后端、KV 迁移管理、协调与负载均衡 | -| Model Executor | [model-executor](model-executor/_index.md) | AR/LLM stage、stage config、并行与设备启动、输入处理和跨 stage 数据桥接 | -| Scheduler | [scheduler](scheduler/_index.md) | AR/生成请求调度、KV transfer 调度面、chunk/full-payload 等待与 tensor prefix cache | -| Serving | [serving](serving/_index.md) | 用户入口、请求解析、在线服务和 engine 边界 | +| [Configuration](configuration/_index.md) | deploy YAML、PipelineConfig、registry、字段归属、default 和 endpoint policy | [rules](configuration/rules.md) | +| [Serving](serving/_index.md) | 用户请求、OpenAI API、响应、AsyncOmni engine 生命周期 | [rules](serving/rules.md) | +| [Model Executor](model-executor/_index.md) | stage config/input、模型加载、worker、跨 stage 数据桥 | [rules](model-executor/rules.md) | +| [Diffusion](diffusion/_index.md) | diffusion pipeline、denoise、VAE/DiT、并行和 cache | [rules](diffusion/rules.md) | +| Distributed | connector、KV 迁移、collective、跨 stage 通信 | [index](distributed/_index.md) | +| [Scheduler](scheduler/_index.md) | 请求队列、token budget、KV transfer、prefix cache | [rules](scheduler/rules.md) | -目录维护登记:[Configuration index](configuration/_index.md)。它只用于维护目录内容,不是命中 Configuration owner 后的必读下一跳。 +需要解释稳定数据流时再进入对应 owner 的 `architecture.md`,不要把 architecture 当成 +review 的默认前置阅读。 diff --git a/knowledge/repos/vllm-omni/components/configuration/_index.md b/knowledge/repos/vllm-omni/components/configuration/_index.md index f9c8188..bb654a9 100644 --- a/knowledge/repos/vllm-omni/components/configuration/_index.md +++ b/knowledge/repos/vllm-omni/components/configuration/_index.md @@ -35,8 +35,10 @@ sources: ["claude-workflow-starter-private@296ea45", vllm_omni/config/] |---|---| | 理解配置从 deploy、CLI、默认 factory 到 structured/legacy config 的稳定边界 | [配置构造架构](architecture.md) | | 根据 PR 描述直达 strict schema、deploy/topology、composable strategy 或显存配置的规则组与第一批源码 | [配置开发门禁与代码地图](rules.md) | -| 审计配置来源、多层加工或初始化参数 | [configuration guides](guides/_index.md) | - -旧 `components/config/` 与 `dev/` 页面已归档,仅用于迁移追溯: -[config archive](../../../../_archive/repos/vllm-omni/components/config/_index.md)、 -[dev archive](../../../../_archive/repos/vllm-omni/dev/_index.md)。 +| 审计配置来源和多层加工 | [config audit](config-audit-plain-language.md) | +| 设计配置归一化与 parity 验证 | [config normalization parity](config-normalization-parity.md) | +| 查询 `Omni()` 初始化参数 | [Omni init args](omni-init-args.md) | +| 写或修改 deploy YAML | [deploy YAML](deploy-yaml.md) | +| 核对 pipeline/deploy schema | [pipeline deploy schema](pipeline-deploy-schema.md) | +| 计算多 stage 显存预算 | [deployment memory budget](deployment-memory-budget.md) | +| 添加新模型和注册点 | [adding a model](adding-a-model.md) | diff --git a/knowledge/_archive/repos/vllm-omni/dev/guides/adding-a-model.md b/knowledge/repos/vllm-omni/components/configuration/adding-a-model.md similarity index 86% rename from knowledge/_archive/repos/vllm-omni/dev/guides/adding-a-model.md rename to knowledge/repos/vllm-omni/components/configuration/adding-a-model.md index c5ceb3e..6acbbac 100644 --- a/knowledge/_archive/repos/vllm-omni/dev/guides/adding-a-model.md +++ b/knowledge/repos/vllm-omni/components/configuration/adding-a-model.md @@ -1,10 +1,10 @@ --- -title: "加新模型:三条官方路径与四个注册点" +title: "vLLM-Omni 新模型接入路径" created: 2026-07-16 -updated: 2026-07-16 +updated: 2026-07-29 type: guide -tags: [vllm-omni, dev] -sources: [docs/contributing/model/adding_omni_model.md, docs/contributing/model/adding_diffusion_model.md, docs/contributing/model/adding_tts_model.md] +tags: [vllm-omni, components, config, models] +sources: ["claude-workflow-starter-private@296ea45", docs/contributing/model/] --- # 加新模型:三条官方路径与四个注册点 diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/config-audit-plain-language.md b/knowledge/repos/vllm-omni/components/configuration/config-audit-plain-language.md similarity index 100% rename from knowledge/repos/vllm-omni/components/configuration/guides/config-audit-plain-language.md rename to knowledge/repos/vllm-omni/components/configuration/config-audit-plain-language.md diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/config-normalization-parity.md b/knowledge/repos/vllm-omni/components/configuration/config-normalization-parity.md similarity index 94% rename from knowledge/repos/vllm-omni/components/configuration/guides/config-normalization-parity.md rename to knowledge/repos/vllm-omni/components/configuration/config-normalization-parity.md index 02c8ca6..aa8a640 100644 --- a/knowledge/repos/vllm-omni/components/configuration/guides/config-normalization-parity.md +++ b/knowledge/repos/vllm-omni/components/configuration/config-normalization-parity.md @@ -11,9 +11,9 @@ sources: ["claude-workflow-starter-private@296ea45"] ## 什么时候用 -实现 [配置开发门禁](../rules.md) 时使用。本页只说明怎样收集最小证据,不扩大审查范围。 +实现 [配置开发门禁](rules.md) 时使用。本页只说明怎样收集最小证据,不扩大审查范围。 字段所有权的解释方法见 [config audit](config-audit-plain-language.md),stage runtime 的严格 -配置约束见 [Model Executor 规则](../../model-executor/rules.md)。 +配置约束见 [Model Executor 规则](../model-executor/rules.md)。 ## 先写最小矩阵 @@ -35,7 +35,7 @@ sources: ["claude-workflow-starter-private@296ea45"] ## 严格 schema 的固定执行顺序 -完整配置路径见 [配置构造架构](../architecture.md)。实现时不得把下面四步折叠成“validator 顺手整理 kwargs”: +完整配置路径见 [配置构造架构](architecture.md)。实现时不得把下面四步折叠成“validator 顺手整理 kwargs”: 1. **Normalize**:按 source priority 合并,再处理 alias、flat→nested、类型转换和 compatibility route。 2. **Validate ownership**:对仍包含所有 key 的规范化映射检查 owner;此时未知 `None` 不能消失。 diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/deploy-yaml.md b/knowledge/repos/vllm-omni/components/configuration/deploy-yaml.md similarity index 80% rename from knowledge/repos/vllm-omni/components/configuration/guides/deploy-yaml.md rename to knowledge/repos/vllm-omni/components/configuration/deploy-yaml.md index 0a89847..373af52 100644 --- a/knowledge/repos/vllm-omni/components/configuration/guides/deploy-yaml.md +++ b/knowledge/repos/vllm-omni/components/configuration/deploy-yaml.md @@ -10,7 +10,7 @@ sources: ["claude-workflow-starter-private@296ea45", vllm_omni/deploy/] # Deploy YAML 写作实操 面向"要给模型写/改部署配置"的场景;schema 语义 owner 是 -[Configuration](../architecture.md)(本页不复制字段表)。 +[Configuration](architecture.md)(本页不复制字段表)。 `main @ 5c390096` 复核。 ## 何时需要 YAML,何时 CLI 就够 @@ -28,11 +28,11 @@ sources: ["claude-workflow-starter-private@296ea45", vllm_omni/deploy/] ## 写作时必查的字段(事故来源) - **每个共卡 stage 显式 `gpu_memory_utilization`**(缺省 0.9/0.92 是 OOM 事故源, - [CONF-1a](../rules.md))。 + [CONF-1a](rules.md))。 - **单 stage/端到端 pipeline pin `async_chunk: false`** - ([ci-gotchas](../../../ci/guides/ci-gotchas.md) 第 2 条)。 -- KV 记账外分配的模型考虑 `kv_cache_memory_bytes` pin([CONF-2a](../rules.md))。 -- 争议以展开后最终配置为准([CONF-3a](../rules.md))。 + ([ci-gotchas](../../ci/guides/ci-gotchas.md) 第 2 条)。 +- KV 记账外分配的模型考虑 `kv_cache_memory_bytes` pin([CONF-2a](rules.md))。 +- 争议以展开后最终配置为准([CONF-3a](rules.md))。 ## 代表样例(58 份 YAML 中的三类拓扑) @@ -44,5 +44,5 @@ sources: ["claude-workflow-starter-private@296ea45", vllm_omni/deploy/] ## 相关 -- 字段语义/合并链:[Configuration architecture](../architecture.md); - connector 声明:[connector-backends](../../distributed/guides/connector-backends.md)。 +- 字段语义/合并链:[Configuration architecture](architecture.md); + connector 声明:[connector-backends](../distributed/connector-backends.md)。 diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/deployment-memory-budget.md b/knowledge/repos/vllm-omni/components/configuration/deployment-memory-budget.md similarity index 95% rename from knowledge/repos/vllm-omni/components/configuration/guides/deployment-memory-budget.md rename to knowledge/repos/vllm-omni/components/configuration/deployment-memory-budget.md index 0fac843..7eb7f23 100644 --- a/knowledge/repos/vllm-omni/components/configuration/guides/deployment-memory-budget.md +++ b/knowledge/repos/vllm-omni/components/configuration/deployment-memory-budget.md @@ -10,7 +10,7 @@ sources: ["claude-workflow-starter-private@296ea45", "SK-fix-missing-gpu-memory- # Deploy 配置与显存预算案例 本页保留 deploy 配置与显存预算的具体诊断材料;可执行门禁已提炼到 -[Configuration rules](../rules.md) 的 `CONF-*` 规则。运营 runbook 仍以 rebase-agent +[Configuration rules](rules.md) 的 `CONF-*` 规则。运营 runbook 仍以 rebase-agent 仓库为准。 ## CONF-1a — 多 stage 共卡时 diffusion stage 必须显式设 gpu_memory_utilization @@ -88,7 +88,7 @@ modules=[worker_runner],status=active,run_count=30,2026-06-07 创建 / 07- - 强制:以 `resolve_deploy_yaml → load_deploy_config → merge_pipeline_deploy → build_stage_runtime_overrides` 展开后的**最终逐 stage 配置**为唯一事实,逐字段 打印核对(工作法见 [配置审计](config-audit-plain-language.md)); - 合并语义见 [architecture](../architecture.md)。 + 合并语义见 [architecture](architecture.md)。 - 禁止:拿某一层 YAML 原文当生效值;用默认值脑补缺失字段(`gpu_memory_utilization` 缺省=0.9、`async_chunk` 缺省=true 这类默认正是事故来源)。 @@ -124,5 +124,5 @@ modules=[worker_runner],status=active,run_count=30,2026-06-07 创建 / 07- ## 相关 -- schema 与解析链见 [architecture](../architecture.md);启动期并行度×设备容量验收在 - [Model Executor 规则](../../model-executor/rules.md)。 +- schema 与解析链见 [architecture](architecture.md);启动期并行度×设备容量验收在 + [Model Executor 规则](../model-executor/rules.md)。 diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/_index.md b/knowledge/repos/vllm-omni/components/configuration/guides/_index.md deleted file mode 100644 index 6775cb2..0000000 --- a/knowledge/repos/vllm-omni/components/configuration/guides/_index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "vLLM-Omni Configuration 指南" -created: 2026-07-16 -updated: 2026-07-29 -type: index -tags: [vllm-omni, components, config] -sources: ["claude-workflow-starter-private@296ea45"] ---- - -# vLLM-Omni Configuration 指南 - -| 遇到什么 | 查看哪里 | -|---|---| -| 用人话解释配置问题 | [config audit](config-audit-plain-language.md) | -| 设计配置归一化与 parity 验证 | [config normalization parity](config-normalization-parity.md) | -| 理解 legacy stage YAML 与顶层 EngineArgs 的优先级 | [Omni init args](omni-init-args.md) | -| 写/改模型部署 YAML | [deploy YAML 实操](deploy-yaml.md) | -| 加新模型的路径与注册点 | [adding a model](adding-a-model.md) | -| 查询 PipelineConfig/deploy schema 与解析链快照 | [pipeline/deploy schema](pipeline-deploy-schema.md) | -| 排查 deploy 配置和显存预算案例 | [deployment memory budget](deployment-memory-budget.md) | diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/adding-a-model.md b/knowledge/repos/vllm-omni/components/configuration/guides/adding-a-model.md deleted file mode 100644 index 6913b46..0000000 --- a/knowledge/repos/vllm-omni/components/configuration/guides/adding-a-model.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "vLLM-Omni 新模型接入路径" -created: 2026-07-16 -updated: 2026-07-29 -type: guide -tags: [vllm-omni, components, config, models] -sources: ["claude-workflow-starter-private@296ea45", docs/contributing/model/] ---- - -# 加新模型:三条官方路径与四个注册点 - -官方 spec(`main @ 5c390096` 复核): -`docs/contributing/model/adding_omni_model.md`(多 stage omni,以 Qwen3-Omni 为 -完整示例——目录结构/关键组件/注册/stage 配置/stage input processor/测试/recipe -九节)、`adding_diffusion_model.md`(纯 diffusion pipeline)、 -`adding_tts_model.md`(TTS)。仓库内的 `.claude/skills/add-*` 打包了同样的工作流。 - -## 四个注册点(漏一个都跑不起来) - -| 注册点 | 位置 | 作用 | -|---|---|---| -| AR/omni 架构 | `model_executor/models/registry.py` `_OMNI_MODELS` | HF arch 名 → 模块/类 | -| Diffusion pipeline | `diffusion/registry.py` `_DIFFUSION_MODELS` | pipeline 类 → 模块 | -| Pipeline(model_type) | `config/pipeline_registry.py` `OMNI_PIPELINES` | model_type → 冻结拓扑/resolver(单 stage diffusion 不注册) | -| Deploy YAML | `vllm_omni/deploy/.yaml` | bundled 默认部署 | - -另有:跨 stage 转换 `stage_input_processors/.py`(`ar2diffusion` 等)、 -serving TTS 适配 `entrypoints/openai/tts_adapters/`、`recipes//.md`。 - -## 照抄谁 - -参照清单见 [reference-models](../../../models/reference-models.md)(GLM-Image / -BAGEL)与 [qwen-omni](../../../models/qwen-omni/_index.md);当前注册全量见 -[models/catalog](../../../models/catalog.md)。 - -## 验收档位 - -plumbing 绿灯(0 missing/0 unexpected、shape smoke、mock 权重)**不等于**语义 -正确——semantic parity 矩阵与逐入口验收见 -[model-adaptation-guardrails](../../../review/guides/model-adaptation-guardrails.md) -与仓库 [rules.md](../../../rules.md) 第 3 节。 diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/omni-init-args.md b/knowledge/repos/vllm-omni/components/configuration/omni-init-args.md similarity index 100% rename from knowledge/repos/vllm-omni/components/configuration/guides/omni-init-args.md rename to knowledge/repos/vllm-omni/components/configuration/omni-init-args.md diff --git a/knowledge/repos/vllm-omni/components/configuration/guides/pipeline-deploy-schema.md b/knowledge/repos/vllm-omni/components/configuration/pipeline-deploy-schema.md similarity index 96% rename from knowledge/repos/vllm-omni/components/configuration/guides/pipeline-deploy-schema.md rename to knowledge/repos/vllm-omni/components/configuration/pipeline-deploy-schema.md index 26e27b2..e0b007f 100644 --- a/knowledge/repos/vllm-omni/components/configuration/guides/pipeline-deploy-schema.md +++ b/knowledge/repos/vllm-omni/components/configuration/pipeline-deploy-schema.md @@ -10,7 +10,7 @@ sources: ["claude-workflow-starter-private@296ea45", vllm_omni/config/stage_conf # PipelineConfig 与 deploy YAML 详细 schema 以下事实在 `main @ 5c390096` 复核;当前稳定职责见 -[Configuration architecture](../architecture.md),官方 spec 见 +[Configuration architecture](architecture.md),官方 spec 见 `docs/configuration/stage_configs.md` (schema 全表)与 `composable_parallel.md`。 @@ -33,7 +33,7 @@ sources: ["claude-workflow-starter-private@296ea45", vllm_omni/config/stage_conf - per-stage `StageDeployConfig` 字段直接平铺(无嵌套 `engine_args:`):`stage_id` (必填,对齐 `PipelineConfig.stages[*].stage_id`)、`max_num_seqs`(默认 64)、 `gpu_memory_utilization`(**默认 0.9**——多 stage 共卡时必须显式设,见 - [rules](../rules.md) `CONF-1a`)、`tensor_parallel_size`、`enforce_eager`、 + [rules](rules.md) `CONF-1a`)、`tensor_parallel_size`、`enforce_eager`、 `max_num_batched_tokens`(默认 32768)、`max_model_len`、`devices`(默认 "0")、 `input_connectors`/`output_connectors`(`from_stage_`/`to_stage_` 键引用顶层 `connectors:` 注册名)、`default_sampling_params`、`engine_extras`(未知键兜底, diff --git a/knowledge/repos/vllm-omni/components/configuration/rules.md b/knowledge/repos/vllm-omni/components/configuration/rules.md index da91cc2..5dad1d3 100644 --- a/knowledge/repos/vllm-omni/components/configuration/rules.md +++ b/knowledge/repos/vllm-omni/components/configuration/rules.md @@ -10,8 +10,8 @@ sources: ["claude-workflow-starter-private@296ea45", "PR #4281", "PR #5031", "zu # vLLM-Omni 配置开发门禁 只在修改 vLLM-Omni 的 config、deploy、pipeline、CLI 字段归属、alias、unknown-field 校验、flat→nested 归一化或默认 factory 时使用。第一次读这些规则时,先看 -[config audit 说人话规则](guides/config-audit-plain-language.md);需要执行时再看 -[config normalization parity](guides/config-normalization-parity.md) 的矩阵和操作顺序。 +[config audit 说人话规则](config-audit-plain-language.md);需要执行时再看 +[config normalization parity](config-normalization-parity.md) 的矩阵和操作顺序。 ## Direct 代码快速入口 diff --git a/knowledge/repos/vllm-omni/components/diffusion/_index.md b/knowledge/repos/vllm-omni/components/diffusion/_index.md index 2bd5b05..572eef8 100644 --- a/knowledge/repos/vllm-omni/components/diffusion/_index.md +++ b/knowledge/repos/vllm-omni/components/diffusion/_index.md @@ -29,4 +29,6 @@ sources: [] |---|---| | 理解共享职责和数据流 | [architecture](architecture.md) | | 根据 PR 描述直达 execution parity、checkpoint/distributed 或 quality evidence 的规则组与第一批源码 | [rules 与代码地图](rules.md) | -| step 执行/batching/缓存加速/并行等特性语义 | [特性指南](guides/_index.md) | +| diffusion step 与 request/continuous batching | [step and batching](step-and-batching.md) | +| Cache-DiT、TeaCache 和 prefix cache | [cache acceleration](cache-acceleration.md) | +| TP/PP/SP/CFG/VAE/HSDP 等并行策略 | [parallelism](parallelism.md) | diff --git a/knowledge/repos/vllm-omni/components/diffusion/guides/cache-acceleration.md b/knowledge/repos/vllm-omni/components/diffusion/cache-acceleration.md similarity index 97% rename from knowledge/repos/vllm-omni/components/diffusion/guides/cache-acceleration.md rename to knowledge/repos/vllm-omni/components/diffusion/cache-acceleration.md index dd4ac66..9e0dd34 100644 --- a/knowledge/repos/vllm-omni/components/diffusion/guides/cache-acceleration.md +++ b/knowledge/repos/vllm-omni/components/diffusion/cache-acceleration.md @@ -29,4 +29,4 @@ sources: [docs/design/feature/cache_dit.md, docs/design/feature/teacache.md, vll ## 相关 - 后端选择入口在 `diffusion/registry.py::initialize_model`(加载类、量化、VAE - slicing/tiling、并行注入的同一初始化链);组件边界见 [architecture](../architecture.md)。 + slicing/tiling、并行注入的同一初始化链);组件边界见 [architecture](architecture.md)。 diff --git a/knowledge/repos/vllm-omni/components/diffusion/guides/_index.md b/knowledge/repos/vllm-omni/components/diffusion/guides/_index.md deleted file mode 100644 index 7414440..0000000 --- a/knowledge/repos/vllm-omni/components/diffusion/guides/_index.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "Diffusion 特性指南" -created: 2026-07-16 -updated: 2026-07-16 -type: index -tags: [vllm-omni, components, diffusion] -sources: [docs/design/feature/] ---- - -# Diffusion 特性指南 - -从官方 feature 设计文档(`docs/design/feature/`)沉淀的共享 diffusion 特性语义 -(`main @ 5c390096` 复核)。 - -| 遇到什么 | 查看哪里 | -|---|---| -| step 执行合同与两种 batching 模式 | [step 与 batching](step-and-batching.md) | -| cache_dit / TeaCache 等缓存加速 | [缓存加速](cache-acceleration.md) | -| diffusion 侧并行策略总览 | [并行策略](parallelism.md) | diff --git a/knowledge/repos/vllm-omni/components/diffusion/guides/parallelism.md b/knowledge/repos/vllm-omni/components/diffusion/parallelism.md similarity index 82% rename from knowledge/repos/vllm-omni/components/diffusion/guides/parallelism.md rename to knowledge/repos/vllm-omni/components/diffusion/parallelism.md index a34032c..0f118e7 100644 --- a/knowledge/repos/vllm-omni/components/diffusion/guides/parallelism.md +++ b/knowledge/repos/vllm-omni/components/diffusion/parallelism.md @@ -12,7 +12,7 @@ sources: [docs/design/feature/tensor_parallel.md, docs/design/feature/cfg_parall 每种策略一篇官方 spec(`docs/design/feature/`,均在 `main @ 5c390096` 验证存在): `tensor_parallel.md`、`pipeline_parallel.md`、`sequence_parallel.md`、 `expert_parallel.md`、`cfg_parallel.md`(CFG 正负分支并行——与 -[architecture 的 CFG companion 流](../../serving/architecture.md)相关)、 +[architecture 的 CFG companion 流](../serving/architecture.md)相关)、 `hsdp.md`、`vae_parallel.md`。本页只做路由:读具体策略以对应 spec 为准。 - 源码:`vllm_omni/diffusion/distributed/`(distributed_vae、sp_plan、序列并行 @@ -20,7 +20,7 @@ sources: [docs/design/feature/tensor_parallel.md, docs/design/feature/cfg_parall (sequence parallelism、patch-parallel、VAE slicing/tiling)。 - **配置入口是 config 组件**:`composable_parallel` 的声明式 per-stage 轴栈 (tp/dp/pp/ep/stage_replica 已接线;sp/cfg/vae_pp/hsdp 为保留位)见 - [Configuration](../../configuration/architecture.md);stage 级 `tensor_parallel_size` 等 + [Configuration](../configuration/architecture.md);stage 级 `tensor_parallel_size` 等 字段见 deploy schema。 - 并行度 × 设备容量的启动验收硬规则在 - [Model Executor 规则](../../model-executor/rules.md)。 + [Model Executor 规则](../model-executor/rules.md)。 diff --git a/knowledge/repos/vllm-omni/components/diffusion/guides/step-and-batching.md b/knowledge/repos/vllm-omni/components/diffusion/step-and-batching.md similarity index 92% rename from knowledge/repos/vllm-omni/components/diffusion/guides/step-and-batching.md rename to knowledge/repos/vllm-omni/components/diffusion/step-and-batching.md index f3f4025..2f94834 100644 --- a/knowledge/repos/vllm-omni/components/diffusion/guides/step-and-batching.md +++ b/knowledge/repos/vllm-omni/components/diffusion/step-and-batching.md @@ -33,5 +33,5 @@ sources: [docs/design/feature/diffusion_step_execution.md, docs/design/feature/d ## 相关 -- 噪声调度/采样归 [Diffusion 组件](../_index.md);请求级排队语义见 - [Scheduler 组件](../../scheduler/_index.md)(AR 侧对照)。 +- 噪声调度/采样归 [Diffusion 组件](_index.md);请求级排队语义见 + [Scheduler 组件](../scheduler/_index.md)(AR 侧对照)。 diff --git a/knowledge/repos/vllm-omni/components/distributed/_index.md b/knowledge/repos/vllm-omni/components/distributed/_index.md index 0df0f56..c72febe 100644 --- a/knowledge/repos/vllm-omni/components/distributed/_index.md +++ b/knowledge/repos/vllm-omni/components/distributed/_index.md @@ -50,4 +50,5 @@ sources: [vllm_omni/distributed/omni_connectors/, vllm_omni/distributed/omni_coo | 按 PR 描述直达 connector、KV transfer、load balancer 或 route-port 首批源码 | [本页 Direct 代码快速入口](#direct-代码快速入口) | | 理解 connector 合同、6 后端、KV 迁移管理与负载均衡 | [architecture](architecture.md) | | 已修过的 connector/端口产品坑 | [connector pitfalls](connector-pitfalls.md) | -| 后端选择与 async_chunk 特性语义 | [特性指南](guides/_index.md) | +| 选择和配置 connector backend | [connector backends](connector-backends.md) | +| 跨 stage `async_chunk` 流式语义 | [async chunk](async-chunk.md) | diff --git a/knowledge/repos/vllm-omni/components/distributed/guides/async-chunk.md b/knowledge/repos/vllm-omni/components/distributed/async-chunk.md similarity index 89% rename from knowledge/repos/vllm-omni/components/distributed/guides/async-chunk.md rename to knowledge/repos/vllm-omni/components/distributed/async-chunk.md index 9adc762..d4ae2b7 100644 --- a/knowledge/repos/vllm-omni/components/distributed/guides/async-chunk.md +++ b/knowledge/repos/vllm-omni/components/distributed/async-chunk.md @@ -11,7 +11,7 @@ sources: [docs/design/feature/async_chunk.md, vllm_omni/distributed/omni_connect 官方 spec:`docs/design/feature/async_chunk.md`(`main @ 5c390096` 复核); 传输适配层 `omni_connectors/transfer_adapter/chunk_transfer_adapter.py`, -调度侧等待状态机在 [Scheduler](../../scheduler/architecture.md) 的 +调度侧等待状态机在 [Scheduler](../scheduler/architecture.md) 的 `OmniSchedulingCoordinator`。 - 语义:多 stage pipeline(如 Qwen3-Omni Thinker→Talker→Code2Wav)不等上游 stage @@ -25,11 +25,11 @@ sources: [docs/design/feature/async_chunk.md, vllm_omni/distributed/omni_connect 解码(支持批推理)。 - 配置:deploy 顶层 `async_chunk`(默认 true);端到端跑完的 pipeline 应 pin `false`——单 stage diffusion 必须 `async_chunk: false` 的事故见 - [ci-gotchas](../../../ci/guides/ci-gotchas.md) 第 2 条。 + [ci-gotchas](../../ci/guides/ci-gotchas.md) 第 2 条。 - 性能:spec 附 E2E/TTFT/TPOT/TTFP/RTF/ITL 实测表(并发 1/4/10 × code2wav batch 1/64 等组合)——引用数字前以当前版本原文为准。 ## 相关 - 阈值变差对精度断言的影响(async_chunk 模式阈值 0.65 案例)见 - [accuracy-attribution](../../../ci/guides/accuracy-attribution.md)。 + [accuracy-attribution](../../ci/guides/accuracy-attribution.md)。 diff --git a/knowledge/repos/vllm-omni/components/distributed/guides/connector-backends.md b/knowledge/repos/vllm-omni/components/distributed/connector-backends.md similarity index 86% rename from knowledge/repos/vllm-omni/components/distributed/guides/connector-backends.md rename to knowledge/repos/vllm-omni/components/distributed/connector-backends.md index 4f2eac9..1f788ee 100644 --- a/knowledge/repos/vllm-omni/components/distributed/guides/connector-backends.md +++ b/knowledge/repos/vllm-omni/components/distributed/connector-backends.md @@ -27,11 +27,11 @@ mooncake_transfer_engine,mori_transfer_engine,yuanrong,yuanrong_transfer_engine} 当前所有后端均为 **D2H2D**(device→host→device)模式。deploy YAML 里的 connector 声明与 stage 引用语法(顶层 `connectors:` + per-stage `input_connectors`/`output_connectors`)见 -[Configuration](../../configuration/architecture.md);`extra` 键(如 SHM 的 +[Configuration](../configuration/architecture.md);`extra` 键(如 SHM 的 `shm_threshold_bytes` 默认 65536;Mooncake 的 host/metadata_server/master/ segment/localbuf/proto)见 config spec 的 connector schema 表。 ## 相关 -- 合同与实现边界见 [architecture](../architecture.md);已修产品坑见 - [connector pitfalls](../connector-pitfalls.md)。 +- 合同与实现边界见 [architecture](architecture.md);已修产品坑见 + [connector pitfalls](connector-pitfalls.md)。 diff --git a/knowledge/repos/vllm-omni/components/distributed/guides/_index.md b/knowledge/repos/vllm-omni/components/distributed/guides/_index.md deleted file mode 100644 index 9a41b45..0000000 --- a/knowledge/repos/vllm-omni/components/distributed/guides/_index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "Distributed 特性指南" -created: 2026-07-16 -updated: 2026-07-16 -type: index -tags: [vllm-omni, components, distributed] -sources: [docs/design/feature/omni_connectors/, docs/design/feature/async_chunk.md] ---- - -# Distributed 特性指南 - -| 遇到什么 | 查看哪里 | -|---|---| -| 六个 connector 后端的选择与配置 | [connector 后端](connector-backends.md) | -| 跨 stage 分块流式(async_chunk)语义 | [async chunk](async-chunk.md) | diff --git a/knowledge/repos/vllm-omni/components/serving/rules.md b/knowledge/repos/vllm-omni/components/serving/rules.md index d4f7f61..8aa99a5 100644 --- a/knowledge/repos/vllm-omni/components/serving/rules.md +++ b/knowledge/repos/vllm-omni/components/serving/rules.md @@ -4,7 +4,7 @@ created: 2026-07-20 updated: 2026-07-31 type: rule tags: [vllm-omni, components, serving] -sources: ["PR #3576", "PR #4718", "PR #5157", "claude-workflow-starter-private@09dca46", "zuiho-kai/claude-workflow-starter@c217fc6", vllm_omni/entrypoints/openai/diffusion_request_utils.py, vllm_omni/entrypoints/openai/serving_speech.py, vllm_omni/metrics/prometheus.py] +sources: ["PR #3576", "PR #4718", "PR #4834", "PR #4905", "PR #4912", "PR #5157", "claude-workflow-starter-private@09dca46", "zuiho-kai/claude-workflow-starter@c217fc6", vllm_omni/entrypoints/async_omni.py, vllm_omni/entrypoints/openai/diffusion_request_utils.py, vllm_omni/entrypoints/openai/serving_speech.py, vllm_omni/metrics/prometheus.py] confidence: high --- @@ -20,6 +20,9 @@ confidence: high | PR 描述在做什么 | 精确规则组 | 第一批 live 源码 | |---|---|---| | `extra_body`、flattened/nested/canonical/legacy 输入、alias、`negative_prompt`、diffusion request extras | `request-contract`:`SERV-4a`–`4h` | `vllm_omni/entrypoints/openai/diffusion_request_utils.py::{normalize_diffusion_request_args,apply_normalized_diffusion_request_extra_args}` → `serving_chat.py::{OmniOpenAIServingChat._preprocess_chat,OmniOpenAIServingChat.generate_diffusion_images}` | +| `chat_template_kwargs`、raw HTTP/SDK `extra_body`、text/audio modalities、choices、空音频 | `chat-multimodal-contract`:`SERV-4c` + 命中模型规则 | upstream `ChatCompletionRequest` → `serving_chat.py::{OmniOpenAIServingChat._preprocess_chat,OmniOpenAIServingChat.chat_completion_full_generator,OmniOpenAIServingChat._create_text_choice,OmniOpenAIServingChat._create_audio_choice}` | +| endpoint restriction、unsupported route、capability、completions/chat/speech 400 | `endpoint-capability`:`SERV-4c`, `SERV-4d` | `config/endpoint_policy.py::{OmniServingCapability,shutdown_unsupported_routes}` → `config/config_factory.py::StageConfigFactory.get_pipeline_endpoint_restrictions` → `engine/async_omni_engine.py::AsyncOmniEngine.__init__` → `entrypoints/openai/api_server.py::build_app` | +| sleep/wake、partial stage/tag、idempotency、ACK、generation admission | `engine-lifecycle`:`SERV-5a`, `SERV-5b` | `entrypoints/async_omni.py::{AsyncOmni.sleep,AsyncOmni.wake_up,AsyncOmni.generate}` → `worker/base.py::{handle_sleep_task,handle_wake_task}` / `diffusion/worker/diffusion_worker.py` | | SSE/streaming speech、audio format、PCM/WAV、speed、首 chunk 前校验 | `streaming-format`:`SERV-1a`, `SERV-1b` | `vllm_omni/entrypoints/openai/protocol/audio.py::{OpenAICreateSpeechRequest.validate_streaming_constraints,StreamingSpeechSessionConfig.validate_streaming_constraints}` → `serving_speech.py::{OmniOpenAIServingSpeech._validate_speech_streaming_request,OmniOpenAIServingSpeech.create_speech}` | | `ref_audio`、x-vector/ICL、artifact cache、readiness、失败后 engine 存活 | `artifact-readiness`:`SERV-3a`, `SERV-3b` | `vllm_omni/entrypoints/openai/serving_speech.py::{_qwen3_tts_can_use_ref_audio_artifact_only,_track_ref_audio_artifact_warmup,_mark_ref_audio_artifact_ready_for_request,_discard_ref_audio_artifact_ready_if_unreferenced}` | | Prometheus、waiting/running gauge、replica stats、throttle、collector lifecycle | `metrics-lifecycle`:`SERV-2a`, `SERV-2b` | `vllm_omni/entrypoints/omni_base.py::{OmniBase._log_summary_and_cleanup,OmniBase._process_stage_metrics_message}` → `vllm_omni/metrics/prometheus.py::{OmniPrometheusMetrics.__init__,set_running,set_waiting}` | @@ -30,6 +33,9 @@ confidence: high | `streaming-format` | SSE、audio streaming、format/default/capability | `SERV-1a`, `SERV-1b` | | `metrics-lifecycle` | metrics、gauge、replica、collector | `SERV-2a`, `SERV-2b` | | `artifact-readiness` | artifact cache、capability、ready/mark/discard | `SERV-3a`, `SERV-3b` | +| `chat-multimodal-contract` | chat template kwargs、SDK flatten、text/audio response shape | `SERV-4c` + 命中模型规则 | +| `endpoint-capability` | endpoint restriction、unsupported route、公开 400 | `SERV-4c`, `SERV-4d` | +| `engine-lifecycle` | sleep/wake、partial stage/tag、ACK、generation admission | `SERV-5a`, `SERV-5b` | | `request-contract` | 请求字段、来源、冲突、dispatcher、consumer view | `SERV-4a`, `SERV-4b`, `SERV-4c`, `SERV-4d`, `SERV-4e`, `SERV-4f`, `SERV-4g`, `SERV-4h` | | `author-routing` | 只供 Direct reviewer 导航,不作为 finding 规则 | `SERV-0a`, `SERV-0b` | @@ -165,5 +171,26 @@ confidence: high - 禁止:继续堆 helper、compatibility branch 或 reviewer-specific patch。 - 验收:恢复编码前 owner、consumer、删除项和 diff 预算都有可检查记录。 +## Engine 生命周期合同 + +### SERV-5a — sleep/wake 状态必须保留 stage 和 tag 作用域 + +- 触发:sleep/wake 接受 `stage_ids`、resource tags 或 partial wake。 +- 强制:状态 key 与公开操作的 stage/tag 作用域一致;只有全部必需 stage/tag 已 warm + 才放行 generation。 +- 禁止:用一个全局 tag set 表示多 stage 状态;唤醒一个 stage 后清掉其他 stage 的 + sleeping 状态或把后续定向 wake 当成 already warm。 +- 验收:sleep 两个 stage、只 wake 一个时 generation 仍拒绝,随后 wake 另一个才放行。 + ^[PR #4834] + +### SERV-5b — 只有成功 ACK 和真实 backend capability 才能转为 warm + +- 触发:worker ACK 可返回 error,或不同 backend 对 level-2 restore 能力不同。 +- 强制:逐目标确认成功 ACK 后再清状态;level-2 能力按 backend/stage 表达。 +- 禁止:错误 ACK 也清 tag;用 engine 全局禁令误伤已经支持 restore 的 diffusion worker。 +- 验收:失败 ACK 保留 sleeping 状态;支持 level-2 的 diffusion 路径仍能 + sleep → wake → generate,不支持的 stage 在调用 worker 前明确拒绝。 + ^[PR #4834] ^[PR #4905] ^[PR #4912] + 请求到 engine 的边界见 [Serving architecture](architecture.md);公开协议通用检查见 [review contracts](../../../../general/review/guides/reviewer-lens-contracts.md)。 diff --git a/knowledge/repos/vllm-omni/docs/design-doc-map.md b/knowledge/repos/vllm-omni/docs/design-doc-map.md index ba2bbcc..20ae4ef 100644 --- a/knowledge/repos/vllm-omni/docs/design-doc-map.md +++ b/knowledge/repos/vllm-omni/docs/design-doc-map.md @@ -21,13 +21,13 @@ Overview、5 篇 feature、metrics、3 篇 module);**完整树比索引大 | `module/ar_module.md` | AR 模块继承链与请求流转 | [scheduler](../components/scheduler/architecture.md) + [model-executor](../components/model-executor/architecture.md) | | `module/dit_module.md` | Diffusion 引擎/调度/worker/pipeline/加速组件 | [diffusion](../components/diffusion/architecture.md) | | `module/entrypoint_module.md` | **stub("update soon")——上游文档缺口** | [serving](../components/serving/_index.md) | -| `feature/disaggregated_inference.md` + `omni_connectors/*` | connector 选择矩阵与逐后端 spec | [distributed guides](../components/distributed/guides/connector-backends.md) | -| `feature/diffusion_step_execution / request_level / continuous_batching` | step 合同与两种 batching | [diffusion guides](../components/diffusion/guides/step-and-batching.md) | -| `feature/async_chunk.md` | 跨 stage 分块流式 | [distributed guides](../components/distributed/guides/async-chunk.md) | -| `feature/cache_dit.md`、`teacache.md`、`prefix_caching.md` | 缓存加速 | [diffusion guides](../components/diffusion/guides/cache-acceleration.md) | -| `feature/{tensor,pipeline,sequence,expert,cfg,vae}_parallel.md`、`hsdp.md` | 并行策略 | [diffusion guides](../components/diffusion/guides/parallelism.md) | +| `feature/disaggregated_inference.md` + `omni_connectors/*` | connector 选择矩阵与逐后端 spec | [distributed](../components/distributed/connector-backends.md) | +| `feature/diffusion_step_execution / request_level / continuous_batching` | step 合同与两种 batching | [diffusion](../components/diffusion/step-and-batching.md) | +| `feature/async_chunk.md` | 跨 stage 分块流式 | [distributed](../components/distributed/async-chunk.md) | +| `feature/cache_dit.md`、`teacache.md`、`prefix_caching.md` | 缓存加速 | [diffusion](../components/diffusion/cache-acceleration.md) | +| `feature/{tensor,pipeline,sequence,expert,cfg,vae}_parallel.md`、`hsdp.md` | 并行策略 | [diffusion](../components/diffusion/parallelism.md) | | `feature/ray_based_execution.md` | Ray vs MP 后端、多机集群 | [serving](../components/serving/_index.md)(暂无专页) | | `metrics.md`、`qwen3_omni_tts_performance_optimization.md` | Prometheus 指标;TTS 性能优化实录 | [qwen-omni](../models/qwen-omni/architecture.md)(perf 部分) | | `docs/configuration/*` | 配置 schema spec | [configuration](../components/configuration/architecture.md) | | `docs/contributing/ci/*` | L1–L5 与 markers | [ci guides](../ci/guides/test-tiers.md) | -| `docs/contributing/model/*` | 加模型三条路径 | [adding-a-model](../components/configuration/guides/adding-a-model.md) | +| `docs/contributing/model/*` | 加模型三条路径 | [adding-a-model](../components/configuration/adding-a-model.md) | diff --git a/knowledge/repos/vllm-omni/models/_index.md b/knowledge/repos/vllm-omni/models/_index.md index 866c719..ae2e5f1 100644 --- a/knowledge/repos/vllm-omni/models/_index.md +++ b/knowledge/repos/vllm-omni/models/_index.md @@ -1,5 +1,5 @@ --- -title: "vLLM-Omni 模型" +title: "vLLM-Omni 模型 owner" created: 2026-07-10 updated: 2026-07-31 type: index @@ -7,93 +7,25 @@ tags: [vllm-omni, models] sources: [] --- -# vLLM-Omni 模型 + -有运行经验沉淀(rules/incidents/history)的家族在上半表;2026-07-21 起,全部 -registry 家族均有源码派生落脚页(`main @ 5d44868e` 复核,全量清单见文末 -"全局入口")。 +# 模型 owner -## 有经验沉淀的家族 +模型目录就是清单,不再在本页手工复制几十个目录名。 -| 模型 | 查看哪里 | -|---|---| -| Cosmos3(常规 / Edge / Distilled) | [cosmos3](cosmos3/_index.md) | -| FLUX.2(含 Mistral text encoder FP8) | [flux2](flux2/_index.md) | -| HunyuanImage3 | [hunyuan-image3](hunyuan-image3/_index.md) | -| Krea 2 | [krea2](krea2/_index.md) | -| LTX-2 家族(含 2.3) | [ltx2](ltx2/_index.md) | -| MiniCPM-o 4.5 | [minicpm-o-4-5](minicpm-o-4-5/_index.md) | -| Ming-Omni-TTS(dense / MoE) | [ming-omni-tts](ming-omni-tts/_index.md) | -| Qwen-Omni 多模态家族(2.5/3) | [qwen-omni](qwen-omni/_index.md) | -| Qwen3-TTS(ref audio / artifact cache) | [qwen3-tts](qwen3-tts/_index.md) | +```powershell +Get-ChildItem knowledge/repos/vllm-omni/models -Directory | + Select-Object -ExpandProperty Name +``` -## 多 stage / 统一模型家族(源码派生) +## 怎么选 -| 模型 | 查看哪里 | -|---|---| -| BAGEL(多形态部署参照) | [bagel](bagel/_index.md) | -| GLM-Image(AR→DiT token 桥,i2i 参照) | [glm-image](glm-image/_index.md) | -| Lance(BAGEL 谱系统一模型) | [lance](lance/_index.md) | -| MammothModa2(DiT 跑在 LLM_GENERATION) | [mammoth-moda2](mammoth-moda2/_index.md) | -| Ming-flash-omni(BailingMM2,4 拓扑) | [ming-flash-omni](ming-flash-omni/_index.md) | -| Dynin-Omni(三 stage,远程代码为主) | [dynin-omni](dynin-omni/_index.md) | -| Aura-Omni(4-stage 组合管线) | [aura-omni](aura-omni/_index.md) | +1. PR title/body 有明确模型名:直接进入同名目录。 +2. 名称、别名或 registry key 不确定:查 + [catalog / Direct 模型代码入口](catalog.md#direct-模型代码入口)。 +3. 需要找相近实现:查 [reference models](reference-models.md)。 +4. 目录只有 `_index.md` 时,把它当源码落脚页;有 `rules.md` 时优先读规则; + 只有需要解释完整拓扑时才读 `architecture.md`。 -## 语音/音频家族(源码派生) - -| 模型 | 查看哪里 | -|---|---| -| Higgs-Audio V2/V3 | [higgs-audio](higgs-audio/_index.md) | -| MiMo-Audio(融合 thinker+talker) | [mimo-audio](mimo-audio/_index.md) | -| Step-Audio2(音频 token 内嵌词表) | [step-audio2](step-audio2/_index.md) | -| MOSS-TTS 家族(Delay/Realtime/Local/Nano) | [moss-tts](moss-tts/_index.md) | -| Fish Speech S2 Pro(fish_qwen3_omni) | [fish-qwen3-omni](fish-qwen3-omni/_index.md) | -| IndexTTS2(非流式两 stage) | [indextts2](indextts2/_index.md) | -| CosyVoice3(RAS 合并停止,TRT) | [cosyvoice3](cosyvoice3/_index.md) | -| VoxCPM2(单 stage AR,48 kHz) | [voxcpm2](voxcpm2/_index.md) | -| SoulX-Singer(SVS/SVC 歌声) | [soulx-singer](soulx-singer/_index.md) | -| Covo-Audio | [covo-audio](covo-audio/_index.md) | -| GLM-TTS | [glm-tts](glm-tts/_index.md) | -| OmniVoice(离散扩散 TTS) | [omnivoice](omnivoice/_index.md) | -| Voxtral TTS | [voxtral-tts](voxtral-tts/_index.md) | -| AudioX(文/视频条件音频) | [audiox](audiox/_index.md) | -| Stable Audio Open | [stable-audio](stable-audio/_index.md) | -| MagiHuman(音频驱动人像视频) | [magi-human](magi-human/_index.md) | - -## 视频/机器人家族(源码派生) - -| 模型 | 查看哪里 | -|---|---| -| Wan 2.2(六架构:T2V/I2V/VACE/S2V/DMD2) | [wan2-2](wan2-2/_index.md) | -| HunyuanVideo-1.5 | [hunyuan-video](hunyuan-video/_index.md) | -| Helios(分块长视频) | [helios](helios/_index.md) | -| DreamZero(VLA 世界模型,AR-Diffusion 引擎) | [dreamzero](dreamzero/_index.md) | -| GR00T N1.7(VLA,actions 输出) | [gr00t](gr00t/_index.md) | -| InternVLA-A1(VLA) | [internvla-a1](internvla-a1/_index.md) | -| DreamID-Omni(Wan 基座音视频身份) | [dreamid-omni](dreamid-omni/_index.md) | - -## 图像家族(源码派生) - -| 模型 | 查看哪里 | -|---|---| -| Qwen-Image(五变体) | [qwen-image](qwen-image/_index.md) | -| FLUX.1(base/Kontext/DMD2) | [flux](flux/_index.md) | -| FLUX.2-Klein | [flux2-klein](flux2-klein/_index.md) | -| HiDream-I1(MoE DiT) | [hidream-image](hidream-image/_index.md) | -| LongCat-Image(T2I+编辑) | [longcat-image](longcat-image/_index.md) | -| OmniGen2(指令图像生成/编辑) | [omnigen2](omnigen2/_index.md) | -| Ovis-Image | [ovis-image](ovis-image/_index.md) | -| ERNIE-Image | [ernie-image](ernie-image/_index.md) | -| NextStep-1.1(AR 图像生成) | [nextstep-1-1](nextstep-1-1/_index.md) | -| SenseNova-U1(统一 LLM,无 VAE) | [sensenova-u1](sensenova-u1/_index.md) | -| Z-Image | [z-image](z-image/_index.md) | -| SD3 | [sd3](sd3/_index.md) | -| SDXL(唯一 UNet/epsilon) | [sdxl](sdxl/_index.md) | -| Diffusers Adapter(通用黑盒桥) | [diffusers-adapter](diffusers-adapter/_index.md) | - -## 全局入口 - -| 遇到什么 | 查看哪里 | 说明 | -|---|---|---| -| PR 描述/别名或 registry key 自动定位模型目录 | [catalog / Direct 模型代码入口](catalog.md#direct-模型代码入口) | 搜三处 registry,进入 AR/diffusion models 目录 | -| 新模型适配的参照定位 | [reference-models](reference-models.md) | GLM-Image/BAGEL/Qwen-Omni 等 | +选择一个模型 owner 后停止枚举其他模型。跨模型共用的不变量应进入 +[components](../components/_index.md),不要复制到多个模型目录。 diff --git a/knowledge/repos/vllm-omni/models/aura-omni/_index.md b/knowledge/repos/vllm-omni/models/aura-omni/_index.md index 51d088f..f88d714 100644 --- a/knowledge/repos/vllm-omni/models/aura-omni/_index.md +++ b/knowledge/repos/vllm-omni/models/aura-omni/_index.md @@ -46,4 +46,4 @@ sources: [vllm_omni/model_executor/models/aura_omni/, vllm_omni/deploy/aura_omni - 审查 aura_omni 拓扑、config shim 或 stage 复用改动;qwen3_tts 侧行为变化会 直接影响本家族 stage 2–3。 -- 新模型注册点清单见 [adding-a-model](../../components/configuration/guides/adding-a-model.md)。 +- 新模型注册点清单见 [adding-a-model](../../components/configuration/adding-a-model.md)。 diff --git a/knowledge/repos/vllm-omni/models/diffusers-adapter/_index.md b/knowledge/repos/vllm-omni/models/diffusers-adapter/_index.md index 19ad5a9..c9b94c4 100644 --- a/knowledge/repos/vllm-omni/models/diffusers-adapter/_index.md +++ b/knowledge/repos/vllm-omni/models/diffusers-adapter/_index.md @@ -37,5 +37,5 @@ sources: [vllm_omni/diffusion/models/diffusers_adapter/, vllm_omni/diffusion/reg - 判断一个 diffusers-only 模型能否先经 adapter 服务再做原生适配;审查 adapter IO 胶水或量化转换改动。 -- 原生适配流程见 [adding-a-model](../../components/configuration/guides/adding-a-model.md); +- 原生适配流程见 [adding-a-model](../../components/configuration/adding-a-model.md); 共享实现归属见 [Diffusion 组件](../../components/diffusion/_index.md)。 diff --git a/knowledge/repos/vllm-omni/models/glm-image/_index.md b/knowledge/repos/vllm-omni/models/glm-image/_index.md index f755564..a2e46c2 100644 --- a/knowledge/repos/vllm-omni/models/glm-image/_index.md +++ b/knowledge/repos/vllm-omni/models/glm-image/_index.md @@ -11,7 +11,7 @@ sources: [vllm_omni/model_executor/models/glm_image/, vllm_omni/diffusion/models 以下事实在 `main @ 5d44868e` 复核。**树内定位**(知识树自身的路由约定,非源码 事实):AR→DiT 图像编辑(i2i/IT2I)行为对齐时的参照家族——hunyuan 的 -[it2i-gap](../hunyuan-image3/guides/it2i-gap.md) 以它为对齐基准,定位依据见 +[it2i-gap](../hunyuan-image3/it2i-gap.md) 以它为对齐基准,定位依据见 [reference-models](../reference-models.md)。 ## 名称与范围 diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/_index.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/_index.md index a7c6400..db2b364 100644 --- a/knowledge/repos/vllm-omni/models/hunyuan-image3/_index.md +++ b/knowledge/repos/vllm-omni/models/hunyuan-image3/_index.md @@ -26,6 +26,11 @@ sources: [] |---|---| | 修改公开入口、prompt、AR→DiT、`model_extras`、shared task examples、条件图、size 或 seed | [开发快速入口和 rules](rules.md#开发快速入口) | | 理解模型和 vLLM-Omni 代码地图 | [architecture](architecture.md) | -| HF 对齐、prompt 和运行方法 | [model guides](guides/_index.md) | +| HF 接入常见偏差 | [HF alignment pitfalls](hf-alignment-pitfalls.md) | +| 运行 HF baseline | [HF baseline runbook](hf-baseline-runbook.md) | +| 对齐 HF 与 Omni 输出 | [HF/Omni alignment method](hf-omni-alignment-method.md) | +| 调查 img-to-img 差距 | [it2i gap](it2i-gap.md) | +| 核对官方 prompt 格式 | [official prompt format](official-prompt-format.md) | +| 运行 image generation demo | [run image-gen demo](run-image-gen-demo.md) | | 调查模型专有错误 | [incidents](incidents/_index.md) | | 查询已结束的历史分析 | [history](history/_index.md) | diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/_index.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/_index.md deleted file mode 100644 index 2204efb..0000000 --- a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/_index.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "HunyuanImage3 指南" -created: 2026-07-10 -updated: 2026-07-10 -type: index -tags: [vllm-omni, models, hunyuan-image3] -sources: [] ---- - -# HunyuanImage3 指南 - -| 遇到什么 | 查看哪里 | -|---|---| -| 对齐 HF 前检查常见陷阱 | [HF alignment pitfalls](hf-alignment-pitfalls.md) | -| 跑 HF baseline | [HF baseline runbook](hf-baseline-runbook.md) | -| 系统化对齐 HF 和 Omni | [HF/Omni alignment](hf-omni-alignment-method.md) | -| 调查 IT2I gap | [IT2I gap](it2i-gap.md) | -| 使用官方 prompt 格式 | [official prompt format](official-prompt-format.md) | -| 运行官方 image generation demo | [image gen demo](run-image-gen-demo.md) | diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/hf-alignment-pitfalls.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/hf-alignment-pitfalls.md similarity index 100% rename from knowledge/repos/vllm-omni/models/hunyuan-image3/guides/hf-alignment-pitfalls.md rename to knowledge/repos/vllm-omni/models/hunyuan-image3/hf-alignment-pitfalls.md diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/hf-baseline-runbook.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/hf-baseline-runbook.md similarity index 100% rename from knowledge/repos/vllm-omni/models/hunyuan-image3/guides/hf-baseline-runbook.md rename to knowledge/repos/vllm-omni/models/hunyuan-image3/hf-baseline-runbook.md diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/hf-omni-alignment-method.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/hf-omni-alignment-method.md similarity index 100% rename from knowledge/repos/vllm-omni/models/hunyuan-image3/guides/hf-omni-alignment-method.md rename to knowledge/repos/vllm-omni/models/hunyuan-image3/hf-omni-alignment-method.md diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/history/legacy-error-summary.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/history/legacy-error-summary.md index bf5f276..72ffe27 100644 --- a/knowledge/repos/vllm-omni/models/hunyuan-image3/history/legacy-error-summary.md +++ b/knowledge/repos/vllm-omni/models/hunyuan-image3/history/legacy-error-summary.md @@ -55,4 +55,4 @@ **衍生教训**:HF `prepare_model_inputs(...)` 返回的 kw dict 自带 `max_new_tokens` / `eos_token_id`(来自 generation_config),调 `model.generate(**kw, max_new_tokens=2048, eos_token_id=[...])` 撞 `TypeError`。必先 `kw.pop("max_new_tokens", None); kw.pop("eos_token_id", None)`。 -当前方法见 [HF alignment pitfalls](../guides/hf-alignment-pitfalls.md)。 +当前方法见 [HF alignment pitfalls](../hf-alignment-pitfalls.md)。 diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/it2i-gap.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/it2i-gap.md similarity index 100% rename from knowledge/repos/vllm-omni/models/hunyuan-image3/guides/it2i-gap.md rename to knowledge/repos/vllm-omni/models/hunyuan-image3/it2i-gap.md diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/official-prompt-format.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/official-prompt-format.md similarity index 100% rename from knowledge/repos/vllm-omni/models/hunyuan-image3/guides/official-prompt-format.md rename to knowledge/repos/vllm-omni/models/hunyuan-image3/official-prompt-format.md diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/rules.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/rules.md index 6054cb8..7c0ac4a 100644 --- a/knowledge/repos/vllm-omni/models/hunyuan-image3/rules.md +++ b/knowledge/repos/vllm-omni/models/hunyuan-image3/rules.md @@ -4,7 +4,7 @@ created: 2026-07-13 updated: 2026-07-31 type: rule tags: [vllm-omni, models, hunyuan-image3] -sources: [incidents/painterly/_index.md, guides/hf-alignment-pitfalls.md, vllm_omni/diffusion/models/hunyuan_image3/prompt_utils.py, vllm_omni/model_extras/hunyuan_image3.py, vllm_omni/model_extras/registry.py] +sources: [incidents/painterly/_index.md, hf-alignment-pitfalls.md, vllm_omni/diffusion/models/hunyuan_image3/prompt_utils.py, vllm_omni/model_extras/hunyuan_image3.py, vllm_omni/model_extras/registry.py] --- # HunyuanImage3 开发规则 @@ -63,7 +63,7 @@ sources: [incidents/painterly/_index.md, guides/hf-alignment-pitfalls.md, vllm_o - **HY3-1c — 内部字段保持正交。** `task` 表示用户要做什么,`bot_task` 表示 AR 怎样生成;进入模型计划后两者不得互相充当默认值。 - **HY3-1d — legacy 有回归证据。** 新旧公开入口各保留一个行为测试。 - **HY3-1e — 单一模型计划。** prompt、stage transition、final stop、CoT 边界和 DiT prompt 必须由同一份模型专属计划导出。每种模式同时写明真实交接机制是 token IDs、decoded text、KV、图片状态、其他 stage state,还是没有下游阶段;字段出现在字典里或没有直接 reader 都不能单独证明对错。 -- **HY3-1f — 官方主入口是语义基线。** 对齐官方 `generate_image()` 等真实用户入口,不用绕过阶段跳转的底层 `generate()` 代替。机制解释见 [HF alignment pitfalls](guides/hf-alignment-pitfalls.md)。 +- **HY3-1f — 官方主入口是语义基线。** 对齐官方 `generate_image()` 等真实用户入口,不用绕过阶段跳转的底层 `generate()` 代替。机制解释见 [HF alignment pitfalls](hf-alignment-pitfalls.md)。 - **HY3-1g — 模型语义留在 owner。** shared serving 不实现 HunyuanImage3 状态机,不导入模型 prompt helper,也不堆模型名称分支;它只传通用请求事实并调用模型 owner 暴露的 adapter/capability,模型专属默认值和跳转计划留在 owner。 - **HY3-1h — 行为表逐行验收。** 每行必须同时给出官方源码、vLLM-Omni consumer 和测试证据;受影响行缺少任一项时状态只能是 `implementation draft`。 - **HY3-1i — 先证明阶段合同。** 在要求某段 AR text、KV 或图片被 DiT 直接读取前,必须从官方用户入口和当前 topology 证明该值就是阶段合同的一部分。若 canonical 路径通过其他 state 完成跳转,或当前模式没有 DiT,不能因为搜索不到字段 reader 就报缺 consumer。 @@ -84,7 +84,7 @@ sources: [incidents/painterly/_index.md, guides/hf-alignment-pitfalls.md, vllm_o - **HY3-3a — 官方分段 tokenization。** HunyuanImage3 chat prompt 使用官方分段 tokenization;需要 Token 级对齐时传 `prompt_token_ids`,不得静默退回整串 BPE。 - **HY3-3b — 缺少模型工件就 fail fast。** tokenizer、processor 或模型专属配置缺失时在 owner 边界报出具体缺项,不切到会改变 token 边界的路径。 - **HY3-3c — system prompt 是完整合同。** 类型、正文、尾部换行、normalization 点和 bot prefix 都必须与对应官方入口一致;不得随手 `strip()` 或保留空白,也不得把一个官方入口的 normalization 推广到另一条 token path。差异必须由真实入口和 token IDs 证明。 -- **HY3-3d — 使用真实 tokenizer 验收。** 至少一个测试使用真实 tokenizer/processor,并同时断言 token ids、raw prompt、system prompt 和图像占位符数量。格式解释见 [official prompt format](guides/official-prompt-format.md)。 +- **HY3-3d — 使用真实 tokenizer 验收。** 至少一个测试使用真实 tokenizer/processor,并同时断言 token ids、raw prompt、system prompt 和图像占位符数量。格式解释见 [official prompt format](official-prompt-format.md)。 - **HY3-3e — stop 和 sampling 在 owner 构造点确定。** 每个受影响模式列出完整 stop token 集合、finish 边界和 sampling defaults。优先修改 stage config 或受支持的构造 API;构造完成后直接改公开字段时,必须证明 scheduler 内部集合也同步。stop 修复不得顺手改变 temperature、top-p、top-k 或其他无关默认值。 - **HY3-3f — 资源获取服从 topology。** 获取 tokenizer、processor、engine 或 stage resource 前,列出哪些 topology 拥有它、默认 CLI 走哪条 topology,以及不存在时的 owner 路径。至少跑一个默认入口和一个受影响入口;不能因为 AR-first 路径有 stage-0 tokenizer 就让 diffusion-only 路径启动即失败。 diff --git a/knowledge/repos/vllm-omni/models/hunyuan-image3/guides/run-image-gen-demo.md b/knowledge/repos/vllm-omni/models/hunyuan-image3/run-image-gen-demo.md similarity index 100% rename from knowledge/repos/vllm-omni/models/hunyuan-image3/guides/run-image-gen-demo.md rename to knowledge/repos/vllm-omni/models/hunyuan-image3/run-image-gen-demo.md diff --git a/knowledge/repos/vllm-omni/models/reference-models.md b/knowledge/repos/vllm-omni/models/reference-models.md index 63d265e..26db307 100644 --- a/knowledge/repos/vllm-omni/models/reference-models.md +++ b/knowledge/repos/vllm-omni/models/reference-models.md @@ -20,7 +20,7 @@ sources: [vllm_omni/model_executor/models/registry.py, vllm_omni/config/pipeline ## GLM-Image — AR+DiT 多 stage 的 IT2I 精度参照 - 何时参考:做 AR→DiT 桥接、IT2I 行为对齐时(hunyuan 的 - [it2i-gap](hunyuan-image3/guides/it2i-gap.md) 与 + [it2i-gap](hunyuan-image3/it2i-gap.md) 与 [ar-dit-bridge 历史](hunyuan-image3/history/_index.md) 均以它为基准)。 - 落脚页:[glm-image](glm-image/_index.md)(token 桥、编辑 KV cache、 魔数矩阵、MRoPE 隐性依赖)。 @@ -44,6 +44,6 @@ sources: [vllm_omni/model_executor/models/registry.py, vllm_omni/config/pipeline ## 相关 -- 加模型的注册点清单见 [adding-a-model](../components/configuration/guides/adding-a-model.md)。 +- 加模型的注册点清单见 [adding-a-model](../components/configuration/adding-a-model.md)。 - 语义验收(plumbing≠语义)见 [model-adaptation-guardrails](../review/guides/model-adaptation-guardrails.md)。 diff --git a/knowledge/repos/vllm-omni/review/_index.md b/knowledge/repos/vllm-omni/review/_index.md index ce73b7c..69dec1f 100644 --- a/knowledge/repos/vllm-omni/review/_index.md +++ b/knowledge/repos/vllm-omni/review/_index.md @@ -1,7 +1,7 @@ --- title: "vLLM-Omni 代码审查" created: 2026-07-10 -updated: 2026-07-20 +updated: 2026-07-31 type: index tags: [vllm-omni, review] sources: [] @@ -9,17 +9,12 @@ sources: [] # vLLM-Omni 代码审查 -## 什么时候查这里 +默认从 PR title/body 直接进入 component/model owner;changed files 只校验范围。本目录 +只放 vLLM-Omni 特有的审查方法,不再承担 owner 导航。 -- 审查 vLLM-Omni 的模型适配、配置桥接或仓库专有改动。 -- 需要把 changed files 路由到 benchmark、component 或 model owner。 - -## 不放什么 - -- 跨仓库通用审查方法;先看 `general/review/`。 - -## 目录内容 - -| 遇到什么 | 查看哪里 | +| 具体问题 | 查看哪里 | |---|---| -| 审查新模型、pipeline 或近期 maintainer 风险模式 | [review guides](guides/_index.md) | +| PR 描述如何路由精确 owner/model 代码地图 | [maintainer pattern routing](guides/maintainer-pattern-routing.md) | +| 模型适配是否漏掉必要链路 | [model adaptation guardrails](guides/model-adaptation-guardrails.md) | +| 模型验证是否证明语义正确 | [model validation](guides/model-validation.md) | +| 维护或浏览本目录 | [guides index](guides/_index.md) | diff --git a/knowledge/tools/check_knowledge_tree.py b/knowledge/tools/check_knowledge_tree.py index 58acd58..d76dd4d 100644 --- a/knowledge/tools/check_knowledge_tree.py +++ b/knowledge/tools/check_knowledge_tree.py @@ -16,6 +16,7 @@ SPECIAL_PAGES = {INDEX_NAME, "rules.md", "architecture.md"} GROUP_DIRS = {"guides", "history", "incidents", "references", "results", "rfcs"} SOURCE_OWNER_DIRS = {"components", "models"} +FILESYSTEM_CHILD_INDEX = "" INCIDENT_NAME = re.compile(r"^\d{4}-\d{2}-\d{2}-[a-z0-9][a-z0-9-]*\.md$") MARKDOWN_LINK = re.compile(r"!?\[[^\]]*\]\(([^)]+)\)") INCIDENT_FIELDS = ("- 编号:", "- 归属:", "- 状态:", "- 搜索词:", "- 影响范围:") @@ -148,6 +149,14 @@ def has_markdown(path: Path) -> bool: return any(path.rglob("*.md")) +def uses_filesystem_child_index(directory: Path, index_text: str) -> bool: + """Allow model families to be discovered from the directory itself.""" + return ( + directory.name == "models" + and FILESYSTEM_CHILD_INDEX in index_text + ) + + def check_file_size(path: Path, index_text: str) -> None: text = read_text(path) non_empty_lines = sum(1 for line in text.splitlines() if line.strip()) @@ -257,7 +266,9 @@ def check_directory(directory: Path) -> None: for child in child_dirs: child_index = (child / INDEX_NAME).resolve() registrations = index_targets.count(child_index) - if registrations == 0: + if registrations == 0 and not uses_filesystem_child_index( + directory, index_text + ): errors.append( f"子目录没有登记到上一层索引:{display(child)} " f"(应在 {display(index)} 链接 {child.name}/{INDEX_NAME})" @@ -297,12 +308,30 @@ def owner_axis_violations(repo: Path) -> list[str]: return violations +def source_owner_guide_violations(repo: Path) -> list[str]: + """Keep component/model feature pages directly under their owner.""" + violations: list[str] = [] + for axis in SOURCE_OWNER_DIRS: + axis_root = repo / axis + if not axis_root.is_dir(): + continue + for owner in axis_root.iterdir(): + guides = owner / "guides" + if owner.is_dir() and guides.is_dir() and has_markdown(guides): + violations.append( + "源码 owner 下不使用 guides 中转层;特性正文直接放 owner " + f"根目录:{display(guides)}" + ) + return violations + + def check_repo_owner_axes() -> None: repos_root = ROOT / "repos" if not repos_root.is_dir(): return for repo in sorted(path for path in repos_root.iterdir() if path.is_dir()): errors.extend(owner_axis_violations(repo)) + errors.extend(source_owner_guide_violations(repo)) def exact_page_duplicate_violations(paths: list[Path]) -> list[str]: @@ -381,14 +410,12 @@ def main() -> int: excluded_parts = { ".git", - "_archive", "artifacts", "contributing", "general", "local", "outputs", "repos", - "遗言", } for path in ROOT.rglob("*.md"): relative_parts = set(path.relative_to(ROOT).parts) diff --git a/knowledge/tools/check_wiki_lint.py b/knowledge/tools/check_wiki_lint.py index 4f898a3..d2741f2 100644 --- a/knowledge/tools/check_wiki_lint.py +++ b/knowledge/tools/check_wiki_lint.py @@ -2,7 +2,7 @@ """检查沉淀层页面的 frontmatter、标签分类法、孤页与陈旧度(SCHEMA.md 机制)。 范围:general/ 与 repos/ 下的沉淀层页面。证据层(incidents/、history/、 -results/)、repos/jianghan-roleplay-data-pipeline/ 与 _archive/ 不检查。 +results/)与 repos/jianghan-roleplay-data-pipeline/ 不检查。 结构/索引/链接/错题校验属于 check_knowledge_tree.py,这里不重复。 """ @@ -19,7 +19,7 @@ SCHEMA = ROOT / "SCHEMA.md" SYNTH_ROOTS = (ROOT / "general", ROOT / "repos") RAW_PARTS = {"incidents", "history", "results"} -SKIP_PARTS = {"_archive"} +SKIP_PARTS: set[str] = set() SKIP_SUBTREES = (ROOT / "repos" / "jianghan-roleplay-data-pipeline",) TYPES = {"rule", "guide", "architecture", "index"} CONFIDENCE = {"high", "medium", "low"} diff --git a/knowledge/tools/test_check_knowledge_tree.py b/knowledge/tools/test_check_knowledge_tree.py index 05ca63f..67be66f 100644 --- a/knowledge/tools/test_check_knowledge_tree.py +++ b/knowledge/tools/test_check_knowledge_tree.py @@ -30,6 +30,61 @@ def test_source_owner_nested_below_workflow_fails(self) -> None: self.assertEqual(len(violations), 1) self.assertIn("源码 owner 目录必须直属仓库", violations[0]) + def test_guides_below_source_owner_fail(self) -> None: + with tempfile.TemporaryDirectory() as temporary: + repo = Path(temporary) / "demo" + guides = repo / "components" / "diffusion" / "guides" + guides.mkdir(parents=True) + (guides / "parallelism.md").write_text( + "# Parallelism\n", encoding="utf-8" + ) + + violations = check_knowledge_tree.source_owner_guide_violations(repo) + + self.assertEqual(len(violations), 1) + self.assertIn("不使用 guides 中转层", violations[0]) + + def test_guides_below_work_topic_pass(self) -> None: + with tempfile.TemporaryDirectory() as temporary: + repo = Path(temporary) / "demo" + guides = repo / "review" / "guides" + guides.mkdir(parents=True) + (guides / "routing.md").write_text( + "# Routing\n", encoding="utf-8" + ) + + self.assertEqual( + check_knowledge_tree.source_owner_guide_violations(repo), + [], + ) + + +class FilesystemChildIndexTests(unittest.TestCase): + def test_models_can_use_filesystem_as_child_inventory(self) -> None: + with tempfile.TemporaryDirectory() as temporary: + models = Path(temporary) / "models" + models.mkdir() + + self.assertTrue( + check_knowledge_tree.uses_filesystem_child_index( + models, + "\n# Models", + ) + ) + + def test_other_directories_cannot_skip_child_registration(self) -> None: + with tempfile.TemporaryDirectory() as temporary: + components = Path(temporary) / "components" + components.mkdir() + + self.assertFalse( + check_knowledge_tree.uses_filesystem_child_index( + components, + "\n# Components", + ) + ) + + class ExactDuplicateTests(unittest.TestCase): def test_identical_page_body_across_owners_fails(self) -> None: with tempfile.TemporaryDirectory() as temporary: diff --git "a/knowledge/\351\201\227\350\250\200/HF\345\256\230\346\226\271baseline\347\232\204SDPA\346\255\273\346\264\273key_size\344\270\215\347\255\211\344\272\216value_size\345\260\261\345\267\256\350\277\231\344\270\200\344\270\252trace\344\272\206-105930_28042026.md" "b/knowledge/\351\201\227\350\250\200/HF\345\256\230\346\226\271baseline\347\232\204SDPA\346\255\273\346\264\273key_size\344\270\215\347\255\211\344\272\216value_size\345\260\261\345\267\256\350\277\231\344\270\200\344\270\252trace\344\272\206-105930_28042026.md" deleted file mode 100644 index cbe6823..0000000 --- "a/knowledge/\351\201\227\350\250\200/HF\345\256\230\346\226\271baseline\347\232\204SDPA\346\255\273\346\264\273key_size\344\270\215\347\255\211\344\272\216value_size\345\260\261\345\267\256\350\277\231\344\270\200\344\270\252trace\344\272\206-105930_28042026.md" +++ /dev/null @@ -1,163 +0,0 @@ -# 遗言:HF官方baseline的SDPA死活key_size不等于value_size就差这一个trace了 - -> 生成时间: 2026-04-28 10:59:30 -> 项目路径: D:\vllm-omni\workflow-starter(本地)/ root@47.79.124.13:31182(远端云实例) - ---- - -## 项目背景 - -**vLLM-Omni × HunyuanImage-3.0-Instruct** profiling 对比工程。 - -- 仓库:`zuiho-kai/vllm-omni`,分支 `pr-3055` -- 远端:L20X × 4(140GB/卡),阿里云容器实例,`root@47.79.124.13:31182`(SSH 直连) -- 共享存储:`/mnt`(1.8PB CPFS),模型在 `/mnt/models/hub` -- 两个 venv: - - `/root/venv` — vllm 0.19.1 + vllm-omni(torch 2.7.0+cu126, transformers 5.6.2) - - `/root/venv_hf` — HF 官方环境(torch 2.8.0+cu128, transformers 4.57.1) - ---- - -## 本次会话目标 - -1. 在全新云实例上跑 3 个 vllm-omni profiling 配置(tp4_fp8 / tp2_fp8_sp2 / tp2_fp8_cfgp2) -2. 拿 torch profiler trace JSON(可在 chrome://tracing 看时序图) -3. 跑 HF 官方 baseline 的 torch profiler trace 做对比 - ---- - -## 已完成的工作 - -### 1. 云实例环境搭建 -- 安装 uv、创建 venv、安装 vllm 0.19.1 -- `git clone https://github.com/zuiho-kai/vllm-omni.git --branch pr-3055`(先从本地 push 了 pr-3055 到 zuiho-kai fork) -- 下载 HunyuanImage-3.0-Instruct 模型到 `/mnt/models/hub`(158GB) -- Patch `pipeline_hunyuan_image3.py:114`:`Siglip2VisionModel(vision_config).vision_model` → `Siglip2VisionModel(vision_config)`(transformers 5.6.2 兼容) - -### 2. vllm-omni 三配置 stage_durations benchmark ✅ -结果 JSON 已下载到本地: -- `profiling_l20x_tp4_fp8.json` — 5.87s 延迟,model.forward 3.96s,47GB/卡 -- `profiling_l20x_tp2_fp8_sp2.json` — 5.40s 延迟,model.forward 3.54s,66GB/卡 -- `profiling_l20x_tp2_fp8_cfgp2.json` — 4.40s 延迟,model.forward 3.07s,66GB/卡 -- `profiling_l20x_results.json` — 汇总 - -### 3. vllm-omni tp4_fp8 torch profiler trace ✅ -- 4 rank trace 文件已下载并解压到 `D:\vllm-omni\workflow-starter\torch_traces\tp4_fp8\20260428-023238_stage_0_diffusion_1777343558\` -- `trace_rank{0-3}.json`(每个 ~889MB)+ `profiler_out_{0-3}.txt` -- Top 算子:fused_moe 820ms(16.6%), fmha_cutlass 695ms(14%), nccl_allreduce 653ms(13.2%), cudnn_conv(VAE) 534ms(10.8%) - -### 4. HF 官方环境搭建 ✅ -- `/root/venv_hf`:torch==2.8.0+cu128, transformers==4.57.1(官方 requirements.txt 精确版本) -- 额外装了 einops, diffusers==0.35.2, torchvision==0.23.0 -- `config.json` 补了 `"model_version": "instruct"`(原始 config 缺这个字段) - -### 5. Error book 更新 ✅ -- `.claude_errors/remote_and_ssh.md`:盲等 210s 不看日志、Siglip2VisionModel 版本不兼容 -- `.claude_errors/profiling_and_model_loading.md`:Siglip2 patch、HF baseline 版本夹缝问题 - ---- - -## 未完成的工作 - -### ❌ HF 官方 baseline torch profiler trace - -**当前阻塞点**:`model.generate_image()` 在 AR decode 阶段崩溃。 - -**错误**: -``` -File ".../modeling_hunyuan_image_3.py", line 1363, in forward - attn_output = torch.nn.functional.scaled_dot_product_attention( -RuntimeError: Expected key.size(1) == value.size(1) to be true, but got false. -``` - -**已尝试的方案**: -1. ❌ `attn_implementation="sdpa"` + transformers 5.6.2 → `StaticLayer.lazy_initialization() missing 1 required positional argument` -2. ❌ `attn_implementation="sdpa"` + transformers 4.50.0 → `HunyuanStaticCache has no attribute 'layers'` -3. ❌ `attn_implementation="sdpa"` + transformers 4.57.1(官方版本)→ `key.size(1) != value.size(1)` -4. ❌ `attn_implementation="eager"` + transformers 4.57.1 → **同样的 SDPA 错误**(eager 没生效) -5. ❌ Patch `attn_mask` dtype(long→bfloat16)→ 解决了 dtype 问题但 key/value size 不匹配仍在 -6. ❌ Patch snapshot + modules 两个目录 → transformers 重新复制代码覆盖 patch - -**根因分析(最后一步发现)**: -- `attn_implementation="eager"` 传给了 `from_pretrained`,但模型自定义代码有**自己的 attention dispatch** -- `modeling_hunyuan_image_3.py:1375`:`Hunyuan_ATTENTION_CLASSES = {...}` 硬编码了 attention 类 -- `line 1388-1389`:`if attn_impl in Hunyuan_ATTENTION_CLASSES: self.self_attn = Hunyuan_ATTENTION_CLASSES[attn_impl](...)` -- 只有 `HunyuanImage3SDPAAttention`(line 1257),没有 eager 实现 -- **所以 `attn_implementation="eager"` 被忽略了,始终走 SDPA** - -**下一步修复方向**: -```python -# 方案 A:在 Hunyuan_ATTENTION_CLASSES 里加一个 eager 实现 -# 查看 line 1375 的 dict,加一个用 torch.matmul 的 eager class - -# 方案 B:直接 patch HunyuanImage3SDPAAttention.forward -# 把 scaled_dot_product_attention 替换成手动 matmul + softmax -# 这样不需要改 dispatch 逻辑 - -# 方案 C:修 HunyuanStaticCache.update() 确保 key/value size 一致 -# 根因可能在 cache 的 update 方法里 -``` - -**HF trace 脚本已上传到远端**:`/tmp/bench_hf_trace.py`(用 `torch.profiler` 包裹 `generate_image` 单次调用) - ---- - -## 关键决策与发现 - -1. **模型存 /mnt(CPFS 共享存储)**:1.8PB,SSD,可跨实例复用 -2. **vllm-omni 是纯 Python overlay**:不需要编译 CUDA 扩展,`pip install -e .` 秒装 -3. **pr-3055 分支**:HunyuanImage3 支持只在这个分支,需要先 push 到 zuiho-kai fork 才能远端 clone -4. **transformers 版本地狱**: - - 模型仓库 config.json 写的 `transformers_version: 4.50.0` - - 官方 requirements.txt 写的 `transformers==4.57.1` - - 模型的 custom code(trust_remote_code)会被 transformers 从 snapshot 复制到 `~/.cache/huggingface/modules/`,每次加载都重新复制 -5. **Hunyuan_ATTENTION_CLASSES 硬编码**:模型自定义了 attention dispatch,忽略 `attn_implementation` 参数 -6. **CFG-Parallel 最快**:tp2_fp8_cfgp2 比 tp4_fp8 快 25%(4.40s vs 5.87s) - ---- - -## 下一步建议(新会话直接执行) - -### 优先级 1:修 HF baseline trace - -```bash -# SSH 进入 -ssh -p 31182 root@47.79.124.13 - -# 查看 attention dispatch -source /root/venv_hf/bin/activate -grep -n "ATTENTION_CLASSES" /mnt/models/modules/transformers_modules/_2ec2c78bee7d4b94157341fba86c4c2c7b1858b2/modeling_hunyuan_image_3.py - -# 方案 B(最快):直接在 HunyuanImage3SDPAAttention.forward 里把 SDPA 换成手动 matmul -# 需要同时 patch snapshot 和 modules 两个目录的文件: -# /mnt/models/hub/models--tencent--HunyuanImage-3.0-Instruct/snapshots/2ec2c78bee7d4b94157341fba86c4c2c7b1858b2/modeling_hunyuan_image_3.py -# /mnt/models/modules/transformers_modules/_2ec2c78bee7d4b94157341fba86c4c2c7b1858b2/modeling_hunyuan_image_3.py - -# Patch 后跑: -export HF_HUB_OFFLINE=1 -python /tmp/bench_hf_trace.py -``` - -### 优先级 2:释放云实例(省钱) - -跑完后删实例,模型在 /mnt 可复用。 - ---- - -## 关键文件清单 - -| 文件 | 说明 | -|------|------| -| `profiling_l20x_results.json` | 三配置汇总结果 | -| `profiling_l20x_tp4_fp8.json` | tp4_fp8 完整 benchmark JSON | -| `profiling_l20x_tp2_fp8_sp2.json` | tp2_fp8_sp2 完整 benchmark JSON | -| `profiling_l20x_tp2_fp8_cfgp2.json` | tp2_fp8_cfgp2 完整 benchmark JSON | -| `torch_traces/tp4_fp8/.../trace_rank{0-3}.json` | tp4_fp8 torch profiler trace(chrome://tracing 可视化) | -| `torch_traces/tp4_fp8/.../profiler_out_{0-3}.txt` | tp4_fp8 profiler 摘要 | -| `run_diffusion_profiling.txt` | vllm-omni profiling 脚本(bash) | -| `analyze_torch_trace.py` | 当时使用的临时 trace 分析脚本,现已从框架仓库删除 | -| `bench_hf_trace.py` | HF 官方 torch profiler 脚本(已上传远端 /tmp/) | -| `bench_hf_dit_only.py` | DiT-only benchmark 脚本(未跑通) | -| `patch_attn_mask.py` | attn_mask dtype patch 脚本 | -| `.claude_errors/profiling_and_model_loading.md` | profiling 踩坑记录 | -| `.claude_errors/remote_and_ssh.md` | 远端操作踩坑记录 | diff --git "a/knowledge/\351\201\227\350\250\200/PR3630_graph_7\345\200\215\345\277\253_\344\275\206AR\347\262\276\345\272\246\344\273\216token8\345\274\200\345\247\213\346\274\202\347\246\273HF-175500_15052026.md" "b/knowledge/\351\201\227\350\250\200/PR3630_graph_7\345\200\215\345\277\253_\344\275\206AR\347\262\276\345\272\246\344\273\216token8\345\274\200\345\247\213\346\274\202\347\246\273HF-175500_15052026.md" deleted file mode 100644 index 02ce1c3..0000000 --- "a/knowledge/\351\201\227\350\250\200/PR3630_graph_7\345\200\215\345\277\253_\344\275\206AR\347\262\276\345\272\246\344\273\216token8\345\274\200\345\247\213\346\274\202\347\246\273HF-175500_15052026.md" +++ /dev/null @@ -1,180 +0,0 @@ -# 遗言:PR3630 graph 模式 7 倍快,但 AR 精度从 token8 开始漂离 HF 参考 - -> 生成时间: 2026-05-15 17:55:00 -> 项目路径: D:\vllm-omni\workflow-starter - -## 项目背景 - -vLLM-Omni × HunyuanImage-3.0-Instruct 验证项目。HunyuanImage-3.0-Instruct 是 Tencent 的 80B MoE 多模态模型(AR + DiT 两阶段),vLLM-Omni 是 vLLM 的多模态分支。 - -- 主仓库:`https://github.com/vllm-project/vllm-omni`,user fork `TaffyOfficial/vllm-omni` -- 远端 GPU:`root@106.15.124.84 -p 31140`(4× L20X,每卡 144GB HBM) -- 本地工作目录:`D:\vllm-omni\workflow-starter` -- 验证目标 PR: - - **PR 3630** `[BugFix][HunyuanImage3] Set MRoPE dynamic_arg_dims so graph mode can compile`(本次重点) - - **PR 3611** `[Feature] Support CUDA Graph for Hunyuan-Image`(PR 3630 的 parent,作为同 GPU 对照基线) - -## 本次会话目标 - -1. 在 L20X GPU 上跑 PR 3630 的 i2t serving bench,对比 PR 3611 NPU 数据 -2. 写 PR 3630 PR 描述(含 bench 数据和文件) -3. 验证 graph vs eager 的精度等价性 -4. 修复 `tests/e2e/offline_inference/test_hunyuanimage3_i2t_expansion.py`(自 #3172 起 broken) - -## 已完成的工作 - -### 1. PR 3630 graph mode online bench(TP=2 GPU 1,2,max_num_seqs=128,enforce_eager=false) - -``` -Mean E2EL: 4145.13 ms | TTFT: 633.93 ms | TPOT: 16.37 ms -Output tok/s: 68.70 | Total tok/s: 1368.92 | ITL: 6.86 ms -10/10 successful in 41.45s -``` - -### 2. PR 3611 同 GPU 同 config 对照 - -``` -Mean E2EL: 4313.40 ms | TTFT: 830.96 ms | TPOT: 21.12 ms -Output tok/s: 47.87 | Total tok/s: 1297.37 | ITL: 6.80 ms -``` - -**PR 3630 相对 PR 3611**:E2EL P99 -22%,TTFT P99 -64%,TPOT -22%,Output 吞吐 +43%。证明 MRoPE 修复让 graph 真正接管 AR 入口(PR 3611 graph 编不出来部分 fallback eager)。 - -### 3. PR 3630 eager vs graph 对比 - -| 指标 | eager | graph | graph 加速 | -|---|---:|---:|---:| -| E2EL | 28 783 ms | 4 145 ms | **6.94×** | -| TPOT | 154 ms | 16.37 ms | **9.42×** | -| Output tok/s | 8.03 | 68.70 | **8.55×** | - -### 4. PR 描述 markdown 已写 - -文件:`D:\vllm-omni\workflow-starter\.scratch\pr3630_description_update.md` -包含:测试方法、yaml、jinja、serve/bench 命令、PR 3611 vs PR 3630 对照表、原始 bench 输出。用户可直接复制贴 PR。 - -### 5. 新分支修 broken offline test - -worktree:`/home/wzr/wt-i2t-test-fix` -分支:`fix-hunyuan-image3-i2t-test-expected` (off upstream/main @ 779bf311) -commit:`7cb8dee0 [Test][HunyuanImage3] Fix broken offline i2t expansion test` -改动: -- 恢复 `vllm_omni/model_executor/stage_configs/hunyuan_image3_i2t.yaml`(#3172 删的) -- 更新 `tests/e2e/offline_inference/test_hunyuanimage3_i2t_expansion.py` 的 EXPECTED token - -⚠️ **这个 commit 方向是错的**(详见"未完成的工作")。 - -### 6. 远端本地 patch(不动 git) - -`/home/wzr/pr_3640/`: -- `vllm_omni/model_executor/models/hunyuan_image3/hunyuan_image3.py`:把 `_hunyuan_image3_unpack_packed_topk` 的 `num_experts` 改 `int | None = None` 绕开 #3537 vllm 兼容 bug(注:upstream main 现在已合 #3640 修这个) -- `vllm_omni/model_executor/models/hunyuan_image3/pipeline.py`:`HUNYUAN_IMAGE3_AR_PIPELINE.owns_tokenizer = True` 让 `is_comprehension` flag 在新 deploy 格式生效 - -`/home/wzr/pr_3611/`:同上 owns_tokenizer 一行 patch - -## 未完成的工作 - -### ❌ 阻塞:commit 7cb8dee0 方向反了 - -用户提醒:**EXPECTED 原本就是官方 HF 参考**,我把它改成 vllm-omni 当前 eager 实测 = 祝福漂移、丢掉 HF cross-validation。 - -实测: -- 官方 HF:`[..., 14113, 6307, 1933, 449, 912, 27339, ...]` = "uniform **green color with no variations**" -- vllm-omni eager 现在:`[..., 14113, 2115, 315, 10107, 6307, 13, ...]` = "uniform **field of bright green**" -- 前 7 token 一致,**第 8 个起 vllm-omni 漂离 HF** - -漂移源**不是** #3444 的 `extra_resolutions`(256×256 ratio=1.0 在 base bucket 里,extras 不会覆盖;如果是 image bucket 变了 token 0 就该分叉,但前 7 token 是 bitwise 一致的)。更可能是某次 vllm 内核 / MoE / sampler 改动累积的 bf16 数值漂移。 - -### 三个修法(待用户决定) - -| 方案 | 做什么 | 评价 | -|---|---|---| -| **A** | `git reset --soft HEAD~1` 撤 commit,bisect 找漂移根因,修 vllm-omni 让它跟 HF 重新对齐 | 最对,可能深;如果是 vllm kernel 版本漂可能修不了 | -| **B** | amend commit:把 `EXPECTED_PREFIX_TOKEN_IDS` 砍到稳定 prefix 7 token + 注释说"vllm-omni 跟 HF 在 token 7 后漂,跟踪 issue #XXXX" | 保留 HF 为 ground truth,断言放宽,可立即合入 | -| **C** | 保留当前 commit(bless 漂移) | 最差,不该做 | - -我倾向 A 先快速 bisect 1-2 步,找不到再退 B。**等用户回复"reset 然后 bisect"或"直接 amend 走 B"**。 - -## 关键决策与发现 - -1. **PR 3630 在 L20X TP=2 graph mode 比 PR 3611 NPU 数据快 1.5-2×**:但不能直接比(NPU vs GPU)。同 GPU 同 config 对照才公允,所以本会话拉了 PR 3611 worktree 在本地跑。 -2. **PR 3630 commit message 写 "Generated tokens identical to eager output" 不准确**:作者只在 TP=2 / 26 token 下验证。我 TP=4 / 20 token 看到 graph 从 token 2 起跟 eager 分叉(` is` vs ` consists`)。这是 bf16 + MoE + TP + graph kernel reorder 的共性,不是 PR 3630 引入。 -3. **chat template + deploy yaml 不在仓库里**:作者跑 i2t 用了私人 `legacy_comprehension.yaml` + `hunyuan_image3_ar.jinja`(`/root/vllm-omni-workspace/`,没进 PR)。我们仿照写了 + Codex 也单独写了一份在 `D:\vllm-omni\wt-hunyuan3-serve-config\`,可参考精髓。 -4. **`--deploy-config` 不接受 legacy `stage_args` schema**:必须用 `--stage-configs-path`(auto-detect 在 utils.py:593 检测 yaml 顶层是 `stage_args` 还是 `stages`)。Codex 那条 `--deploy-config legacy_comprehension.yaml` 命令在代码层面跑不通。 -5. **vllm 0.20.0 + HunyuanImage3 MoE 在 TP=4 + bf16 + greedy 下,graph 跟 eager 不 bit-identical**:drift 从 token 2 起。语义仍正确。这是 vllm graph mode 的已知行为。 -6. **#3172 删了 stage_configs/hunyuan_image3_i2t.yaml** 但没更新引用它的 test,test 自 5 月 13 日已 broken。 - -### 踩过的坑(消耗 token 教训) - -- 应该**第一次 bench 失败就 `curl` 单请求**看 4xx body,而不是反复跑 10-prompt bench(每次 5min 模型重载) -- 应该**先 grep 现成 yaml/jinja** 再写自己的(Codex 已有 reference,省 1 小时) -- `is_comprehension` 在新 deploy 格式不可写 yaml,要靠 pipeline.py 改 `owns_tokenizer=True` 绕;legacy stage_args 格式才直接读 yaml 字段 - -## 下一步建议 - -新会话进来按这个顺序: - -1. `cat 遗言/PR3630_graph_7倍快_但AR精度从token8开始漂离HF-175500_15052026.md`(你正在读) -2. **找用户确认**:A(bisect+fix)还是 B(amend commit 缩到 7 token) -3. 如果选 A: - - SSH `root@106.15.124.84 -p 31140`(用 `~/.ssh/id_ed25519`) - - 候选 commit 排除:#3590(只删 assert,无数学)、#3537(加未用形参,已被 #3640 修)、#3172(只删/加 config)。剩 **#3444 ResolutionGroup 改动** 最可疑,但需要实测 256×256 是否真换 bucket - - 如果不是 #3444,下沉到 MoE block / attention kernel 的 vllm 内部 commit(这层修不了,直接退 B) -4. 如果选 B: - - `cd /home/wzr/wt-i2t-test-fix && git reset --soft HEAD~1`,重写 EXPECTED 砍到前 7 token,amend -5. 任一路径完成后: - - push 分支:`git push origin fix-hunyuan-image3-i2t-test-expected` - - 开 PR,body 描述 test 自 #3172 起 broken + 修法 -6. **PR 3630 的 PR 描述**已经在 `D:\vllm-omni\workflow-starter\.scratch\pr3630_description_update.md`,用户已经看过,可直接贴上 GitHub。eager-vs-graph 对照那段我建议补进去(commit message 里"identical to eager"那句记得软化或删,避免被 reviewer 怼) - -## 关键文件清单 - -### 本地 (D:\vllm-omni\workflow-starter\) - -- `.scratch/pr3630_description_update.md` — PR 3630 PR 描述完整版(bench 数据、yaml、jinja、命令) -- `CLAUDE.md` — 项目规则(远端、Slurm、CI 等硬规则) -- `docs/remote_server.md` — 远端连接信息(**已过期,新远端是 root@106.15.124.84:31140**) - -### Codex reference(D:\vllm-omni\wt-hunyuan3-serve-config\) - -- `vllm_omni/deploy/hunyuan_image3_ar_legacy_comprehension.yaml` — legacy stage_args 格式,含 `is_comprehension: true` + `engine_output_type: text` -- `examples/online_serving/hunyuan_image3/hunyuan_image3_ar.jinja` — i2t 用 chat template,content 顺序穿插 image/text - -### 远端 (root@106.15.124.84:31140) - -- `/home/wzr/pr_3640/` — PR 3630 worktree(commit `deca9dae`)+ 本地 2 处 patch(num_experts 默认值、owns_tokenizer=True) -- `/home/wzr/pr_3611/` — PR 3611 worktree(commit `52558ea1`)+ owns_tokenizer patch -- `/home/wzr/wt-i2t-test-fix/` — **新分支** `fix-hunyuan-image3-i2t-test-expected`(off upstream/main `779bf311`),含**方向错的** commit `7cb8dee0` -- `/home/wzr/pr_3640/pr3640_ar_graph.yaml` — graph mode deploy yaml -- `/home/wzr/pr_3640/pr3640_ar_eager.yaml` — eager mode deploy yaml -- `/home/wzr/pr_3640/hunyuan_image3_i2t.jinja` — chat template(Codex 精髓 + `image_url` / `image` 都识别) -- `/home/wzr/pr_3640/run_bench_c1.sh` — bench 脚本 -- `/home/wzr/wt-i2t-test-fix/vllm_omni/model_executor/stage_configs/hunyuan_image3_i2t.yaml` — 恢复的 legacy stage_args yaml(拷自 `/home/wt-mi/...`) -- `/tmp/pr3640_serve.log` / `/tmp/pr3640_eager_serve.log` / `/tmp/pr3640_bench.log` / `/tmp/wt_i2t_test.log` — 各次跑的完整日志 - -### 远端登录 - -```bash -ssh -i ~/.ssh/id_ed25519 -p 31140 root@106.15.124.84 -# 模型缓存:/root/.cache/huggingface/hub/models--tencent--HunyuanImage-3.0-Instruct/ -# 主 venv:/home/wzr/vllm-omni/.venv(system vllm 0.20.0,编辑模式 vllm-omni 装在 wt-it2i-marker-log) -# 启动 serve 必须 export PYTHONPATH=/home/wzr/:$PYTHONPATH 才能加载该 worktree 的 vllm_omni -``` - -### 关键 bench 命令(用户提供的"金标准") - -```bash -vllm bench serve \ - --omni --backend openai-chat-omni \ - --host 127.0.0.1 --port 8091 --endpoint /v1/chat/completions \ - --model tencent/HunyuanImage-3.0-Instruct \ - --dataset-name random-mm \ - --num-prompts 10 --request-rate inf --max-concurrency 1 \ - --random-input-len 256 --random-output-len 512 --random-range-ratio 0 \ - --random-mm-base-items-per-request 1 --random-mm-num-mm-items-range-ratio 0 \ - --random-mm-limit-mm-per-prompt '{"image":1,"video":0,"audio":0}' \ - --random-mm-bucket-config '{"(1024, 1024, 1)": 1.0}' \ - --extra-body '{"modalities":["text"]}' \ - --temperature 0 --ignore-eos \ - --percentile-metrics ttft,tpot,itl,e2el --metric-percentiles 50,90,99 -``` diff --git "a/knowledge/\351\201\227\350\250\200/dtype_cast_fix\345\256\236\346\265\213\346\227\240\350\247\202\346\265\213\346\224\271\345\226\204\344\275\206\347\220\206\350\256\272\345\257\271\345\276\205commit-100604_30042026.md" "b/knowledge/\351\201\227\350\250\200/dtype_cast_fix\345\256\236\346\265\213\346\227\240\350\247\202\346\265\213\346\224\271\345\226\204\344\275\206\347\220\206\350\256\272\345\257\271\345\276\205commit-100604_30042026.md" deleted file mode 100644 index 1cefbe8..0000000 --- "a/knowledge/\351\201\227\350\250\200/dtype_cast_fix\345\256\236\346\265\213\346\227\240\350\247\202\346\265\213\346\224\271\345\226\204\344\275\206\347\220\206\350\256\272\345\257\271\345\276\205commit-100604_30042026.md" +++ /dev/null @@ -1,139 +0,0 @@ -# 遗言:dtype cast fix 实测无观测改善但理论对,dtype fix commit pending - -> 生成时间: 2026-04-30 10:06:04 -> 项目路径: D:\vllm-omni\workflow-starter - -## 项目背景 - -vLLM-Omni × HunyuanImage-3.0-Instruct。80B 多模态 MoE 模型。 -本次会话场景:让 vllm-omni IT2I AR 输出与 HF 官方 baseline **对齐**——用户最初投诉 omni 离线 IT2I 输出"丢失描述细节"。 -远端:`47.79.124.13:31230`,模型在 `/mnt/models/hub/models--tencent--HunyuanImage-3.0-Instruct/snapshots/2ec2c78bee7d4b94157341fba86c4c2c7b1858b2/`。 -worktree:`D:/vllm-omni/wt-hunyuan-t2t-sdpa-fa`,分支 `feature/hunyuan-t2t-sdpa-fa`。 - -## 本次会话目标 - -排查 omni vs HF 输出差异的根因,逐项修复,做到尽可能 byte-identical 对齐。 - -## 已完成的工作 - -### Commit 推到 zuiho-kai + TaffyOfficial fork(共 4 笔有效修复 + 2 笔文档) - -| commit | 内容 | -|---|---| -| `42ee44b6` | Siglip2ImageProcessorFast 在 transformers ≥5.x 返回 list 的 squeeze 崩溃修复 | -| `80617a1d` | T2T `build_prompt` 改 instruct 格式(早版) | -| `88d16caa` | 统一 i2t/it2i_*/t2i_* 用 instruct chat 模板,trigger 在 `Assistant:` 之后(**最关键修复**——main 分支 IT2I greedy 死循环 garbage 的根因)| -| `80e0237f` | `A:` → `Assistant:` 匹配 HF tokenizer 实际输出(token 72803)| -| `42c2f349` | 新增 `build_prompt_tokens()` 走 prompt_token_ids 路径,绕过 BPE 跨段 merge——文本 input_ids 与 HF byte-identical | -| `0a63ab5e` | docs:解释 `` slot 用 `` 占位与 HF 等价(embedding 层等价,单点改坏) | -| `a7a5ab3f` | docs:解释 image preprocessing 已对齐 HF(resize/crop math + VAE normalize 一致) | - -### dtype cast fix(**改完未 commit**——这是 pending 状态) - -`vllm_omni/model_executor/models/hunyuan_image3/hunyuan_image3.py`: -- `process_image()` line 876:删 `.to(dtype=torch_dtype)`,让 `vae_pixel_values` 保留 fp32 -- `_vae_encode()` line 1424 入口加 cast:`if images.dtype != self.vae.dtype: images = images.to(dtype=self.vae.dtype)` -- 删 line 845 `torch_dtype = ...` 已不用的赋值 - -**实测**:pixel-level 数值与 HF byte-identical(fp32 mean=0.157296 完全一致)。但 VAE encoder 内部第一个 conv 层照样 cast 到 bf16,所以**最终 latent 与 cast 前 byte-identical**——greedy/sampling 输出都没观测变化。**理论对,工程上 0 退化 0 改善**。 - -### 数据点确认(保存在 `D:\vllm-omni\workflow-starter\it2i_t2t_outputs\`) - -| 文件 | 来源 | 长度 | 状态 | -|---|---|---|---| -| `MAIN_BRANCH_omni.txt` | 主线 main 无 fix,greedy | 2267 | ❌ 无 ``,`image_1` 死循环 6 次 | -| `MAIN_BRANCH_sample.txt` | 主线 main 无 fix,sampling | 8188 | ❌ "吐舌头" × N 完全 garbage | -| `DTYPE_FIX_omni.txt` / `T4571_omni.txt` | fix 后 greedy(含 dtype fix)| 2167 | ✅ 完整 think 分析,0 image_X | -| `SAMPLE_omni.txt` | fix 后 sampling | 2751 | ✅ think + recaption,1 个 image_2 幻觉 | -| `FINAL_hf.txt` | HF baseline greedy | 1354 | 标杆 | -| `SAMPLE_hf.txt` | HF baseline sampling | 1255 | 标杆 | - -→ **fix 后是 strict improvement**:从主线的"死循环 garbage"修到"完整结构 + 关键元素全覆盖"。 - -### memory 更新 - -- `memory/official_prompt_format.md` —— Instruct 模板细节、BPE 边界陷阱、`` 展开差异 -- `memory/hf_omni_alignment_method.md` —— 5 步排查方法 + sampler 不可对齐硬下界 + transformers 4.57.1 实测对 omni 输出 0 影响 -- `memory/feedback_pr_test_path_audit.md` —— PR #2713/#3107/#2986 测试盲区分析 -- `memory/feedback_alignment_debug_pitfalls.md` —— 本会话踩的 4 个对齐调试坑 - -### claudeception skill 增强 - -`~/.claude/skills/claudeception/SKILL.md` v3.0.0 → v3.1.0:retrospective 必须扫错误教训 + 容量自适应规模(2-4 / 5-8 / 9+)。 - -### vllm-omni venv 配置 - -把 `/root/venv` 的 transformers 从 5.6.2 降到 **4.57.1**(与 HF baseline 对齐)。实测:omni 输出与 5.6.2 时代 byte-identical(pixel preprocessing 不受 transformers 版本影响)。`/root/venv_hf` 仍是 4.57.1 不变。 - -## 未完成的工作 - -### 1. dtype cast fix 待 commit - -文件 `vllm_omni/model_executor/models/hunyuan_image3/hunyuan_image3.py` 当前 dirty。改动:`process_image` 不 cast bf16 + `_vae_encode` 入口 cast。理论对、零退化、零改善。**用户最后问"要不要 commit"**,会话结束前未答复。 - -### 2. omni vs HF 仍有 800+ 字差异 + sampling 偶发 image_2 幻觉 - -**已确认不是**这些层面的问题: -- prompt 格式 ✓ 修了 -- BPE 跨段 merge ✓ 修了 -- transformers 版本 ✓ 验证 4.57.1 vs 5.6.2 输出 byte-identical -- pixel preprocessing 数值 ✓ fp32 byte-identical with HF -- attention backend ✓ FA = SDPA 验证过 -- enforce_eager ✓ 已开(但只关 compile 不影响 model 实现) - -**剩下根因(架构级,本会话不可修)**: -- vllm-omni 的 `HunyuanImage3ForCausalMM` 自己写的 forward vs HF 的 `modeling_hunyuan_image_3.py` —— 完全两套独立代码(PagedAttention vs 普通 cache、Triton fused MoE vs python loop、attention metadata 实现差异) -- vllm sampler ≠ transformers sampler —— RNG primitive、logits processor 顺序、Triton fused kernel 都不同 → 同 seed 下 token 序列必然不同(已写进 `hf_omni_alignment_method.md`) - -## 关键决策与发现 - -1. **PR #2713 的 "first 30 token matched, BF16 expected" 是误导**:测试方法绕过了 `build_prompt`,把所有差异糊弄成"BF16 噪声"。本会话证伪——大部分差异是确定性代码 bug。 -2. **enforce_eager: true 不让 omni 走 HF eager**——只关 torch.compile/CUDA graphs,model code 还是 vllm-omni 自己的实现。 -3. **transformers 4.57.1 与 5.6.2 在 omni 输出上 byte-identical**:之前以为版本差是数值差异源,错了。 -4. **Pixel-level fp32 cast 修好但不影响输出**:VAE encoder 内部 cast 抵消了。 -5. **同 seed 下 vllm 和 transformers 的 sampler 不可对齐**:硬下界,不要再试。 -6. **HunyuanImage3 image expansion 用 `` 占 timestep slot 与 HF ``等价**:embedding 层都被 timestep_emb(0) 替换。单点换 token id 会触发 image_2..N 幻觉(破坏 routing)。 - -## 下一步建议 - -**优先**: -1. 决定 dtype fix 是否 commit。建议 **commit**——理论对(pixel-level fp32 与 HF 一致)+ 零退化 + 不会成为 future deeper alignment 工作的瓶颈。Commit 后所有 5 个 fix commit 都在分支上。 -2. 整理 PR 描述——把"main vs fix"对比作为 PR 说服力的核心证据,而不是"fix vs HF"(永远对不齐)。 - -**如果用户想继续深挖**: -- A. 跑多 seed sampling 统计 image_2 幻觉率(5+ seeds),评估这是 deterministic bug 还是 RNG 路径 luck -- B. dump 两边在 `` 位置的 logits(top-20 token + 概率),看 omni 是不是把 `<|endoftext|>` 给的概率比 HF 低 —— 这是 forward 实现差异的最直接证据 -- C. 不做了,承认架构级差异不可消除,按 sampling 模式跑生产 + 把 top_k 调到 50 抑制 sampling 尾部尾乱 - -## 关键文件清单 - -| 文件 | 作用 | -|---|---| -| `D:/vllm-omni/wt-hunyuan-t2t-sdpa-fa/` | 本次会话主 worktree,分支 `feature/hunyuan-t2t-sdpa-fa` | -| `D:/vllm-omni/wt-main/` | 本次会话新建的 origin/main worktree(用于对比基准)| -| `examples/offline_inference/hunyuan_image3/end2end.py` | `build_prompt` + 新增 `build_prompt_tokens` | -| `vllm_omni/model_executor/models/hunyuan_image3/hunyuan_image3.py` | dtype fix dirty 状态 + `_get_prompt_updates` + `embed_multimodal` + `_vae_encode` 全部已注释清楚 | -| `D:/vllm-omni/workflow-starter/it2i_t2t_outputs/` | 所有对比输出 + README + FINAL_README | -| `D:/vllm-omni/workflow-starter/memory/` | 4 个新增 / 更新的 memory 文件 | -| `~/.claude/skills/claudeception/SKILL.md` | 加强了错误教训扫描的 v3.1.0 | -| 远端 `/tmp/test_step1_e2e.py` | 主测试脚本(IT2I greedy)| -| 远端 `/tmp/test_it2i_omni_sample.py` | sampling 测试脚本 | -| 远端 `/tmp/it2i_ar_tp2.yaml` / `_v2.yaml` | greedy / sampling 配置(max_tokens=2048 v2 是 HF 对齐版) | -| 远端 `/tmp/input_0_0.png` | 测试用 demo image | -| 远端 `/root/venv` | omni venv,**已降到 transformers 4.57.1** | -| 远端 `/root/venv_hf` | HF baseline venv,transformers 4.57.1 | -| Branch on Github | `zuiho-kai/feature/hunyuan-t2t-sdpa-fa` + `TaffyOfficial/feature/hunyuan-t2t-sdpa-fa` 都已 push 到 commit `a7a5ab3f` | - -## PR 描述要点(写给下次会话用) - -**关键说服力**: -- main 分支 IT2I greedy 是结构性坏的(`MAIN_BRANCH_omni.txt` 2267 字 image_1 × 6 死循环) -- main 分支 IT2I sampling 是完全 garbage 的(`MAIN_BRANCH_sample.txt` 8188 字 "吐舌头" × N) -- fix 后 greedy 完整 think 分析(`DTYPE_FIX_omni.txt` 2167 字 0 幻觉) -- fix 后 sampling 完整 think + recaption(`SAMPLE_omni.txt` 2751 字 1 个 image_2 小幻觉,但比 main 强一个数量级) - -**不要承诺的事**: -- byte-identical with HF —— 不可能(vllm sampler ≠ transformers sampler,PagedAttention ≠ contiguous cache) -- 消除 image_X 幻觉 —— 是 vllm-omni vs HF forward 实现差异的副作用,不是 prompt-level bug - -**回归测试建议**:跑 `--modality text2text` 是 prompt 格式 bug 的最强 canary(无 DiT 兜底)。 diff --git "a/knowledge/\351\201\227\350\250\200/\345\217\252\345\267\256\350\277\220\350\241\214HF_baseline\345\257\271\346\257\224\345\260\261\350\203\275\347\237\245\351\201\223vllm-omni\347\262\276\345\272\246\345\267\256\345\234\250\345\223\252\344\272\206-110132_29042026.md" "b/knowledge/\351\201\227\350\250\200/\345\217\252\345\267\256\350\277\220\350\241\214HF_baseline\345\257\271\346\257\224\345\260\261\350\203\275\347\237\245\351\201\223vllm-omni\347\262\276\345\272\246\345\267\256\345\234\250\345\223\252\344\272\206-110132_29042026.md" deleted file mode 100644 index e99d29c..0000000 --- "a/knowledge/\351\201\227\350\250\200/\345\217\252\345\267\256\350\277\220\350\241\214HF_baseline\345\257\271\346\257\224\345\260\261\350\203\275\347\237\245\351\201\223vllm-omni\347\262\276\345\272\246\345\267\256\345\234\250\345\223\252\344\272\206-110132_29042026.md" +++ /dev/null @@ -1,141 +0,0 @@ -# 遗言:只差运行 HF baseline 对比就能知道 vllm-omni 精度差在哪了 - -> 生成时间: 2026-04-29 11:01:32 -> 项目路径: D:\vllm-omni\workflow-starter - -## 项目背景 - -vLLM-Omni × HunyuanImage-3.0-Instruct。80B 多模态模型,AR(LLM)+ DiT(扩散)双阶段。 - -本次工作场景:T2T(text-to-text)offline 推理,只跑 AR 阶段(`mode="gen_text"`)。 -远端服务器:`47.79.124.13:31230`(SSH root 直连)。 -模型路径:`/mnt/models/hub/models--tencent--HunyuanImage-3.0-Instruct/snapshots/2ec2c78.../` - -## 本次会话目标 - -用户反馈 vllm-omni T2T 输出比 HF 官方模型缺少细节描述(无乱码、无重复,就是描述不丰富)。 -本会话目标: -1. 统一 SDPA / FA 注意力后端 -2. 跑 HF 官方 AR baseline,与 vllm-omni 输出对比,定位精度差异根因 - -## 已完成的工作 - -### 1. FA vs SDPA 对比测试(结论:两者输出完全相同) -- 测试脚本:远端 `/tmp/test_t2t_backends_v2.py` -- 配置:远端 `/tmp/t2t_tp2.yaml`(TP=2, temperature=0, greedy) -- 结论:FA 和 SDPA 输出逐字相同(2187 chars),**attention backend 不是精度差异的原因** -- 输出存档:`/tmp/t2t_fa_default.txt` 和 `/tmp/t2t_sdpa.txt`(内容一致) - -### 2. process_image() Siglip2 兼容性修复(已 commit + push) -- 文件:`D:/vllm-omni/wt-hunyuan-t2t-sdpa-fa/vllm_omni/model_executor/models/hunyuan_image3/hunyuan_image3.py` -- 问题:transformers ≥5.x 的 `Siglip2ImageProcessorFast` 返回 list 而非 tensor,`.squeeze(0)` 崩溃 -- 修复:在 `process_image()` 约 854-868 行加 `isinstance(x, list)` 判断 + `torch.stack()` -- 已提交:commit `42ee44b6`,branch `feature/hunyuan-t2t-sdpa-fa`,repo `zuiho-kai/vllm-omni` - -### 3. HF 模型 snapshot 已打好三个 patch - -文件:`/mnt/models/hub/models--tencent--HunyuanImage-3.0-Instruct/snapshots/2ec2c78bee7d4b94157341fba86c4c2c7b1858b2/modeling_hunyuan_image_3.py` - -| Patch | 状态 | 说明 | -|-------|------|------| -| RoPE broadcast fix (Bug1) | ✅ 已打 | `seq_len = q.size(-2)` else 分支 | -| 2D attention_mask fix (Bug2) | ✅ 已打 | `attention_mask.ndim == 2` → None | -| lazy_initialization 单参数 | ✅ 正确 | 4.57.1 版只需 `(key_states)`,5.x 才要两个参数 | -| use_cache in prepare_inputs | ✅ 已打 | 取消注释,为 transformers 5.x 加的,4.57.1 不影响 | -| use_cache in _update_model_kwargs | ✅ 已打 | 同上 | - -### 4. claudeception 知识固化 -- 更新 `memory/feedback_hf_trust_remote_code.md` 新增 Rule 6(patch snapshot 不是 cache)和 Rule 7(runbook 版本不容置疑) - -## 未完成的工作 - -### ⚠️ 主任务:跑 HF baseline 并与 vllm-omni 对比 - -**当前状态**:用户正在手动执行以下 4 步(会话结束时可能完成也可能没完成) - -**Step 1 — 杀进程 + 确认 GPU 空闲** -```bash -pkill -9 -f python 2>/dev/null; sleep 5; nvidia-smi --query-gpu=index,memory.used --format=csv,noheader -``` - -**Step 2 — 确认 snapshot runbook patch 已在**(已验证两个都是 ✅) -```bash -SNAP=/mnt/models/hub/models--tencent--HunyuanImage-3.0-Instruct/snapshots/2ec2c78bee7d4b94157341fba86c4c2c7b1858b2/modeling_hunyuan_image_3.py -grep -c 'seq_len = q.size(-2)' $SNAP # 应输出 1 -grep -c 'attention_mask.ndim == 2' $SNAP # 应输出 1 -``` - -**Step 3 — 清 module cache** -```bash -rm -rf /mnt/models/modules/transformers_modules/_2ec2c78bee7d4b94157341fba86c4c2c7b1858b2/ -``` - -**Step 4 — 用 venv_hf(transformers 4.57.1)跑** -```bash -source /root/venv_hf/bin/activate && python /tmp/hf_baseline_ar.py 2>&1 | tee /tmp/hf_baseline_ar.log -``` - -### ⚠️ 对比分析(HF baseline 跑完后) -```bash -cat /tmp/t2t_hf_baseline.txt # HF 官方 AR 输出 -cat /tmp/t2t_fa_default.txt # vllm-omni FA 输出 -``` -比较两者差异,判断是否有质量差距,找根因。 - -## 关键决策与发现 - -### FA = SDPA(已确认) -vllm-omni AR 的 FA 和 SDPA 路径在 temperature=0, greedy 下输出逐字相同。注意力后端不是精度差异来源。 - -### trust_remote_code 模型的 patch 必须改 snapshot(重要教训) -transformers 每次 `from_pretrained(..., trust_remote_code=True)` 都会从 snapshot 重建 -`$HF_HOME/modules/transformers_modules//`,覆盖所有对 cache dir 的手动修改。 -**必须 patch snapshot + rm -rf cache dir**。 - -### venv 区分 -- `/root/venv_hf` → transformers 4.57.1(HF baseline 专用,runbook 指定版本) -- `/root/venv` → transformers 5.6.2(vllm-omni 专用) - -### transformers 版本 API 差异 -- 4.57.1: `lazy_initialization(key_states)` — 1个参数 -- 5.6.2: `lazy_initialization(key_states, value_states)` — 2个参数 -- 4.50.0: `StaticCache` 没有 `layers` 属性,完全无法用 - -### HF 模型 gen_text 调用方式(正确) -```python -kw = model.prepare_model_inputs(prompt=PROMPT, mode="gen_text") -kw.pop("mode", None) # 避免 duplicate kwarg -kw["use_cache"] = True # 防止 transformers 5.x KeyError(4.57.1 不需要但无害) -out = model.generate(**kw, mode="gen_text", decode_text=True) -txt = out[0] # decode_text=True 返回 List[str] -``` - -### 本次会话犯的错:在 5.6.2 上打补丁而不是直接用 runbook 指定的 4.57.1 -打了 7+ 个补丁(lazy_init 参数/use_cache/KeyError),全是不必要的。教训写入 memory。 - -## 下一步建议 - -1. **确认 GPU 空闲**(`nvidia-smi`,两卡都应该 0 MiB) -2. **执行 Step 3 + Step 4**(清 cache,`source venv_hf` 跑 baseline) -3. **看 `/tmp/hf_baseline_ar.log` 输出**,如果报新错,优先读报错行附近的模型代码 -4. 输出存到 `/tmp/t2t_hf_baseline.txt` 后,`diff /tmp/t2t_hf_baseline.txt /tmp/t2t_fa_default.txt` 对比 - -如果 HF baseline 跑通了且输出有明显质量差距,根因大概率在: -- prompt 格式(vllm-omni vs HF 的 input_ids 对比) -- KV cache 精度(fp16 vs bf16) -- generation config(temperature/top_p 等) - -## 关键文件清单 - -| 文件 | 说明 | -|------|------| -| `远端 /tmp/hf_baseline_ar.py` | HF baseline 推理脚本(用 venv_hf 跑) | -| `远端 /tmp/hf_baseline_ar.log` | 最近一次运行日志 | -| `远端 /tmp/t2t_fa_default.txt` | vllm-omni FA 输出(2187 chars,基准) | -| `远端 /tmp/t2t_sdpa.txt` | vllm-omni SDPA 输出(与 FA 相同) | -| `远端 /tmp/t2t_tp2.yaml` | vllm-omni T2T 测试配置(TP=2) | -| `远端 snapshot/modeling_hunyuan_image_3.py` | HF 模型代码,已打 5 个 patch | -| `D:/vllm-omni/wt-hunyuan-t2t-sdpa-fa/vllm_omni/model_executor/models/hunyuan_image3/hunyuan_image3.py` | 本地 worktree,已修 process_image(),已 commit | -| `D:/vllm-omni/workflow-starter/memory/feedback_hf_trust_remote_code.md` | 本次会话新增 Rule 6/7 | -| `D:/vllm-omni/workflow-starter/memory/hf_baseline_runbook.md` | HF baseline 完整运行手册 | -| `C:\Users\user\.claude\plans\hunyuanimage3-ins-t2t-vllm-omni-t2t-sdp-quizzical-acorn.md` | 当前计划文件 | diff --git "a/knowledge/\351\201\227\350\250\200/\346\230\216\346\230\216tp2_fp8_sp2\345\222\214cfgp2\345\217\252\345\267\256\344\270\200\344\270\252\344\272\221\345\256\236\344\276\213\345\260\261\350\203\275\350\267\221\345\256\214\344\272\206-120000_27042026.md" "b/knowledge/\351\201\227\350\250\200/\346\230\216\346\230\216tp2_fp8_sp2\345\222\214cfgp2\345\217\252\345\267\256\344\270\200\344\270\252\344\272\221\345\256\236\344\276\213\345\260\261\350\203\275\350\267\221\345\256\214\344\272\206-120000_27042026.md" deleted file mode 100644 index 1befb36..0000000 --- "a/knowledge/\351\201\227\350\250\200/\346\230\216\346\230\216tp2_fp8_sp2\345\222\214cfgp2\345\217\252\345\267\256\344\270\200\344\270\252\344\272\221\345\256\236\344\276\213\345\260\261\350\203\275\350\267\221\345\256\214\344\272\206-120000_27042026.md" +++ /dev/null @@ -1,168 +0,0 @@ -# 遗言:明明 tp2_fp8_sp2 和 cfgp2 只差一个云实例就能跑完了 - -> 生成时间: 2026-04-27 12:00:00 -> 项目路径: D:\vllm-omni\workflow-starter(本地)/ `/home/fq9hpsac/fq9hpsacuser03/sources/vllm-omni`(远端) - ---- - -## 项目背景 - -**vLLM-Omni × HunyuanImage-3.0-Instruct** 接入工程。 - -- 仓库:`zuiho-kai/vllm-omni`,PR 分支 `feat/hunyuan-image3-accuracy-ci` -- 技术栈:Python / PyTorch / vLLM-Omni / Slurm / Docker / Buildkite CI -- 远端节点:`hk01dgx036`(8× H800 80GB),登录节点 `fq9hpsacuser03@10.248.12.11` -- 容器:`wzr_omni`,image `taichangzhou/vllm-omni-ci:cuda-12.9` -- venv:`/app/vllm-omni/.venv`(容器镜像预装) -- 模型缓存:`/home/models/hub`(Lustre 持久) - ---- - -## 本次会话目标 - -1. 跑完 HunyuanImage3 三个 perf 配置的 stage duration profiling: - - `tp4_fp8`(已完成) - - `tp2_fp8_sp2`(未完成,节点 GPU 全满) - - `tp2_fp8_cfgp2`(未完成,节点 GPU 全满) -2. 把结果写入 `memory/profiling_tp4_fp8_baseline.md`(已完成 tp4 部分) -3. 解决 Windows SSH 稳定性问题(已完成,方案固化到 memory) - ---- - -## 已完成的工作 - -### 1. tp4_fp8 profiling 基线跑通并记录 -- 节点 hk01dgx036,GPU 4,5,6,7(偷卡),NUM_STEPS=20,NUM_PROMPTS=2,1024×1024 -- 结果写入 `memory/profiling_tp4_fp8_baseline.md`: - - 端到端均值 2.85s,transformer forward 1.147s,VAE decode 0.487s - - 峰值显存 32.8 GB(4 卡),吞吐 0.35 req/s - -### 2. Windows SSH 方案固化 -- 用 `/c/Windows/System32/OpenSSH/ssh.exe` + key auth + 5次重试 -- 方案写入 `memory/ssh_windows_strategy.md` -- Error book 更新:`.claude_errors/remote_and_ssh.md`(ControlMaster 不可用、fail2ban、srun PATH、ioctl 错误、sinfo 查空闲 GPU) - -### 3. CI perf test 拆分方案(PR #2495) -- HunyuanImage3 perf test 从 mandatory CI step 拆出为独立 step -- `soft_fail: true` + `RUN_HUNYUAN_IMAGE3_PERF=1` env gate -- 3 个 JSON 配置拆分(tp4_fp8 / tp2_fp8_sp2 / tp2_fp8_cfgp2),每个独立 pytest 调用 -- 模型改为 `tencent/HunyuanImage-3.0-Instruct` -- profiling 脚本移到 `tools/`,model 作为 CLI 参数 - -### 4. async_chunk 问题修复 -- 单阶段 diffusion pipeline 需要 `async_chunk: false` -- 方案:创建 `vllm_omni/deploy/hunyuan_image_3_moe.yaml`(`async_chunk: false`) -- 记录在 `memory/async_chunk_default_gotcha.md` 和 `.claude_errors/profiling_and_model_loading.md` - -### 5. HF_HUB_CACHE 覆盖问题修复 -- Docker 镜像设了 `HF_HUB_CACHE=/models/hub`,覆盖 `HF_HOME` -- 进容器后必须 `unset HF_HUB_CACHE`(和 `unset TRANSFORMERS_CACHE` 一起) -- 记录在 `memory/hf_hub_cache_gotcha.md` 和 `.claude_errors/profiling_and_model_loading.md` - -### 6. srun module load 问题 -- 新登录节点 srun 不在 PATH,需 `source /etc/profile && module load slurm/slurm/23.02.7` -- 记录在 `.claude_errors/remote_and_ssh.md` - ---- - -## 未完成的工作 - -### tp2_fp8_sp2 和 tp2_fp8_cfgp2 profiling 未跑 -- **原因**:hk01dgx036 节点 GPU 全满(8 卡全被占),无法偷卡 -- **状态**:需要等节点空闲,或换一个有空闲 GPU 的节点/云实例 - -### 云实例方案(已分析,未执行) -用户在看某云平台的容器实例配置界面(Start Command / File system Mount / Environment Variable / Ports & Protocol / Lifecycle)。 - -推荐配置: -- **实例类型**:`c48m8192.L20X`(4× L20X,每卡 140GB,$0.68/h) -- 可跑三个配置(tp4_fp8 / tp2_fp8_sp2 / tp2_fp8_cfgp2) -- 跑完立刻删,总费用 ≤ $2 - ---- - -## 关键决策与发现 - -1. **偷卡模式**:`srun --gres=gpu:2` + 容器 `--gpus all` → 能看到节点全部 8 卡,挑空闲的用。申请保底卡数,进容器看全景,偷空闲卡。 - -2. **HF 缓存变量优先级**(坑最多): - - `HF_HUB_CACHE` > `TRANSFORMERS_CACHE` > `HF_HOME` - - 进容器后必须同时 `unset HF_HUB_CACHE && unset TRANSFORMERS_CACHE` - - 空字符串 ≠ unset - -3. **async_chunk 默认 True**:单阶段 diffusion pipeline 没有 next-stage processor,必须 `async_chunk: false`,否则 ValueError。 - -4. **srun --pty 在非交互 SSH 下报 ioctl 错误**:不影响执行,忽略即可。需要真正交互式 shell 必须用 tmux。 - -5. **Windows SSH 稳定性**:Git Bash SSH 触发 fail2ban,必须用 Windows 原生 OpenSSH + key auth。 - ---- - -## 下一步建议(新会话直接执行) - -### 方案 A:等 hk01dgx036 空闲(免费) - -```bash -WIN_SSH=/c/Windows/System32/OpenSSH/ssh.exe -# 查空闲 GPU -$WIN_SSH vllm-server 'source /etc/profile && module load slurm/slurm/23.02.7 2>/dev/null; sinfo -p q-fq9hpsac --noheader -o "%n %G %C %t" | grep hk01dgx036' -``` - -有空闲卡后: -```bash -# 申请 2 卡(保底),进容器偷空闲卡 -srun -p q-fq9hpsac -w hk01dgx036 --gres=gpu:2 --cpus-per-gpu=24 --mem-per-cpu=8G --job-name=wzr --pty bash -docker exec -it wzr_omni bash - -# 进容器后标准三连 -export HF_HOME=/home/models -unset HF_HUB_CACHE -unset TRANSFORMERS_CACHE -source /app/vllm-omni/.venv/bin/activate -git config --global --add safe.directory "*" -cd /home/fq9hpsac/fq9hpsacuser03/sources/vllm-omni - -# 查空闲卡 -nvidia-smi --query-gpu=index,memory.used,memory.free --format=csv,noheader - -# 跑 tp2_fp8_sp2(假设空闲卡是 4,5) -cd /tmp -python tools/profile_diffusion_pipeline.py \ - --model tencent/HunyuanImage-3.0-Instruct \ - --config tp2_fp8_sp2 \ - --devices 4,5 \ - --num-steps 20 --num-prompts 2 \ - 2>&1 | tee /tmp/prof_tp2_sp2.log - -# 跑 tp2_fp8_cfgp2(假设空闲卡是 6,7) -python tools/profile_diffusion_pipeline.py \ - --model tencent/HunyuanImage-3.0-Instruct \ - --config tp2_fp8_cfgp2 \ - --devices 6,7 \ - --num-steps 20 --num-prompts 2 \ - 2>&1 | tee /tmp/prof_tp2_cfgp2.log -``` - -### 方案 B:云实例($0.68/h,最快) - -1. 创建 `c48m8192.L20X` 实例(4× L20X 140GB) -2. Start Command:`tail -f /dev/null`(保持容器活着) -3. 挂载:把模型目录挂进去,或者用 `HF_HUB_OFFLINE=0` 现下 -4. 进容器后同样执行标准三连 + profiling 命令 - ---- - -## 关键文件清单 - -| 文件 | 说明 | -|------|------| -| `memory/profiling_tp4_fp8_baseline.md` | tp4_fp8 profiling 基线结果(已填) | -| `memory/ci_hunyuan_perf_isolation.md` | CI perf test 拆分方案说明(PR #2495) | -| `memory/ssh_windows_strategy.md` | Windows SSH 可靠方案(key auth + retry) | -| `memory/hf_hub_cache_gotcha.md` | HF_HUB_CACHE 覆盖 HF_HOME 陷阱 | -| `memory/async_chunk_default_gotcha.md` | async_chunk 默认 True 导致 ValueError | -| `memory/steal_idle_gpus.md` | 偷卡技巧:申请少卡 + 容器 --gpus all | -| `memory/remote_0036_env.md` | hk01dgx036 节点完整环境信息 | -| `.claude_errors/remote_and_ssh.md` | SSH / Slurm 踩坑记录(本次新增 4 条) | -| `.claude_errors/profiling_and_model_loading.md` | Profiling 踩坑(HF_HUB_CACHE、async_chunk) | -| `memory/hunyuanimage3_ci_progress.md` | GEBench accuracy CI 当前进展(独立分支) | diff --git a/plugins/infermatrix-copilot/skills/imreview/SKILL.md b/plugins/infermatrix-copilot/skills/imreview/SKILL.md index ab2045e..a0f2166 100644 --- a/plugins/infermatrix-copilot/skills/imreview/SKILL.md +++ b/plugins/infermatrix-copilot/skills/imreview/SKILL.md @@ -3,13 +3,39 @@ name: imreview description: Review a PR or local changes with InferMatrixCopilot Direct mode. Use when the user invokes imreview. --- -Call InferMatrixCopilot `review` with `mode="direct"` for the supplied target, -or the current PR/worktree when omitted. Read `knowledge_entry`, inspect the -live code, and return only evidence-backed findings with file/line references. -Within 60 seconds, first update the host conversation with the pinned head SHA, -current CI status, mergeability, and any early findings. Mark early findings as -preliminary and continue the review. This update is not a GitHub comment; do not -post an interim review. +For the supplied target, or the current PR/worktree when omitted, first pin one +snapshot and collect title, body, changed files, head SHA, CI, and mergeability. +Immediately update the host conversation with the pinned head SHA, current CI +status, mergeability, and any early findings before reading knowledge, searching +source, or running tests. Within 60 seconds, do this. Then call +InferMatrixCopilot `review` once +with `mode="direct"` plus the +collected `title`, `body`, and `changed_files`. Use the embedded `quick_map` in +each returned `knowledge_routes` item. Do not open the full route file unless a +concrete ambiguity blocks source review, and do not reopen `AGENTS.md`, +`CLAUDE.md`, repo indexes, or model catalogs. Inspect the live code and return +only evidence-backed findings with file/line references. +Treat the returned `execution_budget` as a hard ceiling. At the limit, return +the supported verdict plus any remaining validation gap. Extend it once by the +returned allowance only when a concrete unresolved P1/high-risk contract +remains, and state that question before extending. +After the progress update, run independent knowledge/source and validation +tracks concurrently. Keep one in-review evidence packet and reuse +files, bounded `rg` searches, callers, tests, repo-map, routing, and findings. +Treat CI as status unless its first failure overlaps the frozen diff or blocks +the verdict; do not open unrelated CI logs. For docs-only changes, skip the +dependency preflight and pytest, and use diff hygiene plus bounded checks of the +referenced live contract. +Before pytest, run a short import/version compatibility preflight. Bind every +validation command and result to the head SHA and an environment fingerprint; +reuse an environment only when its dependency fingerprint matches. After the +preflight passes, run targeted tests and low-cost static checks alongside the +source review. +Stop when every changed semantic path has a supported finding or an explicit +no-issue conclusion; do not add searches only for confidence. +Do not wait for CI completion or resolved mergeability before the progress +update. Mark early findings as preliminary and continue the review. This update +is not a GitHub comment; do not post an interim review. Before finalizing, classify `subtraction_signal`. Use `none` without a minimality proof when the diff does not add or expand a helper, class, fallback, compatibility branch, or public behavior. Use `triggered` for those changes and diff --git a/src/infermatrix_copilot/thin_mcp_server.py b/src/infermatrix_copilot/thin_mcp_server.py index a540e42..84699dc 100644 --- a/src/infermatrix_copilot/thin_mcp_server.py +++ b/src/infermatrix_copilot/thin_mcp_server.py @@ -43,11 +43,141 @@ def _knowledge_root() -> Path: _REPO_ALIASES = { "vllm-project/vllm-omni": "vllm-omni", } +_DIRECT_OWNER_ROUTES = ( + { + "owner": "configuration", + "path": "repos/vllm-omni/components/configuration/rules.md", + "signals": ( + "config", + "configuration", + "yaml", + "registry", + "deploy", + "pipeline", + "override", + "default", + "cli flag", + "topology", + ), + "scope_prefixes": ( + "vllm_omni/config/", + "vllm_omni/deploy/", + ), + }, + { + "owner": "serving", + "path": "repos/vllm-omni/components/serving/rules.md", + "signals": ( + "serving", + "server", + "endpoint", + "openai", + "request", + "response", + "http", + "chat completion", + "completion endpoint", + "speech api", + "sse", + "websocket", + "sleep", + "wake", + "partial wake", + "engine lifecycle", + "idempotency", + "ack", + ), + "scope_prefixes": ( + "vllm_omni/entrypoints/openai/", + "vllm_omni/entrypoints/api_server.py", + "vllm_omni/entrypoints/async_omni.py", + ), + }, + { + "owner": "model-executor", + "path": "repos/vllm-omni/components/model-executor/rules.md", + "signals": ( + "model executor", + "loader", + "checkpoint", + "tokenizer", + "processor", + "stage input", + "stage handoff", + "runtime info", + "runtime_info", + "batch", + "sampling", + ), + "scope_prefixes": ( + "vllm_omni/model_executor/", + "vllm_omni/inputs/", + ), + }, + { + "owner": "diffusion", + "path": "repos/vllm-omni/components/diffusion/rules.md", + "signals": ( + "diffusion", + "image generation", + "text to image", + "image to image", + "lora", + "vae", + "dit", + "ulysses", + "cache dit", + ), + "scope_prefixes": ( + "vllm_omni/diffusion/", + "vllm_omni/model_executor/models/diffusers/", + ), + }, + { + "owner": "distributed", + "path": "repos/vllm-omni/components/distributed/_index.md", + "signals": ( + "distributed", + "tensor parallel", + "data parallel", + "replica", + "collective", + "rpc", + ), + "scope_prefixes": ( + "vllm_omni/distributed/", + "vllm_omni/worker/", + "vllm_omni/entrypoints/async_omni.py", + ), + }, + { + "owner": "scheduler", + "path": "repos/vllm-omni/components/scheduler/rules.md", + "signals": ( + "scheduler", + "scheduling", + "prefix cache", + "token budget", + "queue", + "side stream", + ), + "scope_prefixes": ( + "vllm_omni/core/sched/", + "vllm_omni/diffusion/sched/", + ), + }, +) _DIRECT_REVIEW_CHECKLIST = [ "Freeze one base/head snapshot and collect PR intent, diff, mergeability, and CI once.", - "Within 60 seconds, report head SHA, CI, mergeability, and preliminary findings in the host conversation; continue the review without posting a GitHub comment.", - "Route PR title/body to exact owner/model rules; use changed files only to validate scope.", - "Reuse one evidence packet for callers, tests, correctness findings, and design/subtraction.", + "Immediately after snapshot metadata returns, report head SHA, CI, mergeability, and preliminary findings in the host conversation; do this before reading knowledge, searching source, or running tests.", + "Call Direct once with the collected title, body, and changed_files; read only the returned knowledge_routes and stop knowledge navigation.", + "After the progress update, run independent knowledge/source and validation tracks concurrently.", + "Reuse one in-review evidence packet for files, bounded rg searches, callers, tests, repo-map, routing, and findings.", + "Treat CI as status only; open logs only when the first failure overlaps the frozen diff or blocks the verdict.", + "For docs-only changes, skip dependency preflight and pytest; use diff hygiene plus bounded checks of the referenced live contract.", + "Before pytest, run a short import/version compatibility preflight; bind commands and results to head SHA and an environment fingerprint.", + "After preflight passes, run targeted tests and low-cost static checks alongside source review.", + "Stop investigating when every changed semantic path has a supported finding or explicit no-issue conclusion; do not add searches only for confidence.", "Run subtraction only when the diff adds or expands a helper, class, fallback, compatibility branch, or public behavior; otherwise mark no subtraction signal.", "Plan exactly one consolidated final review comment.", ] @@ -63,6 +193,15 @@ def _knowledge_root() -> Path: "early_findings_status": "preliminary", "continue_review": True, "github_comment": False, + "emit_before": [ + "knowledge_read", + "source_search", + "tests", + ], + "do_not_wait_for": [ + "ci_completion", + "mergeability_resolution", + ], } _SUBTRACTION_ACTIONS = {"DELETE", "DEFER", "INLINE", "MERGE", "MOVE"} _SUBTRACTION_SIGNALS = {"none", "triggered"} @@ -104,6 +243,190 @@ def _knowledge_entry(name: str) -> str: return str(path) +def _knowledge_path(relative_path: str) -> str: + path = (_KNOWLEDGE / relative_path).resolve() + try: + path.relative_to(_KNOWLEDGE.resolve()) + except ValueError as exc: + raise ValueError( + f"knowledge route escapes the knowledge root: {relative_path}" + ) from exc + if not path.is_file(): + raise FileNotFoundError(f"knowledge route is missing: {path}") + return str(path) + + +def _route_text(value: str) -> str: + normalized = re.sub(r"[_./-]+", " ", str(value).casefold()) + return re.sub(r"\s+", " ", normalized).strip() + + +def _signal_matches(text: str, signal: str) -> bool: + normalized = _route_text(signal) + return bool( + re.search( + rf"(? str: + """Return only the embedded Direct code map, never the whole rule page.""" + lines = Path(path).read_text(encoding="utf-8").splitlines() + start = next( + ( + index for index, line in enumerate(lines) + if re.match(r"^##\s+.*Direct", line, re.IGNORECASE) + ), + None, + ) + if start is None: + return "" + end = next( + ( + index for index in range(start + 1, len(lines)) + if lines[index].startswith("## ") + ), + len(lines), + ) + excerpt = "\n".join(lines[start:end]).strip() + if len(excerpt) <= max_chars: + return excerpt + return excerpt[:max_chars].rsplit("\n", 1)[0].rstrip() + + +def _direct_execution_budget(changed_files: list[str]) -> dict: + normalized = [path.replace("\\", "/").casefold() for path in changed_files] + docs_only = bool(normalized) and all( + path.startswith(("docs/", "doc/", "recipes/")) + or path.endswith((".md", ".mdx", ".rst", ".txt")) + for path in normalized + ) + return { + "profile": "docs_only" if docs_only else "code", + "knowledge_file_reads": 0, + "initial_source_files": 6, + "search_matches_per_query": 40, + "command_output_chars": 12000, + "validation_commands": 2 if docs_only else 4, + "total_command_calls": 12 if docs_only else 20, + "hard_ceiling": True, + "extension_command_calls": 4, + "on_limit": ( + "Stop and return the supported verdict plus remaining validation " + "gap unless the bounded extension condition is met." + ), + "extension": ( + "One bounded extension is allowed only for a concrete unresolved " + "P1/high-risk contract; state the question before extending." + ), + } + + +def _direct_knowledge_routes( + repo: str, + *, + title: str = "", + body: str = "", + changed_files: Optional[list[str]] = None, +) -> dict: + """Select bounded Direct knowledge routes from PR intent. + + Title/body select owners. Changed files only report whether the frozen diff + supports or contradicts that selection; they never silently replace it. + """ + selected_repo = _normalize_repo(repo) + changed_files = changed_files or [] + if not isinstance(changed_files, list) or any( + not isinstance(path, str) for path in changed_files + ): + raise ValueError("changed_files must be a list of paths") + + intent = _route_text(f"{title}\n{body}") + if not intent: + return { + "status": "needs_pr_context", + "selected_by": "title_body", + "required": ["title", "body", "changed_files"], + "changed_files_role": "scope_validation_only", + "routes": [], + "scope_validation": [], + } + if selected_repo != "vllm-omni": + return { + "status": "unsupported_exact_router", + "selected_by": "title_body", + "changed_files_role": "scope_validation_only", + "routes": [], + "scope_validation": [], + } + + owner_routes: list[dict[str, object]] = [] + for route in _DIRECT_OWNER_ROUTES: + matched = [ + signal for signal in route["signals"] + if _signal_matches(intent, signal) + ] + if matched: + path = _knowledge_path(str(route["path"])) + owner_routes.append({ + "owner": str(route["owner"]), + "path": path, + "reason": f"title/body: {', '.join(matched[:3])}", + "quick_map": _direct_quick_map(path), + "read_required": False, + }) + + model_routes: list[dict[str, object]] = [] + model_root = _KNOWLEDGE / "repos" / "vllm-omni" / "models" + for model_dir in sorted(model_root.iterdir(), key=lambda path: -len(path.name)): + rules = model_dir / "rules.md" + if not rules.is_file(): + continue + model_name = _route_text(model_dir.name) + compact_name = re.sub(r"[^a-z0-9]", "", model_name) + compact_intent = re.sub(r"[^a-z0-9]", "", intent) + exact_match = _signal_matches(intent, model_name) + compact_match = len(compact_name) >= 8 and compact_name in compact_intent + if exact_match or compact_match: + path = str(rules.resolve()) + model_routes.append({ + "owner": f"model:{model_dir.name}", + "path": path, + "reason": f"title/body model: {model_dir.name}", + "quick_map": _direct_quick_map(path), + "read_required": False, + }) + + routes = (model_routes + owner_routes)[:3] + scope_validation = [] + for route in _DIRECT_OWNER_ROUTES: + hits = sorted({ + path for path in changed_files + if any( + path.replace("\\", "/").startswith(prefix) + for prefix in route["scope_prefixes"] + ) + }) + if hits: + scope_validation.append({ + "owner": route["owner"], + "changed_files": hits, + "selected_from_description": any( + item["owner"] == route["owner"] for item in owner_routes + ), + }) + + return { + "status": "ready" if routes else "description_unrouted", + "selected_by": "title_body", + "changed_files_role": "scope_validation_only", + "routes": routes, + "scope_validation": scope_validation, + } + + def _direct_completion_result( subtraction_signal: str = "", subtraction: Optional[list[dict[str, str]]] = None, @@ -251,11 +574,18 @@ def build_mcp( "infermatrix-copilot", instructions=( "Use review in direct mode unless the user explicitly requests " - "Strict. Direct returns a knowledge entry and compact first-review " - "checklist for the host model. Within 60 seconds the host reports " - "head SHA, CI, mergeability, and preliminary findings in its " - "conversation, then continues reviewing without posting an early " - "GitHub comment. Before treating a Direct review as " + "Strict. For Direct, first freeze the PR snapshot and report head " + "SHA, CI, mergeability, and preliminary findings in the host " + "conversation. Do not read knowledge or source before that update. " + "Then call review once with title, body, and changed_files. Direct " + "returns at most three exact knowledge routes with embedded quick " + "maps; use those excerpts and do not open full rule pages unless a " + "concrete ambiguity blocks source review. Follow the returned " + "execution_budget as a hard ceiling; stop with the supported " + "verdict at the limit. Extend it once by the returned allowance " + "only for a stated unresolved P1/high-risk contract. Continue " + "reviewing without " + "posting an early GitHub comment. Before treating a Direct review as " "complete or posting its only final comment, call " "validate_direct_review. Mark subtraction_signal=none when the diff " "does not add or expand a helper, class, fallback, compatibility " @@ -275,12 +605,17 @@ def review( mode: str = "direct", post: bool = False, review_depth: str = "", + title: str = "", + body: str = "", + changed_files: Optional[list[str]] = None, ) -> dict: """Begin a Direct or Strict review. - Direct returns the knowledge entrypoint for the host model. Strict - runs the previous Eco PR-review workflow. ``post`` still requires both - explicit user intent and server-side ``ALLOW_POST=1``. + For Direct, first collect the frozen PR title, body, and changed files, + publish the host progress update, then pass that context here. Direct + returns at most three exact owner/model routes; changed files only + validate scope. Strict runs the previous Eco PR-review workflow. + ``post`` still requires explicit intent and server-side ``ALLOW_POST=1``. """ def run() -> dict: if not str(target).strip(): @@ -289,9 +624,37 @@ def run() -> dict: if selected_mode not in {"direct", "strict"}: raise ValueError("mode must be 'direct' or 'strict'") if selected_mode == "direct": + routing = _direct_knowledge_routes( + repo, + title=title, + body=body, + changed_files=changed_files, + ) + knowledge_routes = routing["routes"] + knowledge_entry = ( + knowledge_routes[0]["path"] + if knowledge_routes + else _knowledge_entry("AGENTS.md") + ) return { "mode": "direct", - "knowledge_entry": _knowledge_entry("AGENTS.md"), + "knowledge_entry": knowledge_entry, + "knowledge_routes": knowledge_routes, + "routing": { + key: value for key, value in routing.items() + if key != "routes" + }, + "navigation_policy": { + "progress_before_knowledge": True, + "use_embedded_quick_maps": True, + "open_route_file_only_for_concrete_ambiguity": True, + "max_routes": 3, + "stop_after_routes": True, + "fallback_entry": _knowledge_entry("AGENTS.md"), + }, + "execution_budget": _direct_execution_budget( + changed_files or [] + ), "first_review_checklist": list(_DIRECT_REVIEW_CHECKLIST), "progress_update": { **_DIRECT_PROGRESS_UPDATE, diff --git a/test/test_imreview_output_contract.py b/test/test_imreview_output_contract.py index bf8a303..ed53d7b 100644 --- a/test/test_imreview_output_contract.py +++ b/test/test_imreview_output_contract.py @@ -26,3 +26,13 @@ def test_imreview_returns_github_style_findings(prompt_path: Path) -> None: assert "classify `subtraction_signal`" in prompt assert "Use `none` without a minimality proof" in prompt assert "Use `triggered` for those changes" in prompt + assert ( + "After the progress update, run independent knowledge/source and " + "validation tracks concurrently" + ) in prompt + assert "Use the embedded `quick_map`" in prompt + assert "Do not open the full route file" in prompt + assert "before reading knowledge, searching source, or running tests" in prompt + assert "bounded `rg` searches" in prompt + assert "import/version compatibility preflight" in prompt + assert "head SHA and an environment fingerprint" in prompt diff --git a/test/test_thin_mcp_server.py b/test/test_thin_mcp_server.py index 939b826..6eb1c84 100644 --- a/test/test_thin_mcp_server.py +++ b/test/test_thin_mcp_server.py @@ -8,6 +8,7 @@ from infermatrix_copilot.thin_mcp_server import ( build_mcp, _direct_completion_result, + _direct_knowledge_routes, _docs, _normalize_repo, ) @@ -80,6 +81,10 @@ def test_direct_entrypoints_do_not_resolve_repo(monkeypatch): assert set(review) == { "mode", "knowledge_entry", + "knowledge_routes", + "routing", + "navigation_policy", + "execution_budget", "first_review_checklist", "progress_update", "completion_gate", @@ -87,10 +92,33 @@ def test_direct_entrypoints_do_not_resolve_repo(monkeypatch): assert review["mode"] == "direct" assert core.requests == [] assert Path(review["knowledge_entry"]).parts[-2:] == ("knowledge", "AGENTS.md") + assert review["knowledge_routes"] == [] + assert review["routing"]["status"] == "needs_pr_context" + assert review["navigation_policy"]["progress_before_knowledge"] is True + assert review["navigation_policy"]["use_embedded_quick_maps"] is True + assert review["navigation_policy"]["stop_after_routes"] is True + assert review["execution_budget"]["profile"] == "code" + assert review["execution_budget"]["total_command_calls"] == 20 + assert review["execution_budget"]["hard_ceiling"] is True + assert review["execution_budget"]["extension_command_calls"] == 4 assert any( "subtraction" in item for item in review["first_review_checklist"] ) + assert any( + "before reading knowledge, searching source, or running tests" + in item + for item in review["first_review_checklist"] + ) + assert any( + "bounded rg searches" in item + for item in review["first_review_checklist"] + ) + assert any( + "compatibility preflight" in item + and "environment fingerprint" in item + for item in review["first_review_checklist"] + ) assert review["progress_update"] == { "deadline_seconds": 60, "channel": "host_conversation", @@ -103,6 +131,15 @@ def test_direct_entrypoints_do_not_resolve_repo(monkeypatch): "early_findings_status": "preliminary", "continue_review": True, "github_comment": False, + "emit_before": [ + "knowledge_read", + "source_search", + "tests", + ], + "do_not_wait_for": [ + "ci_completion", + "mergeability_resolution", + ], } assert review["completion_gate"] == { "tool": "validate_direct_review", @@ -126,6 +163,124 @@ def test_direct_entrypoints_do_not_resolve_repo(monkeypatch): ) +def test_direct_routes_title_body_before_changed_files(monkeypatch): + mcp, _core = _fake_mcp(monkeypatch) + review = mcp.tools["review"]( + target="https://github.com/vllm-project/vllm-omni/pull/4762", + repo="vllm-project/vllm-omni", + mode="direct", + title="[Core / Bugfix] Add Mechanism for Endpoint Rejection", + body=( + "Add pipeline config endpoint restrictions and return a 400 from " + "the OpenAI serving layer." + ), + changed_files=[ + "vllm_omni/config/config_factory.py", + "vllm_omni/entrypoints/openai/api_server.py", + "vllm_omni/model_executor/models/qwen3_omni/model.py", + ], + ) + + assert review["routing"]["status"] == "ready" + assert review["routing"]["changed_files_role"] == "scope_validation_only" + assert [route["owner"] for route in review["knowledge_routes"]] == [ + "configuration", + "serving", + ] + assert review["knowledge_entry"] == review["knowledge_routes"][0]["path"] + assert all( + Path(route["path"]).is_file() + for route in review["knowledge_routes"] + ) + assert all( + "## Direct" in route["quick_map"] + and len(route["quick_map"]) <= 3500 + and route["read_required"] is False + for route in review["knowledge_routes"] + ) + scope = { + item["owner"]: item + for item in review["routing"]["scope_validation"] + } + assert scope["model-executor"]["selected_from_description"] is False + assert review["execution_budget"]["profile"] == "code" + assert review["execution_budget"]["knowledge_file_reads"] == 0 + + +def test_direct_docs_only_budget_stays_small(monkeypatch): + mcp, _core = _fake_mcp(monkeypatch) + review = mcp.tools["review"]( + target="https://github.com/vllm-project/vllm-omni/pull/4950", + mode="direct", + title="Fix MiniCPM-o 4.5 TTS request example", + body="Correct the serving request and TTS response documentation.", + changed_files=["recipes/OpenBMB/MiniCPM-o-4_5.md"], + ) + + assert review["execution_budget"]["profile"] == "docs_only" + assert review["execution_budget"]["validation_commands"] == 2 + assert review["execution_budget"]["total_command_calls"] == 12 + assert review["execution_budget"]["command_output_chars"] == 12000 + assert review["execution_budget"]["hard_ceiling"] is True + + +def test_direct_serving_quick_map_covers_request_and_lifecycle(monkeypatch): + mcp, _core = _fake_mcp(monkeypatch) + + docs_review = mcp.tools["review"]( + target="https://github.com/vllm-project/vllm-omni/pull/4950", + mode="direct", + title="Fix MiniCPM-o 4.5 TTS request example", + body="Correct chat_template_kwargs and the TTS response contract.", + changed_files=["recipes/OpenBMB/MiniCPM-o-4_5.md"], + ) + assert [ + route["owner"] for route in docs_review["knowledge_routes"] + ] == ["model:minicpm-o-4-5", "serving"] + serving_map = next( + route["quick_map"] + for route in docs_review["knowledge_routes"] + if route["owner"] == "serving" + ) + assert "chat_template_kwargs" in serving_map + assert "chat_completion_full_generator" in serving_map + + lifecycle_review = mcp.tools["review"]( + target="https://github.com/vllm-project/vllm-omni/pull/4834", + mode="direct", + title="[Bugfix] Guard generation during partial wake", + body=( + "Preserve sleep/wake stage scope, validate worker ACKs, and make " + "wake idempotent." + ), + changed_files=[ + "vllm_omni/entrypoints/async_omni.py", + "vllm_omni/worker/base.py", + ], + ) + owners = [route["owner"] for route in lifecycle_review["knowledge_routes"]] + assert owners == ["serving"] + assert "SERV-5a" in lifecycle_review["knowledge_routes"][0]["quick_map"] + + +def test_direct_routes_model_rules_without_index_navigation(): + routing = _direct_knowledge_routes( + "vllm-omni", + title="Fix MiniCPM-o 4.5 TTS request example", + body="The serving request must reach the TTS stage input processor.", + changed_files=["recipes/OpenBMB/MiniCPM-o-4_5.md"], + ) + + assert routing["status"] == "ready" + assert [route["owner"] for route in routing["routes"]] == [ + "model:minicpm-o-4-5", + "serving", + "model-executor", + ] + assert len(routing["routes"]) == 3 + assert all(route["quick_map"] for route in routing["routes"]) + + def test_direct_completion_requires_subtraction_signal_classification(): result = _direct_completion_result()