Skip to content

8节点64×V100 PCIe 集群 · 大模型训练全套落地方案

版本:V1.0 适用前提:8台裸金属,每台8×NVIDIA V100 PCIe 32GB(共64卡),无NVLink,补齐InfiniBand互联 目标:跑通 70B~130B 级模型的分布式训练(Megatron-DeepSpeed / FSDP 双方案) 文档性质:从采购上架到验收移交的端到端实施手册,可直接作为运维SOP下发


第零章 · 总体架构与执行路线

0.1 集群逻辑架构

┌─────────────────────────────────────────────────────────────┐
│                    K8S + Volcano 调度层                       │
├─────────────────────────────────────────────────────────────┤
│  gpu-node-0  gpu-node-1  gpu-node-2  ...  gpu-node-7          │
│  8×V100 PCIe 8×V100 PCIe 8×V100 PCIe      8×V100 PCIe       │
│  1×ConnectX  1×ConnectX  1×ConnectX       1×ConnectX        │
├─────────────────────────────────────────────────────────────┤
│         IB 交换机(EDR 100G / HDR 200G,全互联胖树)            │
├─────────────────────────────────────────────────────────────┤
│    共享存储:NFS/Lustre(checkpoint + 数据集 + 容器镜像仓库)    │
└─────────────────────────────────────────────────────────────┘

0.2 并行策略(锁死)

维度取值说明
TP(张量并行)1纯PCIe无NVLink,节点内8卡互联带宽不足以支撑TP
PP(流水线并行)8跨节点流水,通信频次低,匹配IB带宽
DP(数据并行)864卡 ÷ (TP1 × PP8) = DP8;原稿笔误写成DP=1,特此更正
显存优化ZeRO-3 + CPU OffloadV100 32GB 跑 70B+ 必须开 offload_param
精度FP16 + 激活重计算V100 不支持 BF16(需Ampere+),统一用 FP16
注意力原生 SDPA / 自定义实现FlashAttention 仅支持 SM80+(A100起),V100(SM70)装不上,原稿 --use-flash-attn 必须删除

0.3 实施路线总览

阶段一(1-3天)   阶段二(2-4天)    阶段三(3-5天)     阶段四(2-3天)    阶段五(1天)
采购验收   →   网络与基础环境  →   K8S+Volcano调度  →   训练跑通调优  →   验收移交
                 ├ IB调通          ├ Gang调度         ├ NCCL调优        └ SOP归档
                 ├ 驱动/CUDA       ├ RDMA DevicePlugin ├ 70B冒烟
                 └ 存储挂载        └ 镜像准备          └ 断点续训

0.4 角色分工建议

角色职责
硬件/机房上架、布线、IB光模块插拔、供电核算
系统运维OS安装、驱动、CUDA、Docker、存储挂载
网络IB子网规划、子网管理器、NCCL网络参数
平台K8S集群、Volcano、监控告警
算法/训练并行配置、ds_config、启动脚本、loss验证

第一章 · 硬件采购与上架验收

1.1 采购清单(补采部分)

物料规格数量备注
IB网卡ConnectX-5 EDR 100G 单口(或 ConnectX-6 HDR 200G)8每节点1张,PCIe x16
IB交换机Mellanox SB7890(EDR 36口)或 QM8700(HDR 40口)18节点接入,留扩容口
AOC/DAC线缆EDR 100G QSFP28,3~5米8同机房用DAC更省
光模块+AOC若跨机柜距离>5米按需
子网管理交换机自带SM(QM8700内置)或独立节点跑opensm1见1.4

关键确认:IB网卡必须插在与GPU同侧NUMA的PCIe x16槽位(x8会带宽腰斩),上架前先查主板槽位图。

1.2 上架检查表

  • [ ] 每节点8张V100全部上电识别:lspci | grep -i nvidia | wc -l = 8
  • [ ] IB卡插入x16槽位,金手指插到底,卡扣到位
  • [ ] IB线缆两端插紧,交换机端口灯绿(LinkUp)
  • [ ] 供电核算:单节点8×V100(250W) + 双CPU + 风扇 ≈ 3.5kW,机柜PDU留20%余量
  • [ ] 散热:V100 PCIe被动散热卡依赖机箱风道,确认前进后出、风速达标

1.3 节点命名与IP规划(示例)

