如何搭建一个GPU训练集群——把手教你从零开始
GPU集群搭建指南 核心概念 GPU集群是将多台GPU服务器互联组成的计算系统,用于分布式训练大模型。典型架构包含: 1个管理节点(Master Node)负责任务调度 多个工作节点(Worker Node)执行计算任务 高速网络(InfiniBand/RoCE)实现节点间通信 共享存储系统存放数据和模型 硬件准备 建议配置: 每节点8张NVIDIA A100 80G显卡 AMD EPYC或Int
大家好,我是V哥。
话说AI运维工程师的成长路径,GPU集群到底怎么搭?公司让我搞这个,我连从哪下手都不知道啊!
行,今天V哥就把这事儿给你掰开了、揉碎了讲清楚。不整那些高大上的概念轰炸,就用大白话,带你一步步把GPU训练集群搭起来。
先说好,这篇文章适合谁:
- 公司刚买了几台GPU服务器,让你"整一下"的运维兄弟
- 想自己攒个小集群玩深度学习的技术爱好者
- 面试前想搞清楚这套东西到底是啥的求职者
马上开整。
一、先搞懂:GPU集群到底是个啥?
在动手之前,V哥先给你打个比方,把概念捋顺。
1. 什么是GPU集群?
你可以把它理解成一个**“GPU网吧”**。
单台服务器就像一台电脑,上面插着1-8张显卡(GPU)。但训练大模型的时候,一台机器不够用,你就需要把好几台机器连起来,让它们一起干活。
这堆机器连在一起,就叫集群(Cluster)。
2. 为什么要搞集群?
很简单,大模型太胖了,一张卡装不下。
举个例子:
- 训练一个7B参数的大模型,至少需要4张A100(80G显存)
- 训练一个70B的模型,可能需要几十张卡一起上
- 要是训练GPT-4那种级别的……别想了,那是几千张卡的事儿
所以,集群的本质就是把多张卡、多台机器的算力"拧成一股绳"。
3. 集群里的几个关键角色
V哥画个简单的图给你:
┌─────────────────────────────────────────────────┐
│ 集群架构 │
├─────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ │
│ │ Master │ ← 管理节点,负责调度任务 │
│ │ Node │ │
│ └────┬────┘ │
│ │ │
│ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Worker │ │ Worker │ │ Worker │ │
│ │ Node 1 │ │ Node 2 │ │ Node 3 │ │
│ │ GPU x 8 │ │ GPU x 8 │ │ GPU x 8 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ ↑ ↑ ↑ │
│ └────────────┴────────────┘ │
│ 高速网络互联 │
│ (InfiniBand / RoCE) │
│ │
└─────────────────────────────────────────────────┘
用人话解释一下:
| 角色 | 干啥的 | 生活中的比喻 |
|---|---|---|
| Master Node | 管理调度,分配任务 | 包工头 |
| Worker Node | 真正干活的,跑训练任务 | 搬砖工人 |
| GPU | 计算核心,算力担当 | 工人手里的电钻 |
| 高速网络 | 让机器之间快速通信 | 工地上的对讲机 |
| 共享存储 | 存放数据和模型 | 工地上的材料仓库 |
二、搭建前的准备工作
1. 硬件清单
V哥假设你有3台GPU服务器,配置如下:
| 项目 | 配置 |
|---|---|
| GPU | 每台8张 NVIDIA A100 80G(或4090、H100都行) |
| CPU | AMD EPYC 7742 或 Intel Xeon |
| 内存 | 512GB 以上 |
| 系统盘 | 1TB NVMe SSD |
| 数据盘 | 4TB NVMe SSD(存数据集) |
| 网卡 | 100Gbps InfiniBand 或 RoCE |
没这么豪华的配置?没关系!
V哥后面也会讲怎么用几张消费级显卡(比如4090)搭个小集群练手。原理是一样的,只是规模不同。
2. 网络规划
这个很重要,很多人翻车就翻在网络上。
网络架构:
┌──────────────────────────────────────────┐
│ 管理网络(1Gbps) │
│ 用于SSH登录、系统管理、监控等 │
│ │
│ Master ──── Worker1 ──── Worker2 ──── │
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
│ 计算网络(100Gbps) │
│ 用于GPU之间通信、分布式训练 │
│ │
│ Worker1 ═══ Worker2 ═══ Worker3 ═══ │
│ InfiniBand / RoCE │
└──────────────────────────────────────────┘
┌──────────────────────────────────────────┐
│ 存储网络(25Gbps) │
│ 用于访问共享存储(NFS/Lustre) │
│ │
│ 所有节点 ──── 存储服务器 │
└──────────────────────────────────────────┘
V哥划重点:
- 管理网络和计算网络一定要分开,不然训练的时候SSH都连不上
- 计算网络带宽越大越好,这是分布式训练的命脉
- 预算有限的话,至少保证计算网络用万兆网(10Gbps)
3. 软件版本选择
V哥推荐的组合(截至2024年):
| 软件 | 版本 | 说明 |
|---|---|---|
| 操作系统 | Ubuntu 22.04 LTS | 稳定,驱动兼容性好 |
| NVIDIA Driver | 535.x 或更高 | 匹配CUDA版本 |
| CUDA | 12.1 | 主流框架都支持 |
| cuDNN | 8.9.x | 深度学习加速库 |
| Docker | 24.x | 容器运行时 |
| NVIDIA Container Toolkit | 最新版 | 让Docker能用GPU |
| Kubernetes | 1.28.x | 容器编排 |
| Python | 3.10 | PyTorch/TensorFlow兼容性好 |
三、实操:一步步搭建集群
第一步:操作系统安装与基础配置
所有节点都要做的事情:
1.1 安装Ubuntu 22.04
这个就不赘述了,用U盘做个启动盘,装就完事儿。
注意几点:
- 分区时给
/至少200GB /home或单独挂载数据盘给足空间- 安装时选择OpenSSH Server
1.2 配置静态IP和主机名
编辑网络配置:
sudo vim /etc/netplan/00-installer-config.yaml
内容示例:
network:
version: 2
ethernets:
eno1: # 管理网络网卡
addresses:
- 192.168.1.10/24
gateway4: 192.168.1.1
nameservers:
addresses:
- 8.8.8.8
- 114.114.114.114
ens10f0: # 计算网络网卡(InfiniBand/RoCE)
addresses:
- 10.0.0.10/24
应用配置:
sudo netplan apply
设置主机名(三台分别设置):
# 第一台
sudo hostnamectl set-hostname master
# 第二台
sudo hostnamectl set-hostname worker1
# 第三台
sudo hostnamectl set-hostname worker2
1.3 配置hosts文件
所有节点都要配置,让它们能通过主机名互相找到:
sudo vim /etc/hosts
添加:
192.168.1.10 master
192.168.1.11 worker1
192.168.1.12 worker2
# 计算网络
10.0.0.10 master-ib
10.0.0.11 worker1-ib
10.0.0.12 worker2-ib
1.4 配置SSH免密登录
在master节点上:
# 生成密钥
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
# 复制到所有节点(包括自己)
ssh-copy-id master
ssh-copy-id worker1
ssh-copy-id worker2
测试一下:
ssh worker1 "hostname"
# 如果输出 worker1,就成功了
1.5 关闭防火墙和SELinux(实验环境)
# 关闭防火墙
sudo systemctl stop ufw
sudo systemctl disable ufw
# Ubuntu默认没有SELinux,如果有的话:
sudo setenforce 0
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
V哥提醒: 生产环境别这么干,要配置好防火墙规则。实验环境为了省事儿可以先关掉。
第二步:安装NVIDIA驱动和CUDA
这一步是重头戏,也是最容易翻车的地方。V哥教你最稳的方法。
2.1 安装依赖
sudo apt update
sudo apt install -y build-essential dkms
2.2 禁用开源驱动nouveau
sudo bash -c "echo 'blacklist nouveau' >> /etc/modprobe.d/blacklist.conf"
sudo bash -c "echo 'options nouveau modeset=0' >> /etc/modprobe.d/blacklist.conf"
sudo update-initramfs -u
sudo reboot
2.3 安装NVIDIA驱动
方法一:使用官方仓库(推荐)
# 添加仓库
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
# 查看可用驱动版本
ubuntu-drivers devices
# 安装推荐版本
sudo apt install -y nvidia-driver-535
# 重启
sudo reboot
方法二:使用runfile(更可控)
# 下载驱动(去官网找对应版本)
wget https://us.download.nvidia.com/XFree86/Linux-x86_64/535.129.03/NVIDIA-Linux-x86_64-535.129.03.run
# 安装
sudo chmod +x NVIDIA-Linux-x86_64-535.129.03.run
sudo ./NVIDIA-Linux-x86_64-535.129.03.run --silent --dkms
# 重启
sudo reboot
2.4 验证驱动安装
nvidia-smi
看到类似这样的输出就成功了:
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 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. |
|===============================+======================+======================|
| 0 NVIDIA A100-SXM... On | 00000000:07:00.0 Off | 0 |
| N/A 30C P0 52W / 400W | 0MiB / 81920MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
2.5 安装CUDA Toolkit
# 下载CUDA(注意版本要和驱动匹配)
wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda_12.1.1_530.30.02_linux.run
# 安装(注意:不要再装驱动了,选择不安装Driver)
sudo ./cuda_12.1.1_530.30.02_linux.run --silent --toolkit --override
# 配置环境变量
echo 'export PATH=/usr/local/cuda-12.1/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
验证:
nvcc --version
# 应该显示 Cuda compilation tools, release 12.1
2.6 安装cuDNN
# 去NVIDIA官网下载cuDNN(需要注册账号)
# 假设下载了 cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz
tar -xvf cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz
sudo cp cudnn-linux-x86_64-8.9.7.29_cuda12-archive/include/* /usr/local/cuda-12.1/include/
sudo cp cudnn-linux-x86_64-8.9.7.29_cuda12-archive/lib/* /usr/local/cuda-12.1/lib64/
sudo chmod a+r /usr/local/cuda-12.1/include/cudnn*.h
sudo chmod a+r /usr/local/cuda-12.1/lib64/libcudnn*
V哥小提示: 以上步骤在所有Worker节点都要做!建议写成脚本,批量执行。
第三步:安装Docker和NVIDIA Container Toolkit
有了Docker,以后跑训练任务就方便多了,不用在每台机器上装一堆Python环境。
3.1 安装Docker
# 卸载旧版本
sudo apt remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 添加仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
# 把当前用户加入docker组(免sudo)
sudo usermod -aG docker $USER
newgrp docker
3.2 安装NVIDIA Container Toolkit
这玩意儿是让Docker能调用GPU的关键。
# 添加仓库
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
# 安装
sudo apt update
sudo apt install -y nvidia-container-toolkit
# 配置Docker使用NVIDIA运行时
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
3.3 验证GPU Docker
docker run --rm --gpus all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi
如果能看到GPU信息,恭喜你,Docker + GPU环境搞定了!
第四步:配置共享存储(NFS)
训练数据和模型需要所有节点都能访问,最简单的方案就是NFS。
4.1 在Master节点上配置NFS服务端
# 安装NFS服务
sudo apt install -y nfs-kernel-server
# 创建共享目录
sudo mkdir -p /data/shared
sudo chown -R nobody:nogroup /data/shared
sudo chmod 777 /data/shared
# 配置导出
sudo vim /etc/exports
添加以下内容:
/data/shared 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
启动服务:
sudo exportfs -ra
sudo systemctl restart nfs-kernel-server
sudo systemctl enable nfs-kernel-server
4.2 在Worker节点上挂载NFS
# 安装NFS客户端
sudo apt install -y nfs-common
# 创建挂载点
sudo mkdir -p /data/shared
# 挂载
sudo mount master:/data/shared /data/shared
# 验证
df -h | grep shared
# 设置开机自动挂载
echo "master:/data/shared /data/shared nfs defaults 0 0" | sudo tee -a /etc/fstab
现在,你在任何一个节点的 /data/shared 目录下放文件,其他节点都能看到了。
第五步:安装Kubernetes(K8s)
K8s是集群管理的核心,有了它,你就能像管理一台电脑一样管理整个集群。
5.1 所有节点的准备工作
# 关闭swap(K8s要求)
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
# 配置内核参数
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
5.2 安装kubelet、kubeadm、kubectl
所有节点执行:
# 添加K8s仓库
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 安装
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
# 配置containerd使用systemd cgroup
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
5.3 初始化Master节点
只在Master节点执行:
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.1.10
初始化成功后,会输出一个 kubeadm join 命令,一定要保存好!
配置kubectl:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5.4 安装网络插件(Flannel)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
5.5 Worker节点加入集群
在Worker节点执行之前保存的join命令:
sudo kubeadm join 192.168.1.10:6443 --token xxxx \
--discovery-token-ca-cert-hash sha256:xxxx
5.6 验证集群状态
回到Master节点:
kubectl get nodes
应该看到:
NAME STATUS ROLES AGE VERSION
master Ready control-plane 10m v1.28.0
worker1 Ready <none> 5m v1.28.0
worker2 Ready <none> 5m v1.28.0
第六步:安装NVIDIA GPU Operator
这是让K8s能识别和调度GPU的关键组件。
6.1 安装Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
6.2 安装GPU Operator
# 添加NVIDIA Helm仓库
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
# 安装GPU Operator
helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--set driver.enabled=false # 因为我们已经手动装了驱动
等待几分钟,所有Pod都Running后:
kubectl get pods -n gpu-operator
6.3 验证GPU资源
kubectl describe nodes worker1 | grep nvidia.com/gpu
应该能看到:
nvidia.com/gpu: 8
这就说明K8s已经能识别到8张GPU了!
第七步:跑一个测试任务
终于到了激动人心的时刻,让我们跑一个GPU测试任务。
7.1 创建测试Pod
创建文件 gpu-test.yaml:
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
restartPolicy: Never
containers:
- name: cuda-container
image: nvidia/cuda:12.1.1-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1 # 申请1张GPU
运行:
kubectl apply -f gpu-test.yaml
kubectl logs gpu-test
能看到GPU信息就成功了!
7.2 跑一个真正的训练任务
创建 pytorch-test.yaml:
apiVersion: v1
kind: Pod
metadata:
name: pytorch-train
spec:
restartPolicy: Never
containers:
- name: pytorch
image: pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
command:
- python
- -c
- |
import torch
print(f"PyTorch version: {torch.__version__}")
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"GPU count: {torch.cuda.device_count()}")
print(f"GPU name: {torch.cuda.get_device_name(0)}")
# 简单的矩阵运算测试
x = torch.randn(10000, 10000).cuda()
y = torch.randn(10000, 10000).cuda()
z = torch.mm(x, y)
print(f"Matrix multiplication done! Result shape: {z.shape}")
resources:
limits:
nvidia.com/gpu: 1
volumeMounts:
- name: shared-data
mountPath: /data
volumes:
- name: shared-data
nfs:
server: master
path: /data/shared
运行:
kubectl apply -f pytorch-test.yaml
kubectl logs -f pytorch-train
四、进阶:分布式训练配置
如果你想让多张卡、多台机器一起训练,还需要一些额外配置。
1. 安装Kubeflow Training Operator
kubectl apply -k "github.com/kubeflow/training-operator/manifests/overlays/standalone"
2. 提交一个PyTorchJob(多GPU分布式训练)
创建 distributed-train.yaml:
apiVersion: "kubeflow.org/v1"
kind: PyTorchJob
metadata:
name: pytorch-distributed
spec:
pytorchReplicaSpecs:
Master:
replicas: 1
restartPolicy: OnFailure
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
command:
- python
- -m
- torch.distributed.launch
- --nproc_per_node=8
- --nnodes=3
- --node_rank=0
- --master_addr=$(MASTER_ADDR)
- --master_port=$(MASTER_PORT)
- /data/train.py
resources:
limits:
nvidia.com/gpu: 8
volumeMounts:
- name: shared-data
mountPath: /data
volumes:
- name: shared-data
nfs:
server: master
path: /data/shared
Worker:
replicas: 2
restartPolicy: OnFailure
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
command:
- python
- -m
- torch.distributed.launch
- --nproc_per_node=8
- --nnodes=3
- --master_addr=$(MASTER_ADDR)
- --master_port=$(MASTER_PORT)
- /data/train.py
resources:
limits:
nvidia.com/gpu: 8
volumeMounts:
- name: shared-data
mountPath: /data
volumes:
- name: shared-data
nfs:
server: master
path: /data/shared
五、常见坑点和解决方案
V哥踩过的坑,你就别踩了:
坑1:驱动和CUDA版本不匹配
症状:nvidia-smi 能用,但CUDA程序报错
解决:查看驱动支持的最高CUDA版本(nvidia-smi右上角显示),安装对应或更低版本的CUDA Toolkit
坑2:容器里看不到GPU
症状:宿主机nvidia-smi正常,Docker里看不到
解决:
# 检查nvidia-container-toolkit是否安装
dpkg -l | grep nvidia-container
# 重新配置Docker运行时
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
坑3:K8s节点NotReady
症状:kubectl get nodes显示NotReady
解决:
# 查看具体原因
kubectl describe node worker1
# 常见原因:containerd没配好、网络插件没装
sudo systemctl restart containerd
kubectl apply -f kube-flannel.yml
坑4:多机训练NCCL超时
症状:分布式训练卡住,报NCCL timeout
解决:
# 检查计算网络是否通畅
ping worker1-ib
# 设置NCCL环境变量
export NCCL_DEBUG=INFO
export NCCL_IB_DISABLE=0 # 如果用InfiniBand
export NCCL_SOCKET_IFNAME=ens10f0 # 指定网卡
六、总结
好了兄弟们,到这里一个完整的GPU训练集群就搭建完成了。
让我们回顾一下整个流程:
1. 操作系统安装 + 基础配置
↓
2. NVIDIA驱动 + CUDA + cuDNN
↓
3. Docker + NVIDIA Container Toolkit
↓
4. 共享存储(NFS)
↓
5. Kubernetes集群
↓
6. GPU Operator
↓
7. 训练框架(PyTorch/TensorFlow)
↓
8. 提交训练任务,开始炼丹!
V哥最后说几句:
搭建集群这事儿,看着步骤多,其实就是个熟练工种。第一次可能要折腾一两天,熟练之后半天就能搞定。
关键是要理解每一步在干什么。驱动是让系统认识GPU,Docker是让环境可复制,K8s是让资源能调度,Operator是让K8s认识GPU……
把这条链路想通了,你就不只是个"会照着文档敲命令的",而是真正理解GPU集群的人。
有问题评论区见,V哥看到都会回复。
下期咱们聊聊如何用vLLM部署大模型推理服务,不见不散!
V哥碎碎念: 这篇文章写了快8000字,够我喝三杯咖啡的。如果对你有帮助,点个赞、收个藏,让更多兄弟看到!
更多推荐


所有评论(0)