分布式训练启动命令解析 | AI生成和翻译

Home 2026.06

问题: 解释这个 SSH + tmux + torchrun 命令中的每个参数,该命令用于启动 nanochat 的 2 节点分布式 CPU 训练运行的 master 节点。

回答:

这是一个分层命令:ssh → tmux → shell → torchrun → base_train。逐层分解。

第 1 层 — SSH 封装

ssh lzw@<WORKSTATION_IP> "..."

在您的 Ubuntu 工作站上以远程 shell 命令的形式执行引号内的字符串。末尾的 && echo OK 仅在 tmux 会话创建成功时打印 OK —— 向您的 Mac 发送一个简单的成功信号。最后的 0.6 不是命令的一部分 —— 看起来是一个粘贴时残留的额外字符(可能是 Warp 时间标注或 shell 历史片段)。如果它在引号内,shell 会将其视为 echo OK 的一个参数;根据现有写法,它位于结束引号之后,因此 ssh 实际上会将其作为附加的远程命令文本(以空格连接)发送,即远程会执行 ... && echo OK 0.6。无害,但应删除。

第 2 层 — tmux 会话管理

tmux kill-session -t dist-master 2>/dev/null

幂等性:终止任何先前名为 dist-master 的会话,以便重新运行命令时不会因“重复会话”而失败。2>/dev/null 在首次运行时吞掉“会话未找到”的错误。

tmux new-session -d -s dist-master '...'
2>&1 | tee /tmp/dist_master.log

将标准错误合并到标准输出(torchrun 和 PyTorch 大量记录日志到标准错误),然后 tee 将数据流复制到 tmux 窗格和日志文件中,您可以从另一个 SSH 会话中使用 tail -f 查看该日志。

第 3 层 — 环境变量

变量 目的
NANOCHAT_BASE_DIR=~/.cache/nanochat nanochat 的根目录,用于存放分词器、检查点、评估包
NANOCHAT_DATA_DIR=.../base_data_small 将预训练指向您的 FineWeb 小分片子集,而不是完整数据集
NANOCHAT_FORCE_SDPA=1 强制 PyTorch 使用 scaled_dot_product_attention 而非 FlashAttention —— 在 CPU 上是必要的,因为那里没有 FA 内核
OMP_NUM_THREADS=8 限制每个进程用于 CPU 矩阵乘法的 OpenMP 线程数。没有这个限制,每个 rank 都会尝试占用所有核心;在 2 节点 × 每节点 1 进程的情况下,8 个线程可以避免过度订阅
PYTHONUNBUFFERED=1 禁用 Python 的标准输出缓冲,以便 tee 和日志文件能实时获取行,而不是按 8KB 块输出
GLOO_SOCKET_IFNAME=enp4s0 告诉 Gloo 后端(CPU 集合通信后端)绑定到哪个网络接口。缺少此设置,Gloo 可能选择 lo 或 Docker 网桥,导致 rank 1 无法连接
NCCL_SOCKET_IFNAME=enp4s0 对 NCCL 做相同设置 —— 这里无害,因为 CPU 训练使用 Gloo,但如果您切换为 GPU,这可以作为廉价保险

IFNAME 配对是多节点设置中最容易出错的部分。错误的接口会导致 rendezvous 在“等待 workers”阶段永远挂起。

第 4 层 — torchrun(启动器)

torchrun --nnodes=2 --nproc_per_node=1 --node_rank=0 \
  --master_addr=<WORKSTATION_IP> --master_port=29500 \
  -m scripts.base_train -- ...

torchrun 会在每个生成进程中设置 RANKLOCAL_RANKWORLD_SIZEMASTER_ADDRMASTER_PORT 环境变量;base_train 在其 dist.init_process_group() 调用中读取这些变量。

第 5 层 — base_train 参数(模型和运行配置)

思维模型

整个命令的存在是为了回答一个问题:我的 2 节点 Gloo rendezvous 和梯度 all-reduce 能否在局域网内工作? 每个模型超参数都被压缩到接近零(深度 4,维度 256,10 步),因此运行在几分钟内完成,任何失败都是网络问题,而非计算问题。一旦打印出 OK 并且日志显示两个 rank 同步前进,您就可以交换 --device-type、IFNAME 后端和模型大小,进行真正的运行。

需要验证的一点:rank 1 的命令必须在 --nnodes--master_addr--master_port、总批次大小和所有模型参数上匹配 —— torchrun 不会捕获超参数不匹配的问题,而 rank 之间配置不一致会导致静默的形状错误或在第一次集合通信时挂起。


Back Donate