DCU技术达人
海光 DCU 上攻坚 32B 全量微调:从 DeepSpeed 弃坑到 FSDP,11 个坑与一个未解之题
2026-10-10 09:41:38
27
先坦白:这是一篇\*\*没有跑通\*\*的文章,记录的是一段进行中的攻坚战。多数技术文章的结尾都是「实测通过」,这一篇的结尾是一个还没解开的 OOM。但把它写出来同样有价值——推理侧的坑网上多少还有零星资料,\*\*国产卡上做百亿级全量微调的坑,几乎无前人脚印\*\*,这段排查记录本身就是产出。 而且它有一个确定的结论可以先说:\*\*8×64GB = 512GB [显存](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E6%98%BE%E5%AD%98&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLmmL7lrZgiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.GwMZx-YVktHStq4OGb5h6DP07z1CvlzTnjOxVAHU9LE&zhida_source=entity),装得下 32B 全量微调\*\*。[算力](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E7%AE%97%E5%8A%9B&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLnrpflipsiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.ThHDyK3bEe-lWADtVbVvPvLe1US_JkT3Fnw4nu12XQ8&zhida_source=entity)从来不是问题,问题全部出在[软件栈](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E8%BD%AF%E4%BB%B6%E6%A0%88&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLova_ku7bmoIgiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.Pj_MWyCv5oJ8zD4ItFRboqvQsAKzp0ba6WdhKSaEFSA&zhida_source=entity)。 ## 目标:三段流水线 整体设计是经典的「大模型教、小模型干」三段流水线,Stage 1 的位置如下: \`\`\` Stage 1: Qwen3-32B 全量微调(teacher) ← 本篇卡住的地方 Stage 2: [在线蒸馏](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E5%9C%A8%E7%BA%BF%E8%92%B8%E9%A6%8F&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLlnKjnur_okrjppo8iLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.OsBCV_XD4bkK46hd07WPrHtxXsjBQ6pDkOFkq4D_S4U&zhida_source=entity) → Qwen3-0.6B(student) Stage 3: student FastAPI 上线(已通) \`\`\` 为什么坚持\*\*全量\*\*微调而不用 [LoRA](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=LoRA&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJMb1JBIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.wQ5eG--inPbVt3_mWgwIHHJ9o9FPPe_tdgyHlrZY_24&zhida_source=entity)/QLoRA?这是 teacher 模型,它产出的软标签质量直接决定 student 的上限,业务上明确要榨干 32B 的[拟合能力](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E6%8B%9F%E5%90%88%E8%83%BD%E5%8A%9B&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLmi5_lkIjog73lipsiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.7X6rDASA8dM1Om0_73Pi9s0BTM0N71-7MLD85BM-qlo&zhida_source=entity)。(更早的迭代里用 LoRA 跑通过,但产物是 \`lora\_adapter/\` 子目录,部署侧还得合并回流,链路别扭;全量微调导出的就是完整权重,反而和 serve 格式天然兼容——这是后话。) ## 先算容量账:这一步救了我们好几次 动手前先做一遍显存算术,别让 OOM 教你: - Qwen3-32B,bf16 权重 62GB,64 层,hidden 5120,GQA(64 头注意力 + 8 头 KV); - 全量 FT [工作集](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E5%B7%A5%E4%BD%9C%E9%9B%86&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLlt6XkvZzpm4YiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.c33JtX263S6dlY7k45aE3k56ojxjxg7Pen48CFnyU1E&zhida_source=entity)约 = 权重 62GB(bf16)+ 梯度 62GB(bf16)+ 优化器状态(AdamW fp32 的 m/v + fp32 master 权重 ≈ 248GB)≈ \*\*370GB 量级\*\*,加上激活与碎片,峰值工作集按 \~400GB 预算; - 单卡 64GB 装不下 → 必须分片:ZeRO-3 / [FSDP](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=FSDP&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJGU0RQIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.C3sudKmhy50mtjMbInlEOqXuVpmZ4u0q7_-WirNzDus&zhida_source=entity) 把上面三样全切到 8 卡 → \*\*每卡 \~50GB\*\*,激活再靠 checkpointing 压缩,能装进 64GB; - 主机内存只有 125GB——这个数字后面会反复出现,它排除了「参数全卸载到 CPU」之外的很多激进方案。 结论:\*\*硬件够,但只够「正确[分片](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=2&q=%E5%88%86%E7%89%87&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLliIbniYciLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MiwiemRfdG9rZW4iOm51bGx9.hQzMHhRF8aCcREk1xN_o-wFnem1i2aVLiI8S_uhAkJk&zhida_source=entity)」的姿势,一点冗余都没有\*\*。这解释了为什么后面每一个「分片没生效」的 bug 都直接以 OOM 的形式爆出来。 ## [DeepSpeed](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=DeepSpeed&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJEZWVwU3BlZWQiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.yDTdk0Zk-wsmSOkWVNbkIYJ1Kq_TXgUE6OSPRjR3pvY&zhida_source=entity) 弃坑记 第一选择当然是 DeepSpeed ZeRO-3。结果在这套栈上(torch 2.5.1 DCU / deepspeed 0.19.2 / transformers 5.12.1)碰到了一个治不好的 bug: \*\*\`zero.Init\` 上下文加载模型时,不把权重复制进 persistent 参数。\*\* 现象是加载完检查,一批参数(layernorm 的 weight、分类头的 bias)的 \`ds\_numel=0\`、状态 \`NOT\_AVAILABLE\`——这些参数被 ZeRO 标记为 persistent(常驻每卡不分片),但 \`zero.Init\` 的[加载路径](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E5%8A%A0%E8%BD%BD%E8%B7%AF%E5%BE%84&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLliqDovb3ot6_lvoQiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.S49tcwKArYdsLpuun4w3srDRVBhdRay2AOb5vejoTJI&zhida_source=entity)没有把实际数值填进去。调 \`persistent\_threshold\`、换 \`low\_cpu\_mem\_usage\` 组合、把分类头移出 \`zero.Init\`……全都治标不治本。\*\*判定:[DeepSpeed ZeRO-3](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=2&q=DeepSpeed+ZeRO-3&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJEZWVwU3BlZWQgWmVSTy0zIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjIsInpkX3Rva2VuIjpudWxsfQ.cIwYue_OBQduu0i6GygETQlX1jjZYu1kv4L97X_TPqI&zhida_source=entity) 在本栈不可用,转 FSDP。\*\* 到弃坑为止,路上还顺手解决了这些(按踩到顺序,部分): 1. \`[numactl](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=numactl&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJudW1hY3RsIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.ANfjBoUghvg8JgiTNmQC9Kx9EoUWLsc2PSeHiRghq6Y&zhida_source=entity)\` 没装——启动脚本改成「有则用、无则直接 torchrun」; 2. 函数内部 \`import json\` 遮蔽了模块级 import → \`UnboundLocalError\`; 3. [argparse](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=argparse&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJhcmdwYXJzZSIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI4MjExNjcyMywiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.jNAL6FRK8fHyugivOdWveTFcvGsD9r6nXL6sUEEo1XE&zhida_source=entity) 的 \`--optim\` choices 漏了 \`[adafactor](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=adafactor&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJhZGFmYWN0b3IiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.KEy891pj0NEoLgNRWOk0l8tWK7hpjb1G_CaT-aD6aEU&zhida_source=entity)\`; 4. DS 配置里的 \`"auto"\` 字符串在配置预校验时崩(\`'>' str vs int\`),写了 \`materialize\_ds\_config()\` 把 auto 物化成具体数值; 5. 只调 \`torch.distributed.init\_process\_group\` \*\*不会初始化 \`deepspeed.comm\`\*\*——DeepSpeed 读到 world\_size=1,必须改用 \`deepspeed.init\_distributed()\`; 6. \`zero.Init\` 下参数占位 shape=[0],transformers 5.12 的加载校验报 [mismatch](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=mismatch&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJtaXNtYXRjaCIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI4MjExNjcyMywiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.IF7gcmgnqXQw5xfEEHH_FWUcpXmkdg-HkbAYupOtCos&zhida_source=entity) → \`ignore\_mismatched\_sizes=True\`; 7. Trainer 会对顶层 wrapper 调 \`gradient\_checkpointing\_enable()\`,自定义 wrapper 没这个方法 → 加委托转发给 backbone。 一半是[业务代码](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E4%B8%9A%E5%8A%A1%E4%BB%A3%E7%A0%81&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLkuJrliqHku6PnoIEiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.F4c-gW49Y825pZftCYoC4GtXx0xNKhY8BAR2CNN0LtQ&zhida_source=entity)的常规 bug,另一半(4、5、6、7)是「DeepSpeed × 新版 transformers × 定制 torch」三方交界处的裂缝。这类交界 bug 的共同特征:\*\*报错位置和根因隔着好几层\*\*,每一个都要往下挖两三个库才能定位。 ## 转 FSDP FSDP(Fully Sharded Data Parallel)是 [PyTorch](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=PyTorch&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJQeVRvcmNoIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.kPhO9XumEbiH8vJ9clwV3IEsM0goVtBgOUfoMWAc3_c&zhida_source=entity) 原生的全分片方案,能力和 ZeRO-3 等价,而且和 transformers Trainer 的集成更成熟。迁移路上又是四个坑: \*\*① FSDP2 要 torch ≥ 2.6,本机 DCU 版钉死在 2.5.1\*\* → \`fsdp\_config["version"]=1\` 强制走 FSDP1。(DCU 环境又一个特点:torch 版本跟着 DTK wheel 走,不是你想升就升。) \*\*② FSDP 下 \`[gradient\_checkpointing](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=2&q=gradient_checkpointing&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJncmFkaWVudF9jaGVja3BvaW50aW5nIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjIsInpkX3Rva2VuIjpudWxsfQ.vCCIC3tqKm1tEDomYEtvRm6fExK497spbIMYitzwJOs&zhida_source=entity)\` 配置无效\*\*,要换 \`fsdp\_config["activation\_checkpointing"]=True\`——名字相似、机制不同,前者走 torch 原生 checkpoint API,后者是 FSDP 自己的激活重算。 \*\*③ dtype 不统一。\*\* backbone 转成了 bf16,但后接的分类头 \`nn.[Linear](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=Linear&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJMaW5lYXIiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.Rm5Q2HrxOI--vrnpg04GW8ZwdUM6tBEljVQneXPtkKo&zhida_source=entity)\` 默认 fp32 初始化,FSDP wrapping 时报 uniform dtype 错误 → \`model.to(compute\_dtype)\` 统一。 \*\*④ 眼下的 OOM——本文的主角。\*\* ## 当前卡点:每卡 59.36GB,恰好是「没分片」的数字 万事俱备,进 \`trainer.train()\` 第一步: \`\`\` HIP out of memory: ... 每卡已分配 59.36GB,再申请 932MB 即爆 \`\`\` 关键不是「爆了」,是\*\*这个数字本身\*\*。59.36GB ≈ bf16 权重 62GB 的量级——\*\*每张卡上都常驻着接近完整的模型\*\*。如果分片生效,每卡参数应该只有 \~8GB。也就是说,症状指向一个明确的推断:\*\*FSDP 的参数分片没有真正发生\*\*,8 张卡各自扛了一个完整模型,第一个 optimizer step 直接压爆。 而它阴险的地方在于:训练开始前的所有诊断都是「正常」的——加载、[分布式初始化](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E5%88%86%E5%B8%83%E5%BC%8F%E5%88%9D%E5%A7%8B%E5%8C%96&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLliIbluIPlvI_liJ3lp4vljJYiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.N3MvPEDrp_ke73dSfJt5j6QxiVGMdtW2QtCIr9JPld8&zhida_source=entity)、[dtype](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=4&q=dtype&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJkdHlwZSIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI4MjExNjcyMywiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjo0LCJ6ZF90b2tlbiI6bnVsbH0.mr4tBllF4ZsduPxQn4RbPV3ZW7mW85uaGDk5uA2zrEc&zhida_source=entity) 检查全过;trainer 创建时打印 FSDP 单元数 = 0,但这是\*\*正常的\*\*(FSDP wrapping 发生在 \`train()\` 内部 \`[accelerate](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=accelerate&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJhY2NlbGVyYXRlIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.lzoC2echDrjx8MfiThZdIMffYIk5Q_SvUx0bK5Joh5M&zhida_source=entity).prepare()\` 的时候,创建时当然还没有)。到目前为止,还没有任何一次观测是在「prepare 之后」做的——\*\*所以严格说,我们连「分片没生效」这个推断都还没验证过\*\*。 ## 下一步:先让证据说话 排查计划按「先诊断、再动手」排好了序: \*\*第一步,把诊断挂到 prepare 之后\*\*——加一个只在第一个训练步触发的回调: \`\`\`python class \_FSDPDiagCallback(TrainerCallback): \_done = False def on\_step\_begin(self, args, state, control, \*\*kw): if self.\_done: return self.\_done = True from torch.distributed.fsdp import FullyShardedDataParallel as FSDP m = kw.get("model") n = sum(1 for x in m.modules() if isinstance(x, FSDP)) [http://**logger.info**](https://link.zhihu.com/?target=http%3A//logger.info)(f"[FSDP-DIAG] FSDP单元数={n}, " f"GPU分配={torch.cuda.memory\_allocated()/1e9:.1f}GB") \`\`\` 两种结果,两条岔路:单元数 = 0 → FSDP 根本没激活(最大嫌疑:训练脚本里\*\*手动调了 \`init\_process\_group\`\*\*,干扰了 accelerate 自己的初始化);单元数 > 0 但仍 59GB → wrap [粒度](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E7%B2%92%E5%BA%A6&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLnspLluqYiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.l_nl-HF2FjDVC2gzFkmNmvGSOmdenOvCvFVYzvCCc5c&zhida_source=entity)太粗(\`transformer\_layer\_cls\_to\_wrap\` 没按 \`Qwen3DecoderLayer\` 逐层包)。 \*\*第二步(疑似正解)\*\*:FSDP 路径去掉手动 \`init\_process\_group\`,\`fsdp\_config\` 加 \`cpu\_ram\_efficient\_loading: True\`,backbone 在所有 rank 上正常 \`from\_pretrained\`——把加载和分片全部交给 accelerate 的标准路径。我们 rank0 加载 + meta device 广播的手写方案,出发点是省内存(125GB 主存不宽裕),但手动方案恰恰是干扰项的头号嫌疑。 \*\*兜底\*\*:FSDP \`[cpu\_offload](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=cpu_offload&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJjcHVfb2ZmbG9hZCIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI4MjExNjcyMywiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.W2-BdO4Js6U6pPcCjRNMhg8qxyU26U4lPDkvRod-vpY&zhida_source=entity)\`(62GB 权重 < 125GB 内存,装得下,慢但能先跑通冒烟)。 ## 已到手的收获 虽然 Stage 1 卡着,流水线的另外两段已经验证是通的: - \*\*接口全部就绪\*\*:\`train\_teacher.py\` 写了 FSDP-aware 的导出(顶层完整 Qwen3Model + classifier\_heads.pt),和 serve 侧 \`AutoModel.from\_[pretrained](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=2&q=pretrained&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJwcmV0cmFpbmVkIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjgyMTE2NzIzLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjIsInpkX3Rva2VuIjpudWxsfQ.lLIDt3YYN1bs0Oz2zMnh7CRCF_21ay3gnvW2KWGEYQk&zhida_source=entity)\` 的加载格式\*\*已经对上\*\*——训练一通,端到端立即能跑; - \*\*蒸馏脚本已修好\*\*:teacher 加载原本走 bitsandbytes 4bit,而 \*\*DCU 上没有 bitsandbytes\*\*,量化路径必崩——已改成 bf16 加载; * 11 个已解决的坑(本文只展开了大部分)全部记录在案,重装环境、换人接手都不用从头踩。 ### 小结 两个多月从推理杀到训练,这一段是最陡的坡。复盘下来有个清晰的感受:**推理侧的坑多是「路径和环境」的坑,训练侧的坑全是「版本交界」的坑**——DeepSpeed、[transformers](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=5&q=transformers&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJ0cmFuc2Zvcm1lcnMiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6NSwiemRfdG9rZW4iOm51bGx9.V7hdwsqQrFwDMV3Uc6RivFXIytOKY859KOqmjTo_WQ0&zhida_source=entity)、FSDP、定制 torch,每两个的交界处都埋着雷,而国产卡定制的[二进制](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E4%BA%8C%E8%BF%9B%E5%88%B6&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLkuozov5vliLYiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.hlwvTF0iN7a1MDuRFxPMjAhDQ4pQ5l_UrENpR0q8zMk&zhida_source=entity)让「升级绕过」这条路基本不存在,只能一个个排。 好消息是问题的边界已经收得很窄:从「训练 32B 会不会 OOM」收窄到「prepare 之后 FSDP 到底包没包住模型」这一个二选一。等这一步有了结果——无论通没通——我会回来更新这篇。 --- *环境信息:[海光](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=%E6%B5%B7%E5%85%89&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiLmtbflhYkiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.IWAzfwJObA7knKEu5CX4q9UWVIYXrJckDqaUgGi0AO0&zhida_source=entity) K100\_AI × 8(本任务用 HCU1-7)/ DTK 26.04 / conda [env](https://zhida.zhihu.com/search?content_id=282116723&content_type=Article&match_order=1&q=env&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3OTE3NjkyMTQsInEiOiJlbnYiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyODIxMTY3MjMsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.Cge_BnKGY9YZf4JPqdofccqxXwx8v86QwVxu0zqJMWY&zhida_source=entity) dcu-train:torch 2.5.1(DCU)+ transformers 5.12.1 + accelerate 1.14.0 / deepspeed 0.19.2(已弃用)/ Qwen3-32B bf16。*
全部评论(0)
只看楼主
暂无数据
--
楼主
Level.1
0 帖子
楼主热帖
暂无数据