“客户提供了最好的GPU了。但是你们的服务为啥只能用CPU?”
“容器能执行nvidia-smi吗?”
“能,但是服务启动的时候有报错,然后就走CPU了。”
接到现场运维同事的反馈后,我们有些尴尬。
无论是Tensorflow还是PyTorch,镜像拿到客户那里那台有着8块A100的机器上上运行,就报了 CUDA_ERROR_SYSTEM_NOT_READY (code 822) 错误 。
PyTorch的错误是: Error 802: system not yet initialized
既然是没加过的报错,就要查阅NVIDIA官方文档。
根据文档的说法,这是因为缺少nvidia-fabric-manager导致的。
解决办法就是——需要安装nvidia-fabric-manager。(真是山猪吃不来细糠啊)
客户的宿主机已经安装了nvidia-fabric-manager,所以现在需要做的,是在docker镜像里面安装好对应的版本。
关于Centos 7安装nvidia-fabric-manager,以腾讯云代表的很多链接是这么说的:
不同操作系统版本安装方法不同,请您参考以下方式,执行对应命令进行安装。
CentOS 7.x 镜像
version=470.103.01
yum -y install yum-utils
yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo
yum install -y nvidia-fabric-manager-${version}-1
可惜,仓库最多提供到470.42.01版本,而客户机器的驱动版本是470.82.01,并不匹配。
好消息是,官方倒是提供了针对yum(rpm包)和apt(deb包)的构建工程。
坏消息是,现在都2023年了,470.82.01版本开始,发布的逻辑也变了…
所知这里我整理了一遍最新版操作步骤:
- 克隆git仓库,切换大版本
git clone https://github.com/NVIDIA/yum-packaging-fabric-manager.git
git checkout 470
官方的仓库其实也就到了470版本,但是现在驱动早就是5xx版本了,不过嘛,后面每个分支都没啥改动,就用470好了。
-
下载文件
访问fabricmanager archive,下载对应版本的包。 -
重新打包*archive.tar.xz得到 .tar.gz,
从470.82开始,打包方式变从tar.gz成了tar.xz,内部结构也发生了变化。不过不要紧,重新打个包。
mkdir fabricmanager && \
tar -xvf fabricmanager-linux-x86_64-470.82.01-archive.tar.xz --strip-components 2 -C fabricmanager/ && \
tar -xvf fabricmanager-linux-x86_64-470.82.01-archive.tar.xz --strip-components 4 -C fabricmanager/ && \
tar -czvf ..\fabricmanager-linux-x86_64-470.82.01.tar.gz --exclude="nvidia" -C fabricmanager/ .
(tar命令无法仅不解压路径仅解压文件,只能这么折衷了XD)
- 执行NVIDIA的打包步骤
cd yum-packaging-fabric-manager
mkdir SPECS SOURCES
cp *.spec SPECS/
cp ../fabricmanager*.tar.gz SOURCES/
rpmbuild \
--define "%_topdir $(pwd)" \
--define "%version 470.82.01" \
--define "%branch 470" \
--define "%_arch x86_64" \
--define "%_build_arch x86_64" \
--target=x86_64 \
-v -ba SPECS/*.spec
生成的 rpm 包在 RPMS/x86_64/ 目录下,一共四个:
cuda-drivers-fabricmanager-470-470.82.01-1.x86_64.rpm
cuda-drivers-fabricmanager-470.82.01-1.x86_64.rpm
nvidia-fabric-manager-470.82.01-1.x86_64.rpm
nvidia-fabric-manager-devel-470.82.01-1.x86_64.rpm
包打好了,剩下的也就简单了。
创建一个目录,放上下面这些文件:
- Dockerfile
- nvidia-fabric-manager-470.82.01-1.x86_64.rpm
- nvidia-fabric-manager-devel-470.82.01-1.x86_64.rpm
其中Dockerfile 内容如下:
ARG BASE_IMAGE
FROM $BASE_IMAGE
ADD nvidia-fabric-manager-470.82.01-1.x86_64.rpm nvidia-fabric-manager-devel-470.82.01-1.x86_64.rpm \
/tmp/
RUN rpm -Uvh /tmp/*.rpm --nodep --force
接下来就可以执行docker build命令了:
docker build -t {image_name}-nvswitch -f Dockerfile --build-arg BASE_IMAGE={image_name} ./
其中{image_name}
为原始镜像的名字。
不过。如果要顺利跑通,还需要启动 nv-fabricmanager。可以用下面两种方式初始化。
- 在宿主机启动服务(一般设置为自启动)
systemctl start nvidia-fabricmanager
- 用 --privileged=true 创建容器,进入后执行
nv-fabricmanager