寒武纪 MLU 370 在容器内的 CNRT 版本兼容问题排查
解读
面试官抛出该问题,核心想验证三件事:
- 你是否真的把国产 AI 加速卡(寒武纪 MLU 370)放进过容器,而不是只跑过 x86 通用镜像;
- 遇到“驱动-运行时-框架”三角冲突时,有没有一套可复现、可灰度、可回滚的排查套路;
- 对国内信创环境常见的“内核锁版本、驱动闭源、RPM 包离线”现状,能否给出工程化而非实验室的解法。
一句话:不是问“版本号是多少”,而是问“你怎么在客户现场 30 分钟内定位并止血”。
知识点
- MLU 370 驱动模型:宿主机必须安装 neuware-driver-4.11.x.ko,容器内只能带 CNRT 用户态库,绝不能把 ko 文件打包进镜像,否则宿主机内核升级即崩溃。
- CNRT 版本三元组:驱动版本 ≥ CNRT 版本 ≥ CNNL/CNML 版本,向下兼容但不向上兼容;容器内 CNRT 一旦高于宿主机驱动,直接报 “cnrtInit: version mismatch”。
- 容器运行时钩子:国内生产环境普遍使用 nvidia-docker 魔改版(寒武纪提供 cn-docker),其 config.toml 里需要声明
/usr/local/neuware为 rshared 挂载点,否则出现 “libcnrt.so: file too short” 伪报错。 - 国产 OS 内核裁剪:麒麟 V10 SP2 默认把
CONFIG_DMIID关闭,导致 cnmon 无法读取板卡 UUID,容器内训练脚本会误判为 “no mlu found”。 - CI 灰度策略:在 GitLab-CI 中利用 parallel: matrix 同时构建 CNRT 4.9/4.10/4.11 三个版本镜像,通过 annotations “cambricon.com/cnrt” 让 K8s 调度器按节点驱动版本精准绑定,实现驱动-运行时同版本灰度。
答案
我给客户现场止血的标准 SOP 分五步,全程 30 分钟内完成:
-
快速确认三角版本
宿主机执行cnmon -t拿到驱动版本,例如 4.11.3;容器内执行strings /usr/local/neuware/lib64/libcnrt.so | grep "CNRT BUILD"拿到 CNRT 版本,例如 4.10.2;只要 CNRT 低于驱动,即可排除版本倒挂。 -
检查容器运行时钩子
cat /etc/cn-docker/config.toml确认[[volume]]字段包含/usr/local/neuware且options = ["rbind", "rshared"];若缺失,systemctl restart cn-docker 后重新创建容器,90% 的 “cnrtInit fail” 在此步消失。 -
验证内核符号缺失
容器内执行cnrtGetDeviceCount(&dev_cnt)若返回 4011(CNRT_ERROR_NO_DEVICE),则到宿主机dmesg | grep cambricon看是否出现 “uuid: no DMI identifier”;若出现,向客户交付临时内核补丁 rpm,打开 CONFIG_DMIID 即可,无需重装驱动。 -
镜像最小化回退
若前三步仍失败,立即回退到官方 registry.cn-hangzhou.aliyuncs.com/cambricon/cnrt:4.9.1-centos7 基础镜像,只保留业务 whl 文件,排除“同事私下升级 CNNL”导致的隐性版本漂移;回退后 5 分钟可恢复训练。 -
固化版本锁
在 Dockerfile 末尾写入RUN echo "4.11.3" > /etc/cambricon-driver-version.lock,CI 构建时通过 ARG DRIVER_VERSION 注入,并在 K8s Pod 的 nodeSelector 加上cambricon.com/driver-version: 4.11.3,实现“驱动-镜像”一一对应,后续再未出现兼容事故。
通过以上五步,现场训练任务 30 分钟内重新跑通,同时把版本锁文件纳入 Git 版本管理,后续迭代零回归。
拓展思考
- 多卡热升级:如果客户要求不中断训练升级驱动到 4.12,可考虑 K8s 的 drain + podDisruptionBudget 策略,把 MLU 370 节点分批隔离,先升级驱动再滚动替换 CNRT 镜像;此时需提前在 CI 里构建 兼容层镜像(CNRT 4.12 + CNNL 4.11),保证 API 符号级向前兼容。
- 国产机密算力场景:在政务云里,容器需通过 工信部可信容器认证,要求镜像内不能出现任何 GPL 动态库;此时需要把 CNRT 静态链接到业务二进制,用 multi-stage 把 LGPL 代码隔离到构建阶段,最终交付 distroless 基础镜像,既满足合规又缩小 60% 体积。
- 故障可观测:建议部署 cambricon-device-plugin 的 debug 模式,把 cnmon 的 temperature、power、memory 指标自动注册到 Prometheus;当再次出现版本兼容异常时,通过 Grafana 面板一眼看出是驱动重启还是 CNRT 崩溃,把排障时间从 30 分钟压缩到 5 分钟。