vLLM-Ascend 全模块源码架构分析
一份覆盖 442 文件 / 127k 行 的全模块深度分析。围绕 5 个核心问题:为什么要 vllm_ascend、设计要解决什么问题、工程关键挑战、软件架构设计、与 upstream vLLM 的关系。由 6 个 agent 并行切片深读后综合。
0. Executive Summary — 5 条 Headline Facts
Headline 1 — vllm_ascend 不是"后端适配",而是 6 层 overlay:Platform 子类 → Config injection → Monkey-patch → Worker 子类 → Device Op Adaptor → Custom Ops/Compile Backend。核心哲学:extension not fork。
Headline 2 — NPU 与 GPU 在 6 个维度不可调和:全局 init-once 约束、无 device capability 概念、4 种芯片变体(A2/A3/310P/A5)算子语义不同、ACL Graph vs CUDA Graph、HCCL vs NCCL、Sleep 模式 + CPU 绑定。
Headline 3 — EPLB 是 Ascend 对 vLLM 唯一净新增子系统:五层流水线(updator → worker 子进程 → policy → D2D loader → adaptor),FlashLB 用 μ+z·σ 风险调整 + depth=4 树搜索 + LPT + Hungarian 最小化迁移。零 upstream 修改。
Headline 4 — KV 传输已从 cache 进化为 memory tier:L1 HBM P2P(Mooncake RDMA)→ L2 跨节点 Pool(Ascend Store, 三后端)→ L3 NVMe SSD offload。对应 OS cache→DRAM→swapfile 同构。
Headline 5 — 5 种 Attention 变体 = 模型结构 × NPU 硬件特性 的笛卡尔积:FIA(标准 paged)、MLA(latent absorption)、DSA(indexer+compressor+SWA 三级缓存)、SFA(block-sparse + 独立 indexer cache)、FA3(第三方旁路)。update_graph_params() 是 NPU full-graph replay 的硬需求。
0.2 分析覆盖范围
| Agent | 模块切片 | 文件数 | 行数 | 核心发现 |
|---|---|---|---|---|
| A1 | Platform + Device + 310P | ~45 | ~12000 | 6 层 overlay、310P 6659 行不可参数化、patch 三层体系 |
| A2 | Attention 全栈 | ~18 | ~13000 | 5 变体、DSA index→paged 链路、update_graph_params 架构税 |
| A3 | Scheduler + Core | ~6 | ~4500 | Roofline 决定 recompute、PP 气泡消除、mixin 注入 |
| A4 | 分布式 + KV + EPLB | ~35 | ~20000 | EPLB 原创、KV memory tier 三级、HCCL shim |
| A5 | 编译 + ACL Graph | ~12 | ~2500 | Full replay ≠ CUDA Graph、70+ pass 双后端 |
| A6 | 模型 + Quant + Ops + Patch | ~120 | ~37000 | 三目录量化、33 patch、Xlite 图运行时、MoE 动态路由 |
1. 为什么要 vllm_ascend — NPU 与 GPU 的 6 维不可调和差异
1.1 全局 init-once 约束 vs 可重入初始化
GPU 的 cudaMemGetInfo 是可重入的;NPU 的 torch_npu 全局状态机只允许一次初始化。platform.py:275 的 get_device_total_memory 被迫 raise NotImplementedError——不是"值不同",而是"调用时机有有毒副作用"。
1.2 Device capability 模型不存在
GPU 用 (major, minor) 标识计算能力(sm80 vs sm90),vLLM 据此分派 kernel。NPU 没有这层概念——platform.py:244 返回 None。芯片变体通过 AscendDeviceType 枚举区分(A2/A3/_310P/A5),capability 对上层透明。
1.3 四种芯片变体 = 四种算子语义空间
| 芯片 | MoE Routing | Attention | 内存模型 | 权重布局 |
|---|---|---|---|---|
| A2 (910B) | npu_moe_init_routing | FIA kernel | 标准 HBM | ND |
| A3 (910C) | npu_moe_init_routing | FIA (不同 CANN) | 标准 HBM | ND |
| 310P (300I DUO) | AllGather-based | KV-quantized sparse | RC 共享内存 | NZ (fractal_z) |
| A5 (950, 2026) | routing_v2 (dtype 透传) | A5 FIA variant | 标准 HBM | ND |
1.4 图执行:ACL Graph vs CUDA Graph
核心差异:CUDA Graph 是"录制-回放"模型(replay 零 host 介入);ACL Graph 是"录制-参数更新-回放"模型。NPU attention 的 block_table/seq_len 无法 capture 时固化,必须通过 update_graph_params() 在 replay 前逐 layer 显式更新。
1.5 通信:HCCL vs NCCL
三个本质差异:进程组绑定(HCCL 需显式 torch.npu.device 上下文)、AllReduce stream 转换(pyhccl.py:186 封装)、UniqueId 分发(HCCL 需显式 broadcast)。
1.6 NPU 独有特性:Sleep 模式 + CPU 绑定
GPU 显存独占不需要腾挪。NPU 在多租户/RL 场景需要 sleep/wakeup 让出显存(sleep_mem_optimized.py:ACL graph + HCCL 双层释放/恢复)。HCCL 依赖 host-side PCIe 拓扑亲和,CPU 绑定对性能敏感(cpu_binding.py:3 种模式 + A5 UVB poll window)。
2. vllm_ascend 要解决的 5 个核心设计问题
2.1 设计问题 1:Platform 接口的"承诺 vs 能力" mismatch
vLLM 的 VllmConfig 是 GPU 中心的配置空间。NPU 必须在 init 早期做一次配置翻译——_fix_incompatible_config(platform.py:1025-1243)系统性清除 10 个配置域、30+ GPU 专用参数(cascade_attn / cpu_kvcache / nvtx_tracing / nsight / partial_prefills / flash_attn_version 等)。check_and_update_config(360 行 14 步)是枢纽。
2.2 设计问题 2:为什么需要 5 种 Attention 变体
"模型结构 × NPU 硬件特性"的笛卡尔积。MLA 的 KV cache 存 latent [num_blocks, block_size, kv_lora_rank];DSA 叠加 compressor + indexer + SWA 三级缓存;SFA 的 indexer 是独立虚拟 AttentionLayer。每种变体的 get_kv_cache_shape() 返回不同 shape,物理分配无法统一。
2.3 设计问题 3:NPU Roofline 决定 Scheduler 策略
NPU 算力/带宽比(~200-267 FLOPS/byte)显著高于 GPU(~156-295),使得 cost(recompute) < cost(swap)。RecomputeScheduler 把 preemption 从"swap to CPU"改为"drop-and-recompute"。ProfilingChunkScheduler 用二次公式 a·x²+(2aL+b)·x=T 解出等时 chunk 大小,消除 PP 气泡。
2.4 设计问题 4:KV Cache 从 cache 进化为 Memory Tier
PD 分离场景下多对多 KV 共享需求迫使引入 Pool 路径(Ascend Store)。三级 tier:L1 HBM P2P → L2 跨节点 Pool(Mooncake/Memcache/Yuanrong 三后端)→ L3 NVMe SSD offload。与 OS cache→DRAM→swapfile 同构。
2.5 设计问题 5:MoE Expert 负载不均衡
DeepSeek-V3/R1 的 routed expert 引入负载不均衡——hot expert 所在 NPU 成为瓶颈。EPLB 在推理阶段动态调整 expert 到 NPU 的物理映射:把 hot expert 复制到多个 NPU,让 gate 路由到空闲副本。这是 Ascend 对 vLLM 生态的唯一净新增子系统。
3. 工程实现的关键挑战
3.1 310P 变体的 6659 行独立代码
5 个不可参数化的差异迫使独立子类:
- 无 Triton(Atlas 300I DUO 不支持)→ CPU numpy slot_mapping + copy_to_gpu
- RC 共享内存(host/device 共享物理内存)→
get_device_total_memory语义不存在 - 5D KV cache(head_dim 按 16 对齐切分)→ 独立 attention 实现
- NZ 权重布局(fractal_z 格式 + transpose)→ 独立 fused_moe
- CPU RNG sampler(无 Triton)→ 独立 sample 路径
is_310p() 在全库被调用 30+ 次,形成隐式分派网——可维护性瓶颈。增加第 5 种芯片变体必须在所有分派点添加新分支。
3.2 Patch 系统的工程约束
vLLM 在 engine-core 子进程加载 plugin,E2E test conftest hook 不运行。全局 patch 必须在 plugin 入口点内部自举——_GLOBAL_PATCH_APPLIED 一次性语义 + _ensure_global_patch() 在 4 个入口调用。28 + 25+ 子模块覆盖 vLLM 内部 GPU 硬编码路径。
33 个 patch 文件遵循"Less is more / 写移除计划 / 随时清理"三原则,通过 vllm_version_is() / is_310p() 条件导入实现版本隔离。
3.3 量化方案选择的工程逻辑
| 场景 | 方案 | 原因 |
|---|---|---|
| MoE 模型 | W4A8_DYNAMIC | INT4 pack + EPLB 兼容 |
| Dense 模型 | W8A8_DYNAMIC | INT8 精度/性能平衡 |
| 极端压缩 (EP off) | W4A4_FLATQUANT / LAOS | NZ 格式约束排除 |
| PD 分离 | W8A8_MIX (PDMix) | Prefill dynamic + Decode static |
| OCP 标准 | MXFP4 / MXFP8 | E8M0 scale dtype |
W4A4∧EPLB 不兼容:W4A4 权重被 pack 成 int4pack 格式,无法运行时按 expert 粒度拆分(w4a4_flatquant.py:161)。
3.4 EPLB 的跨进程设计
FlashLB 的 numba JIT 编译 + 树搜索耗时可达数十 ms,不能阻塞 forward pipeline。EplbProcess 跑在独立子进程中,通过 Manager().dict() 做跨进程数据交换。三段式状态机:Heat Collection (600 步) → Algorithm Execution (50 步) → Weight Update (逐层 D2D)。
3.5 ACL Graph 的精细工程
- GC 禁用:piecewise 模式下每层 capture 一个 graph,反复 gc 极慢
- ExternalEvent 排序:graph stream 等待 host update_stream 上的 metadata 写入完成
- weak_ref 内存优化:capture 后立即释放 output 和 workspaces 强引用
- 双后端编译:npugraph_ex(首选)vs torch._inductor + fusion_pass_compile(fallback)
4. 软件架构设计 — 6 层 Overlay 模型
4.1 六层 Overlay 架构
| 层 | 机制 | 关键文件 | 哲学 |
|---|---|---|---|
| 1. Platform 子类 | NPUPlatform(Platform) override | platform.py | 接口承诺 → 设备能力 translators |
| 2. Config injection | AscendConfig 单例 + additional_config | ascend_config.py | 运行时翻译,不修改 VllmConfig 类 |
| 3. Monkey-patch | import 时替换 vLLM 内部函数/类 | patch/platform/ patch/worker/ | 覆盖 GPU 硬编码路径 |
| 4. Worker 子类 | worker_cls 字符串注入 | worker/ _310p/ xlite/ | vLLM 原生扩展点 |
| 5. Device Op Adaptor | 运行时多态分派 | device_op.py | 策略模式:Base/A5/310P |
| 6. Custom Ops + Compile | oot_compiler + ACL Graph | compilation/ ops/ | AscendCompiler + 70+ pass |
4.2 为什么是"extension not fork"
NPUPlatform继承Platform(不复制修改)_fix_incompatible_config只重置不存在的参数,不添加新字段到 VllmConfigregister()返回字符串路径——vLLM 主仓完全不知道 NPU 存在AscendConfig挂在additional_config上worker_cls是 vLLM 原生扩展点- EPLB 全部通过
if self.dynamic_eplb:条件分支注入
4.3 五种适配机制分类学
| 机制 | 示例 | 使用场景 | overlay 侵入性 |
|---|---|---|---|
| Subclass | NPUPlatform, NPUWorker, AscendMLAImpl | 接口明确、差异面的关键路径 | 低 |
| Custom Op | ops/fused_moe/ 完全重写 | NPU 通信/计算路径完全不同 | 中 |
| Config Injection | AscendConfig → additional_config | 新增配置维度 | 最低 |
| Monkey-patch | patch/worker/patch_deepseek_mtp.py | 小幅修改现有类 | 中(技术债) |
| Full Rewrite | ops/fused_moe/moe_mlp.py | GMM+SwiGLU 融合路径 | 高(仅限独立模块) |
5. Platform + Device + 310P 变体
5.1 入口与注册体系
vllm_ascend/__init__.py 定义 5 个注册入口:register()(Platform)、register_connector()(KV + weight connector)、register_model_loader()(netloader/rforkloader)、register_service_profiling()、register_model()。除 register() 和 register_model() 外,其余都在调用前触发 _ensure_global_patch()。
5.2 worker_cls 三路分派
# platform.py:612-623
if is_310p():
worker_cls = "vllm_ascend._310p.worker_310p.NPUWorker310"
elif ascend_config.xlite_graph_config.enabled:
worker_cls = "vllm_ascend.xlite.xlite_worker.XliteWorker"
else:
worker_cls = "vllm_ascend.worker.worker.NPUWorker"
5.3 Device Op Adaptor 策略模式
device_op.py:1964 的 get_device_adaptor() 在运行时根据芯片类型返回 BaseDeviceAdaptor / A5DeviceAdaptor / Ascend310PDeviceAdaptor。三种 adaptor 覆盖 20+ 个算子接口(attention score、MoE routing、softmax 等)。
5.4 Sleep 内存优化三层管理
SleepWakeupManager(sleep_mem_optimized.py:34)组合:
AclGraphSleepWakeupManager:释放 attention workspace、重置 graph params、清空 graph poolHcclSleepWakeupManager:destroy HCCL process groups(释放通信显存)CaMemAllocator(camem.py):CANN-mem pluggable allocator,按 tag 选择性 offload
6. Attention 全栈 — 5 种变体 + Context Parallel
6.1 5 种变体的唯一职责
| 变体 | 唯一职责 | 对应模型 | 核心算法 | update_graph_params |
|---|---|---|---|---|
| FIA (attention_v1) | 标准 paged attention via NPU FIA kernel | Qwen/LLaMA/Mixtral | npu_fused_infer_attention_score + C8 INT8 KV | ✅ 完整实现 |
| MLA (mla_v1) | Latent absorption:存 latent,decode 时 up-project | DeepSeek-V2/V3/R1 | chunked prefill workspace + kv_b_proj | ✅ 完整实现 |
| DSA (dsa_v1) | Dynamic Sparse Attention:indexer+compressor+SWA 三级缓存 | DeepSeek-V4 | QLI topk → compressor → dsa_sparse_attn | ❌ 空 pass |
| SFA (sfa_v1) | Sparse Flash Attention:indexer 独立 cache + block-sparse | DeepSeek-V3.2 | npu_sparse_flash_attention | ❌ 空 pass |
| FA3 (fa3_v1) | 第三方 flash_attn_npu_v3 包装 | 实验性 | flash_attn_with_kvcache (纯 eager) | N/A |
6.2 DSA index → paged attention 数据流
hidden_states
├─ _mla_prolog_multistream() → q, qr (dual-stream overlap)
├─ _indexer_qkv_prepare() → indexer QKV
│ └─ npu_quant_matmul + inplace_partial_rotary_mul + hadamard rotate
├─ compressor() → compressed_kv + compress_slot_mapping
├─ _indexer_qli() → topk_indices
│ └─ npu_vllm_quant_lightning_indexer(layout_key="PA_BSND")
│ ← 直接在 paged block 上做 score 计算
└─ dsa_sparse_attn(q, ori_kv, sparse_count=index_topk)
IndexCache 优化:DSA 的 index_topk_pattern(如 "FSSF")控制哪些层运行 indexer,哪些层复用前层 topk。indexer 是计算密集型 kernel(全量 KV block 上算 score),跳过非必要层可降低 30-50% decode latency。算法-硬件协同设计范例。
6.3 Context Parallel:NPU ≠ GPU Ring-Attention
| 维度 | GPU Ring-Attention | NPU Ascend CP |
|---|---|---|
| KV 分布 | 环形轮转,每 rank 存 1/N | 每 rank 存 full KV(AllGather 获取) |
| 通信模式 | 环形 P2P send/recv | AllGather (PCP) + All-to-All (DCP) |
| 输出合并 | reduce-scatter | AllGather out+lse + online softmax merge |
6.4 Registry / Dispatch 机制
不是 subclass polymorphism,是 registry pattern:platform.py:791 的 backend_map 根据 (use_mla, use_sparse, use_compress) 三元组查表返回 backend 类路径。CP 是 backend 的透明扩展——get_impl_cls() 内部通过 enable_cp() 开关返回 CP 变体,上层无感。
7. Scheduler + Core — 三种调度创新
7.1 三种 Scheduler 对比
| 维度 | RecomputeScheduler | ProfilingChunkScheduler | SRF (mixin) |
|---|---|---|---|
| 解决的问题 | NPU 带宽紧时 preemption 代价过高 | PP 流水线气泡(attention O(n²)) | 长请求饿死短请求 |
| 核心算法 | drop-and-recompute(free blocks) | 二次公式 a·x²+(2aL+b)·x=T | 三路队列 + aging |
| roofline 依据 | NPU 算力强带宽紧 | attention FLOPS ∝ seq_len² | SLA 公平性 |
| 对 upstream 改动 | preempt 分支 + SchedulerOutput 加 2 字段 | time_budget 维度叠加 | 3 个 override 方法 |
| 关键文件:行 | recompute_scheduler.py:316-340 | scheduler_profiling_chunk.py:261-307 | short_request_first_scheduler.py:419-435 |
7.2 三种挂载点
| 挂载点 | 侵入性 | 适用场景 | 示例 |
|---|---|---|---|
| scheduler_cls 字符串替换 | 低 | 整个 scheduler 类替换 | ProfilingChunkScheduler |
| SchedulerConfig 整体替换 | 中 | 新 scheduler + 新 config 字段 | RecomputeSchedulerConfig |
| Mixin 注入 | 低 | 修改部分调度策略 | ShortRequestFirstSchedulerMixin |
关键约束:RecomputeScheduler 和 ProfilingChunkScheduler 互斥(都替换 scheduler_cls)。SRF 通过 mixin 注入 RecomputeScheduler。三套 scheduler 通过 platform.py:648-690 的枢纽逻辑选择。
8. 分布式通信 + KV 传输 + EPLB
8.1 通信层架构
PyHcclCommunicator(pyhccl.py:37)是轻量 shim:ctypes 加载 libhccl.so,构造时 rank 0 生成 UniqueId、broadcast 给所有 rank。NPUCommunicator(npu_communicator.py:23)暴露 vLLM 兼容接口。all2all_manager 是 no-op stub——NPU 用 MC2 + all_gather 走 MoE 通信。
8.2 KV 传输三级 Memory Tier
| Tier | 实现 | 后端 | 传输模型 |
|---|---|---|---|
| L1 HBM P2P | MooncakeConnector (3552L) | Mooncake TransferEngine | Decode 端 pull (RDMA read) |
| L2 Cross-node Pool | AscendStoreConnector (328L) | Mooncake / Memcache / Yuanrong | Put/Get 全局对象存储 |
| L3 NVMe SSD | enable_ssd_offload | Mooncake SSD spill | 冷 KV 自动 spill/load |
8.3 EPLB 五层流水线
EplbUpdator (主进程)
├─ forward_before(): 取 update_info → D2D 异步启动
├─ forward_end(): gather load → wakeup worker
│
├─ [shared_dict] → EplbProcess (子进程)
│ └─ EplbWorker.do_update()
│ ├─ fetch load_info
│ ├─ policy.rebalance_experts() → 新 placement
│ └─ compose_expert_update_info_greedy()
│
├─ [Queue] → D2DExpertWeightLoader
│ └─ generate_expert_d2d_transfer_task()
│ └─ asyn_expert_weight_transfer()
│
└─ VllmEplbAdaptor
└─ 注册 MoE layer + 管理 expert_param
8.4 FlashLB 算法(type=3,生产级)
- 统计建模:μ + z·√σ 风险调整负载(z=0.674 对应 75% 置信度)
- 树搜索:depth=4 层,neighbor_search width=8 局部搜索
- LPT 部署:greedy 放到 risk 最低 device
- Hungarian 最小化迁移:
scipy.optimize.linear_sum_assignment对齐新旧部署 - numba JIT:核心循环
@njit(fastmath=True, cache=True)
8.5 EPLB 四策略对比
| 策略 | Type | 算法 | 生产价值 |
|---|---|---|---|
| RandomLoadBalance | 0 | 随机交换 NPU 1/3 末尾 expert | 仅 baseline |
| DefaultEplb | 1 | 贪心 BFD 冗余分配 | 基础负载均衡 |
| SwiftBalanceEplb | 2 | 约束局部交换 + 阈值触发 | 中等规模 |
| FlashLB | 3 | 树搜索 + LPT + Hungarian + numba | 生产级 |
9. 编译 + ACL Graph + 70+ Fusion Pass
9.1 ACL Graph vs CUDA Graph
| 维度 | CUDA Graph | ACL Graph (NPU) |
|---|---|---|
| 回放模型 | 纯 replay(零 host 介入) | host 先 update_graph_params() → ExternalEvent wait → replay |
| 参数更新 | 不需要(或 input pointer) | GraphParams 四元组(events/workspaces/handles/attn_params) |
| 跨 stream 排序 | graph 内自动 | ExternalEvent.wait(stream) + current_stream().synchronize() |
| GC 影响 | 无 | capture 时 patch gc.collect + empty_cache 为空操作 |
9.2 GraphParams 四元组
@dataclass
class GraphParams:
events: dict[int, list[ExternalEvent]] # 每 size 每 layer
workspaces: dict[int, Tensor] # attention 间接参数
handles: dict[int, list[NPUTaskGroupHandle]] # task group handle
attn_params: dict[int, list[tuple]] # 已捕获 attn 元数据
9.3 70+ Fusion Pass 分类学
| 类别 | Pass | Pattern → Replacement | 开关 |
|---|---|---|---|
| 通算融合 | MatmulAllReduceAddRMSNorm | Matmul+AllReduce+RMSNorm → 融合 kernel | fuse_allreduce_rms |
| 通算融合 | SequenceParallelism | AllReduce → ReduceScatter+AllGather | enable_sp |
| 量化融合 | AddRMSNormQuant | AddRMSNorm+Quant → npu_add_rms_norm_quant (12 variant) | fuse_norm_quant |
| 算子融合 | QKNormRope | split+RMSNorm×2+RoPE → 单融合 kernel | fuse_qknorm_rope |
| 算子融合 | MulsAdd | x*scale+y → Triton muls_add | fuse_muls_add |
| 消除简化 | NoOpElimination | no-op view/reshape → 直通 | 默认 |
9.4 双后端编译
AscendCompiler 通过 enable_npugraph_ex 开关分派:
- npugraph_ex 路径(首选):自带 pattern matcher,不经过 GraphFusionPassManager
- fusion_pass_compile 路径(fallback):torch._inductor + GraphFusionPassManager
BasePattern.register() 同时向两者注册,保证 pass 在两个后端都能匹配。
10. 模型支持 + 量化 + 自定义算子 + Patch + Xlite
10.1 模型注册三目录枚举
| 目录 | 注册机制 | 注册模型 |
|---|---|---|
models/__init__.py | ModelRegistry.register_model() | DeepseekV4, DeepseekV4MTP, LlamaEagle3Vwn |
xlite/ | _architecture_strategy_map 自动注册 | Llama, Qwen2/3, Qwen3Moe, Glm4Moe, MiniMaxM2 |
patch/worker/ | monkey-patch 注入 | DeepSeek MTP, Qwen3.5, DFlash, DSpark, Step3.5, Kimi K25 |
10.2 Xlite — 图运行时而非 edge runtime
Xlite 是华为 openEuler GVirt 项目下的图编译运行时,作为 ACL Graph 的替代路径。三层结构:
XliteModel(抽象基类,子类按架构注册到_architecture_strategy_map)XliteWrapper(持有 C++ Runtime,dispatch 在 xlite graph 和原始 runnable 之间)XliteModelRunner/XliteWorker(替换 NPU 默认 runner)
10.3 量化方案选择逻辑
AscendModelSlimConfig.get_quant_method()(modelslim_config.py:637)是核心路由。NZ format 是硬约束(ACL_FORMAT_FRACTRAL_NZ),msModelSlim 生态兼容(三种布局),MXFP 系列是 OCP 标准落地。
10.4 MoE 通信四维度动态路由
select_moe_comm_method(num_tokens, vllm_config):
A2 + EP → MC2 (tokens ≤ capacity) / AllGather
A3 + EP → FUSED_MC2 (w8a8 + small EP) / MC2 / AlltoAll
A5 + EP → MC2 / AllGather / AlltoAll
310P → AllGather
no EP → AllGather
10.5 Patch 分类学
| 类别 | 文件数 | 触发条件 | 移除条件 |
|---|---|---|---|
| Platform/分布式 | 3 | always | upstream 支持 |
| Platform/调度 | 4 | always | upstream merge |
| Platform/KV Cache | 3 | always | 上游化 |
| Platform/版本兼容 | 4 | vllm_version_is("0.23/0.24") | 版本 EOL |
| Worker/模型结构 | 8 | not 310P / always | upstream merge |
| Worker/算子 | 4 | HAS_TRITON / always | 稳定 |
| Worker/权重 | 2 | always | upstream merge |
10.6 Spec Decode 在 NPU 上的复杂性
AscendSpecDecodeBaseProposer(2156 行)承载三大复杂性:
- TP-patch:draft/target 不同 TP size 时 patch TP group
- ACL Graph:GLM 系列不支持 draft graph mode,FULL mode 需
_pad_query_start_loc_for_fia - PCP/DP 集成:PCP 需独立 block table 拷贝,DP 需 allgather + reduce
11. 横向架构评估与洞察
11.1 "变化速率不同"原则在 vllm-ascend 的体现
| 变化速率 | 子系统 | 表现 |
|---|---|---|
| never | 推理数学 / EngineCore.step | 1 step = schedule → forward → sample |
| yearly | Platform / Worker / Scheduler | NPUPlatform 子类、三种 scheduler |
| monthly | Attention / Compilation / EPLB | 5 变体、70+ pass、FlashLB |
| weekly | Patch / 310P 变体 / 量化 | 33 patch、is_310p() 分派网、10+ 量化 |
11.2 最脆弱的架构决策
310P 分派网:is_310p() 在 30+ 处被调用形成隐式分派。增加第 5 种芯片变体时必须在所有分派点添加新分支。建议:把分派逻辑集中到一个 DeviceCapability 对象中,用策略模式替代 if/else 网。
Patch 技术债:33 个 patch 文件中至少 10 个标注了 upstream PR 作为移除条件。vLLM upstream 迭代快,patch 容易 stale。建议:定期审计 patch 的 upstream 状态。
11.3 最有价值的架构决策
"Extension not fork":6 层 overlay 在 vLLM 的 4 个扩展点(Platform 子类 / worker_cls / custom ops / additional_config)上做文章。EPLB 零 upstream 修改。这使得 vllm-ascend 能跟随 vLLM 主仓迭代而不产生合并冲突。
Scheduler 的 mixin 注入:SRF 只替换了 waiting queue 数据结构,schedule() 主循环零修改。这是"关注点分离"的最佳实践。
KV memory tier 三级架构:L1 P2P → L2 Pool → L3 SSD 的演化路径与 OS 内存层级同构,为未来 CXL/持久内存预留了扩展空间。
11.4 与 vLLM 统一报告的关联
本报告与 vllm_architecture_unified.html(vLLM upstream 12 章分析)互补:
- 统一报告回答"vLLM 为什么这样设计"(软件架构第一性原理)
- 本报告回答"vLLM-Ascend 为什么需要 overlay"(硬件差异 + 工程约束)
- 统一报告的 §7 (Ascend Overlay) 和 §9 (Playbook) 与本报告 §4 重叠,但本报告提供了更深的源码证据
12. References & File Index
12.1 关键文件全索引
| 文件 | 行数 | 职责 |
|---|---|---|
vllm_ascend/platform.py | 1255 | NPUPlatform + 配置翻译枢纽 |
vllm_ascend/ascend_config.py | 897 | AscendConfig 单例 + 8 子配置 |
vllm_ascend/worker/model_runner_v1.py | 5187 | NPU ModelRunner(最大文件) |
vllm_ascend/attention/dsa_v1.py | 2820 | DSA attention(最复杂变体) |
vllm_ascend/attention/sfa_v1.py | 1919 | SFA attention |
vllm_ascend/attention/mla_v1.py | 1767 | MLA attention |
vllm_ascend/attention/attention_v1.py | 1849 | FIA attention |
vllm_ascend/core/recompute_scheduler.py | 1173 | RecomputeScheduler |
vllm_ascend/core/scheduler_profiling_chunk.py | 756 | ProfilingChunkScheduler |
vllm_ascend/distributed/kv_transfer/kv_p2p/mooncake_connector.py | 3552 | P2P KV 传输 |
vllm_ascend/eplb/core/policy/policy_flashlb.py | 1026 | FlashLB 算法 |
vllm_ascend/compilation/acl_graph.py | 381 | ACL Graph Wrapper |
vllm_ascend/compilation/compiler_interface.py | 368 | AscendCompiler |
vllm_ascend/models/deepseek_v4.py | 1515 | DeepSeek V4 适配 |
vllm_ascend/spec_decode/llm_base_proposer.py | 2156 | Spec decode 核心 |
vllm_ascend/ops/fused_moe/fused_moe.py | 798 | MoE 核心 |
vllm_ascend/quantization/modelslim_config.py | 984 | 量化配置 + 路由 |
vllm_ascend/sample/rejection_sampler.py | 1566 | Rejection sampler |
vllm_ascend/patch/__init__.py | 1199 | Patch 管理 |
vllm_ascend/cpu_binding.py | 806 | CPU 绑定 |
vllm_ascend/device/device_op.py | 1971 | Device adaptor |
vllm_ascend/_310p/model_runner_310p.py | 1042 | 310P runner |
12.2 外部引用
- vllm-project/vllm-ascend — 代码仓库
- Ascend 官方文档
- Introducing vLLM Hardware Plugin (2025/05)
- RFC: Hardware Pluggable (#11162)
vllm_architecture_unified.html— vLLM upstream 12 章统一报告hbm_index_architecture.html— HBM 索引专题
12.3 Agent 报告原件
| 文件 | 内容 | 行数 |
|---|---|---|
_ascend_full_analysis/agent_reports/01_platform_device.md | Platform + Device + 310P | 540 |
_ascend_full_analysis/agent_reports/02_attention.md | Attention 全栈 | 450 |
_ascend_full_analysis/agent_reports/03_scheduler_core.md | Scheduler + Core | 469 |
_ascend_full_analysis/agent_reports/04_distributed_eplb.md | 分布式 + EPLB | 506 |
_ascend_full_analysis/agent_reports/05_compilation_graph.md | 编译 + ACL Graph | 356 |
_ascend_full_analysis/agent_reports/06_models_quant_ops.md | 模型 + 量化 + Ops | 459 |