2
4
DCU技术达人
一个报错两个真凶:海光 DCU 上 Qwen3-32B 部署崩溃的罗生门排查
2026-09-30 08:56:33
24
## 在[海光 DCU](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=%E6%B5%B7%E5%85%89+DCU&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiLmtbflhYkgRENVIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMjQ2MDg5LCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.l52TsWZTJNICEyv1P0WZWCOmKx66ePA9yw97EKL4xPo&zhida_source=entity) 上部署 Qwen3-32B 的过程,是我遇过最典型的一次「[罗生门式](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=%E7%BD%97%E7%94%9F%E9%97%A8%E5%BC%8F&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiLnvZfnlJ_pl6jlvI8iLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIyNDYwODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.x-ufRnD_jNq0wGGil_DvzLwnEkgk5bIBhfz2T7Hpdo8&zhida_source=entity)」排查:同一个加载崩溃,摆着三个都讲得通的嫌疑解释,每个都有证据、每个又都有反例。0.6B 小模型在同一环境跑得好好的,32B 一启动就崩;报错信息指向 [FlashAttention](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=FlashAttention&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJGbGFzaEF0dGVudGlvbiIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI4MjI0NjA4OSwiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.sCuWm-ijUk2Uomzq5VL9M7NvfZm-NaiSPJA3R2qLC6s&zhida_source=entity) 的限制;而另一台 [docker 容器](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=docker+%E5%AE%B9%E5%99%A8&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJkb2NrZXIg5a655ZmoIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMjQ2MDg5LCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.49mirA51NlWE7jDFNc_3ScPunaNdu4FvcrG2P0KlN4o&zhida_source=entity)里同规模的 32B 却跑得很欢。 从第一次崩溃到最终跑通花了 13 天。结局颇有戏剧性:**根本不是一个问题,而是两个完全独立的问题叠在一起**——修好第一个,第二个才露出水面。而第二个问题的答案,藏在一个「版本号更新反而不行」的 triton 里。这篇完整还原排查与破案过程,以及最终落地的两套并行的部署方案。 ## 第一幕:三个报错,三个方向 环境:主机 conda 环境([vLLM](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=vLLM&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJ2TExNIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMjQ2MDg5LCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.yqIRoUMzdSJ-thjUJOuo8kizJZkdfRsXIzaWyOw0wC4&zhida_source=entity) 0.11.0 DCU 定制版 + DTK 26.04 + torch 2.5.1),模型 Qwen3-32B(62GB BF16,17 个分片),目标 TP=4 四卡跑通。 **报错一:[显存](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=%E6%98%BE%E5%AD%98&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiLmmL7lrZgiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIyNDYwODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.OOsBwVrQTRTWJM0mGoRijZTRFYQJxhIDlF97YVPnDUQ&zhida_source=entity)不足?** ```text ValueError: Free memory on device (4.8/63.98 GiB) on startup is less than desired GPU memory utilization (0.9, 57.59 GiB) ``` 明明是空卡,怎么只剩 4.8GB?排查发现:之前有张卡上跑过的 0.6B 实例进程死了,但 DCU 驱动层的 [HIP](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=HIP&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJISVAiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIyNDYwODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.EYoYFehJ2-KJIxS-QXuSaO4qc-wZZdTTF9uoiikBqeQ&zhida_source=entity) 内存没有立即回收——host 视角看显存是空的,device 视角的 free\_memory 只剩零头。**同一个事实,两个视角给出相反的读数**。解决:换 `HIP_VISIBLE_DEVICES` 到真正干净的卡。这个插曲先给排查定了个调:在这台机器上,眼见未必为实。 **报错二(主犯):FlashAttention 不支持 head size 80** ```text ValueError: Head size 80 is not supported by FlashAttention. Supported head sizes are: [32, 64, 96, 128, 160, 192, 224, 256]. Set VLLM_ATTENTION_BACKEND=FLEX_ATTENTION to use FlexAttention backend which supports all head sizes. ``` 打开模型 config 算账:`hidden_size=5120`,`num_attention_heads=64`,一除正好 80——数字对得上,解释闭环了。vLLM 0.11 在 [ROCm](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=ROCm&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJST0NtIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMjQ2MDg5LCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.GKb-WHAJpn5L1aG-xfW8F5y3B_pGlMWyAcSlnFBnD2g&zhida_source=entity)/HIP 平台的 attention 后端只支持 FLASH\_ATTN 和 [TORCH](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=TORCH&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJUT1JDSCIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI4MjI0NjA4OSwiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.T92BUTWpgiCmj09b6O1LXJ4EoYIO18Fp9kTlSOQ59q0&zhida_source=entity)\_SDPA,报错建议的 FLEX\_ATTENTION 是 NVIDIA 独占,**报错信息开的药方在这个平台上不存在**。可以设 `VLLM_USE_FLASH_ATTN_PA=0` 切到 [Triton attention](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=Triton+attention&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJUcml0b24gYXR0ZW50aW9uIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMjQ2MDg5LCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ._Ne9xS5MfkuEP_axhuNXAOy8ORgoCpRBcKRo0YhHZ1w&zhida_source=entity) 试试,但慢且未验证。 **反证三:docker 里同款 32B 为什么能跑?** 此前我们在 docker 容器里(vLLM 0.6.2 + DTK 24.04.3,V0 引擎)跑通过 DeepSeek-R1-Distill-Qwen-32B。同样是 32B 量级、同样是 Qwen 系架构,它怎么不挑 head size?这说明「32B + DCU」本身不是死路——但差异变量太多(vLLM 版本、DTK 版本、引擎代际、模型 config),每一条都是嫌疑。 ## 罗生门:三个解释的对峙 | 解释 | 支持证据 | 反对证据 | | ------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------ | | vLLM 0.11 ROCm 后端选择逻辑缺陷 | FA 不支持 80 属实;0.6.2 的选择逻辑确实不同 | 无直接证据是 0.11 引入的锅 | | 模型 config 有问题 | config 里 arch 写的是 Qwen2ForCausalLM(Qwen3 的模型怎么会是 Qwen2 的架构名?) | 下载的官方权重,没人动过(我们以为) | | 平台/head\_size 天生不兼容 | 报错信息言之凿凿 | docker 里的 Qwen 系 32B 跑通了 | 正确的做法不是三选一押注,而是**逐个钉死**。先从最便宜、最可证的入手:把 config 审计了一遍。 ## 破案一:config.json 是坏的 真凶一落网:模型目录里的 `config.json` 被改成了 `Qwen2ForCausalLM`,而且**没有** `head_dim` **字段**。vLLM 拿不到显式的 `head_dim`,就按 `hidden_size / num_attention_heads = 5120/64 = 80` 反推——但 Qwen3-32B 真实的 head\_dim 是 **128**(它用了非整除的 GQA 设计,head\_dim 必须由 config 显式声明)。 修法:`config.json` 改回 `Qwen3ForCausalLM` + `"head_dim": 128`(128 在 FA 支持列表里)。改完再启——**head size 报错消失**。docker 里那个 32B 能跑的原因也顺带解释了:它的 config 是完好的,head\_dim 本来就不过 80 这个坎。 这一段最大的教训:**「官方下载的[权重](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=2&q=%E6%9D%83%E9%87%8D&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiLmnYPph40iLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIyNDYwODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MiwiemRfdG9rZW4iOm51bGx9.naxxu7mWb0T2N7ZEgLMaJEl8V1N_MDSQO0vOdhe5Pkw&zhida_source=entity)不会错」是个危险假设**。config.json 这种小文件可能在任何一次手工调整、同步、转换中被改坏,且改坏后模型列表正常、tokenizer 正常,只在某个特定检查点炸出一条误导性极强的报错。备份原文件(我们留了 `config.json.qwen2-broken` 作证物)+ diff 官方原始 config,五分钟就能钉死或排除这个嫌疑——它本该是排查的第一步。 ## 破案二:修好 config 后,崩在了更深的地方 head size 过了,启动继续推进,然后卡死在新的报错上: ```text unsupported target: 'gfx928' PassManager::run failed ``` 这是 V1 引擎 inductor 阶段,triton 在给 DCU 的 gfx928 架构编译 kernel 时拒绝了目标。试过的逃生通道全部无效:`--enforce-eager`(不编译)、关 inductor、退回 V0 引擎(0.11 的 serve 入口直接 assert 禁掉了 V0)。 顺着工具链查,结论反直觉:**本机环境里的 triton 3.1.0 不认识 gfx928,而更老的 triton 3.0.0 认识**。版本号在这里完全失去了指示意义——这是 DCU 生态的又一例「新版本 ≠ 更好」:3.0.0 里有对 gfx928 的支持代码,3.1.0(dtk2604 适配版)反而没有。triton 3.0.0 在哪?在 vLLM 0.9.2 的官方容器镜像里。 至此全案告破:**问题一(config 损坏)制造了 head\_size 假象,问题二(triton 3.1.0 不认 gfx928)藏在它后面**。两个问题独立存在、先后引爆——只修任何一个都无法跑通。这就是罗生门排查的要害:当多个解释都有证据时,可能性最大的假设其实是「不止一个为真」。 ## 终局:两套并行方案落地 既然答案在 vLLM 0.9.2 + triton 3.0.0 的组合里,就把它搬到主机上: **方案 A(主用·裸机)**:建 conda 环境,把官方容器里的两套 python 包目录(11GB 主包 + 27MB apt 依赖)用 tar 流式拷出,得到 vLLM 0.9.2 + torch 2.5.1 + triton 3.0.0 + flash\_attn 2.6.1 的完整栈。有两个前置验证值得记录:一是 dtk25.04 编译的[二进制](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=%E4%BA%8C%E8%BF%9B%E5%88%B6&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiLkuozov5vliLYiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIyNDYwODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.GY_f6OI4OJ0N_yuMSjczSHm_OTTJRKvvtrSFzlNzY1U&zhida_source=entity)在主机 DTK 26.04 上**前向兼容实测通过**(import / matmul / triton 编 gfx928 全 OK,主版本号相同的[运行库](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=1&q=%E8%BF%90%E8%A1%8C%E5%BA%93&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiLov5DooYzlupMiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIyNDYwODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.ZwihXMKB31XtIQfgdfACtIqKe7e9PARgyC0uM6yqSaY&zhida_source=entity) ABI 兼容);二是 CLI 入口 `vllm` 不在 site-packages 里,用 `python -m vllm.entrypoints.openai.api_server` 启动。落地:TP=2 两卡,中文对话正常,每卡 KV 缓存 24.24GiB。 **方案 B(保底·容器)**:直接用官方镜像(vLLM 0.9.2 + DTK 25.04.3),TP=4 四卡。每卡 KV 约 39.5GiB、总 KV 容量 646K tokens,eager 模式实测约 19 tok/s。 两套方案并行保留是有意的:裸机方案便于排查和脚本化运维,容器方案是厂商背书的最稳兜底。32B 在这台 8 卡机上的定位也就此明确——对话场景够用,批量生成场景吞吐有限,属于「能跑」而非「能扛」。 ## 复盘:三条方法论 1. **多解释对峙时,先钉死最便宜的嫌疑**。config 审计只要五分钟,却排在最后才做——因为「官方权重不会错」的偏见替我们排除了它。排查顺序应该按「验证成本 × 证伪威力」排,不按直觉排; 2. **同一条报错背后可以叠着多个独立故障**。修好一个还崩,不代表修错了,只代表修的不全。「报错变了」本身就是进展——它在向你暴露下一层; 3. **在国产卡生态里,版本号不可作为能力依据**。triton 3.1.0 > 3.0.0,但认识 gfx928 的是后者;vLLM 0.11 > 0.9.2,但配好 [triton](https://zhida.zhihu.com/search?content_id=282246089&content_type=Article&match_order=11&q=triton&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTA5MDI0NTMsInEiOiJ0cml0b24iLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIyNDYwODksImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MTEsInpkX3Rva2VuIjpudWxsfQ.bLEeCRqI57u2SB0SwVWx6_1kLWD_YRSXXqyE-Bl4bTM&zhida_source=entity) 后后者全通。判断依据只能是「这个组合在目标行为上的实测结果」——这也是我们最终把环境矩阵表钉在部署文档最顶部的原因。 ## 小结 Qwen3-32B 这次部署,表面上是一次故障排查,实质是一堂「证据课」:显存的读数要问视角(host vs device)、config 要问出处(官方也可能被动过)、版本号要问行为(新不一定兼容)、报错信息要问平台(它开的药方可能本地没有)。四个「不要全信」串起来,就是国产平台上排错的基本功。最后落地的双方案(裸机 0.9.2 主用 + 官方容器保底)也成了一种模式:**在快速演进的生态里,永远给自己留一条厂商背书的退路**。 --- *环境信息:海光 K100\_AI × 8 / 主机 DTK 26.04 / 最终栈:vLLM 0.9.2 + torch 2.5.1 + triton 3.0.0(自官方容器迁移)+ flash\_attn 2.6.1 / 排查周期 2026-07-10 至 07-23。*
全部评论(0)
只看楼主
暂无数据
--
楼主
Level.6
0 帖子
楼主热帖
暂无数据