我当然无法回答与此相关的所有可能的问题。我会试着做一个总结。我在这里写的一些内容是基于here 和here 记录的内容。我这里的讨论也将集中在 linux 和 docker(不是 windows,不是奇异,不是 podman 等)。我也不太可能能够详细解决诸如“为什么其他 PCI 设备不必这样做?”之类的问题。我也不想让我对 docker 工作原理的描述完全准确到该领域的专家。
NVIDIA GPU 驱动程序包含在user space 中运行的组件以及在内核空间中运行的其他组件。这些组件协同工作,必须协调一致。这意味着驱动程序 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 代码存在的兼容性策略(“向前”),以及在谈论特定驱动程序和 @987654324 时存在的兼容性策略(“向后”) @。我也不打算提供有关使用 nvidia-container-toolkit 的说明,该说明已记录在案,并且关于它的许多问题/答案也已经存在。
我将无法回答诸如“为什么采用这种架构?”之类的后续问题。或“那不应该是必要的,你为什么不这样做?”