一、裸机摆设
裸机中要使用上 GPU 需要安装以下组件:
- GPU Driver
- CUDA Toolkit
二者的关系如 NVIDIA 官网上的这个图所示:
GPU Driver 包括了 GPU 驱动和 CUDA 驱动,CUDA Toolkit 则包含了 CUDA Runtime。
GPU 作为一个 PCIE 设备,只要安装好之后,在系统中就可以通过 lspci 命令查看到,先确认呆板上是否有 GPU:
可以看到,该设备有1张 Tesla V100 GPU。
安装 GPU Driver
首先到 NVIDIA 驱动下载 下载对应的显卡驱动:
复制下载链接
- wget https://cn.download.nvidia.com/tesla/550.144.03/nvidia-driver-local-repo-ubuntu2204-550.144.03_1.0-1_amd64.deb
复制代码- sudo apt update && sudo apt upgrade -y
- sudo apt install -y build-essential dkms
- sudo dpkg -i nvidia-driver-local-repo-ubuntu2204-550.144.03_1.0-1_amd64.deb
复制代码- 安装 NVIDIA 驱动:
- sudo apt install -y nvidia-driver-550
- nvidia-smi
复制代码
至此,我们就安装好 GPU 驱动了,系统也能正常辨认到 GPU。
这里显示的 CUDA 版本表示当前驱动最大支持的 CUDA 版本。
安装 CUDA Toolkit
对于深度学习步伐,一般都要依靠 CUDA 情况,因此需要在呆板上安装 CUDA Toolkit。
也是到 NVIDIA CUDA Toolkit 下载 下载对应的安装包,选择操纵系统和安装方式即可
- wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.debsudo
- dpkg -i cuda-keyring_1.1-1_all.debsudo
- apt-get updatesudo
- apt-get -y install cuda-toolkit-12-4
复制代码 配置下 PATH
测试
整个调用链:
代码测试:
- import torch
- def 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):.2f} GB")
- print(f"设备 {i} 的显存当前使用量: {torch.cuda.memory_allocated(i) / (1024 ** 3):.2f} GB")
- print(f"设备 {i} 的显存最大使用量: {torch.cuda.memory_reserved(i) / (1024 ** 3):.2f} GB")
- else:
- print("CUDA 设备不可用。")
- except Exception as e:
- print(f"检查 PyTorch CUDA 环境时出现错误: {e}")
- if __name__ == "__main__":
- check_cuda_with_pytorch()
复制代码
二、Docker 情况
调用链从 containerd --> runC 变成 containerd --> nvidia-container-runtime --> runC 。
nvidia-container-runtime 在中间拦截了容器 spec,就可以把 gpu 相关配置添加进去,再传给 runC 的 spec 内里就包含 gpu 信息了。
- Ubuntu 上安装 Docker:
- 30 sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
- 31 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- 32 echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- 33 apt update
- 34 apt install -y docker-ce docker-ce-cli containerd.io
- 35 systemctl enable docker
复制代码 安装 nvidia-container-toolkit
- # 1. Configure the production repository
- 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
- # Optionally, configure the repository to use experimental packages
- sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/nvidia-container-toolkit.list
- # 2. Update the packages list from the repository
- sudo apt-get update
- # 3. Install the NVIDIA Container Toolkit packages
- sudo apt-get install -y nvidia-container-toolkit
复制代码 配置使用该 runtime
支持 Docker, Containerd, CRI-O, Podman 等 CRI。
详细见官方文档 container-toolkit#install-guide
这里以 Docker 为例举行配置:
旧版本需要手动在 /etc/docker/daemon.json 中增加配置,指定使用 nvidia 的 runtime。
- {
- "runtimes": {
- "nvidia": {
- "args": [],
- "path": "nvidia-container-runtime"
- }
- }
- }
复制代码 新版 toolkit 带了一个nvidia-ctk 工具,执行以下命令即可一键配置:
- sudo nvidia-ctk runtime configure --runtime=docker
复制代码 然后重启 Docker 即可
Docker 情况中的 CUDA 调用:
从图中可以看到,CUDA Toolkit 跑到容器里了,因此宿主机上不需要再安装 CUDA Toolkit。
使用一个带 CUDA Toolkit 的镜像即可。
最后我们启动一个 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 命令
- docker run --rm --gpus all nvidia/cuda:12.0.1-runtime-ubuntu22.04 nvidia-smi
复制代码 正常情况下应该是可以打印出容器中的 GPU 信息:
三、 k8s 情况
在 k8s 情况中使用 GPU,则需要在集群中摆设以下组件:
gpu-device-plugin 用于管理 GPU,device-plugin 以 DaemonSet 方式运行到集群各个节点,以感知节点上的 GPU 设备,从而让 k8s 能够对节点上的 GPU 设备举行管理。
gpu-exporter:用于监控 GPU
安装 device-plugin
device-plugin 一般由对应的 GPU 厂家提供,比如 NVIDIA 的 k8s-device-plugin
安装其实很简朴,将对应的 yaml apply 到集群即可。
- kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.15.0/deployments/static/nvidia-device-plugin.yml
复制代码 device-plugin 启动之后,会感知节点上的 GPU 设备并上报给 kubelet,终极由 kubelet 提交到 kube-apiserver。
因此我们可以在 Node 可分配资源中看到 GPU,就像这样:
- 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 资源
安装 GPU 监控
安装 DCCM exporter 结合 Prometheus 输出 GPU 资源监控信息。
- helm repo add gpu-helm-charts \
- https://nvidia.github.io/dcgm-exporter/helm-charts
-
- helm repo update
-
-
- helm install \
- --generate-name \
- gpu-helm-charts/dcgm-exporter
复制代码 查看 metrics
- curl -sL http://127.0.0.1:8080/metrics
- # HELP DCGM_FI_DEV_SM_CLOCK SM clock frequency (in MHz).# TYPE DCGM_FI_DEV_SM_CLOCK gauge# HELP DCGM_FI_DEV_MEM_CLOCK Memory clock frequency (in MHz).# TYPE DCGM_FI_DEV_MEM_CLOCK gauge# HELP DCGM_FI_DEV_MEMORY_TEMP Memory temperature (in C).# TYPE DCGM_FI_DEV_MEMORY_TEMP gauge
- ...
- 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。
- 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 # requesting 1 GPU
复制代码 这样 kueb-scheduler 在调度该 Pod 时就会思量到这个情况,将其调度到有 GPU 资源的节点。
启动后,查看日志,正常应该会打印 测试通过的信息,k8s 情况中就可以使用 GPU 了。
- 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
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |