云计算百科
云计算领域专业知识百科平台

DeepSeek-V4-Flash 昇腾 910B PD 分离部署(11 月 6 日中午调试篇):14.4% 请求失败率是怎么定位出来的

/* 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 卡计数器横向对比

指标dev0–dev5、dev7dev6
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 止血(先让服务可用)

  • 降低 D 侧并发:–max-num-seqs 32 → 8
  • 确认代理层对 500 有重试(已有 Attempt 1/2,确认第 2 次是否真生效)
  • 必要时在代理前加并发闸,避免瞬时建链风暴
  • 6.2 取证(保住现场)

  • 注释掉 run_dp_template.sh 第 4 行 rm -rf ~/ascend/log
  • 备份历史 ~/ascend/log
  • 统计 HcclCommInit / HcclCommDestroy 次数,判断是否有通信域泄漏
  • 核对 CANN 与 HDK 版本配套
  • 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 / 重传 / 乱序 是否下降


    七、中午这一轮的结论

  • 时间基准修正:之前认定的两次 8 卡同步掉线,发生在服务启动前 3 小时,与本轮无关。
  • 物理层排除:拓扑是点对点直连;全 8 卡 PFC/discard 全 0;管理网 20 万包 flood ping 0 丢包。
  • dev6 单独跟踪:确实有真实误码和不配套光模块,8 月也实锤导致过生产崩溃,但不是本轮根因(换 MPO 后仍报错)。
  • 根因定性:HcclCommPrepare ret 0x9 + DoConnect 103901 timeout 10000ms 属于纯软件/资源层,候选为「通信域泄漏」或「瞬时建链风暴」。
  • 头号嫌疑:HCCL_BUFFSIZE=1024(默认 200)把单通信域 SDMA 缓冲放大 5 倍,在按需高频建域场景下极易耗尽 NPU 内存。
  • 附带发现:代理 _release_load 缺 max(0.0, …) 下限,是 DP 倾斜的代码级根因。
  • 取证被破坏:rm -rf ~/ascend/log 必须优先注释,否则 ret 0x9 永远没有 plog 现场。
  • 中午这一轮把战场从"硬件/网络"收缩到了"软件/资源"。真正把问题解决掉的是下午和晚上的两处修改 —— 见《最终版处理完成篇》。


    附录:本轮用到的命令速查

    # —- 时区对齐 —-
    # 容器内确认
    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

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » DeepSeek-V4-Flash 昇腾 910B PD 分离部署(11 月 6 日中午调试篇):14.4% 请求失败率是怎么定位出来的
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!