Collective communication: algorithms, cost and the library that runs them集體通訊:演算法、成本與執行它們的函式庫
Learn how a collective is carried out step by step, how to predict its time from two numbers (latency and bandwidth), how NCCL turns a collective into network traffic, and how training hides collectives behind computation.了解集體操作如何一步一步執行、如何用兩個數字(延遲與頻寬)預測它的時間、NCCL 如何把集體操作變成網路流量,以及訓練如何把集體操作藏在計算後面。
This chapter builds on Chapters 2, 3. These earlier terms appear most often below; each chip links to its definition.
New terms in this chapter (13)本章新名詞(13)
Each term is defined in the text where it first appears; the link jumps there. Terms from earlier chapters are listed under "Before you start".
每個名詞都在它第一次出現的段落中定義,點連結可跳過去。前面各章的名詞列在「開始之前」。
- Ring all-reduce環狀 all-reduce Ranks pass chunks to their neighbor around a ring: a reduce-scatter then an all-gather. Each sends about 2× its buffer. 各 rank 沿環把資料塊傳給鄰居:先 reduce-scatter 再 all-gather。每個 rank 約送出緩衝區的 2 倍。
- Bandwidth-optimal頻寬最優 An algorithm whose busiest rank sends the fewest bytes possible; for all-reduce, 2(N−1)/N times the buffer. 最忙的 rank 送出最少位元組的演算法;all-reduce 為緩衝區的 2(N−1)/N 倍。
- α–β cost modelα–β 成本模型 Time of a collective ≈ α × (dependent steps) + bytes sent ÷ bandwidth; α is the latency of one step. 集體操作時間 ≈ α × (相依步數)+ 送出位元組 ÷ 頻寬;α 是每一步的延遲。
- Tree, recursive doubling and halving樹、遞迴加倍與減半 Algorithms with about log₂N steps instead of 2(N−1): fewer steps, more bytes per step. 約 log₂N 步、而非 2(N−1) 步的演算法:步數少,每步位元組多。
- Rabenseifner's algorithmRabenseifner 演算法 Recursive halving then doubling: the ring's byte count in only 2 log₂N steps, on a network where all pairs can talk at full rate. 先遞迴減半、再遞迴加倍:只用 2 log₂N 步達到環狀的位元組數;需要所有配對都能全速通訊的網路。
- Hierarchical all-reduce階層式 all-reduce Reduce-scatter inside each server over NVLink, all-reduce one slice across servers among same-local-rank GPUs, then all-gather inside. 先在伺服器內以 NVLink 做 reduce-scatter,再在各伺服器本地 rank 相同的 GPU 間 all-reduce 一個切片,最後在伺服器內 all-gather。
- In-network reduction網內歸約 Switches that add the data themselves, so each rank sends its buffer up once and receives the sum once. 由交換器自己做加總,每個 rank 只需送出一次緩衝區、接收一次總和。
- NCCLNCCL NVIDIA's collective communication library; PyTorch calls it for every collective. NVIDIA 的集體通訊函式庫;PyTorch 的每個集體操作都呼叫它。
- Communicator, channel通訊器(communicator)、通道(channel) A communicator is one group of ranks; a channel is one independent ring or tree inside it, with its own buffers and connection. 通訊器是一組 rank;通道是其中一個獨立的環或樹,有自己的緩衝區與連線。
- SM (streaming multiprocessor)SM(串流多處理器) One of the ~130 compute units inside a GPU. NCCL runs each channel on one SM, taking it from computation. GPU 內約 130 個運算單元之一。NCCL 每個通道占用一個 SM,從運算中拿走。
- Clear-to-send (CTS), receiver-driven admission允許傳送(CTS)、接收端准入 A small message in which the receiver names a free buffer slot; the sender may write only after it, which caps bytes in flight. 接收端指出一個空閒緩衝槽的小訊息;傳送端收到後才能寫入,因此限制了在途位元組。
- Overlap, exposed communication重疊、暴露的通訊 Running communication while the GPU computes; the part that outlasts the computation is exposed and adds to the step time. 在 GPU 運算時同時進行通訊;比運算更久的部分即「暴露」,會加到步驟時間。
- algbw, busbwalgbw、busbw The two numbers nccl-tests reports: buffer size ÷ time (algbw), and that rescaled by the algorithm's bytes so it compares with the link rate (busbw). nccl-tests 報告的兩個數字:緩衝區大小 ÷ 時間(algbw),以及依演算法位元組換算後可與鏈路速率比較的值(busbw)。
4.1The collectives, with sizes集體操作與它們的大小
| Collective | 集體操作 | Input → output per rank | 每 rank 的輸入 → 輸出 | Bytes sent per rank | 每 rank 送出位元組 | Who uses it | 誰在用 |
|---|---|---|---|---|---|---|---|
broadcast | Root has ; all end with . | 根持有 ;最後所有 rank 都有 。 | Loading a checkpoint to a DP group (MegaScale) | 把檢查點載入 DP 群組(MegaScale) | |||
reduce | All have ; root ends with the sum. | 所有 rank 有 ;根得到總和。 | Rare in training; loss logging | 訓練中少見;損失記錄 | |||
all-reduce | All have ; all end with the sum. | 所有 rank 有 ;所有 rank 得到總和。 | Classic DP gradients; TP partial sums | 傳統 DP 梯度;TP 部分和 | |||
reduce-scatter | All have ; each ends with of the sum. | 所有 rank 有 ;每個得到總和的 。 | ZeRO / FSDP gradients; TP with sequence parallel | ZeRO / FSDP 梯度;TP 搭配序列平行 | |||
all-gather | Each has ; all end with . | 每個有 ;所有 rank 得到 。 | FSDP parameters; CP keys and values; TP | FSDP 參數;CP 的 key 與 value;TP | |||
all-to-all | Each has blocks of ; block goes to rank . | 每個有 塊各 ;第 塊送到 rank 。 | Expert parallelism (MoE); embedding lookups | 專家平行(MoE);embedding 查找 | |||
send / recv | One rank's moves to one other rank. | 一個 rank 的 搬到另一個 rank。 | Pipeline activations and their gradients | 管線的激活值與其梯度 |
Two patterns in the table matter for the rest of this chapter. First, an all-reduce is exactly a reduce-scatter followed by an all-gather, and its byte count is the sum of theirs. That is why ZeRO and FSDP, which split the two halves apart in time, move the same total bytes as classic data parallelism; they just move them at different moments and keep less memory. Second, the byte count per rank does not grow with for any collective in the table. What grows with is the number of dependent steps, which is the subject of the next section.
表中有兩個模式對本章其餘部分很重要。第一,all-reduce 正好是一個 reduce-scatter 接一個 all-gather,位元組數也是兩者之和。這就是為什麼把兩半在時間上拆開的 ZeRO 與 FSDP,搬動的總位元組數與傳統資料平行相同;它們只是在不同時刻搬、並佔用較少記憶體。第二,表中沒有任何集體操作的每 rank 位元組數會隨 增長。隨 增長的是相依步驟的數量,這是下一節的主題。
Panel 4.1 computes these byte counts for any and .
面板 4.1 為任何 與 算出這些位元組數。
The mapping from parallelism to collective is fixed by the mathematics of the split. DP averages gradients: all-reduce in the classic form, reduce-scatter plus all-gather in ZeRO and FSDP. TP splits a weight matrix, so every layer must all-reduce the partial products, or all-gather inputs and reduce-scatter outputs under sequence parallelism. EP routes each token to the rank holding its expert: an all-to-all by definition. PP hands activations to the next stage: a point-to-point send. CP in Llama 3 gathers the keys and values of the whole sequence: an all-gather (Llama 3 §3.3). The sizes differ by orders of magnitude: for GPT-3 175B at TP=8, PP=8, DP=512, HPN's Table 3 lists 560 MB of TP, 5.5 GB of DP and 6 MB of PP traffic, without saying over what period (Chapter 5 reads the table).
平行化到集體操作的對應由切分的數學決定。DP 要平均梯度:傳統形式是 all-reduce,ZeRO 與 FSDP 是 reduce-scatter 加 all-gather。TP 切分權重矩陣,所以每一層都必須對部分乘積做 all-reduce,或在序列平行下對輸入做 all-gather、對輸出做 reduce-scatter。EP 把每個 token 送到持有其專家的 rank:依定義就是 all-to-all。PP 把激活值交給下一個階段:點對點傳送。Llama 3 的 CP 收集整個序列的 key 與 value:all-gather(Llama 3 §3.3)。大小相差好幾個數量級:GPT-3 175B 在 TP=8、PP=8、DP=512 下,HPN 的 Table 3 列出 TP 560 MB、DP 5.5 GB、PP 6 MB,但沒有說明是多長時間內的量(第 5 章會解讀這張表)。
4.2The ring all-reduce環形 all-reduce
The naive way to average gradients is to send everything to one server, add it up, and send the result back. That server's link becomes the bottleneck. The ring algorithm avoids this. The GPUs form a ring. Each GPU's data is cut into chunks. In the first phase (reduce-scatter), each GPU passes one chunk to its neighbor and adds the chunk it receives. After steps, every GPU holds the full sum of one chunk. In the second phase (all-gather), the complete chunks go around the ring again. After more steps, every GPU has everything.
把梯度取平均最直覺的做法,是把所有東西送到一台伺服器加總再送回去。那台伺服器的鏈路就會成為瓶頸。環形演算法避開了這個問題。GPU 排成一個環,每顆 GPU 的資料切成 塊。第一階段(reduce-scatter),每顆 GPU 把一塊傳給鄰居,並把收到的那塊加上去。經過 步,每顆 GPU 都持有某一塊的完整總和。第二階段(all-gather),完整的塊再繞環一圈。再經過 步,每顆 GPU 都拿到全部。
The number of bytes that each GPU sends is
每顆 GPU 送出的位元組數是
where is the size of its data. For large , this is almost exactly , and it does not grow with . No algorithm can do better in bytes sent per GPU. That is what bandwidth-optimal means. The cost is latency: sequential steps. For a ring of 1,000 GPUs, the steps add up. So NCCL uses rings for large messages and tree algorithms for small ones, and it builds hierarchical rings that stay inside a server first.
其中 是它的資料大小。當 很大時,這幾乎就是 ,而且不隨 增長。以每顆 GPU 送出的位元組數來看,沒有演算法能做得更好。這就是「頻寬最佳」的意思。代價是延遲:要跑 個連續步驟。一千顆 GPU 的環,步數會累積得很多。所以 NCCL 對大訊息用環、對小訊息用樹狀演算法,並且會先建立留在伺服器內的階層式環。
The figure shows every step for four GPUs. Each GPU starts with its own gradient , cut into four segments. A colored stripe in a segment means that GPU's data has been added into it. A "sends" row shows which segment each GPU passes to its right neighbor; the "after" row below it shows the result, with a red box around each segment that was just received and added.
下圖畫出四顆 GPU 的每一步。每顆 GPU 一開始只有自己的梯度 ,切成四段。某一段裡出現哪個顏色的條紋,代表那顆 GPU 的資料已經加進這一段。「送出」那一列顯示每顆 GPU 把哪一段傳給右鄰;下面的「後」那一列顯示結果,剛收到並加完的段用紅框標出。
The ring, one step at a time環,一步一步來
The figure above showed the ring as a picture. Here is the index arithmetic, because it explains why every link is busy in every step, and that is the property that makes the ring bandwidth-optimal. Number the ranks to and cut each rank's buffer into chunks, also numbered to . Rank always sends to rank and receives from rank .
上圖把環畫成一張圖。這裡給出索引算術,因為它解釋了為什麼每一步每條鏈路都在忙,而這正是讓環達到頻寬最佳的性質。把 rank 編號 到 ,把每個 rank 的緩衝區切成 塊,同樣編號 到 。rank 永遠送給 rank ,並從 rank 接收。
- Reduce-scatter, step (). Rank sends chunk , which it has partly summed, to its right neighbor. The neighbor adds its own copy of that chunk to what arrives. After step , the chunk that rank has just received contains the contributions of ranks. After steps, rank holds the complete sum of exactly one chunk, number , and partial sums of the others that it no longer needs.Reduce-scatter,第 步()。rank 把它已部分加總的第 塊送給右鄰。鄰居把自己那一塊加到收到的資料上。第 步之後,rank 剛收到的那塊包含 個 rank 的貢獻。 步之後,rank 持有恰好一塊的完整總和(第 塊),以及其他不再需要的部分和。
- All-gather, step (). Rank sends the complete chunk to its right neighbor, which overwrites its partial sum with the finished one. After steps every rank has every complete chunk.All-gather,第 步()。rank 把完整的第 塊送給右鄰,右鄰用完成品覆寫自己的部分和。 步之後每個 rank 都有每一塊完整的總和。
Count the traffic: in each of the steps, all links carry one chunk of bytes at the same time, and no link is idle while another works. The bytes per rank are , as in the table. Count the latency too: a step cannot start until the previous chunk has fully arrived and been added, so the ring pays a total of times. NCCL pipelines several chunks through each ring, which hides part of each , but the dependent chain still grows linearly with .
算一算流量:在 步的每一步,全部 條鏈路同時各承載一塊 位元組,沒有鏈路在別人工作時閒著。每 rank 的位元組數是 ,與表中一致。也算一算延遲:前一塊完整到達並相加之後下一步才能開始,所以環要付 共 次。NCCL 會讓數個 chunk 在每個環中管線化,隱藏每個 的一部分,但相依鏈仍隨 線性增長。
The figure below writes the two index rules as a table of the chunk that each rank sends in each step.
下圖把兩條索引規則寫成一張表:每個 rank 在每一步送出哪個 chunk。
The figure below records the whole run for as seven snapshots of the grid of ranks and chunks. Panel 4.2 then animates the same rules for 4, 6 or 8 ranks.
下圖把 的整個過程記成 rank 與 chunk 網格的七張快照。面板 4.2 則用同樣的規則為 4、6 或 8 個 rank 做動畫。
Animation 4.1 plays the same index rules on a physical ring of 3 to 8 ranks. Every link carries one chunk in every step, and each chunk fills as partial sums arrive.
動畫 4.1 在 3 到 8 個 rank 的實體環上播放同樣的索引規則。每一步每條鏈路都承載一塊,每塊隨著部分和抵達而逐漸填滿。
4.3The α–β cost modelα–β 成本模型
The oldest and still most useful model of message passing, the α–β model, has two parameters. is the latency of one message, from the decision to send until the receiver can act on the data, independent of size. is the time per byte, for a link of bandwidth . A message of bytes costs . A collective is a sequence of rounds in which every rank sends and receives at once, so its cost is
訊息傳遞最古老、也仍然最有用的模型——α–β 模型——有兩個參數。 是一則訊息的延遲,從決定發送到接收端能使用資料,與大小無關。 是每個位元組的時間,對頻寬為 的鏈路就是 。一則 位元組的訊息成本為 。集體操作是一連串每個 rank 同時發送與接收的回合,所以它的成本是
The two terms come from different physics. is set by software overhead, the NIC, and the propagation and switching delay of the path: tens of microseconds across several switch hops. Meta measured a round trip of about 22 µs across its training fabric, against the under-10 µs that NCCL's defaults assume (Meta RoCE paper, §6.1). is set by the slowest link: 400 Gb/s is 50 GB/s, so one gigabyte costs 20 ms. Everything in collective design is a trade between these two terms.
兩項來自不同的物理。 由軟體開銷、NIC,以及路徑的傳播與交換延遲決定:跨數個交換器跳數時是數十微秒。Meta 量到跨訓練網路的往返約 22 µs,而 NCCL 的預設假設是低於 10 µs(Meta RoCE 論文,§6.1)。 由最慢的鏈路決定:400 Gb/s 是 50 GB/s,所以一 GB 要 20 ms。集體通訊設計中的一切都是這兩項之間的取捨。
The figure below takes the formula apart for the two algorithms that the next subsections derive, a ring and a tree on 4 ranks. The ring pays six times and sends a small piece each time; the tree pays twice and sends the whole buffer each time.
下圖把這條公式拆開,用的是接下來兩小節要推導的兩種演算法:4 個 rank 上的環與樹。環付六次 、每次送一小片;樹只付兩次 ,但每次都送整個緩衝區。
Ring: bandwidth-optimal, latency-poor環:頻寬最佳,延遲不佳
In the ring all-reduce every rank sends bytes in each of steps. Its cost is therefore
在環形 all-reduce 中,每個 rank 在 步的每一步送出 位元組。所以成本是
The second term is as small as it can be: each rank must receive the other contributions to the slice it will own, bytes, and then the finished slices it does not own, another . No algorithm can deliver an all-reduce with fewer bytes into the busiest rank. The first term is the price. With 1,024 ranks and the ring spends in pure latency; for a 1 GB buffer the bandwidth term at 50 GB/s is 40 ms, so the ring is already more latency than data.
第二項已經小到不能再小:每個 rank 必須收到其他 個對它將持有那一片的貢獻,即 位元組,然後再收到它不持有的 片完成品,又是 。沒有演算法能用更少進入最忙 rank 的位元組完成 all-reduce。第一項是代價。1,024 個 rank、 時,環花 的純延遲;對 1 GB 的緩衝區,50 GB/s 下的頻寬項是 40 ms,所以環的延遲已經多於資料。
Trees: latency-optimal, bandwidth-poor樹:延遲最佳,頻寬不佳
The opposite design is recursive doubling. In step each rank exchanges its whole buffer with the rank whose index differs in bit , and adds. After steps every rank holds the full sum. The cost is
相反的設計是遞迴倍增。在第 步,每個 rank 與索引第 位元不同的 rank 交換整個緩衝區並相加。 步之後每個 rank 都持有完整的總和。成本是
For 1,024 ranks that is 10 steps instead of 2,046, but each rank now sends bytes ten times, five times more than the ring. Rabenseifner's algorithm (recursive halving for the reduce-scatter, doubling for the all-gather) gets the best of both in the model, , but needs a power-of-two and a fabric where every pair can talk at full rate at once. NCCL's own "tree" is a pipelined double binary tree that, in NVIDIA's description, keeps the byte count near the ring's while cutting the dependent steps to a logarithm. Treat the two formulas above as the ends of a spectrum and real implementations as points between them.
對 1,024 個 rank,那是 10 步而非 2,046 步,但現在每個 rank 要送 位元組十次,是環的五倍。Rabenseifner 演算法(reduce-scatter 用遞迴減半,all-gather 用倍增)在模型中兼得兩者之長:,但要求 是 2 的冪,且網路要讓每一對都能同時以全速通訊。NCCL 自己的「tree」是管線化的雙二元樹,依 NVIDIA 的描述,它把位元組數維持在接近環的水準,同時把相依步驟減到對數級。把上面兩條公式當成一條光譜的兩端,真實實作則是中間的點。
The butterfly below shows both tree schemes on 8 ranks. The exchange pattern is the same in both: in step each rank pairs with the rank whose index differs in one bit. Recursive doubling sends the whole buffer in every step; recursive halving sends half of what is left.
下方的蝶形圖在 8 個 rank 上畫出這兩種樹狀方案。兩者的交換模式相同:第 步每個 rank 與索引差一個位元的 rank 配對。遞迴倍增每一步都送整個緩衝區;遞迴減半只送剩下的一半。
Animation 4.2 plays both schemes on 4 or 8 ranks. In recursive halving the partner distance doubles while the message halves; the all-gather then runs the same pairs in reverse order.
動畫 4.2 在 4 或 8 個 rank 上播放這兩種方案。遞迴減半時夥伴距離加倍、訊息減半;接著 all-gather 以相反順序走同樣的配對。
NCCL's double binary tree is built so that two trees can work at the same time (figure below). Each tree is an ordinary binary tree over the nodes, but no node is an inner node in both trees, so no node has to forward data in both. Inside a node the GPUs form a chain, and the tree branches only between nodes (Demystifying NCCL, HOTI 2025).
NCCL 的雙二元樹是為了讓兩棵樹能同時運作而建的(見下圖)。每棵樹都是節點上一棵普通的二元樹,但沒有節點同時是兩棵樹的內部節點,所以沒有節點必須在兩棵樹裡都轉送資料。在一個節點內,GPU 串成一條鏈,樹只在節點之間分支(Demystifying NCCL,HOTI 2025)。
| Ring環 | Tree (binary)樹(二元) | Rabenseifner | |
|---|---|---|---|
| How data moves資料怎麼走 | around a ring, always to the same neighbor沿環走,永遠送給同一個鄰居 | up to the root, then back down往上到根,再往下 | swaps with a partner; the partner changes every step與夥伴交換;每一步換一個夥伴 |
| Sequential steps循序步數 | |||
| Steps for 1,024 GPUs1,024 顆 GPU 的步數 | 2,046 | 20 | 20 |
| Size of one message單則訊息大小 | , the whole buffer,整個緩衝區 | ||
| Bytes sent per GPU每顆 GPU 送出的位元組 | (a GPU at the bottom of the tree) to (inner GPU: up, to each child), if not pipelined不切塊時,(葉)到 (內部 GPU:往上 、給每個子節點各 ) | ||
| Strength優點 | fewest possible bytes; only neighbor links are used位元組數最少;只用到相鄰的鏈路 | few steps, so low latency for small messages步數少,小訊息延遲低 | fewest bytes and few steps位元組少、步數也少 |
| Weakness缺點 | steps grow with , so small messages are slow at scale步數隨 增長,大規模時小訊息很慢 | each message carries all of ; needs pipelining for large messages每則訊息都帶整個 ;大訊息必須切塊串流 | should be a power of two; distant partners load more links 最好是 2 的冪次;相隔遠的夥伴會占用更多鏈路 |
| Typical use典型用途 | NCCL, large messagesNCCL,大訊息 | NCCL (two pipelined trees), small and medium messagesNCCL(兩棵切塊串流的樹),中小訊息 | MPI libraries, large messagesMPI 函式庫,大訊息 |
The crossover交叉點
Set the ring and doubling costs equal and solve for . The message size at which they tie is
令環與倍增的成本相等並解出 。兩者打平的訊息大小是
Below the tree wins; above it the ring wins. The product , the bytes a link carries during one latency, appears in every formula in this chapter. For , and , is about . Double the latency and the crossover doubles, so a library tuned for a 5 µs fabric chooses the wrong algorithm on a 22 µs one: its table is off by four times.
以下樹勝出;以上環勝出。乘積 ——鏈路在一個延遲期間能承載的位元組數——出現在本章的每一條公式中。、、 時, 約為 。延遲加倍,交叉點就加倍,所以為 5 µs 網路調校的函式庫在 22 µs 的網路上會選錯演算法:它的表差了四倍。
The figure below plots both formulas for these values. For small messages each curve is flat at its latency term, for the ring and for the tree. For large messages each curve rises with its byte term, and the ring's curve is lower because the ring sends fewer bytes.
下圖畫出這組數值下的兩條公式。小訊息時每條曲線平在它的延遲項:環是 ,樹是 。大訊息時每條曲線隨它的位元組項上升,而環的曲線較低,因為環送的位元組較少。
Two worked examples兩個算例
A data-parallel gradient exchange. Llama 3 405B has 405 billion parameters; in bf16 the gradients are 810 GB. As a first estimate, let 128 data-parallel ranks each hold a full copy and all-reduce it over 400 Gb/s (50 GB/s) links with . In the real run (Llama 3 Table 4, row 2) the model is also split by TP = 8 and PP = 16, so each DP rank owns only a shard, and FSDP's reduce-scatter plus all-gather moves that shard. Both are compared with one step of compute at 400 TFLOP/s per GPU on 16,384 GPUs with a 16M-token batch. The arithmetic, one question per row:
一次資料平行的梯度交換。Llama 3 405B 有 4,050 億個參數;bf16 的梯度是 810 GB。先做第一個估計:讓 128 個資料平行 rank 各持有一份完整副本,在 400 Gb/s(50 GB/s)鏈路上以 做 all-reduce。在真實運行中(Llama 3 Table 4 第二行)模型還被 TP = 8 與 PP = 16 切分,所以每個 DP rank 只持有一個分片,由 FSDP 的 reduce-scatter 加 all-gather 搬動。兩者都與一步的計算量比較:16,384 顆 GPU、每顆 400 TFLOP/s、16M token 批次。逐列計算如下:
| Question問題 | Calculation算式 | Result結果 |
|---|---|---|
| Full-copy all-reduce, bandwidth term (810 GB, 128 ranks, 50 GB/s)完整副本 all-reduce 的頻寬項(810 GB、128 個 rank、50 GB/s) | s | |
| Full-copy all-reduce, latency term (254 dependent steps at )完整副本 all-reduce 的延遲項(254 個相依步驟,) | ms | |
| Parameters per DP rank with TP = 8 and PP = 16 (Llama 3 Table 4, row 2)TP = 8、PP = 16 時每個 DP rank 的參數(Llama 3 Table 4 第二行) | parameters, 6.3 GB in bf16個參數,bf16 下 6.3 GB | |
| FSDP reduce-scatter plus all-gather of that 6.3 GB shardFSDP 對這個 6.3 GB 分片做 reduce-scatter 加 all-gather | s | |
| FLOP in one step: per token, 16M tokens一步的 FLOP:每個 token 、16M 個 token | FLOP | |
| Step time on 16,384 GPUs at 400 TFLOP/s each16,384 顆 GPU、每顆 400 TFLOP/s 的步時間 | s | |
| Sharded exchange as a share of the step, if nothing hides it若沒有任何隱藏,分片交換占一步的比例 |
The full-copy all-reduce would spend about 32 s per step on bandwidth, and its 5.6 ms latency term is nothing beside that. With the real layout the exchange is about 0.25 s, 4% of a 5.9 s step if nothing hides it; most of it is hidden (Section 4.7).
完整副本的 all-reduce 每步要花約 32 s 在頻寬上,它 5.6 ms 的延遲項相比之下微不足道。換成真實的配置,交換約 0.25 s;若沒有任何隱藏,占 5.9 s 一步的 4%;大部分都被隱藏了(第 4.7 節)。
A small tensor-parallel all-reduce. Take a 1 MB all-reduce among the 8 GPUs of one server, joined by NVSwitch at about 450 GB/s per GPU, and assume inside the server (the exact value depends on the protocol). The ring takes 14 dependent steps and the doubling tree 3. The arithmetic, one question per row:
一次小的張量平行 all-reduce。取一台伺服器內 8 顆 GPU 之間 1 MB 的 all-reduce,GPU 由 NVSwitch 連接、每顆約 450 GB/s,並假設伺服器內 (精確值取決於協定)。環要走 14 個相依步驟,倍增樹 3 個。逐列計算如下:
| Question問題 | Calculation算式 | Result結果 |
|---|---|---|
| Ring, latency term (14 steps at 5 µs)環的延遲項(14 步、每步 5 µs) | µs | |
| Ring, bandwidth term (1 MB at 450 GB/s)環的頻寬項(1 MB、450 GB/s) | µs | |
| Ring, total環的總耗時 | µs95% of it latency其中 95% 是延遲 | |
| Doubling tree, latency term (3 steps at 5 µs)倍增樹的延遲項(3 步、每步 5 µs) | µs | |
| Doubling tree, bandwidth term (the whole 1 MB, 3 times)倍增樹的頻寬項(整個 1 MB 送 3 次) | µs | |
| Doubling tree, total倍增樹的總耗時 | µsabout 3.4 times faster than the ring比環快約 3.4 倍 |
The tree is more than three times faster, and 95% of the ring's time is latency. Small collectives are latency problems, and the link speed is almost irrelevant to them. That is the whole reason NCCL has more than one algorithm and protocol.
樹快了三倍多,而環的時間有 95% 是延遲。小的集體操作是延遲問題,鏈路速度對它們幾乎無關。這就是 NCCL 擁有多種演算法與協定的全部理由。
In Panel 4.3, set , and . The ring takes about 45 ms and the tree about 0.4 ms. Now raise until the ring wins. How does the crossover move when you halve to 11 µs? This is the decision NCCL makes, with a built-in table, at the start of every collective.
在面板 4.3 中設 、、。環大約要 45 ms,樹大約 0.4 ms。現在提高 直到環勝出。把 減半到 11 µs 時交叉點怎麼移動?這就是 NCCL 在每次集體操作開始時,用內建的表所做的決定。
4.4Hierarchical collectives and in-network reduction階層式集體操作與網內歸約
A training server is two networks in one. Inside it, 8 GPUs share an NVSwitch fabric at about 3.6 Tb/s per GPU. Outside it, each GPU has a 400 Gb/s NIC. The gap is about 9× (Rail-only paper, §II). A flat ring across 1,024 GPUs ignores this: 7 of every 8 links in the ring would be NVLink and 1 of every 8 would be a NIC, and the ring runs at the pace of the slowest link, so the NVLink bandwidth is wasted.
一台訓練伺服器是兩個網路合在一起。在內部,8 顆 GPU 共用每顆約 3.6 Tb/s 的 NVSwitch 網路。在外部,每顆 GPU 有一張 400 Gb/s 的 NIC。差距約 9 倍(Rail-only 論文,§II)。跨 1,024 顆 GPU 的平面環忽略了這點:環中每 8 條鏈路有 7 條是 NVLink、1 條是 NIC,而環以最慢鏈路的速度前進,所以 NVLink 的頻寬被浪費。
The hierarchical all-reduce does the operation in three phases. First, a reduce-scatter inside each server over NVSwitch: 7 steps, bytes per GPU, at NVLink speed. Each GPU now owns one eighth of the server's partial sum. Second, an all-reduce across servers, but only among the GPUs that own the same eighth: GPU of every server forms a group of ranks and all-reduces bytes over the network. Third, an all-gather inside each server, again 7 steps at NVLink speed. The network now carries bytes per GPU instead of : eight times less. The rail-only paper's analysis found this for 16 DGX GH200 systems, where the high-bandwidth domain holds 256 GPUs: 98% of the all-reduce bytes crossed NVSwitch and 2% crossed the network.
階層式 all-reduce分三個階段做這件事。第一,在每台伺服器內透過 NVSwitch 做 reduce-scatter:7 步、每顆 GPU 位元組、NVLink 速度。現在每顆 GPU 持有該伺服器部分和的八分之一。第二,跨伺服器做 all-reduce,但只在持有同一個八分之一的 GPU 之間:每台伺服器的 GPU 組成 個 rank 的群組,在網路上對 位元組做 all-reduce。第三,在每台伺服器內做 all-gather,同樣 7 步、NVLink 速度。網路現在每顆 GPU 承載 位元組而非 :少了八倍。Rail-only 論文分析 16 台 DGX GH200 系統時發現這一點,那裡的高頻寬 domain 容納 256 顆 GPU:all-reduce 有 98% 的位元組跨 NVSwitch、2% 跨網路。
The figure below draws the three phases on two servers. Follow the slice that each GPU owns: only slice of GPU leaves the server, and it travels only to GPU of the other server.
下圖在兩台伺服器上畫出這三個階段。追蹤每顆 GPU 持有的那一片:只有 GPU 的第 片會離開伺服器,而且只送到另一台伺服器的 GPU 。
Animation 4.3 plays the three phases on two servers of 4 GPUs each. Watch which half-slices leave the servers, and between which GPUs.
動畫 4.3 在兩台各有 4 顆 GPU 的伺服器上播放這三個階段。注意哪些半片離開伺服器,以及在哪些 GPU 之間流動。
In-network reduction. A switch that can add changes the byte count: each rank sends up once and receives the sum once, about per direction instead of , with no -dependent step chain. NVIDIA's SHARP does this in InfiniBand switches, the H100 generation's NVSwitch can reduce inside the server, and Ultra Ethernet, an industry effort to extend Ethernet for AI and supercomputing (Chapter 7), has proposals for it. None of the training-network papers in this book rely on it, so treat the gain as something to measure, and remember that it needs switch state per collective, a scaling cost of its own.
網內歸約。一台能做加法的交換器會改變位元組數:每個 rank 把 往上送一次、把總和收一次,每個方向約 而非 ,也沒有取決於 的步驟鏈。NVIDIA 的 SHARP 在 InfiniBand 交換器中做這件事,H100 世代的 NVSwitch 可以在伺服器內歸約,Ultra Ethernet(擴充 Ethernet 以用於 AI 與超級電腦的業界計畫,第 7 章)也有相關提案。本書的訓練網路論文都不依賴它,所以把這個增益當成需要量測的東西,並記得它需要交換器為每個集體操作保存狀態,這本身就是一種擴展成本。
In Panel 4.3 choose "Hierarchical", , , and compare the time and the network bytes with the flat ring. Then switch the collective to all-to-all. Why does the hierarchy stop helping? (Every byte of an all-to-all has a distinct destination, so grouping by server cannot remove network traffic; it can only reorder it.)
在面板 4.3 選「階層式」、、,比較耗時與網路位元組數和平面環的差異。然後把集體操作切到 all-to-all。為什麼階層不再有幫助?(all-to-all 的每個位元組都有不同的目的地,所以依伺服器分組無法移除網路流量,只能重新排序。)
4.5Inside NCCLNCCL 的內部
NCCL is NVIDIA's collective library. PyTorch calls it for every all-reduce. NCCL splits one collective into several parallel channels. Each channel is a ring or tree with its own buffers and its own network connection. In RDMA terms, each connection is a queue pair (QP). The number of channels and QPs decides how many network flows one collective creates. This matters in Chapter 8: more flows give the switches more chances to spread the load, and both Meta and Alibaba modified NCCL to control which path each flow takes.
NCCL 是 NVIDIA 的集體通訊函式庫。PyTorch 每次做 all-reduce 都會呼叫它。NCCL 會把一個集體操作切成數個平行的 channel。每個 channel 是一個環或樹,有自己的緩衝區與自己的網路連線。用 RDMA 的術語,每條連線就是一個 queue pair(QP)。channel 與 QP 的數量決定了一個集體操作會產生幾條網路流。這在第 8 章很重要:流越多,交換器就越有機會把負載分散;Meta 與 Alibaba 都修改了 NCCL,以控制每條流走哪條路徑。
NCCL is the library that turns a call such as all_reduce(tensor) into GPU kernels and network operations. Its vocabulary is small and worth knowing exactly, because the papers on this site tune its internals by name.
NCCL 是把 all_reduce(tensor) 這樣的呼叫變成 GPU kernel 與網路操作的函式庫。它的詞彙很少,值得精確掌握,因為本站的論文會指名調校它的內部。
Communicators and channels. A communicator is one group of ranks with a fixed numbering; a job has one per parallelism dimension. Inside it, NCCL builds one or more channels: independent copies of the algorithm, each a ring or tree over the same ranks with its own GPU thread block, staging buffers and connection to each neighbor. A collective is split across channels, so with 8 channels each ring carries one eighth of the message. More channels mean more concurrent flows and more copying threads, up to a few dozen; Meta's Table 2 reports about 4 connections per GPU for an all-reduce on 128 GPUs and about 15 for an all-to-all, before any of the extra connections described in Chapter 8.
Communicator 與 channel。communicator 是一組有固定編號的 個 rank;一個任務在每個平行化維度各有一個。在它之內,NCCL 建立一個或多個 channel:演算法的獨立副本,每個都是同一組 rank 上的一個環或一棵樹,有自己的 GPU thread block、分段緩衝區,以及到每個鄰居的連線。一次集體操作會切到各 channel,所以 8 個 channel 時每個環承載訊息的八分之一。更多 channel 意味著更多並行的流與更多在複製的執行緒,上限是幾十個;Meta 的 Table 2 回報 128 顆 GPU 上 all-reduce 每顆 GPU 約 4 條連線、all-to-all 約 15 條,這是在加上第 8 章所說的額外連線之前。
The figure below follows one GPU's channels down to the wire. Each channel runs as one CUDA block on its own streaming multiprocessor (SM), one of the GPU's 132 processing units on an H100. Its staging buffer is cut into NCCL_STEPS slots (typically 8); a slot can be refilled only after the receiver has emptied it and said so with a tiny message called a clear-to-send (CTS), and different channels can leave through different NICs (Demystifying NCCL, HOTI 2025). So every extra channel takes an SM away from computation and adds a flow to the fabric.
下圖追蹤一顆 GPU 的 channel 一路到線上。每個 channel 以一個 CUDA block 在自己的串流多處理器(SM,H100 上 132 個處理單元之一)上執行。它的分段緩衝區切成 NCCL_STEPS 個槽(通常是 8 個);一個槽要等接收端清空它、並以一則稱為 clear-to-send(CTS)的極小訊息告知之後,才能再次填入;不同的 channel 可以從不同的 NIC 離開(Demystifying NCCL,HOTI 2025)。所以每多一個 channel,就從計算中拿走一個 SM,並在網路上多一條流。
Chunks and the two-stage copy. Each channel moves data in pieces the size of a buffer slot. The GPU kernel copies a piece from the user's tensor into the channel's staging buffer, doing the arithmetic of the reduction on the way. A CPU thread called the proxy then issues the RDMA write that moves the piece into the matching staging buffer on the receiving rank. The receiver's kernel copies it out, adds it, and the slot is free again. In stock NCCL the staging buffer behind one channel is about 4 MB, divided into a small number of slots (8 in the versions we know), so each piece on the wire is on the order of half a megabyte. These sizes are tunable and they are what Meta and the Llama 3 team changed.
Chunk 與兩階段複製。每個 channel 以緩衝槽大小的片段搬資料。GPU kernel 把一片從使用者的張量複製到 channel 的分段緩衝區,順路做歸約的算術。一個稱為 proxy 的 CPU 執行緒接著發出 RDMA write,把這一片搬到接收端 rank 對應的分段緩衝區。接收端的 kernel 把它複製出來、相加,槽就再次空出。在原版 NCCL 中,一個 channel 背後的分段緩衝區約 4 MB,分成少數幾個槽(我們所知的版本是 8 個),所以線上每一片大約半 MB。這些大小都可調,也正是 Meta 與 Llama 3 團隊所改動的。
Panel 4.4 does this arithmetic for any message size, channel count and buffer size.
面板 4.4 為任何訊息大小、channel 數與緩衝區大小做這個算術。
On InfiniBand and RoCE, each pair of connected ranks uses two reliable-connection QPs: the forward QP carries the RDMA writes of data, and the reverse QP carries the small clear-to-send writes (Demystifying NCCL, HOTI 2025). The figure below shows the whole path.
在 InfiniBand 與 RoCE 上,每一對相連的 rank 使用兩個 reliable-connection QP:正向的 QP 承載資料的 RDMA write,反向的 QP 承載小小的 clear-to-send 寫入(Demystifying NCCL,HOTI 2025)。下圖畫出整條路徑。
The clear-to-send handshake is admission control. The proxy may not post a write into a slot until the receiver has said the slot is free, with a tiny control message that Meta's paper calls the clear-to-send (CTS). Because the number of slots is fixed, the data a sender can have on the wire toward one receiver is bounded by the slots granted and not yet reclaimed. This is receiver-driven admission: the receiver decides when bytes enter the network, and the sender cannot overrun it. It is why Meta could run its 400G network without the usual network-side controls (Chapter 7): when sixteen senders sent to one receiver at once, nothing backed up, because sixteen senders each limited to a few slots cannot exceed what the receiver's buffers can drain (Meta §5.2). A 2018 paper, IRN, proposed the same cap, one bandwidth-delay product per queue pair, inside the NIC (Chapter 7); NCCL enforces it in software, per channel.
Clear-to-send 交握就是許可控制。proxy 不能把寫入提交到某個槽,除非接收端用一則極小的控制訊息說該槽是空的,Meta 論文稱之為 clear-to-send(CTS)。因為槽數固定,發送端朝一個接收端在線上的資料量,受限於已授權且尚未回收的槽。這就是接收端驅動的許可:接收端決定位元組何時進入網路,發送端無法超越它。這正是 Meta 能讓 400G 網路不靠一般壅塞控制機制運行的原因(第 7 章):十六個發送端同時送往一個接收端時,什麼都沒有堵住,因為十六個各自只限幾個槽的發送端,無法超過接收端緩衝區能排空的量(Meta §5.2)。2018 年的 IRN 論文提出同樣的上限——每個 queue pair 一個頻寬延遲乘積——放在 NIC 內(第 7 章);NCCL 以軟體、逐 channel 執行它。
Protocols: Simple, LL, LL128. Independently of the algorithm, NCCL has three ways to tell the receiving kernel that data has arrived. Simple writes a block, then a flag; lowest overhead per byte, used for large messages. LL (low latency) puts a flag in every 16 bytes next to 8 bytes of data, so each small piece is usable the moment it lands, at the cost of half the bytes being flags. LL128 uses 128-byte lines with 120 bytes of payload, about 95% efficient, but relies on ordering guarantees that NVLink provides and not every network does. The thresholds change between versions; what stays true is that small messages take a flag-per-piece protocol to shave , and large ones take the plain protocol to maximize .
協定:Simple、LL、LL128。與演算法無關,NCCL 有三種方式告訴接收端的 kernel 資料已到達。Simple 先寫一塊、再寫一個旗標;每位元組開銷最低,用於大訊息。LL(低延遲)在每 16 位元組中放一個旗標與 8 位元組資料,每個小片一落地就能使用,代價是一半的位元組是旗標。LL128 使用 128 位元組的行、120 位元組是資料,效率約 95%,但依賴 NVLink 提供而非每種網路都提供的順序保證。門檻隨版本改變;不變的是:小訊息用每片帶旗標的協定來削減 ,大訊息用普通協定來最大化 。
The figure below draws the three layouts. An LL unit is 8 bytes, 4 of data and a 4-byte flag written in one atomic store, so half of the bytes are data. An LL128 line is 120 bytes of data and an 8-byte flag. A measurement study of NCCL 2.19 reports about 1 µs per hop for LL at 25–50% of peak bandwidth, about 2 µs for LL128 at about 95%, and about 6 µs for Simple near peak. LL128 needs atomic 128-byte writes, so NCCL disables it on some PCIe systems (Demystifying NCCL, HOTI 2025).
下圖畫出三種格式。LL 的一個單位是 8 位元組:4 位元組資料加 4 位元組旗標,以一次原子寫入完成,所以一半的位元組是資料。LL128 的一行是 120 位元組資料加 8 位元組旗標。一項對 NCCL 2.19 的量測研究回報:LL 每跳約 1 µs、達到峰值頻寬的 25–50%;LL128 約 2 µs、約 95%;Simple 約 6 µs、接近峰值。LL128 需要 128 位元組的原子寫入,所以 NCCL 在某些 PCIe 系統上停用它(Demystifying NCCL,HOTI 2025)。
Auto-selection. At the start of every collective NCCL evaluates a cost model close to the – model of Section 4.3 for every (algorithm, protocol) pair the machine supports, using latency and bandwidth tables measured for the platform, and picks the smallest predicted time for the message size. Roughly: tiny messages get a tree with LL, medium ones a tree or ring with LL128, large ones a ring with Simple; on NVSwitch systems an in-switch reduction may be chosen. Environment variables can force a choice, which is the tuning the Meta and Llama 3 papers describe. The point for a network engineer is that the choice depends on the latency the library believes it has. If the fabric is slower than the table says, every threshold is wrong at once.
自動選擇。在每次集體操作開始時,NCCL 對機器支援的每一組(演算法、協定),用為該平台量測的延遲與頻寬表,評估一個接近第 4.3 節 – 模型的成本模型,並為該訊息大小選出預測時間最小的一組。粗略地說:極小的訊息用樹加 LL,中等的用樹或環加 LL128,大的用環加 Simple;在 NVSwitch 系統上可能選交換器內歸約。環境變數可以強制選擇,這就是 Meta 與 Llama 3 論文描述的調校。對網路工程師重要的是:這個選擇取決於函式庫相信自己擁有的延遲。如果網路比表上說的慢,所有門檻會同時出錯。
4.6Bytes in flight and the round trip在途位元組與往返時間
Here is the mechanism behind Meta's "more than 2×" result, in one formula. A link of bandwidth and round-trip time holds bytes between the moment a sender starts and the moment the next grant can return: the bandwidth-delay product (BDP). At 400 Gb/s and 22 µs it is ; at the under-10 µs NCCL's defaults assume, under 0.5 MB. Data that has been sent but not yet acknowledged, or here not yet granted again, is in flight. If the sender may have only bytes in flight, the link can be busy for at most of every , so
這就是 Meta「超過 2 倍」結果背後的機制,用一條公式說完。頻寬 、往返時間 的鏈路,在發送端開始到下一個授權能回來之間,容納 位元組:這是頻寬延遲乘積(BDP)。在 400 Gb/s 與 22 µs 下是 ;在 NCCL 預設假設的低於 10 µs 下,低於 0.5 MB。已送出但尚未確認(在這裡是尚未再次獲得授權)的資料稱為在途資料。如果發送端只能有 位元組在途,鏈路在每個 中最多忙 的時間,所以
In NCCL, is the credit the receiver has granted: , as the figure above shows. Stock NCCL sizes those buffers for a round trip inside one rack. Meta measured about 22 µs across its fabric, more than twice that, so the granted credit covered less than half of the BDP and the 400G links sat idle between grants about half the time. No queue was building anywhere; the network was simply not being asked to carry anything. This is why out-of-the-box RoCE collectives ran at well under half of the hardware's capability, and why enlarging the channel buffers was the single largest gain (Meta §6.1). The Llama 3 team made the same change under the name NCCLX: chunk and transfer sizes re-tuned for a fabric where DP and PP traffic sees "tens of microseconds" of latency (Llama 3 §3.3.3).
在 NCCL 中, 是接收端授權的額度:,如上圖所示。原版 NCCL 依單一機櫃內的往返時間設定這些緩衝區。Meta 量到跨網路約 22 µs,是它的兩倍以上,所以授權的額度不到 BDP 的一半,400G 鏈路在授權之間約一半時間閒置。沒有任何地方在排隊;網路只是沒有被要求承載任何東西。這就是為什麼開箱即用的 RoCE 集體通訊遠低於硬體能力的一半,也是為什麼加大 channel 緩衝區是最大的單一增益(Meta §6.1)。Llama 3 團隊以 NCCLX 之名做了同樣的改動:把 chunk 與傳輸大小重新調校給 DP 與 PP 流量會遇到「數十微秒」延遲的網路(Llama 3 §3.3.3)。
The figure below shows the slots on the wire. With eight small slots, the sender empties its window long before the first clear-to-send returns, and the link waits. With slots large enough that the eight of them cover , a grant always returns before the window runs out.
下圖畫出線上的槽。8 個小槽時,發送端在第一個 clear-to-send 回來之前早就送完視窗,鏈路只能等。槽大到 8 個合起來能覆蓋 時,授權總是在視窗送完之前回來。
Worked example: sizing a channel buffer算例:決定 channel 緩衝區大小
Worked example: sizing a channel buffer. A collective runs 16 flows between a pair of GPUs (Llama 3). All 16 share one 400G NIC, so the NIC as a whole needs about 1.1 MB in flight, about 70 KB per flow at 22 µs. If the library grants only 32 KB per flow, the NIC sends about 0.5 MB per RTT and the link runs at about 45% of line rate, close to the "well under half" that Meta observed out of the box. Double the RTT with more switches on the path or a long queue, and the same buffers halve throughput again. This is why the Llama 3 team wrote NCCLX with chunk sizes tuned to the measured latency rather than to a one-rack assumption.
實例:為 channel 緩衝區定大小。一個集體操作在一對 GPU 之間跑 16 條流(Llama 3)。16 條共用一張 400G NIC,所以整張 NIC 需要約 1.1 MB 在途,22 µs 時每條流約 70 KB。如果函式庫只給每條流 32 KB,NIC 每個 RTT 只送約 0.5 MB,鏈路跑在線速的約 45%,接近 Meta 開箱觀察到的「遠低於一半」。路徑上多幾台交換器或一條長佇列讓 RTT 加倍,同樣的緩衝區會讓吞吐再減半。這就是 Llama 3 團隊寫 NCCLX、把 chunk 大小調到實測延遲而非單機櫃假設的原因。
Animation 4.4 plays this worked example: data fills the pipe until the buffers run out, and then the link waits for the ACKs.
動畫 4.4 播放這個實例:資料填入管道直到緩衝用完,然後鏈路等待 ACK。
Panel 4.5 lets you change the buffer per flow, the number of flows and the RTT, and shows how busy the link stays.
面板 4.5 讓你改變每條流的緩衝、流數與 RTT,並顯示鏈路能保持多忙。
Animation 4.5 plays the same loop in time. The sender spends one credit per slot, and each clear-to-send gives one back.
動畫 4.5 在時間軸上播放同一個循環。發送端每寫一個槽就用掉一個授權,每個 clear-to-send 還回一個。
The control message must not queue behind data. The formula uses RTT, but the real cycle is RTT plus however long the clear-to-send waits in a queue. A CTS is a few bytes; if it shares a switch queue with megabytes of data from other ranks, the sender's slots stay un-granted for as long as it waits. Meta measured a 90th-percentile CTS delay of 43 µs before tuning. At 400 Gb/s that stall is 2.15 MB of link capacity, twice the whole BDP, lost per grant cycle. A high-priority switch queue for CTS packets cut it to 4 µs (Meta §6.1). The requirement for full utilization is therefore
控制訊息不能排在資料後面。公式用的是 RTT,但真實的週期是 RTT 加上 clear-to-send 在佇列中等待的時間。一個 CTS 只有幾個位元組;如果它與其他 rank 的 MB 級資料共用一個交換器佇列,發送端的槽就有多久得不到授權,取決於它等多久。Meta 量到調校前 CTS 的第 90 百分位延遲是 43 µs。在 400 Gb/s 下,這個停頓是 2.15 MB 的鏈路容量——整個 BDP 的兩倍——在每個授權週期中損失。給 CTS 封包一個高優先權的交換器佇列,讓它降到 4 µs(Meta §6.1)。因此達到滿使用率的條件是
The figure below shows where the CTS delay comes from and how much credit each case needs.
下圖顯示 CTS 延遲從哪裡來,以及每種情況需要多少額度。
Why not grant everything? Because the bound is also the protection. The IRN paper capped bytes in flight per queue pair at one BDP of the longest path, 120 KB for 40 Gb/s links with six 2 µs hops, and showed that this alone kept switch queues short (Chapter 7). Meta's receiver-driven admission is the same idea at the library level, and it is why sixteen senders sending to one receiver did not back up. Grant too little and the link idles; grant too much and the switches overflow. The right value is one BDP plus the CTS delay per receiving link, both measured on the real fabric, not read from a default.
為什麼不全部授權?因為這個上限同時也是保護。IRN 論文把每個 queue pair 的在途位元組限制在最長路徑的一個 BDP——40 Gb/s 鏈路、六跳各 2 µs 下是 120 KB——並證明光是這樣就能讓交換器佇列保持很短(第 7 章)。Meta 的接收端驅動許可是同一個想法放在函式庫層,也是十六個發送端送往同一個接收端時沒有堵住的原因。授權太少鏈路閒置;授權太多交換器會溢出。正確的值是每條接收鏈路一個 BDP 加 CTS 延遲,兩項都在真實網路上量測,不能從預設值讀出。
In Panel 4.6, keep the tuned preset and raise the link rate to 800 Gb/s. What happens to utilization, and what must change to recover it? Then set RTT to 60 µs, which is a plausible cross-building path. The lesson: every speed upgrade and every change in how the network is wired re-opens the buffer question, because the BDP moved.
在面板 4.6 保持「調校後」預設,把鏈路速率提高到 800 Gb/s。使用率怎麼了?要恢復它必須改什麼?然後把 RTT 設到 60 µs,這是跨建築路徑的合理值。教訓:每一次速度升級與每一次網路接法的改動都會重新打開緩衝區的問題,因為 BDP 移動了。
4.7Overlap: hiding the collective重疊:把集體操作藏起來
A collective that runs while the GPUs compute costs nothing; one that runs while they wait costs its full time. The difference is overlap, and the rules of what can hide behind what come from the dependency structure of the training step.
在 GPU 計算時執行的集體操作不花任何成本;在 GPU 等待時執行的則花掉全部時間。差別就是重疊,而什麼可以藏在什麼後面的規則,來自訓練步的依賴結構。
Data parallel. The gradient of layer is complete as soon as the backward pass through it finishes, while layer is still computing, so the reduce-scatter of one chunk of layers runs behind the backward computation of the next chunk. In FSDP the all-gather of the next chunk's parameters runs behind the current chunk's forward computation. MegaScale does both, and prefetches the first chunk's all-gather during data loading because it has nothing else to hide behind (MegaScale §3.2). Llama 3 goes further and does not re-shard parameters after the forward pass, which removes one all-gather from the backward pass.
資料平行。第 層的梯度在反向經過它時就完成了,而第 層仍在計算,所以一個 chunk 的層的 reduce-scatter 藏在下一個 chunk 的反向計算後面。在 FSDP 中,下一個 chunk 參數的 all-gather 藏在目前 chunk 的正向計算後面。MegaScale 兩者都做,並在載入資料時預先抓取第一個 chunk 的 all-gather,因為它沒有別的東西可藏(MegaScale §3.2)。Llama 3 更進一步,正向之後不重新分片參數,從反向中移除一次 all-gather。
Pipeline parallel. Stage must receive activations before it can compute, but it never has to wait for its own send to complete. MegaScale decouples the two, so the send of micro-batch runs in the background while stage computes on micro-batch . In the 1F1B steady state the sends and receives are asynchronous and hidden; the warm-up and cool-down phases are where the decoupling earns its 2.5 MFU points. Llama 3's schedule, with a tunable number of micro-batches in flight and asynchronous point-to-point communication, is the same idea.
管線平行。第 階段必須先收到激活值才能計算,但從不需要等自己的 send 完成。MegaScale 把兩者解耦,讓 micro-batch 的 send 在背景執行,同時第 階段對 micro-batch 計算。在 1F1B 穩態中 send 與 receive 是非同步且隱藏的;暖機與收尾階段才是解耦賺到 2.5 個 MFU 百分點的地方。Llama 3 的排程——可調的在途 micro-batch 數與非同步點對點通訊——是同一個想法。
Tensor parallel. Here the collective sits in the middle of a layer and nothing can run before its result is known, so the only way to hide it is to cut the work into pieces. MegaScale splits each large matrix multiplication into chunks and fuses the collective with it, so chunk computes while the all-gather or reduce-scatter of chunk is in flight. These collectives run on NVLink with small pieces, which is where the LL and LL128 protocols matter most. The three overlaps are worth 6.2 MFU points in MegaScale's ablation: TP 2.2, PP 2.5, DP 1.5.
張量平行。這裡集體操作坐在一層的中間,結果出來之前什麼都不能跑,所以唯一能藏的方法是把工作切成小片。MegaScale 把每個大矩陣乘法切成多段並把集體操作與它融合,讓第 段計算時第 段的 all-gather 或 reduce-scatter 仍在傳輸中。這些集體操作走 NVLink、片段又小,正是 LL 與 LL128 協定最重要的地方。三種重疊在 MegaScale 的消融中值 6.2 個 MFU 百分點:TP 2.2、PP 2.5、DP 1.5。
The figure below draws this for one all-gather cut into four chunks.
下圖以切成四塊的一個 all-gather 畫出這件事。
The condition, and what breaks it. Overlap works for a chunk only if
條件,以及什麼會打破它。重疊對一個 chunk 成立,只有當
In the – model the communication of a chunk of parameters on a DP ring is ; the compute that hides it is also proportional to , with the batch size as a multiplier, so the ratio is a fixed property of the configuration. Now let the fabric deliver half the planned bandwidth, as Meta's did out of the box. Every network doubles, the chunks closest to the line cross it first, and the largest transfers, the DP reduce-scatters, are exposed before the small TP collectives. The step grows by the exposed time and the MFU gained by overlap is handed back. This is why MegaScale puts network tuning and the straggler hunt in the same paper as the overlap schemes: they protect the assumption that overlap depends on.
在 – 模型中, 個參數的 chunk 在 DP 環上的通訊是 ;藏住它的計算也與 成正比、多了批次大小作為乘數,所以比值是配置的固定性質。現在讓網路只提供規劃一半的頻寬,像 Meta 開箱時那樣。每個網路的 都加倍,最接近那條線的 chunk 最先越線,而最大的傳輸——DP 的 reduce-scatter——比小的 TP 集體操作更早暴露。步時間增加暴露的量,重疊賺到的 MFU 被交回去。這就是為什麼 MegaScale 把網路調校與 straggler 追捕和重疊方案放在同一篇論文:它們守護的是重疊所依賴的假設。
The figure below draws this for four chunks of a backward pass. At the planned bandwidth, each chunk's collective finishes before the next chunk is ready, and only the last one is exposed. At half the bandwidth, the collectives queue behind each other, and the exposed tail grows to several chunks.
下圖以反向計算的四個 chunk 畫出這件事。在規劃頻寬下,每個 chunk 的集體操作在下一個 chunk 準備好之前就完成,只有最後一個暴露。頻寬減半時,集體操作一個排在一個後面,暴露的尾巴變成好幾個 chunk 長。
Panel 4.7 applies the same rule to any number of chunks and any delivered bandwidth.
面板 4.7 把同一條規則用在任何 chunk 數與任何實際頻寬上。
A collective that cannot be hidden shows up directly in the MFU. Llama 3's context parallelism gathers keys and values in every attention layer, and the paper attributes a 3-point drop in MFU, from 41% to 38%, to that exposed all-gather (Table 4, rows 2 and 3). That is the cost of one collective per layer that has nothing to hide behind, at the scale of 16,384 GPUs.
藏不住的集體操作會直接出現在 MFU 上。Llama 3 的上下文平行在每個注意力層收集 key 與 value,論文把 MFU 從 41% 降到 38% 的 3 個百分點歸因於那個暴露的 all-gather(Table 4 第二、三行)。這就是每層一個無處可藏的集體操作,在 16,384 顆 GPU 規模上的代價。
4.8Measuring: algbw, busbw and efficiency量測:algbw、busbw 與效率
The standard tool is nccl-tests. It runs one collective at a sweep of sizes and reports two bandwidths. algbw, the algorithm bandwidth, is simply : the buffer size divided by the measured time. It is what the application experiences, and it is also the number that must be used in the overlap condition. busbw, the bus bandwidth, rescales algbw by the bytes the algorithm must actually move per rank, so that it can be compared with the link speed:
標準工具是 nccl-tests。它對一種集體操作掃過一系列大小,回報兩種頻寬。algbw(演算法頻寬)就是 :緩衝區大小除以量到的時間。它是應用程式感受到的值,也是重疊條件中必須使用的數字。busbw(匯流排頻寬)把 algbw 依演算法每 rank 實際必須搬動的位元組重新縮放,使它能與鏈路速度比較:
| Collective | 集體操作 | busbw from algbw | 由 algbw 得到 busbw | Example: algbw 25 GB/s on 64 ranks | 例:64 個 rank、algbw 25 GB/s |
|---|---|---|---|---|---|
all-reduce | |||||
reduce-scatter, all-gather, all-to-all | |||||
broadcast, reduce, send/recv | 25 GB/s |
The figure below takes the 64-rank example apart. algbw divides the buffer by the time; busbw divides the bytes that each rank actually sent by the same time.
下圖把 64 個 rank 的例子拆開。algbw 是緩衝區除以時間;busbw 是每個 rank 實際送出的位元組除以同一段時間。
A busbw of 49.2 GB/s on a 400 Gb/s (50 GB/s) NIC means the link carried useful bytes 98% of the time. That ratio, , is what "bandwidth efficiency" means in this chapter and in Panel 4.3, and it is only meaningful for large messages: at small sizes the time is , busbw collapses toward zero with nothing wrong, and the right metric is latency in microseconds. A healthy all-reduce curve from nccl-tests therefore rises steeply through the kilobyte sizes, bends around the crossover of Section 4.3, and flattens near the link rate above a few tens of megabytes. A curve that flattens at half the link rate, as Meta's did before tuning, points at the bytes-in-flight bound of Section 4.6, not at an overloaded network.
在 400 Gb/s(50 GB/s)的 NIC 上 busbw 為 49.2 GB/s,表示鏈路有 98% 的時間在承載有用的位元組。這個比值 ,就是本章與面板 4.3 所說的「頻寬效率」,而且只對大訊息有意義:小尺寸時時間是 ,busbw 會塌向零而什麼都沒出錯,正確的指標是以微秒計的延遲。因此 nccl-tests 中健康的 all-reduce 曲線會在 KB 級大小陡升、在第 4.3 節的交叉點附近轉彎,並在幾十 MB 以上靠近鏈路速率處平坦。像 Meta 調校前那樣在鏈路速率一半處平坦的曲線,指向的是第 4.6 節的在途位元組上限,而不是網路超載。
The figure below sketches the two shapes.
下圖畫出這兩種形狀的示意。
Panel 4.8 turns one line of nccl-tests output into these numbers.
面板 4.8 把 nccl-tests 的一行輸出換算成這些數字。
Three measured results anchor what "good" looks like. Meta: out of the box, RoCE collectives ran at well under half of the hardware's capability; co-tuning buffers, CTS priority and switch credits gave more than 2× in many cases (Meta §6.1). Alibaba: an all-reduce on 448 GPUs improved by up to 59.3% once the job fit inside one group of 1,024 GPUs that share a single layer of switches (HPN §9; Chapter 6). Meta again: a better way of spreading flows over the network's paths improved all-reduce by up to 40% (Meta §4.2; Chapter 8). None of these gains came from faster links; they came from letting the existing links carry bytes more of the time.
三個量測結果錨定了「好」長什麼樣。Meta:開箱即用時,RoCE 集體通訊遠低於硬體能力的一半;共同調校緩衝區、CTS 優先權與交換器 credit,在許多情況下帶來超過 2 倍(Meta §6.1)。阿里:任務一旦放進一個共用單層交換器的 1,024 顆 GPU 群組,448 顆 GPU 的 all-reduce 改善最多 59.3%(HPN §9;第 6 章)。再一次 Meta:更好地把流分散到網路的各條路徑上,讓 all-reduce 改善最多 40%(Meta §4.2;第 8 章)。這些增益沒有一個來自更快的鏈路;它們來自讓既有的鏈路有更多時間在承載位元組。
Every collective's time is about α × (dependent steps) + (bytes each rank sends) ÷ (bandwidth). The ring all-reduce sends the fewest bytes, about 2S per rank, but needs 2(N−1) steps; trees need about log₂N steps but send more bytes. Small messages are latency problems and large ones bandwidth problems, and NCCL picks the algorithm per call. A hierarchical all-reduce reduces inside each server first, so only one eighth of the bytes cross the network, and only between GPUs of the same local rank. NCCL cuts a collective into channels and slots; a clear-to-send from the receiver admits each slot, so the bytes in flight must cover one bandwidth-delay product or the link idles. Collectives that overlap with computation cost nothing; the condition is that each chunk's communication finishes before its computation does.
每個集體操作的時間約為 α ×(相依步數)+(每個 rank 送出的位元組)÷(頻寬)。環形 all-reduce 送出的位元組最少,每個 rank 約 2S,但需要 2(N−1) 步;樹約需 log₂N 步,但送出較多位元組。小訊息是延遲問題,大訊息是頻寬問題,NCCL 每次呼叫時挑選演算法。階層式 all-reduce 先在每台伺服器內歸約,所以只有八分之一的位元組跨越網路,而且只在本地 rank 相同的 GPU 之間。NCCL 把一個集體操作切成多個 channel 與 slot;接收端以 clear-to-send 准許每個 slot,所以在途位元組必須涵蓋一個頻寬延遲乘積,否則鏈路會閒置。與計算重疊的集體操作不花時間;條件是每一塊的通訊都在它的計算結束前完成。
Chapter 5 adds up the bytes and the time of one whole training step, and shows why the network decides how well thousands of GPUs scale.
第 5 章把一整個訓練步驟的位元組與時間加總起來,說明為何網路決定了數千顆 GPU 的擴展效果。