《分布式 AI 系统》GPU 算力与实验环境搭建指南

读了书却缺集群?花几美元搭一套跨机分布式训练环境。

《分布式 AI 系统》封面

纸上得来终觉浅:为什么必须亲手跑一次“多节点”?

最近不少读了《分布式 AI 系统》(Distributed AI Systems)的读者朋友,在后台和社群里问了我同一个很普遍的现实困惑:

“书里讲的 DDP 原理、跨机通信拓扑、NCCL 集合通信和 Slurm 调度我都看懂了。但我平时工作或自己手头根本没有几十张卡的大集群,最多只有单卡机或者双卡机。我特别想亲手跑一次真正的跨节点分布式训练(哪怕只是两台机器、每台各一张卡),到底去哪里找环境?怎样才能花最少的钱跑起来,还不踩网络配置的坑?”

这个问题提得非常好。

搞分布式系统,光在单机上跑跑 Demo 是远远不够的。单机环境(哪怕是单机多卡)往往会把许多真正的分布式工程细节给“掩盖”掉:

  • 概念容易混淆:在单台双卡机器上,GPU 0 的全局号和本地号都是 0(rank=0, local_rank=0),GPU 1 也恰好都是 1(rank=1, local_rank=1)。很多初学者分不清 RANKLOCAL_RANK 的本质区别,甚至代码里写错了在单机上也会碰巧跑通;

  • 网络通信被降级为回环:单机训练走的是本地回环(127.0.0.1)或 PCIe/NVLink,你根本体会不到网络延迟抖动、跨机 Rendezvous 主节点握手、NCCL 动态端口协商以及跨网卡通信的真实挑战。

只有当你真正把训练任务分发到两台物理隔离的机器(比如最经典的 2 Nodes, 1 GPU/Node 拓扑)上时,两台机器的 GPU 都叫 cuda:0local_rank=0),但全局进程号分别为 rank=0rank=1,跨机寻址与集合通信的真实世界才会向你完全敞开。

今天这篇笔记,就是专门写给所有手头没有现成集群、但渴望动手实战多机分布式训练的读者。

我把目前业界最实用、性价比较高的几种跨机实验方案整理出来,连同实际操作中会遇到的平台细节一并讲清楚,哪怕你手里只有几美元预算(花费甚至不到一杯咖啡),也能少走弯路,跑通书里的多机实验。

方案一:单机双卡模拟双机单卡(以 Vast.ai 为例)

很多工程师初学分布式训练时,第一直觉往往是:“既然要跑多节点,我是不是必须先找两台物理机器、把网络连通起来?”

其实不然。在分布式系统工程中,最高效的调试方法始终是“关注点分离”:先把进程拓扑、设备映射(Device Ordinal)与控制流逻辑调通,再去硬刚真实的物理网络。 否则一旦程序卡死,你根本分不清是自己的代码逻辑写错了,还是底层的网络端口被拦截了。

因此,门槛最低、反馈最快的第一步,是用一台“双卡机器”虚拟出两台“单卡节点”

如果你本地没有现成的双卡设备,完全不需要大费周章去采购硬件或申请昂贵的企业级算力,目前门槛最低的途径是在 Vast.ai 这样的 GPU 算力众包平台上临时租用消费级显卡实例。

但这里有一个至关重要的工程选型原则,也是绝大多数初学者最容易走弯路的地方:

直接租一台“2x GPU”双卡实例,千万不要租两台“1x GPU”单卡实例去尝试跨机组网!
Vast.ai 上的机器大多是散落在全球各地的个人或独立数据中心 Docker 容器,处于复杂的公网 NAT 之后。一方面容器内部普遍缺失 /dev/net/tun 内核模块,导致 Tailscale/WireGuard 这类 Mesh VPN 根本打不通;另一方面,PyTorch DDP 和 NCCL 需要在运行时动态协商大量随机端口进行集合通信,公网端口映射完全覆盖不了,结果几乎 100% 会在第一次 all_reduce 时无限卡死。

最极客破局方案:直接在 Vast.ai 上租一台“单机双卡”实例,用环境变量虚拟出两台独立的单卡机 - “双机单卡”!

