使用 Docker 挂载天数 GPU 驱动并运行训练任务

解读

国内大厂与中小型 AI 公司普遍采用 天数 GPU(Iluvatar CoreX) 作为英伟达的替代方案,面试时考官不仅想看你会不会“跑起来”,更关注你对 国产 GPU 驱动架构、Docker 隔离机制、权限模型、训练框架兼容性 的理解。
核心矛盾:天数驱动以 内核模块 + 用户态运行时(libcorex.so / libixblas.so 等) 形式存在,容器内必须同时满足 驱动版本一致性、设备可见性、库路径正确性、非 root 安全约束 四大条件,否则训练脚本直接报 “libixblas.so: cannot open shared object file” 或 “no CUDA-capable device”。
因此回答要体现:① 宿主驱动版本确认;② 镜像内最小化依赖;③ 挂载策略(设备文件 + 库 + 内核接口);④ 运行时验证;⑤ 训练任务入口封装。

知识点

  1. 天数 GPU 驱动栈

    • 内核模块:corex_drv.ko(/dev/corex* 字符设备)
    • 用户态:libcorex.solibixcuda.solibixblas.solibixcudart.so(版本须与内核模块严格一致,国内 yum/apt 源不提供,必须挂载宿主目录
    • 设备节点:/dev/corex0/dev/corexctl/dev/ixvidiactl
  2. Docker 挂载 GPU 的三种范式

    • --device 直接映射字符设备(最轻量,但缺库)
    • --gpus 需要 nvidia-docker 等价物;天数官方提供 docker-corex-runtime(基于 runC 的 pre-start hook,自动注入库与设备)
    • 手动 -v 挂载(国内生产常用,可控且易审计)
  3. 镜像层最佳实践

    • 多阶段构建:第一阶段用官方 corex-devel:2.2-cudnn8-ubuntu20.04 装依赖,第二阶段仅保留 libcorex.so.* 与训练 whl,减少 60% 体积
    • 非 root 用户RUN groupadd -g 1001 corex && useradd -u 1001 -g corex -m trainer防止宿主驱动目录被意外改写
    • LD_LIBRARY_PATH 必须在 ENTRYPOINT 脚本中导出,避免 Dockerfile ENV 被 docker-compose 覆盖
  4. 国内 CI/CD 卡点

    • 天数驱动 RPM/DEB 包需走 内网 Artifactory;镜像构建节点必须打 “corex-driver=2.2.1” 标签,防止驱动版本漂移
    • 若使用 Harbor 镜像扫描,需把 .so 加入白名单,否则被误判为“私有 so 泄露”
  5. 故障排查三板斧

    • docker exec -it ctr ls -l /dev/corex* && ldd /usr/local/lib/python3.8/site-packages/corextorch/lib/libixcudart.so
    • dmesg | grep corex_drv 查看宿主内核是否报 “version magic mismatch”
    • strace -e openat python train.py 2>&1 | grep libix 快速定位缺库路径

答案

  1. 宿主准备(以 CentOS 7.9 + CoreX Driver 2.2.1 为例)

    # 确认驱动已加载
    lsmod | grep corex_drv
    ls -l /dev/corex*
    # 记录用户态库路径
    ls /usr/local/corex/{lib,bin}
    
  2. 编写最小 Dockerfile

    FROM ubuntu:20.04
    RUN apt-get update && apt-get install -y --no-install-recommends python3-pip libgomp1 && rm -rf /var/lib/apt/lists/*
    # 创建非 root 用户
    RUN groupadd -g 1001 corex && useradd -u 1001 -g corex -m trainer
    # 只拷贝训练代码与 requirements
    COPY --chown=trainer:corex train.py /home/trainer/
    COPY --chown=trainer:corex requirements.txt /home/trainer/
    USER trainer
    WORKDIR /home/trainer
    RUN pip3 install -r requirements.txt --user
    ENTRYPOINT ["python3", "train.py"]
    
  3. 启动容器(手动挂载方案,国内生产最常用

    docker run --rm -it \
      --device /dev/corex0:/dev/corex0 \
      --device /dev/corexctl:/dev/corexctl \
      -v /usr/local/corex/lib:/usr/local/corex/lib:ro \
      -v /usr/local/corex/bin:/usr/local/corex/bin:ro \
      -e LD_LIBRARY_PATH=/usr/local/corex/lib:$LD_LIBRARY_PATH \
      -v /data/imagenet:/data:ro \
      myrepo/corex-train:1.0 \
      --batch-size 128 --epochs 10
    
  4. 使用官方 runtime(可选,面试加分项

    # 安装 docker-corex-runtime_2.2.1-1_amd64.deb
    sudo dpkg -i docker-corex-runtime_2.2.1-1_amd64.deb
    # 配置 daemon.json
    sudo tee /etc/docker/daemon.json <<EOF
    {
      "runtimes": {
        "corex": {
          "path": "docker-corex-runtime",
          "runtimeArgs": []
        }
      }
    }
    EOF
    sudo systemctl restart docker
    # 运行
    docker run --rm -it --runtime=corex -e COREX_VISIBLE_DEVICES=0 myrepo/corex-train:1.0
    
  5. 验证
    容器内执行

    python3 -c "import corextorch; print(corextorch.device_count())"
    # 预期输出 1
    

拓展思考

  • 多卡并行:天数 GPU 采用 IXCL 通信库,对标 NCCL;需在容器内挂载 /etc/ixcl.conf 并设置 IXCL_SOCKET_IFNAME=eth1,否则 ring-allreduce 卡在 100 Mbps 管理网
  • 热升级场景:驱动 2.2.1 → 2.3.0 时,内核模块 ABI 可能变动;应使用 Kubernetes 的 device-plugin 机制,通过 /var/lib/kubelet/device-plugins/corex.sock 向上屏蔽版本差异,实现 业务容器无感热升级
  • 安全加固:若训练任务需访问 企业 LDAP 密钥,可把 COREX_LICENSE_FILE 放入 Kubernetes Secrets,通过 tmpfs 挂载到 /run/secrets/corex.lic避免明文落入镜像层
  • 混合部署:同一节点存在英伟达与天数 GPU 时,需 分别配置 nvidia-docker 与 corex-runtime,并在 Dockerfile 中通过 ARG GPU_VENDOR=corex条件编译,防止库冲突。