心情: 掌控全局(终于不用像保姆一样盯着屏幕了) 任务: 制作黄金镜像 (AMI)、部署 AWS ParallelCluster、配置 Slurm 作业脚本、实现自动伸缩 关键词: Custom AMI, AWS ParallelCluster, Slurm, EFA, Placement Group, Shared Storage
早上 10:00,李博士甩给我一个 Excel 表格,上面列了 10 组实验参数(不同的学习率、Batch Size)。 "YY,这 10 个实验我要挨个跑。之前的做法太累了,我要守着屏幕等上一个跑完,再手动改参数跑下一个。而且每次都要重新配环境、传数据,太慢了。"
我意识到,我们需要从"手工作坊"升级为"自动化工厂"了。 这需要解决三个核心问题:
-
环境固化: 怎么保证自动弹出来的机器,显卡驱动和 PyTorch 都是装好的?
-
集群配置: 怎么自动创建支持 EFA 和 Placement Group 的高性能网络?
-
任务分发: 怎么把李博士的代码自动分发到 4 台机器上并同步启动?
第一步:制作"黄金镜像" (Custom AMI) ------ 这一步最关键!
ParallelCluster 虽然能自动开机器,但它开出来的机器是"裸机"。如果每次开机都要重新安装 NVIDIA 驱动、CUDA、PyTorch,那得等半小时,而且容易出错。
我的操作:
-
找到我们在 Day 2 费尽千辛万苦配置好的那台 Node 1(装好了 EFA 驱动、Docker、Anaconda、NCCL 库)。
-
确保它是关机状态。
-
在 EC2 控制台,右键点击该实例 -> Image and templates -> Create image。
-
命名为:
ami-p4d-ai-training-base-v1。 -
等待几分钟,我得到了一个 AMI ID (例如
ami-0abcdef1234567890)。
意义: 以后无论集群扩展到 100 台还是 1000 台,只要用这个 AMI 启动,里面的环境就跟 Day 2 调好的那台一模一样,开机即用,零配置。
第二步:编写集群蓝图 ------ 找回丢失的高性能参数
我不打算自己写脚本去开关机,而是使用 AWS ParallelCluster 。 我编写了配置文件 cluster-config.yaml。这里必须把我们之前学的网络知识(EFA, Placement Group)写进去,否则跑不快。
Region: us-east-1
Image:
Os: ubuntu2004
CustomAmi: ami-0abcdef1234567890 # <--- 关键!使用刚才做好的黄金镜像
HeadNode:
InstanceType: t3.medium
Networking:
SubnetId: subnet-public-xxx # 头节点要有公网,方便博士登录
Ssh:
KeyName: my-key
Scheduling:
Scheduler: slurm # 使用 Slurm 调度器
SlurmQueues:
- Name: training-queue
ComputeResources:
- Name: p4d-instances
InstanceType: p4d.24xlarge
MinCount: 0 # <--- 核心!没任务时缩容到 0,省钱
MaxCount: 4 # 最多开 4 台,防止破产
# 【关键点 1】启用 EFA (Day 1 的教训)
# 告诉 AWS:这几台机器要开启 EFA 网络接口
Efa:
Enabled: true
GdrSupport: true
# 【关键点 2】启用 Placement Group (Day 1 的教训)
# 告诉 AWS:这 4 台机器必须物理上挨在一起,减少延迟
Networking:
SubnetIds:
- subnet-private-xxx
PlacementGroup:
Enabled: true
SharedStorage:
- MountDir: /fsx
Name: my-fsx
StorageType: FsxLustre
FsxLustreSettings:
FileSystemId: fs-0123456789 # 挂载我们在 Day 5 创建好的 FSx
执行创建: 在我的笔记本终端执行: pcluster create-cluster --cluster-name ai-hpc-cluster --cluster-configuration cluster-config.yaml
第三步:代码上车 ------ 怎么把训练代码放进去?
集群创建好了,目前只有一台 HeadNode (头节点) 在运行,计算节点是 0。 李博士问:"我代码放哪?还要像以前一样 scp 到每台机器吗?"
"不用,"我指着 HeadNode 的 /fsx 目录,"你只要把代码放进这儿,所有的计算节点自动都能看见。"
操作流程:
-
李博士登录 HeadNode:
ssh head-node。 -
他把本地写好的
train_llama3.py上传到/fsx/project/目录下。 -
原理: 因为计算节点启动时会自动挂载这个 FSx,所以它们一醒来就能访问
/fsx/project/train_llama3.py。 -
数据: 训练数据也在
/fsx/datasets/下(这是 FSx 自动关联 S3 带来的)。
第四步:编写"点火指令" ------ Slurm 作业脚本
这是运维和算法交接的最后一步。 李博士不能直接跑 python train.py 了,因为那只是在头节点跑。他需要写一个 Slurm 脚本 (submit_job.sh) 来告诉集群怎么干活。
#!/bin/bash
# ================= 运维关注的资源参数 =================
#SBATCH --job-name=Exp_01_LR_0.001
#SBATCH --nodes=4 # 申请 4 台 P4d
#SBATCH --ntasks-per-node=8 # 每台机器启动 8 个进程 (对应 8 张卡)
#SBATCH --gres=gpu:8 # 明确申请 8 个 GPU 资源
#SBATCH --partition=training-queue
#SBATCH --output=%x_%j.log # 日志输出位置
# ================= 环境准备 (基于 AMI) =================
# 虽然 AMI 里装好了环境,但我们需要激活它
source /opt/conda/bin/activate pytorch_env
# 设置 EFA 网络环境变量 (Day 3 的经验)
export NCCL_DEBUG=INFO
export FI_EFA_ENABLE_SHM_TRANSFER=1
export NCCL_IB_HCA=^roce # 屏蔽掉非 EFA 的网卡
# ================= 算法关注的训练命令 =================
# srun 是核心!它会像广播一样,让 4 台机器同时执行后面的命令
# 注意:代码和数据都读的是 /fsx 里的路径
srun python /fsx/project/train_llama3.py \
--model_dir /fsx/models/Llama-3-Base \
--data_dir /fsx/datasets/wiki_data \
--output_dir /fsx/checkpoints/exp_01 \
--learning_rate 0.001 \
--batch_size 128
第五步:见证"自动扩容"与"自动关机"
下午 3:00:提交任务 李博士在 HeadNode 敲下:sbatch submit_job.sh。 系统返回:Submitted batch job 101。
下午 3:05:自动伸缩 我看了一眼 squeue,状态是 PD (Pending)。 紧接着,我在 AWS 控制台看到:4 台 P4d 实例正在启动! ParallelCluster 自动帮我们把这 4 台机器加入了 Placement Group,并且挂载了 FSx。
下午 3:10:任务运行 机器状态变为 Running。 我 SSH 进其中一台计算节点,输入 nvidia-smi。 完美! 驱动正常,显卡满载,正在跑李博士的 Python 代码。
晚上 8:00:自动回收 任务跑完了。 Slurm 发现队列空了。 10 分钟后,这 4 台昂贵的 P4d 自动关机销毁。
今日总结:
-
AMI 是基石: 没有 Day 2 手动配置并保存的 AMI,自动化就是空中楼阁。
-
FSx 是桥梁: 它连接了 S3(数据湖)、HeadNode(代码入口)和 ComputeNodes(算力),让代码和数据实现了"一次上传,处处可见"。
-
Slurm 是指挥官: 它把李博士的 Python 命令精准地分发到了 4 台机器的 32 张显卡上。
现在的架构: 李博士 (HeadNode + /fsx) -> Slurm -> ParallelCluster -> AWS Auto Scaling -> 4x P4d (Based on Custom AMI)
📎 附件:YY 的 AI 运维学习笔记(Day 9 - 自动化集群架构解密)
文档说明:
Day 9 我们引入了 AWS ParallelCluster 和 Slurm。这套架构解决了手动管理 GPU 服务器的痛点,但也带来了新的复杂度。本笔记用于理清控制流、数据流和网络流的走向。
核心主题: HeadNode vs ComputeNode、FSx 共享原理、Slurm 调度逻辑、AMI 的战略意义。
1. 架构透视:Head Node 与 Compute Node 的关系
在 ParallelCluster 中,服务器被分为了两类,它们的地位完全不同:
| 角色 | Head Node (头节点) | Compute Node (计算节点) |
|---|---|---|
| 实例类型 | t3.medium (便宜 CPU 机) |
p4d.24xlarge (昂贵 GPU 机) |
| 生命周期 | 一直开机 (7x24) | 按需开关 (用完即毁) |
| 职责 | 1. 接受用户登录 (SSH) 2. 运行 Slurm 控制器 3. 存放代码和脚本 | 1. 只负责计算 2. 甚至不需要公网 IP 3. 不允许用户直接登录修改配置 |
| YY 的理解 | 指挥塔。李博士只跟它交互。 | 雇佣兵。招之即来,挥之即去。 |
操作启示:
-
千万不要在 Compute Node 上手动装软件!因为它们下次启动时,所有手动改动都会丢失。
-
所有的软件环境,必须固化在 AMI 里,或者写在 启动脚本 里。
2. 数据流解密:代码是怎么"飞"到 4 台机器上的?
-
传统误区: 以为要用
scp把代码拷贝到每一台机器,或者每台机器都去git pull。 -
真相(Shared Storage Pattern):
-
我们在 Head Node 和所有 Compute Nodes 上,都挂载了同一个 FSx for Lustre 文件系统,挂载点通常是
/fsx。 -
操作: 李博士在 Head Node 上把代码放入
/fsx/project/。 -
效果: 哪怕 Compute Node 还没启动,只要它一旦启动并挂载
/fsx,它立刻就能看到那份代码。 -
数据同理:
/fsx/datasets/也是所有节点共享的。
-
3. 控制流解密:Slurm 是如何"点火"的?
Slurm 的 srun 命令是整个集群的灵魂。
-
场景: 4 台机器,每台 8 张卡,共 32 卡。
-
命令:
srun python train.py -
Slurm 做的事:
-
SSH 广播: Slurm 会在毫秒级的时间内,通过内部的高速网络,同时向 4 台机器发送启动指令。
-
环境变量注入: 它会告诉第 1 台机器:"你是 Rank 0(老大)";告诉第 4 台机器:"你是 Rank 3"。
-
进程绑定: 它确保
train.py这个进程准确地绑定在显卡上,而不是跑在 CPU 上。 -
日志聚合: 4 台机器打印出来的 Log,会被 Slurm 收集起来,统一显示在 Head Node 的终端里。李博士不用去 4 台机器上看日志。
-
4. 关键决策复盘:为什么必须用 Custom AMI?
这是 Day 9 最容易被忽视,但最重要的操作。
-
如果不做 AMI:
-
每次 Slurm 拉起 4 台新机器,AWS 都要从纯净的 Ubuntu 开始安装。
-
安装 NVIDIA 驱动(重启)、安装 Docker、安装 PyTorch、安装 EFA 驱动...
-
耗时: 至少 40 分钟。
-
后果: 李博士提交任务后,要等 40 分钟机器才能跑起来。且一旦中间网络抖动,安装失败,任务直接挂掉。
-
-
做了 Custom AMI (Day 2 的成果):
-
耗时: 2-5 分钟(仅仅是 AWS 启动虚拟机的时间)。
-
稳定性: 100%。环境是我们在 Day 2 亲手调教好的,绝对不会缺库。
-
5. 网络参数复盘:YAML 里的玄机
在 cluster-config.yaml 里,有两段配置是绝对不能省的:
-
PlacementGroup: Enabled-
物理意义: 强行要求 AWS 把这 4 台 P4d 放在同一个机架或相邻机架。
-
如果不配: 机器可能一台在机房东头,一台在西头。光速跑过去都要几微秒,这对于 AI 训练的梯度同步是不可接受的延迟。
-
-
Efa: Enabled&GdrSupport: true-
物理意义: 开启显卡直连网卡(GPUDirect RDMA)。
-
如果不配: 数据要先从显卡拷贝到 CPU 内存,再拷贝到网卡。CPU 会被累死,显卡会闲置等待数据。
-