Files
project_6/COMP168_DIAGNOSIS.md
project6-dev 2893a8e132 diag: comp 168 完整分析 + verify_deployment.sh
关键发现:
- 07-23: base corex chain 完好(GDN+MoE+FA2全fused), 但OOM(max_model_len=100000)
- 08-07: 我们覆盖qwen3_5.py打断corex chain → GDN NaN + MoE Python fallback
- 修复: patch_ops.sh v2 不覆盖base, max_model_len=80000
- 新增: verify_deployment.sh 真机验证, COMP168_DIAGNOSIS.md
2026-08-12 03:08:35 +00:00

7.9 KiB
Raw Blame History

comp 168 Docker 诊断 → .so 开发清单

基于 2d5232c5d6bc (comp 168 docker log, 3786 行) 当前 HEAD: b25fc53e (414 commits)

一、comp 168 日志三大致命问题

# 错误 出现次数 根因 状态
1 GDN NaN frac=0.9998 16次(layer 0-4) 我们的 GDN prefill 实现产生 NaN → replace with zeros → 模型质量归零 P0 未修
2 vllm_moe_topk_softmax not found 39次 ixformer.functions 没有 Python binding → fallback to Python for 循环 P0 需 .so
3 CUDA OOM 32 MiB 17次 max_model_len=100000 超过 KV cache 容量 → engine 死亡 已修为 80000

二、真机探测确认的事实

从你贴的真机 probe 输出:

ixformer.functions 有:
  ✓ silu_and_mul, rms_norm, fused_add_rms_norm, rotary_embedding
  ✓ flash_attn_*, vllm_single_query_cached_kv_attention_v2
  ✓ vllm_cache_ops_reshape_and_cache, vllm_swap_blocks, vllm_copy_cache
  ✗ vllm_moe_topk_softmax (不存在!)
  ✗ moe_compute_token_index_api (不存在!)
  ✗ moe_w16a16_group_gemm (不存在!)

libixformer.so 中:
  ✓ 上述函数全部存在 (C++ 符号, xllm 的 ixformer.h 声明了它们)
  但 Python binding (_C.so) 没有暴露

结论: MoE 7 步 pipeline 中的 topk_softmax / gen_idx / expand / group_gemm / combine 全部需要通过 ix_moe_bridge.so 桥接。

三、需要开发/修复的 .so 清单

SO-1: ix_moe_bridge.so (MoE 7步 pipeline) — 代码已有,需真机编译验证

源码: ex_engine/csrc/ix_moe_bridge.cpp (258行) 编译: ex_engine/precompile_ix_bridge.pytorch.utils.cpp_extension.load(-lixformer) 状态: 代码写好了Dockerfile 有 build step但从未在真机验证过编译成功

真机验证命令:

cd /workspace/ex_engine
python3 precompile_ix_bridge.py
ls -la build/ix_moe_bridge*.so
python3 -c "import torch; from torch.utils.cpp_extension import load; m=load('test', sources=['csrc/ix_moe_bridge.cpp'], extra_ldflags=['-L/usr/local/corex/lib64/python3/dist-packages/ixformer', '-lixformer']); print(dir(m))"

SO-2: GDN prefill 修复 — P0 最高优先级

现状: 我们的 _torch_chunk_gated_delta_rule 在 fp16 下产生 99.98% NaN 参考: upstream_ref/xllm/core/layers/npu_torch/qwen3_gated_delta_net_base.cpp (576行)

关键差异:

  • xllm 用 fp32 accumulation: decay_mask = ... .exp().float()
  • xllm 用 torch::matmul 而不是自定义 chunk kernel
  • xllm 的 recurrent state 管理有精确的 clamp(-20, 20) 限制

解决方案: 不写新 .so而是从 xllm 搬运 GDN 的 PyTorch 实现C++ torch ops, 全 fp32 accumulation替换我们的 chunk kernel。

SO-3: _custom_ops.py patch — 已有 fallback 逻辑

base image 的 _custom_ops.py 调用 ixf_F.vllm_moe_topk_softmax 时会报错。 但 comp 168 的 base 镜像绕过了 _custom_ops,直接走 corex_moe.py 的 7 步 pipeline。

如果 base 有 corex_moe.py: 不需要 patch 如果 base 没有 corex_moe.py: 我们的版本 + ix_moe_bridge.so 补位

四、upstream 已有、不需要重写的代码

