[feat]Qwen4Exp PLE INT8 量化、CPU offload/UVA 零拷贝与 prefetch stream 合入 - #115
Open
guanyu1998 wants to merge 9 commits into
Open
guanyu1998 wants to merge 9 commits into
guanyu1998 wants to merge 9 commits into
Conversation
问题: - HCU 所用 vLLM 快照中 Qwen4Exp PLE 表仍构造为未量化的 PLEVocabParallelEmbedding - compressed-tensors INT8(per-channel)量化的 checkpoint 无法正确加载与推理 解决方案: - 新增 patch_qwen4_exp_ple_int8 补丁,worker 启动时替换模块内 PLE 存储类及 shard loader - INT8 权重 + 每 vocab 行一个 BF16 scale,embedding 查表后按 scale 反量化,TP 下 scale 走 all_reduce - 劫持 Qwen4ExpNGramEmbedding.load_weights,校验并加载 ngram_embedding.weight_scale 分片 修改文件: - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_int8.py: 新增 PLE INT8 量化方法、存储类与 loader 补丁 - vllm_hcu/patch/worker/core_fix/__init__.py: 注册 patch_qwen4_exp_ple_int8 模块 - vllm_hcu/patch/worker/__init__.py: 添加 patch_qwen4_exp_ple_int8 回调 Signed-off-by: guanyu1 <1065311602@qq.com>
问题: - 上一提交的 PLE INT8 存储类在基类 VocabParallelEmbedding.forward 之后才反量化 - TP>1 时基类先将 int8 查表结果送入 tensor_model_parallel_all_reduce - custom allreduce 仅支持 fp32/fp16/bf16,cudagraph capture 阶段抛出 RuntimeError: custom allreduce only supports float32, float16 and bfloat16 解决方案: - HcuQwen4ExpPLEInt8EmbeddingMethod.embedding() 查表后立即按 weight_scale 反量化,直接返回 params_dtype 浮点张量,再进入基类 all-reduce 路径 - input_ 已由基类 mask 到本 rank 局部索引,非 owner 行由基类 masked_fill_ 清零 - 删除外层 forward/dequantize 两段式处理,链路与 unquantized 路径一致 已知问题(HCU 暂无修改保护): - M-RoPE RopeState.prefill_positions 按 (max_num_reqs x num_dims, max_model_len) int32 申请 UVA/pinned 内存:128 x 3 x 262144 x 4B = 384 MiB/worker, TP4 合计约 1.5 GiB pinned,在 torch.zeros(..., pin_memory=True) 处 抛 hipErrorOutOfMemory(buffer_utils.py UvaBuffer.__init__) - 该 buffer 宽度绑定 max_model_len 准入上限,不受 --max-num-batched-tokens 影响;当前只能靠 --max-num-seqs / --max-model-len 缓解 - vllm_hcu 侧暂无对该问题的修改与保护,待跟进(候选方案:text-only arange 快路径、mm 专用小池) 修改文件: - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_int8.py: embedding() 内联反量化,移除外层 forward/dequantize Signed-off-by: guanyu1 <1065311602@qq.com>
问题: - Qwen4Exp PLE INT8 ngram embedding 表常驻 GPU,每 TP rank 占用约 12.36 GiB 显存 解决方案: - 新增 VLLM_HCU_PLE_CPU_OFFLOAD 开关,将 PLE INT8 表 offload 到 CPU pinned 内存 - UVA 优先:注册 get_cuda_view_from_cpu_tensor 算子,把 CPU pinned 表包成 cuda device view,embedding lookup 零拷贝直读 host 内存,无 D2H 同步, 兼容 CUDA graph capture - H2D 降级:UVA 算子不可用时自动降级到显式 host gather + H2D staging fallback - UVA view 惰性创建并缓存:因 process_weights_after_loading 阶段权重临时在 GPU, 改在首次 embedding() 调用时(weight 已还原 CPU pinned)创建 view 验证: - 真机 8×BW100 HCU、TP=4:eager 与 CUDA graph(FULL_AND_PIECEWISE)模式均端到端通过, capture 无报错,推理数值正常,每卡省约 12.36 GiB 环境变量: - VLLM_HCU_PLE_CPU_OFFLOAD=1 开启 offload(默认 False) 修改文件: - patch_qwen4_exp_ple_int8.py: 新增 UVA/Offload embedding 类、_is_uva_available、工厂 UVA 优先降级逻辑 - envs.py: 注册 VLLM_HCU_PLE_CPU_OFFLOAD 环境变量 - hcu.py: import vllm._C_stable_libtorch 注册 UVA 零拷贝算子 Signed-off-by: guanyu1 <1065311602@qq.com>
问题: - PLE INT8 UVA 零拷贝查表在当前 stream 内串行执行,查表延迟 无法被前序 decoder layer 计算掩盖 解决方案: - 新增 opt-in 的 PLE prefetch stream 机制,在 decoder layer 前向 之前提前在独立 stream 上发起 UVA 查表,与模型计算重叠 - 将统一 custom op schema 扩展为带 prefetch workspace buffer 的 固定签名,PREFETCH=0 时用零尺寸 tensor 保持原有路径 - 在 piecewise cudagraph capture 前同步 prefetch stream,保证 捕获正确性 - module_exchange 按 VLLM_HCU_PLE_PREFETCH_STREAM 条件注册 ple_layer 替换 环境变量: - VLLM_HCU_PLE_PREFETCH_STREAM=True 开启 prefetch(默认 False) 修改文件: - vllm_hcu/models/qwen4_exp/amd/ple_layer.py: 新增 HCU PLE layer 替换实现(含 prefetch workspace) - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_prefetch.py: 新增 prefetch stream 注册与 layer 前置查表逻辑 - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_cudagraph.py: 新增 capture 前 prefetch stream join - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_conv.py: custom op 扩展 prefetch workspace 参数并统一 schema - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_int8.py: 适配 prefetch workspace - vllm_hcu/patch/module_exchange.py: 条件注册 ple_layer 替换 - vllm_hcu/patch/worker/__init__.py、core_fix/__init__.py: 注册新 patch 回调 - vllm_hcu/platforms/envs.py: 新增 VLLM_HCU_PLE_PREFETCH_STREAM - tests/: 新增/更新 prefetch、int8 offload、conv、module_exchange 相关测试 Signed-off-by: guanyu1 <1065311602@qq.com>
Signed-off-by: guanyu1 <1065311602@qq.com>
Signed-off-by: guanyu1 <1065311602@qq.com>
问题: - 上游 Engram 校验仅接受 CUDA,导致 HCU 显式 cpu_offload 配置被拒绝 - PLE 跨 DP 分片缺少非均匀 token 聚合、ETP 归约和本地结果恢复 解决方案: - 增加 HCU CUDA-like Engram 兼容门禁并保留上游模型约束 - 为 PLE 接入 ETP group、跨 DP ID gather、padding 和本地结果切片 - 扩展 prefetch buffer,并适配 ETP all-reduce 与 CUDA Graph 路径 修改文件: - ple_layer.py: 接入跨 DP ETP 查表、非均匀 token padding 和 prefetch buffer - patch_engram_config.py: 增加 HCU Engram 配置兼容门禁 - core_fix/__init__.py: 注册 Engram 平台补丁 - patch_qwen4_exp_ple_int8.py: 使用 ETP group 完成 PLE all-reduce Signed-off-by: guanyu1 <1065311602@qq.com>
问题: - @support_torch_compile 会在运行时替换模型构造函数,替换后的 wrapper 签名为 (self, *args, vllm_config, prefix, **kwargs), 与 require_model_init 校验的原始签名不符,导致 patch 应用失败 - 原 hcu_init 闭包仅接受 keyword-only 参数,无法透传被包装 构造函数的额外位置参数 解决方案: - 新增 _is_torch_compile_init 结构化识别 vLLM 的编译支持包装器, 校验 wrapper 参数名与参数类型,不依赖共享校验契约 - 新增 _require_model_init_compatible:原始签名匹配直接通过, 否则若为 support_torch_compile 包装则放行 - hcu_init 改为 (self, *args, vllm_config=None, prefix="", **kwargs) 透传形式,兼容两种构造路径 修改文件: - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_prefetch.py: 新增包装器识别与兼容校验,调整 hcu_init 签名 Signed-off-by: guanyu1 <1065311602@qq.com>
AI Review本次变更中未发现有明确证据的正确性或安全性问题。 |
Contributor
|
Review findings
|
Author
|
问题: - PLE INT8 CPU-offload 权重已驻留 pinned CPU memory,但 post-load 默认仍将完整表执行 CPU→GPU→CPU 往返搬运 - UVA 不可用时自动选择的 H2D fallback 与 CUDA Graph 不兼容,可能延迟到 graph capture 阶段才失败 - Engram 配置 patch 缺少直接 contract test,导致 patch coverage 质量门失败 解决方案: - PLE UVA 权重在 post-load 阶段始终保留在 pinned CPU memory,不再经过 CPU→GPU→CPU 路径 - 删除 H2D fallback,CPU offload 开启但 UVA 不可用时在模型初始化阶段直接报错 - 补充 post-load、UVA fail-fast 和 Engram patch contract 回归测试 修改文件: - vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_int8.py: 跳过 post-load 设备搬运并移除 H2D fallback - vllm_hcu/platforms/envs.py: 更新 PLE CPU offload 的 UVA 依赖说明 - tests/runtime_patch/test_qwen4_exp_ple_int8_offload.py: 验证 CPU storage 不变和 UVA 缺失时立即报错 - tests/runtime_patch/test_platform_core.py: 增加 Engram 配置 patch contract 测试 - tests/runtime_patch/test_qwen4_exp_ple_prefetch.py: 删除已移除 H2D fallback 类的旧断言 Signed-off-by: guanyu1 <1065311602@qq.com>
Author
|
PLE CPU offload 权重不再进入默认的 post-load CPU→设备→CPU 往返搬运流程。权重会始终保留在 pinned CPU memory 中,并在首次使用时延迟创建 UVA view。
验证结果:
|
There was a problem hiding this comment.
AI Review
🟡 建议修改
发现有明确证据的问题,建议核对并处理。
已确认 1 个问题,其中 0 个已添加到对应代码行。
变更概览
本次变更主要包含:
- 新增 Qwen4Exp PLE 模块交换测试,验证注册仅在指定环境变量开启时生效且保持目标模块不被提前导入,规范模块已被导入时报错
- 新增 patch_engram_config 契约测试,覆盖 HCU 支持判定与包装合约、上游拒绝场景保留及签名/源码形状漂移检测;并更新 ngram 动态预处理 fake run 签名以校验新增的四个空 buffer 参数
- 新增针对 Qwen4Exp PLE INT8 CPU offload 路径的测试,覆盖 UVA/驻留方法选择、engram 配置与环境变量优先级、create_weights 的 CPU 分配以及加载后权重驻留 CPU 的行为验证。
- 新增 Qwen4Exp PLE INT8 offload 的测试,覆盖 UVA 方法与驻留方法的子类关系、UVA 零拷贝查表与 GPU 驻留反量化数值一致性,以及设备视图跨调用缓存复用。
文件审查摘要
| 文件 | 变更 | 审查结果 |
|---|---|---|
vllm_hcu/models/qwen4_exp/amd/ple_layer.py |
新增 · +1461/-0 | P2 × 1 |
tests/runtime_patch/test_qwen4_exp_ple_prefetch.py |
新增 · +592/-0 | — |
vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_int8.py |
新增 · +503/-0 | — |
vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_prefetch.py |
新增 · +373/-0 | — |
tests/runtime_patch/test_qwen4_exp_ple_int8_offload.py |
新增 · +329/-0 | — |
vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_cudagraph.py |
新增 · +131/-0 | — |
vllm_hcu/patch/platform/core_fix/patch_engram_config.py |
新增 · +128/-0 | — |
tests/runtime_patch/test_platform_core.py |
修改 · +121/-1 | — |
vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_conv.py |
修改 · +95/-8 | — |
vllm_hcu/patch/module_exchange.py |
修改 · +35/-3 | — |
tests/patch/test_module_exchange.py |
修改 · +31/-0 | — |
vllm_hcu/models/qwen4_exp/engram.py |
新增 · +25/-0 | — |
tests/runtime_patch/test_qwen4_exp_ple_conv.py |
修改 · +15/-1 | — |
vllm_hcu/platforms/envs.py |
修改 · +15/-0 | — |
vllm_hcu/patch/worker/core_fix/init.py |
修改 · +6/-0 | — |
vllm_hcu/models/qwen4_exp/init.py |
新增 · +3/-0 | — |
vllm_hcu/models/qwen4_exp/amd/init.py |
新增 · +3/-0 | — |
vllm_hcu/patch/worker/init.py |
修改 · +3/-0 | — |
vllm_hcu/patch/platform/core_fix/init.py |
修改 · +2/-0 | — |
vllm_hcu/platforms/hcu.py |
修改 · +1/-0 | — |
无法定位到 diff 行的问题(1)
P2 · 填充行映射到槽 0 后 index_copy_ 重复索引可能覆盖真实请求状态
- 文件:
vllm_hcu/models/qwen4_exp/amd/ple_layer.py(无法安全定位到当前 diff 行) - 触发条件:批次前 num_prefills 行中存在 NULL_BLOCK_ID 填充行(代码注释自述该路径会处理填充行),且同一批次有真实请求占用缓存槽 0。
- 证据与影响:state_indices 先用 torch.where 把无效索引替换为 0,随后用 conv_state.index_copy_(0, state_indices, existing_state) 回写。填充行的 update_mask 为 False,只会把槽 0 的旧值再写回槽 0,与真实请求写入的新状态形成同索引竞争。 index_copy_ 对重复索引的结果在加速卡上不确定:真实请求位于槽 0 的新 conv 状态可能被旧值覆盖,后续解码沿用过期卷积状态,产生难以复现的输出错误。
- 修改建议:回写前先按 valid_state 压缩索引与数据(如 state_indices[valid_state] 与对应 next_state 子集)再执行唯一索引的 index_copy_,避免重复索引写入。
审查信息
- 变更统计:20 个文件,+3872/-13。
- 覆盖情况:共 20 个文件,已完整审查 20 个。
- 候选问题:1 项;证据复核过滤:0 项;发布前敏感信息保护:0 项。
- 本服务只审查 GitHub 提供的 PR diff,未执行代码或重跑测试;结论仍需维护者核验。
Contributor
|
[P1] embedding_across_dp 仍然只有开启 PLE prefetch 时才真正生效
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更概要
将
guanyu-hcu-upstream-54371-56208-v0.28.1-dev的 8 个 commit 合入v0.28.1-dev:a9925a4feat(qwen4_exp): 新增 Qwen4Exp PLE embedding compressed-tensors INT8 支持987b7d1fix(qwen4_exp): PLE INT8 查表即反量化,修复 custom allreduce dtype 报错af8b8f1feat(qwen4_exp_ple): 新增 PLE INT8 CPU offload 与 UVA 零拷贝支持1e8c1bdfeat(qwen4_exp_ple): 新增 PLE INT8 UVA 查表与模型计算重叠的 prefetch streamffc81cafeat(qwen4_exp_ple): PLE INT8 UVA 查表与模型计算重叠的 prefetch stream 优化及测试60cbd30feat(qwen4_exp): engram 模块与 PLE INT8 offload 相关调整及测试8ec6851feat(qwen4_exp): 新增 PLE ETP 与 HCU Engram 配置支持604b381feat(qwen4_exp_ple): 兼容 support_torch_compile 包装的模型构造函数改动内容
PLE INT8 量化支持与修复(commit 1 & 2)
patch_qwen4_exp_ple_int8补丁,worker 启动时替换模块内 PLE 存储类与 shard loader,INT8 权重 + 每 vocab 行一个 BF16 scale,TP 下 scale 走 all_reducePLE INT8 CPU offload 与 UVA 零拷贝(commit 3 & 6)
VLLM_HCU_PLE_CPU_OFFLOAD=1将表 offload 到 CPU pinned 内存get_cuda_view_from_cpu_tensor算子,embedding lookup 零拷贝直读 host 内存,无 D2H 同步,兼容 CUDA graph capture;算子不可用时自动降级为显式 host gather + H2D stagingprefetch stream 计算重叠(commit 4 & 5 & 8)
VLLM_HCU_PLE_PREFETCH_STREAM=True开关,在 decoder layer 前向之前于独立 stream 提前发起 UVA 查表_is_torch_compile_init识别@support_torch_compile包装的模型构造函数,hcu_init改为(*args, vllm_config=None, prefix="", **kwargs)透传形式,避免 patch 应用失败ETP 与 HCU Engram 配置(commit 7 & 6)
影响的模块
vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_int8.py:新增(INT8 存储/loader/量化方法,UVA/offload 工厂与降级逻辑)vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_prefetch.py:新增(prefetch stream 注册、layer 前置查表、torch_compile 兼容)vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_cudagraph.py:新增(capture 前 prefetch stream join)vllm_hcu/patch/worker/core_fix/patch_qwen4_exp_ple_conv.py:修改(custom op 扩展 prefetch workspace 参数并统一 schema)vllm_hcu/models/qwen4_exp/amd/ple_layer.py:新增(HCU PLE layer 替换实现,含跨 DP ETP 查表与 prefetch workspace)vllm_hcu/models/qwen4_exp/engram.py:新增(engram 模块)vllm_hcu/patch/platform/core_fix/patch_engram_config.py:新增(HCU Engram 配置兼容门禁)vllm_hcu/patch/module_exchange.py:修改(按VLLM_HCU_PLE_PREFETCH_STREAM条件注册 ple_layer 替换)vllm_hcu/platforms/envs.py:新增环境变量VLLM_HCU_PLE_CPU_OFFLOAD、VLLM_HCU_PLE_PREFETCH_STREAMvllm_hcu/platforms/hcu.py:修改(注册 UVA 零拷贝算子)vllm_hcu/patch/worker/__init__.py、patch/worker/core_fix/__init__.py、patch/platform/core_fix/__init__.py:注册新 patch 回调tests/runtime_patch/test_qwen4_exp_ple_int8_offload.py、tests/runtime_patch/test_qwen4_exp_ple_prefetch.py;更新test_qwen4_exp_ple_conv.py、test_module_exchange.py验证方式
VLLM_HCU_PLE_PREFETCH_STREAM=True/False两种模式下的 cudagraph capture 与解码吞吐对比风险评估
RopeState.prefill_positions按(max_num_reqs × num_dims × max_model_len)申请 pinned 内存(TP4 约 1.5 GiB),可能触发hipErrorOutOfMemory,当前只能靠--max-num-seqs/--max-model-len缓解,待后续跟进