MLX 分布式运行本地调试指南:mlx.launch 从 SSH 免密到多机跑通的 6 步完整流程
【免费下载链接】mlxMLX: An array framework for Apple silicon项目地址: https://gitcode.com/GitHub_Trending/ml/mlx
MLX 是苹果芯片上的数组计算框架,mlx.launch 负责把同一份脚本在多台 Mac 或多个进程上同时拉起,是 MLX 分布式运行与本地调试的核心入口。本文围绕 MLX 分布式调试和 mlx.launch SSH 配置展开:先做环境检查,再配好 SSH 免密与主机文件,用--verbose验证首次启动,最后按错误类型给出一套排障清单。全程只用官方工具链,命令可直接复用,读完你就能把单机代码扩展到两台机器。
开始前的环境检查清单:机器、网络与路径
动手之前,先确认下面几条都成立。绝大多数“连不上”的问题,其实都卡在这一步。
- ✔ 至少准备 2 台能通过 SSH 登录的 Mac;只想先验证逻辑时,1 台就够,用
-n起多进程即可。 - ✔ 各节点在同一网络内可达(以太网 / 雷雳 / 同网段 Wi-Fi)。ring 后端走 TCP socket,必须能被对方网络访问到。
- ✔ 每个节点装相同版本的 Python,且待运行脚本放在相同路径。解释器路径可用
mlx.launch --print-python查看并逐台比对。 - ⚠️ 想用 JACCL(雷雳 RDMA)需 macOS 26.2+,且必须在恢复模式执行
rdma_ctl enable,这一步无法远程完成,详见 docs/src/usage/distributed.rst 的 JACCL 小节。
让两台 Mac 互相信任:SSH 免密登录配置
mlx.launch 的每个节点进程本质上是ssh一条命令包装起来的远端任务,所以“能免密 SSH”是分布式运行的前提。下面三步分别解决“有没有密钥、密钥到没到对面、真的免密了没”。
生成密钥对,给 mlx.launch 一把不依赖密码的钥匙:
ssh-keygen -t ed25519 -C "mlx-distributed"把公钥推到远端节点,这一步决定了后面ssh是否还弹密码:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@node2最后验证。要求是不弹密码、也不弹 host 确认,直接回显ok:
ssh user@node2 "echo ok"如果这里还会要密码,mlx.launch 一定起不来,先别往下走。
用 mlx.distributed_config 自动生成主机文件
主机文件(hostfile)告诉 mlx.launch“登录谁、用哪个 IP 通信”。手写 JSON 容易漏字段,用官方工具生成最稳妥。以太网场景下,这条命令会 ssh 到各节点、提取en0的 IP 并写出主机文件:
mlx.distributed_config --verbose --hosts node1,node2 --over ethernet \ --output-hostfile hosts.json生成后打开hosts.json,结构很简单——一个节点对象的数组:
[ {"ssh": "node1", "ips": ["192.168.1.101"]}, {"ssh": "node2", "ips": ["192.168.1.102"]} ]字段含义:ssh是登录用的主机名或别名,ips是该节点通信时绑定的 IP(ring 后端必填,且 rank 0 的 IP 必须能被所有节点访问到)。雷雳场景改用--over thunderbolt,工具会帮你识别 ring / mesh 拓扑并给出配置命令;JACCL 还要求额外填写rdma设备列表。
mlx.launch 首次启动:从单进程到多节点
先在单机上把逻辑跑对,再上多机,能排除掉一大半“是代码问题还是网络问题”。
单机两进程自测,-n 2表示本机起 2 个进程:
mlx.launch -n 2 my_script.py正常的话,你会看到 rank 0、1 各打印一行、且求和结果正确。确认无误后再上多机。注意 ring 后端的--hosts只收 IP、不收主机名;要按主机名登录,就交给--hostfile:
mlx.launch --hosts 192.168.1.101,192.168.1.102 my_script.py mlx.launch --hostfile hosts.json my_script.py加--verbose能打印正在运行的命令和每个节点的完成状态,ring 后端还会自动打开MLX_RING_VERBOSE=1。mlx.launch 会把每个进程的 stdout/stderr 转发回本地,并把 stdin 广播给所有进程,所以交互式调试(比如pdb)也能直接用。
mlx.launch 报错排查:三类高频故障的定位方法
报错时别慌,按“症状 → 可能原因 → 排查命令”对号入座。
症状 A:每次启动都弹密码或直接卡住。可能原因:SSH 免密没配好。排查:跑一遍ssh user@node2 "echo ok",哪台要密码就用ssh-copy-id给哪台补公钥。
症状 B:某节点报Failed to change directory或找不到 python。可能原因:各节点解释器或脚本路径不一致。排查:先mlx.launch --print-python拿到解释器路径,逐台核对;再确认脚本在每台机器上都存在且路径相同。
症状 C:ring 报“requires IPs, not hostnames”,或端口被占用连不上。可能原因:--hosts传了主机名,或--starting-port默认端口被占。排查:改用--hostfile,或用--starting-port/-p换一个起始端口(每个 rank、每个 IP 依次 +1)。
症状 D:通信层卡死,看不出哪个 rank 卡住。可能原因:GPU 侧任务依赖异常。排查:用 Xcode 的 Metal 调试器看任务依赖。先用MLX_METAL_DEBUG编译,再以MTL_CAPTURE_ENABLED=1运行并在代码里mx.metal.start_capture(...),把生成的.gputrace拖进 Xcode 的 Dependencies 视图回放,依赖关系一目了然。具体做法见 docs/src/dev/metal_debugger.rst。
该选哪种通信后端:ring / JACCL / NCCL / MPI
mlx.launch 通过--backend指定后端,不指定时 CUDA 环境默认nccl、其余默认ring。按硬件和拓扑选:
- ring(默认):基于 TCP socket,无第三方依赖、总是可用,官方称通常比 MPI 快。雷雳高带宽场景的首选。注意
--hosts只收 IP,可用--starting-port设端口、--connections-per-ip增加相邻节点连接数。 - JACCL:雷雳 RDMA,延迟比 ring 低一个数量级,适合张量并行等。要求节点间全连接 mesh,hostfile 必须含
rdma设备;--auto-setup需要各节点免密 sudo,否则会打印需手动执行的命令。 - NCCL:CUDA 环境默认。从 Mac 远程拉起 Linux GPU 时显式
--backend nccl;用-n起多机多卡,例如mlx.launch --backend nccl --hosts linux-1,linux-2 -n 8 -- ./my-job.sh。 - MPI:成熟完备,mlx.launch 是
mpirun的薄封装,自动处理DYLD_LIBRARY_PATH与MPI_LIBNAME。要求mpirun在各节点同路径、且节点间两两可达;用--mpi-arg透传参数,如--mpi-arg '--mca btl_tcp_if_include en0'指定网卡。
更多后端细节与“不用 mlx.launch 直接设环境变量”的方式,见 docs/src/usage/distributed.rst。
从单机到多机:完整流程回顾
把全流程串成一句话:环境检查清单 → SSH 免密三步 →mlx.distributed_config生成主机文件 →-n 2单机自测 →--hosts/--hostfile起多机 →--verbose验证 → 按症状排障 → 按硬件选后端。工具与参数汇总在 docs/src/usage/launching_distributed.rst,遇到具体报错优先回这两份文档对照。照这个顺序走,绝大多数本地调试的坑都能在第一轮就绕开。
【免费下载链接】mlxMLX: An array framework for Apple silicon项目地址: https://gitcode.com/GitHub_Trending/ml/mlx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考