节点管理网IPIB网IP主机名
010.0.1.10192.168.100.10gpu-node-0
110.0.1.11192.168.100.11gpu-node-1
710.0.1.17192.168.100.17gpu-node-7
  • IB子网单独一个网段(192.168.100.0/24),与管理网物理隔离
  • /etc/hosts 全节点同步写入8台主机名 ↔ IB IP映射

1.4 IB子网管理器(SM)

  • 用QM8700/SB7890这类管理型交换机:开启内置SM即可,无需额外配置
  • 用非管理型交换机:选一台管理节点(非GPU节点)常驻跑 opensm
bash
yum install -y opensm
systemctl enable --now opensm
# 验证
sminfo | grep -E "sm lid|state"

第二章 · 硬件拓扑测绘(必做,存档)

每台机器执行,结果存档到 拓扑测绘-节点名.txt

bash
# GPU 互联拓扑(确认是 PCIe 不是 NVLink)
nvidia-smi topo -m

# NUMA 与 PCIe 亲和(V100 跨 NUMA 通信会慢一倍)
lscpu | grep -A3 "NUMA node(s)"
nvidia-smi -q | grep -i "PCI Bus ID"
cat /sys/class/net/ib0/device/numa_node

# IB 网卡状态
ibstat | grep -E "State|Rate|Port"
ibv_devices

判定标准

  • topo -m 里 GPU 间显示 PIX(同PCIe switch)或 SYS(跨CPU)都正常,绝不能出现 NVLink 误报
  • IB 卡 State: Active,Rate 显示 100(EDR)或 200(HDR)
  • IB 卡 NUMA 尽量和所绑 GPU 同侧;若跨NUMA,记录下来,后续绑核时规避

附:GPU↔NUMA↔IB 亲和速查脚本

bash
#!/bin/bash
# 保存为 numa_affinity_check.sh,每节点执行
for gpu in /sys/class/nvidia/gpu*/device; do
  echo "$(basename $(dirname $gpu)): NUMA=$(cat $gpu/numa_node)"
done
echo "IB: NUMA=$(cat /sys/class/net/ib0/device/numa_node)"

第三章 · 基础环境安装(8节点统一)

3.1 操作系统与内核

  • 推荐 Ubuntu 20.04/22.04 LTSRocky Linux 8/9,内核 ≥ 4.15(GDR需要)
  • 关闭 NUMA balancing(防止训练进程被迁移跨NUMA):
bash
echo "kernel.numa_balancing=0" >> /etc/sysctl.conf
sysctl -p
  • 关闭ASLR随机化对perf的影响(可选)、开启hugepage(CPU offload受益):
bash
echo "vm.nr_hugepages=1024" >> /etc/sysctl.conf
sysctl -p

3.2 NVIDIA 驱动 + CUDA

bash
# V100 用 525+ 驱动,CUDA 11.8(对老卡兼容最好)
# Ubuntu 示例:
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run
sudo sh cuda_11.8.0_520.61.05_linux.run   # 只装驱动+CUDA toolkit,不装sample
nvidia-smi   # 确认8卡全识别,驱动525+
nvcc --version

注意:V100 计算能力 SM70,CUDA 12.x 部分新版框架已放弃优化,建议锁 CUDA 11.8 + PyTorch 1.13/2.0,兼容性最好。

3.3 MLNX_OFED(IB驱动栈)

bash
# 下载对应OS版本的 MLNX_OFED(≥5.4)
wget https://content.mellanox.com/ofed/MLNX_OFED-5.8-3.0.7.0/MLNX_OFED_LINUX-5.8-3.0.7.0-ubuntu20.04-x86_64.tgz
tar xf MLNX_OFED_LINUX-*.tgz && cd MLNX_OFED_LINUX-*
sudo ./mlnxofedinstall --with-nvmf --with-nfsrdma   # 视需要加组件
sudo /etc/init.d/openibd restart

# 验证
ofed_info -s | head -1
ibstat | grep -E "State|Rate"

3.4 GPUDirect RDMA(GDR)内核模块

bash
# CUDA 11.4+ 推荐 nvidia-peermem(随驱动自带)
modprobe nvidia-peermem
lsmod | grep peermem

# 老内核/老驱动用 nv_peer_mem(需从GDRCopy源码编译)
# git clone https://github.com/Mellanox/nv_peer_memory.git && cd nv_peer_memory
# ./build_module.sh && insmod nv_peer_mem.ko

3.5 Docker + NVIDIA Container Toolkit

bash
# Docker
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker

