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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions knowledge/repos/afd-plugin/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ sources:
| 核对 connector/graph/DBO 当前支持组合 | [execution-platforms](components/execution-platforms/architecture.md) | v0.26 CUDA/Ascend 平台现状 |

默认 briefing 只加载本入口和仓库规则;深层 owner 页面由 changed-file route 或 `doc_search` / `doc_read` 按需读取。
- [AFD plugin 评审规则:上游漂移与跨文档隐含不变量](rules-seed-vllm-omni-rebase-upstream-api-drift.md)
- [适用于任何 AFD PR review 的通用规则。先读这一页,再读本仓库的 rules.md 和对应的组件 owner 页。](../../general/review/rules.md)
- [以下情况读这一页,判断是否应先改上游:新增或刷新 compat patch、复制 vLLM/vLLM-Ascend 函数,或在 MoE routing、graph、forward context 上偏离原生实现。](../../general/review/guides/upstream-first-for-algorithm.md)
160 changes: 160 additions & 0 deletions knowledge/repos/afd-plugin/_routes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Direct-mode owner routing for afd-plugin, written by kb init (pin 9cae2d2ddaae).
schema_version: 1
owners:
- owner: components
path: repos/afd-plugin/components/_index.md
Comment on lines +2 to +5

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve adapter coverage before enabling this route table

Adding a nonempty _routes.yaml makes _direct_knowledge_routes bypass the existing AFD adapter mapping, but this table omits established paths such as afd_plugin/config.py, afd_plugin/v1/worker/attention_worker.py, and afd_plugin/v1/worker/ffn_worker.py. For a PR with a generic description, each of those now returns description_unrouted with no route or scope validation, and PYTHONPATH=src pytest -q test/test_knowledge_view_routing.py::test_golden_routes_unchanged_by_extraction fails for both AFD fixtures. Because Direct reviews consume only the exact routes returned, either retain the adapter fallback or make this table reach parity before activating it.

AGENTS.md reference: knowledge/AGENTS.md:L16-L16

Useful? React with 👍 / 👎.

signals:
- components
scope_prefixes:
- afd_plugin/connectors/
- afd_plugin/model_executor/
- afd_plugin/compat/
- owner: attention-runtime
path: repos/afd-plugin/components/attention-runtime/_index.md
signals:
- attention runtime
scope_prefixes:
- afd_plugin/v1/worker/attention_model_runner.py
- owner: connectors
path: repos/afd-plugin/components/connectors/_index.md
signals:
- connectors
scope_prefixes:
- afd_plugin/connectors/
- afd_plugin/distributed/
- owner: ffn-runtime
path: repos/afd-plugin/components/ffn-runtime/_index.md
signals:
- ffn runtime
scope_prefixes:
- afd_plugin/v1/worker/ffn_model_runner.py
- owner: model-integration
path: repos/afd-plugin/components/model-integration/_index.md
signals:
- model integration
scope_prefixes:
- afd_plugin/model_executor/
- owner: plugin-boundary
path: repos/afd-plugin/components/plugin-boundary/_index.md
signals:
- plugin boundary
scope_prefixes:
- afd_plugin/__init__.py
- afd_plugin/v1/__init__.py
- owner: execution-platforms
path: repos/afd-plugin/components/execution-platforms/_index.md
signals:
- cuda graph
- acl graph
- graph
- FULL_DECODE_ONLY
- DBO
- ubatch
- profiler
- npu
- ascend
- csrc
- aclnn
- a2e
- e2a
- CANN
- build
- MLA graph
- stream
scope_prefixes:
- afd_plugin/compat/profiler.py
- afd_plugin/compat/npu/forward_context.py
- afd_plugin/compat/npu/ops.py
- afd_plugin/compat/npu/profiler.py
- afd_plugin/v1/worker/cuda_graph.py
- afd_plugin/v1/worker/dbo.py
- afd_plugin/v1/worker/npu/forward_context.py
- afd_plugin/v1/worker/npu/mla_graph.py
- afd_plugin/v1/worker/npu/npu_ubatch_wrapper.py
- afd_plugin/v1/worker/npu/ubatch_utils.py
- afd_plugin/v1/worker/npu/ubatching.py
- csrc/
- setup.py
- MANIFEST.in
- docs/design/module/execution_platforms.md
- docs/npu/CAM_ASYNC_ROUTED_OPS.md
- tests/unit/compat/test_profiler.py
- tests/unit/compat/test_ascend_ops.py
- tests/unit/compat/npu/test_profiler.py
- tests/unit/package/test_ascend_build_files.py
- tests/unit/v1/worker/test_cuda_graph.py
- tests/unit/v1/worker/test_dbo.py
- tests/unit/v1/worker/test_npu_mla_graph.py
- tests/unit/v1/worker/test_npu_device_contract.py
- tests/unit/v1/worker/test_npu_runtime.py
- owner: compatibility
path: repos/afd-plugin/components/compatibility/_index.md
signals:
- patch
- monkey patch
- compat
- bump vllm
- vllm upgrade
- vllm-ascend
- EngineCore
- engine core
- async dp
- config_validation
- force load balance
- routing simulator
- upstream
scope_prefixes:
- afd_plugin/compat/
- afd_plugin/model_executor/routing_simulator.py
- docs/design/module/compatibility_and_patches.md
- tests/unit/compat/
- tests/unit/model_executor/test_routing_simulator.py
- owner: e2e-ci
path: repos/afd-plugin/rules.md
signals:
- e2e
- ci
- buildkite
- github actions
- workflow
- gsm8k
- accuracy
- e2e runner
- test
- docker
- pre-commit
- lint
scope_prefixes:
- tests/e2e/
- tests/conftest.py
- tests/unit/test_e2e_runner.py
- tests/unit/test_e2e_process_utils.py
- tests/unit/test_dsv4_e2e.py
- .agents/skills/run-e2e/
- .buildkite/
- .github/
- docker/
- docs/design/module/e2e_testing.md
- docs/npu/TESTING.md
- .pre-commit-config.yaml
- .markdownlint.yaml
- owner: docs-recipes
path: repos/afd-plugin/rules.md
signals:
- docs
- readme
- recipe
- design doc
- AGENTS.md
- support matrix
- known gaps
- deployment
- guide
scope_prefixes:
- README.md
- recipe/
- docs/
- AGENTS.md
- CLAUDE.md
- .claude/
- .agents/
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
title: "AFD plugin 评审规则:上游漂移与跨文档隐含不变量"
created: 2026-09-30
updated: 2026-09-30
type: rule
tags: [afd-plugin]
sources: []
---

