这遍文章可能还要加个纸上谈兵, 我并没有去搞几块 GPU 来验证相关认知. 我日常的工作并不涉及对 GPU 资源的管理, 我对蓬勃发展的 AI 相关内容也缺乏关注.

在代码中使用 GPU

CUDA Toolkit 是 NVIDIA 为 GPU 提供的一站式工具包, 包括了 api, runtime 和 compile 等功能.

基本的功能包括:

  • __global__ 申明对应的函数可以在 GPU 上执行
  • <<< >>> 在调用时指定允许有多少线程去并发执行该函数 ```c++ // Kernel definition global void VecAdd(float* A, float* B, float* C) { int i = threadIdx.x; C[i] = A[i] + B[i]; }

int main() { … // Kernel invocation with N threads VecAdd«<1, N»>(A, B, C); … } ``` An Even Easier Introduction to CUDA 是一个具体的入门案例. CUDA C++ Programming Guide 的前四章可以帮助树立最基本的认知.

在容器中使用 GPU

容器并不是天然支持 GPU 的, 大多数情况下, 我们需要依赖 NVIDIA 提供的一系列工具.

主流的方式有两种.

一种是使用 NVIDIA 在 runc 基础上实现的容器运行时 nvidia-container-runtime runtime-spec 中定义的 create, start, delete 等操作依然通过更底层的 runc 来执行. nvidia-container-runtime 仅会在容器创建时, 将 [nvidia-container-hook] 注入为 prestart hook, 由其为容器绑定 GPU. 对应官方文档中的案例 Docker.

另一种方式依赖于 CDIContainer Device Interface). 仅需要提前根据宿主机的 GPU 信息生成相关信息, 并按 CDI 的要求放在指定目录下. 随后即可在运行容器时直接通过通过 device 指定需要的 GPU, 并由诸如 containerd 之类的容器运行时负责绑定. 对应官方文档中的案例 Step 2: Generate a CDI specificationStep 3: Using the CDI specification.

在 k8s 中使用 GPU

在前文的基础之上, 如果我们想在 k8s 中部署使用 GPU 的应用, 我们还需要 NVIDIA/k8s-device-plugin

k8s 有一套 device plugins 机制, 允许

  • 供应商将自定义的设备注册到 k8s
  • 用户为容器指定需要的第三方设备

NVIDIA/k8s-device-plugin 实现了这套机制, 主动发现宿主机上的 GPU 设备, 暴露给 k8s, 供用户使用.

NVIDIA 似乎更进一步的提供了更自动化的 NVIDIA GPU Operator.

Reference