# NVIDIA Container Toolkit
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list \
  > /etc/apt/sources.list.d/nvidia-docker.list
apt-get update && apt-get install -y nvidia-container-toolkit
nvidia-ctk runtime configure --runtime=docker
systemctl restart docker

# 验证
docker run --rm --gpus all nvcr.io/nvidia/cuda:11.8.0-base-ubuntu20.04 nvidia-smi

3.6 共享存储挂载

所有节点挂载同一套共享存储,用于 checkpoint / 数据集 / 代码:

bash
# NFS 示例(生产建议 Lustre/GPFS,小规模 NFS 够用)
mkdir -p /shared/{ckpt,dataset,code}
mount -t nfs <nfs-server>:/export/ckpt /shared/ckpt
mount -t nfs <nfs-server>:/export/dataset /shared/dataset
mount -t nfs <nfs-server>:/export/code /shared/code

# 写进 /etc/fstab 持久化
# <nfs-server>:/export/ckpt /shared/ckpt nfs defaults,_netdev 0 0

IO压测(确保读带宽 ≥ 2GB/s,否则 dataloader 成瓶颈):

bash
fio --name=readtest --directory=/shared/dataset --rw=read --bs=1M \
    --size=10G --numjobs=8 --runtime=60 --time_based --group_reporting

第四章 · IB 网络调通与 NCCL 环境锁死

4.1 IB 连通性测试

bash
# 节点A(server):
ib_write_bw -d mlx5_0 &
# 节点B(client):
ib_write_bw -d mlx5_0 192.168.100.10
# 预期:EDR ~97 Gb/s,HDR ~195 Gb/s

8节点两两全测一遍(或至少测任意两两组合各一次),结果存档。