一台配备 2x RTX 5070Ti2x RTX 4090 的实例,在 Vast.ai 上每小时只需要 \$0.20 ~ \$0.50(不到半美元),而且不需要任何企业认证或人工配额审批,充值几美元即可秒级开机。

1. 租用双卡实例

注册为 Vast.ai 的用户,设置好你的 SSH Key,然后进入搜索界面如下:

在 Vast.ai 筛选器中设置:

  • GPUs:选择 2X
  • Template:选择 PyTorch 官方镜像(支持 CUDA 13)。

找到价格合适(比如 $0.27/hr)的机器点击 RENT

然后点击左边的Instances, 可以看到Instance正在被创建:

等待一两分钟,状态变为 running,你就会看到一个蓝色的 Connect 按钮。

点击按钮会看到 SSH 命令:

在终端输入这个命令就可以SSH进入远程GPU节点了。

2. 源码克隆和tmux终端分屏

当你已经 SSH 进去,应该是身处 tmux 会话中。

先把本书的附带源码克隆下来:

git clone https://github.com/PacktPublishing/Distributed-AI-Systems.git

Vast.ai 的 PyTorch 官方镜像里已经预装好了配套 CUDA 版本的 torch,直接用镜像自带的环境装本书的配套包即可

pip install distai

别急着 python -m venv:新建的虚拟环境默认会把镜像预装的 site-packages 隔离掉,torch 和 CUDA 运行时一并消失,而 pip install distai 并不会帮你把匹配当前驱动版本的 torch 装回来,重装一次又要拖好几个 GB。如果确实需要隔离环境,记得加上 --system-site-packages

bash python -m venv --system-site-packages .venv && source .venv/bin/activate

最后直接通过 tmux 分屏获得两个终端:

  • 左右分屏(切成左右两个终端):

按下快捷键组合:Ctrl + b,松开,然后按 %(即 Shift + 5

  • 上下分屏(切成上下两个终端):

按下快捷键组合:Ctrl + b,松开,然后按 "(双引号,即 Shift + '

常用分屏操作

  • 在两个分屏之间切换光标

Ctrl + b,松开,然后按 键盘方向键 / / )。

  • 关闭当前分屏

在那个终端里输入 exit 或按 Ctrl + d 即可。

分屏后:

  • 终端 1(分屏 1):充当 Node 0(模拟第一台单卡机);
  • 终端 2(分屏 2):充当 Node 1(模拟第二台单卡机)。

我的例子:

3. 核心黑魔法:用 CUDA_VISIBLE_DEVICES 启动训练

在两个终端中分别设置环境变量,限制各自进程能看到的显卡:

# ==========================================
# 终端 1(模拟 Node 0:全局 rank 0,本地卡 0)
# ==========================================
CUDA_VISIBLE_DEVICES=0 torchrun \
  --nnodes=2 \
  --nproc_per_node=1 \
  --node_rank=0 \
  --master_addr=127.0.0.1 \
  --master_port=29500 \
  chapter3-distributed-training-with-pytorch-ddp/code/profile_ddp.py
# ==========================================
# 终端 2(模拟 Node 1:全局 rank 1,本地卡 0)
# ==========================================
CUDA_VISIBLE_DEVICES=1 torchrun \
  --nnodes=2 \
  --nproc_per_node=1 \
  --node_rank=1 \
  --master_addr=127.0.0.1 \
  --master_port=29500 \
  chapter3-distributed-training-with-pytorch-ddp/code/profile_ddp.py