# AFD plugin 评审规则:上游漂移与跨文档隐含不变量

## AFD-I15 — 保持 CPU-safe 导入边界,CUDA/Ascend 类互不继承

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Move seeded conclusions to their nearest owner rules

Do not keep this repository-root seed page as a catch-all: its rules span plugin-boundary/CPU imports (AFD-I15), connectors (I16–I17), execution platforms (I18/I23), compatibility (I20/I22), and CI (I24), despite those owners already having dedicated directories, and several conclusions duplicate the new root rules (for example I15 versus I10/I11 and I20 versus I7). This both leaves the rules outside the exact component routes and creates competing copies that can drift; merge each conclusion union-first into the nearest owner's rules.md and remove the heterogeneous seed page.

AGENTS.md reference: AGENTS.md:L11-L17

Useful? React with 👍 / 👎.


- `vllm` 只是 optional extra,默认的 `uv run pytest` 要能在没有 CUDA wheel 的 CPU/macOS 环境运行。以下模块在导入时不能 import torch/vLLM 的 CUDA 运行时、`torch_npu` 或 `vllm_ascend`:
- 顶层 `afd_plugin`;
- 图策略 helper(`validate_cuda_graph_mode()`);
- `afd_plugin/connectors/factory.py`。
- factory 使用 lazy loader。注册新 connector 时要保持惰性加载,不能在 factory 模块顶层 import `connectors/gpu` 或 `connectors/npu` 的实现。
- Ascend 原生算子通过 `ensure_cam_p2p_ops_available()` 在 connector 初始化时才加载。算子缺失应该在 connector 初始化时报错,不能在包导入时报错。
- NPU 类不能继承 CUDA AFD 类,反过来也一样。例如 `AFDNPUFFNModelRunner` 直接继承 vLLM-Ascend 的 `NPUModelRunner`,不继承 `GPUFFNModelRunner`。共享逻辑放在 config、connector payload、metadata、validation 或小 helper 里。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I16 — 新增 connector 或 connector 配置字段时要多处同步