4.2 NCCL 全局环境变量(写进 /etc/profile.d/nccl.sh

针对纯PCIe + IB场景的固定安全值:

bash
# ============ 通信后端 ============
export NCCL_IB_DISABLE=0
export NCCL_SOCKET_IFNAME=ib0
export NCCL_IB_HCA=mlx5_0
# GID_INDEX=3 仅用于 RoCE(以太网跑RDMA);纯IB默认不用设
# export NCCL_IB_GID_INDEX=3    # 纯IB场景注释掉;若误用RoCE再打开

# ============ 纯 PCIe 无 NVLink:强制关 P2P,防 CUDA 上下文死锁 ============
export NCCL_P2P_DISABLE=1
export NCCL_P2P_LEVEL=PIX

# ============ 跨节点 Tree 算法更稳 ============
export NCCL_ALGO=Tree
export NCCL_PROTO=Simple

# ============ PCIe 场景 buffer 调小,IB 场景 channel 调大 ============
export NCCL_BUFFSIZE=16777216
export NCCL_MIN_NCHANNELS=16
export NCCL_MAX_NCHANNELS=32

# ============ GDR:V100 支持 GPUDirect RDMA ============
export NCCL_NET_GDR_LEVEL=2      # SYS 级即可,不要强设 3/5 防回退

# ============ 超时与异步错误处理(防 hang) ============
export NCCL_SOCKET_TIMEOUT=6000
export NCCL_ASYNC_ERROR_HANDLING=1

# ============ 调试开关(调通后改 WARN) ============
export NCCL_DEBUG=INFO
export NCCL_DEBUG_SUBSYS=INIT,NET

修正说明:原稿 NCCL_IB_GID_INDEX=3 是 RoCE(RDMA over Converged Ethernet)专用,纯IB场景无需设置,保留会导致部分NCCL版本报GID解析失败。纯IB建议注释掉。

4.3 单机/双机 NCCL 冒烟测试

先不碰 K8S,裸机验证:

bash
# 容器内或裸机装 nccl-tests
git clone https://github.com/NVIDIA/nccl-tests.git
cd nccl-tests && make -j MPI=0

# 单机 8 卡 PCIe 带宽基线(纯 PCIe 预期 ~10-14 GB/s)
./build/all_reduce_perf -b 64M -e 2G -f 2 -g 8

# 跨两节点共16卡(IB EDR 预期 busbw > 8 GB/s)
# 用 mpirun 起:
mpirun -np 16 -H node0:8,node1:8 \
  -x NCCL_IB_DISABLE=0 -x NCCL_SOCKET_IFNAME=ib0 \
  -x NCCL_DEBUG=INFO \
  ./build/all_reduce_perf -b 64M -e 2G -f 2

通过标准

  • 日志出现 NET/IBGDRDMA 字样,不是 NET/Socket
  • 单机 all-reduce busbw > 10 GB/s
  • 双机 16 卡 busbw > 8 GB/s(IB 100G 理论 ~11GB/s)

第五章 · K8S + Volcano 调度层(防死锁)

5.1 集群组件清单

组件版本要求用途
K8S≥ 1.26容器编排
NVIDIA Device Plugin最新上报 nvidia.com/gpu
Volcano≥ 1.8Gang Scheduling(防半启动死锁)
RDMA Shared Device Plugin最新上报 rdma/rdma_shared_device_a(IB给容器用)
Metrics Server / Prometheus可选监控

5.2 安装 Volcano

bash
helm repo add volcano-sh https://volcano-sh.github.io/helm-charts
helm install volcano volcano-sh/volcano -n volcano-system --create-namespace

5.3 安装 RDMA Shared Device Plugin

bash
# 用 k8s-rdma-shared-dev-plugin
kubectl apply -f https://raw.githubusercontent.com/Mellanox/k8s-rdma-shared-dev-plugin/master/images/k8s-rdma-shared-dev-plugin-config-map.yaml
kubectl apply -f https://raw.githubusercontent.com/Mellanox/k8s-rdma-shared-dev-plugin/master/images/k8s-rdma-shared-dev-plugin-ds.yaml

# 验证节点上多了 rdma 资源
kubectl describe node gpu-node-0 | grep -A3 "rdma"

5.4 节点打标

bash
for i in $(seq 0 7); do
  kubectl label node gpu-node-$i gpu-type=v100-pcie
  kubectl label node gpu-node-$i ib-net=ib0
done

5.5 NCCL ConfigMap(把第四章变量注入容器)

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nccl-defaults
data:
  NCCL_IB_DISABLE: "0"
  NCCL_SOCKET_IFNAME: "ib0"
  NCCL_IB_HCA: "mlx5_0"
  NCCL_P2P_DISABLE: "1"
  NCCL_P2P_LEVEL: "PIX"
  NCCL_ALGO: "Tree"
  NCCL_PROTO: "Simple"
  NCCL_BUFFSIZE: "16777216"
  NCCL_MIN_NCHANNELS: "16"
  NCCL_MAX_NCHANNELS: "32"
  NCCL_NET_GDR_LEVEL: "2"
  NCCL_SOCKET_TIMEOUT: "6000"
  NCCL_ASYNC_ERROR_HANDLING: "1"
  NCCL_DEBUG: "INFO"
  NCCL_DEBUG_SUBSYS: "INIT,NET"

5.6 Volcano Queue

yaml
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
  name: training
spec:
  weight: 1
  capability:
    cpu: "512"
    memory: "2048Gi"
    nvidia.com/gpu: 64

5.7 Volcano Job 完整版(8机64卡 Gang)

yaml
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: v100-train-gang
spec:
  schedulerName: volcano
  minAvailable: 8          # 8机必须同时起,否则全 Pending
  queue: training
  plugins:
    env: []
    svc: []
  maxRetry: 3
  tasks:
  - name: trainer
    replicas: 8
    template:
      metadata:
        labels:
          app: megatron-train
      spec:
        hostNetwork: true        # IB直通用hostNetwork最简单
        dnsPolicy: ClusterFirstWithHostNet
        containers:
        - name: megads
          image: your-registry/megatron-deepspeed:v100-cuda118
          imagePullPolicy: IfNotPresent
          envFrom:
          - configMapRef:
              name: nccl-defaults
          env:
          - name: WORLD_SIZE
            value: "64"
          - name: TP_SIZE
            value: "1"
          - name: PP_SIZE
            value: "8"
          - name: DP_SIZE
            value: "8"
          - name: MASTER_ADDR
            value: "v100-train-gang-trainer-0"
          - name: MASTER_PORT
            value: "29500"
          - name: RANK
            valueFrom:
              fieldRef:
                fieldPath: metadata.labels['batch.volcano.sh/job-task-index']
          ports:
          - containerPort: 29500
          resources:
            limits:
              nvidia.com/gpu: 8
              rdma/rdma_shared_device_a: 1
            requests:
              nvidia.com/gpu: 8
          volumeMounts:
          - name: dshm
            mountPath: /dev/shm
          - name: ckpt
            mountPath: /shared/ckpt
          - name: dataset
            mountPath: /shared/dataset
          - name: code
            mountPath: /shared/code
          securityContext:
            capabilities:
              add: ["IPC_LOCK"]     # GDR需要
        volumes:
        - name: dshm
          emptyDir:
            medium: Memory
            sizeLimit: 64Gi
        - name: ckpt
          persistentVolumeClaim:
            claimName: pvc-ckpt
        - name: dataset
          persistentVolumeClaim:
            claimName: pvc-dataset
        - name: code
          persistentVolumeClaim:
            claimName: pvc-code

关键minAvailable: 8 + schedulerName: volcano 缺一个就会半启动死锁。 hostNetwork: true 让容器直接用宿主机IB协议栈,省去Macvlan/SR-IOV的复杂配置,性能无损。

5.8 PVC 模板(NFS示例)

yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-ckpt
spec:
  capacity:
    storage: 10Ti
  accessModes: ["ReadWriteMany"]
  nfs:
    server: <nfs-server>
    path: /export/ckpt
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-ckpt
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 10Ti

第六章 · 训练框架启动(双方案)

方案A:Megatron-DeepSpeed(TP1 + PP8 + ZeRO3)

6.1 ds_config.json(ZeRO-3 + V100 专用)

json
{
  "fp16": {
    "enabled": true,
    "loss_scale": 0,
    "loss_scale_window": 1000,
    "initial_scale_power": 16
  },
  "zero_optimization": {
    "stage": 3,
    "offload_optimizer": { "device": "cpu", "pin_memory": true },
    "offload_param": { "device": "cpu", "pin_memory": true },
    "overlap_comm": true,
    "contiguous_gradients": true,
    "reduce_bucket_size": "auto",
    "stage3_prefetch_bucket_size": "auto",
    "stage3_gather_fp16_weights_on_model_save": true
  },
  "activation_checkpointing": true,
  "gradient_clipping": 1.0,
  "train_micro_batch_size_per_gpu": 1,
  "gradient_accumulation_steps": 2,
  "train_batch_size": 128,
  "steps_per_print": 10,
  "wall_clock_breakdown": false
}

6.2 Megatron 启动脚本

bash
#!/bin/bash
# launch_megatron.sh
set -x

deepspeed --num_nodes 8 --num_gpus 8 \
  --master_addr ${MASTER_ADDR} --master_port ${MASTER_PORT} \
  pretrain_gpt.py \
  --num-layers 80 \
  --hidden-size 8192 \
  --num-attention-heads 64 \
  --seq-length 2048 \
  --max-position-embeddings 2048 \
  --micro-batch-size 1 \
  --global-batch-size 128 \
  --tensor-model-parallel-size 1 \
  --pipeline-model-parallel-size 8 \
  --fp16 \
  --recompute-activations \
  --recompute-granularity selective \
  --deepspeed \
  --deepspeed_config ds_config.json \
  --distributed-backend nccl \
  --data-path /shared/dataset/gpt2/my-gpt2_text_document \
  --vocab-file /shared/dataset/gpt2/gpt2-vocab.json \
  --merge-file /shared/dataset/gpt2/gpt2-merges.txt \
  --save /shared/ckpt/megatron-70b \
  --save-interval 500 \
  --log-interval 10 \
  --train-iters 1000

已删除 --use-flash-attn:V100(SM70)不支持 FlashAttention(需 SM80+)。Megatron 会自动回退到原生注意力实现。若想加速,可装 xformers(部分算子支持SM70)或用 torch.nn.functional.scaled_dot_product_attention(PyTorch 2.0+ 内置,CPU/GPU通用)。

6.3 显存保护策略

V100 32G 跑 70B+ 必须开 offload_param,若仍 OOM:

  1. --micro-batch-size 保持 1(已经最小)
  2. --seq-length 降到 1024
  3. recompute-granularityselective 改为 full
  4. 检查 ds_config.jsonoffload_param.device 确实是 cpu

方案B:FSDP(PyTorch 原生,不依赖 Megatron)

适合不用Megatron生态、想快速验证或训非GPT架构的场景。

6.4 FSDP 启动脚本

python
# fsdp_train.py 关键配置
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
from torch.distributed.fsdp.fully_sharded_data_parallel import (
    CPUOffload, ShardingStrategy
)
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy

model = FSDP(
    model,
    sharding_strategy=ShardingStrategy.FULL_SHARD,   # 等价 ZeRO-3
    cpu_offload=CPUOffload(offload_params=True),      # 70B+ 必须开
    auto_wrap_policy=functools.partial(
        transformer_auto_wrap_policy,
        transformer_layer_cls={TransformerBlock},
    ),
    mixed_precision=MixedPrecision(
        param_dtype=torch.float16,
        reduce_dtype=torch.float16,
        buffer_dtype=torch.float16,
    ),
    device_id=torch.cuda.current_device(),
)

6.5 FSDP torchrun 启动命令

bash
torchrun \
  --nnodes=8 \
  --nproc_per_node=8 \
  --rdzv_id=v100-fsdp \
  --rdzv_backend=c10d \
  --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} \
  fsdp_train.py \
  --model_size 70b \
  --seq_len 2048 \
  --batch_size 1 \
  --grad_accum 2 \
  --ckpt_dir /shared/ckpt/fsdp-70b

