我遇到了有趣且奇怪的问题。
当我使用 GPU 启动 docker 容器时,它工作正常,并且我看到 docker 中的所有 GPU。然而,几个小时或几天后,我无法在 docker 中使用 GPU。
当我在 docker 机器中执行
nvidia-smi
时。我看到这条消息
“无法初始化 NVML:未知错误”
但是,在主机中,我看到所有带有 nvidia-smi 的 GPU。另外,当我重新启动 docker 机器时。它完全工作正常并显示所有 GPU。
我的 Inference Docker 机器应该一直打开,并根据服务器请求进行推理。有没有人有同样的问题或者这个问题的解决方案?
我尝试过一个解决方法,发现它有效。 如果您需要完整的详细信息,请检查此链接: https://github.com/NVIDIA/nvidia-docker/issues/1730
我在这里总结了问题的原因并详细阐述了解决方案,方便大家使用。
原因:
主机执行守护程序重新加载(或类似的活动)。如果容器使用 systemd 来管理 cgroup,则 daemon-reload 会“触发重新加载任何引用 NVIDIA GPU 的单元文件”。然后,您的容器将无法访问重新加载的 GPU 引用。
如何检查您的问题是否是由问题引起的:
当您的容器仍然具有 GPU 访问权限时,打开“host”终端并运行
sudo systemctl daemon-reload
然后,返回容器。如果容器中的 nvidia-smi 立即出现问题,您可以继续使用解决方法。
解决方法:
虽然我在一次讨论中看到NVIDIA计划在6月中旬发布正式修复程序,但截至2023年7月8日,我还没有看到。因此,这应该对您仍然有用,特别是当您无法更新容器堆栈时。
最简单的方法是通过 docker daemon.json 禁用容器中的 cgroup。如果禁用 cgroup 不会对您造成伤害,请执行以下步骤。一切都在主机系统中完成。
sudo nano /etc/docker/daemon.json
然后,在文件中添加此参数设置。
"exec-opts": ["native.cgroupdriver=cgroupfs"]
不要忘记在此参数设置之前添加逗号。这是众所周知的 JSON 语法,但我想有些人可能不熟悉它。这是我的机器上编辑的文件示例。
{
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
},
"exec-opts": ["native.cgroupdriver=cgroupfs"]
}
最后一步,重启主机中的docker服务。
sudo service docker restart
注意:如果您的容器运行自己的 NVIDIA 驱动程序,则上述步骤将不起作用,但参考链接有更多处理它的详细信息。我仅详细阐述一个简单的解决方案,我希望很多人会发现它有用。
我有同样的错误。我尝试了docker的健康检查作为临时解决方案。当 nvidia-smi 失败时,容器将被标记为不健康,并通过 willfarrell/autoheal 重新启动。
Docker-compose 版本:
services:
gpu_container:
...
healthcheck:
test: ["CMD-SHELL", "test -s `which nvidia-smi` && nvidia-smi || exit 1"]
start_period: 1s
interval: 20s
timeout: 5s
retries: 2
labels:
- autoheal=true
- autoheal.stop.timeout=1
restart: always
autoheal:
image: willfarrell/autoheal
environment:
- AUTOHEAL_CONTAINER_LABEL=all
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
Dockerfile 版本:
HEALTHCHECK \
--label autoheal=true \
--label autoheal.stop.timeout=1 \
--start-period=60s \
--interval=20s \
--timeout=10s \
--retries=2 \
CMD nvidia-smi || exit 1
使用自动修复守护进程:
docker run -d \
--name autoheal \
--restart=always \
-e AUTOHEAL_CONTAINER_LABEL=all \
-v /var/run/docker.sock:/var/run/docker.sock \
willfarrell/autoheal
我也遇到了同样奇怪的问题。根据你的描述,它很可能与 nvidia-docker 官方仓库上的这个问题相关:
https://github.com/NVIDIA/nvidia-docker/issues/1618
我计划尝试相关线程中提到的解决方案,建议将主机上的内核cgroup版本从v1升级到v2。
ps:我们已经在生产环境中验证了这个解决方案,它确实有效!但不幸的是,这个解决方案至少需要linux内核4.5。如果无法升级内核,sih4sing5hog5提到的方法也可能是一个解决方案。
略有不同,但对于其他可能偶然发现这一点的人来说。
对我来说,在使用 nvidia-docker 启动 docker 容器后,GPU 还不可用,但仅在
Failed to initialize NVML: Unknown Error
上显示 nivida-smi
。
经过几个小时的寻找解决方案后,我偶然发现了类似的错误
Failed to initialise NVML: Driver/library version mismatch
。一个建议是简单地 reboot
主机。我这样做了,现在可以了。
这是在我升级 Ubuntu 20->22 和 Docker 19->20 以及 nvidia 驱动程序之后发生的
525.116.04
。
在重新启动容器后,我遇到了同样的错误,而没有对容器进行任何更改。只需再次重新启动容器即可解决问题。
寓意:在深入研究之前,先尝试最简单的解决方案。
我遇到了同样的问题,我刚刚在容器中运行了
screen watch -n 1 nvidia-smi
,现在它可以连续工作。