我当然无法回答与此相关的所有可能的问题。我会试着做一个总结。我在这里写的一些内容是基于此处和此处记录的内容。我这里的讨论也将集中在 linux 和 docker(不是 windows,不是奇异,不是 podman 等)。我也不太可能能够详细解决诸如“为什么其他 PCI 设备不必这样做?”之类的问题。我也不想让我对 docker 工作原理的描述完全准确到该领域的专家。
NVIDIA GPU 驱动程序具有在用户空间中运行的组件以及在内核空间中运行的其他组件。这些组件协同工作,必须协调一致。这意味着驱动程序 XYZ.AB 的内核模式组件只能与驱动程序 XYZ.AB(而不是任何其他版本)中的用户空间组件一起使用,反之亦然。
粗略地说,docker 是一种提供隔离的用户空间 linux 存在的机制,该存在运行在 linux 内核(所有内核空间的东西所在的地方)之上,并与其接口。linux内核位于基础机器中(容器外),大部分/大部分linux用户空间代码位于容器内。这是允许您做类似在 RHEL 内核上运行 ubuntu 容器之类的工作的架构因素之一。
从 NVIDIA 驱动的角度来看,它的一些组件需要安装在容器内,一些需要安装在容器外。
我可以使用库存的 Docker(或 podman)运行时访问我的 NVIDIA GPU 吗?
是的,你可以,这就是人们在 nvidia-docker 或 nvidia-container-toolkit 存在之前所做的。您需要在基础机器和容器中安装完全相同的驱动程序。上次我检查时,这是可行的(尽管我不打算在这里提供说明。)如果您这样做,容器内的驱动程序组件与容器外的驱动程序组件匹配,并且它可以工作。
我错过了什么?
NVIDIA(可能还有其他人)想要一个更灵活的场景。上面的描述意味着如果一个容器是用任何其他驱动程序版本(不是安装在你的基础机器上的那个)构建的,它就不能工作。这很不方便。
nvidia-docker 的最初目的是执行以下操作:在容器加载时,将存在于基础机器中的驱动程序的运行时组件安装到容器中。这协调了事情,虽然它不能解决所有的兼容性场景,但它解决了一堆问题。通过一个简单的规则“将基础机器上的驱动程序更新到最新版本”,它有效地解决了可能由不匹配的驱动程序/CUDA 运行时引起的每种兼容性情况。(CUDA 工具包和任何依赖它的东西,比如 CUDNN,只需要安装在容器中。)
正如您所指出的,随着时间的推移,nvidia-container-toolkit 已经获得了许多其他可能有用的功能。
我不会在这里花很多时间谈论编译的 CUDA 代码存在的兼容性策略(“向前”),以及在谈论特定驱动程序和支持的 CUDA 版本时存在的兼容性策略(“向后”)那个司机。我也不打算提供有关使用 nvidia-container-toolkit 的说明,该说明已经记录在案,并且关于它的许多问题/答案也已经存在。
我将无法回答诸如“为什么要这样设计?”之类的后续问题。或“那不应该是必要的,你为什么不这样做?”