- 只在 `AFDConnectorFactory` 注册是不够的。配置层有一份独立的硬编码 allow-list(即 README 中 `connector` 允许的三个名字),它不从 factory 派生。不同步的话,新 connector 会在配置校验阶段被拒绝。
- 实现要放在 `afd_plugin.connectors.gpu` 或 `afd_plugin.connectors.npu` 下,继承 `AFDConnectorBase`,并实现闭合 schema 的 `parse_extra_config()`,未知字段必须报错。`P2pNcclAFDConnector` 的 `connector_extra_config` 必须是空映射。
- `compat/npu/feature_validation.py` 通过 factory 解析同一份 schema。新增字段时要在这里拒绝不支持的组合。
- 要明确是否安装 `control_plane`。`GPUFFNModelRunner` 构造时断言 `connector.control_plane is not None`,所以 CUDA connector 必须提供 control plane。运行时只能按 `connector.control_plane is None` 分支,不能按具体类名判断。
- 不要假设所有 connector 的 world 排序相同:
- `P2pNcclAFDConnector` 和 `CAMP2pAFDConnector` 是 FFN-first,要求 `num_attention_ranks >= num_ffn_ranks`,但不要求整除;
- `CAMAsyncAFDConnector` 是 Attention-first。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I17 — connector 构造必须轻量,集体 rendezvous 延迟到权重加载之后

- 构造函数和 `parse_extra_config()` 不能创建 process group、communicator 或算子注册。这些都只能在 `init_afd_connector()` 里完成。
- Attention 在 `load_model()` 末尾初始化,时间点在 AFD/Ascend ubatch wrapper 安装之后;
- FFN 在 `initialize_from_config()` 中初始化,时间点在空 KV-cache surface 之后、daemon 线程启动之前。
- 如果把初始化提前到权重加载之前,两个角色就不能再重叠加载权重。rendezvous 必须在 Attention 做显存 profiling 或首次 forward 之前完成。
- `close()` 必须满足:
- 清理该 connector 自己创建的 registry、pending queue、communicator 和 process group。
- connector 变更要测试 cleanup,以及重试或重新初始化。
- 模型代码可以通过 forward metadata 调用 connector 的 data-path 方法,但不拥有这些资源。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I18 — 特性组合矩阵分散在多份文档,放宽或收紧时要整体一致

- `compute_gate_on_attention`:
- CUDA V1 + P2P 两个值都可以,取决于模型是否支持;
- Qwen3 MoE 和 Qwen3.5/3.6 只允许 `false`;
- 任何 V2 部署只允许 `false`;
- CAMP2P 要求通用字段和 connector-local 的同名字段都为 `false`;
- CAM async 要求通用字段为 `true`,`async_moe_ubatching` 同样要求 `true`。
- 图模式:CUDA(V1 和 V2)只接受 `FULL_DECODE_ONLY`;Ascend V2 还接受 `FULL`;CAM async 只允许 eager。
- DBO 和 ubatching:
- V1 原生 ubatching 只接受恰好两个 ubatch;
- V2 在两个平台上都拒绝 DBO 和 ubatching;
- CAM async 拒绝原生 DBO,它只有 AFD 自己管理的两阶段 `async_moe_ubatching`,两者不能混为一谈。
- 不支持的组合必须在 config、worker 或 runner 初始化阶段失败。
- 改动矩阵中任意一项时,都要同步以下三处:README 的「Known gaps」、`execution_platforms.md` 的 tested runtime matrix、对应 validator 的测试。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I19 — README 和设计文档对 ModelRunnerV2 的支持说法互相矛盾

- 设计文档和 E2E 契约记录了 CUDA V2 的 DP2/TP2 eager/graph 证据,CI 在 `l4_4` 上按 node ID 运行 4 个 `afd-v2-*` 用例。
- 评审时不要根据 README 把 V2 代码当成死代码,因此删除代码、跳过测试或放松校验。
- 改动 `attention_model_runner_v2.py`、`npu/attention_model_runner_v2.py` 或 `AFDMetadataProviderMixin` 的 PR,必须保证 `afd-v2-{eager,graph}-{dp2,tp2}` 继续通过。
- Ascend V2 只有单元测试证据,没有硬件 E2E。文档或 PR 描述里不能写成已经过硬件验证。
- V2 的限制是两个角色共同遵守的契约。FFN 虽然不用原生 V2 runner,也必须运行同一个 topology/feature validator。只改 Attention 侧校验是不完整的。
- 改变 V2 支持说法的 PR,要同时让 README 的 Known gaps、「Using the Plugin」和设计文档保持一致。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I20 — 临时替换上游符号时,必须在 `finally` 中恢复,并纳入升级审计

