跳转至

分布式教程(Distributed Tutorials)

pld 词汇表按步骤讲解:一个十六步的教程系列,每步一个概念。全部十六个可运行 示例现已交付——从 "hello rank" 到点对点移动、动态 rank 数量、三种 all-reduce 及其揭示、其余集合通信动物园,以及一个组合 kernel。

前置条件: 先通读分布式编程章节——了解词汇, 再回到这里亲手构建同样的概念。硬件:步骤 01–06 需要两个设备,步骤 07 需要任意 ≥ 2 的数量(三个或更多才能看到环与 P=2 的差异),步骤 08–15 的集合通信对比需要四个设备。

思路(The idea)

参考章节告诉你 pld 是什么;本教程系列展示它 做什么。每个已交付步骤 都是一个小型、经 golden 校验的程序,只教授一个抽象,并且顺序经过设计: 先用原语手工构建每个概念,再让内置原语取代它:

  • 步骤 01–02 建立执行模型(rank 身份、三层模型)。
  • 步骤 03 引入 window memory——所有其他内容接触的基座。
  • 步骤 04 在揭示内置原语之前,先用 notify/wait 手工构建 barrier
  • 步骤 05–06 覆盖点对点移动(remote_load/remote_storeput/get)。
  • 步骤 07 让 rank 数量变成动态pl.dynamic("NR")):同一份源码可为 任意 P 编译——这是 P=4 集合通信所依赖的机制。
  • 步骤 08–11 用三种方式构建 all-reduce(mesh、two-phase、ring),然后 揭示 pld.tensor.allreduce
  • 步骤 12–15 覆盖其余集合通信(broadcast、allgather、reduce_scatter、 all_to_all),每个先手工再揭示。
  • 步骤 16 在一个 kernel 中组合 broadcast + allreduce + allgather—— 收官之作。

揭示纪律(Reveal discipline): 教程页面在揭示它们的步骤之前,不会引入 内置原语(pld.tensor.barrierpld.tensor.allreduce 等)——本索引仅预告 即将出现的内容。等到内置原语出现时,你已经写出手工版本,并知道它们 lower 成什么。

知识递进(Progression): 每个步骤只使用更早步骤(或前置章节)引入的 概念。当某个步骤提到较晚才讲解的内容——例如步骤 04 的 barrier 揭示中 用了一行 remote_load——那只是指引,不是必需知识:你可以在后续步骤中 正式认识它。

建议阅读顺序(Suggested reading order)

按顺序阅读这些步骤——01 → 02 → 03 → 04 → 05 → 06 → 07 → 08 → 09 → 10 → 11 → 12 → 13 → 14 → 15 → 16。每个页面都会重复此顺序块。全部 16 步 一起交付。

16 个步骤

步骤 程序 教授内容 状态
01 01_hello_rank.py Rank 身份、pld.world_size()DistributedConfig;一次 per-rank 分发 ✅ 已交付
02 02_programming_model.py 三层模型:@pl.jit.host@pl.jit@pl.jit.incore ✅ 已交付
03 03_window_buffer.py Window memory:alloc_window_buffer/window;仅自身 slice,无通信 ✅ 已交付
04 04_barrier.py 仅信号:notify(AtomicAdd)/wait(Ge);单次汇合 N-rank barrier;揭示 pld.tensor.barrier ✅ 已交付
05 05_remote_load_store.py Tile 级 RMA:remote_load/remote_store;一步环形移位 ✅ 已交付
06 06_put_get.py Tensor 级 p2p:put/get;push 与 pull ✅ 已交付
07 07_dynamic_rank_count.py 动态 rank 数量:pl.dynamic("NR");同一份源码,任意 P ✅ 已交付
08 08_allreduce_mesh.py All-reduce v1(mesh):每个 rank 读取所有对端,本地求和 ✅ 已交付
09 09_allreduce_two_phase.py All-reduce v2:reduce-scatter + all-gather ✅ 已交付
10 10_allreduce_ring.py All-reduce v3(ring):沿环分块 ✅ 已交付
11 11_allreduce_reveal.py 揭示pld.tensor.allreduce(mesh + ring);对比 IR ✅ 已交付
12 12_broadcast.py 一对多;揭示 pld.tensor.broadcast ✅ 已交付
13 13_allgather.py 全对全切片;揭示 pld.tensor.allgather ✅ 已交付
14 14_reduce_scatter.py 全对分块;揭示 pld.tensor.reduce_scatter ✅ 已交付
15 15_all_to_all.py 个性化交换;揭示 pld.tensor.all_to_all ✅ 已交付
16 16_putting_it_together.py 在一个 kernel 中组合 broadcast + allreduce + allgather ✅ 已交付