6.6 两方案选型建议

场景推荐
训标准GPT/LLaMA架构,追求极致吞吐Megatron-DeepSpeed
自定义模型架构,不想改Megatron源码FSDP
团队熟悉PyTorch生态,快速验证FSDP
需要精细PP调度(1F1B、Interleaved)Megatron-DeepSpeed

第七章 · 断点续训与容错

7.1 Checkpoint 策略

  • save-interval 建议 500 iter 一次(70B 模型单次 ckpt ~280GB,FP16 权重)
  • 共享存储预留 ≥ 3 倍模型大小的空间(保留最近3份)
  • 开启 stage3_gather_fp16_weights_on_model_save(ds_config已含),保证 save 时权重完整聚合,避免 ZeRO-3 分片 ckpt 恢复失败

7.2 断点恢复

bash
# Megatron 自动找 latest_checkpointed_iteration.txt
--load /shared/ckpt/megatron-70b \
--no-load-optim \      # 只想恢复权重不恢复optimizer state时加
--no-load-rng

7.3 节点故障演练

  • 训练中途 kubectl delete pod 杀掉一个 trainer
  • 观察 Volcano 是否按 maxRetry: 3 整体重启 Job(Gang语义:一个挂,全组重调度)
  • 重启后 --load 自动从最近 ckpt 恢复,loss 曲线应连续