- 以下作用域替换都必须在 `finally` 中恢复所有符号和 runner 状态,异常路径也一样:
- worker 在 `init_device()` 中替换 runner 符号;
- dummy run 和 V2 执行时包装 `create_forward_context`;
- V2 捕获时包装输入准备;
- full-graph replay 的实例级 hook;
- 构建多个 DBO ubatch 时临时禁用 Attention metadata cache。
- 新增这类接缝时,要补恢复路径和错误路径的单测,可参照 `tests/unit/v1/worker/test_attention_model_runner.py` 对 DBO workaround 的覆盖。
- 还要确保新接缝进入 `compatibility_and_patches.md` 里的作用域接缝清单。它们不是进程级 import-time patch,漏登记的话下次升级 vLLM 时容易被漏审。
- 优先用作用域级或实例级替换。不要把 AFD 自有行为藏进方便的进程级全局 hook。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I22 — vLLM-Ascend 基线只以源码 commit 记录

- 仓库不在 `pyproject.toml` 里声明 vLLM-Ascend 依赖,也没有 v0.26 的发布容器 tag。兼容证据就是 commit `80d8c194f` 加上已记录的 NPU 验证。
- 不要为了「补上依赖」去加包依赖,也不要把 v0.19.1rc1 镜像当作 v0.26 运行时。
- 刷新 Ascend patch 时,要引用确切的 vLLM-Ascend 源码 commit,并附上受影响路径的 NPU unit/E2E 证据。
- 如果前移基线,以下几处的 `80d8c194f` 要一起更新:README 的 Ascend 表格和 Environment 段、`compatibility_and_patches.md`、`execution_platforms.md`。
- v0.19.1rc1 基于 PCP 的部署在 v0.26 上不支持。legacy PCP8 recipe 只对应 `release/v0.19.1rc1`,不能当作 v0.26 支持的证据。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I23 — Ascend 原生算子的构建选择与打包

- `setup.py` 只在检测到 `torch_npu`、CANN 环境变量或默认 toolkit 路径时构建 Ascend 扩展,GPU 构建默认跳过。
- 环境变量的作用:`AFD_BUILD_ASCEND_OPS=1/0` 显式覆盖自动检测;`AFD_SKIP_ACLNN_BUILD=1` 只在产物已存在时跳过 ACLNN vendor build。改动不能让 CPU/GPU 环境默认触发 CANN 构建。
- 构建要在 `csrc/npu` 下完成 CANN vendor build,并打包 `_cann_ops_custom`(`setup.py` 和 `MANIFEST.in` 属于同一个 owner)。`csrc/gpu` 只是保留目录,目前没有插件自己的 CUDA 扩展。
- `CAMAsyncAFDConnector` 需要全部四个 `torch.ops.afd_ascend.afd_async_*` 算子。910C 包注册了它们,950 包没有注册,不要在 950 目标上假设这些算子存在。
- routed-only 算子的 host tiling 以 MiB 为单位读取 `HCCL_BUFFSIZE`。host helper 不查询实际窗口大小,所以引入或修改 `hccl_buffer_size` 覆盖时,要保证两者取值一致。
- 构建或原生算子的变更,要跑对应单测(如 `tests/unit/package/test_ascend_build_files.py`、`tests/unit/compat/test_ascend_ops.py`),并提供硬件 E2E 证据。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->

## AFD-I24 — E2E 的 CI 用例选择:PR 门禁和 2A1F 用例的边界(文档内部有冲突)

- PR 门禁只能按 pytest node ID 选以下用例:
- 使用不超过 4 个设备、2 Attention + 2 FFN 的 legacy 用例;
- 4 个 CUDA V2 DP2/TP2 用例。
- README 推荐的本地冒烟用例 `afd-eager-2a1f` 不能进 PR 门禁。
- `e2e_testing.md` 内部有冲突:一处说 2A1F 是「local-only」「run outside CI」;accuracy gate 表却把 DeepSeek `afd-graph-dbo-2a1f` 和 Qwen3 MoE/Qwen3.6 MoE 用例(Qwen3.6 套件是 2A1F)列进 weekly。
- 修改 `.buildkite/` 或 `.github/` 的调度时,2A1F 用例只能出现在 scheduled/weekly job 里,并应顺手让文档说法一致。
- CI 不能设置 `AFD_GSM8K_LIMIT`,也不能降低 `AFD_GSM8K_THRESHOLD`、样本数或必选用例集。DBO 用例要保留 24 个样本的下限和 12 个并发请求。
- CUDA 的 legacy 矩阵和 V2 矩阵各是一个独立的 40 分钟 job。更慢的覆盖放到 scheduled job。

<!-- kb:rule status=active since=init-9cae2d2ddaae -->
Loading
Loading