架构揭秘:控制平面与数据平面
Monarch 的高性能源于其独特的设计哲学:控制平面与数据平面的严格分离,以及一套用 Rust 编写的底层引擎 Hyperactor。
1. 双层架构
控制平面 (Control Plane) - Python
- 职责:逻辑编排、任务分发、状态监控;
- 实现:基于 Python。用户编写的单控制器脚本运行在这一层;
- 通信:使用高效的多播树(Multicast Trees)。当控制器调用
mesh.method()时,指令并非通过 for 循环逐个发送,而是通过树状结构层层转发——这就是 Monarch 能把一条消息组播到上千台机器还保持低延迟的原因。
数据平面 (Data Plane) - Rust + RDMA
- 职责:重型数据的搬运(Tensor、模型权重);
- 实现:基于 Rust 开发的 Hyperactor 引擎;
- 通信:直接利用 RDMA(Remote Direct Memory Access),基于 libibverbs 走 InfiniBand 或 RoCE。
2. 为什么需要分离?
在 AI 训练中,控制指令("开始训练第 N 步")非常小但频率高;数据传输("同步 70B 模型的梯度")非常大。如果混在一起处理,大数据传输会阻塞控制指令,导致 GPU 空转。
Monarch 的设计保证了:
- 控制指令走低延迟的消息树;
- 数据传输走高吞吐的 RDMA 通道,且绕过 CPU——网卡与显存直通。
RDMABuffer API 体现了这一分离:消息里传递的只是轻量级的缓冲区引用,真正的数据搬运在你显式调用时才发生(详见《RDMA 编程》一章)。
3. Hyperactor 与无畏并发
Monarch 的底层是一个名为 Hyperactor 的高性能分布式 Actor 系统(仓库内的 hyperactor* 系列 crate),用 Rust 编写:
- Fearless Concurrency:Rust 的所有权机制保证处理大量并发消息时不出现数据竞争;
- 零拷贝数据路径:直接管理 GPU 显存指针,实现从网卡到显存的直通;
- 进程即 Actor 树:每个进程、每个 Actor 都有父级,构成严格的监督层级(下一章详解)。
想深入了解 Hyperactor 的设计,官方文档附带一本 Hyperactor Book,覆盖底层 Actor 运行时与系统架构。
4. 工程细节:从仓库布局看架构
浏览 Monarch 仓库的 crate 结构,可以直观感受这套架构的分工:
| 组件 | 职责 |
|---|---|
hyperactor | 核心 Actor 运行时 |
hyperactor_mesh / hyperactor_mesh_admin_tui | 网格管理与终端诊断工具 |
monarch_rdma / rdmaxcel-sys | RDMA 数据平面(libibverbs 绑定) |
monarch_tensor_worker | 分布式张量的 worker 执行单元 |
monarch_extension / monarch_mini | Python 扩展与轻量构建 |
torch-sys2 / nccl-sys | PyTorch / NCCL 的 Rust 绑定 |
PyO3 把 Rust 引擎暴露给 Python:monarch/_rust_bindings 下的 .pyi 类型存根就是两层世界的接口文档。也正因为 Rust 二进制要链接 Python 库,官方要求跑 Rust 测试前必须先激活某个 Python 环境。
5. 单控制器 vs SPMD:一个对照
| 维度 | SPMD(torchrun 启动) | 单控制器(Monarch) |
|---|---|---|
| 编程模型 | 每个进程跑同一份脚本 | 一个脚本编排全部进程 |
| 控制流 | 集体同步原语内隐式 | 显式 if/for/try-except |
| 调试 | 断点会卡住整个 world | 控制器可随意交互,worker 保持运行 |
| 容错 | 通常整 world 重启 | 监督树细粒度恢复 |
| 适用场景 | 稳态大规模训练 | 编排、调试、异构工作流 |
关键点
- 控制平面(Python 消息树)与数据平面(Rust RDMA)严格分离,各走各的最优路径;
- Hyperactor 是 Rust 底座,提供 Actor 运行时、网格管理与零拷贝传输;
- PyO3 桥接两个世界,
.pyi存根是权威 API 参考; - 单控制器的真正优势在编排、交互调试与容错,而非替代 SPMD 的稳态吞吐。
下一章,我们看看这套架构如何支撑"渐进式容错"。