全部 16 步一起交付。下面的教程页面(06–21)覆盖步骤 01–16。

抽象总览(The abstractions map)

每个 pld 抽象:一行用途、文档它的章节小节、教授它的教程步骤。 教程的覆盖契约:代码中存在的任何内容都必须能由某个示例教授。

此总览中操作行的机器级对应物是操作目录 §分布式—— 集合通信、put/get、notify/wait 与 remote load/store 家族会 lower 为列在那里 的操作;上面的 window、context 与装饰器辅助项是没有目录条目的语言抽象。

系统基座(System substrate)

抽象 用途 章节小节 运行位置 教程步骤
pld.world_size() world 中的 rank 数量 02-primitives §系统基座 Host(编排器) 01
pld.get_comm_ctx(dt) 解析 DistributedTensor 所属的通信上下文 02-primitives §系统基座 Host / InCore 04
pld.rank(ctx) 本 rank 在上下文中的索引 02-primitives §系统基座 InCore 04
pld.nranks(ctx) 上下文中的 rank 数量 02-primitives §系统基座 InCore 04
pl.dynamic("NR") 命名一个运行期解析的维度(如 rank 数量) 00-getting_started 07

内存(Memory)

抽象 用途 章节小节 教程步骤
pld.DistributedTensor 绑定 window 的张量类型,对端可见 00-model §术语表 03
pld.alloc_window_buffer(...) 分配对称 per-rank window buffer 02-primitives §Window Buffer 管理 03
pld.window(...) window buffer 的 DistributedTensor 视图 02-primitives §Window Buffer 管理 03

信号(Signals)

抽象 用途 章节小节 运行位置 教程步骤
pld.system.notify(...) 在对端增加一个信号单元 02-primitives §Notify 与 Wait InCore 04
pld.system.wait(...) 阻塞直到信号单元达到阈值 02-primitives §Notify 与 Wait InCore 04
pld.NotifyOp.AtomicAdd 累加的 notify 模式(多写入者安全) 02-primitives §选择 NotifyOp 与 WaitCmp 04
pld.WaitCmp.Ge wait 模式:>= expected 时通过 02-primitives §选择 NotifyOp 与 WaitCmp 04

Tile 级 RMA

抽象 用途 章节小节 教程步骤
pld.tile.remote_load(...) 将对端的 window slice 拉入本地 tile 02-primitives §Tile 级 RMA 05
pld.tile.remote_store(...) 将本地 tile 推入对端的 window slice 02-primitives §Tile 级 RMA 05

Tensor 级点对点

抽象 用途 章节小节 教程步骤
pld.tensor.put(...) 将本地 window slice 推入对端的 window 02-primitives §Put 与 Get 06
pld.tensor.get(...) 将对端的 window slice 拉入本地内存 02-primitives §Put 与 Get 06
pld.AtomicType put/get 的原子性模式 02-primitives §Put 与 Get 06

集合通信(Collectives)

抽象 用途 章节小节 教程步骤
pld.tensor.barrier(...) 同步所有 rank(揭示的内置原语) 01-collectives §Barrier 04
pld.tensor.allreduce(...) 归约并广播结果(mesh/ring) 01-collectives §AllReduce 11
pld.tensor.broadcast(...) 一个 rank 的数据到全部 01-collectives §Broadcast 12
pld.tensor.allgather(...) 所有 rank 的切片到全部 01-collectives §AllGather 13
pld.tensor.reduce_scatter(...) 归约结果,每个 rank 一个分块 01-collectives §ReduceScatter 14
pld.tensor.all_to_all(...) 个性化交换 01-collectives §AllToAll 15

组合(Composition)

抽象 用途 章节小节 教程步骤
@pl.jit.host 主机编排器:分配 window、分发 rank 00-model §术语表 02
@pl.jit / @pl.jit.incore 每设备编排 / 设备端 kernel 03-execution 02
device=r 从主机循环将一次分发固定到某个设备 00-model 01
DistributedConfig 编译的设备列表与 worker 数量 03-execution 01

阅读路径(Reading path)

本阶梯是更长路径上的一站。分层的单设备示例教授本阶梯所假设的 pl 语言—— 它只需要 examples/beginner/examples/intermediate/。下面的阶段是推荐的 推进顺序;只有前两个是本阶梯的前置,后面的阶段是可选的后续:

  • pl 语言:examples/beginner/examples/intermediate/
  • 分布式阶梯:examples/distributed/01 … 16(本系列,P ≥ 2)
  • 更大规模:examples/advanced/examples/models/
  • 应用:pypto-lib(分布式 MoE、模型 JIT decode)

分布式阶梯是唯一需要多于一个设备的站点。

参见(See also)