
适配NVIDIA GPU 集群,包含Gres.conf(GPU 资源定义)、slurm.conf(GPU 集群主配置)、多类 GPU 作业脚本模板(单卡 / 多卡 / 多节点),可直接替换原有配置使用,兼容你之前搭建的 Slurm 集群架构。
一、GPU 节点专属 Slurm 配置文件
1. Gres.conf(GPU 资源核心配置,控制节点编写后分发)
定义每个计算节点的 GPU 卡数、型号(可选)、设备路径,所有节点需完全一致 ,放在/usr/local/slurm/etc/下。
bash
# 控制节点执行编写
cat > /usr/local/slurm/etc/Gres.conf << EOF
# 格式:NodeName=节点名 Name=gpu Count=GPU卡数 [Type=显卡型号] [File=/dev/nvidia*]
# CPU节点无需配置,仅GPU节点配置
NodeName=slurm-com01 Name=gpu Count=4 Type=A100 File=/dev/nvidia0,/dev/nvidia1,/dev/nvidia2,/dev/nvidia3
NodeName=slurm-com02 Name=gpu Count=2 Type=3090 File=/dev/nvidia0,/dev/nvidia1
# 按需添加更多GPU节点,示例:NodeName=slurm-com03 Name=gpu Count=8 Type=V100 File=/dev/nvidia0-/dev/nvidia7
EOF
# 给配置文件赋权(控制节点)
chown slurm:slurm /usr/local/slurm/etc/Gres.conf
chmod 644 /usr/local/slurm/etc/Gres.conf
# 分发到所有节点(控制节点执行,免密已配置)
scp /usr/local/slurm/etc/Gres.conf root@slurm-login:/usr/local/slurm/etc/
scp /usr/local/slurm/etc/Gres.conf root@slurm-com01:/usr/local/slurm/etc/
scp /usr/local/slurm/etc/Gres.conf root@slurm-com02:/usr/local/slurm/etc/
关键说明 :
Type为可选字段,用于区分显卡型号(方便后续按型号调度);File为 GPU 设备实际路径,默认/dev/nvidiaX,可通过ls /dev/nvidia*在 GPU 节点验证。若所有 GPU 节点卡数相同,可简写:
NodeName=slurm-com[01-02] Name=gpu Count=4
2. slurm.conf(GPU 集群主配置,更新原有文件)
在原有slurm.conf基础上,新增 GPU 分区、开启 GPU 资源调度 ,替换原有NodeName和PartitionName段即可,其余配置保持不变。
bash
# 控制节点执行,覆盖原有slurm.conf(或手动修改对应段)
cat > /usr/local/slurm/etc/slurm.conf << EOF
# 集群基础配置(与之前一致,无需修改)
ClusterName=slurm-cluster
SlurmctldHost=slurm-master
SlurmdbdHost=slurm-master
AuthType=auth/munge
StateSaveLocation=/var/run/slurm
SlurmdSpoolDir=/var/run/slurm/slurmd
LogFile=/var/log/slurm/slurmctld.log
SlurmdLogFile=/var/log/slurm/slurmd.log
PidFile=/var/run/slurm/slurmctld.pid
SlurmdPidFile=/var/run/slurm/slurmd.pid
# 通信配置(与之前一致,无需修改)
SlurmctldPort=6817
SlurmdPort=6818
MpiDefault=none
ProctrackType=proctrack/cgroup
ReturnToService=1
# 资源调度配置(开启GPU资源识别,核心修改)
SchedulerType=sched/backfill
SelectType=select/cons_res
SelectTypeParameters=CR_Core_Memory_GPU # 新增GPU资源调度支持
# 节点配置(CPU+GPU节点分开定义,核心修改)
## CPU计算节点(按需保留,无则删除)
NodeName=slurm-cpu01 CPUs=32 MemPerCPU=8192 State=UNKNOWN NodeAddr=192.168.1.301
## GPU计算节点(核心,按实际节点修改)
NodeName=slurm-com01 CPUs=64 MemPerCPU=16384 Gres=gpu:4 State=UNKNOWN NodeAddr=192.168.1.201
NodeName=slurm-com02 CPUs=32 MemPerCPU=8192 Gres=gpu:2 State=UNKNOWN NodeAddr=192.168.1.202
# 分区配置(分CPU/GPU分区,核心修改)
## CPU分区(默认分区,无GPU需求时使用)
PartitionName=cpu-part Nodes=slurm-cpu01 Default=YES MaxTime=INFINITE State=UP
## GPU分区(高性能分区,指定GPU节点,核心)
PartitionName=gpu-part Nodes=slurm-com[01-02] Default=NO MaxTime=INFINITE State=UP AllowGroups=all
# 记账配置(与之前一致,无需修改)
AccountingStorageType=accounting_storage/slurmdbd
AccountingStorageHost=slurm-master
AccountingStoreJobComment=YES
JobAcctGatherType=jobacct_gather/cgroup
JobAcctGatherFrequency=30
EOF
# 赋权+分发(控制节点执行)
chown slurm:slurm /usr/local/slurm/etc/slurm.conf
scp /usr/local/slurm/etc/slurm.conf root@slurm-login:/usr/local/slurm/etc/
scp /usr/local/slurm/etc/slurm.conf root@slurm-com01:/usr/local/slurm/etc/
scp /usr/local/slurm/etc/slurm.conf root@slurm-com02:/usr/local/slurm/etc/
-
核心修改点 :
SelectTypeParameters=CR_Core_Memory_GPU(开启 GPU 资源调度)、节点新增Gres=gpu:X(关联 GPU 卡数)、新增gpu-partGPU 专属分区。
3. 重启 Slurm 服务使配置生效(关键步骤)
bash
# 控制节点重启调度服务
systemctl restart slurmctld
# 所有GPU计算节点重启执行服务
ssh slurm-com01 "systemctl restart slurmd"
ssh slurm-com02 "systemctl restart slurmd"
# 登录节点验证GPU配置(核心,确认生效)
sinfo -o "%N %P %G %C %m" # 查看节点GPU资源
scontrol show node slurm-com01 | grep Gres # 查看指定节点GPU详情
生效验证标准 :执行
sinfo能看到gpu-part分区,节点行显示gres:gpu:4/gres:gpu:2对应卡数。
二、GPU 节点环境前置检查(所有 GPU 节点执行)
确保 NVIDIA 驱动、CUDA 已安装,Slurm 能识别 GPU,必须执行:
bash
# 1. 验证NVIDIA驱动
nvidia-smi # 输出显卡信息、驱动版本即正常
# 2. 验证CUDA(按需,如CUDA11.8)
nvcc -V # 输出CUDA版本即正常
# 3. 修复GPU设备权限(防止Slurm用户无权限访问)
chmod 666 /dev/nvidia*
chmod 666 /dev/nvidia-caps/*
# 4. 永久修复权限(添加开机自启)
echo -e "#!/bin/bash\nchmod 666 /dev/nvidia*\nchmod 666 /dev/nvidia-caps/*" > /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
systemctl enable rc-local
三、GPU 作业脚本模板(登录节点执行,存 NFS 共享目录)
所有脚本均放在/nfs/slurm/jobs/下,赋予执行权限后用sbatch 脚本名.sh提交,支持单卡、多卡、指定显卡型号、多节点多卡等常见场景。
模板 1:单 GPU 卡基础作业(最常用,如单卡训练 / 推理)
bash
cat > /nfs/slurm/jobs/gpu_single.sh << EOF
#!/bin/bash
#SBATCH --job-name=GPU_Single # 作业名
#SBATCH --partition=gpu-part # 指定GPU分区
#SBATCH --gres=gpu:1 # 申请1块GPU(核心)
#SBATCH --cpus-per-task=8 # 每GPU绑定8核CPU(按显卡性能调整,A100建议16核,3090建议8核)
#SBATCH --mem=32G # 申请内存(按需求调整,单卡建议32G/64G)
#SBATCH --output=/nfs/slurm/jobs/gpu_single_%j.out # 输出日志
#SBATCH --error=/nfs/slurm/jobs/gpu_single_%j.err # 错误日志
#SBATCH --nodelist=slurm-com01 # 可选:指定运行节点,不写则由Slurm调度
# 激活环境(按需,如Anaconda/CUDA)
source /usr/local/anaconda3/bin/activate pytorch
export CUDA_HOME=/usr/local/cuda-11.8
export PATH=\$CUDA_HOME/bin:\$PATH
export LD_LIBRARY_PATH=\$CUDA_HOME/lib64:\$LD_LIBRARY_PATH
# 验证GPU是否可用
echo "当前节点:\$(hostname)"
echo "GPU信息:"
nvidia-smi
echo "CUDA版本:\$(nvcc -V | grep release | cut -d' ' -f5 | cut -d',' -f1)"
# 执行GPU任务(替换为你的实际命令,如python训练脚本)
cd /nfs/slurm/jobs # 切换到作业目录(NFS共享,确保文件存在)
python train.py --gpu 0 --epoch 100 --batch-size 32
EOF
# 赋权
chmod +x /nfs/slurm/jobs/gpu_single.sh
# 提交
sbatch /nfs/slurm/jobs/gpu_single.sh
模板 2:多 GPU 卡作业(单节点多卡,如 DataParallel)
bash
cat > /nfs/slurm/jobs/gpu_multi.sh << EOF
#!/bin/bash
#SBATCH --job-name=GPU_Multi # 作业名
#SBATCH --partition=gpu-part # GPU分区
#SBATCH --gres=gpu:4 # 申请4块GPU(单节点最大卡数,按实际节点调整)
#SBATCH --cpus-per-task=32 # 4GPU绑定32核CPU(每卡8核)
#SBATCH --mem=128G # 多卡建议128G/256G
#SBATCH --output=/nfs/slurm/jobs/gpu_multi_%j.out
#SBATCH --error=/nfs/slurm/jobs/gpu_multi_%j.err
# 激活环境
source /usr/local/anaconda3/bin/activate pytorch
export CUDA_HOME=/usr/local/cuda-11.8
export PATH=\$CUDA_HOME/bin:\$PATH
export LD_LIBRARY_PATH=\$CUDA_HOME/lib64:\$LD_LIBRARY_PATH
# 验证多GPU
echo "当前节点:\$(hostname)"
echo "多GPU信息:"
nvidia-smi -L # 列出所有可用GPU
# 执行多GPU任务(示例:PyTorch DataParallel)
cd /nfs/slurm/jobs
python train.py --gpu 0,1,2,3 --epoch 100 --batch-size 128 --dp True
EOF
chmod +x /nfs/slurm/jobs/gpu_multi.sh
# 提交
sbatch /nfs/slurm/jobs/gpu_multi.sh
模板 3:指定 GPU 型号作业(区分显卡,如仅用 A100)
适用于集群有多种显卡型号(如 A100+3090),需指定型号执行作业:
bash
cat > /nfs/slurm/jobs/gpu_spec_type.sh << EOF
#!/bin/bash
#SBATCH --job-name=GPU_A100 # 作业名
#SBATCH --partition=gpu-part # GPU分区
#SBATCH --gres=gpu:A100:2 # 申请2块A100显卡(核心:Type=型号:卡数)
#SBATCH --cpus-per-task=32 # 2块A100绑定32核CPU
#SBATCH --mem=64G # 内存配置
#SBATCH --output=/nfs/slurm/jobs/gpu_a100_%j.out
#SBATCH --error=/nfs/slurm/jobs/gpu_a100_%j.err
# 激活环境
source /usr/local/anaconda3/bin/activate pytorch
export CUDA_HOME=/usr/local/cuda-11.8
export PATH=\$CUDA_HOME/bin:\$PATH
export LD_LIBRARY_PATH=\$CUDA_HOME/lib64:\$LD_LIBRARY_PATH
# 验证指定型号GPU
echo "当前节点:\$(hostname)"
echo "指定A100 GPU信息:"
nvidia-smi
# 执行高算力任务(A100适用大模型训练/大批次计算)
cd /nfs/slurm/jobs
python train_large_model.py --gpu 0,1 --epoch 50 --batch-size 256
EOF
chmod +x /nfs/slurm/jobs/gpu_spec_type.sh
# 提交
sbatch /nfs/slurm/jobs/gpu_spec_type.sh
模板 4:多节点多 GPU 作业(分布式训练,如 DDP/MPI)
适用于大模型训练,需跨多个 GPU 节点,Slurm 自动分配节点并配置通信:
bash
cat > /nfs/slurm/jobs/gpu_multi_node.sh << EOF
#!/bin/bash
#SBATCH --job-name=GPU_DDP # 作业名
#SBATCH --partition=gpu-part # GPU分区
#SBATCH --nodes=2 # 申请2个节点(核心)
#SBATCH --ntasks-per-node=4 # 每个节点4个任务(对应4块GPU)
#SBATCH --gres=gpu:4 # 每个节点4块GPU
#SBATCH --cpus-per-task=8 # 每个任务绑定8核CPU
#SBATCH --mem=128G # 每个节点128G内存
#SBATCH --output=/nfs/slurm/jobs/gpu_ddp_%j.out
#SBATCH --error=/nfs/slurm/jobs/gpu_ddp_%j.err
#SBATCH --ntasks=8 # 总任务数=节点数*每节点任务数
# 激活环境
source /usr/local/anaconda3/bin/activate pytorch
export CUDA_HOME=/usr/local/cuda-11.8
export PATH=\$CUDA_HOME/bin:\$PATH
export LD_LIBRARY_PATH=\$CUDA_HOME/lib64:\$LD_LIBRARY_PATH
export NCCL_SOCKET_IFNAME=eth0 # 集群通信网卡(按实际修改,如ib0为InfiniBand)
# 验证多节点
echo "所有节点:\$SLURM_NODELIST"
echo "节点数:\$SLURM_NNODES"
echo "总GPU数:\$((\$SLURM_NNODES * \$SLURM_GPUS_PER_NODE))"
# 执行分布式训练(示例:PyTorch DDP,用srun启动)
cd /nfs/slurm/jobs
srun python -m torch.distributed.launch \
--nproc_per_node=4 \
--nnodes=2 \
--node_rank=\$SLURM_NODEID \
--master_addr=\$SLURM_LAUNCH_NODE_IPADDR \
--master_port=29500 \
train_ddp.py --epoch 100 --batch-size 64
EOF
chmod +x /nfs/slurm/jobs/gpu_multi_node.sh
# 提交
sbatch /nfs/slurm/jobs/gpu_multi_node.sh
模板 5:GPU 交互式作业(调试用,实时操作 GPU 节点)
无需编写脚本,直接在登录节点执行命令,适用于代码调试、GPU 环境验证:
bash
# 单卡交互式(最常用)
srun --partition=gpu-part --gres=gpu:1 --cpus-per-task=8 --mem=32G --pty bash
# 多卡交互式
srun --partition=gpu-part --gres=gpu:4 --cpus-per-task=32 --mem=128G --pty bash
# 指定型号交互式
srun --partition=gpu-part --gres=gpu:A100:2 --cpus-per-task=16 --mem=64G --pty bash
调试完成后 :执行
exit退出交互式终端,Slurm 自动释放 GPU 资源。
四、GPU 作业常用管理命令(登录节点执行)
1. 查看 GPU 作业状态
bash
squeue -p gpu-part # 仅查看GPU分区作业
squeue -u \$USER -p gpu-part # 查看当前用户GPU作业
scontrol show job 作业ID # 查看GPU作业详细信息(含分配的GPU节点/卡号)
2. 取消 GPU 作业
bash
scancel 作业ID # 取消指定GPU作业
scancel -u \$USER -p gpu-part # 取消当前用户所有GPU作业
3. 查看 GPU 节点资源使用情况
bash
sinfo -p gpu-part -o "%N %G %C %m %T" # 查看GPU节点GPU/CPU/内存状态
ssh slurm-com01 "nvidia-smi" # 查看指定GPU节点实时显卡使用情况
# 批量查看所有GPU节点显卡状态
for node in slurm-com01 slurm-com02; do echo "=== \$node ==="; ssh \$node "nvidia-smi | grep -A 10 'GPU Util'"; done
4. 查看 GPU 作业历史记账信息
bash
sacct -p gpu-part -o JobID,JobName,Nodes,NTasks,Gres,Elapsed,State # 查看GPU作业历史
sacct -j 作业ID -o JobID,JobName,Gres,CPUs,Mem,Elapsed,State # 查看指定GPU作业记账详情
五、GPU 集群常见问题排查
1. 作业提交失败:gres/gpu not found
原因:Gres.conf 配置错误或 Slurm 服务未重启
解决:检查 Gres.conf 节点名 / 卡数是否正确,重启
slurmctld和slurmd服务,执行scontrol show node | grep Gres验证 GPU 配置生效。
2. 作业执行报错:no CUDA-capable device is detected
原因:GPU 设备权限不足或 CUDA 环境未配置
解决:执行
chmod 666 /dev/nvidia*修复权限,检查 CUDA 环境变量是否正确,验证nvidia-smi能否正常输出。
3. 多卡作业仅单卡工作
原因:未绑定 CPU 核心或代码未开启多卡模式
解决:作业脚本中指定
--cpus-per-task(每卡绑定 8-16 核),代码中使用 DataParallel/DDP 开启多卡,验证nvidia-smi -L能看到所有 GPU。
4. 多节点作业通信失败
原因:集群通信网卡配置错误或防火墙未关闭
解决:指定
NCCL_SOCKET_IFNAME为集群实际通信网卡(如 eth0/ib0),确保所有节点防火墙已关闭,验证节点间免密登录正常。