第八章 · 监控与性能分析

8.1 基础监控

指标工具告警阈值
GPU利用率nvidia-smi / DCGM Exporter< 50% 持续5min(可能hang)
GPU显存DCGM> 30GB(接近OOM)
IB带宽perfquery / ib counters< 50 Gb/s(链路降级)
PCIe带宽nvidia-smi dmon持续 < 8 GB/s(拓扑问题)
CPU内存node_exporter> 90%(offload溢出风险)

8.2 训练侧关键日志

bash
# 关注这三个字段判断健康度:
# iteration 时间(每iter秒数,稳定才算调通)
# lm loss(应持续下降,前100 iter 下降明显)
# grad norm(应 < 10,持续 > 100 说明发散)
tail -f /shared/ckpt/megatron-70b/train.log | grep -E "iteration|lm loss|grad norm"

8.3 性能基准(V100 参考值)

模型并行配置预期吞吐
70BTP1/PP8/DP8, ZeRO3+offload~30-50 TFLOPs/卡
130BTP1/PP8/DP8, ZeRO3+offload, seq1024~25-40 TFLOPs/卡

若实测 < 60% 预期值,优先查:① NCCL 是否走了 Socket 而非 IB;② dataloader IO 瓶颈;③ CPU offload 换页抖动。


第九章 · 常见故障速查表

