将 GPU 用于计算密集型工作负荷

适用于:Azure Local 22H2 上的 AKS、Windows Server 上的 AKS

图形处理单元(GPU)用于计算密集型工作负荷,例如机器学习、深度学习等。 本文介绍如何将 GPU 用于 Azure Arc 启用的 AKS 中计算密集型工作负荷。

开始之前

如果要从 2022 年 10 月之前运行启用 GPU 的节点池的预览版本更新 AKS,请确保在开始之前删除所有运行 GPU 的工作负荷群集。 按照本部分中的步骤操作。

步骤 1:卸载 Nvidia 主机驱动程序

在每个主机上,导航到 控制面板 > 添加或删除程序,卸载 NVIDIA 主机驱动程序,然后重新启动计算机。 计算机重新启动后,确认驱动程序已成功卸载。 打开以管理员权限运行的 PowerShell 终端并运行以下命令:

Get-PnpDevice  | select status, class, friendlyname, instanceid | findstr /i /c:"3d video" 

应会看到 GPU 设备显示为错误状态,如以下示例输出所示:

Error       3D Video Controller                   PCI\VEN_10DE&DEV_1EB8&SUBSYS_12A210DE&REV_A1\4&32EEF88F&0&0000 
Error       3D Video Controller                   PCI\VEN_10DE&DEV_1EB8&SUBSYS_12A210DE&REV_A1\4&3569C1D3&0&0000 

步骤 2:从主机卸载主机驱动程序

卸载主机驱动程序时,物理 GPU 进入错误状态。 必须从主机中卸载所有 GPU 设备。

对于每个 GPU(3D 视频控制器)设备,请在 PowerShell 中运行以下命令。 复制实例ID,例如从上一个命令输出中复制 PCI\VEN_10DE&DEV_1EB8&SUBSYS_12A210DE&REV_A1\4&32EEF88F&0&0000

$id1 = "<Copy and paste GPU instance id into this string>"
$lp1 = (Get-PnpDeviceProperty -KeyName DEVPKEY_Device_LocationPaths -InstanceId $id1).Data[0]
Disable-PnpDevice -InstanceId $id1 -Confirm:$false
Dismount-VMHostAssignableDevice -LocationPath $lp1 -Force

若要确认 GPU 已从主机中正确卸载,请运行以下命令。 应将 GPU 置于 Unknown 状态:

Get-PnpDevice  | select status, class, friendlyname, instanceid | findstr /i /c:"3d video"
Unknown       3D Video Controller               PCI\VEN_10DE&DEV_1EB8&SUBSYS_12A210DE&REV_A1\4&32EEF88F&0&0000 
Unknown       3D Video Controller               PCI\VEN_10DE&DEV_1EB8&SUBSYS_12A210DE&REV_A1\4&3569C1D3&0&0000 

步骤 3:下载并安装 NVIDIA 缓解驱动程序

该软件可能包括 NVIDIA Corporation 或其许可商开发并拥有的组件。 这些组件的使用受 NVIDIA 最终用户许可协议的约束。

请参阅 NVIDIA 数据中心文档,以下载 NVIDIA 缓解措施驱动程序。 下载驱动程序后,展开存档并在每台主机上安装缓解驱动程序。

Invoke-WebRequest -Uri "https://docs.nvidia.com/datacenter/tesla/gpu-passthrough/nvidia_azure_stack_inf_v2022.10.13_public.zip" -OutFile "nvidia_azure_stack_inf_v2022.10.13_public.zip"
mkdir nvidia-mitigation-driver
Expand-Archive .\nvidia_azure_stack_inf_v2022.10.13_public.zip .\nvidia-mitigation-driver\

若要安装缓解驱动程序,请导航到包含提取文件的文件夹,右键单击 nvidia_azure_stack_T4_base.inf 文件,然后选择 安装。 检查是否具有正确的驱动程序;AKS 目前仅支持 NVIDIA Tesla T4 GPU。

您还可以通过命令行安装,方法是导航到相应文件夹并运行以下命令以安装缓解驱动程序:

pnputil /add-driver nvidia_azure_stack_T4_base.inf /install 
pnputil /scan-devices 

安装缓解驱动程序后,GPU 将在 Nvidia T4_base - 被卸载下以正常状态列出:

Get-PnpDevice  | select status, class, friendlyname, instanceid | findstr /i /c:"nvidia"
OK       Nvidia T4_base - Dismounted               PCI\VEN_10DE&DEV_1EB8&SUBSYS_12A210DE&REV_A1\4&32EEF88F&0&0000 
OK       Nvidia T4_base - Dismounted               PCI\VEN_10DE&DEV_1EB8&SUBSYS_12A210DE&REV_A1\4&3569C1D3&0&0000

步骤 4:重复步骤 1 到 3

对故障转移群集中的每个节点重复步骤 1 到 3。

重要

