/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
DeepSeek-V4-Flash 昇腾 910B PD 分离部署(11 月 6 日中午调试篇):14.4% 请求失败率是怎么定位出来的
环境:Atlas 800I A2(910B-64GB × 8)× 2 节点,1P1D
P 节点 10.10.10.1(业务网)/ 192.168.100.10 ~ 192.168.100.17(RoCE 网)
D 节点 10.10.10.2(业务网)/ 192.168.100.2 ~ 192.168.100.9 (RoCE 网)
镜像 quay.io/ascend/vllm-ascend:v0.23.0,模型 DeepSeek-V4-Flash-0731-w8a8
部署形态:DP4 × TP2 + EP,每节点 4 个 vLLM 实例(HTTP 7000–7003),代理监听 10.10.10.1:1999
注:文中所有 IP 均已脱敏。
这篇只讲中午那一轮做的事:把一个从 0.1% 一路恶化到 14.4% 的请求失败率,从"怀疑光模块"一路收窄到"软件层通信域问题"。
一、先修表:时间基准差了 8 小时,之前两天的结论全要重算
1.1 现象
容器内 date 显示 UTC,宿主机是 CST(+8)。拿容器日志的时间去和宿主机 dmesg、hccn_tool 的输出对齐,每一条都差 8 小时。
1.2 后果(这条最要命)
在此之前,我们认定"服务运行期发生过两次全 8 卡同步链路掉线",并把它当成主要嫌疑。
对齐时间后真相是:
| 8 卡同步 down/up | 13:42 → 13:47 | 21:42 → 21:47 | ❌ 服务启动前 3 小时 |
| 8 卡同步 down/up | 08:15 → 08:19 | 16:15 → 16:19 | ❌ 服务启动前 3 小时 |
两次掉线都发生在服务启动之前,跟本轮故障没有任何关系。
1.3 修复方式
改 docker run,三行搞定:
docker run –privileged \\
–name DeepSeek-V4-Flash-0731-w8a8 \\
–net=host \\
-e TZ=Asia/Shanghai \\
-v /etc/localtime:/etc/localtime:ro \\
-v /usr/share/zoneinfo:/usr/share/zoneinfo:ro \\
...
坑中坑:不要挂 /etc/timezone。欧拉系(openEuler)宿主机上这个文件不存在,-v 会把容器里的文件变成目录,容器起来后一堆程序读时区失败。
二、物理层排查:把"光路有问题"这条线彻底排掉
怀疑链路的时候不能靠感觉,要能拿出"全 8 卡 + 全计数器"的横向对比。
2.1 拓扑先确认:8 条点对点直连,没有交换机
P.dev0 (192.168.100.10) ──直连── D.dev0 (192.168.100.2)
P.dev1 (192.168.100.11) ──直连── D.dev1 (192.168.100.3)
…
P.dev7 (192.168.100.17) ──直连── D.dev7 (192.168.100.9)
lldp.log + /etc/hccn.conf 双向确认,没有交换机参与,所以不存在"某台交换机拥塞"这种可能。
2.2 全 8 卡计数器横向对比
| mac_rx_fcs_err_pkt_num | 0 | 19 |
| PCS err | 2696–3051 | 15584 |
| roce_new_pkt_rty_num | 0 | 1861 |
| roce_out_of_order_num | 0 | 79 |
| roce_tx_err_pkt_num | 0 | 3 |
dev6 确实是全机唯一有真实误码的链路,而且两端插的都是全机唯一一对异型号光模块 WTD RTXM500-301(其余都是同型号)。
dev6 的 link up/down 计数更是夸张:up = 40643 / down = 40642,即亚秒级震荡了 4 万次(其余 dev 只有 15–19 次)。
2.3 换了 MPO 跳线,还是报错
换了 MPO 跳线后复测,HcclCommPrepare ret 0x9 依然出现。结合后来(8 月)那次生产崩溃日志里 EI0013 Execution_Error_ROCE_CQE 明确点名 device ID 6,我们判断:
dev6 是一条有历史劣迹、需要单独跟踪的链路,但不是本轮运行期故障的根因。
理由:如果根因是链路误码,故障应该与 dev6 强相关、且表现为 CQE/SDMA 类错误;而本轮是纯软件层的 HcclCommPrepare 失败,与链路无关。
2.4 PFC / 拥塞:完全清白
mac_tx_pfc_pkt_num = 0 (全 8 卡)
mac_tx_mac_pause_num = 0 (全 8 卡)
rx_full_drop_cnt = 0 (全 8 卡)
业务走 TC2,没有触发任何流控。可以排除"网络拥塞导致丢包"这条线。
2.5 管理网:双向 flood ping 20 万包,0 丢包
ping -f -c 200000 10.10.10.2
# 0% packet loss, RTT avg 0.021 ms
反向同样 0 丢包,avg 0.027 ms。10.10.10.x(bond1.4000)这条业务/管理网也没问题。
三、根因收窄:错误链一路读到底
3.1 完整调用链
HcclCommPrepare fail, ret: 0x9 ← 一切的起点
└─ comm_channel.cc:60
└─ channel_manager.cc:459
└─ channel_msg_handler.cc:310 / 379
└─ DoConnect error_code[103901] timeout 10000ms
└─ adxl_inner_engine.cc:359
└─ adxl_engine_impl.cc:136 / 255
要点:
- 103901 是 vLLM 侧的封装错误码,本体是 DoConnect … timeout 10000ms,即 10 秒建链超时
- 0x9 是 HCCL 侧的返回码,出现在 HcclCommPrepare(通信域准备阶段),不是 HcclCommInit(创建阶段),也不是数据传输阶段
- 从 D 侧(kv_consumer)发起,目标是 P 侧(kv_producer)的 KV 传输端口
3.2 量级
D 侧在某段 13.6 小时运行期里累计 2518 次 10 秒 KV 建链超时。
请求失败率随时间恶化:
早期 → 0.1%
中期 → 数个百分点
本轮 → 14.4%(最严重的一次:489 个请求里 489 个 500)
3.3 一个新特征:瞬时并发建链风暴
后续抓到的一组日志显示出很不一样的形态:20 毫秒内,多个远端 engine 端口(20191、20224、20341)和多个本地进程同时爆发 HcclCommPrepare ret 0x9。
这不是单点故障,而是大量请求同时发起建链,把 HCCL 通信域资源瞬间抢空。
于是有两个候选假设:
| A. 通信域资源泄漏 | 错误随时间单调增长,重启后重置 | 统计 HcclCommInit / HcclCommDestroy 次数是否配平 |
| B. 瞬时并发建链风暴 | 错误成簇出现,与请求峰值同步 | 降并发(–max-num-seqs 降低)后是否缓解 |
⚠️ 取证被自己人清掉了:run_dp_template.sh 第 4 行有一句 rm -rf ~/ascend/log,每次启动都会清空 Ascend 日志。ret 0x9 的确切含义需要从 plog 里挖,而这句命令让每次故障都没有现场。这一条必须优先注释掉。
四、环境变量审计:三个偏离官方默认值的高危项
run_dp_template.sh 里这三条,是当时列出的头号嫌疑:
export HCCL_BUFFSIZE=1024 # 官方默认 200 ← 最可疑
export HCCL_EXEC_TIMEOUT=204 # 官方默认 1800
export HCCL_CONNECT_TIMEOUT=1200 # 官方默认 120
HCCL_BUFFSIZE 为什么会炸:
- 它决定每个通信域占用的 SDMA 缓冲大小
- 从 200 拉到 1024 = 单通信域缓冲放大约 5 倍
- PD 分离场景下,通信域是按需建、高频建的(每次 KV 传输的 rank 配对组合都可能新建)
- 高并发下瞬间建大量通信域 → NPU 内存被吃穿 → HcclCommPrepare 直接失败
- 失败不影响已有通信域,所以表现为"偶发、低频、持续"——完美匹配观测现象
另外两条已经作废、只会刷 Unknown vLLM environment variable detected 告警:
export VLLM_RPC_TIMEOUT=3600000 # vLLM 0.23.0 已不再识别
export VLLM_ASCEND_APPLY_DSV4_PATCH=1 # vLLM 0.23.0 已不再识别
五、顺带查出来的一个真 bug:DP 负载倾斜
5.1 现象
4 个 engine 的活跃度分布大约 8 : 4 : 2 : 1。
5.2 一个必须纠正的口径
我一开始说这是"负载占比 8:4:2:1",这是错的。
正确口径:这是"engine 在多少个 10 秒窗口内有活跃请求"的覆盖率,不是吞吐占比。真实分布要看后端 /metrics 的差值。
5.3 代码层面的根因
代理的选路打分是:
# prefill
score = active_tokens + active_kv_cache * 0.3
# decode
score = active_tokens
而 _release_load 在归还负载时没有下限保护,active_tokens 可能被减成负数。一旦某个 engine 的分数变成负的,它就会永远排在堆顶,所有请求都被吸走 → 倾斜。
修复(一行):
# _release_load 里
pool.servers[key].active_tokens = max(0.0, pool.servers[key].active_tokens – load)
decode 侧没有下限,这是明确的 bug,不是调参问题。
六、止血 + 取证动作清单(中午这一轮的输出)
6.1 止血(先让服务可用)
6.2 取证(保住现场)
6.3 A/B 实验矩阵(单变量,每轮跑 30 分钟)
| 基线 | 不动 | 代理 500 率、Mooncake transfer failed 计数、Connect timeout 计数 |
| 1 | 仅 HCCL_BUFFSIZE 恢复默认 200 | 同上 |
| 2 | 仅 HCCL_EXEC_TIMEOUT / HCCL_CONNECT_TIMEOUT 恢复默认 | 同上 |
| 3 | 仅 –max-num-seqs 32 → 8 | 同上 |
单变量是关键——一起改就再也说不清是谁的功劳。
6.4 顺手验证 dev6
hccn_tool -i 6 -stat -g # 看换 MPO 后 FCS / PCS err / 重传 / 乱序 是否下降
七、中午这一轮的结论
中午这一轮把战场从"硬件/网络"收缩到了"软件/资源"。真正把问题解决掉的是下午和晚上的两处修改 —— 见《最终版处理完成篇》。
附录:本轮用到的命令速查
# —- 时区对齐 —-
# 容器内确认
date; cat /etc/localtime
# 宿主机确认
timedatectl
# —- RoCE 链路状态与计数器 —-
hccn_tool -i 0 -stat -g
hccn_tool -i 6 -stat -g
hccn_tool -i 6 -link -g
# 关注这几个字段是否非 0:
# mac_rx_fcs_err_pkt_num
# roce_rx_err_pkt_num / roce_tx_err_pkt_num
# roce_qp_status_err_num
# roce_new_pkt_rty_num / roce_out_of_order_num
# —- PFC / 拥塞 —-
hccn_tool -i 0 -pfc -g
# mac_tx_pfc_pkt_num / mac_tx_mac_pause_num / rx_full_drop_cnt 应全为 0
# —- 业务网连通性压力测试 —-
ping -f -c 200000 10.10.10.2
# —- 通信域泄漏排查 —-
grep -c "HcclCommInit" ~/ascend/log/plog/*.log
grep -c "HcclCommDestroy" ~/ascend/log/plog/*.log
# —- 错误链关键字 —-
grep -n "HcclCommPrepare" ~/ascend/log/plog/*.log
grep -n "103901\\|DoConnect" /path/to/serve.log
grep -n "Mooncake transfer failed" /path/to/serve.log
# —- 代理日志里的失败统计 —-
grep -c "Error occurred in disagg prefill proxy server" proxy.log
grep -c "All connection attempts failed" proxy.log
grep -oE '" [0-9]{3} ' proxy.log | sort | uniq -c
网硕互联帮助中心






评论前必须登录!
注册