现象可能原因排查命令解决方案
NCCL 初始化 hang 住IB 不通 / SM 没跑 / GID 错误ibstatsminfo、NCCL_DEBUG=INFO确认 IB State=Active;纯IB注释掉 GID_INDEX
日志显示 NET/Socket 而非 NET/IBNCCL 没找到 IB 设备ls /sys/class/infiniband/、NCCL_IB_HCA确认 NCCL_IB_DISABLE=0,容器内装了 libibverbs
单机 8 卡 all-reduce 只有 2-3 GB/s误开 NVLink P2P / PCIe 降速nvidia-smi topo -mnvidia-smi -q -d PERFORMANCENCCL_P2P_DISABLE=1;查 PCIe 协商速率是否 x16
双机 busbw < 4 GB/s走了 TCP / IB 线缆半速ib_write_bw 裸测换线缆/光模块;确认 ibstat Rate=100/200
训练 OOM(CUDA out of memory)offload 没生效 / mbs 太大nvidia-smi、ds_config确认 offload_param=cpu;mbs=1;seq降1024
ZeRO-3 save ckpt 后恢复失败权重没聚合就 saveckpt 目录大小是否完整stage3_gather_fp16_weights_on_model_save
Volcano Job 一半 Pod Pending缺 Gang 调度 / 资源不够kubectl describe vcjob确认 minAvailable=replicas;查节点 GPU/RDMA 资源
容器内 ibstat 没设备没挂 RDMA 资源kubectl describe podrdma/rdma_shared_device_a: 1 + hostNetwork: true
训练 loss 突然 NaNFP16 溢出 / 学习率过大grad norm 日志loss_scale 调小;warmup 加长;grad clipping 1.0
CPU 内存爆掉(offload溢出)offload_param+offload_opt 同时开,内存不够free -h、`dmesggrep OOM`
dataloader 慢,GPU 等数据NFS IO 瓶颈 / num_workers 太少iostat -x 1、fio换 Lustre/本地SSD缓存;num_workers=8+
--use-flash-attn 报错V100 不支持 FlashAttentionpip show flash-attn删除该参数;用原生SDPA或xformers

第十章 · 验收标准(上线前 Gate)

#验收项通过标准
1NCCL 网络nccl-tests 双机 16 卡 busbw ≥ 8 GB/s
2Gang 调度Volcano Job 64 Pod 同时 Running,无 Pending
3NCCL 路径训练日志出现 NCCL INFO Trees + GDRDMA
470B 跑通TP1/PP8/DP8 + ZeRO3 跑完 50 iter 不 OOM,loss 持续下降
5故障恢复拔 1 节点,Volcano 按策略重试或完整释放,无半吊子
6断点续训kill 后重启,自动从 ckpt 恢复,loss 曲线连续
7监控就绪GPU/IB/存储 监控面板有数据,告警规则生效
8文档移交拓扑测绘、NCCL变量、启动脚本、SOP 全部归档

附录A · 端到端实施 Checklist

【阶段一 · 采购上架】
□ IB网卡/交换机/线缆到货验收
□ IB卡插入GPU同侧NUMA的x16槽位
□ 8节点上电,lspci 识别8×V100 + 1×IB
□ IB交换机SM开启,ibstat State=Active

【阶段二 · 基础环境】
□ OS/CUDA 11.8/驱动525+ 安装
□ MLNX_OFED 安装,ib_write_bw 双机测通
□ nvidia-peermem 加载,lsmod 确认
□ Docker + nvidia-container-toolkit 装完
□ 共享存储挂载,fio 读带宽 ≥ 2GB/s

【阶段三 · 网络调优】
□ NCCL 环境变量写进 /etc/profile.d/nccl.sh
□ 单机 8 卡 all-reduce > 10 GB/s
□ 双机 16 卡 all-reduce > 8 GB/s,走 NET/IB + GDRDMA

【阶段四 · 调度平台】
□ K8S ≥1.26 就绪
□ Volcano、NVIDIA Device Plugin、RDMA Plugin 装完
□ 节点打标 gpu-type=v100-pcie
□ NCCL ConfigMap、Queue、PVC 就绪
□ Volcano Job 64 Pod 同时 Running

【阶段五 · 训练跑通】
□ Megatron-DeepSpeed 70B 跑 50 iter 不 OOM
□ loss 下降,grad norm 正常
□ 断点续训验证通过
□ FSDP 备选方案验证(可选)

【阶段六 · 验收移交】
□ 10项验收标准全过
□ 监控告警就绪
□ SOP/脚本/拓扑图归档移交运维

附录B · 参考资源


修订记录

版本日期变更
V1.02026-07-31初版全套落地方案,含采购到验收全流程

相对原稿的关键修正

  1. 并行策略 DP=1 → DP=8(64卡 ÷ TP1×PP8)
  2. 删除 --use-flash-attn(V100 SM70 不支持 FlashAttention)
  3. NCCL_IB_GID_INDEX=3 标注为 RoCE 专用,纯IB建议注释
  4. 补全 Volcano 完整 YAML(ConfigMap/Queue/PVC/hostNetwork)
  5. 补全 FSDP 备选启动方案
  6. 补全故障速查表(原稿为空)