为什么这是学习与验证多节点逻辑最高效的方式?

  • 100% 还原跨节点设备拓扑

  • 在终端 2 启动的 Python 进程眼中,由于设置了 CUDA_VISIBLE_DEVICES=1,CUDA 运行时驱动层被严格限制,它只能看到一张物理卡,且在它眼里的局部编号必定是 0

  • 此时系统的真实状态为:

    • 终端 1(Node 0):全局 RANK = 0,本地 LOCAL_RANK = 0,访问设备 cuda:0
    • 终端 2(Node 1):全局 RANK = 1,本地 LOCAL_RANK = 0,访问设备 cuda:0
  • 精准暴露代码中的常见 Bug

  • 如果代码中误把张量搬运写成了 data.cuda(rank),终端 2 就会试图去找 cuda:1,瞬间被底层拦截并抛出经典的 invalid device ordinal 报错;只有写成规范的 data.cuda(local_rank) 才能畅通无阻。

  • 零网络阻碍,秒级反馈

  • 节点间的 Rendezvous 握手直接走本机回环接口(127.0.0.1),完全不存在跨公网的延迟丢包与防火墙拦截,代码改完立刻重启验证,调试循环只要几秒钟。

也要清楚这一招的边界:两个进程跑在同一台物理机上,NCCL 在拓扑探测阶段会发现它们 hostname 相同,于是集合通信实际走的是共享内存与 CUDA IPC(P2P),根本不经过网络传输层。所以这套方法能百分之百验证设备映射(rank / local_rank)与控制流逻辑,但验证不了跨机网卡绑定、NCCL_SOCKET_IFNAME 选错网卡、MTU 与防火墙拦截这类真实网络问题——那些必须留给下面的方案二。

方案二:进阶真实跨机——公有云原生 VPC 实战(以 Oracle Cloud OCI 为例)

当你在方案一中把代码逻辑、ranklocal_rank 的映射彻底理顺之后,如果希望进一步感受真实的物理网络延迟、跨机网卡绑定与内网防火墙机制,使用主流公有云的 GPU 实例 + 原生私有网络(VPC)是标准首选。

关于 AWS EC2 和 Google Cloud (GCP) 的基础开机教程网上已经汗牛充栋,但在实操中它们普遍有两个痛点:一是新账号的 GPU 配额审批极为严苛且漫长,二是入门机型显存偏小(如 T4 仅 16GB,虽然便宜但在大模型面前捉襟见肘;而 A10G / L4 24G 机型单价偏高)。

相比之下,Oracle Cloud Infrastructure (OCI) 凭借 24GB 显存的 NVIDIA A10、高达 240GB 的系统内存以及极具竞争力的按小时计费,成为目前大模型与分布式工程验证中最具性价比的公有云选择。

下面我将以自己亲手在 OCI 上申请与部署的完整实操记录,手把手拆解从配额审批、资源避坑、费用计算到双节点组网的全流程。

1. 申请 GPU 服务限额(Service Limits)与极速获批

每一个全新的公有云账号,其 GPU 配额(Quota)默认全都是 0。在 OCI 中,这被称为 Service Limits

纯免费试用账号是没有 GPU 权限的,必须先绑定信用卡升级为 Pay As You Go (PAYG)。升级后在后台提交工单:
- Service:选择 compute
- Limit Name:选择 gpu-a10-count
- Requested Value:建议初次申请填 1(最容易稳过)或 2
- Reason:简明扼要写明学术研究或分布式训练测试,例如:

"For PyTorch distributed training and model validation testing"

很多人以为云厂商的审批要等好几天,但只要填写规范、理由合理,OCI 的审核非常高效。我在下午 5:47 提交申请,不到 4 个小时(当晚 9:36)就收到了官方审批通过的通知邮件:

在 OCI 控制台的 Limit increase requests 页面中,可以看到该申请的状态已经正式变更为绿色的 Approved

2. 看懂 OCI 的“Critical 警报”:配额(Quota)与物理库存(Capacity)的本质区别

在获批之后创建实例时,很多开发者第一次看到下面这个界面会被吓一跳:

界面上赫然弹出了黄色警告:

Service limits status — Some resource limit is critical.
GPUs for GPU A10 based VM and BM instances: Usage 0 of 1, Can select existing: No

这究竟是代表机房没卡了,还是账号被限制了?

答案是:都不是!
- Usage: 0 of 1 明确告诉你:你的账号当前占用了 0 张卡,最大允许使用 1 张卡——你当前完全有资格启动 1 台单卡 A10 实例!
- 为什么会报 critical?因为一旦你启动这台机器,你的配额占用就会瞬间从 0/1 变成 1/1(达到 100% 满额),OCI 系统机制会自动将其标记为资源临界警报;
- “Can select existing: No” 只是说当前流程里没有可复用的现有资源分配,不影响新创建。

