大家好,我是 [锅巴王子]。最近团队在大规模模型训练(LLM 炼丹)的架构演进中,决定将底层算力底座全面向云原生迁移。今天这篇是实战系列的第一发:如何使用 EKS 拉起带 EFA(极速网卡)的 GPU 物理节点,并利用 Training Operator(我们的"分布式帅印")提交多机多卡训练任务。
很多同学在本地或者单机多卡上跑得飞起,一上集群就遇到 NCCL 通信超时、显卡空转的问题。这篇实战会把中间的底层细节彻底扒开。
步骤一:使用 eksctl 拉起 EKS 集群与 GPU 节点池
在 AWS 上拉起集群,强烈建议丢掉控制台鼠标点击,直接用 eksctl 也就是 Infrastructure as Code (IaC) 的方式。因为大模型的节点池配置非常苛刻。
这里我们目标是拉起一个挂载了 p4d.24xlarge(单机 8 张 A100) 的节点组。
1. 编写 cluster.yaml
新建一个 eks-hyperpod-cluster.yaml,注意看里面的高亮注释,这是大模型训练的命脉:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: llm-train-cluster
region: ap-southeast-1 # 新加坡节点
version: "1.29"
# 必须开启 OIDC,为了后续给 Pod 分配 IAM 权限(比如读写 S3 里的模型权重)
iam:
withOIDC: true
managedNodeGroups:
- name: p4d-a100-pool
instanceType: p4d.24xlarge
minSize: 2
maxSize: 4
# 【避坑 1】必须使用专用的加速镜像,自带 NVIDIA 驱动、CUDA 和 NCCL 库
amiFamily: AmazonLinux2
# 【避坑 2】放置群组!保证这几台机器在同一个物理机架上,降低网络延迟
placement:
groupName: "hyperpod-placement-group"
# 【避坑 3】开启 EFA(弹性网络适配器)支持,这是多机通信不卡顿的物理基础
efaEnabled: true
volumeSize: 500
iam:
withAddonPolicies:
s3: true # 允许节点读写 S3 数据集
2. 执行拉起命令
eksctl create cluster -f eks-hyperpod-cluster.yaml
喝杯咖啡(大约需要 15-20 分钟),AWS 会在底层自动帮你搞定 VPC、子网、控制面和这极其昂贵的 A100 机器。
步骤二:给 EKS 授予"帅印"(安装 Training Operator)
原生的 Kubernetes 只能看懂 Web 服务(Deployment)。为了让它懂 AI,我们需要安装 Amazon SageMaker HyperPod 训练操作符 (Training Operator)。
在 AWS 控制台 -> EKS -> 你的集群 -> Add-ons (附加组件) 中,直接搜索 SageMaker HyperPod Training Operator 并一键安装。
安装完成后,你的集群就认识了一个全新的物种:PyTorchJob。它就是我们调兵遣将的"帅印"。
步骤三:编写"帅印" YAML (PyTorchJob 任务书)
这是最硬核的部分。我们要跑一个 2 机 16 卡(2x8 A100)的分布式任务。要在容器里用上 EFA 网卡,并且让 PyTorch 顺利建立 RDMA 连接,YAML 里的环境变量一个都不能写错。
新建 llama-train-job.yaml:
apiVersion: "kubeflow.org/v1"
kind: PyTorchJob
metadata:
name: llama-3-finetune
namespace: default
spec:
pytorchReplicaSpecs:
# ---------------- 统帅节点 (Master) ----------------
Master:
replicas: 1
restartPolicy: OnFailure
template:
spec:
containers:
- name: pytorch
image: 你的ecr地址.dkr.ecr.ap-southeast-1.amazonaws.com/llm-train:latest
# 启动脚本,torchrun 会自动读取底层注入的环境变量
command: ["torchrun"]
args:
- "--nnodes=2"
- "--nproc_per_node=8"
- "train.py"
# 【核心:NCCL 与 EFA 环境变量】
env:
- name: NCCL_DEBUG
value: "INFO"
- name: FI_PROVIDER
value: "efa" # 强制 Libfabric 使用 EFA 绕过内核
- name: FI_EFA_USE_DEVICE_RDMA
value: "1" # 开启 GPU 显存直接读取网络数据 (GPUDirect RDMA)
- name: NCCL_TREE_THRESHOLD
value: "0" # AWS 官方推荐的网络拓扑优化参数
resources:
limits:
nvidia.com/gpu: 8
vpc.amazonaws.com/efa: 4 # p4d 机器有 4 个 EFA 网卡,必须透传给容器!
memory: "1000Gi"
volumeMounts:
- name: dshm
mountPath: /dev/shm
volumes:
# 【避坑 4】必须挂载共享内存,否则 PyTorch 多进程 DataLoader 会报 Bus Error
- name: dshm
emptyDir:
medium: Memory
# ---------------- 士兵节点 (Worker) ----------------
Worker:
replicas: 1 # 因为一共 2 台机器,除去 Master 还需要 1 台 Worker
restartPolicy: OnFailure
template:
spec:
# Worker 的配置通常与 Master 保持一致,这里为了文章排版省略重复的环境变量和 limits 块
containers:
- name: pytorch
image: 你的ecr地址.dkr.ecr.ap-southeast-1.amazonaws.com/llm-train:latest
command: ["torchrun"]
args: ["--nnodes=2", "--nproc_per_node=8", "train.py"]
# ... (此处务必复制粘贴 Master 节点的 env, resources, volumeMounts 配置) ...
volumes:
- name: dshm
emptyDir:
medium: Memory
步骤四:掷出帅印,拉起训练!
1. 提交任务
现在,像发布普通服务一样提交这个 Job:
kubectl apply -f llama-train-job.yaml
2. 查看容器拉起状态
Training Operator 会自动帮你算出 IP,并分别在两台物理机上拉起 Pod:
kubectl get pods -l training.kubeflow.org/job-name=llama-3-finetune
你会看到类似这样的输出:
NAME READY STATUS RESTARTS AGE
llama-3-finetune-master-0 1/1 Running 0 2m
llama-3-finetune-worker-0 1/1 Running 0 2m
3. 验证 EFA 和 NCCL 是否握手成功 (极其关键)
这是高级 SRE 和新手的分水岭。跑起来不代表网络正常,如果回退到走普通 TCP 网络,你的 8 卡训练速度会比单卡还慢。
查看 Master 的日志:
kubectl logs -f llama-3-finetune-master-0
如果你在日志里看到了下面这几行闪过,恭喜你,你成功打通了 AWS 的顶级超算网络底座!
...
[INFO] NCCL INFO NET/OFI Selected Provider is efa
[INFO] NCCL INFO Using network EFA
[INFO] NCCL INFO efa: device rdma supported
[INFO] llama-3-finetune-master-0:14:14 [0] NCCL INFO Bootstrap : Using eth0:10.0.12.34<0>
...
总结
到这里,我们已经完成了 EKS 训练大模型的最核心底座搭建。
-
我们用 eksctl 拉起了带 EFA 的专属物理节点。
-
通过 Training Operator 解决了原生 K8s 无法调度多机通信的痛点。
-
注入了正确的 EFA 环境变量,激活了底层的高速网络。
但这是不是就完美了?并不是。如果此时有其他团队也提交了一个 PyTorchJob,大家就会互相抢占这几张 A100,导致全部死锁。
各种场景下的配对公式
为了让你以后在写 YAML 时不抓瞎,你可以参考下面这个对照表:
| 训练场景 | 推荐实例 (Node) | 物理 GPU 数 | Pod 的 GPU 限制 | Node : Pod 比例 |
|---|---|---|---|---|
| 大规模 LLM 训练 | p4d.24xlarge |
8 (A100) | 8 | 1 : 1 (最强性能) |
| 中型模型微调 | g5.12xlarge |
4 (A10) | 4 | 1 : 1 (高性价比) |
| 小型模型实验 | g5.4xlarge |
1 (A10) | 1 | 1 : 1 |
| 推理/打标业务 | g5.48xlarge |
8 (A10) | 1 | 1 : 8 ( |