GPU 配置指南 本文以常见的NVIDIA GPU为例,介绍在Linux系统中如何配置GPU环境。其他厂商的GPU理论上流程相同。
环境要求:
裸机环境 :安装对应的GPU Driver和CUDA Toolkit。
Docker环境 :需额外安装nvidia-container-toolkit
并配置Docker使用NVIDIA runtime。
K8s环境 :需安装对应的device-plugin,使kubelet能够感知GPU设备,进行管理。
注:一般在K8s中使用gpu-operator进行安装,本文为手动安装各组件以理解其作用。
1. 裸机环境 在裸机环境中使用GPU需要安装以下组件:
GPU Driver :包括GPU驱动和CUDA驱动。
CUDA Toolkit :包含CUDA Runtime。
检查GPU设备 使用lspci
命令检查是否有GPU:
GPU 作为一个 PCIE 设备,只要安装好之后,在系统中就可以通过 lspci 命令查看到,先确认机器上是否有 GPU:
1 2 3 root@test :~# lspci|grep NVIDIA 3b:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) 86:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)
可以看到,该设备有两张 Tesla T4 GPU。
安装驱动 从NVIDIA官网 下载驱动,运行.run
文件安装:
最终下载得到的是一个.run
文件,例如 NVIDIA-Linux-x86_64-550.54.14.run
1 sh NVIDIA-Linux-x86_64-550.54.14.run
接下来会进入图形化界面,一直选择 yes / ok
使用nvidia-smi
命令检查安装是否成功。
如果出现显卡信息则是安装成功,就像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 root@test :~ nvidia-smi Wed Jul 10 05:41:52 2024 +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 535.161.08 Driver Version: 535.161.08 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla T4 On | 00000000:3B:00.0 Off | 0 | | N/A 51C P0 29W / 70W | 12233MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ | 1 Tesla T4 On | 00000000:86:00.0 Off | 0 | | N/A 49C P0 30W / 70W | 6017MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | +---------------------------------------------------------------------------------------+
至此,我们就安装好 GPU 驱动了,系统也能正常识别到 GPU。
这里显示的 CUDA 版本表示当前驱动最大支持的 CUDA 版本。
对于深度学习程序,一般都要依赖 CUDA
环境,因此需要在机器上安装 CUDA Toolkit
。
和安装驱动类似,也是一个 .run 文件
1 2 3 4 5 wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.runsudo sh cuda_12.2.0_535.54.03_linux.run
注意:之前安装过驱动了,这里就不再安装驱动,仅安装 CUDA Toolkit 相关组件
安装完成后输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 root@iZbp15lv2der847tlwkkd3Z:~# sudo sh cuda_12.2.0_535.54.03_linux.run =========== = Summary = =========== Driver: Installed Toolkit: Installed in /usr/local/cuda-12.2/ Please make sure that - PATH includes /usr/local/cuda-12.2/bin - LD_LIBRARY_PATH includes /usr/local/cuda-12.2/lib64, or, add /usr/local/cuda-12.2/lib64 to /etc/ld.so.conf and run ldconfig as root To uninstall the CUDA Toolkit, run cuda-uninstaller in /usr/local/cuda-12.2/bin To uninstall the NVIDIA Driver, run nvidia-uninstall Logfile is /var/log/cuda-installer.log
根据提示配置环境变量PATH
和LD_LIBRARY_PATH
。
1 2 export PATH=/usr/local/cuda-12.2/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH
确认安装:
输出如下所示:
1 2 3 4 5 6 root@iZbp15lv2der847tlwkkd3Z:~*# nvcc -V* nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2023 NVIDIA Corporation Built on Tue_Jun_13_19:16:58_PDT_2023 Cuda compilation tools, release 12.2, V12.2.91 Build cuda_12.2.r12.2/compiler.32965470_0
测试CUDA环境 使用PyTorch检测CUDA环境是否正常,check_cuda_pytorch.py
内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import torchdef check_cuda_with_pytorch (): """检查 PyTorch CUDA 环境是否正常工作""" try : print ("检查 PyTorch CUDA 环境:" ) if torch.cuda.is_available(): print (f"CUDA 设备可用,当前 CUDA 版本是: {torch.version.cuda} " ) print (f"PyTorch 版本是: {torch.__version__} " ) print (f"检测到 {torch.cuda.device_count()} 个 CUDA 设备。" ) for i in range (torch.cuda.device_count()): print (f"设备 {i} : {torch.cuda.get_device_name(i)} " ) print (f"设备 {i} 的显存总量: {torch.cuda.get_device_properties(i).total_memory / (1024 ** 3 ):.2 f} GB" ) print (f"设备 {i} 的显存当前使用量: {torch.cuda.memory_allocated(i) / (1024 ** 3 ):.2 f} GB" ) print (f"设备 {i} 的显存最大使用量: {torch.cuda.memory_reserved(i) / (1024 ** 3 ):.2 f} GB" ) else : print ("CUDA 设备不可用。" ) except Exception as e: print (f"检查 PyTorch CUDA 环境时出现错误: {e} " )if __name__ == "__main__" : check_cuda_with_pytorch()
先安装下 torch
运行一下
1 python3 check_cuda_pytorch.py
正常输出应该是这样的:
1 2 3 4 5 6 7 8 检查 PyTorch CUDA 环境: CUDA 设备可用,当前 CUDA 版本是: 12.1 PyTorch 版本是: 2.3.0+cu121 检测到 1 个 CUDA 设备。 设备 0: Tesla T4 设备 0 的显存总量: 14.75 GB 设备 0 的显存当前使用量: 0.00 GB 设备 0 的显存最大使用量: 0.00 GB
2. Docker 环境 在Docker环境中使用GPU的步骤如下:
安装nvidia-container-toolkit
。
配置Docker使用NVIDIA runtime。
启动容器时增加--gpu
参数。
NVIDIA Container Toolkit 的主要作用是将 NVIDIA GPU 设备挂载到容器中。
兼容生态系统中的任意容器运行时,docker、containerd、cri-o 等。
NVIDIA 官方安装文档:nvidia-container-toolkit-install-guide
对于 Ubuntu 系统,安装命令如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/nvidia-container-toolkit.listsudo apt-get updatesudo apt-get install -y nvidia-container-toolkit
配置使用该 runtime 支持 Docker, Containerd, CRI-O, Podman 等 CRI。
具体见官方文档 nvidia-container-toolkit-install-guide
这里以 Docker 为例进行配置:
旧版本需要手动在 /etc/docker/daemon.json
中增加配置,指定使用 nvidia 的 runtime。
1 2 3 4 5 6 "runtimes" : { "nvidia" : { "args" : [ ] , "path" : "nvidia-container-runtime" } }
新版 toolkit 带了一个nvidia-ctk
工具,执行以下命令即可一键配置:
1 sudo nvidia-ctk runtime configure --runtime=docker
然后重启 Docker 即可
1 sudo systemctl restart docker
测试 最后我们启动一个 Docker 容器进行测试,其中命令中增加 --gpu
参数来指定要分配给容器的 GPU。
--gpu
参数可选值:
--gpus all
:表示将所有 GPU 都分配给该容器
--gpus "device=<id>[,<id>...]"
:对于多 GPU 场景,可以通过 id 指定分配给容器的 GPU,例如 –gpu “device=0” 表示只分配 0 号 GPU 给该容器
GPU 编号则是通过nvidia-smi
命令进行查看
这里我们直接使用一个带 cuda 的镜像来测试,启动该容器并执行nvidia-smi
命令
1 docker run --rm --gpus all nvidia/cuda:12.0.1-runtime-ubuntu22.04 nvidia-smi
3. K8s 环境 在K8s中使用GPU需部署以下组件:
gpu-device-plugin :管理GPU设备。
gpu-exporter :监控GPU使用情况。
安装device-plugin 从NVIDIA k8s-device-plugin 下载对应的yaml文件,部署至集群:
1 kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.15.0/deployments/static/nvidia-device-plugin.yml
就像这样
1 2 3 root@test :~# kgo get po -l app=nvidia-device-plugin-daemonset NAME READY STATUS RESTARTS AGE nvidia-device-plugin-daemonset-7nkjw 1/1 Running 0 10m
检查节点资源:
1 kubectl describe node <node_name> | grep Capacity -A7
device-plugin 启动之后,会感知节点上的 GPU 设备并上报给 kubelet,最终由 kubelet 提交到 kube-apiserver。
因此我们可以在 Node 可分配资源中看到 GPU,就像这样:
1 2 3 4 5 6 7 8 9 root@test :~# k describe node test |grep Capacity -A7 Capacity: cpu: 48 ephemeral-storage: 460364840Ki hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 98260824Ki nvidia.com/gpu: 2 pods: 110
可以看到,除了常见的 cpu、memory 之外,还有nvidia.com/gpu
, 这个就是 GPU 资源,数量为 2 说明我们有两张 GPU。
安装GPU监控 使用DCGM exporter 结合Prometheus监控GPU资源:
1 2 helm repo add gpu-helm-charts https://nvidia.github.io/dcgm-exporter/helm-charts helm install --generate-name gpu-helm-charts/dcgm-exporter
查看 metrics
1 2 3 4 5 6 7 curl -sL http://127.0.0.1:8080/metrics ... DCGM_FI_DEV_SM_CLOCK{gpu="0" , UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52" ,container="" ,namespace="" ,pod="" } 139 DCGM_FI_DEV_MEM_CLOCK{gpu="0" , UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52" ,container="" ,namespace="" ,pod="" } 405 DCGM_FI_DEV_MEMORY_TEMP{gpu="0" , UUID="GPU-604ac76c-d9cf-fef3-62e9-d92044ab6e52" ,container="" ,namespace="" ,pod="" } 9223372036854775794 ...
测试 在 k8s 创建 Pod 要使用 GPU 资源很简单,和 cpu、memory 等常规资源一样,在 resource 中 申请即可。
比如,下面这个 yaml 里面我们就通过 resource.limits 申请了该 Pod 要使用 1 个 GPU。
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: restartPolicy: Never containers: - name: cuda-container image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2 resources: limits: nvidia.com/gpu: 1
这样 kueb-scheduler 在调度该 Pod 时就会考虑到这个情况,将其调度到有 GPU 资源的节点。
启动后,查看日志,正常应该会打印 测试通过的信息。
1 2 3 4 5 6 7 kubectl logs gpu-pod [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
5. 小结 本文主要分享了在裸机、Docker 环境、k8s 环境中如何使用 GPU。
对于裸机环境,只需要安装对应的 GPU Driver 即可。
对应 Docker 环境,需要额外安装 nvidia-container-toolkit
并配置 docker 使用 nvidia runtime。
对应 k8s 环境,需要额外安装对应的 device-plugin
使得 kubelet 能够感知到节点上的 GPU 设备,以便 k8s 能够进行 GPU 管理。
现在一般都是在 k8s 环境中使用,为了简化安装步骤, NVIDIA 也提供了 gpu-operator
来简化安装部署,后续分享一下如何使用 gpu-operator
来快速安装。
参考资料