核心工程认知:配额(Quota)≠ 物理库存(Capacity)
配额是云厂商给你的“许可额度”。只要你没在最终点击 Create 实例时遇到 Out of host capacity 报错,就说明物理机房依然有空闲算力,完全可以大胆继续推进。

3. 机型规格选择(Shape)与真实计费真相

在 OCI 的 Browse all shapes 界面中,GPU 机型归类在 Specialty and previous generation 下:

展开选中 VM.GPU.A10.1,可以看到其极其彪悍的硬件底盘:

  • GPU 算力:1 × NVIDIA A10(24 GB 独立显存);
  • CPU 核心:15 OCPU(相当于 30 个 vCPU,Intel Xeon Platinum 8358,2.6 GHz);
  • 系统内存:高达 240 GB RAM(特别提醒:这是宿主机内存,不是显存,但在处理大规模数据加载、Shuffle 与 Checkpoint 序列化时极具优势);
  • 网络带宽:24 Gbps。
计费真相:月度估算是怎么算出来的

选中该机型时,右侧会弹出一个费用估算:
Estimated total: \$1,490.00 / month(其中计算费 1,488 美元/月,系统盘 2 美元/月):

这个数字对应的是 全月 744 小时(24×7 永不停机) 的场景,不是开机那一刻就要付的钱。

做个简单的算术:

$$\$1,488 \div 744 \text{ 小时} = \mathbf{\$2.00 / \text{小时}}$$

也就是说,这台 24G 显存 + 240G 内存的服务器,实际计算费用是每小时 $2.00
跑一次验证实验通常只需要 1~2 小时,总共花费不过 \$2 ~ \$4。实验跑完后在控制台点击 Terminate(并勾选 Permanently delete the attached boot volume),计费瞬间截止。

4. 双卡机型 VM.GPU.A10.2:从单卡配额到双卡配额

单卡 A10.1 能验证 rank 映射、跨机寻址这些逻辑,但如果你要的是真正的单机双卡 NCCL 通信(而不是靠 CUDA_VISIBLE_DEVICES 模拟),就绕不开双卡机型 VM.GPU.A10.2 了。

VM.GPU.A10.2 的规格直接翻倍(2 张 A10 48G 显存、30 OCPU、480 GB 内存、48 Gbps 带宽,约合 $4.00/小时):

OCI 还提供了消费预估的功能,作为用户我非常喜欢这个设计。

但如果你在只有 1 张卡配额的情况下勾选它,控制台会立刻弹出醒目的红色致命错误:

原因一目了然:VM.GPU.A10.2 需要 2 张 A10,而当前配额只有 1 张。在公有云上,“在列表中可见”绝不代表“有权创建”——配额是按 GPU 张数算的,不是按机型算的。

这时候不用改变主意,直接回到配额页面再次点击 Request Increase,把申请值提升到 2(够用 A10.2)或 4(够同时开两台 A10.1 做真跨节点集群):

提交后可以在申请列表中追踪进度(还是同一张 Limit increase requests 列表页,这次看上面 a10 那一行,状态为 In progress):

5. 操作系统镜像选择与 VCN 网络 / 防火墙打通

开机与组网阶段,有两个值得提前了解的细节——不同于前几步都能拿截图对照,这两条是 OCI 网络与 Ubuntu 镜像的通用配置知识,供参考,具体是否需要以你自己环境里的实际报错为准:

  1. 操作系统镜像:首选 Ubuntu 24.04 LTS