upstream 文件 行数 我们的对应文件 搬运状态
xllm/core/kernels/ilu/ixformer.h 147 ex_engine/csrc/ilu/ixformer.h 已搬
xllm/core/kernels/ilu/fused_moe.cpp 99 ex_engine/csrc/ilu_kernel_fused_moe.cpp 已搬
xllm/core/layers/ilu/fused_moe.cpp 797 ex_engine/csrc/ilu_layer_fused_moe.cpp 已搬
xllm/core/kernels/ilu/attention.cpp 162 ex_engine/csrc/ilu_kernel_attention.cpp 已搬
xllm/core/layers/ilu/attention.cpp 189 ex_engine/csrc/ilu_layer_attention.cpp 已搬
xllm/core/kernels/ilu/norm.cpp 50 ex_engine/csrc/ilu_kernel_norm.cpp 已搬
xllm/core/kernels/ilu/activation.cpp 32 ex_engine/csrc/ilu_kernel_activation.cpp 已搬
xllm/core/kernels/ilu/rope.cpp 31 ex_engine/csrc/ilu_kernel_rope.cpp 已搬
xllm/core/kernels/ilu/group_gemm.cpp 39 ex_engine/csrc/ilu_kernel_group_gemm.cpp 已搬
xllm/core/kernels/ilu/matmul.cpp 73 ex_engine/csrc/ilu_kernel_matmul.cpp 已搬
xllm/core/layers/npu_torch/qwen3_gated_delta_net_base.cpp 576 ex_engine/csrc/qwen3_gated_delta_net_base.cpp 已搬
ds_vllm/csrc/moe/topk_softmax_kernels.cu 874 ex_engine/csrc/moe_v055/topk_softmax_kernels.cu 已搬
xllm/core/kernels/cuda/moe/moe_topk_softmax_kernels.cuh ~400 ex_engine/csrc/moe/moe_topk_softmax_kernels.cuh 已搬

五、真机验证 checklist

在真机上按顺序执行:

# 1. 验证 ix_moe_bridge.so 编译
cd /workspace/ex_engine && python3 precompile_ix_bridge.py
ls build/ix_moe_bridge*.so   # 必须存在

# 2. 验证符号解析
python3 -c "
import torch
import importlib.util
spec = importlib.util.spec_from_file_location('ix', 'build/ix_moe_bridge.cpython-310-x86_64-linux-gnu.so')
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
print([x for x in dir(m) if not x.startswith('_')])
# 应输出: ['topk_softmax', 'moe_gen_idx', 'moe_expand_input', 'moe_group_gemm', 
#          'silu_and_mul', 'moe_combine_result', 'paged_attention', 'rms_norm',
#          'fused_add_rms_norm', 'linear', 'reshape_and_cache', 'rotary_embedding']
"

# 3. 验证 topk_softmax 功能
python3 -c "
import torch
# ... load ix_moe_bridge ...
gating = torch.randn(4, 64, device='cuda', dtype=torch.float32)
tw = torch.empty(4, 8, device='cuda', dtype=torch.float32)
ti = torch.empty(4, 8, device='cuda', dtype=torch.int32)
tei = torch.empty(4, 8, device='cuda', dtype=torch.int32)
m.topk_softmax(tw, ti, tei, gating)
print('topk_weights:', tw)
print('topk_ids:', ti)
"

# 4. 验证 GDN 不再 NaN
# (需要先修复 GDN prefill 代码)

# 5. 启动服务验证
python3 -m vllm.entrypoints.openai.api_server --model /model ...

六、最关键发现07-23 的 base image 自带完整 corex_* chain

07-23 日志证据 (dockerrizhi.txt):

corex_gdn.py:56   → Loaded fused CoreX GDN decode operator from /usr/local/corex/lib64/libcorex_gdn.so ✅
corex_gdn.py:228  → Using fused CoreX GDN prefill operator ✅
corex_moe.py:339  → Using CoreX fused MoE prefill operator: tokens=4096, kernel=expert-grouped-wmma ✅
corex_fa2.py:333  → Using CoreX FA2 packed prefill: B=2 Hq=4 Hkv=1 D=256 ✅
corex_fa2.py:507  → Using CoreX paged FA2 chunked prefill ✅

08-07 日志: 零条 corex_* 加载记录。取而代之的是 qwen3_5.py:445 NaN in prefill + _custom_ops.py:58 topk_softmax not found

根因: 08-07 提交部署了我们自己的 qwen3_5.py,覆盖了 base image 自带的版本,打断了 corex_gdn.py / corex_moe.py / corex_fa2.py 的调用链。

当前状态: patch_ops.sh v2 已经有条件跳过逻辑(_QW_SIZE > 1000 → KEEPING IT),但需要确保下次提交时不再触发 qwen3_5.py 覆盖。

结论: 如果 base image 有工作的 corex_* chain我们只需要:

  1. 不覆盖 qwen3_5.py
  2. 只部署 serving 层protocol/serving_chat/api_server/tool_parser
  3. max_model_len=80000(已修)
  4. ix_moe_bridge.so 作为备用(如果 base 的 _custom_ops 有路径碰到 topk_softmax

七、代码量评估

组件 文件数 总行数 状态
ex_engine/csrc (C++) 39 ~8000 全部已有,需真机编译
ex_engine/python (Python) 7 ~1200 全部已有dispatch chain 完整
qwen3_6_scripts (serving) 20+ ~6000 全部已有patch_ops.sh 管部署
upstream_ref (xllm reference) 500+ ~100K 参考用,关键文件已搬到 ex_engine

结论: 代码量是够的。问题不是代码不够,而是:

  1. GDN NaN 没修(需要用 xllm 的 fp32 accumulation 逻辑替换)
  2. ix_moe_bridge.so 从未在真机编译成功
  3. 没有 "不允许 fallback" 的硬要求落实到代码里