未将启用了 GPU 的虚拟机添加到 Windows Server 2019、Windows Server 2022 或 Azure 本地的故障转移群集中。

安装或更新 AKS

请参阅使用 PowerShell 或使用 Windows Admin Center 安装或更新 Arc 启用的 AKS 快速入门的 AKS 快速入门。

使用启用了 GPU 的节点池创建新的工作负荷群集

目前,使用启用了 GPU 的节点池仅适用于 Linux 节点池。

New-AksHciCluster -Name "gpucluster" -nodePoolName "gpunodepool" -nodeCount 2 -osType linux -nodeVmSize Standard_NK6 

安装工作负荷群集后,运行以下命令以获取 Kubeconfig:

Get-AksHciCredential -Name gpucluster

确认可以计划 GPU

创建 GPU 节点池后,确认可以在 Kubernetes 中调度 GPU。 首先,使用 kubectl get nodes 命令列出群集中的节点:

kubectl get nodes
NAME             STATUS  ROLES                 AGE   VERSION
moc-l9qz36vtxzj  Ready   control-plane,master  6m14s  v1.22.6
moc-lhbkqoncefu  Ready   <none>                3m19s  v1.22.6
moc-li87udi8l9s  Ready   <none>                3m5s  v1.22.6

现在,使用 kubectl describe node 命令来确认 GPU 可以被调度。 在“容量”部分中,GPU 应显示为 nvidia.com/gpu:1

kubectl describe <node> | findstr "gpu" 

输出应显示各个工作器节点中的 GPU,如下所示:

         nvidia.com/gpu.compute.major=7
         nvidia.com/gpu.compute.minor=5
         nvidia.com/gpu.count=1
         nvidia.com/gpu.family=turing
         nvidia.com/gpu.machine=Virtual-Machine
         nvidia.com/gpu.memory=16384
         nvidia.com/gpu.product=Tesla-T4
Annotations:    cluster.x-k8s.io/cluster-name: gpucluster
                cluster.x-k8s.io/machine: gpunodepool-md-58d9b96dd9-vsdbl
                cluster.x-k8s.io/owner-name: gpunodepool-md-58d9b96dd9
         nvidia.com/gpu:   1
         nvidia.com/gpu:   1
ProviderID:         moc://gpunodepool-97d9f5667-49lt4
kube-system         gpu-feature-discovery-gd62h       0 (0%)    0 (0%)   0 (0%)      0 (0%)     7m1s
         nvidia.com/gpu   0     0

运行利用 GPU 的任务

完成前面的步骤后,创建新的 YAML 文件进行测试;例如,gpupod.yaml。 将以下 YAML 复制并粘贴到名为 gpupod.yaml的新文件中,然后保存该文件:

apiVersion: v1
kind: Pod
metadata:
  name: cuda-vector-add
spec:
  restartPolicy: OnFailure
  containers:
  - name: cuda-vector-add
    image: "k8s.gcr.io/cuda-vector-add:v0.1"
    resources:
      limits:
        nvidia.com/gpu: 1

运行以下命令来部署示例应用程序:

kubectl apply -f gpupod.yaml

验证该 Pod 是否已启动、运行完成,并已分配 GPU:

kubectl describe pod cuda-vector-add | findstr 'gpu'

上一个命令应显示分配的一个 GPU:

nvidia.com/gpu: 1
nvidia.com/gpu: 1

检查 Pod 的日志文件,查看测试是否已通过:

kubectl logs cuda-vector-add

下面是上一命令的示例输出:

[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done

如果在调用驱动程序时收到版本不匹配错误,例如“CUDA 驱动程序版本不足以用于 CUDA 运行时版本”,请查看 NVIDIA 驱动程序矩阵兼容性图表

常见问题

在升级启用了 GPU 的节点池期间会发生什么情况?

升级包含 GPU 的节点池遵循用于常规节点池的相同滚动升级模式。 要在新的 VM 中成功创建启用了 GPU 的节点池,物理主机上需要有一个或多个物理 GPU 可供使用,以确保设备的成功分配。 这种可用性确保了当 Kubernetes 在此升级节点上调度 Pod 时,你的应用程序可以继续运行。

在升级之前:

  1. 规划升级期间的停机时间。
  2. 如果运行的是 Standard_NK6,则每个物理主机都有一个额外的 GPU;如果运行的是 Standard_NK12,则有 2 个额外的 GPU。 如果以完整容量运行,并且没有额外的 GPU,我们建议在升级前将节点池缩减到单个节点,然后在升级成功后纵向扩展。

如果在升级期间物理计算机上没有额外的物理 GPU,会发生什么情况?

如果在群集上触发升级,而无需额外的 GPU 资源来促进滚动升级,则升级过程会挂起,直到 GPU 可用。 如果以完整容量运行,并且没有额外的 GPU,我们建议在升级前将节点池缩减到单个节点,然后在升级成功后纵向扩展。

后续步骤