创建页面中可能会默认出现 Canonical Ubuntu 26.04 等最新镜像。但对于深度学习体系(CUDA 驱动、PyTorch、NCCL、vLLM、SGLang),更成熟稳定的 Ubuntu 24.04 LTS 通常是更稳妥的选择,可以少踩一些前沿系统的底层编译链和驱动兼容性的坑。

  1. 打通 VCN 内网全端口与清空本地 iptables(一个常见的隐蔽坑)

  2. VCN 安全列表(Security List):默认仅开放 22 端口。一般需要在对应 VCN 的 Default Security List 中增加一条 Ingress 规则:源 CIDR 填当前 VCN 网段(例如 10.0.0.0/16,以你实际的 VCN 网段为准),IP 协议选择 All Protocols,放行内网全端口互通;

  3. 系统自带防火墙:OCI 官方镜像内部往往预置了比较严格的 iptables 规则,即使 VCN 安全列表全开,跨节点 NCCL 动态随机端口仍可能被本地系统丢弃。如果多机通信卡在这一步,可以登录机器执行:
    bash sudo iptables -P INPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -F

6. 运行真实跨节点 DDP 训练

配额提到 2 张卡之后,按第 3 节的流程重复创建两台 VM.GPU.A10.1(注意不是一台 A10.2)。创建时只要把它们放进同一个 VCN 的同一个子网——OCI 新账号默认只有一个 VCN,不手工改网络配置就天然满足这个条件。两台都起来之后,在控制台的实例详情页 Instance Information → Primary VNIC → Private IP Address 就能看到各自的私网地址。

假定 Node 0 私网 IP 为 10.0.0.10,Node 1 为 10.0.0.20。先在 Node 0 上 ping 10.0.0.20 确认内网通(不通就回到第 5 节检查 Security List 和 iptables),然后无需任何额外 VPN,直接在两台机器终端启动 torchrun

# Node 0(在 10.0.0.10 上执行)
torchrun --nnodes=2 --nproc_per_node=1 --node_rank=0 \
  --master_addr=10.0.0.10 --master_port=29500 \
  chapter3-distributed-training-with-pytorch-ddp/code/profile_ddp.py

# Node 1(在 10.0.0.20 上执行)
torchrun --nnodes=2 --nproc_per_node=1 --node_rank=1 \
  --master_addr=10.0.0.10 --master_port=29500 \
  chapter3-distributed-training-with-pytorch-ddp/code/profile_ddp.py

方案三:手头已有本地显卡?本地工作站的零成本实践

如果你手头本身就有双卡工作站(比如实验室工作站或个人台式机),你可能不需要云,甚至连 Vast.ai 都不需要,完全可以在本地实现零门槛实战:

场景 1:如果你本地刚好有双卡工作站(如双卡 3090 / 4090)

完全不需要任何云端实例。直接在本地机器上打开两个终端窗口,完全复用方案一中的 CUDA_VISIBLE_DEVICES 启动命令

  • 终端 1 绑定 CUDA_VISIBLE_DEVICES=0
  • 终端 2 绑定 CUDA_VISIBLE_DEVICES=1
  • 本机 0 成本、0 等待、纯回环秒通,这是最极致的日常算法调试环境。

场景 2:如果你手头只有一张单卡(如 1 张 RTX 4090)

很多开发者的个人电脑只有一张 24GB 显存的顶级 4090。此时你有两种优雅的玩法:

  1. 纯本地多进程逻辑验证

在编写控制流(主节点打印日志、Checkpoint 仅 Rank 0 存储)时,可以在 PyTorch 中用 Gloo 后端(也就是 CPU 后端)在本机虚拟出多个 Rank,优先把所有非通信逻辑理顺;

  1. 极客混合云(Hybrid Multi-Node,未实测,仅供参考)

  2. Node 0:以你本地的 RTX 4090 作为 Master;

  3. Node 1:云端租一台单卡实例,通过 Tailscale 等 Mesh VPN 打通本地和云端的虚拟内网;
  4. 这条路径本质上是要在真实公网 NAT 之间打通隧道,比方案一、方案二都更难保证成功——注意云端节点不要选 Vast.ai:前面方案一里提过,Vast.ai 的容器普遍缺 /dev/net/tun 内核模块,Tailscale/WireGuard 这类 Mesh VPN 根本建立不了隧道;这里更适合选 OCI 这样给你完整虚拟机(有内核模块访问权限)的云厂商。即便如此,Tailscale 隧道能否稳定打通、NCCL 动态端口能不能被两端网络放行,我自己没有实测验证过,遇到问题可以参考方案二里 VCN + iptables 的排查思路。

方案四:如果必须跑真正的 Slurm 集群?大厂云(AWS / GCP / OCI)的多机调度实战

很多读者在读到第 8 章(Running Distributed Training with SLURM)时,会产生一个非常自然的疑问:

“前面讲的 CUDA_VISIBLE_DEVICES 或直接 torchrun 都是交互式命令。但真实的超算中心或大厂 AI 基础设施全是用 Slurm 批量提交作业的(sbatch run.slurm)。我在单机或者 Vast.ai 上能不能搭一个 Slurm 集群来练手?”

答案是:在单机或 Docker 容器里模拟多节点 Slurm 极其痛苦,且得不偿失;如果必须实战 Slurm,去 AWS、GCP 或 OCI(甲骨文云)租两台虚拟机才是唯一正规、省心的途径。

1. 为什么在单机或容器里模拟 Slurm 巨麻烦?

要在单台机器或容器里假装跑起一个“像模像样”的多节点 Slurm 集群,你得踩过一整套复杂的系统级暗坑:

  • 守护进程链条:Slurm 不是单个可执行程序,它依赖 munged(鉴权服务,必须有专用密钥文件且权限必须为 400)、slurmctld(中心调度主控)和 slurmd(节点计算代理);
  • 单机假装多节点(MultipleSlurmd):要在同一台机器上假装是 Node 0 和 Node 1,必须在 slurm.conf 中为不同的 slurmd 守护进程手工分配不同的网络端口、独立的本地 Spool 目录和 CPU 绑定;
  • 容器环境权限残缺:像 Vast.ai 这种以 Docker 启动的实例,默认没有 systemd(PID 1 不是 init 系统),也没有完整的 Linux cgroup v2 隔离权限,想在里面托管后台服务,需要折腾 Docker-in-Docker,没有几个小时的 Linux 运维底子根本跑不起来。

2. 真实 Slurm 集群的三个硬性条件(只有原生公有云能满足)

真正的多节点 Slurm 集群,必须依赖具备原生 VPC(虚拟私有网络) 的公有云虚拟机(VM)或裸金属:

  1. 完整的 Linux 系统级权限:两台实例运行完整的 Ubuntu/RHEL 操作系统,由 systemd 正常管理后台服务,底层 cgroup 提供真正的资源隔离;
  2. 原生私网全端口解析:Node 0(10.0.0.10)与 Node 1(10.0.0.20)在同一个 VPC/VCN 内,通过主机名或内网 IP 自由建立 RPC 连接(默认走 6817/6818 调度端口),无需任何 VPN 打洞;
  3. 共享文件系统(NFS / EFS)——最关键的一环
    Slurm 调度多机作业时,要求所有节点看到完全一致的文件路径。当你在 Node 0 提交 sbatch run.slurm 时,Node 1 上的 slurmd 进程必须能在本地的同一个绝对路径下读到你的 Python 脚本、写出训练日志。在 AWS 上挂载一个 EFS,或者在 Node 0 起一个原生 NFS 服务挂载给 Node 1,所有节点路径瞬间统一。

3. 大厂官方的一键拉起工具(无需从零手动安装)

在公有云上,各大厂商早就为 HPC 和 AI 工程师准备了成熟的官方编排工具,不需要你手动一行行敲 apt install slurm-wlm

云厂商 官方 Slurm 一键部署方案 特点与适用场景
AWS AWS ParallelCluster(首选推荐) AWS 官方开源 CLI。写一个简短的 YAML 配置文件,一条命令 pcluster create-cluster,AWS 就会自动创建 HeadNode、ComputeNodes,自动配置好 Slurm 调度器、NVIDIA GPU 驱动和挂载好 EFS/FSx 共享存储。
GCP GCP HPC Toolkit / Slurm on GCP Google 官方提供的开源自动化蓝图(基于 Terraform),10 分钟在 Google Compute Engine 上自动编排出一套可扩展的 Slurm 集群。
OCI OCI HPC / Slurm Cluster Stack 甲骨文云 Resource Manager 自带的 Slurm 栈模版,搭配 OCI 著名的裸金属与 RDMA 网络,在大规模训练场景下极具性价比。

4. 一个极其省钱的实操诀窍:用 CPU 虚机做 Slurm 逻辑验证

很多工程师被多机 Slurm 劝退,是因为看到 GPU 机器昂贵的单价。

但请记住一个关键事实:如果你只是为了学习,为了跑通第 8 章的 Slurm 自动化调度流、作业分发与主节点寻址逻辑,你根本不需要租 GPU!

  • 在 OCI 上用 Always Free 额度开 2 台纯 CPU 虚拟机,例如 2 台 VM.Standard.E2.1.Micro(1/8 OCPU + 1GB 内存,永久免费)——前面第 3 节挑机型的截图里就能看到它标着 Always Free-eligible,不需要额外的 GPU 配额审批。(如果想用 Ampere A1 Flex 额度,注意 Oracle 在 2026 年 6 月悄悄把这部分免费额度从 4 OCPU/24GB 砍到了 2 OCPU/12GB,两台机器加起来只够分,比如各 1 OCPU/6GB;PAYG 账号是否受影响 Oracle 官方口径也不一致,建议开之前先在控制台核实自己账号当前的实际额度。A1 Flex 是 ARM64 架构,不过 Slurm 本身和 CPU 架构无关,slurm-wlm 在 Ubuntu 的 arm64 源里和 x86 一样正常安装,不会因为选了 ARM 机型多出什么坑。)
  • 配置成双节点 Slurm 集群后,直接提交你的 run.slurm 作业脚本;
  • 把 PyTorch 训练脚本里的 GPU 显存分配临时换成 CPU 张量运算,或者干脆只留一行 print(f"Rank {rank} connected to Master {master_addr}"),几秒钟就能验证整个分布式调度流程是否正确闭环。

这一步有个必须改的地方:纯 CPU 机器上没有 GPU,init_process_group(backend="nccl") 会在初始化阶段直接抛错退出,你根本走不到验证调度流那一步。务必把后端换成 Gloo(init_process_group(backend="gloo")),或者写成 backend = "nccl" if torch.cuda.is_available() else "gloo",让同一份脚本在 CPU 验证和 GPU 实跑之间无缝切换。

而作业脚本里真正的核心逻辑——动态解析主节点地址、通过 srun 把任务分发给所有节点、以及 Slurm 环境变量(SLURM_PROCIDSLURM_LOCALIDSLURM_NNODES)的自动注入:

# Slurm 作业脚本里最关键的一行:动态解析出主节点地址
MASTER_ADDR=$(scontrol show hostnames \
  "$SLURM_JOB_NODELIST" | head -n 1)

这套调度逻辑在两台永久免费的 CPU 小机器上跑的效果,与在价值百万的 H100 集群上 100% 完全一样。

结语

学分布式系统,最核心的不是死记硬背概念,而是建立对“网络拓扑”“资源映射”的肌肉记忆。

不需要几百万的算力预算,也不需要等待单位分配集群。一顿快餐的钱租两台云虚机,或者用 CUDA_VISIBLE_DEVICES 把手里的一张双卡机切成两个虚拟节点,亲手跑通一次多节点的集合通信与设备绑定,你对书本上所有架构图的理解就会彻底鲜活起来。真正花时间的,往往不是训练代码本身,而是配额审批、守护进程、内核模块这类平台细节——这些同样是分布式工程能力的一部分,值得和算法一起被认真对待。

欢迎来信到 xuanxinjishu@gmail.com,或者加我的 LinkedIn 聊聊你踩过的坑。


Github: https://github.com/PacktPublishing/Distributed-AI-Systems
Amazon 购买链接: https://www.amazon.com/dp/1807301710/
本书配套网站: https://distaisys.com/
Mocksphere 书本配套练习: https://www.mocksphere.com/categories/Distributed%2520AI%2520Systems/
分布式 AI 资料分享群: https://www.mocksphere.com/creator/groups/9/files/