Chương 7 · Mạng trung tâm dữ liệu
Các đơn vị và đặc trưng của mạng trung tâm dữ liệu: băng thông, cách truyền, tắc nghẽn và ảnh hưởng của chúng lên hiệu quả tính toán.
~133 phút đọc · Thuật ngữ
Mạng trung tâm dữ liệu
Chương trước đã phân tán matrix, layer và expert lên các card khác nhau và chọn quy mô instance dựa trên chi phí truyền thông. Giờ đây, giữ nguyên model và tổng số card, ta chuyển một phần card sang một supernode (siêu nút) khác: cách phân vùng ban đầu còn phù hợp không? Các tổng một phần trước đây chỉ cần đi qua kết nối nội nút tốc độ cao nay có thể phải đi qua InfiniBand hoặc RoCE; cùng một thao tác đồng bộ do đó tiêu thụ băng thông, hàng đợi và miền lỗi khác nhau. Điều cần tính lại là chi phí đặt và thực thi của phân vùng, chứ không phải một bộ khái niệm song song hóa mới.
Một khi model được chia trên nhiều máy chủ, việc huấn luyện vẫn phải tiếp tục, và phần việc dùng chung đầu tiên là hòa giải (reconcile) các gradient giữa các bản sao. Sau khi nhiều bản sao song song dữ liệu xử lý các mẫu khác nhau, gradient của chúng phải được hòa giải trước khi cập nhật tham số trên cùng một batch. Gradient trước hết được tổng hợp trong một supernode, rồi trao đổi xuyên nút — cùng cách tiếp cận như Chương 5, vốn tích lũy các tổng một phần tại chỗ trước để giảm việc di chuyển ra ngoài nút. Bản thân việc tổng hợp tại chỗ cũng tốn thời gian, và cách sắp xếp này chỉ đáng giá khi khoản tiết kiệm từ việc giảm chuyển từ xa và chờ đợi vượt qua thời gian đó.
Chương này theo dấu đường đi của dữ liệu khi rời khỏi một máy chủ, nghiên cứu cách các card được chia trên nhiều máy chủ cùng hoàn thành công việc. Toàn chương xoay quanh hai máy chủ, mỗi máy tám card: trước tiên quyết định gradient được giảm tổng xuyên máy chủ như thế nào, sau đó thảo luận cách liên tục gửi và xử lý các yêu cầu truyền thông, rồi giải thích khi nào dữ liệu trở nên có thể đọc và khi nào buffer có thể được tái sử dụng, và cách xử lý tắc nghẽn trong mạng dùng chung. Cuối cùng, phân tích này được mở rộng tới một tác vụ huấn luyện cố định 1024 card, so sánh phân lớp truyền thông, thông lượng và chi phí phục hồi giữa các quy mô supernode khác nhau. Chương cũng so sánh các truyền dữ liệu nhỏ của suy luận độ đồng thời thấp, cho thấy cùng một mạng nên ưu tiên tối ưu hóa gì dưới các khối lượng công việc khác nhau.
Chương sử dụng ba mô hình phân tích xuyên suốt. Mô hình lưu lượng và tài nguyên tính mất bao lâu để dữ liệu đi qua từng liên kết và giao diện, định vị các nút thắt; mô hình độ đồng thời và thông lượng giải thích cùng lúc phải có bao nhiêu yêu cầu đang bay (in flight) để dùng trọn băng thông; mô hình phụ thuộc và đường găng (critical path) xác định thao tác nào có thể chạy đồng thời và việc rút ngắn thao tác nào làm giảm tổng thời gian. Một số ca thiết kế trong cuốn sách này đến từ các công trình tác giả tham gia: KV-Direct để NIC lập trình được xử lý trực tiếp các yêu cầu key-value store; 1Pipe dùng mạng để cung cấp một thứ tự thao tác toàn cục, đơn giản hóa việc phối hợp trong chương trình phân tán; UB cung cấp kết nối thiết bị thống nhất. Khi tham gia nghiên cứu và thiết kế các công trình này, tác giả luôn quay lại ba câu hỏi: làm sao giảm việc di chuyển dữ liệu, làm sao làm việc khác khi đang chờ một thao tác, và làm sao đơn giản hóa lập trình mà không làm hệ thống trì trệ.
Chương này dùng GB/s cho băng thông thập phân và KiB, MiB, GiB cho dung lượng nhị phân, với byte.
7.1 Từ siêu nút đến cụm
7.1.1 Nhu cầu lưu trữ dẫn đến hợp tác xuyên máy chủ
Một model cần nhiều dung lượng hơn một máy đơn cung cấp là một lý do trực tiếp dẫn đến hợp tác xuyên máy chủ. Lấy một model 8B tham số huấn luyện bằng Adam độ chính xác hỗn hợp làm ví dụ. Độ chính xác hỗn hợp (mixed precision) nghĩa là chọn độ chính xác số khác nhau cho các đối tượng khác nhau trong quá trình huấn luyện. Nếu tham số, gradient, trọng số master FP32 và hai moment thứ nhất, thứ hai của optimizer cùng tiêu thụ 16 byte mỗi tham số thì cần 128 GB. Một card 80 GB không chứa nổi; hai card cộng lại cho 160 GB, sau khi trừ đi phần trạng thái này còn 32 GB cho activation và không gian làm việc. Khi tham số tăng lên 284B, dùng cùng biểu diễn dữ liệu, riêng trạng thái này đã cần khoảng 4,5 TB, và phải trải rộng lên nhiều card hơn để lưu trữ và xử lý.
Suy luận không cần lưu gradient hay trạng thái optimizer, nhưng trọng số của model lớn vẫn có thể cần nhiều máy chủ để giữ. Lưu khoảng 1,6T tham số của DeepSeek V4-Pro và khoảng 2,8T tham số của Kimi K3 ở mức 0,5 byte mỗi tham số cho trọng số khoảng 800 GB và 1,4 TB tương ứng. Một máy chủ tám card với 80 GB mỗi card tổng cộng 640 GB, nên chỉ riêng việc giữ trọng số đã cần ít nhất hai và ba máy chủ tương ứng. Router của MoE chỉ chọn một tập con expert cho mỗi token để thực thi, giúp giảm lượng tính toán cho một lượt forward; trọng số của các expert không được chọn vẫn cần được lưu trữ.
Một khi trọng số được đặt riêng rẽ, chương trình vẫn phải nối các mảnh tính toán lại với nhau. Chia theo layer cần chuyển giao activation giữa các stage; chia trong một layer cần tổng hợp các kết quả một phần; để nhiều bản sao model xử lý các mẫu khác nhau cần hòa giải gradient. Vì vậy, ngay cả với cùng một model, các lựa chọn phân vùng khác nhau tạo ra các yêu cầu truyền thông khác nhau.
Để so sánh các mẫu truyền thông này, chương này dùng hai máy chủ H100 chuẩn HGX tạo thành một nhóm truyền thông mười sáu card, mỗi card một tiến trình truyền thông. Các tiến trình này cùng thực thi truyền thông tập thể (collective communication) và được gọi là các bên tham gia (participants) bên dưới, phân biệt bằng rank. Các participant 0 đến 7 ở trên máy chủ A, và 8 đến 15 ở trên máy chủ B. Tám card trong một máy chủ liên kết đầy đủ với nhau qua NVLink thông qua NVSwitch. Tổng băng thông NVLink của mỗi H100 là 900 GB/s, cộng cả hai chiều, tức 450 GB/s mỗi chiều. Mỗi card được trang bị một card giao diện mạng (NIC) 400 Gbit/s, 50 GB/s mỗi chiều, nối tới card đó qua một chip switch PCIe và không dùng chung với các card khác. Các NIC mang số tương ứng trên hai máy chủ nối tới cùng một switch, và một đường đi như vậy từ NIC này đến NIC kia được gọi là một rail. Mạng switch có thể mang lưu lượng hai chiều giữa hai máy chủ. Thời gian khởi động mỗi vòng truyền thông tập thể lấy là 0,83 μs: các bản ghi công khai của nccl-tests cho thấy trên hai máy chủ như vậy, mười sáu card thực hiện AllReduce trên 16 B đến 128 B dữ liệu mất khoảng 25 μs; với dữ liệu nhỏ như vậy, thời gian truyền là không đáng kể, và chia trung bình 25 μs cho 30 vòng của ring AllReduce thảo luận ở mục sau cho khoảng 0,83 μs mỗi vòng.

Ranh giới máy chủ trong Hình 7-1 cũng là ranh giới truyền thông mà chương này phân tích nhiều lần. Lấy một tensor gradient 192 MiB, yêu cầu cả mười sáu participant nhận kết quả đã giảm tổng. Trong Ví dụ 7.6 (Mục 7.6.2), bước huấn luyện tính toán mất 20 ms, và gradient sẵn sàng ở thời điểm 17 ms; để truyền thông được che hoàn toàn sau tính toán, nó phải hoàn thành trong vòng 3 ms. Chương này lấy 3 ms làm ngân sách cho truyền thông này. Ví dụ này tiện cho việc tính toán từng vòng, và cũng minh họa khó khăn chính của việc hợp tác xuyên máy chủ: các kết quả tính toán cục bộ phải đi qua một NIC có băng thông thấp xa so với NVLink trước khi có thể tới một máy chủ khác.
Vì NIC chậm hơn NVLink rất nhiều, trước tiên ta phải quyết định loại truyền thông nào đi giữa các máy chủ. Chương này tiếp tục dùng sơ đồ chiến lược song song hóa từ Mục 6.1.4 mà không định nghĩa lại. Giữ các reduce tensor-parallel thường xuyên nằm trong kết nối nhanh hơn, đồng thời đặt đồng bộ gradient song song dữ liệu hoặc chuyển giao stage song song pipeline giữa các máy chủ, là lớp sơ đồ ứng viên nên được tính toán trước; nếu dung lượng cục bộ không đủ, song song ngữ cảnh (context parallelism) cần ngữ cảnh rộng hơn, hoặc định tuyến expert song song trải nhiều nút, sẽ đòi hỏi mở rộng phạm vi truyền thông. Việc có đặt như vậy hay không phải được quyết định bởi lưu lượng thực tế và đường găng.
Việc vượt qua ranh giới supernode bản thân nó không thay đổi lượng dữ liệu phải trao đổi; thuật toán, vị trí đặt, độ chính xác và việc phía nhận có khử trùng lặp hay không quyết định phải truyền bao nhiêu byte, còn đường đi quyết định các byte này thoát ra qua cổng nào và chờ đợi bao lâu. Chỉ biết mạng là InfiniBand hay RoCE chưa cho biết băng thông hiệu dụng, độ trễ truyền, tỉ lệ over-subscription (tỉ số giữa băng thông downlink và uplink của một switch), cửa sổ in-flight, hay thời gian phục hồi sau lỗi. Phần còn lại của chương này tính toán dựa trên các tham số mạng được cho tường minh; trong triển khai thực tế, hãy thay bằng các giá trị đo được của hệ thống tương ứng.
Thí nghiệm 7-1 · Mở rộng: phân vùng model giữa các máy chủ tám card
Tính số máy chủ tối thiểu cho hai model suy luận ở trên, cộng thêm 8 GB KV cache và không gian làm việc mỗi card. Vẽ sự phân công lao động của tensor parallelism hoặc expert parallelism trong một máy chủ và pipeline parallelism giữa các máy chủ, và cho trường hợp tensor parallelism xuyên máy chủ, đánh dấu vị trí mà một prefill và một decode yêu cầu chuyển giao xuyên máy chủ.
7.1.2 Mô hình lưu lượng và tài nguyên
Đã cố định vị trí card và kích thước gradient, tiếp theo ta tính mất bao lâu để dữ liệu đi trên từng đoạn của đường đi. Một mẩu dữ liệu rời bộ nhớ GPU, đi qua giao diện accelerator đến NIC, rồi qua mạng switch, và cuối cùng được ghi vào bộ nhớ của bên nhận. Cùng một mẩu dữ liệu phải tuần tự đi qua các giao diện và liên kết này, trong khi các khối dữ liệu khác nhau có thể được truyền đồng thời trên các đoạn khác nhau, tạo thành một pipeline. Dưới các truyền lớn duy trì bền bỉ, đoạn có băng thông thấp nhất quyết định tổng thông lượng. Ví dụ, một card có thể gửi ở 450 GB/s mỗi chiều qua NVLink, nhưng NIC của nó chỉ gửi được 50 GB/s mỗi chiều, nên tốc độ gửi duy trì tới một máy chủ khác của card đó bị giới hạn bởi 50 GB/s của NIC.
Mở rộng từ một đường đơn tới toàn cụm, ta có thể trước tiên chọn ranh giới mạng để phân tích, rồi cộng mọi dữ liệu đi ngang nó. Chia các nút mạng thành hai nhóm, các liên kết nối hai nhóm tạo thành một tập cắt (cut set) như trong Chương 6. Nếu một tác vụ cần truyền byte ngang tập cắt theo một chiều, và băng thông hiệu dụng theo chiều đó là , thì thời gian truyền ít nhất là
Đây là một cận dưới của thời gian truyền: dù lập lịch như thế nào, số byte một liên kết truyền mỗi giây cũng không thể vượt băng thông của nó. Hai chiều của một liên kết song công (full-duplex) được tính riêng; nếu nhiều cổng dùng chung một giao diện nội bộ, lưu lượng tổng hợp của giao diện đó cũng được tính riêng. Cùng một dữ liệu phải tuần tự đi qua các liên kết mắc nối tiếp, nên băng thông đầu cuối bị giới hạn bởi đoạn chậm nhất, và băng thông của các đoạn không thể cộng lại với nhau.
Tập cắt rộng bao nhiêu phụ thuộc cách tổ chức mạng switch. Một mạng Clos gồm nhiều tầng switch, cung cấp nhiều đường đi giữa các đầu cuối qua một tầng chuyển mạch trung gian. Trong mạng Clos phân cấp, các switch lá (leaf switch) nối tới máy chủ, và các switch tầng trên cung cấp nhiều đường đi giữa các switch lá. Lấy ví dụ switch InfiniBand NVIDIA Quantum QM9700 dùng trong kiến trúc tham chiếu DGX SuperPOD: mỗi cổng chạy ở mức tốc độ InfiniBand NDR, 400 Gbit/s, tức 50 GB/s mỗi chiều; nếu một switch lá dùng 48 cổng cho máy chủ và 16 cổng cho tầng trên, tổng băng thông downlink là 2,4 TB/s và tổng băng thông uplink là 0,8 TB/s, và tỉ lệ 3:1 này được gọi là tỉ lệ over-subscription. Các uplink này, tổng cộng 0,8 TB/s, tạo thành tập cắt mà lưu lượng rời khỏi switch lá này phải đi qua. Các máy chủ nối vào cùng một switch lá có thể trao đổi dữ liệu trực tiếp; chỉ truyền thông đi ngang các switch lá mới tiêu thụ băng thông uplink.
Ví dụ 7.1: Khi nào lợi ích của việc thêm card bị giới hạn bởi truyền thông xuyên máy chủ? Sắp mười sáu participant thành một vòng để giảm tổng (tính từng vòng ở Mục 7.2.1), mỗi máy chủ gửi 360 MiB sang máy kia; các byte này đều đi qua một NIC, ở 50 GB/s mỗi chiều. Với số card ban đầu, thời gian tính toán là 20 ms. Khi số card tăng, tính toán được chia đều, trong khi khối lượng truyền xuyên máy chủ và đường đi không đổi. Tìm thời gian hoàn thành cho hai cách sắp xếp: tuần tự hoàn toàn và chồng lấp hoàn toàn.
Lời giải: Cận dưới của truyền theo một chiều là
Gọi là bội số của số card ban đầu. Thời gian tính toán trở thành ms. Cách sắp xếp tuần tự cần ms; khi tính toán và truyền thông chồng lấp hoàn toàn, tổng thời gian bằng giá trị lớn hơn trong hai giá trị. Gấp đôi số card làm hai kết quả giảm từ khoảng 27,5 và 20,0 ms xuống 17,5 và 10,0 ms tương ứng. Tăng gấp bốn, cách tuần tự khoảng 12,5 ms, và cách chồng lấp hoàn toàn khoảng 7,5 ms. Hình 7-2 vẽ đường cong của cả hai cách theo số card.

Khi thời gian tính toán bằng thời gian truyền, , cho . Vượt qua điểm này, thời gian tính toán đã ngắn hơn thời gian truyền, và thêm card không còn rút ngắn thời gian của cách chồng lấp hoàn toàn. Để tiếp tục rút ngắn thời gian, phải hoặc giảm khối lượng dữ liệu ngang tập cắt, hoặc đưa thêm nhiều NIC hoạt động đồng thời để nâng băng thông hiệu dụng của tập cắt. Mục 7.2 sẽ cho thấy cách tổ chức lại cùng một reduction có thể đạt được cả hai cùng lúc.
Cách tiếp cận này — tổng tác vụ cố định, tăng số card — được gọi là strong scaling (mở rộng mạnh); weak scaling (mở rộng yếu) tăng quy mô tác vụ theo số card. Ví dụ, nếu khối lượng truyền mỗi chiều cũng tăng gấp đôi trong khi băng thông thoát cố định, thời gian truyền thông tăng gấp đôi. Hình dạng của đường cong mở rộng phụ thuộc cách khối lượng tính toán và khối lượng truyền xuyên máy chủ mỗi loại biến thiên theo số card.
Thí nghiệm 7-2 · Mở rộng: khối lượng truyền thông và băng thông thoát giới hạn lợi ích của việc mở rộng như thế nào
Theo Ví dụ 7.1, xét hai thay đổi riêng biệt: giảm một nửa lưu lượng mỗi chiều, và gấp đôi băng thông thoát bằng cách cho hai NIC hoạt động đồng thời. Với mỗi thay đổi, vẽ thời gian hoàn thành theo bội số card dưới cả hai cách sắp xếp tuần tự và chồng lấp hoàn toàn, và tìm bội số card tại đó thời gian tính toán bằng thời gian truyền thông. Rồi cho lưu lượng tăng tuyến tính theo bội số card, và tìm bội số card cực tiểu hóa thời gian hoàn thành dưới cách chồng lấp hoàn toàn.
Số tầng của mạng Clos và băng thông chia đôi (bisection bandwidth). Trước đó ta coi uplink của switch lá là tập cắt. Tập cắt của toàn cụm rộng bao nhiêu phải được tính bắt đầu từ số cổng của một switch đơn. Giả sử mỗi switch có cổng, mỗi cổng cung cấp 50 GB/s mỗi chiều; QM9700 có . Một switch lá dùng cổng cho máy chủ và cổng cho các switch spine tầng trên, và là tỉ lệ over-subscription. Không over-subscription nghĩa là . Trong mạng Clos hai tầng, mỗi switch spine dùng cổng để nối tới mỗi một switch lá, và uplink của mỗi switch lá nối tới switch spine, nên có thể có tối đa switch lá và đầu cuối; một mạng ba tầng xây dựng dạng fat-tree (một Clos nhiều tầng không thu hẹp băng thông ở bất kỳ tầng nào, tổ chức thành các pod — một pod là một nhóm switch lá cộng một tầng switch giữa, các pod nối với nhau qua các switch tầng trên) có thể chứa tới đầu cuối. Với , hai tầng nối 2048 đầu cuối dùng 96 switch — chính xác là 64 switch lá cộng 32 switch spine dùng cho 2048 GPU trong kiến trúc tham chiếu DGX SuperPOD; ba tầng nối 65536 đầu cuối dùng 5120 switch.
Chia một cụm thành hai nửa có số đầu cuối bằng nhau, tổng hợp băng thông của các liên kết nối hai nửa được gọi là băng thông chia đôi (bisection bandwidth). Với một mạng không over-subscription, băng thông chia đôi bằng tổng băng thông của một nửa số đầu cuối: với hai tầng và 2048 đầu cuối, giá trị này là TB/s; với ba tầng, 1638,4 TB/s. Với tỉ lệ over-subscription 3, một switch lá với 48 cổng xuống và 16 cổng lên có thể nối 3072 đầu cuối chỉ dùng 80 switch; 64 switch lá có tổng cộng 1024 uplink, và băng thông chia đôi là một nửa của tổng đó, 25,6 TB/s — chỉ bằng một phần ba của 76,8 TB/s mà một mạng không over-subscription cùng 3072 đầu cuối sẽ cho, với phần chia tập cắt của mỗi đầu cuối giảm từ 50 GB/s xuống 16,7 GB/s. Hình 7-3 vẽ một mạng Clos hai tầng và tập cắt đi ngang nó.

Khi tác vụ huấn luyện 1024 card trong Mục 7.6.4 chiếm một số nguyên các switch lá, tập cắt của nó là toàn bộ uplink của các switch lá này:
| Tỉ lệ over-subscription | Down/up mỗi leaf | Số leaf switch bị 1024 card chiếm | Liên kết trong tập cắt | Băng thông tập cắt | Phần chia mỗi card |
|---|---|---|---|---|---|
| 1:1 | 32/32 | 32 | 1024 | 51,2 TB/s | 50 GB/s |
| 3:1 | 48/16 | 22 | 352 | 17,6 TB/s | 17,2 GB/s |
Tỉ lệ over-subscription cũng thay đổi giá trị trong cột “exit tăng theo số card” của bảng ở Mục 7.6.4. Cột đó lấy exit mỗi supernode bằng số card nhân 50 GB/s, ngầm giả định một mạng switch không over-subscription; với tỉ lệ over-subscription 3, exit chỉ bằng một phần ba, và thời gian truyền xuyên miền trở thành gấp ba:
| Card mỗi supernode | Gửi xuyên nút mỗi nút | Exit không over-subscription | Exit over-subscription 3:1 | Thời gian truyền xuyên miền (không over → 3:1) |
|---|---|---|---|---|
| 8 | 127 GB | 400 GB/s | 133 GB/s | 0,318 → 0,953 s |
| 64 | 120 GB | 3,2 TB/s | 1,07 TB/s | 37,5 → 112,5 ms |
| 128 | 112 GB | 6,4 TB/s | 2,13 TB/s | 17,5 → 52,5 ms |
| 256 | 96 GB | 12,8 TB/s | 4,27 TB/s | 7,5 → 22,5 ms |
Bảng thể hiện thời gian truyền thuần túy. Thành phần xuyên miền trong Mục 7.6.4 còn gồm khởi động cho vòng với mỗi vòng 0,83 μs; với supernode 128 card, , tổng khởi động khoảng 12 μs, không đáng kể so với các thời gian cỡ mili-giây trong bảng.
Thảo luận: khi nào một tập cắt over-subscription trở thành nút thắt? Một tỉ lệ over-subscription giảm phần chia tập cắt của mỗi card xuống GB/s. Nếu chỉ một phần các byte mà một NIC gửi cần rời khỏi switch lá tại chỗ, điều kiện để uplink không thành nút thắt là : không over-subscription nghĩa là không có giá trị nào bị ràng buộc; ở , chưa tới một phần ba số byte có thể ngang switch lá mà không bị ràng buộc. Trong giai đoạn xuyên máy chủ của reduction phân cấp, nếu hai máy chủ ghép cặp không nằm dưới cùng một switch lá (trong cấu trúc đa rail ở Mục 7.2.5, các máy chủ có NIC cùng số nối tới cùng một switch lá, theo nhóm 32 máy chủ mỗi nhóm; đây là trường hợp hai máy chủ không cùng nhóm), thì toàn bộ byte của mỗi NIC phải ngang switch lá, , và tập cắt over-subscription trực tiếp kéo dài giai đoạn này thêm hệ số ; khi hai máy chủ cùng nhóm, việc ghép cặp thẳng hàng ở Mục 7.2.5 đảm bảo byte của mỗi cặp chỉ đi qua một switch lá, , và uplink không mang byte nào của reduction này. Đặt các máy chủ của cùng một nhóm đồng bộ vào cùng một nhóm là cách để giảm .
Thí nghiệm 7-3 · Mở rộng: số cổng switch và tỉ lệ over-subscription quyết định tập cắt như thế nào
Đổi số cổng switch thành 128, và tìm số đầu cuối, số switch và băng thông chia đôi cho các mạng Clos không over-subscription hai tầng và ba tầng tương ứng. Giữ 64 cổng, đổi tỉ lệ over-subscription thành 2:1, và tìm băng thông tập cắt và phần chia mỗi card cho một phân vùng 1024 card, và thời gian truyền xuyên miền cho supernode 128 card trong Mục 7.6.4. Cuối cùng, ở tỉ lệ over-subscription 3, tìm phần byte của một NIC phải nằm trong switch lá tại chỗ để tập cắt không còn là nút thắt trong giai đoạn xuyên máy chủ của reduction phân cấp.
7.1.3 Kết nối thống nhất (Unified Interconnect)
Các cận dưới ở trên mô tả giới hạn của các liên kết vật lý. Chương trình còn đối mặt một vấn đề khác: cùng một mẩu dữ liệu thường phải đi qua các giao diện truy cập khác nhau tùy việc nó di chuyển trong một máy hay xuyên máy chủ. Điều này bắt nguồn từ sự phân công lao động lâu đời giữa bus và mạng: kết nối liên kết chặt (tightly coupled interconnect) gắn thiết bị vào bộ xử lý và hệ bộ nhớ, hợp với hợp tác thường xuyên, hạt mịn; mạng cụm nối một lượng lớn các nút độc lập và cũng phải xử lý lỗi nút và lỗi liên kết. Một khi model trải trên nhiều máy chủ, cùng một phép tính sử dụng cả hai cơ chế đồng thời. Một truy cập bộ nhớ cục bộ và một truyền từ xa biểu diễn các phụ thuộc dữ liệu tương tự nhau trong chương trình, nhưng đi theo các đường nộp và hoàn tất khác nhau.
Khi tác giả tham gia thiết kế giai đoạn đầu của UB, một trong các vấn đề cốt lõi là làm sao cung cấp một giao diện thống nhất cho hợp tác cục bộ và từ xa. Ứng dụng muốn biểu diễn là “đọc dữ liệu này”, “chuyển kết quả cho giai đoạn tiếp theo”, “chờ nó kết thúc, rồi dùng lại không gian đó”. Kết nối thống nhất cung cấp một giao diện chung cho việc định địa chỉ, truy cập dữ liệu và truyền thông giữa các thiết bị, cho phép CPU, accelerator và các thiết bị khác cùng tham gia.
Để hiểu sự thống nhất này cần phân biệt hai thứ. Giao diện quyết định chương trình biểu diễn công việc như thế nào; đường vật lý quyết định công việc đó đi qua tài nguyên nào. Một read từ xa có thể được phát ra bằng một lệnh đơn, nhưng dữ liệu vẫn phải đi qua cổng thoát 50 GB/s của NIC; một write không đồng bộ có thể được nộp sớm, nhưng phía nhận phải chờ dữ liệu sẵn sàng trước khi bắt đầu dùng nó. Theo đó, chương này trước tiên tính lưu lượng cần thiết, rồi các yêu cầu đồng thời cần để dùng trọn băng thông, và cuối cùng là thứ tự thao tác mà ứng dụng yêu cầu. Lợi ích của một giao diện thống nhất hiện ra ở chính ba mức này: giảm di chuyển, rút ngắn đường nộp yêu cầu, và đơn giản hóa phối hợp. Mục 6.5.5 đã thảo luận, từ góc độ quy mô supernode, hai lựa chọn thiết kế trong UB: gắn controller vào bus trên chip, và tách trạng thái kết nối thành các bản ghi endpoint và kênh truyền tải lưu riêng. Chương này theo dấu đường đi của một truy cập từ xa đơn, tính tác động của hai lựa chọn này từng giai đoạn.
7.2 Lưu lượng xuyên nút và đường đi vật lý
7.2.1 Lưu lượng xuyên máy chủ trong song song dữ liệu
Một giao diện thống nhất không thể loại bỏ các truyền cần thiết, nhưng thuật toán reduction có thể thay đổi dữ liệu nào cần xuyên máy chủ. Bắt đầu với song song dữ liệu: mỗi participant tính một gradient cục bộ, các phần tử tương ứng sau đó được cộng lại, và cuối cùng mọi participant phải thu được kết quả đã giảm tổng đầy đủ. Lấy ví dụ gradient của phép chiếu gate trong lớp FFN đầu tiên của Qwen3-8B, với shape , lưu ở FP32 với 4 byte mỗi phần tử; đầu vào của mỗi participant là
Mục 6.4.2 đã suy ra ring AllReduce: trước tiên ReduceScatter, để mỗi card giữ một lát của kết quả đã giảm tổng, rồi AllGather để gom các lát này lên mọi card; tensor được chia đều thành phần, mỗi bước trong hai bước mất vòng, và mỗi vòng gửi một lát tới participant tiếp theo. Vậy mỗi participant gửi
Mỗi participant trong mười sáu gửi 360 MiB, tổng cộng 5760 MiB, qua ba mươi vòng. Thuật toán quyết định tổng khối lượng gửi; sự phân bố participant trên các máy chủ quyết định bao nhiêu phần trong đó phải xuyên máy chủ, và qua những NIC nào.
Ví dụ 7.2: thuật toán reduction nào có thể hoàn thành truyền trong ngân sách 3 ms? Dùng hai máy chủ từ Mục 7.1, so sánh một ring liền nhau không phân cấp, một ring xen kẽ, và reduction phân cấp.
Lời giải: tính khối lượng truyền xuyên máy chủ cho từng sơ đồ reduction. Ring liền nhau được sắp là 0, 1, …, 15. Trong mười sáu cạnh có hướng, chỉ 7→8 và 15→0 xuyên máy chủ. Mỗi vòng gửi 12 MiB mỗi cạnh; qua ba mươi vòng, mỗi chiều gửi tổng cộng 360 MiB, cả hai chiều 720 MiB; các byte này chỉ đi qua NIC của participant 7 trên máy chủ A và NIC của participant 15 trên máy chủ B, trong khi mười bốn NIC còn lại ngồi không. Nếu thay vào đó thứ tự được xen kẽ là 0, 8, 1, 9, …, 7, 15, cả mười sáu cạnh đều xuyên máy chủ, mỗi vòng gửi 12 MiB mỗi NIC, và tổng xuyên máy chủ tăng lên 5760 MiB.
Reduction phân cấp trước tiên chạy một ReduceScatter trên tám participant trong mỗi máy chủ. Sau bảy vòng, mỗi participant giữ một phần tám kết quả reduction của máy chủ, tức 24 MiB. Hai participant trên hai máy chủ chịu trách nhiệm cho cùng một lát sau đó chạy một AllReduce giữa chúng: mỗi bên chia 24 MiB của mình thành hai nửa, trao đổi và giảm tổng một nửa trong một vòng, rồi trao đổi nửa kia trong vòng thứ hai. Mỗi cặp gửi 48 MiB tổng hợp cả hai chiều, và tám cặp gửi 384 MiB tổng hợp; mỗi cặp dùng rail riêng của mình, với cả tám NIC hoạt động đồng thời. Cuối cùng, mỗi máy chủ chạy bảy vòng AllGather để thu kết quả đầy đủ. Các Hình 7-4 đến 7-6 lần lượt vẽ đường đi của ba sơ đồ, và Hình 7-7 so sánh số byte xuyên máy chủ giữa ba sơ đồ.




Lời giải: tính thời gian reduction từ tải trên mỗi liên kết mỗi vòng. Các vòng thực thi tuần tự, với các truyền khác nhau trong cùng một vòng tiến hành song song. Gọi là khối lượng dữ liệu đi qua tài nguyên trong vòng , là băng thông của tài nguyên đó, và là thời gian khởi động mỗi vòng; mô hình truyền khi đó là
Theo các mũi tên của ba sơ đồ trên từng vòng một biến lưu lượng thành thời gian. Biểu thức này tách hai quan hệ: trong một vòng, truyền chậm nhất thống trị; giữa các vòng, thời gian chỉ cộng lại. Ở đây ta chỉ tính thời gian truyền dữ liệu và thời gian khởi động mỗi vòng.
Ring liền nhau gửi 12 MiB mỗi chiều mỗi vòng qua một NIC, tốn khoảng 0,25 ms; mười bốn cạnh còn lại của cùng vòng đi qua NVLink, mỗi cạnh 12 MiB chỉ tốn khoảng 0,03 ms, nhưng tất cả phải chờ một cạnh đó. Vậy ba mươi vòng tổng cộng khoảng 7,6 ms. Ring xen kẽ có cả mười sáu cạnh mỗi cạnh gửi 12 MiB qua NIC riêng mỗi vòng, cũng khoảng 0,25 ms mỗi vòng, cũng tổng cộng khoảng 7,6 ms qua ba mươi vòng: ring xen kẽ giữ mọi NIC bận rộn, nhưng tăng lưu lượng xuyên máy chủ gấp tám lần mà không rút ngắn thời gian.
Hai vòng xuyên máy chủ của reduction phân cấp mỗi vòng gửi 12 MiB mỗi NIC, tổng cộng khoảng 0,50 ms. ReduceScatter và AllGather cục bộ tổng cộng mười bốn vòng, mỗi participant gửi 24 MiB qua NVLink ở 450 GB/s, tổng cộng khoảng 0,78 ms. Mười sáu vòng khởi động tổng cộng khoảng 13 μs, cho
Việc truyền của ring liền nhau đã vượt ngân sách 3 ms, trong khi reduction phân cấp để lại khoảng 1,7 ms cho việc tính toán reduction, lan truyền và xếp hàng. Reduction phân cấp giảm khối lượng truyền xuyên máy chủ khoảng 47%, và giảm thời gian truyền thông khoảng 83%. Hai tỉ lệ này khác nhau rất lớn, và nguyên nhân không nằm ở số byte mà nằm ở đường đi: trong mỗi vòng trong ba mươi vòng của ring liền nhau, mọi vòng phải chờ cạnh xuyên máy chủ truyền xong 12 MiB qua NIC của nó, trong khi mười bốn cạnh kia truyền xong qua NVLink trong khoảng 0,03 ms rồi chỉ ngồi chờ cạnh đó, khiến mười bốn NIC còn lại không có gì để truyền trong suốt vòng; reduction phân cấp nén truyền xuyên máy chủ vào hai vòng, với cả tám NIC đồng thời truyền mỗi cái 12 MiB, biến băng thông hiệu dụng của tập cắt từ 50 GB/s thành 400 GB/s.
Thảo luận: kết nối nội bộ phải nhanh đến mức nào để reduction phân cấp có lợi? Viết băng thông cục bộ là , giữ NIC ở 50 GB/s mỗi chiều. Mười bốn vòng cục bộ của reduction phân cấp gửi tổng cộng 336 MiB, và hai vòng xuyên máy chủ mất khoảng 0,5 ms; chỉ cần không thấp hơn băng thông NIC, thời gian của ring liền nhau luôn được quyết định bởi cạnh xuyên máy chủ duy nhất đó, khoảng 7,6 ms. Đặt hai giá trị bằng nhau, , cho GB/s: chỉ cần kết nối cục bộ không chậm hơn một NIC, reduction phân cấp nhanh hơn, và NVLink ở 450 GB/s vượt xa ngưỡng này. Reduction phân cấp không gánh phí tổn nào trên máy chủ này, vì khối lượng gửi cục bộ của mỗi participant (336 MiB) không lớn hơn so với ring liền nhau (360 MiB), và giai đoạn xuyên máy chủ sử dụng cả tám NIC.
Reduction phân cấp không phải lúc nào cũng miễn phí. Làm phản ví dụ, hãy xét một cấu hình máy chủ PCIe phổ biến (gọi là cấu hình tham chiếu bên dưới): bốn card A100 80GB mỗi máy, nối card-tới-card qua PCIe Gen4 x16 điểm-nối-điểm, 32 GB/s mỗi chiều; mỗi máy trang bị một ConnectX-7 hai cổng, với hai cổng 200 Gbit/s mỗi cổng 25 GB/s, dùng chung cùng một khe PCIe Gen4 x16 cho NIC này, nên cũng chỉ cho 32 GB/s mỗi chiều. Ring liền nhau trên tám participant mất mười bốn vòng, mỗi vòng gửi 24 MiB; các cạnh cục bộ bị giới hạn bởi liên kết điểm-nối-điểm, các cạnh xuyên máy chủ bởi khe của NIC, mỗi vòng được tính ở 32 GB/s, mất khoảng 11,0 ms. Hai vòng xuyên máy chủ của reduction phân cấp mỗi vòng cần gửi 96 MiB qua khe mỗi chiều, tổng cộng khoảng 6,3 ms, cộng sáu vòng truyền thông cục bộ khoảng 9,4 ms, tổng cộng khoảng 15,7 ms — thực tế chậm hơn ring liền nhau. Đặt hai giá trị bằng nhau cho băng thông cục bộ khoảng 64 GB/s, gần gấp đôi băng thông khe của NIC. Cầu NVLink của A100 PCIe cung cấp 300 GB/s mỗi chiều, vượt xa ngưỡng này, nhưng một cầu đơn chỉ nối được hai card, nên hai trong các cạnh của ring bốn card vẫn đi qua PCIe; nếu mọi cạnh của ring bốn card có băng thông này, reduction phân cấp sẽ giảm xuống khoảng 7,3 ms, chỉ khi đó mới nhanh hơn ring liền nhau. Sự khác biệt bắt nguồn từ giao diện dùng chung: giai đoạn xuyên máy chủ dồn lát của cả tám participant vào hai vòng, và lưu lượng của cả hai vòng phải đi qua cùng một khe 32 GB/s, nên các byte từ xa tiết kiệm được nhờ giảm tổng cục bộ bị bù một phần bởi các vòng từ xa dài hơn; và vì liên kết cục bộ không nhanh hơn khe đó, thời gian tăng thêm do giảm tổng cục bộ cũng không thể thu hồi lại.
Reduction phân cấp trước tiên hoàn thành giảm tổng một phần trên kết nối cục bộ nhanh hơn, rồi gửi kết quả ra ngoài qua NIC. Nó giảm số byte xuyên máy chủ, và quan trọng hơn, cho mỗi NIC một lát riêng để truyền. Khi băng thông xuyên máy chủ được cung cấp bởi nhiều NIC độc lập, reduction phân cấp gần như không tốn kém; khi băng thông xuyên máy chủ là một giao diện dùng chung, reduction phân cấp chỉ nhanh hơn nếu thời gian tăng thêm do giảm tổng cục bộ nhỏ hơn thời gian truyền từ xa mà nó tiết kiệm được.
Sơ đồ thứ tư: reduction trong mạng. Ba sơ đồ đầu đều cho các participant gửi dữ liệu theo cặp, với switch chỉ chuyển tiếp. Reduction trong mạng (in-network reduction) cho switch thực hiện phép cộng trong khi chuyển tiếp: SHARP (Scalable Hierarchical Aggregation and Reduction Protocol) của NVIDIA giảm tổng dữ liệu từ nhiều cổng dọc theo một cây gom tụ bên trong chip switch, rồi phân phối kết quả trở lại, nên các đầu cuối không bao giờ phải gửi cùng một dữ liệu nhiều lần. Giữ nguyên ReduceScatter và AllGather cục bộ của reduction phân cấp, chỉ giai đoạn xuyên máy chủ được thay thế: mỗi participant gửi lát 24 MiB của mình tới switch một lần, và nhận kết quả đã giảm tổng một lần — chỉ một vòng. Với hai máy chủ, mỗi NIC vẫn gửi 24 MiB mỗi chiều, và tổng xuyên máy chủ vẫn là 384 MiB, giống reduction phân cấp; thời gian thay đổi từ 0,505 ms của hai vòng thành 0,504 ms của một vòng, chỉ tiết kiệm một lần khởi động 0,83 μs.
Sự khác biệt hiện ra khi số máy chủ tăng lên. Gọi là số máy chủ giữ cùng một lát. Ring AllReduce có mỗi NIC gửi MiB qua vòng; reduction trong mạng có mỗi NIC luôn gửi một lần và nhận một lần. Thời gian của giai đoạn xuyên máy chủ được thể hiện trong bảng dưới và Hình 7-8:
| Máy chủ | Ring: gửi mỗi NIC | Ring: số vòng | Ring: thời gian | Reduction trong mạng: gửi mỗi NIC | Reduction trong mạng: thời gian |
|---|---|---|---|---|---|
| 2 | 24 MiB | 2 | 0,505 ms | 24 MiB | 0,504 ms |
| 4 | 36 MiB | 6 | 0,760 ms | 24 MiB | 0,504 ms |
| 8 | 42 MiB | 14 | 0,892 ms | 24 MiB | 0,504 ms |
| 16 | 45 MiB | 30 | 0,969 ms | 24 MiB | 0,504 ms |
| 32 | 46,5 MiB | 62 | 1,027 ms | 24 MiB | 0,504 ms |

Thảo luận: khi nào reduction trong mạng rõ ràng nhanh hơn? Với hai máy chủ, hai cách chỉ khác một lần khởi động; từ trở đi, ring truyền lần số byte so với reduction trong mạng và thêm lần khởi động vòng — khoảng cách nới rộng khi số máy chủ tăng, và ở 32 máy chủ reduction trong mạng chỉ mất 49% thời gian của ring. Mô hình này chỉ tính các lần gửi nối tiếp của NIC và các lần khởi động; mỗi giây động cơ reduction của switch có thể giảm tổng bao nhiêu byte, và nó hỗ trợ những kiểu dữ liệu nào, là các đầu vào phải được cung cấp riêng — một khi lưu lượng vượt mức đó, nút thắt chuyển từ NIC sang switch. Bài báo SHARP đo trên 128 máy chủ, một AllReduce 8 byte giảm từ 6,01 μs xuống 2,83 μs, và một AllReduce 4096 byte giảm từ 46,93 μs xuống 14,48 μs: với thông điệp nhỏ, khoản tiết kiệm chủ yếu đến từ thời gian khởi động tiết kiệm được nhờ ít vòng hơn.
Thí nghiệm 7-4 · Mở rộng: khi nào reduction trong mạng đáng giá
Chuyển gradient sang BF16 (96 MiB mỗi participant), và tính lại thời gian xuyên máy chủ cho ring và reduction trong mạng với hai và tám máy chủ. Giả sử động cơ reduction của switch có thông lượng reduction mỗi chiều 200 GB/s, xác định nó có trở thành nút thắt khi tám rail giảm tổng đồng thời hay không, và tìm thông lượng động cơ tối thiểu để reduction trong mạng vẫn nhanh hơn ring. Cuối cùng, dùng đầu vào 8 KiB từ Mục 7.6.3, so sánh tổng thời gian khởi động cho 36 layer mỗi layer hai lần reduction khác nhau bao nhiêu giữa hai sơ đồ.
7.2.2 Yêu cầu truyền thông của song song tensor và song song pipeline
Song song dữ liệu hòa giải gradient của mọi participant qua reduction. Song song tensor chia phép tính của một layer lên nhiều participant, và toán tử tiếp theo thường phải chờ các kết quả cục bộ được hòa giải mới bắt đầu được, nên truyền thông trong một layer trực tiếp làm trì hoãn tính toán tiếp theo. Song song pipeline cắt model ra theo stage, dồn các chuyển giao xuyên máy chủ vào ranh giới stage. Dưới hai sơ đồ, số lần dữ liệu đi ngang ranh giới máy chủ khác nhau.
Trước tiên tính khối lượng dữ liệu của một lần chuyển giao giữa các layer. Qwen3-8B có chiều rộng ẩn 4096, nên một vector ẩn BF16 là 8 KiB. Trong prefill, cùng tensor đó cho 8192 token là 64 MiB, trong khi cho decode yêu cầu đơn là 8 KiB. Lấy băng thông liên kết bằng giá trị NIC của chương này là 50 GB/s, và thời gian khởi động mỗi truyền là 5 μs; truyền byte mất
64 MiB mất khoảng 1,3 ms, và 8 KiB mất khoảng 5,2 μs. Với trường hợp trước, phần lớn thời gian dành để truyền dữ liệu; với trường hợp sau, khoảng 97% thời gian dành cho khởi động. Khi thời gian khởi động bằng thời gian truyền, byte, tức khoảng 244 KiB. Khi khối lượng dữ liệu lớn hơn giá trị này rất nhiều, thời gian truyền chiếm ưu thế và tăng băng thông hiệu quả hơn; khi nhỏ hơn rất nhiều, giảm số lần truyền hiệu quả hơn.
Công thức trên cho chi phí của một lần chuyển giao; với song song pipeline ta cũng cần thấy nhiều lần chuyển giao xen kẽ với tính toán như thế nào. Song song pipeline đặt vài layer liên tiếp trên cùng một stage, truyền activation giữa các stage. Trong khi stage trước xử lý micro-batch kế tiếp, stage sau có thể xử lý micro-batch trước đó. Lấy bốn stage forward, mỗi stage mất 1 ms. Một micro-batch đi qua bốn stage theo thứ tự, kết thúc sau 4 ms. Với tám micro-batch độc lập được nạp liên tục, stage đầu chuyển kết quả của một micro-batch cho stage kế tiếp mỗi mili-giây, và micro-batch cuối kết thúc ở mốc 11 ms.
Nhìn dọc theo cùng một số trong Hình 7-9, một micro-batch phải đi qua cả bốn stage; nhìn dọc theo cùng một hàng, một stage có thể xử lý tám micro-batch liên tiếp. Các vùng trống ở góc dưới-trái và trên-phải là thời gian nhàn rỗi lúc pipeline khởi động và kết thúc.

Tổng quát, với stage thời lượng bằng nhau, micro-batch độc lập, và mỗi stage mất , tổng thời gian và mức sử dụng của mỗi stage là
Với bốn stage và tám micro-batch, mức sử dụng khoảng 73%. Để đạt 90%, từ ta cần ít nhất 27 micro-batch độc lập. Giữ mọi stage pipeline liên tục bận rộn đòi hỏi đủ micro-batch độc lập. Trong decode độ đồng thời thấp, token tiếp theo của cùng một yêu cầu phụ thuộc đầu ra của token trước, nên thêm máy chủ không tạo ra micro-batch độc lập mới; chỉ tăng yêu cầu đồng thời mới tăng công việc độc lập trong pipeline.
Do đó hai dạng song song hóa tạo ra các loại chờ đợi khác nhau: song song tensor phải thường xuyên hòa giải các kết quả cục bộ, còn song song pipeline khiến một số card nhàn rỗi lúc khởi động và kết thúc. Tensor của prefill lớn, nên ưu tiên nên đặt vào việc giảm dữ liệu truyền xuyên máy chủ; decode độ đồng thời thấp sinh token từng cái một, nên ưu tiên đặt vào việc giảm số lần khởi động truyền thông mỗi layer. Số yêu cầu đồng thời quyết định mức sử dụng pipeline.
7.2.3 Tải truyền thông của song song chuyên gia (Expert Parallelism)
Truyền thông của song song tensor và song song pipeline được quyết định bởi cách chia; MoE thêm một biến nữa: các expert được mỗi token chọn có thể khác nhau, nên đích gửi thay đổi theo. Expert parallelism đặt các expert trên các card khác nhau, và token được định tuyến tới các expert tương ứng. Lấy 1024 token, mỗi token chọn tám expert, tổng cộng 8192 lần dispatch. Mỗi activation là 8 KiB, một nửa trong đó xuyên máy chủ, nên đầu vào được dispatch tới các expert ở xa lên tới 4096 mảnh, tổng cộng 32 MiB; combine trả về một kết quả cùng kích thước, thêm 32 MiB nữa.
Gọi số token là , số lượng chọn mỗi token là , kích thước mỗi activation là byte, và tỉ lệ vượt biên là . Nếu mỗi lần dispatch được truyền riêng lẻ, khối lượng truyền dispatch là , và cộng các kết quả expert do combine trả về cho tổng . Đặt các expert phổ biến trên máy chủ nơi người gửi đang ở giảm ; thay đổi kiểu dữ liệu hay phương pháp mã hóa của activation thay đổi .
Cách 32 MiB này được phân phối tới các bên nhận cũng ảnh hưởng thời gian truyền. Gửi toàn bộ vào một NIC 50 GB/s cần ít nhất khoảng 0,67 ms để nhận (Hình 7-10); chia đều lên tám NIC của máy chủ nhận, mỗi NIC nhận 4 MiB, hạ thời gian nhận xuống khoảng 0,08 ms (Hình 7-11). Trong cấu hình tham chiếu, hai cổng của NIC hai cổng dùng chung một khe PCIe 32 GB/s, nên dù chia lưu lượng thế nào giữa hai cổng, nhận 32 MiB vẫn cần ít nhất khoảng 1,05 ms. Trải đều lưu lượng lên các NIC loại bỏ nút thắt NIC đơn; khi các cổng dùng chung một khe, cái khe dùng chung đó trở thành nút thắt mới.


Sau khi đã trải các đích nhận lên nhiều NIC, ta vẫn cần lần ngược về giao diện dùng chung mà chúng đi qua. Hình 7-12 vẽ riêng khe dùng chung của cấu hình tham chiếu: dù lưu lượng sau đó được chia thế nào lên hai cổng, 32 MiB này trước hết phải đi qua cùng một khe.

So sánh ba sơ đồ đường đi này, trải các đích giảm khối lượng dữ liệu trên từng NIC; nhìn dọc theo điểm vào dùng chung trong sơ đồ cuối, toàn bộ 32 MiB vẫn phải đi qua nó. Khi tính truyền thông không đều, cũng nên thống kê trước lưu lượng tại từng điểm này một cách riêng biệt.
Ký hiệu tải trọng gửi từ card i tới card là . Cộng dọc theo một hàng cho khối lượng gửi của người gửi, cộng dọc theo một cột cho khối lượng nhận của người nhận; cộng các phần tử ngang một tập cắt cho trước cho khối lượng truyền của tập cắt đó. Chia mỗi đại lượng này cho băng thông tương ứng và lấy giá trị lớn nhất chính là mô hình tài nguyên của Mục 7.1 áp dụng cho các trao đổi không đều.
Ma trận này cũng cho thấy các điểm nóng của dispatch và combine tương ứng ra sao. Nếu token được gửi tới các expert từng mảnh một, và vector trả về cùng kích thước với không gộp nào ở phía nhận, ma trận trả về là chuyển vị của ma trận gửi: bên nhận điểm nóng của dispatch là bên gửi điểm nóng của combine. Tổng byte bằng nhau ở hai chiều không có nghĩa là thời gian bằng nhau ở hai chiều: dữ liệu trả về chưa sẵn sàng cho tới khi expert tính xong, và băng thông khả dụng, định dạng dữ liệu, vị trí giảm tổng cũng có thể khác nhau giữa hai chiều. Nếu dispatch dùng FP8 và combine dùng BF16, tải trọng trả về gần gấp đôi so với dispatch, không tính metadata như các thang lượng tử hóa. Mục 9.4 sẽ đặt lưu lượng này cùng với thời điểm sẵn sàng tính toán trong cùng một ví dụ làm việc.
Vì vậy việc đặt expert có hai mục tiêu liên kết với nhau: giữ nhiều dispatch ở cục bộ hơn, và trải các dispatch từ xa lên các bên nhận còn băng thông dư. Nhân bản các expert phổ biến đánh đổi dung lượng thừa để giảm lưu lượng từ xa; đầu vào dành cho nhiều expert trên cùng một card có thể được truyền như một activation đơn và được chia cho các expert một khi nó tới card đó. Cả hai cách tiếp cận giảm khối lượng truyền trên các đường đi tương ứng.
7.2.4 Nhiều NIC
Dispatch của expert minh họa cả lợi ích của các điểm vào song song lẫn giới hạn của một điểm vào dùng chung. Phân tích tương tự cũng áp dụng phía người gửi: thêm một NIC chỉ rút ngắn thời gian truyền khi nó thực sự cung cấp thêm băng thông khả dụng và có dữ liệu được gán cho nó. Ring ngây thơ của Mục 7.2.1 là một ví dụ: mỗi trong tám NIC của máy chủ nối tới một card, vậy mà ring ngây thơ chỉ đưa cho một trong chúng dữ liệu để truyền; chỉ sau khi reduction phân cấp chia shard giữa tám cặp participant, giai đoạn xuyên máy chủ mới giảm từ 7,6 ms xuống khoảng 0,5 ms. Có một NIC không có nghĩa là nó đang được dùng — thuật toán truyền thông quyết định mỗi NIC nhận bao nhiêu byte.
Cấu hình tham chiếu minh họa một loại giới hạn khác. NIC hai cổng của nó có hai cổng 25 GB/s dùng chung một khe PCIe 32 GB/s. Chỉ dùng một cổng, mười bốn vòng của ring ngây thơ tám participant mất khoảng 14,1 ms; chia dữ liệu của mỗi lần truyền thành hai đoạn và đưa cho hai cổng chỉ nâng thông lượng lên mức cho phép 32 GB/s của khe, hạ thời gian xuống khoảng 11,0 ms — không phải khoảng 7,1 ms mà tổng 50 GB/s của hai cổng gợi ý. Ngay cả chuyển sang ConnectX-7 bốn cổng và đưa cổng thứ ba vào dùng, khe vẫn là PCIe Gen4 x16 cũ, nên truyền này không thể rút ngắn thêm. Một khi băng thông của giao diện dùng chung đã cạn, thêm cổng không còn nâng thông lượng.
Một tình huống khác là khi NIC gắn trực tiếp vào một GPU đang bận trong khi NIC của một GPU lân cận nhàn rỗi. Mượn cổng thoát của người hàng xóm đòi hỏi trước tiên gửi dữ liệu tới GPU lân cận qua NVLink, thêm một đoạn truyền cục bộ. Hệ truyền thông đa NIC FuseLink đi đúng đường này: dùng các kết nối GPU nội máy, nó ánh xạ lại bộ đệm mạng lên một NIC nhàn rỗi.
Bên dưới ta so sánh gửi trực tiếp với chuyển tiếp qua một GPU lân cận. NIC gắn trực tiếp cung cấp 50 GB/s mỗi chiều, hai NIC lân cận có thể mượn mỗi cái cũng 50 GB/s; NVLink tới GPU lân cận cung cấp 450 GB/s mỗi chiều.

Theo nhánh trong Hình 7-13: đường trực tiếp và đường chuyển tiếp có thể truyền đồng thời, nhưng dữ liệu phải tuần tự đi qua hai đoạn bên trong đường chuyển tiếp. Vậy đường trực tiếp và đường chuyển tiếp cùng có thể cung cấp GB/s. Gọi là băng thông mà mạng ngoài và đường nhận cùng nhau cho phép; công suất gửi hiệu dụng là
trong đó cũng đo bằng GB/s. Khi , NIC trực tiếp đã có thể làm bão hòa băng thông hạ lưu, và chuyển tiếp không mang lại lợi ích; khi , lợi ích của chuyển tiếp tăng khi băng thông khả dụng hạ lưu tăng; vượt 150, băng thông tổng hợp của hai NIC mượn trở thành nút thắt mới. Nếu NVLink đồng thời đang mang lưu lượng cho việc giảm tổng cục bộ, và băng thông cục bộ còn lại cho chuyển tiếp giảm xuống dưới 100 GB/s, thì ràng buộc trên đường chuyển tiếp chuyển sang đoạn cục bộ này. Một tải trọng 1,125 GiB mất khoảng 24,2 ms trên đường trực tiếp 50 GB/s, giảm xuống 12,1 ms khi hạ lưu hỗ trợ 100 GB/s, và giảm xuống 8,1 ms khi nó hỗ trợ 150 GB/s.
Phân tích mượn NIC dựa trên băng thông ở trên giả định khối lượng dữ liệu của mỗi lần truyền đủ lớn. Dispatch và combine của MoE decode có mỗi card gửi vài nghìn thông điệp nhỏ, lúc đó ta cũng phải kiểm tra mỗi giây NIC có thể khởi động bao nhiêu yêu cầu — tức từ Mục 7.3.4. Dùng ns của mục đó cho các triển khai kết nối tin cậy RoCE, một NIC có thể khởi động khoảng 54 triệu yêu cầu mỗi giây; trên một liên kết 50 GB/s, chỉ khi một thông điệp nhỏ hơn khoảng 0,93 KB thì tốc độ khởi động mới trở thành nút thắt trước băng thông. Một thông điệp dispatch của MoE là vector ẩn của một token — với chiều ẩn 7168, đó là khoảng 7 KiB ở FP8 hoặc khoảng 14 KiB ở BF16, cả hai đều vượt xa điểm giao này, nên card giữ expert nóng vẫn cạn băng thông trước, và mượn một NIC lân cận bằng cách phân bổ byte là đủ. Chỉ khi mỗi thông điệp dưới 1 KB, ví dụ các thông điệp điều khiển gửi từng cái một, tốc độ khởi động mới cạn trước băng thông; Mục 9.4.2, khi thảo luận việc đặt bản sao expert, cũng tính năng lực xử lý gói tin của NIC như một tài nguyên cần khoảng trống dự trữ trong trường hợp này.
Dù là reduction phân cấp, đặt expert, hay chuyển tiếp đa NIC, các bước phân tích đều giống nhau: vẽ đường đi, tính khối lượng dữ liệu truyền qua từng liên kết và giao diện, và tìm mục có thời lượng dài nhất.
Thí nghiệm 7-5 · Cốt lõi: băng thông cục bộ và cổng thoát dùng chung ảnh hưởng việc chọn thuật toán reduction như thế nào
Làm lại hoàn toàn Ví dụ 7.2, rồi chuyển sang cấu hình tham chiếu (bốn card A100 80GB PCIe mỗi máy chủ, nối từng cặp qua PCIe Gen4 ở 32 GB/s mỗi chiều, ConnectX-7 hai cổng với hai cổng 25 GB/s dùng chung một khe PCIe 32 GB/s) và tính lại ring ngây thơ và reduction phân cấp. Dưới cấu hình tham chiếu, nâng băng thông cục bộ từ 32 GB/s lên 300 GB/s của cầu NVLink (giả định mọi cạnh giữa bốn card có băng thông này), và giải thích vì sao lựa chọn thuật toán reduction bị đảo ngược, trong khi dưới cấu hình của chương này thì không. Rồi tăng số cổng dùng mỗi máy chủ trong cấu hình tham chiếu từ một lên hai lên ba, giữ khe 32 GB/s cố định, vẽ thời gian reduction theo số cổng, và xác định vượt quá bao nhiêu cổng thì thêm cổng không còn rút ngắn thời gian.
7.2.5 Cấu trúc liên kết đa rail
Reduction phân cấp của Mục 7.2.1 cho tám cặp participant mỗi cặp dùng một rail. Kiến trúc tham chiếu DGX SuperPOD tổ chức mạng tính toán thành một cấu trúc liên kết đa rail (multi-rail topology) (tối ưu hóa rail): tám NIC của mỗi máy chủ nối tới tám switch lá khác nhau, và NIC trên mọi máy chủ nối tới switch lá ; switch lá cùng với mọi NIC gắn vào nó tạo thành rail . Trong cùng một nhóm 32 máy chủ, lưu lượng trên cùng một rail tới đích trong một hop qua switch lá, còn lưu lượng giữa các rail khác nhau phải đi qua một switch spine. Mạng chuyển mạch trong Hình 7-1 với “một switch mỗi rail” được tổ chức theo cách này.
Giai đoạn xuyên máy chủ của reduction phân cấp ghép cặp rank với rank : rank dùng NIC trên máy chủ A, và rank dùng NIC trên máy chủ B, và cả hai NIC đều nối tới switch lá . Vậy lưu lượng của cả tám cặp nằm trong một rail duy nhất, chỉ đi qua một switch lá, và không một byte nào đi ngang switch spine. Mỗi rail mang 24 MiB mỗi chiều, mất 0,505 ms cho hai vòng; dồn 192 MiB này lên một NIC đơn sẽ mất 4,03 ms, và cho tám rail hoạt động đồng thời rút ngắn xuống khoảng một phần tám. Nửa trên của Hình 7-14 vẽ việc ghép cặp thẳng hàng này, và nửa dưới vẽ việc ghép cặp lệch thảo luận bên dưới.

Đổi ghép cặp thành rank với rank (rank 7 với rank 8), rank vẫn dùng rail , nhưng bạn của nó giờ dùng rail . Byte của mỗi cặp trước hết phải vào switch lá , rồi chuyển sang switch lá qua switch spine — cả tám cặp không ngoại lệ — nên mỗi chiều, toàn bộ 192 MiB đi qua tầng spine. Khối lượng gửi mỗi NIC không đổi, và cận dưới của giai đoạn xuyên máy chủ vẫn là 0,505 ms; điều thay đổi là các byte này giờ chiếm các liên kết trên switch spine, dùng chung chúng với lưu lượng xuyên rail của các job khác, và cũng đi qua băm đa đường thảo luận ở Mục 7.5.3. Việc ghép cặp có thẳng hàng hay không chỉ phụ thuộc chỉ số của hai rank trong máy chủ tương ứng của chúng có khớp nhau hay không: bằng nhau thì nằm trong một rail, khác nhau thì qua tầng spine. Ring xen kẽ (Hình 7-5) trả cùng chi phí này trên cấu trúc đa rail: cả mười sáu cạnh của nó đều xuyên máy chủ, cạnh thẳng hàng, cạnh không, nên một nửa số byte phải đi qua tầng spine.
Áp quy tắc này vào supernode 128 card của Mục 7.6.4. Mười sáu máy chủ mỗi máy tám card; nhóm tensor-parallel chiếm cả tám card của một máy chủ, và card ở tọa độ tensor-parallel luôn là card trên mọi máy chủ, dùng rail ; mười sáu thành viên song song dữ liệu ở cùng tọa độ trao đổi, sau khi giảm tổng trong supernode, chính xác shard gradient cho tọa độ đó xuyên các supernode. Các shard ở tám tọa độ có kích thước bằng nhau (mỗi card giữ GB), nên tám rail mỗi cái mang một phần tám khối lượng gửi xuyên supernode, tức 14 GB trong 112 GB, không có rail nào bận hơn rail nào. Một rail bận hơn chỉ xuất hiện khi kích thước shard khác nhau (ví dụ từ việc chia tensor không đều), hoặc khi một NIC hỏng và lưu lượng của nó được định tuyến lại qua một NIC lân cận trên NVLink (Mục 7.2.4).
Thí nghiệm 7-6 · Mở rộng: thẳng hàng rail và lưu lượng tầng spine
Trên hai máy chủ, đổi ghép cặp thành rank với rank , và tìm số byte đi qua tầng spine. Rồi cho NIC 3 trên máy chủ B hỏng, với lưu lượng của rank 11 chia đều qua NVLink giữa NIC 2 và NIC 4, và tìm byte mà mỗi rail mang và thời gian của giai đoạn xuyên máy chủ. Cuối cùng, trong supernode 128 card của Mục 7.6.4, chuyển sang TP16 (một nhóm trải hai máy chủ), và giải thích mỗi rail mang shard của những tọa độ nào và tải có còn cân bằng hay không.
7.3 Đường đi và độ đồng thời trong truy cập từ xa
7.3.1 Truyền dữ liệu và thông báo hoàn tất
Mục 7.2 chỉ tính các byte đi qua những liên kết nào và mất bao lâu, mà không giải thích các byte này được bàn giao ra sao. Trong giai đoạn xuyên máy chủ của reduction phân cấp, card 0 đã có shard đã giảm tổng cục bộ và cần chuyển nó cho card 8. Một lần bàn giao dữ liệu gồm hai việc: ghi shard vào một vị trí card 8 đọc được, và cho card 8 biết dữ liệu đã sẵn sàng. Việc đầu thay đổi vị trí dữ liệu cư trú; việc thứ hai báo cho bên nhận thời điểm nó có thể bắt đầu tính toán.
read/write một phía trong Mục 6.5.5 cho phía khởi động truy cập trực tiếp bộ nhớ từ xa đã được ủy quyền — ví dụ, card 0 ghi shard của nó vào vùng nhận của card 8: NIC của phía khởi động đọc shard từ bộ nhớ cục bộ, NIC đích ghi nó vào bộ nhớ của card 8, và chương trình bạn không tham gia vào thao tác di chuyển này. Truyền thông hai phía (two-sided messaging) yêu cầu người gửi và người nhận hợp tác: người nhận nộp trước một yêu cầu nhận và cung cấp một buffer, và hệ truyền thông khớp các thông điệp đến với các yêu cầu tương ứng. Một shard lớn với đích đã biết hợp với read/write trực tiếp; các thông báo từ nhiều người gửi thì nên đặt trong một hàng đợi thông điệp, thứ phân biệt từng thông báo và đưa nó cho người tiêu thụ dữ liệu tương ứng, gọi là consumer bên dưới.
Dữ liệu lớn và thông báo do đó có thể được chia ra: ghi shard trước, rồi gửi một thông điệp ngắn báo shard đã sẵn sàng để dùng. Gộp việc ghi và thông báo thành một lần nộp tiết kiệm thêm một vòng tròn. Consumer bắt đầu giảm tổng sau khi nhận thông báo; thứ tự giữa ghi và thông báo được thảo luận thêm ở Mục 7.4.
Ghi và thông báo hoàn thành việc bàn giao dữ liệu. Nếu bên nhận cũng phải xử lý dữ liệu theo một cách xác định, hãy dùng một thủ tục gọi từ xa (RPC): điều này yêu cầu bên bạn thực thi một hàm xác định, và một lần gọi gồm truyền tham số, thực thi từ xa, và trả về kết quả. Cách tham số được mã hóa ảnh hưởng trực tiếp chi phí của đường này: JSON là định dạng trao đổi dữ liệu dạng văn bản; base64 mã hóa mỗi 3 byte nhị phân thành 4 ký tự văn bản. Đặt 1 MiB dữ liệu nhị phân vào một trường JSON base64 làm tăng tải trọng mã hóa khoảng một phần ba. Chuyển sang một yêu cầu nhị phân đồng thời giảm số byte gửi và khối lượng công việc mã hóa.
Trong một bộ đo RPC xuyên máy chủ kèm cuốn sách này, kích thước yêu cầu giảm từ khoảng 1,33 MiB xuống 1,00 MiB, và thời gian xử lý CPU phía client trung vị giảm từ khoảng 9,8 ms xuống 1,1 ms. Trong 20 cặp lời gọi sản xuất được ghép, 11 cặp nhanh hơn về tổng thể, trong khi thời gian truyền mạng và chờ chuyển tiếp dao động nhiều hơn. Các phép đo này phân biệt hai loại thời gian: giảm mã hóa tiết kiệm thời gian CPU cục bộ; rút ngắn toàn bộ lời gọi cũng cần giảm việc chờ đợi trong mạng, chuyển tiếp và thực thi từ xa.
Thí nghiệm 7-7 · Mở rộng: gỡ bỏ chuyển đổi mã hóa tiết kiệm được bao nhiêu thời gian gọi từ xa
Từ các bản ghi kèm theo, chọn các cặp lời gọi có cùng tải trọng, và vẽ dòng thời gian của mã hóa phía client, gửi, chờ, giải mã và thực thi phía máy chủ. Giải thích vì sao thời gian thực thi phía máy chủ đã nằm trong thời gian chờ phía client. Tính mức giảm byte truyền khi bỏ mã hóa base64, và phân tích phần thời gian dành cho mã hóa ảnh hưởng tốc độ tăng thu được cho lời gọi đầy đủ như thế nào.
7.3.2 Truyền thông trực tiếp do bộ tăng tốc sinh dữ liệu khởi động
Mục 7.3.1 phân biệt read/write, thông điệp và RPC từ góc nhìn bên nhận. Phía người gửi, câu hỏi là: ai là người đầu tiên biết dữ liệu đã sẵn sàng, và ai chịu trách nhiệm nộp yêu cầu. Shard của card 0 được sinh trên GPU. Nếu CPU nộp truyền thông, GPU trước hết báo sẵn sàng, CPU dựng yêu cầu và đưa cho NIC, và khi hoàn tất nó trao trạng thái lại cho GPU. Đường điều khiển này gồm nhiều lần bàn giao; ngay cả khi tải trọng không bao giờ đi qua bộ nhớ CPU, bản thân các lần bàn giao vẫn tốn thời gian.
NIC RDMA đã có thể truy cập bộ nhớ từ xa đã được ủy quyền; GPUDirect RDMA của NVIDIA đi xa hơn, để NIC truy cập trực tiếp bộ nhớ GPU đã đăng ký và được ủy quyền, nên tải trọng không cần chuyển tiếp qua bộ nhớ host. Khi CPU khởi động truyền thông, CPU vẫn chịu trách nhiệm nộp yêu cầu và xử lý thông báo hoàn tất; khi bộ tăng tốc khởi động truyền thông, bản thân GPU dựng hoặc kích hoạt yêu cầu và đọc trạng thái hoàn tất, nên nó có thể phát truyền ngay khi tính toán xong. URMA là giao diện truy cập bộ nhớ từ xa thống nhất do UB cung cấp. GPU truy cập bộ nhớ của bên bạn qua NVLink, và một thiết bị khởi động truy cập không đồng bộ qua UB, đều là các triển khai của sự cộng tác trực tiếp này trên các đường đi tương ứng. Các Hình 7-15 đến 7-18 lần lượt vẽ RPC host, GPUDirect RDMA do CPU nộp, GPU truy cập qua NVLink, và truy cập URMA do thiết bị khởi động.


Một khi dữ liệu bỏ qua bộ nhớ host, người khởi động truyền có thể được thay đổi xa hơn. Trong Hình 7-17, bản thân GPU khởi động truy cập bộ nhớ của bên bạn, loại bỏ lần bàn giao mà nếu không sẽ đòi hỏi CPU nộp yêu cầu mỗi lần.

Hình 7-18 đặt cùng quan hệ khởi động-và-hoàn-tất lên giao diện truy cập không đồng bộ của UB. Lần theo tải trọng dọc theo đường liền và phần điều khiển theo quan hệ nộp-và-hoàn-tất cho phép ta tách chi phí truyền dữ liệu khỏi chi phí quản lý yêu cầu.

Thay đổi này có thể được giải thích bằng công thức thời gian truyền từ Mục 7.2. Dùng lại ví dụ liên kết 50 GB/s từ Mục 7.2.2, thời gian truyền cho 8 KiB dữ liệu là khoảng 0,16 μs; nếu thời gian khởi động co từ 5 μs xuống 2 μs, tổng thời gian giảm từ khoảng 5,2 μs xuống 2,2 μs — một khoản tiết kiệm hơn một nửa. Với tải trọng 64 MiB, bản thân việc truyền mất khoảng 1,3 ms, nên cùng khoản tiết kiệm 3 μs trở nên không đáng kể. Các truyền nhỏ do đó nên ưu tiên giảm chi phí nộp, còn các truyền lớn nên ưu tiên băng thông cao hơn.
Việc host tổ chức truyền thông thống nhất có lợi ích cung cấp một cơ chế nộp và xử lý hoàn tất đa dụng cho các chương trình tùy ý. Trong thực thi model, người sản xuất, người tiêu thụ và điều kiện sẵn sàng của dữ liệu đều được xác định rõ, nên việc khởi động và xử lý hoàn tất thường xuyên có thể được chuyển về phía thiết bị: hệ thống thiết lập ánh xạ địa chỉ và quyền truy cập trước, sau đó thiết bị liên tục khởi động tính toán và truyền thông mà không chuyển tiếp qua host mỗi lần. Lợi ích chính là việc giảm thời gian khởi động thấy trong ví dụ trên.
Hệ điều hành chịu trách nhiệm thiết lập ánh xạ, đặt quyền và phân bổ tài nguyên; thiết bị chịu trách nhiệm các thao tác nhanh, đã được ủy quyền; thông báo hoàn tất trao kết quả của thao tác lại cho runtime. Một khi trách nhiệm được phân chia như vậy, luồng khởi động truyền thông trên chính thiết bị cũng trở thành một giới hạn của thông lượng. Phân tích giới hạn này đòi hỏi trước tiên xác định một yêu cầu đơn phải chờ bao lâu, liệu các yêu cầu khác có thể được khởi động trong lúc chờ đó, rồi tính mỗi đơn vị thời gian xử lý được bao nhiêu yêu cầu.
7.3.3 Ngữ nghĩa bộ nhớ: load/store so với read/write
Để phân biệt hai cái này, trước hết tách chúng theo cách thức truy cập được biểu diễn. Truy cập từ xa có hai biểu diễn phổ biến: các lệnh load/store của bộ xử lý, và các yêu cầu read/write không đồng bộ tường minh. Cả hai cần theo dõi các yêu cầu đang treo; sự khác biệt nằm ở ai quản lý việc theo dõi đó.
Kết quả của một load có thể trở thành đầu vào trực tiếp của một lệnh tiếp theo. Bộ xử lý ghi lại phụ thuộc này và thực thi các lệnh độc lập khác trong lúc chờ. Một yêu cầu không đồng bộ thay vào đó đặt địa chỉ đích, độ dài và điều kiện hoàn tất vào một hàng đợi; phần mềm có thể nộp nhiều mẩu công việc theo thứ tự và chờ yêu cầu tương ứng hoàn tất trước khi dùng kết quả. Cái trước giao sự phụ thuộc cho cơ chế thực thi lệnh; cái sau giao nó cho sự kiện và runtime. Cuốn sách này gọi load/store là truy cập đồng bộ để nhấn mạnh rằng các phụ thuộc lệnh được quản lý bởi phần cứng — không phải bộ xử lý chỉ có thể có một truy cập bộ nhớ đang treo tại một thời điểm; các bộ xử lý hiện đại có thể thực thi song song nhiều load độc lập, và các store cũng có thể vào một buffer trước.
| So sánh | Load/store | Read/write không đồng bộ |
|---|---|---|
| Khởi động và đường đi | Lệnh bộ xử lý, tới bộ nhớ truy cập được qua ánh xạ địa chỉ; trên UB có thể được xử lý bởi một controller trên die | Nộp địa chỉ, độ dài, v.v. như một yêu cầu; tiến triển qua hàng đợi, doorbell, hoặc giao diện do thiết bị khởi động |
| Phụ thuộc và hoàn tất | Phần cứng theo dõi người tiêu thụ của một load; khả năng thấy từ xa của một store cần các đảm bảo thứ tự riêng | Runtime chờ một sự kiện hoàn tất được chỉ định trước khi dùng kết quả hoặc thu hồi buffer |
| Các trường hợp dùng điển hình | Các đọc hạt mịn, truy cập con trỏ, dữ liệu truy cập thường xuyên và cần chi phí nộp thấp | Di chuyển khối lượng lớn activation, KV, trọng số, và pipeline hóa tường minh |
| Giới hạn độ đồng thời | Phụ thuộc lệnh, slot truy cập đang treo, dịch địa chỉ và tài nguyên phần cứng | Hàng đợi yêu cầu, hàng đợi hoàn tất, bộ nhớ đã đăng ký, năng lực nộp phần mềm hoặc thiết bị |
| Xử lý lỗi | Phụ thuộc cơ chế timeout, ngoại lệ và lỗi bộ nhớ của nền tảng | Lỗi có thể được báo cáo mỗi yêu cầu; timeout, ghi một phần và thu hồi buffer vẫn phải được xử lý |
Cả hai loại giao diện đều có thể áp dụng ngữ nghĩa bộ nhớ, nhưng tính nhất quán cache (cache coherence) không thể được suy ra chỉ từ cái tên của giao diện. Read/write một phía không yêu cầu ứng dụng từ xa nộp các yêu cầu nhận khớp nhau mỗi lần, nhưng vẫn cần ủy quyền trước và tính hợp lệ của bộ nhớ; load/store cũng không đảm bảo tính nhất quán tự động của các cache dùng chung giữa các nút. Đường load/store được triển khai trong OpenURMA không duy trì tính nhất quán cache xuyên nút; các phụ thuộc giữa write, publish và read được sắp xếp bởi chính ứng dụng. Vòng tròn PCIe mà nó loại bỏ đến từ việc thay đổi vị trí controller và đường đi yêu cầu — chỉ đơn thuần đổi tên một giao diện phần mềm thành “load” không mang lại cùng lợi ích.
Phân rã độ trễ của một read từ xa đơn. Chia đường găng của một read từ xa 64 B đơn thành các giai đoạn, gán độ trễ cho mỗi giai đoạn, và cộng chúng lại để lấy tổng thời gian của read đó. Ba đường được so sánh ở đây: một read không đồng bộ qua NIC ngoại vi PCIe, một read không đồng bộ qua controller bus trên die (giao diện URMA của UB), và một lệnh load qua controller bus trên die. Các điều kiện cho trước như sau: một lần đi ngang bus trên die mất 30 ns; một doorbell write PCIe mất 150 ns, một DMA read PCIe 500 ns và write 250 ns; lan truyền đường một chiều là 100 ns; một row hit trên bộ nhớ phía đích (hàng DRAM giữ dữ liệu được yêu cầu đã mở sẵn) mất 30 ns; các chu kỳ pipeline NIC được quy đổi ở xung nhịp 322 MHz — 9 chu kỳ cho NIC ngoại vi, 25 chu kỳ cho đường không đồng bộ UB, và 8 chu kỳ cho đường load; nộp thư viện giao diện, dựng bộ mô tả yêu cầu, và poll hoàn tất đều tính là chi phí phần mềm. Bảng dưới liệt kê các giai đoạn theo thứ tự đường găng; một ô trống nghĩa là đường đó không có giai đoạn như vậy.
| Giai đoạn | Loại | NIC ngoại vi PCIe | UB read không đồng bộ | UB load | |---|---|---|---:|---:|---:| | Nộp thư viện giao diện | Nộp phần mềm | 50 | 50 | | | Dựng bộ mô tả yêu cầu | Nộp phần mềm | 30 | 30 | | | Doorbell write | Đi ngang PCIe | 150 | | | | NIC DMA đọc bộ mô tả | Đi ngang PCIe | 500 | | | | Nộp bus trên die | Bus trên die | | 30 | 30 | | Pipeline gửi NIC | Pipeline NIC | 28 | 78 | 25 | | Đường đi ra | Đường truyền | 100 | 100 | 100 | | Pipeline nhận NIC đích | Pipeline NIC | 28 | 78 | 25 | | NIC đích DMA đọc bộ nhớ host | Đi ngang PCIe | 500 | | | | Truy cập bộ nhớ bus trên die đích | Bus trên die | | 30 | 30 | | Row hit bộ nhớ đích | Bộ nhớ và hoàn tất | 30 | 30 | 30 | | NIC đích gửi phản hồi | Pipeline NIC | 28 | 78 | 25 | | Đường trả về | Đường truyền | 100 | 100 | 100 | | NIC nhận phản hồi | Pipeline NIC | 28 | 78 | 25 | | DMA ghi tải trọng phản hồi | Đi ngang PCIe | 250 | | | | DMA ghi bản ghi hoàn tất | Đi ngang PCIe | 250 | | | | Hoàn tất bus trên die | Bus trên die | | 30 | 30 | | Poll hàng đợi hoàn tất | Bộ nhớ và hoàn tất | 70 | 5 | | | Poll thư viện giao diện | Bộ nhớ và hoàn tất | 30 | 30 | | | Tuần tự hóa phân bổ số thứ tự | Bộ nhớ và hoàn tất | 50 | | | | Tổng (suy ra) | | 2222 | 746 | 419 | | Đo mô phỏng | | 2236 | 757 | 500 |
Các thời gian pipeline NIC trong bảng đã được làm tròn, và các tổng được cộng từ các giá trị chưa làm tròn. Đường qua NIC ngoại vi PCIe tổng cộng 2222 ns, trong đó năm lần đi ngang PCIe chiếm 1650 ns; đường không đồng bộ UB không có giai đoạn PCIe nào và tổng cộng 746 ns; đường load cũng loại bỏ việc nộp và poll phần mềm, tổng cộng 419 ns. Hình 7-19 xếp chồng ba đường theo loại giai đoạn dưới dạng biểu đồ cột. Trong triển khai OpenURMA của tác giả, dưới một mô phỏng hai nút theo chu kỳ với cùng điều kiện, các giá trị đo được là 2236, 757 và 500 ns, khác các giá trị suy ra lần lượt 14, 11 và 81 ns. Chênh lệch đến từ chi phí cố định của bộ mô phỏng khi truyền dữ liệu giữa các mô-đun; vì đường load có ít giai đoạn nhất và tổng thời gian ngắn nhất, chi phí này chiếm tỉ trọng lớn nhất ở đó.

Các giai đoạn thêm trong đường NIC ngoại vi PCIe không phải chín sự kém hiệu quả độc lập có thể tối ưu hóa từng cái, mà đến từ ba nguyên nhân cấu trúc. Thứ nhất, yêu cầu phải được ghi thành một bộ mô tả trong bộ nhớ host trước khi NIC đọc nó, do đó có các giai đoạn nộp thư viện giao diện và dựng bộ mô tả. Thứ hai, NIC và bộ xử lý mỗi cái có không gian địa chỉ riêng, do đó có doorbell write, DMA bộ mô tả và các giai đoạn DMA phía đích. Thứ ba, một khi thao tác hoàn tất, bộ xử lý phải được thông báo xuyên các không gian địa chỉ, do đó có DMA phản hồi, DMA bản ghi hoàn tất, và hai giai đoạn poll. Một khi controller được gắn vào bus trên die, loại giai đoạn thứ hai gộp thành một lần đi ngang bus trên die; một khi dùng các lệnh load, việc theo dõi phụ thuộc của chính bộ xử lý thay thế cơ chế thông báo hoàn tất, và các loại giai đoạn thứ nhất cũng như thứ ba biến mất hoàn toàn.
Còn có một đường thứ tư: NIC vẫn là ngoại vi PCIe, nhưng bộ mô tả yêu cầu được dựng và tiêu thụ bởi một bộ xử lý bên trong chính NIC — vị trí khởi động thứ ba từ Mục 6.4.4. Làm việc qua cùng bảng này, đường này loại bỏ doorbell write và đi ngang DMA-đọc-bộ-mô-tả của NIC, tiết kiệm 650 ns; 80 ns cho việc nộp phần mềm và dựng bộ mô tả thay vào đó được thực hiện trên bộ xử lý của chính NIC, định giá theo cùng cách; DMA ghi tải trọng, DMA ghi bản ghi hoàn tất và DMA đọc phía đích vẫn còn. Tổng cộng khoảng 1572 ns, nằm giữa 2222 ns của đường kiểu ngoại vi và 746 ns của đường bus trên die. Thứ bị loại bỏ là các lần đi ngang trên đường điều khiển; thứ không thể loại bỏ là dữ liệu và thông báo hoàn tất vẫn phải đi qua hai không gian địa chỉ. Đường này không được mô phỏng, chỉ được suy ra từ các giá trị trong bảng.
Khi độ trễ đường truyền thay đổi, các khoảng cách giữa ba đường thay đổi theo. Tổng thời gian của mỗi đường bằng một chi phí cố định cộng hai lần độ trễ đường truyền một chiều : với NIC ngoại vi PCIe là 2022 ns cộng ; với đường không đồng bộ UB, 546 ns cộng ; với đường load, 219 ns cộng . Hình 7-20 vẽ từ 50 ns đến 500 ns: ba đường có cùng độ dốc nhưng hệ số chặn khác nhau, và khoảng cách tuyệt đối giữ nguyên khoảng 1,8 μs trong suốt, trong khi khoảng cách tương đối co từ 5,3× ở ns xuống 2,5× ở ns. Đường càng ngắn, lợi ích tương đối của vị trí controller càng lớn — đó là lý do lợi ích này nổi bật nhất bên trong một supernode; trên các liên kết dài trải khắp một trung tâm dữ liệu, bản thân độ trễ đường truyền trở thành phần chiếm ưu thế của tổng thời gian. Hai thành phần này khác nhau về bản chất. được ấn định bởi tốc độ lan truyền tín hiệu và không thể bị loại bỏ bởi bất kỳ đường nào — đó là cận dưới vật lý của một read từ xa đơn. Phần của hệ số chặn vượt quá giá trị của đường load là chi phí của tầng trừu tượng hóa, trong đó riêng năm lần đi ngang PCIe đã chiếm 1650 ns. Các khoảng cách 14, 11 và 81 ns giữa giá trị suy ra và mô phỏng rơi vào loại khoảng cách thứ nhất được mô tả trong Mục 1.3.4: mô hình đã bỏ qua chi phí cố định giữa các mô-đun của bộ mô phỏng, và một khi số hạng đó được thêm lại thì khoảng cách biến mất — không cần đi tìm chi phí triển khai.

Giờ dùng cùng các độ trễ truy cập để so sánh độ đồng thời và phụ thuộc, rồi thảo luận việc tái sử dụng dữ liệu. Cái trước áp dụng cho cả hai loại giao diện; cái sau là một lựa chọn đặt — “truy cập từ xa theo nhu cầu, hay di chuyển dữ liệu về cục bộ trước” — và độc lập với giao diện được dùng. Đọc từ xa trực tiếp không tương đương với load, và việc di chuyển dữ liệu về trước cũng không ứng với một giao diện cụ thể nào.
Xét tám read từ xa độc lập lẫn nhau. Phần cứng có thể xử lý cả tám cùng lúc, mỗi cái mất khoảng 2,2 μs trên đường NIC ngoại vi PCIe (chi phí nộp đã được tính). Phát chúng từng cái một theo kiểu “gửi, chờ, dùng” mất khoảng 17,8 μs; phát cả tám cùng lúc, các kết quả đều tới sau khoảng 2,2 μs. Nếu read đầu trả về địa chỉ cho read thứ hai, và read thứ hai trả về địa chỉ cho read thứ ba, thì mỗi read phải chờ read trước trả về trước khi phát read tiếp theo. Có thể phát bao nhiêu read đồng thời phụ thuộc có bao nhiêu yêu cầu có địa chỉ đã biết và độc lập lẫn nhau.
Các read song song khai thác tính độc lập giữa các yêu cầu khác nhau. Nếu nhiều yêu cầu truy cập cùng một mẩu dữ liệu, có thể khai thác một quan hệ khác: ở lần truy cập đầu, di chuyển dữ liệu về cục bộ, và tái sử dụng bản sao đó cho các lần đọc sau. Giả sử một consumer sẽ đọc hoàn toàn một snapshot KV bất biến 144 MiB, và có đủ chỗ cục bộ để giữ nó. Cả các read từ xa và truyền staging đều đi qua NIC của chương này, ở 50 GB/s mỗi chiều; các read cục bộ dùng băng thông HBM 3350 GB/s của H100. Gồm khởi động và ghi phía đích, một read từ xa tốn khoảng 3,02 ms, chi phí cố định của một lần truyền staging khoảng 3,07 ms, và mỗi read cục bộ sau đó tốn khoảng 0,046 ms.
Gọi là số lần tái sử dụng. Thời gian của hai đường xấp xỉ
Đọc sau staging trở nên nhanh hơn khi — tức từ lần đọc đầy đủ thứ hai trở đi. Với một lần đọc, truy cập từ xa trực tiếp nhanh hơn chút (3,02 ms so với 3,12 ms); với bốn lần đọc, staging cục bộ trước rút tổng thời gian từ khoảng 12,1 ms xuống khoảng 3,3 ms, và mạng chỉ cần truyền snapshot một lần, cắt khối lượng truyền từ 576 MiB xuống 144 MiB. Hình 7-21 vẽ hai đường sử dụng, và Hình 7-22 vẽ điểm giao của thời gian tích lũy.


Sự khác biệt giữa hai đường quy về “trả một chi phí staging một lần, so với đọc qua mạng mỗi lần”. Giờ đổi phạm vi truy cập trong mỗi read. Nếu một lời gọi đơn chỉ truy cập một phần nhỏ các vị trí của snapshot, nó có thể truyền theo tham chiếu, để hàm từ xa đọc dữ liệu theo nhu cầu. Giả sử mỗi read chỉ truy cập 10% snapshot, trong khi cách staging vẫn sao toàn bộ snapshot. Trong trường hợp này, chi phí của các read từ xa theo nhu cầu trở thành khoảng ms, mỗi truy cập cục bộ sau staging khoảng 0,0046 ms, và điểm giao rơi vào khoảng 10,3 lần đọc — nên chỉ bắt đầu từ lần đọc thứ 11, staging cục bộ mới tiết kiệm tổng thời gian đọc (Hình 7-23).

Lựa chọn giữa read từ xa theo nhu cầu và staging toàn bộ snapshot về cục bộ do đó nên phụ thuộc vào phạm vi truy cập và số lần tái sử dụng. URPC là một giao diện thủ tục gọi từ xa trên kết nối thống nhất, cung cấp truy cập từ xa dưới dạng lời gọi hàm và hỗ trợ mẫu này; truyền theo tham chiếu cho phép phía được gọi chỉ lấy dữ liệu nó thực sự cần. Mục 7.4 sẽ giải thích khi nào cần thông báo cho các thiết bị khác dùng những đối tượng này, và khi nào giải phóng không gian chúng chiếm.
7.3.4 Mô hình độ đồng thời và thông lượng
Mục 7.3.3 dùng tái sử dụng để giảm số read từ xa; với các yêu cầu vẫn phải đi qua mạng, liên kết cần luôn có dữ liệu để truyền. Mục này phân tích cần bao nhiêu yêu cầu đồng thời cho một đường 50 GB/s mỗi chiều trên một NIC đơn, như dùng trong các ví dụ của chương này. Một slot yêu cầu là một bản ghi chứa địa chỉ, độ dài và trạng thái của một yêu cầu đang treo: nó được phân bổ khi nộp và được giải phóng sau khi trạng thái hoàn tất đã được xử lý, và không thể bị một yêu cầu mới dùng lại trước đó. Giả sử mỗi truy cập từ xa truyền 256 B, và mất 2 μs từ khi phát yêu cầu đến khi giải phóng slot yêu cầu. Trong 2 μs đó, liên kết có thể truyền 100.000 B, tương đương khối lượng dữ liệu của 390,6 truy cập. Để giữ liên kết được cấp dữ liệu liên tục trong lúc chờ, phải duy trì ít nhất 391 giao dịch in-flight — yêu cầu đã phát nhưng chưa được xử lý xong. Hình 7-24 vẽ vòng đời của một slot từ phân bổ đến giải phóng.

Tổng quát, nếu tải trọng mỗi giao dịch là , thời gian chiếm slot là , và băng thông mục tiêu là , độ đồng thời cần thiết là
Tích băng thông–độ trễ (bandwidth-latency product) là tích của băng thông mục tiêu và thời gian chờ, biểu diễn lượng dữ liệu in-flight cần thiết để giữ liên kết được dùng liên tục trong lúc chờ. Chia cho tải trọng mỗi giao dịch rồi ra số yêu cầu. Liên kết càng nhanh và thời gian chờ càng dài, mỗi lần trả về mang càng ít dữ liệu, và hệ thống phải theo dõi đồng thời càng nhiều yêu cầu đang treo.
Ví dụ 7.3: Vì sao số slot in-flight không đủ cho các read từ xa ngăn việc dùng trọn băng thông thoát. Mỗi giao dịch truyền 256 B và chiếm một slot trong 2 μs, với băng thông đường là 50 GB/s. Tìm băng thông đọc hiệu dụng khi dùng 128 slot hoạt động; rồi, biết rằng khoảng cách ngắn nhất giữa hai giao dịch liên tiếp do đơn vị xử lý yêu cầu phát ra là 18,6 ns (giá trị cho triển khai kết nối tin cậy RoCE thảo luận sau trong mục này), tìm cận trên băng thông hiệu dụng khi cả số slot lẫn tốc độ phát cùng giới hạn thông lượng.
Lời giải: 128 slot quay vòng mỗi 2 μs, cung cấp tải trọng B, cho tối đa khoảng 16,4 GB/s. Với chỉ một giao dịch in-flight, con số đó là 0,128 GB/s. Số slot đã phân bổ và số slot thực tế được dùng đồng thời là hai đại lượng khác nhau.

Các khoảng xám trong Hình 7-25 xuất hiện vì các slot chưa được giải phóng; dù có đủ slot, các yêu cầu có thể không được nộp kịp. Nếu đơn vị xử lý yêu cầu phát một giao dịch mỗi 18,6 ns, nó có thể phát tối đa khoảng 54 triệu mỗi giây, và các giao dịch 256 B chỉ cung cấp được khoảng 13,7 GB/s — thậm chí thấp hơn cả 16,4 GB/s mà 128 slot cho. Ngay cả tăng lên 391 slot, đơn vị xử lý yêu cầu vẫn không nộp đủ nhanh để đạt mức đó. Gộp băng thông đường, số yêu cầu in-flight và tốc độ phát thành một ràng buộc duy nhất cho

Ở đây, là thời gian một yêu cầu đơn chiếm một slot, và là khoảng phát ngắn nhất giữa hai yêu cầu liên tiếp. Cái trước quyết định một slot có thể được tái dùng sớm bao lâu; cái sau quyết định số yêu cầu tối đa có thể phát mỗi giây. Hình 7-26 so sánh băng thông hiệu dụng khi chỉ xét ràng buộc slot với khi thêm ràng buộc tốc độ phát.
Thảo luận: một read từ xa cần bao nhiêu độ đồng thời để đạt 50 GB/s? Giữ các giao dịch 256 B, khoảng phát phải co xuống còn ns — ngắn hơn cả 6.2 ns của triển khai UB thảo luận bên dưới — trong khi vẫn duy trì ít nhất 391 thao tác in-flight. Một cách tiếp cận khác là gộp các truy cập liền kề: chuyển mỗi lần truyền thành 4 KiB, một khoảng phát không quá 82 ns là đủ để đạt 50 GB/s; một khoảng 18,6 ns khi đó ứng với khoảng 220 GB/s, vượt xa liên kết — và với thời gian chờ 2 μs, chỉ cần 25 slot để duy trì 50 GB/s. Cái trước tăng tốc độ giao dịch; cái sau truyền nhiều dữ liệu hơn mỗi yêu cầu, hạ chi phí nộp trên mỗi byte.
Một nguồn cụ thể của khoảng phát có thể thấy trong triển khai của OpenURMA: giai đoạn chậm nhất của pipeline gửi nhận một yêu cầu mỗi 2 chu kỳ xung nhịp, cho ns ở 322 MHz, hay tối đa khoảng 161 triệu yêu cầu mỗi giây. Trong một so sánh dùng cùng chuỗi công cụ để triển khai các kết nối tin cậy RoCE, việc phân bổ số thứ tự của mỗi kết nối có một phụ thuộc tuần tự, nên mỗi yêu cầu tốn 6 chu kỳ, cho ns, hay khoảng 54 triệu mỗi giây. Mô phỏng với các burst liên tục 256 yêu cầu, các tốc độ duy trì đo được lần lượt là 150 và 54 yêu cầu mỗi micro-giây: RoCE khớp con số suy ra 53,7 mỗi micro-giây, còn UB thấp hơn khoảng 7% so với con số suy ra 161; khi burst được kéo dài lên 1000 yêu cầu, UB tăng lên khoảng 159 mỗi micro-giây, trong khoảng 1% của giá trị suy ra. Thay vào : ở 64 B mỗi yêu cầu, hai cái cho lần lượt 10,3 GB/s và 3,4 GB/s; ở 4 KiB mỗi yêu cầu, 660 GB/s và 220 GB/s — cả hai đều vượt xa 50 GB/s mỗi chiều của NIC 400 Gbit/s trong chương này. Tức là, với tải trọng nhỏ nút thắt là tốc độ yêu cầu, còn với tải trọng lớn nút thắt chuyển sang đường truyền.
Vì sao read và write bị giới hạn khác nhau. và trong công thức có nguồn gốc rõ ràng trên PCIe. PCIe là một bus chuyển mạch gói tin, và mỗi DMA read hoặc write là một gói tin lớp giao dịch (transaction layer packet — TLP). Write là giao dịch posted: gói tin mang địa chỉ và dữ liệu và được coi là hoàn tất ngay khi gửi đi, không chờ phản hồi. Read là giao dịch non-posted: một gói tin yêu cầu mang một tag được phát ra, và dữ liệu được trả về bằng một hoặc nhiều gói tin hoàn tất, khớp lại với yêu cầu ban đầu qua tag. Số yêu cầu đọc mà một người gửi có thể có in-flight đồng thời bị giới hạn bởi hai thứ: số credit mà bên nhận đã cấp trước cho loại giao dịch đó, và số tag mà người gửi có thể phân bổ. Hình 7-27 vẽ hai loại giao dịch.

Các giới hạn do credit và tag áp đặt có thể được quan sát trên các nền tảng thực. Tác giả đo cả hai giới hạn trong KV-Direct. NIC lập trình được dùng truy cập bộ nhớ host qua PCIe Gen3 x8, với băng thông lý thuyết 7,87 GB/s; mỗi DMA read hoặc write 64 B mang một tiêu đề gói tin 26 B và phần đệm, nên cận trên dựa trên chi phí gói tin là 5,6 GB/s, hay 87 triệu thao tác mỗi giây. Vòng tròn của một DMA read ngẫu nhiên khoảng 1050 ns, cần 92 read đồng thời để bão hòa liên kết; nhưng host chỉ phát hành 84 credit cho DMA read, và động cơ DMA của FPGA chỉ hỗ trợ 64 tag, nên tối đa 64 read có thể in-flight, cho cận trên khoảng 61 triệu mỗi giây khi chia cho vòng tròn 1050 ns; các phép đo cho thấy read ngẫu nhiên 64 B đạt khoảng 60 triệu mỗi giây, khớp sát cận trên này. Write không cần phản hồi và không tiêu thụ tag, và các phép đo tiến sát cận trên do riêng chi phí gói tin đưa ra. Hình 7-28 vẽ cùng nhau vài cận trên này: read bị giới hạn bởi số in-flight, write bởi tốc độ xử lý gói tin — chính là một minh họa và mỗi cái tác động riêng. Việc để pipeline NIC tự xử lý việc tính địa chỉ, truy cập bộ nhớ và xử lý kết quả chính xác là điều cho phép nó tiếp tục phát các yêu cầu khác trong khi chờ kết quả của một read. Các con số này cũng minh họa thứ tự kiểm tra từ Mục 1.3.4: tinh chỉnh mô hình liên tiếp với băng thông liên kết, chi phí gói tin và các giới hạn tag in-flight cho đến khi trong khoảng 1,6% của phép đo — tại điểm đó mô hình không còn thiếu sót nào, và khoảng cách dư không cần theo đuổi thêm.

Khi cùng một liên kết PCIe được chia sẻ bởi hai loại lưu lượng, sự bất đối xứng này biến thành tranh chấp không đều. Giả sử chiều vào GPU trên liên kết PCIe của GPU mang hai flow đồng thời: NIC đưa dữ liệu từ xa trực tiếp vào bộ nhớ GPU qua các write posted; trong khi đó động cơ copy của GPU đang sao dữ liệu từ bộ nhớ host vào GPU, phát các yêu cầu đọc mà dữ liệu của chúng trả về GPU dưới dạng gói tin hoàn tất. Một khi liên kết bão hòa, các write posted phải tiếp tục tiến lên theo giao thức, còn phía đọc, một khi các tag in-flight của nó cạn kiệt, không thể phát yêu cầu mới và phải chờ các gói tin hoàn tất trở về — nhận được ít hơn một nửa băng thông. Chiều ra khỏi GPU khác: bản sao của GPU tới host là một write posted do GPU phát, trong khi một read từ xa vào bộ nhớ GPU yêu cầu GPU trả lời bằng một gói tin hoàn tất; cả hai trước hết phải lấy dữ liệu từ HBM rồi gửi ra qua đường gửi của GPU, nên nút thắt nằm bên trong GPU thay vì trên liên kết, và hai flow suy thoái đối xứng hơn. Hình 7-29 vẽ cả hai chiều. Để xét loại tranh chấp này, trước hết xác định mỗi flow là write posted hay read mang hoàn tất, rồi xem chúng hội tụ ở phía nào của liên kết và đi qua thành phần dùng chung nào. Các công cụ đo PCIe đời sau như rPCIeBench, nghiên cứu các đường PCIe dùng chung, cũng cho thấy khối lượng công việc in-flight và tranh chấp điểm vào thay đổi cách phân bổ băng thông. Công thức trên có thể dùng để xét nút thắt: liệu băng thông liên kết đã cạn, các slot yêu cầu chưa được giải phóng, hay tốc độ phát yêu cầu quá thấp.

Reduction phân cấp giảm tải trọng xuyên máy chủ, và nộp đồng thời giữ mạng truyền liên tục; chương trình vẫn cần biết khi nào dữ liệu này có thể được dùng, và khi nào không gian nó chiếm có thể được giải phóng.
Thí nghiệm 7-8 · Mở rộng: cần bao nhiêu giao dịch in-flight để bão hòa băng thông đọc từ xa
Trong Ví dụ 7.3, tăng thời gian chiếm slot từ 2 μs lên 4 μs; thời gian này được đo từ khi yêu cầu được phát đến khi slot trở nên tái dùng được. Tìm số giao dịch in-flight cần để duy trì băng thông mục tiêu cho các truyền 256 B và 4 KiB tương ứng. Cố định khoảng phát ở 18,6 ns, tìm kích thước giao dịch tối thiểu cần để đạt 50 GB/s; rồi tính lại dùng 6,2 ns của triển khai UB. Cuối cùng, đổi các địa chỉ độc lập thành một chuỗi con trỏ, và giải thích thời gian cần để đọc xuyên toàn bộ chuỗi con trỏ tăng theo độ dài chuỗi như thế nào.
7.4 Bàn giao dữ liệu, thứ tự thực hiện và quản lý trạng thái
7.4.1 Tạo shard, tiêu thụ và tái sử dụng bộ đệm
Một khi dữ liệu tới, bên nhận có thể chưa bắt đầu dùng nó, hoặc đã đang dùng. Điều này giống việc trao một khay vật liệu cho giai đoạn tiếp theo của quy trình: khay đã tới, nhưng phía bên kia vẫn cần thời gian để xử lý vật liệu trong khay, và vật liệu trên khay không thể bị hoán đổi sang mẻ kế tiếp trước khi nó xong. Ánh xạ sang truyền thông, việc hoàn tất gửi, khả năng thấy dữ liệu của bên nhận, và việc tiêu thụ xong của bên nhận phải được xét riêng biệt. Mục 7.3.4 coi thời gian chiếm slot là một giá trị cho trước; mục này theo dõi các sự kiện này để xác định khi nào một buffer có thể được giải phóng.
Trong reduction phân cấp, card 0 chuyển shard cục bộ của nó cho card 8, và card 8 cộng nó vào shard của chính mình. Người gửi cần biết khi nào buffer nguồn có thể bị ghi đè, người nhận cần biết khi nào buffer đích có thể được đọc, và lần ghi tiếp theo cần biết khi nào buffer đích này có thể bị ghi đè. Chúng tương ứng với ba sự kiện riêng biệt.
Một shard trải qua quy trình sau từ khi tạo đến khi giải phóng: tạo dữ liệu, ghi sang phía từ xa, làm dữ liệu thấy được với bên nhận, phát thông báo sẵn sàng, đọc và xử lý dữ liệu, và cuối cùng giải phóng không gian. Buffer nguồn có thể được tái dùng hay không phụ thuộc việc ngữ nghĩa hoàn tất của giao diện có đảm bảo truyền không còn đọc nó; để bên nhận bắt đầu dùng dữ liệu, write trước hết phải thấy được với nó, và các thông báo sẵn sàng phải được publish và kiểm tra đúng quy ước; buffer đích có thể bị ghi đè hay không vẫn phụ thuộc việc bên nhận dùng xong dữ liệu trong đó. Việc hoàn tất của bản thân truyền mạng không thể thay thế cho một thông báo “dùng xong”.
Ví dụ, gửi hoàn tất ở 5 μs, và consumer bắt đầu đọc ở 8 μs và kết thúc ở 12 μs. Người gửi có thể tái dùng buffer nguồn ngay khi gửi hoàn tất, nhưng buffer đích không thể bị ghi đè cho tới 12 μs. Nếu write kế tiếp ghi đè địa chỉ đích ở 6 μs, consumer đọc mẻ dữ liệu tiếp theo; mỗi byte truyền qua mạng đều đúng, vậy mà chương trình nhận tiêu thụ nhầm dữ liệu.

Trong Hình 7-30, hai khoảng chiếm dụng kết thúc ở những sự kiện khác nhau. Vẽ “sự kiện nào phải xảy ra trước khi việc này có thể tiến hành” thành các mũi tên tạo ra một đồ thị phụ thuộc mô tả việc bàn giao đúng: các nút biểu diễn công việc, và một cạnh nghĩa là chỉ được bắt đầu sau khi hoàn tất. Với mỗi nút, lấy thời gian hoàn tất muộn nhất trong các nút tiền nhiệm của nó cộng thời gian thực thi của chính nó cho thời gian hoàn tất; chuỗi từ đầu đến cuối có tổng thời gian dài nhất là đường găng.
Mô hình này giải thích cả tính đúng lẫn hiệu năng. Thiếu phụ thuộc “dữ liệu thấy được → thông báo đã phát” khiến consumer đọc dữ liệu chưa được publish; các cạnh thừa ép cả các truyền không liên quan chờ đợi làm tăng thời gian chờ. Nhiệm vụ của quản lý trạng thái là ghi lại nút nào đã hoàn tất, phụ thuộc nào đã được thỏa mãn, và tài nguyên nào có thể được trả về.
Quyền sở hữu buffer cũng ảnh hưởng số lần sao chép. Nếu một thư viện truyền thông phân bổ một buffer đã đăng ký riêng cho việc gửi, kết quả tính toán trước hết phải được sao vào nó, metadata phải được đóng gói cùng dữ liệu, và bên nhận sau đó phải giải nén và chuyển nó vào một vùng liên tục — toàn bộ việc sao chép và đóng gói này tiêu thụ thời gian SM. Việc để phép tính ghi trực tiếp vào một buffer đã đăng ký tránh được bước này, nhưng siết chặt thứ tự sự kiện thảo luận trong mục này: việc gửi chỉ có thể được khởi động sau khi phép tính ghi xong và dữ liệu thấy được với NIC, buffer này không thể bị ghi đè trước khi gửi thực sự hoàn tất, và bên nhận cũng phải theo cùng các quy tắc để xác định khi nào nó có thể đọc và khi nào có thể thu hồi.
7.4.2 Tách lớp giao dịch khỏi lớp truyền tải: Jetty và trạng thái dùng chung
Các phụ thuộc và trạng thái hoàn tất này cần được hệ thống lưu ở đâu đó. Có phải mỗi quan hệ truyền thông được thêm vào đòi hỏi lưu thêm một bộ bản ghi truyền tải giống hệt nhau? Một reduction giữa mười sáu participant chỉ liên quan một số ít quan hệ truyền thông. Khi hệ thống mở rộng, một tiến trình có nhiều luồng, và mỗi luồng truy cập nhiều đích từ xa, nên số quan hệ tăng theo dạng tích. Ứng dụng cần ghi lại ai đã nộp yêu cầu và thông báo hoàn tất nên được gửi cho ai; lớp truyền tải cần duy trì số thứ tự, xác nhận, truyền lại và trạng thái tắc nghẽn. Cái trước nhận diện ứng dụng, cái sau đảm bảo truyền dữ liệu tin cậy.
Endpoint ứng dụng là các định danh logic theo đó một chương trình nộp truyền thông và nhận thông báo hoàn tất; trạng thái truyền tải giữ tiến trình truyền thông như số thứ tự, xác nhận, truyền lại và tốc độ gửi. Lấy 64 endpoint ứng dụng, mỗi endpoint truy cập 128 đích từ xa, cho 8192 quan hệ trong tổng cộng. Nếu lưu một trạng thái truyền tải 1 KiB riêng cho mỗi quan hệ, riêng phần truyền tải đã chiếm 8 MiB. Nếu các quan hệ trỏ tới cùng một đích dùng chung một trạng thái truyền tải, chỉ cần 128 bản sao, tổng cộng 128 KiB. Thứ được tiết kiệm là trạng thái truyền tải mà nếu không sẽ được lưu riêng cho các quan hệ truyền thông khác nhau tới cùng một đích.
Định danh ứng dụng vẫn cần được giữ lại. Mỗi endpoint chiếm 256 B, tổng cộng 16 KiB; thông tin ràng buộc của mỗi quan hệ chiếm 64 B, tổng cộng 512 KiB. Cộng các phần này, tổng trạng thái với lưu trữ độc quyền mỗi quan hệ là khoảng 8,52 MiB, còn dùng chung theo đích đưa nó xuống khoảng 0,64 MiB. Số bản sao trạng thái truyền tải giảm xuống 1/64 so với ban đầu, và tổng trạng thái giảm xuống khoảng 1/13 so với ban đầu.
Gọi là số endpoint, là số đích, và giả sử mỗi endpoint, thông tin ràng buộc của mỗi quan hệ, và mỗi trạng thái truyền tải chiếm lần lượt byte; khi đó
Bài báo OpenURMA mô tả sự tách này bằng các thuật ngữ khác: trên một giao diện cục bộ với endpoint ứng dụng truy cập host từ xa, các bản ghi endpoint cốt lõi và ngữ cảnh truyền tải tăng theo ; nếu mọi quan hệ ứng dụng chiếm giữ độc quyền một kết nối tin cậy, phần này tăng theo . Kết luận này chỉ áp dụng cho trạng thái phần cứng cốt lõi có thể dùng chung; các ánh xạ phần mềm, quyền, yêu cầu đang treo và cache không đều chỉ chiếm không gian cộng tính. Các phương trình trên giữ lại số hạng vì sơ đồ giảng dạy này tính tường minh các bản ghi ràng buộc mỗi quan hệ; về cuối mục này ta tính lại một lần nữa bằng các kích thước bản ghi của một triển khai thực tế.
Hai phương trình trực tiếp cho thấy không gian tiết kiệm được nhờ dùng chung: trở thành , còn số hạng quan hệ ứng dụng giữ nguyên. UB tách Jetty khỏi kênh truyền tải (Mục 6.5.5), áp dụng chính xác thiết kế này: một trạng thái truyền tải đơn có thể phục vụ nhiều quan hệ ứng dụng.


Trong Hình 7-31, nhiều quan hệ dùng lại cùng một trạng thái truyền tải, tiết kiệm lưu trữ nhưng có khả năng tranh chấp cửa sổ gửi, cơ hội lập lịch và tài nguyên phục hồi của kênh đó. Phân lớp không đòi hỏi mọi giao dịch phải được xếp hàng trong một hàng đợi có thứ tự toàn cục duy nhất; thứ tự thực thi, thứ tự hoàn tất và thứ tự gói tin đến của các giao dịch ứng dụng vẫn cần được xác định riêng. Nếu triển khai dùng một hàng đợi đầu-vào-đầu-ra dùng chung hoặc chờ tuần tự, mất gói và yêu cầu dài sẽ gây chặn đầu hàng đợi (head-of-line blocking — khi yêu cầu ở đầu hàng đợi bị trì trệ, các yêu cầu không liên quan phía sau chỉ có thể chờ); cho phép các giao dịch độc lập tiếp tục tiến triển có thể giảm tác động này, nhưng không loại bỏ sự tranh chấp băng thông và cửa sổ dùng chung. Một số lượng lớn yêu cầu đang treo thuộc một quan hệ truyền thông chiếm một hàng đợi dùng chung ép các yêu cầu ngắn từ các quan hệ khác phải chờ. Nếu nhóm độc lập của trạng thái truyền tải được thiết lập cho các mục đích kinh doanh khác nhau, tổng trạng thái trở thành
Dưới cấu hình trên, phần cố định là 528 KiB, và mỗi nhóm trạng thái truyền tải độc lập được thêm vào tốn thêm 128 KiB. Bộ nhớ 1 MiB có thể chứa tối đa ba nhóm độc lập; bốn nhóm cần 1040 KiB, đã vượt dung lượng; tám nhóm cần khoảng 1,52 MiB. Hình 7-32 vẽ dung lượng trạng thái cho các chiến lược dùng chung này. Vậy, việc cô lập theo nghiệp vụ phải được sắp xếp trong giới hạn dung lượng lưu trữ: phân bổ trạng thái truyền tải riêng cho nghiệp vụ quan trọng trong khi để nghiệp vụ khác dùng chung có thể giảm nhiễu mà nghiệp vụ quan trọng gặp phải.
Ngoài việc dùng chung giữa các quan hệ khác nhau, trạng thái cũng có thể được lưu theo phân cấp. Trạng thái đầy đủ nằm trong bộ nhớ chính, trong khi các phần được dùng thường xuyên được cache trên chip NIC. Dùng chung có thể giảm các bản ghi trùng lặp, để một cache cùng kích thước giữ được nhiều quan hệ truyền thông hơn. Trạng thái được dùng thường xuyên nằm trong cache cũng giảm số lần đọc trạng thái từ bộ nhớ chính. Vậy việc tiết kiệm không gian trạng thái cũng có thể giảm chi phí xử lý yêu cầu.
Kích thước bản ghi triển khai và tổng trạng thái. Các con số 256, 64 và 1024 B đưa ra trước đó trong mục này là các giá trị giả định cho mục này. Các cấu trúc trạng thái của triển khai OpenURMA cho một bộ kích thước có thể được đối chiếu với thực tế: 20 B mỗi Jetty, 32 B mỗi đoạn bộ nhớ đã đăng ký, 56 B mỗi kênh truyền tải; để so sánh, một triển khai kết nối tin cậy RoCE lưu một ngữ cảnh QP 512 B mỗi kết nối. Gọi là số endpoint cục bộ truy cập endpoint từ xa; dưới hai sơ đồ tổ chức, trạng thái lưu trên NIC là
So với các phương trình trước, ở đây , , và : triển khai này đặt ràng buộc quan hệ trong một ánh xạ phần mềm, và NIC không lưu trạng thái phần cứng cho mỗi quan hệ. Ở , các kết nối theo từng cặp cần khoảng 512 MiB, trong khi endpoint cộng kênh chỉ cần 108 KiB, chênh khoảng 4855×; ngay cả khi bản ghi Jetty được độn lên bộ đầy đủ các trường trong đặc tả (48 B), tỉ lệ vẫn vượt ba nghìn lần. Hình 7-33 vẽ hai đường cong trên thang log: một đường độ dốc 2, một đường độ dốc 1, với tỉ lệ của chúng tăng tuyến tính theo .

Tổng trạng thái và tràn cache trên chip. NIC cache ngữ cảnh trên chip, với phần không vừa bị tràn xuống bộ nhớ host. Lấy dung lượng cache là 256 KiB, các kết nối theo từng cặp tràn khi , tức ; endpoint cộng kênh tràn khi , tức . Sau khi tràn, mỗi thao tác phải lấy lại ngữ cảnh, và chi phí phụ thuộc ngữ cảnh nằm ở đâu: một NIC ngoại vi PCIe đọc từ bộ nhớ host, với phía khởi động và phía đích mỗi bên thực hiện một DMA read PCIe, tốn thêm khoảng 1000 ns mỗi thao tác; một controller bus trên chip đọc từ bộ nhớ cục bộ, với cả hai bên mỗi bên thực hiện một lần đi ngang bus trên chip và một truy cập bộ nhớ, tốn thêm khoảng 200 ns. Hình 7-34 vẽ độ trễ của hai đường này, suy ra ở Mục 7.3.3, theo số endpoint hoạt động. Truyền thông all-to-all trong huấn luyện thường liên quan hàng chục tới hàng nghìn endpoint, rơi đúng vào khoảng này; trong khoảng này, mọi read dưới các kết nối theo từng cặp phải trả chi phí lấy lại ngữ cảnh. Bộ mô phỏng của tác giả xác định tràn theo số mục chứ không theo số byte (512 mục cho RoCE, 2048 mục cho UB), đặt điểm tràn của UB ở 1024 endpoint; dưới cả hai cách đếm, kết luận là giống nhau: endpoint cộng kênh tràn muộn hơn hơn một bậc độ lớn, và chi phí sau tràn cũng nhỏ hơn một bậc độ lớn.

Thí nghiệm 7-9 · Mở rộng: trạng thái truyền tải dùng chung có thể hỗ trợ bao nhiêu nhóm cô lập
Giữ 64 endpoint chỉ truy cập một đích từ xa đơn, tính tổng không gian lưu trữ cần cho trạng thái truyền tải độc quyền so với dùng chung. Rồi đổi số đích hoạt động thành 128 và nâng không gian lưu trữ khả dụng lên 2 MiB; tìm số nhóm cô lập đầy đủ tối đa có thể xếp vừa. So sánh tác động của việc tăng số endpoint với tăng số đích lên trạng thái cố định và trạng thái truyền tải. Cuối cùng, dùng các kích thước bản ghi của triển khai (20 B mỗi Jetty, 56 B mỗi kênh truyền tải, 512 B mỗi ngữ cảnh kết nối), tìm số endpoint tràn cho mỗi sơ đồ tổ chức khi cache trên chip là 1 MiB.
7.4.3 Phụ thuộc thao tác và cô lập lỗi
Mục 7.4.2 giảm nhiễu giữa các đơn vị nghiệp vụ khác nhau qua các nhóm truyền tải độc lập. Việc chờ không cần thiết cũng có thể xuất hiện bên trong một nhóm thao tác duy nhất, tùy những thao tác nào hệ thống ép phải hoàn tất theo thứ tự. Lấy quy trình publish shard của card 0 làm ví dụ. Thao tác A ghi dữ liệu D, thao tác B publish một thông báo “D đã sẵn sàng”, và thao tác C truyền một mẩu dữ liệu khác không liên quan. Để dùng D đúng cách, thứ tự A→B phải được duy trì, trong khi C có thể dùng một đường truyền tải riêng, độc lập.
Ví dụ 7.4: Những thao tác nào hoàn tất sớm hơn khi các ràng buộc thứ tự được nới lỏng? Việc ghi của A mất 20 μs, tiếp theo là một bước phục hồi 80 μs, sau đó D trở nên thấy được; B mất 2 μs; C mất 10 μs. So sánh hai cách sắp xếp: A, B, C hoàn tất theo thứ tự, so với chỉ yêu cầu B thực thi sau khi A hoàn tất.
Lời giải: Chuỗi phụ thuộc ghi–phục hồi–thông báo mất μs. Cách sắp xếp tuần tự khiến C chờ tới 102 μs mới bắt đầu, với cả nhóm kết thúc ở 112 μs. Chỉ giữ phụ thuộc cần thiết cho phép C bắt đầu ở thời điểm 0 và kết thúc ở 10 μs; chuỗi thông báo vẫn kết thúc ở 102 μs. Cả nhóm kết thúc sớm hơn 10 μs, còn C kết thúc sớm hơn 102 μs. Các Hình 7-35 và 7-36 lần lượt vẽ hai cách sắp xếp này.


Nếu thời gian phục hồi tăng lên 200 μs, C trong cách sắp xếp tuần tự chỉ kết thúc ở 232 μs, trong khi C trong cách độc lập vẫn kết thúc ở 10 μs. Gỡ bỏ phụ thuộc không cần thiết giam sự trì trệ do phục hồi gây ra trong chuỗi thực sự cần dữ liệu này. Với các tác vụ hạ lưu đang chờ C, sự cô lập này quan trọng hơn nhiều so với việc cả nhóm kết thúc sớm hơn 10 μs.
Thứ tự toàn cục giúp các tầng cao dễ mô tả trình tự thao tác, nhưng cũng gấp công việc độc lập vào cùng một chuỗi chờ. Một khi đồ thị tính toán làm tường minh phụ thuộc publish A→B, giao diện và runtime có thể cung cấp các đảm bảo thứ tự xoay quanh phụ thuộc này trong khi để C tiến hành độc lập. Khi ứng dụng cung cấp thông tin phụ thuộc chính xác hơn, mạng chỉ áp đặt thứ tự cho các thao tác liên quan theo đó, vừa đảm bảo bên nhận đọc dữ liệu đã ghi sau khi nhận thông báo vừa giảm việc chờ không cần thiết.
Giờ giả sử mọi thao tác dùng chung một đơn vị xử lý duy nhất: từ khi A bắt đầu ghi đến khi B hoàn tất thông báo, đơn vị đó bị chiếm dụng, và C chỉ có thể thực thi sau đó. Trong trường hợp này, bản thân việc sử dụng tài nguyên thêm vào một cạnh thứ tự từ chuỗi thông báo tới C, và cả hai cách sắp xếp đều kết thúc ở 112 μs. Phụ thuộc chương trình và phụ thuộc tài nguyên do đó phải được vẽ trên cùng một đồ thị: giảm ràng buộc thứ tự trong chương trình vẫn để lại các ràng buộc tài nguyên giới hạn mức song song.
Ca thiết kế: chi phí phần cứng của thứ tự được đặc tả theo nhu cầu. Triển khai OpenURMA của tác giả đặt bốn chế độ dịch vụ thứ tự của UB và ba tag thực thi lên cùng một pipeline gửi. Mô phỏng theo chu kỳ cho thấy: dù một yêu cầu yêu cầu thứ tự nào, nó vẫn tốn 24 chu kỳ từ nộp đến gói tin đầu tiên rời đi; chỉ khi một yêu cầu tường minh yêu cầu chờ các thao tác trước hoàn tất, bộ theo dõi thứ tự mới ép nó chờ, và với tối đa bốn thao tác trước đang treo, việc chờ không vượt 50 chu kỳ, khoảng 155 ns; các yêu cầu không yêu cầu thứ tự không gánh chi phí này. Quan trọng hơn là hiệu ứng cô lập: việc làm trì trệ yêu cầu của một initiator tại điểm nó chờ các thao tác trước không kéo theo bốn initiator khác, những người có 8 yêu cầu không yêu cầu thứ tự đều vẫn được phát trong 78 chu kỳ (khoảng 242 ns). Ngược lại, các yêu cầu trong cùng một QP của một kết nối tin cậy RoCE phải thực thi theo đúng thứ tự — khi một yêu cầu chờ, mọi yêu cầu sau cũng chờ. Đây chính xác là biểu hiện phần cứng của sắp xếp trong Ví dụ 7.4 khi C được đặt sau A và B.
Bối cảnh thiết kế: thứ tự toàn cục đơn giản hóa nhân bản và phối hợp như thế nào?
Tác giả đã khám phá một thiết kế trong nghiên cứu 1Pipe nơi mạng cung cấp một thứ tự toàn cục. Mọi participant quan sát các thao tác theo cùng một thứ tự, để các tầng cao dùng các mô hình thứ tự đơn giản hơn cho nhân bản và phối hợp. Khi xử lý lỗi sâu hơn, thứ tự và phân phát cần được xử lý riêng: nếu một người gửi thoát giữa chừng khi đang gửi, hệ thống phải xác định những nút nào đã nhận được nó; nếu một người nhận thoát vĩnh viễn, hệ thống phải quyết định công việc nào tiếp tục chạy. Những vấn đề này đòi hỏi tách đảm bảo thứ tự khỏi cơ chế phân phát và phục hồi, và thể hiện rõ ràng các phụ thuộc mà ứng dụng thực sự cần.
Ví dụ trên yêu cầu thông báo chỉ được phát sau khi write hoàn tất. Bên nhận cũng phải đọc dữ liệu đúng thời điểm, nếu không nó có thể dùng một giá trị cũ (stale) ngay cả khi thứ tự thông báo đúng. Giả sử giá trị ban đầu của D là 0, được cập nhật thành 1 ở 2 μs; cờ sẵn sàng trở nên thấy được ở 3 μs. Consumer đọc D sớm ở 1 μs và đọc cờ ở 4 μs. Lúc đó, nó giữ cờ mới nhưng dữ liệu cũ. Ngay cả nếu kết quả đọc được trả về ở 5 μs theo thứ tự “cờ, rồi dữ liệu”, D nó đã lưu vẫn là 0.

Trong Hình 7-37, di chuyển điểm rỗng đánh dấu thời điểm trả về kết quả ra sau không di chuyển điểm đặc đánh dấu thời điểm đọc thực tế. Phản ví dụ này cho thấy các yêu cầu thứ tự phải được áp đặt tại thời điểm dữ liệu thực sự được đọc. Consumer có thể hoặc chỉ đọc D sau khi quan sát cờ, hoặc đọc sớm, kiểm tra xung đột, và đọc lại. Nếu xung đột được phát hiện ở 4 μs và đọc lại mất 2 μs, dữ liệu đúng thu được ở 6 μs. Thứ tự phía bên nhận di chuyển việc chờ về đầu nhận, trong khi kiểm tra xung đột chịu trách nhiệm xác định những read sớm nào vẫn còn hiệu lực. Dựa vào các đảm bảo thứ tự để đơn giản hóa lập trình đòi hỏi lưu trạng thái này và thực hiện các kiểm tra tương ứng.
7.4.4 Giải phóng slot yêu cầu và điều áp ngược (backpressure)
Các slot yêu cầu thảo luận trong Mục 7.3.4 chỉ được giải phóng sau khi phần mềm xử lý xong thông báo hoàn tất, sau đó một yêu cầu mới mới có thể dùng chúng. Buffer dữ liệu thảo luận trong Mục 7.4.1 có một cửa sổ sử dụng riêng: trong khi bên nhận chưa dùng xong dữ liệu, buffer đó phải được giữ riêng. Nếu truyền nhanh lên nhưng các thông báo hoàn tất không được xử lý kịp thời, một số lượng lớn các yêu cầu “thao tác đã hoàn tất, slot chưa giải phóng” tích tụ lại.
Lấy 16 thao tác, mỗi cái truyền 8 KiB, được nộp tối đa mỗi 1 μs, hoàn tất 5 μs sau khi nộp. Với 16 slot, cái cuối được nộp ở 15 μs, và mọi truyền hoàn tất ở 20 μs. Nếu phần mềm đọc và xử lý bốn thông báo hoàn tất mỗi 20 μs, 16 thông báo cần bốn vòng, và các slot tương ứng không được giải phóng hết cho tới 80 μs.
Nếu chỉ có tám slot, tám lần nộp đầu nhanh chóng lấp đầy mọi slot. Lần nộp thứ chín phải chờ tới 20 μs, khi phần mềm đã xử lý các thông báo hoàn tất và giải phóng slot; các yêu cầu sau tiếp tục được nộp theo từng mẻ, với mọi truyền không hoàn tất cho tới 48 μs. Gấp đôi số slot di chuyển thời gian hoàn tất truyền từ 48 μs xuống 20 μs, nhưng việc giải phóng hết mọi slot vẫn không xong cho tới 80 μs.


So sánh các Hình 7-38 và 7-39, thêm slot di chuyển các thanh truyền màu xanh sang sớm hơn, nhưng khoảng chờ màu cam dài hơn ở bên phải vẫn còn. Điều quyết định thông lượng duy trì là các slot này cuối cùng được giải phóng nhanh bao nhiêu. Nhìn qua mô hình độ đồng thời và thông lượng, luồng xử lý các thông báo hoàn tất chỉ xử lý mục mỗi giây; ở 8 KiB mỗi mục, con số đó tương ứng với năng lực xử lý duy trì khoảng 1,64 GB/s. Với kích thước thao tác này, để đạt 50 GB/s của một NIC đơn cần xử lý khoảng 6,1 triệu mục mỗi giây, gần một mục mỗi 0,164 μs. Thêm slot chỉ có thể hấp thụ các đợt tăng vọt ngắn của khối lượng yêu cầu; tải duy trì đòi hỏi hoặc nâng tốc độ xử lý thông báo hoàn tất hoặc tăng tải trọng mỗi thao tác.
Khi các thông báo hoàn tất được xử lý quá chậm, việc nộp ở thượng nguồn cần bị siết lại — đây chính là backpressure (điều áp ngược) được giới thiệu trong Chương 5: một khi các slot yêu cầu cạn kiệt, endpoint tạm dừng hoặc giảm tốc độ nộp cho tới khi các slot được giải phóng; backpressure điều khiển phía thượng nguồn bằng cách giới hạn số yêu cầu đang treo, ngăn công việc đang treo tăng vô hạn. Nếu một buffer chỉ có thể được giải phóng sau khi chương trình từ xa dùng xong dữ liệu, backpressure lan truyền xuyên các thiết bị; khi nhiều mẩu công việc dùng chung trạng thái truyền tải, phạm vi lan truyền còn lớn hơn.
Sau khi một lỗi xảy ra, các yêu cầu cũ cũng phải được kết thúc trước khi không gian chúng chiếm có thể được giải phóng. Sau khi hủy một yêu cầu, hệ thống trước hết dừng các nộp mới, rồi chờ hoặc cô lập các truy cập in-flight cũ, và chỉ sau đó giải phóng không gian. Nếu không, một write cũ đến muộn sẽ ghi đè đối tượng mới. Gán một số phiên bản mới cho mỗi đối tượng được tái dùng, thu hồi quyền truy cập, và cô lập các endpoint đã ngắt kết nối đều phục vụ việc ngăn các yêu cầu cũ truy cập không gian đã được cấp lại. Sau khi timeout kích hoạt phục hồi, hệ thống trước hết phải xác nhận các yêu cầu cũ đã kết thúc, hoặc chặn chúng tiếp tục truy cập không gian, trước khi tái dùng nó. Khi nhiều endpoint dùng chung một mạng, cùng một khoảng chênh giữa tốc độ đến và tốc độ xử lý trở thành một hàng đợi bên trong switch.
Thí nghiệm 7-10 · Cốt lõi: nới lỏng thứ tự thao tác giảm chờ đợi trong khi vẫn giữ dữ liệu đúng như thế nào
Đổi thời lượng của thao tác độc lập C trong Ví dụ 7.4 thành 50 μs, và tìm thời gian hoàn tất của cả nhóm và của thao tác độc lập dưới cả hai cách sắp xếp. Rồi giả sử consumer cần 30 μs để xử lý dữ liệu sau khi nhận thông báo, và đánh dấu thời điểm sớm nhất mà buffer đích có thể được ghi dữ liệu mới. Với phản ví dụ giá trị cũ, vẽ hai đường thực thi: một đường đọc sau khi chờ, và một đường đọc sớm kèm đọc lại khi phát hiện xung đột.
7.5 Tắc nghẽn và độ tin cậy trong mạng dùng chung
7.5.1 Từ lưu lượng cố định đến nhu cầu biến thiên theo thời gian
Thêm vào cấu hình từ các mục trước một job huấn luyện nữa dùng hai máy chủ, và đặt cả hai job lên cấu trúc đa rail từ Mục 7.2.5: hai máy chủ của mỗi job thuộc các nhóm khác nhau (32 máy chủ mỗi nhóm), nên lưu lượng xuyên máy chủ trên cùng một rail không còn tới trong một hop mà phải đi qua uplink của switch lá lên tầng spine; các flow của cả hai job trên rail này bị băm lên cùng một uplink 400 Gbit/s, 50 GB/s mỗi chiều. Giai đoạn xuyên máy chủ của reduction phân cấp có mỗi NIC gửi ở 50 GB/s, và khi các đỉnh của hai job trùng nhau, nhu cầu vượt năng lực truyền của liên kết này.
Ví dụ 7.5: Trung bình chỉ dùng 40% băng thông liên kết — vì sao hàng đợi vẫn xảy ra? Mỗi trong hai job có một đỉnh truyền thông 20 ms trong mỗi 100 ms, cả hai đều đạt đỉnh ở tốc độ 50 GB/s, không gửi gì trong thời gian còn lại. Giả sử hàng đợi bắt đầu rỗng, cả hai job gửi theo lịch này, và buffer đủ lớn để giữ toàn bộ lượng đọng lại.
Lời giải: Tổng nhu cầu trung bình của hai job là
So với 50 GB/s, mức sử dụng trung bình chỉ là 40%. Nhưng khi cả hai đỉnh bắt đầu đồng thời, tốc độ đến vượt tốc độ đi 50 GB/s, và trong 20 ms lượng đọng lại tăng tới
Sau khi đỉnh kết thúc, vẫn mất ms để rút cạn. Cả hai job ngừng gửi ở 20 ms, nhưng liên kết đi cần thêm 20 ms truyền để gửi hết lượng đọng này. Nếu job thứ hai bị trễ 20 ms, các đỉnh hoàn toàn không chồng nhau, tối đa 50 GB/s đến ở mỗi thời điểm, và hàng đợi luôn rỗng. Cả hai cách sắp xếp gửi cùng một tổng lượng dữ liệu; sự khác biệt nằm ở thời điểm tương đối hai job bắt đầu gửi. Hình 7-40 vẽ tốc độ đến dưới các mức chồng đỉnh khác nhau, và Hình 7-41 vẽ lượng đọng lại tương ứng.


Thảo luận: cần lệch thời gian gửi bao nhiêu để tạo lượng đọng lại trên một liên kết đi dùng chung? Khi thời lượng chồng lấp là , lượng đọng lại thêm là . Chỉ 5 ms chồng lấp đã tạo 250 MB lượng đọng lại. Nếu chỉ 512 KiB buffer được giữ riêng cho burst này, bắt đầu từ hàng đợi rỗng, thời lượng chồng lấp chịu được khoảng μs. Ngay cả khi sai số trong thời gian gửi chỉ gây chồng lấp cỡ mili-giây, nó đã vượt xa điều buffer này chịu được.
Ý tưởng làm lệch các đỉnh đã được triển khai trong các hệ thống. CASSINI khai thác tính tuần hoàn của truyền thông huấn luyện để sắp xếp việc đặt job và thời điểm truyền thông nhằm làm lệch các đỉnh, đồng thời giám sát trôi pha và điều chỉnh lại. Các thí nghiệm kèm cuốn sách này chạy một so sánh có kiểm soát dùng hai job huấn luyện song song dữ liệu phân tán (DDP) trên CPU với một lần lệch đỉnh: sau khi trễ một job 50 ms, pha của hai job tiếp tục trôi trong lúc chạy, và qua ba vòng đo, tổng thời gian hoàn thành job thực tế tăng khoảng 2% đến 3%. Lập lịch tuần hoàn đòi hỏi duy trì pha liên tục; điều khiển tắc nghẽn, ngược lại, điều chỉnh tốc độ gửi theo thời gian thực dựa trên phản hồi về độ lệch so với kỳ vọng.
7.5.2 Độ trễ phản hồi và dung lượng bộ đệm
Làm lệch các đỉnh giảm chồng đỉnh, nhưng truyền thực tế vẫn lệch so với kế hoạch. Vậy ta cũng cần làm chậm người gửi kịp thời một khi hàng đợi bắt đầu tăng. Khi dữ liệu đến nhanh hơn liên kết đi có thể gửi, lượng dư tích tụ trong một hàng đợi. Gọi độ dài hàng đợi là , tốc độ đến là , và tốc độ đi là . Khi hàng đợi không rỗng và chưa đầy,
Khi tốc độ đến vượt tốc độ gửi, hàng đợi tăng; khi tốc độ đến thấp hơn tốc độ gửi, lượng đọng lại co lại.
Có hai cơ chế để hạ tốc độ đến kịp thời. Điều khiển lưu lượng cấp liên kết (link-level flow control) cho phép một bên nhận lân cận tạm dừng người gửi ở thượng nguồn khi buffer của nó sắp cạn, ngăn tràn buffer nhận. Điều khiển tắc nghẽn đầu cuối (end-to-end congestion control) mang thông tin nút thắt về người gửi, hạ tốc độ gửi. Cái trước nhanh chóng chặn tràn cục bộ; cái sau để tốc độ gửi của nguồn thích ứng với năng lực của toàn bộ đường đi.
Tiếp tục với tốc độ đến 100 GB/s chống lại tốc độ đi 50 GB/s, giả sử tổng buffer là 512 KiB và 256 KiB đã bị chiếm. Mỗi micro-giây thêm vào mang 50 KB dữ liệu nhiều hơn lượng đi, tiêu thụ không gian còn lại, vốn chỉ duy trì được khoảng 5,2 μs. Nếu phản hồi không làm chậm người gửi cho tới 20 μs, nó sẽ sinh ra 1 MB dữ liệu thừa; sau khi trừ không gian còn lại, khoảng 738 KB bị loại bỏ.
Ký hiệu buffer còn lại là và độ trễ từ phát hiện tắc nghẽn đến giảm tốc là . Tránh tràn này đòi hỏi
Vậy, với các tốc độ đến và gửi cho trước, ta có thể suy ngược từ kích thước buffer ra độ trễ phản hồi cho phép. Gấp đôi không gian còn lại gấp đôi độ trễ phản hồi chịu được; gấp đôi khoảng chênh giữa tốc độ đến và đi làm giảm một nửa độ trễ phản hồi chịu được. Với các tốc độ trên, nếu giảm tốc mất 50 μs, thêm 2,5 MB tích tụ.
Sau khi phản hồi tới, lượng đọng lại vẫn phải được rút cạn. Làm chậm người gửi xuống đúng 50 GB/s khiến tốc độ đến bằng tốc độ gửi đi, nên hàng đợi hiện có đứng yên; làm chậm xuống 40 GB/s để lại biên 10 GB/s mỗi giây cho việc rút cạn, nên 512 KiB mất khoảng 52 μs để dọn sạch. Tính từ lúc bắt đầu, hàng đợi trở về không ở khoảng 72 μs. Điều khiển tắc nghẽn vừa phải ngăn hàng đợi tiếp tục tăng vừa để lại biên cho việc rút cạn lượng đọng lại. Hình 7-42 vẽ vòng phản hồi này, và Hình 7-43 vẽ việc buffer đầy lên và rút xuống.


Trong Hình 7-43, thời điểm phản hồi có hiệu lực quyết định hàng đợi nằm đầy bao lâu, và độ lớn của việc giảm tốc quyết định độ dốc suy giảm. Các cơ chế điều khiển tắc nghẽn khác nhau đều hoạt động bằng cách thay đổi hai đại lượng này. Thông báo tắc nghẽn tường minh (ECN) cho các switch đánh dấu gói tin để mang thông tin hàng đợi về người gửi; DCQCN là một thuật toán dùng thông báo này để điều chỉnh tốc độ gửi RDMA; các phương pháp dựa trên độ trễ quan sát việc xếp hàng từ các thay đổi trong thời gian khứ hồi; C-AQM của UB để các endpoint và mạng chuyển mạch hợp tác trong việc quản lý hàng đợi chủ động (làm chậm người gửi dựa trên trạng thái hàng đợi trước khi hàng đợi thực sự tràn). Để hiểu các cơ chế này, trước hết xác định mỗi cơ chế rút ngắn đoạn nào của đường phản hồi, và người gửi thay đổi gì khi nhận thông tin. Ngưỡng, bước cập nhật và tần suất phản hồi cùng nhau quyết định tốc độ và độ lớn của phản ứng hàng đợi.
Hội tụ nhiều-một và điều khiển lưu lượng cấp liên kết. Tốc độ đến 100 GB/s trên đây đến từ hai job. Bản thân truyền thông tập thể cũng có thể tạo ra các tốc độ đến dốc hơn. Nếu ReduceScatter được triển khai trực tiếp, mỗi participant gửi shard thẳng tới người giữ shard , hoàn tất trong một vòng. Nếu participant gửi tới các đích theo từng cái một theo cùng một thứ tự, và mỗi cái gửi ở toàn bộ tốc độ của NIC, thì trong khoảng khi tới lượt người giữ , người gửi còn lại đồng thời truyền tới nó, và cổng switch dẫn tới nó nhận dữ liệu ở tốc độ ; nếu thứ tự gửi được làm lệch theo rank, mỗi đích chỉ nhận một flow tại bất kỳ thời điểm nào. Tình huống nhiều người gửi đồng thời truyền tới cùng một cổng đi được gọi là incast. Thay vào phương trình trên, với mỗi người gửi ở GB/s, tốc độ đi cũng 50 GB/s, và buffer còn lại 1 MiB: ở tốc độ đến không phải 50 GB/s của một flow mà là bảy flow gộp lại, 350 GB/s:
| Người gửi | Tốc độ đến | Tốc độ dư | Độ trễ phản hồi cho phép | |
|---|---|---|---|---|
| 8 | 7 | 350 GB/s | 300 GB/s | 3,50 μs |
| 16 | 15 | 750 GB/s | 700 GB/s | 1,50 μs |
| 64 | 63 | 3150 GB/s | 3100 GB/s | 0,34 μs |
Điều khiển lưu lượng cấp liên kết và điều khiển tắc nghẽn đầu cuối tương ứng với hai khoảng cách phản hồi khác nhau ở đây. Một triển khai của điều khiển lưu lượng cấp liên kết là Điều khiển lưu lượng ưu tiên (PFC) của IEEE 802.1Qbb: khi hàng đợi của một cổng nhận vượt một ngưỡng, nó gửi một khung pause tới cổng lân cận ở thượng nguồn, tạm dừng một liên kết đơn theo mức ưu tiên. Khoảng cách phản hồi của nó chỉ một hop: với cáp 30 m ở 5 ns/m, khung pause đi lên thượng nguồn trong 150 ns, dữ liệu đã trên dây đi xuống hạ lưu trong 150 ns, cộng 30 ns để tuần tự hóa một gói tin 1500 B ở 50 GB/s, tổng cộng 0,33 μs. Dữ liệu dư tiếp tục tới trong 0,33 μs này phải có không gian buffer để giữ; không gian dành riêng này được gọi là headroom: ở nó là KB, ở là 231 KB, và ở là 1,02 MB — không cái nào vượt 1 MiB. Bài báo DCQCN đưa một ví dụ 22,4 KB mỗi cổng mỗi mức ưu tiên, dựa trên đơn vị truyền cực đại (MTU) 1500 B. Khoảng cách phản hồi cho điều khiển tắc nghẽn đầu cuối (đánh dấu ECN và giảm tốc DCQCN) là một vòng khứ hồi 20 μs; dữ liệu dư tràn vào trong 20 μs này là 6,0, 14 và 62 MB — tức 5,7, 13,4 và 59,1 MiB — không cái nào vừa một buffer 1 MiB. Hình 7-44 vẽ sự tăng trưởng hàng đợi dưới ba giá trị này bên cạnh hai khoảng cách phản hồi.

Hai khoảng cách quyết định sự phân công lao động: PFC chặn hop lân cận trong 0,33 μs, giữ buffer không tràn trong 20 μs mà DCQCN cần; DCQCN rồi hạ tốc độ gửi của nguồn xuống một mức cổng đi duy trì được, lúc đó pause có thể được gỡ. Riêng dựa vào phản hồi đầu cuối để tránh mất gói đòi hỏi : một buffer 1 MiB chỉ cho phép , và ngay cả 4 MiB cũng chỉ đạt . Nới buffer lên 4 MiB thay đổi độ trễ phản hồi cho phép thành 13,98, 5,99, 1,35 μs — vẫn thấp hơn nhiều so với 20 μs. Chi phí của PFC được để lại cho Mục 7.5.4: các pause lan truyền từng hop lên thượng nguồn, và khi chúng tạo thành một vòng phụ thuộc tròn, kết quả là bế tắc.
Thí nghiệm 7-11 · Mở rộng: kích thước buffer và độ lớn giảm tốc ảnh hưởng sự phân rã lượng đọng lại như thế nào
Cho tốc độ đến 100 GB/s, tốc độ đi 50 GB/s, và lượng đọng lại ban đầu 256 KiB, tìm độ trễ phản hồi chịu được cho tổng buffer 512 KiB và 1 MiB. Giả sử phản hồi có hiệu lực đúng khi buffer đầy lên, và đặt tốc độ đến sau giảm tốc lần lượt là 50, 45 và 40 GB/s; tìm thời gian từ khi phản hồi có hiệu lực đến khi dọn sạch lượng đọng lại, và giải thích vì sao một trong các điều kiện này không thể rút cạn lượng đọng lại.
Thí nghiệm 7-12 · Mở rộng: buffer incast và khoảng cách phản hồi
Đổi tốc độ đi thành 100 GB/s (hai NIC) trong khi mỗi người gửi vẫn ở 50 GB/s, và tính lại độ trễ phản hồi cho phép và headroom PFC cho , 16, 64. Rồi đổi cáp thành 100 m, tìm khoảng cách phản hồi một hop, và xác định headroom ở có còn vừa trong 1 MiB hay không. Cuối cùng, tìm tối đa để chỉ phản hồi đầu cuối đã tránh được mất gói khi thời gian khứ hồi là 5 μs.
7.5.3 Đa đường và truyền lại
Điều khiển phản hồi giảm nhẹ tắc nghẽn bằng cách hạ tốc độ gửi; nếu các đường khác vẫn còn băng thông dư, lưu lượng cũng có thể được chuyển hướng tới chúng. Mạng Clos cung cấp nhiều đường ứng viên. Gán các kết nối khác nhau cho các đường khác nhau trải lưu lượng ra khỏi các liên kết điểm nóng; chia các gói tin của một truyền đơn lên nhiều đường cho phép nó dùng băng thông của vài liên kết cùng lúc. Cách sau cũng mang sự khác biệt độ trễ giữa các đường về phía bên nhận.
Lấy một vector trạng thái ẩn BF16 cho bốn token, tổng cộng 32 KiB, chia thành tám gói tin 4 KiB, luân phiên lên hai đường 50 GB/s độc lập. Tuần tự hóa mỗi gói tin mất khoảng 82 ns, nên mỗi đường mất khoảng 0,33 μs để gửi bốn gói tin của nó. Với cả hai đường có độ trễ lan truyền 1 μs, toàn bộ truyền được giao ở khoảng 1,33 μs; cùng tám gói tin trên một đường đơn sẽ mất khoảng 1,66 μs. Hai đường mỗi cái đảm nhận một nửa việc gửi, hoàn thành truyền song song.
Đổi độ trễ lan truyền của đường thứ hai thành 9 μs, và gói tin cuối trên đường đó không tới cho tới khoảng 9,33 μs. Các gói tin đến sớm trên đường nhanh phải chờ gói tin thiếu phía trước chúng được lấp; bên nhận có thể cần đệm tới 12 KiB dữ liệu lệch thứ tự. Với cùng tổng số byte, dùng thêm một đường thực tế chậm hơn nhiều so với một đường đơn, vì thời gian tuần tự hóa tiết kiệm được chỉ khoảng 0,33 μs, nhỏ hơn nhiều so với 8 μs độ trễ đường thêm vào.


Các đường ngang trong Hình 7-45 và 7-46 cho thấy gửi xong trên đường nhanh không có nghĩa toàn bộ truyền có thể được trao cho ứng dụng. Hai đường tiết kiệm thời gian gửi nhưng có thể tăng thời gian chờ các gói tin thiếu. Ta có thể suy trực tiếp điều kiện truyền hai đường nhanh hơn. Một đường đơn cần gửi tám gói tin; hai đường gửi bốn trên mỗi đường. Tuần tự hóa mỗi gói tin mất khoảng 82 ns, nên hai đường tiết kiệm khoảng 0,33 μs. Nếu độ trễ lan truyền của đường thứ hai vượt đường thứ nhất hơn 0,33 μs này, ngay cả việc chia đều cũng mất lợi thế thời gian. Trên một liên kết 50 GB/s, biên này chỉ hơn hai lần độ trễ lan truyền của một cáp 30 m (khoảng 150 ns) một chút, nên ngay cả một khác biệt nhỏ giữa các đường cũng triệt tiêu nó; chia đều một truyền vài chục KiB lên các đường có độ trễ khác nhau hiếm khi đáng giá. Lựa chọn đường hoặc phân bổ không đều nên giảm số gói tin gán cho đường chậm, để gói tin cuối trên mỗi đường tới trong khoảng cùng thời điểm. Đa đường chỉ có lợi khi thời gian tuần tự hóa cấp cho mỗi đường lớn hơn nhiều so với chênh lệch độ trễ đường — việc phun gói tin (packet spraying) 8 MiB thảo luận bên dưới chính là một trường hợp như vậy.
Ngoài lan truyền chậm, mất gói tin là một kịch bản khác, và nó gây một loại chờ khác. Giả sử gói tin 0 bị mất và được truyền lại 20 μs sau khi lần gửi ban đầu hoàn tất; toàn bộ truyền không thể giao cho tới khoảng 21,2 μs — việc giao phải chờ khoảng trống khép lại, dù phần còn lại đến sớm thế nào. Lúc này bảy gói tin kia đều đã đến, và bên nhận đã đệm 28 KiB tải trọng, chỉ cần truyền lại 4 KiB thiếu; nếu thay vào đó mọi thứ kể từ gói tin thiếu được gửi lại, phải truyền thêm 32 KiB. Truyền lại chọn lọc dùng trạng thái theo dõi tiến trình nhận để đánh đổi lấy ít truyền trùng hơn; Hình 7-47 vẽ kịch bản này khi chỉ gửi lại gói tin 0. Mô phỏng hai nút của OpenURMA đưa so sánh tương tự: lớp truyền tải của UB dùng xác nhận chọn lọc, chỉ gửi lại các gói tin thiếu, nên thông lượng suy giảm nhẹ khi mất gói tăng; truyền lại go-back-N, ở cùng tỉ lệ mất, phải gửi lại toàn bộ cửa sổ.

Truyền lại đặt ra một câu hỏi riêng: khi nào quyết định một khoảng trống cần được phục hồi. Chờ quá lâu làm tăng sự trì trệ sau một mất gói thực sự; gửi lại một gói tin trên một đường chậm chỉ đơn giản là chưa tới thêm lưu lượng trùng. Sự phân bố độ trễ đường quyết định việc phát hiện lệch thứ tự phải dung thứ bao nhiêu, và trạng thái bên nhận theo dõi quyết định nó có thể đệm bao nhiêu dữ liệu đến sau gói tin thiếu. Việc giao tin cậy, cùng với các phụ thuộc ứng dụng từ Mục 7.4, cùng nhau quyết định thao tác nào đã đến có thể tiến hành.
Xung đột băm trên nhiều đường. Trước đó ta chia các gói tin của một truyền đơn lên nhiều đường; cách tiếp cận khác được nhắc ở đầu mục này gán đường theo kết nối (flow), tránh lệch thứ tự nhưng có thể dồn vài flow lên cùng một liên kết. Khi một flow xuyên nhóm rời một switch lá, nó phải chọn một trong các uplink của leaf đó. Các switch thường băm trên các trường địa chỉ và cổng của tiêu đề gói tin để chọn uplink, gọi là ECMP (equal-cost multipath — đa đường chi phí bằng nhau): toàn bộ gói tin của cùng một flow đi cùng một đường, và các flow khác nhau được phân phối lên các uplink khác nhau theo giá trị băm. Vì băm hiệu quả là ngẫu nhiên, xác suất hai flow rơi lên cùng một uplink là khác không. Các flow có thể xung đột là các flow xuyên nhóm trên cùng một switch lá: trong Mục 7.2.5, dù việc ghép cặp lệch đã gửi tám flow vào tầng spine, chúng xuất phát từ tám switch lá khác nhau, mỗi leaf chỉ mang một flow xuyên nhóm, nên chúng không bao giờ gặp nhau trên uplink của cùng một leaf. Sự thẳng hàng rail giảm thiểu các flow xuyên nhóm trên mỗi leaf chính xác để tránh xung đột này. Nếu flow cùng tốc độ trên cùng một leaf được băm độc lập và đều lên uplink của leaf đó — một leaf không chặn với có 32 uplink, một leaf over-subscription 3:1 có 16 — gọi là số flow trên uplink bận nhất. Không xung đột, uplink bận nhất mang flow; khi mỗi flow chia sẻ công bằng băng thông liên kết của nó và cả nhóm chờ flow chậm nhất xong, tốc độ của nhóm chỉ bằng tốc độ không xung đột. Tính chính xác phân bố của tải cực đại, cột p99 trong bảng dưới là phân vị thứ 99 của — tức là, trong 99% kết quả băm, uplink bận nhất mang không quá số flow bằng giá trị này:
| Flow | Uplink | Flow trên uplink bận nhất khi không xung đột | p99 | Xác suất không xung đột | Tốc độ so với không xung đột | |
|---|---|---|---|---|---|---|
| 8 | 32 | 1 | 1,66 | 3 | 38,6% | 60,1% |
| 8 | 16 | 1 | 2,06 | 4 | 12,1% | 48,5% |
| 32 | 32 | 1 | 3,53 | 6 | 28,3% | |
| 32 | 16 | 2 | 4,83 | 8 | 0 | 41,4% |
| 128 | 16 | 8 | 13,36 | 18 | 0 | 59,9% |
Chỉ với tám flow xuyên nhóm trên một leaf, một leaf không chặn có 38,6% khả năng hoàn toàn không xung đột; một khi xung đột xảy ra, hai flow dồn lên một uplink, mỗi cái nhận nửa băng thông, và uplink bận nhất trung bình 1,66 flow, để nhóm chỉ còn 60,1% tốc độ không xung đột trung bình. Chia nửa số uplink trên một leaf over-subscription hạ xác suất không xung đột xuống 12,1% và tốc độ xuống 48,5%. Trường hợp xấu nhất là khi cả một nhóm 32 máy chủ mỗi máy gửi một flow xuyên nhóm và leaf không chặn có đúng 32 uplink: với flow bằng uplink, gần như chắc chắn một số uplink nằm nhàn rỗi trong khi các uplink khác mang ba hoặc bốn, để nhóm chỉ còn 28,3%. Khi flow đông hơn uplink rất nhiều, sự dao động tương đối của phép gán ngẫu nhiên co lại: 32 flow lên 16 uplink cho 41,4%, và 128 flow lên 16 uplink cho 59,9%. Hình 7-48 vẽ tải của liên kết bận nhất cho các cấu hình này. Điều kiện lật cửa: xung đột tốn kém nhất khi số flow gần số uplink, và ít tốn kém hơn khi flow đông hơn hẳn hoặc thưa hơn hẳn so với uplink; tránh chi phí này hoặc có nghĩa dùng thẳng hàng rail để giảm các flow xuyên nhóm trên cùng một leaf, hoặc bỏ phép gán theo flow để chuyển sang phun gói tin thảo luận bên dưới.

Phun gói tin (packet spraying). Chia các gói tin của cùng một flow lên nhiều đường loại bỏ xung đột băm cấp flow, với cái giá là việc lệch thứ tự được tính trước đó trong mục này. Lấy một activation prefill 8 MiB (vector trạng thái ẩn BF16 cho 1024 token), chia thành 2048 gói tin 4 KiB, luân phiên lên tám đường 50 GB/s với độ trễ lan truyền từ 1 đến 8 μs. Mỗi đường xử lý 1 MiB, mất 20,97 μs để tuần tự hóa; đường chậm nhất thêm 8 μs, nên mọi thứ đến bằng 28,97 μs, khoảng 29,0 μs; cùng 8 MiB trên một đường đơn mất 167,8 μs cộng 1 μs lan truyền, tổng cộng 168,8 μs. Phun tiết kiệm thời gian tuần tự hóa và thêm các chênh lệch độ trễ đường; theo điều kiện suy ra trước đó trong mục này, chỉ cần độ trễ của đường chậm nhất nhỏ hơn μs, phun nhanh hơn — ở đây đường chậm nhất chỉ 8 μs. Cái giá của lệch thứ tự là bên nhận phải đệm các gói tin đến sớm: các gói tin trên đường nhanh phải chờ các gói tin có số thấp hơn trên các đường chậm, và bên nhận giữ tối đa 339 gói tin, 1,39 MB, một lúc.
Ultra Ethernet (một đặc tả nhắm tới AI và điện toán hiệu năng cao) xây cả hai ý tưởng này vào lớp truyền tải của mình: các gói tin được phun lên nhiều đường theo giá trị entropy (một trường trong tiêu đề gói tin mà switch băm để chọn đường), thường với 64 đến 256 giá trị entropy, và khi phản hồi cho thấy một đường bị tắc nghẽn, ít gói tin được định tuyến lên nó hơn; các gói tin mất được truyền lại chọn lọc — chỉ những gói thiếu — thay vì gửi lại toàn bộ cửa sổ theo go-back-N. Đây chính xác là mô hình trong Hình 7-47: phun thu được băng thông của mọi liên kết, và truyền lại chọn lọc giam chi phí của mất gói vào các gói tin thiếu, với cái giá là bên nhận duy trì trạng thái lệch thứ tự.
Thí nghiệm 7-13 · Mở rộng: chênh lệch độ trễ đường và độ trễ truyền lại tác động việc giao theo thứ tự như thế nào
Cho độ trễ lan truyền của đường thứ hai biến thiên giữa 1 μs và 9 μs, và tìm độ trễ lan truyền của đường thứ hai tại đó việc chia đều lên hai đường tốn cùng thời gian như chỉ dùng đường thứ nhất. Rồi cho đường thứ nhất và thứ hai lần lượt mang năm và ba gói tin, và tìm thời gian hoàn thành khi độ trễ lan truyền của đường thứ nhất là 1 μs và của đường thứ hai là 9 μs. Giữ kịch bản mất gói tin đầu, tăng khoảng chờ phục hồi từ 20 μs lên 40 μs, và tính thời điểm dữ liệu lần đầu có thể giao theo thứ tự, cùng với lượng dữ liệu phải được đệm trước đó.
Thí nghiệm 7-14 · Mở rộng: ranh giới xung đột băm và phun
Tìm tải kỳ vọng của liên kết bận nhất và tốc độ so với không xung đột khi 16 flow trải lên 32 uplink, và so sánh với trường hợp trong bảng là 8 flow lên 16 uplink, vốn có cùng . Đổi các độ trễ đường phun thành các khoảng đều từ 1 đến 30 μs, và tìm thời gian hoàn thành và đỉnh buffer lệch thứ tự; rồi tìm độ trễ đường chậm nhất tại đó phun không còn nhanh hơn một đường đơn. Cuối cùng, đổi kích thước gói tin thành 1 KiB, và giải thích số gói tin và số byte của đỉnh buffer lệch thứ tự thay đổi như thế nào.
7.5.4 Bế tắc
Trong Mục 7.5.3, các gói tin đã đến phải được giữ cho tới khi khoảng trống được lấp trước khi không gian của chúng có thể được giải phóng. Backpressure endpoint và điều khiển lưu lượng cấp liên kết cũng lan truyền loại chờ này lên thượng nguồn: khi bên nhận không còn slot trống, người gửi ở thượng nguồn không thể tiếp tục truyền. Nếu bản thân hành động giải phóng một tài nguyên lại cần chính tài nguyên đó, một vòng tròn hình thành. Xét hai yêu cầu lần lượt giữ tài nguyên A và B; yêu cầu thứ nhất vẫn cần chiếm B để hoàn tất, và yêu cầu thứ hai vẫn cần chiếm A để hoàn tất. Cả hai đều chờ bên kia giải phóng trước.
Trong một hệ reduction, loại vòng này có thể trải nhiều mức: một yêu cầu làm đầy buffer nhận, phản hồi hoàn tất chờ trên hàng đợi gửi, và hàng đợi gửi lại chờ phía xa giải phóng không gian mà yêu cầu chiếm. Vẽ một cạnh cho “đang giữ một tài nguyên, đang yêu cầu tài nguyên tiếp theo” tạo ra một đồ thị phụ thuộc tài nguyên. Khi mọi tài nguyên trên một vòng đều bị giữ, mọi điều kiện giải phóng trì trệ đồng thời. Hình 7-49 vẽ một vòng như vậy, và Hình 7-50 vẽ giải pháp được mô tả bên dưới là giữ trước một đường cho các phản hồi.


Một giải pháp là áp đặt một thứ tự nghiêm ngặt cho các yêu cầu tài nguyên — ví dụ, yêu cầu mọi công việc yêu cầu A trước B. Theo cách này, công việc giữ B không bao giờ phải chờ A nữa, bẻ gãy vòng. Một giải pháp khác là giữ trước một buffer độc lập và một cơ hội gửi cho các phản hồi hoàn tất. Giả sử tám slot dữ liệu của bên nhận đầy và người gửi đang chờ giải phóng; nếu phản hồi cũng phải chiếm chính các slot dữ liệu này, mọi thứ sẽ trì trệ cùng nhau. Thêm các slot phản hồi độc lập cho phép thông điệp giải phóng sau khi xử lý dữ liệu trở về, giải phóng không gian bị ít nhất một yêu cầu chiếm để hàng đợi dữ liệu có thể tiếp tục quay vòng.
Các kênh ảo dùng các hàng đợi tách biệt về mặt logic để phân vùng tài nguyên. Đặt các yêu cầu và phản hồi vào các kênh khác nhau, và áp đặt một hướng cho các yêu cầu tài nguyên, có thể dựng được một cấu trúc phụ thuộc không có vòng. Điều thực sự quan trọng ở đây là năng lực độc lập và thứ tự sử dụng.
Truy cập bộ nhớ cũng có thể cần dịch địa chỉ và đọc bảng trang. Nếu yêu cầu ban đầu chờ dịch địa chỉ, và bản thân việc dịch địa chỉ kích hoạt một truy cập từ xa, và cả hai tranh giành cùng một nhóm slot đã cạn, cùng một vòng tròn hình thành. Khi tác giả tham gia thiết kế UB, chúng tôi đã phải phân tích cùng nhau các phụ thuộc giữa xử lý giao dịch, truy cập bộ nhớ và truyền liên kết. Chỉ bằng cách giữ trước tài nguyên cho các thông báo hoàn tất, dịch địa chỉ và phục hồi lỗi, hệ thống mới có thể tránh bị trì trệ dưới tắc nghẽn hoặc lỗi.
7.6 Từ cải thiện truyền thông đến hoàn thành tác vụ
7.6.1 Đường găng bắt đầu từ độ sẵn sàng của dữ liệu
Các Mục 7.2 đến 7.5 đã theo dấu một mẩu dữ liệu qua truyền, chờ, thông báo hoàn tất và giải phóng không gian. Để xét những cải thiện này tiết kiệm được bao nhiêu thời gian huấn luyện, ta cũng phải tính quá trình tính toán sinh ra và tiêu thụ dữ liệu này, và xác định khi nào truyền thông thực sự bắt đầu. Một card vào một lời gọi truyền thông tập thể rất sớm, trong khi gradient của một card khác chưa được tính xong; card trước chờ card sau bên trong lời gọi. Việc chờ này được ghi là một phần thời lượng của lời gọi truyền thông, nhưng nguyên nhân gốc nằm ở tính toán hoặc chuẩn bị dữ liệu phía trước.
Xét bốn participant phải thực hiện một reduction cục bộ, trở nên sẵn sàng lần lượt ở 0, 0, 0 và 2 ms, và thực thi một trao đổi 0,4 ms khi mọi bên sẵn sàng. Theo đồ thị phụ thuộc từ Mục 7.4, thời điểm bắt đầu của trao đổi bằng giá trị lớn nhất trong bốn thời điểm sẵn sàng, và cả nhóm kết thúc ở 2,4 ms. Chia đôi thời lượng trao đổi đổi thời gian hoàn thành thành 2,2 ms; nếu cả bốn participant sẵn sàng từ đầu, thời gian hoàn thành trở thành 0,4 ms. Hai sự tối ưu hóa tác động lên các nút khác nhau của đồ thị phụ thuộc, và các Hình 7-51 đến 7-53 minh họa lần lượt ba kịch bản này.



Sự lệch sẵn sàng này cũng tồn tại trong các hệ huấn luyện quy mô lớn. MegaScale, một hệ huấn luyện phân tán quy mô lớn, đã phát hiện trong quá trình chẩn đoán hiệu năng rằng băng thông mạng vẫn ổn định, nhưng khoảng chênh về thời điểm các participant bắt đầu truyền thông ngày càng lớn, và thời gian chờ bên trong ReduceScatter tăng theo. Phân tích thêm cho thấy sự sai lệch này liên quan các thao tác phía host trong quá trình tính toán forward. Các phép đo trong thí nghiệm kèm cuốn sách này, dùng thư viện truyền thông tập thể Gloo với bốn tiến trình trên CPU, cho cùng quan hệ: với đầu vào 4 KiB, khi một participant đến muộn khoảng 25,1 ms, thời gian hoàn thành trung vị của cả nhóm tăng từ khoảng 1,6 ms lên 26,6 ms; đoạn đuôi sau khi participant cuối đến vẫn khoảng 1,6 ms.
Vậy, dòng thời gian tác vụ nên được vẽ từ thời điểm dữ liệu được sinh ra. Chia gradient thành nhiều bucket để reduction có thể bắt đầu ngay khi gradient của mỗi bucket được sinh ra; trong khi bucket kế tiếp vẫn đang được tính, bucket trước đã có thể được truyền. Truyền thông cho các bucket khác nhau cạnh tranh NIC và các liên kết, và cập nhật tham số phải chờ reduction của bucket cuối hoàn tất. Việc chia bucket cho phép truyền thông bắt đầu sớm hơn, chồng lấp với việc tính gradient tiếp theo.
7.6.2 Tính thời gian truyền thông trong một mạng phân cấp
Ví dụ 7.6: Cái nào nên được tối ưu hóa trước — thuật toán reduction, thứ tự thực thi, hay băng thông liên kết? Tiếp tục với gradient 192 MiB trong ví dụ trước. Gradient trở nên sẵn sàng 20 ms sau khi tính toán bắt đầu, và cập nhật sau reduction mất 2 ms. So sánh một ring liền nhau với reduction phân cấp, rồi xét độ đồng thời không đủ, truyền thông sớm, và suy giảm liên kết.
Lời giải: trước tiên tính thời gian bước huấn luyện khi reduction và tính toán chạy tuần tự. Tính toán → reduction → cập nhật tạo thành một chuỗi tuần tự. Dùng mô hình truyền từ Mục 7.2, tổng thời gian của ring liền nhau khoảng ms, và của reduction phân cấp khoảng ms. Thời gian truyền thông giảm khoảng 83%, nhưng cả bước chỉ rút ngắn khoảng 21%. 20 ms tính toán và 2 ms cập nhật chiếm phần thời gian còn lại.
Tổng quát, gọi là thời gian không bị tối ưu hóa ảnh hưởng, là thời gian truyền thông, và là hệ số tăng tốc truyền thông; khi đó tốc độ tăng tổng thể là
Tiếp theo xét giới hạn yêu cầu đồng thời từ Mục 7.3. Nếu mỗi NIC chỉ có 128 giao dịch 256 B in-flight và thời gian quay vòng slot là 2 μs, thì — bỏ qua tốc độ phát ở đây — thông lượng từ xa của mỗi NIC bị chặn ở 16,4 GB/s. Trong reduction phân cấp, mỗi NIC gửi 24 MiB xuyên máy chủ, nên riêng truyền từ xa cần khoảng 1,5 ms; cộng truyền thông cục bộ và khởi động, tổng truyền thông khoảng 2,3 ms, và cả bước khoảng 24,3 ms. Chỉ sau khi tăng lên 391 giao dịch hoạt động với tốc độ phát đủ, nó mới quay về khoảng 23,3 ms. Sau khi đổi thuật toán reduction, tốc độ nộp và xử lý yêu cầu cũng phải đủ nhanh để hiện thực hóa lợi thế của thuật toán.
Giờ xét chồng lấp. Giả sử dữ liệu cần truyền thông sẵn sàng 17 ms sau khi tính toán bắt đầu, trong khi phần tính toán còn lại vẫn cần 3 ms. 3 ms tính toán này có thể thực thi đồng thời với truyền thông. Hai cái dùng các tài nguyên phần cứng không tranh chấp lẫn nhau, và cập nhật phải chờ cả hai xong. Trong trường hợp này,
Các Hình 7-54 đến 7-59 lần lượt vẽ sáu cách sắp xếp, mỗi hình dùng cùng một thang thời gian. Khoảng tính toán màu xám không đổi; độ dài khoảng truyền thông màu xanh được quyết định bởi khối lượng truyền và thông lượng, còn điểm bắt đầu của nó được quyết định bởi khi nào dữ liệu trở nên sẵn sàng.






Khi dữ liệu sẵn sàng ở 17 ms và chồng lấp với tính toán, cả bước của ring liền nhau khoảng 26,6 ms, và của reduction phân cấp khoảng 22,0 ms: truyền thông phân cấp kết thúc khoảng 18,3 ms, sớm hơn thời điểm kết thúc tính toán 20 ms, và cập nhật bắt đầu ngay sau khi tính toán xong. Ngay cả khi dữ liệu sẵn sàng muộn tới 18,7 ms, truyền thông phân cấp vẫn có thể ẩn sau tính toán. Rút ngắn truyền thông thêm nữa không còn thay đổi đường găng này; lúc đó, phải rút ngắn tính toán hoặc cập nhật để giảm tổng thời gian hơn nữa.
Thảo luận: sau khi giảm NIC, reduction có trở thành nút thắt của bước huấn luyện nữa không? Nếu chỉ một trong tám rail còn khả dụng, cả tám shard mỗi máy chủ phải đi qua NIC duy nhất còn lại, cho 96 MiB mỗi chiều mỗi vòng, 192 MiB qua cả hai vòng; truyền từ xa tăng từ khoảng 0,5 ms lên khoảng 4,0 ms, và truyền thông trở thành khoảng 4,8 ms. Với dữ liệu sẵn sàng ở 17 ms, truyền thông không hoàn tất cho tới 21,8 ms, và cả bước khoảng 23,8 ms. Khi thời gian truyền thông tăng, một phần lớn hơn của nó chỉ có thể hoàn tất sau khi tính toán kết thúc.
So sánh các dòng thời gian này theo thứ tự: giảm khối lượng truyền thông rút ngắn dải màu xanh, độ đồng thời không đủ kéo dài nó, và dữ liệu sẵn sàng sớm hơn dời nó sang trái. Cập nhật màu xanh lá phải chờ cả tính toán lẫn truyền thông xong mới bắt đầu được. Ba mô hình lưu lượng, độ đồng thời và phụ thuộc cùng nhau cho một thứ tự tối ưu hóa rõ ràng. Trước tiên dùng reduction phân cấp để cắt truyền xuyên máy chủ và đảm bảo mỗi NIC có một shard để truyền; rồi dùng nộp và xử lý yêu cầu đồng thời để bão hòa băng thông liên kết; một khi băng thông chạm giới hạn, tìm truyền thông có thể bắt đầu sớm hơn; và một khi thời gian truyền thông được che hoàn toàn sau tính toán, tối ưu cái nào trong tính toán hoặc cập nhật giờ quyết định thời gian hoàn thành.
7.6.3 Nút thắt truyền thông trong huấn luyện và suy luận
Dải màu xanh trong Hình 7-54 có thể được rút ngắn đáng kể vì, với gradient lớn, truyền dữ liệu chiếm phần lớn thời gian truyền thông. Trong decode độ đồng thời thấp, một vector ẩn 8 KiB phải được chuyển giao lặp đi lặp lại giữa các layer; việc truyền dữ liệu thực tế mất rất ít thời gian, và chính chi phí khởi động mỗi lần gọi chiếm ưu thế. Lấy một vòng tám participant, với khởi động 5 μs mỗi vòng và băng thông hiệu dụng mỗi participant; với đầu vào kích thước , một reduction mất
Mười bốn vòng khởi động tổng cộng 70 μs. Lấy băng thông liên kết bằng NIC 50 GB/s của chương này, đặt số hạng tải trọng bằng số hạng khởi động cho MB, khoảng 1,91 MiB. Khi đầu vào vượt bậc độ lớn này, phần thời gian dành cho truyền dữ liệu tăng lên; 8 KiB thấp hơn nhiều, nên phần lớn thời gian đến từ khởi động.

Đọc trục ngang của Hình 7-60 từ trái sang phải, đoạn kích thước dữ liệu nhỏ gần như phẳng, còn đoạn kích thước lớn dốc lên theo tải trọng tăng. Nâng băng thông chủ yếu làm phẳng độ dốc bên phải; rút ngắn thời gian khởi động chủ yếu hạ đường cong trong vùng phẳng bên trái.
Với đầu vào 8 MiB, nâng băng thông từ 50 lên 150 GB/s giảm một reduction từ khoảng 364 μs xuống 168 μs; với đầu vào 8 KiB, nó chỉ giảm từ khoảng 70,3 μs xuống 70,1 μs. Giả sử ta chạy một model 36 layer với mỗi layer một reduction như vậy cho attention và một cho FFN; 72 reduction nối tiếp tổng cộng khoảng 5,1 ms dưới cả hai băng thông, chỉ khác khoảng 14 μs. Giảm khởi động mỗi vòng từ 5 μs xuống 2 μs, ngược lại, cắt khoảng 3,0 ms khỏi 72 reduction đó.
Vậy, huấn luyện và prefill batch lớn được hưởng lợi dễ dàng hơn từ việc giảm byte, tăng băng thông và chồng lấp; decode độ đồng thời thấp thay vào đó cần ít đồng bộ xuyên máy chủ hơn trong một layer và một đường từ khởi động đến hoàn tất ngắn hơn. Điều này cũng giải thích sơ đồ song song pipeline thảo luận trong Mục 7.2: giữ một stage cục bộ giảm truyền thông từ xa trong stage đó, trong khi số yêu cầu độc lập được xử lý đồng thời quyết định mức sử dụng pipeline.
Vượt trên độ trễ trung bình, các lần chờ dài ngẫu nhiên cũng có thể làm trễ việc hoàn thành tác vụ. Lấy 100 sự kiện truyền thông, trong đó 98 cái mất 0,4 ms, một cái thêm 2 ms do sẵn sàng muộn, và một cái thêm 10 ms do phục hồi. Trung bình khoảng 0,52 ms; p99, lấy là giá trị thứ 99 khi sắp xếp từ nhỏ đến lớn, là 2,4 ms. Chia đôi thời gian truyền bình thường giảm p99 xuống 2,2 ms; nếu các sự kiện phục hồi tăng lên hai, p99 khi đó được quyết định bởi sự kiện truyền thông bao gồm phục hồi lỗi, trở thành 10,4 ms.
Truyền bình thường, trễ chuẩn bị dữ liệu và phục hồi lỗi mỗi loại đều có thể trở thành yếu tố thống trị quyết định thời gian hoàn thành tác vụ. Các truyền dữ liệu nhỏ thường xuyên cần chi phí khởi động mỗi lần gọi thấp hơn; phục hồi lỗi dài dằng dặc cần phạm vi lỗi nhỏ hơn. Sau khi một lỗi truyền thông xảy ra trong quá trình huấn luyện, nhóm truyền thông phải được dựng lại và trạng thái huấn luyện được khôi phục; Chương 10 đề cập sâu hơn quy trình này.
Cả các so sánh băng thông lẫn chi phí khởi động đều giữ mẫu truyền thông cố định. Bản thân mẫu truyền thông cũng có thể thay đổi: điều chỉnh sơ đồ song song hóa và phân bố expert có thể giảm số lần bàn giao; việc để bộ tăng tốc khởi động truyền thông trực tiếp, hoặc ủy việc khởi động và xử lý hoàn tất cho một đơn vị offload, có thể rút ngắn mỗi lần bàn giao. Việc định tuyến, dispatch và combine của MoE đặt ra các yêu cầu lên các thao tác mạng; việc mạng có thể hoàn thành các thao tác này hiệu quả hay không, đến lượt nó, ảnh hưởng hạt expert và việc triển khai xuyên nút. Nếu tính toán model tăng tốc nhờ phần cứng chuyên dụng trong khi bản thân thời gian truyền thông không đổi, phần của nó trên đường găng tăng lên.
Phân tích lưu lượng tương tự cũng áp dụng cho việc di trú trạng thái trong suy luận. Tiếp tục với cùng cuộc hội thoại DeepSeek V4.1 dùng xuyên suốt cuốn sách này, giả sử yêu cầu này phải di trú tới một instance không giữ KV toàn cục của nó. Trước tiên tính thời gian truyền cho tải trọng lịch sử toàn cục: với ngữ cảnh 128K, truyền qua một ConnectX-7 đơn chạy ở 200 Gbit/s, cho băng thông hiệu dụng 25 GB/s. 439,281 MiB của V4-Flash cần khoảng 18,425 ms, trong khi 111,250 MiB của V4.1 cần khoảng 4,666 ms. Nén trạng thái cắt khoảng 13,759 ms khỏi đường truyền này.
13,759 ms này là thời gian sơ đồ di trú có thể tiết kiệm được ở bước truyền. Nếu một yêu cầu đi qua xếp hàng, tra cứu cache, truyền và dựng lại trạng thái SWA cục bộ theo thứ tự, thời gian phục hồi là tổng của bốn đoạn này; dù truyền rút ngắn bao nhiêu, tổng thời gian cũng rút ngắn đúng bấy nhiêu. Chương 9 sẽ so sánh đường phục hồi này với việc ở lại instance gốc để chờ, hoặc tính lại từ đầu vào, để quyết định một yêu cầu nên thực thi ở đâu.
7.6.4 Cố định 1024 card: cách tái lựa chọn sau khi siêu nút lớn hơn
Các mục trước dùng mười sáu participant để phân tích đường đi; mục này mở rộng lên 1024 card: giữ tổng số card cố định trong khi thay đổi quy mô supernode từ 8 lên 64, 128 và 256 card, để xét những thời gian nào thay đổi. Ta trước hết cố định khối lượng tính toán và sơ đồ song song hóa, rồi thay đổi riêng các điều kiện mạng, và cuối cùng so sánh lại các mức song song.
Model và job huấn luyện cố định. Ta áp dụng shape của Qwen3-32B: 64 layer, chiều ẩn 5120, số tham số . 1024 card H100 SXM 80 GB được tổ chức với tensor parallelism 8 và data parallelism 128, viết là TP8×DP128, với mọi nhóm tensor-parallel tám card nằm gọn trong một supernode. Mỗi cập nhật xử lý một số token cố định là , và mỗi bản sao song song dữ liệu xử lý một micro-batch 8192 token; ý nghĩa của batch size toàn cục, độ chính xác và cập nhật optimizer đều không đổi. Trạng thái huấn luyện được tính ở 16 byte mỗi tham số, cho 64 GB mỗi card; ta cũng giả định 8 GB activation và không gian làm việc là đủ, và tạm thời không dùng ZeRO (Zero Redundancy Optimizer — optimizer phân mảnh trạng thái optimizer, gradient và tham số lên các bản sao song song dữ liệu).
Gradient được truyền ở BF16, nên shard mỗi card giữ là GB. Gọi siêu nút có card, nên số siêu nút là , và mỗi supernode chứa thành viên song song dữ liệu ở cùng một tọa độ tensor-parallel. Hình 7-61 vẽ sự phân nhóm trong một supernode 64 card: tám card trên cùng một hàng tạo thành một bản sao model, và các card trên cùng một cột thuộc cùng một nhóm đồng bộ gradient.

Khối lượng truyền xuyên supernode. thành viên song song dữ liệu trong một nút trước hết thực hiện ReduceScatter, để mỗi card còn lại một shard gradient ; supernode giữ cùng một shard sau đó thực hiện AllReduce; cuối cùng, một AllGather được thực hiện trong nút. Dùng thuật toán ring, mỗi card gửi xuyên nút, và nhân với card trong nút cho khối lượng gửi mỗi chiều mỗi supernode:
Khi nút mở rộng từ 8 lên 128 card, tăng từ 1 lên 16, và số byte xuyên nút mỗi card giảm, nhưng tổng khối lượng gửi mỗi supernode mỗi chiều chỉ giảm từ 127 GB xuống 112 GB. Vậy việc mở rộng supernode lên 16× không có nghĩa số byte đi qua cổng thoát cũng giảm 16×.
Trong một nút, NVLink được lấy ở 450 GB/s mỗi card mỗi chiều: 8 card chính xác là một HGX H100. Các trường hợp 64-đến-256-card tương ứng với NVLink Switch System, thứ có thể nối tối đa 256 GPU Hopper vào một miền NVLink đơn với băng thông all-to-all 115,2 TB/s — chính xác 256 card ở mỗi cái 450 GB/s. Xuyên nút, mỗi card có một ConnectX-7 ở 50 GB/s mỗi chiều. Khởi động mỗi vòng là trong một nút và xuyên nút, cả hai lấy 0,83 μs theo Mục 7.1.1. Gọi là băng thông mỗi card mỗi chiều trong một nút, là băng thông mỗi chiều mỗi NIC, và là băng thông thoát một chiều khả dụng của toàn bộ supernode; thời gian gradient phân cấp là
Các số hạng, theo thứ tự, là reduction và gather cục bộ, khởi động xuyên nút, và cái chậm hơn trong hai cái — NIC hay cổng thoát dùng chung. Một hệ thống thực cũng có thể bị ảnh hưởng bởi các tập cắt của mạng chuyển mạch và truyền thông đồng thời cục bộ; ví dụ này giả định mạng có thể cung cấp các băng thông được liệt kê, với không chồng lấp giữa các giai đoạn.
Tổng thời gian bước huấn luyện. Tính toán hiệu dụng mỗi card được lấy là đỉnh BF16 mật độ 989,4 TFLOP/s của H100 SXM nhân 41%, khoảng 405,7 TFLOP/s; 41% là MFU BF16 được báo cáo cho Llama 3 405B huấn luyện trên 16384 H100 với TP8, PP16 (pipeline parallelism 16 stage), DP128. Theo định nghĩa trong Mục 1.2.2, 41% nghĩa là 59% đỉnh tính toán không chuyển thành tính toán model. Một phần trong đó là công việc mà ước lượng bậc một này không đếm, ví dụ số hạng bậc hai trong attention và việc tính lại (recompute) làm trong quá trình huấn luyện để tiết kiệm bộ nhớ GPU; một phần khác là việc chờ có thể tránh được, ví dụ độ lệch sẵn sàng từ Mục 7.6.1 và các yêu cầu in-flight không đủ từ Mục 7.3.4. Tính toán được ước lượng là s, bỏ qua số hạng bậc hai của attention. Forward và backward mỗi layer cùng nhau được tính là bốn thao tác AllReduce tensor-parallel; tensor ẩn BF16 cho 8192 token là 80 MiB, và qua 64 layer tổng cộng khoảng 0,086 s; cập nhật optimizer được tính riêng ở 0,050 s. Thời gian bước và thông lượng (token xử lý mỗi giây) dưới một lịch cố định khi đó là
Đây là một ước lượng lịch cố định mắc chuỗi tính toán, truyền thông tensor-parallel, đồng bộ gradient và cập nhật; một hệ thống thực sẽ trừ đi phần đã được chồng lấp dọc theo dòng thời gian sẵn sàng gradient. Để so sánh, ta cũng tính một ring song song dữ liệu liên tục không phân cấp: mỗi tọa độ tensor-parallel chỉ có một cạnh ring xuyên nút, không trải cạnh này lên các NIC khác. Bảng dưới lấy thuật toán nhanh hơn trong hai thuật toán trong mỗi trường hợp.
| Card mỗi supernode | Số supernode | Thành viên DP cục bộ | Gửi xuyên miền mỗi nút | Exit tăng theo số card: thời gian bước/thông lượng | Exit cố định ở 400 GB/s: thời gian bước/thông lượng |
|---|---|---|---|---|---|
| 8 | 128 | 1 | 127 GB | 0,939 s/1,117M token/s | 0,939 s/1,117M token/s |
| 64 | 16 | 8 | 120 GB | 0,690 s/1,520M token/s | 0,939 s/1,117M token/s |
| 128 | 8 | 16 | 112 GB | 0,672 s/1,560M token/s | 0,935 s/1,122M token/s |
| 256 | 4 | 32 | 96 GB | 0,663 s/1,581M token/s | 0,896 s/1,171M token/s |
“Exit tăng theo số card” lấy GB/s, nghĩa là NIC 400 Gbit/s của mọi card đều nối vào mạng chuyển mạch — ngụ ý một nút lớn hơn được cấp tương ứng nhiều cổng ngoài dùng đồng thời và đủ năng lực chuyển mạch; exit không tự động mở rộng chỉ vì nút lớn hơn. “Exit cố định” thay vào đó cho mỗi supernode chỉ nối 8 làn 400 Gbit/s vào mạng chuyển mạch QM9700, tổng cộng 400 GB/s, giống một máy chủ HGX. Trong sơ đồ 64-card của trường hợp sau, reduction phân cấp cần khoảng ms, thực tế chậm hơn ring liên tục khoảng 317,7 ms, nên bảng chọn ring liên tục ở đây. Điều này khớp phán đoán từ Mục 7.2 về việc liệu reduction cục bộ có đáng giá. Cột “exit tăng theo số card” cũng ngầm giả định một mạng chuyển mạch không chặn: như tính trong Mục 7.1.2, over-subscription 3:1 cắt exit của mỗi supernode xuống một phần ba, nâng số hạng xuyên miền của nút 128-card từ khoảng 17,5 ms lên khoảng 52,5 ms, thêm khoảng 35 ms vào thời gian bước; Mục 7.2.5 giải thích các byte xuyên miền này được trải đều lên tám rail trong một cấu trúc đa rail như thế nào.

Hình 7-62 cho thấy thông lượng biến thiên theo quy mô supernode như thế nào dưới ba điều kiện mạng. Đi từ 8 lên 64 card nâng thông lượng khoảng 36% khi exit tăng theo số card. Một supernode 8-card chỉ là một máy chủ; mỗi card phải đồng bộ toàn bộ shard gradient 8 GB của nó qua NIC, mất 0,318 s — một phần ba thời gian bước. Ở 64 card, shard trước hết được giảm xuống một phần tám qua NVLink, nên mỗi card chỉ trao đổi mảnh nhỏ này xuyên nút, hạ việc đồng bộ gradient xuống khoảng 69 ms. Đi từ 128 lên 256 card chỉ nâng thông lượng khoảng 1,3%, vì lúc đó tính toán và truyền thông tensor-parallel đã chiếm 86% thời gian bước. Nếu băng thông nội bộ được nâng thêm từ 450 lên 900 GB/s — băng thông mỗi chiều của NVLink thế hệ thứ năm — nút 128-card đạt khoảng 0,614 s, 1,709M token/s; khoản tăng này đến từ băng thông nội bộ cao hơn, không phải từ bản thân kích thước nút.
So sánh lại các mức song song. Một miền tốc độ cao lớn hơn có thể chứa một nhóm tensor-parallel lớn hơn, nhưng không nhất thiết phải lấp đầy đến giới hạn. Với supernode 128-card, dưới điều kiện exit mở rộng, liệt kê tensor parallelism 8, 16, 32, 64, với data parallelism tương ứng 128, 64, 32, 16, giữ số token toàn cục cố định. Vì mỗi bản sao song song dữ liệu phải xử lý nhiều chuỗi hơn, mỗi chuỗi vẫn 8192 token, cả số hàng của ma trận cục bộ lẫn khối lượng truyền tensor-parallel đều phải được tính lại; giả định các shape này đều đạt hiệu quả tính toán của ví dụ này, các thời gian bước lần lượt khoảng 0,672, 0,753, 0,942 và 1,333 s. TP8 vẫn là tốt nhất ở đây: một nhóm tensor-parallel lớn hơn nghĩa là nhiều activation phải trao đổi hơn mỗi bản sao, và khoản tiết kiệm trong đồng bộ gradient cục bộ không bù được việc tăng trao đổi activation. Khi tensor parallelism vượt số KV head, các bố cục như KV nhân bản cũng phải được hỗ trợ; ví dụ này giả định kernel hỗ trợ điều này với đủ khoảng trống.
Sàng lọc này cho thấy 1024 card có thể huấn luyện một model cùng nhau, nhưng điều đó không có nghĩa mỗi layer của model bị chia lên toàn bộ 1024 card. Nếu chuyển sang suy luận, vài instance nhỏ hơn có thể mỗi cái tự xử lý các yêu cầu và cô lập lỗi một cách độc lập; Mục 6.7.4 đã dùng cùng phương pháp để tính tác động của quy mô supernode lên thông lượng decode. Khi huấn luyện thực tế có hiệu quả ma trận cục bộ, bộ nhớ, hoặc năng lực chồng lấp khác, một tổ hợp nào đó của tensor, context và pipeline parallelism có thể hoạt động tốt hơn; nên mở rộng sơ đồ và tính lại như trong Mục 6.7.3, thay vì coi TP8 của ví dụ này là một câu trả lời phổ quát.
Chi phí phục hồi sau lỗi. Mọi con số thông lượng trên đều giả định job không bao giờ bị ngắt. Trong huấn luyện đồng bộ, một card đơn hỏng có thể dừng cả job; khác với một instance suy luận độc lập, một bản sao song song dữ liệu không thể đơn giản bị bỏ, vì điều đó sẽ thay đổi các mẫu và gradient dùng trong cập nhật này. Trừ khi hệ thống cung cấp phục hồi cục bộ hoặc một sơ đồ co giãn bảo toàn ngữ nghĩa huấn luyện, nó phải quay lại một checkpoint nhất quán. Giả sử mỗi giây, tính toán hiệu dụng tạm dừng giây để lưu một checkpoint, tỉ lệ ngắt của job là , và phục hồi mất giây. Khi tỉ lệ lỗi thấp và thời điểm lỗi phân bố gần đều trong khoảng checkpoint, tỉ lệ chi phí có thể được ước lượng gần đúng là
Điều này chỉ ước lượng tiến triển hiệu dụng trung bình và không đảm bảo độ trễ đuôi. Các lỗi card độc lập có thể có tỉ lệ ngắt được cộng theo số card, trong khi các lỗi thiết bị dùng chung cấp supernode nên được đếm theo phạm vi lỗi thực của chúng; không phải mọi lỗi đều nên được coi là độc lập. Tỉ lệ ngắt được lấy từ thống kê cho cụm nghiên cứu của Meta: một job 1024-card gặp một lần ngắt trung bình mỗi 7,9 giờ, với tỉ lệ ngắt tỉ lệ thuận với số card, tương đương khoảng một lần ngắt mỗi card mỗi 337 ngày (khoảng 8090 giờ) trung bình; Chương 10 cũng dùng bộ dữ liệu này. Các thống kê này đã gồm các lỗi thiết bị dùng chung, nên ví dụ này không thêm một số hạng lỗi dùng chung riêng ở cấp supernode, và tỉ lệ ngắt không thay đổi theo quy mô supernode; mọi lần ngắt đều kích hoạt phục hồi toàn bộ job. Mỗi 600 giây, tính toán hiệu dụng tạm dừng 10 giây để lưu một checkpoint. Phục hồi được lấy là cố định 60 giây, cộng thời gian đọc lại trạng thái 64 GB mỗi card của mỗi supernode bị ảnh hưởng qua một liên kết PCIe Gen5 x16 (64 GB/s mỗi chiều). Với các nút 128- và 256-card, thời gian phục hồi lần lượt là 188 và 316 giây, với chi phí thêm khoảng 3,4% và 3,8%; dưới điều kiện exit mở rộng, thông lượng hiệu dụng khoảng 1,509M và 1,523M token/s: nút 256-card phục hồi chậm hơn, nhưng chi phí thêm của nó vẫn nhỏ hơn cải thiện của nó trong thông lượng vận hành bình thường.
Tỉ lệ ngắt đến từ thống kê cho một cụm, còn khoảng checkpoint và kênh phục hồi là các đầu vào cho trước. Một nút lớn hơn có thể giảm số thiết bị dùng chung, nhưng cũng có thể phóng đại lượng mất và lưu lượng phục hồi từ một lỗi đơn; với card dự phòng, phục hồi cục bộ, hoặc một tỉ lệ lỗi khác, các con số này nên được tính lại. Vậy, khi so sánh các sơ đồ, nên báo cáo cùng nhau thông lượng vận hành bình thường, mô hình phục hồi và tiến triển huấn luyện hiệu dụng trong thời gian mục tiêu; Chương 10 mở rộng về các giao thức checkpoint và phục hồi.
7.6.5 Triển khai và các cạm bẫy thường gặp
Gradient lớn, truyền khối lượng nhỏ và phục hồi lỗi mỗi loại làm nổi bật một nút thắt khác nhau: lần lượt là băng thông, chi phí khởi động và chờ phụ thuộc. Việc so sánh các sơ đồ triển khai cũng nên bắt đầu từ các khối lượng công việc này. InfiniBand, RoCE và UB mỗi cái cung cấp các cơ chế kết nối và truyền thông cụ thể; khi chọn một sơ đồ triển khai, trước tiên dùng ba mô hình trong chương này để so sánh các đường truyền thông của mỗi phương án. Kết nối giữa GPU và NIC, các giao diện dùng chung và cấu trúc chuyển mạch quyết định băng thông khả dụng; các cơ chế nộp và hoàn tất yêu cầu quyết định thông lượng thực tế; và các cơ chế đồng bộ và phục hồi của ứng dụng quyết định thứ tự thực thi.
Để tính băng thông khả dụng, trước hết phải làm rõ các cổng vật lý được nối như thế nào. Ví dụ, trong Ascend 950, UBoE và UB Link đều dùng chung SerDes theo một sơ đồ cấu hình trước, và mục đích của một nhóm SerDes cho trước được quyết định bởi cấu hình cổng. Chỉ sau khi mục đích của cổng được chọn, mới có thể tính băng thông liên kết thực dùng được theo chiều đó. Một khi giao diện được thống nhất, các chương trình có thể truy cập nó theo một cách chung, trong khi cấu hình cổng quyết định dữ liệu đi qua những liên kết nào và các liên kết đó có bao nhiêu băng thông.
Các bản ghi vận hành công khai của AllReduce cho phép ta phân tích tác động tổng hợp của các yếu tố này. Với đầu vào 16 GiB, và với đầu vào và đầu ra dùng các buffer riêng, hai máy chủ H100 tám card cùng thông số với ví dụ của chương này mất khoảng 68,7 ms, và bốn máy chủ mất khoảng 91,0 ms. Thêm máy chủ mang thêm participant và một đường hợp tác dài hơn.
Các suy diễn của chương này cũng giúp làm rõ bốn cạm bẫy thường gặp.
Cạm bẫy: nếu tổng lượng gửi bằng nhau, thời gian truyền thông bằng nhau. Ring liền nhau phẳng, ring xen kẽ và reduction phân cấp đều gửi 5760 MiB, vậy mà phần xuyên máy chủ lần lượt là 720, 5760 và 384 MiB, dùng lần lượt một, tám và tám NIC. Thời gian truyền phụ thuộc dữ liệu đi qua những tài nguyên nào; cách sắp xếp các participant thay đổi mỗi NIC phụ trách bao nhiêu byte.
Cạm bẫy: mức sử dụng liên kết trung bình thấp là đủ để xử lý các đỉnh truyền thông. Hai job tuần hoàn chỉ cần trung bình 20 GB/s, nhưng khi các đỉnh truyền thông của chúng chồng nhau chúng đạt 100 GB/s, làm đọng lại 1 GB ở một cổng thoát 50 GB/s. Cái buffer giữ là khoản thâm hụt tích lũy trong một khoảng nào đó, và pha cùng phản hồi quyết định khoản thâm hụt đó tích lũy trong bao lâu.
Cạm bẫy: trả về theo đúng thứ tự đảm bảo đọc dữ liệu đúng. Một giá trị cũ đọc trước lúc cập nhật dữ liệu không trở thành giá trị mới chỉ vì việc trả về bị trễ. Phụ thuộc giữa publish và read phải ràng buộc thời điểm đọc thực tế; thực thi sớm đòi hỏi kiểm tra và đọc lại.
Cạm bẫy: tốc độ tăng truyền thông bằng tốc độ tăng tác vụ. Reduction phân cấp giảm truyền thông từ khoảng 7,6 ms xuống 1,3 ms, và bước huấn luyện tuần tự từ khoảng 29,6 ms xuống 23,3 ms; làm dữ liệu sẵn sàng sớm hơn giảm sơ đồ phân cấp xuống 22,0 ms. Cùng một tối ưu hóa truyền thông tiết kiệm một lượng tổng thời gian khác nhau tùy thứ tự thực thi.
Theo tôi hiểu, điểm khởi đầu của kết nối thống nhất là để các thiết bị truy cập trực tiếp dữ liệu từ xa và khởi động truyền thông, để các tầng cao biểu diễn tường minh các phụ thuộc, và để các tầng dưới tái sử dụng cùng một trạng thái truyền. Đánh giá các thiết kế này đòi hỏi trả lời ba câu hỏi: những byte nào không còn được di chuyển, khoảng nào không còn phải chờ, và để đạt được điều đó phải giữ thêm trạng thái yêu cầu nào và thực hiện thêm xử lý gì.
Thí nghiệm 7-15 · Cốt lõi: tối ưu hóa truyền thông tiết kiệm bao nhiêu thời gian huấn luyện và suy luận
Trước tiên, tính lại ví dụ 1024 card, giữ số token toàn cục cố định trong khi thay đổi từng lúc một quy mô supernode, mức chặn thoát và băng thông cục bộ, và ghi lại thuật toán truyền thông và ứng viên tensor-parallel nào hoạt động tốt hơn. Rồi chia đôi băng thông của kênh phục hồi và so sánh tiến triển hiệu dụng. Cuối cùng, tính lại Ví dụ làm việc 7.6 và vẽ dòng thời gian cả bước cho ring liền nhau phẳng, reduction phân cấp, yêu cầu in-flight không đủ, truyền thông sớm, và trường hợp chỉ còn một NIC. Tìm thời điểm muộn nhất dữ liệu có thể trở nên sẵn sàng sao cho truyền thông phân cấp được che trọn vẹn bởi 20 ms tính toán. Rồi chuyển sang 36 layer với hai reduction 8 KiB mỗi layer, và xét riêng việc tăng băng thông lên ba lần giá trị ban đầu và việc giảm mỗi chi phí khởi động xuống 2 μs; giải thích vì sao thứ tự cải thiện khác nhau giữa hai loại khối lượng công việc.
Chú thích nguồn
-
Về phương pháp tính quy mô model và kích thước trạng thái, xem Model Resource Accounting và Tài liệu mở rộng Chương 7. Ví dụ Adam mixed-precision cấp 16 byte trạng thái huấn luyện cho mỗi tham số; ví dụ suy luận model nghìn tỷ tham số tính dung lượng trọng số ở 0,5 byte mỗi tham số.
-
Ghi chú đối chiếu giữa đặc tả UB và thiết kế tham chiếu hệ điều hành.
-
Tính toán reduction gradient hai cấp, ring liền nhau phẳng, ring xen kẽ. Hình dạng model cố định; mỗi vòng đồng bộ tại một barrier, và các thời gian liệt kê là tổng thời gian truyền tải payload và thời gian khởi động trong điều kiện không tranh chấp: NVLink 450 GB/s mỗi chiều, một NIC mỗi card ở 50 GB/s mỗi chiều, khởi động 0,833 μs mỗi vòng. Chạy
python3 calculations/calc.py hierarchical-gradient --inputs calculations/scenarios/hierarchical-gradient-example.json --format mdđể tính lại. -
Reduction phân cấp cho cấu hình tham chiếu, ring liền nhau phẳng, ring xen kẽ: bốn card A100 80GB PCIe mỗi server, PCIe Gen4 x16 điểm-nối-điểm giữa các card ở 32 GB/s mỗi chiều; một ConnectX-7 hai cổng, mỗi cổng 200 Gbit/s ở 25 GB/s, chia sẻ khe PCIe Gen4 x16 32 GB/s mỗi chiều; khởi động 0,833 μs mỗi vòng. Data sheet A100 80GB liệt kê PCIe 4.0 ở 64 GB/s và cầu nối NVLink hai card ở 600 GB/s, cả hai là con số tổng hợp cho cả hai hướng gửi và nhận; data sheet ConnectX-7 liệt kê các cấu hình 1/2/4 cổng, với tổng hợp một card lên tới 400 Gbit/s, và giao diện host PCIe Gen5 x16/x32; cấu hình tham chiếu tính card này như được lắp trong khe PCIe Gen4 x16. Con số 300 GB/s băng thông cục bộ thu được bằng cách tính lại với
local_bytes_per_secondđổi thành 300 GB/s. -
Với cấu hình tham chiếu, ring liền nhau phẳng với một cổng, hai cổng và ba cổng: thông điệp liên server được rải qua các cổng, và 32 GB/s mỗi chiều của khe PCIe Gen4 x16 không tăng theo số cổng. Với reduction phân cấp một NIC trong Mục 7.6.2, xem reduction phân cấp một NIC.
-
Data sheet HGX H100: tám GPU nối với nhau qua NVSwitch, NVLink 900 GB/s giữa các GPU và tốc độ mạng tối đa 400 Gbit/s; đặc tả NVIDIA H100 liệt kê NVLink 900 GB/s và PCIe Gen5 128 GB/s của H100 SXM, cả hai là tổng hợp cho cả hai hướng gửi và nhận; trang đặc tả NVLink đưa băng thông NVLink mỗi GPU theo từng thế hệ; data sheet ConnectX-7: một cổng tối đa 400 Gbit/s, giao diện host PCIe Gen5 x16; data sheet DGX H200: tám GPU đi kèm tám NIC ConnectX-7 400 Gbit/s. Cấu hình một NIC 400 Gbit/s mỗi card được lấy từ bản ghi chạy công khai của experiments/ch07/07-03: hai server HGX, mỗi server 8 H100 và 8 NIC ConnectX-7 400 Gbit/s InfiniBand. Cấu trúc liên kết dạng rail trong đó các NIC có số hiệu giống nhau kết nối cùng một switch được mô tả trong kiến trúc tham chiếu DGX SuperPOD H100. PCIe Gen5 x16 64 GB/s mỗi chiều vượt quá 50 GB/s của NIC, nên NIC là nút thắt trên đường này. Thời gian khởi động 0,833 μs mỗi vòng được suy ra từ cùng bản ghi công khai: trong nhật ký thô, một AllReduce out-of-place 16 rank với kích thước thông điệp từ 16 B đến 128 B mất 24,93–25,68 μs; lấy 25 μs chia cho 30 vòng của ring AllReduce giữa mười sáu thành viên sẽ cho giá trị này. Thuật toán thực tế NCCL chọn cho thông điệp nhỏ không được tiết lộ trong nhật ký; ở đây chỉ quy đổi bằng mô hình ring của chương này.
-
Nghiên cứu tình huống song song hóa model, văn bản chính Chương 6. Ví dụ EP của chương này dùng 1024 token, tám lần phân phối mỗi token, 8 KiB mỗi lần phân phối, tỷ lệ vượt biên một nửa, và sơ đồ định tuyến được dựng cho mục đích giảng dạy.
-
Ren et al., Enabling Efficient GPU Communication over Multiple NICs with FuseLink, OSDI 2025; bài báo hội nghị chính thức, suy diễn đường truyền thông. Giá trị đường chuyển tiếp trong đoạn này theo cấu hình của chương: NIC 50 GB/s mỗi chiều, NVLink 450 GB/s mỗi chiều; với việc triển khai plugin và nền tảng thí nghiệm, xem bài báo gốc.
-
Xác minh bản ghi chạy công khai của experiments/ch07/07-03. Dữ liệu đến từ một bản ghi do người dùng nộp trong dự án chính thức.
-
Tính lại giai đoạn RPC và ghép cặp, bản ghi gốc 264 lời gọi. Thay đổi trong giai đoạn CPU và số byte yêu cầu, và thay đổi trong lời gọi được ghép cặp, được thống kê riêng biệt. Đường đo là một máy Mac chuyển tiếp qua SSH tới một host Linux, gồm mã hóa, chuyển tiếp và biến thiên mạng; ghép cặp các lời gọi hoàn tất tiết kiệm trung vị khoảng 10,1 ms.
-
Cửa sổ đọc từ xa, chờ tuần tự: đường ở 50 GB/s, 256 B mỗi giao dịch, chiếm khe 2 μs. Khoảng khởi động 18,6 ns và 6,2 ns được lấy từ hình tỷ lệ yêu cầu trong tính toán kết nối liên kết UB (trong bộ công cụ OpenURMA, kết nối tin cậy RoCE tốn 6 chu kỳ mỗi yêu cầu và UB tốn 2 chu kỳ mỗi yêu cầu, ở xung nhịp 322 MHz). Chờ yêu cầu và khoảng khởi động phục vụ được định nghĩa riêng trong công thức.
-
Bojie Li và cộng sự, KV-Direct: Kho lưu trữ key-value trong bộ nhớ hiệu năng cao với NIC lập trình được, SOSP 2017, §2.4 và Hình 3; thảo luận thêm về PCIe credits và tags, xem Chương 5 của luận án tiến sĩ của tác giả. Các con số này trích theo nền tảng gốc (PCIe Gen3 x8, NIC FPGA); các nền tảng khác có số credit, số tag và độ trễ khác nhau, nhưng chia sẻ cùng cấu trúc trong đó đọc bị giới hạn bởi số yêu cầu in-flight và ghi bị giới hạn bởi tốc độ gói.
-
Điểm giao giữa tốc độ gói và băng thông suy ra từ khoảng khởi động 18,63 ns của kết nối tin cậy RoCE trong Mục 7.3.4 và băng thông NIC 50 GB/s của chương này, cho ra khoảng 931 B; về việc vay băng thông của FuseLink, xem chú thích FuseLink ở trên; về chiều ẩn 7168 của phân phối MoE và phân phối FP8 kết hợp BF16, xem ảnh chụp README DeepEP.
-
Ảnh chụp README DeepEP mô tả các kích thước bộ đệm dành riêng riêng cho NVLink và RDMA; chi phí sao chép và đóng gói được suy luận từ mô hình sự kiện của phần này, không đo với bất kỳ phiên bản cụ thể nào.
-
Hou et al., Understanding Routable PCIe Performance for Composable Infrastructures, NSDI 2024, thí nghiệm tiến hành trên nền tảng PCIe Gen3; đường PCIe và chẩn đoán.
-
Đọc từ xa và lấy lại một ảnh chụp KV không đổi. Ảnh chụp là 1024 token của Qwen3-8B, KV full-layer BF16, tổng 144 MiB; đọc từ xa và truyền về được tính ở 50 GB/s mỗi chiều cho ConnectX-7 với 391 giao dịch 256 B in-flight, và đọc/ghi cục bộ ở băng thông HBM 3350 GB/s của H100 SXM; một lần truyền về có chi phí cố định khoảng 3,075 ms, mỗi lần đọc từ xa khoảng 3,025 ms, và đọc cục bộ khoảng 0,046 ms. Phản ví dụ truy cập 10% chia tỷ lệ chi phí mỗi lần truy cập một cách tương ứng, trong khi vẫn tính chi phí truyền về cho toàn bộ ảnh chụp.
-
Phản ví dụ phụ thuộc cần thiết và giá trị cũ, biến thể tài nguyên dùng chung, đọc về nghiên cứu thứ tự từ xa và một triển khai NVSHMEM cố định. Thứ tự phía đích là một thiết kế đòi hỏi hỗ trợ phần cứng mới; thí nghiệm tham chiếu trên các NIC hiện tại được dùng để quan sát thời điểm yêu cầu và hoàn tất. Chuỗi công bố 20+80+2 μs và phản ví dụ giá trị cũ 1–6 μs là hai đầu vào độc lập. “Thực thi mọi thứ nghiêm ngặt theo thứ tự” đóng vai trò chiến lược đường cơ sở tuần tự.
-
Quan hệ hoạt động và trạng thái truyền, cách ly tám chiều. Mô hình hạch toán riêng ba loại dung lượng: đầu cuối, ràng buộc quan hệ, và trạng thái truyền.
-
Xử lý thông báo hoàn tất và giải phóng khe, khe bổ sung. Chu kỳ thăm dò, số thông báo hoàn tất được xử lý mỗi lần thăm dò, và thời gian chiếm khe là các điều kiện giảng dạy.
-
Nhu cầu định kỳ và hàng đợi, lệch pha, trôi pha. Tốc độ đến trong ví dụ biến thiên theo chu kỳ cho trước.
-
Rajasekaran et al., CASSINI: Lập lịch công việc nhạy cảm mạng trong cụm học máy, NSDI 2024; đặt công việc và lập lịch giai đoạn. Thí nghiệm chính của bài báo dùng 24 server, mỗi server một A100 40 GB, NIC 50 Gbps, và mạng logic oversubscribe 2:1; mỗi công việc có thiết bị huấn luyện độc quyền nhưng chia sẻ mạng.
-
experiments/ch07/07-08: huấn luyện CPU thực và làm lệch một lần. Kết quả ba vòng đã tính cả độ trễ ban đầu 50 ms, và trạng thái model cùng optimizer được xác minh nhất quán; so sánh này được dùng để phân tích thứ tự thực thi CPU. Môi trường là CPU dùng chung với Gloo loopback; thời gian hoàn tất qua ba vòng tăng 2,27%–3,32%.
-
Bộ đệm hữu hạn và độ trễ phản hồi. Thời điểm phản hồi đặt ở 20 μs, và tốc độ gửi sau phản hồi được điều chỉnh theo thiết lập bài toán.
-
cả hai đường bị trễ như nhau, trễ đường không đều, phục hồi mất gói đã định. Số byte được thống kê ở mức payload ứng dụng. Cả hai đường chạy ở 50 GB/s, gói 4 KiB, dùng payload cố định với phân bổ round-robin, và thời điểm phục hồi do thiết lập bài toán cho trước; 32 KiB truyền lại bắt đầu từ gói thiếu được dùng để tính payload phụ trội.
-
Jiang et al., MegaScale: Mở rộng huấn luyện mô hình ngôn ngữ lớn lên hơn 10.000 GPU, NSDI 2024; bài báo chính thức, chẩn đoán truyền thông tập thể.
-
Bản ghi giảng dạy độ lệch sẵn sàng, 100 bản ghi hỗn hợp, hai bản ghi phục hồi. p99 lấy phần tử thứ sau khi sắp xếp.
-
experiments/ch07/07-10/rank-readiness: độ lệch sẵn sàng giữa bốn tiến trình Gloo. Apple M2 Max, CPU cục bộ, 180 bản ghi chính thức; hoàn tất nhóm được đo từ lần trả về barrier sớm nhất đến lần trả về lời gọi muộn nhất, và phần đuôi sau lượt đến cuối cùng vẫn gồm reduction, lập lịch và đánh thức. Văn bản chính dùng trung vị trên các thống kê mẫu khác nhau; với dòng thời gian từng mẫu, xem bản ghi gốc.
-
Nghiên cứu tình huống lập kế hoạch mạng và truyền thông tập thể. Ví dụ thông điệp nhỏ giả định 5 μs khởi động mỗi vòng, với băng thông hiệu dụng của mỗi bên đặt ở băng thông NIC 50 GB/s của chương này và ở ba lần giá trị đó, 150 GB/s; mô hình ring tính truyền tải payload cộng khởi động, với giá trị cho trong mục
small_messagescủa ví dụ giảng dạy chương này; reduction khối lớn trước đó dùng 0,833 μs mỗi vòng suy ra từ các bản ghi nccl-tests. -
Đối chiếu nguồn UB và Ascend 950, gồm UB Base Specification 2.0.1, thiết kế tham chiếu hệ điều hành 2.0, và sách trắng chính thức Ascend 950. Miền, chế độ truyền tải, băng thông hai chiều, và ghép kênh SerDes được hạch toán riêng từng loại.
-
Báo cáo kỹ thuật chính thức DeepSeek V4.1, Mục 1, 2, 3 và 6; điều kiện cố định và tính lại được mang qua các chương.
-
Bojie Li, “Reflections Behind Unified Bus”, các mục về Jetty, thứ tự giao dịch và Load/Store; bài báo OpenURMA, bản sửa ngày 2026-06-02 (arXiv:2605.28717), §3 thiết kế, §7–§9 trạng thái và độ trễ, §10 thứ tự, §12 vận chuyển, §13 tóm tắt kết quả. Nguồn và phạm vi cho việc tích hợp này.
-
Với tham số và kết quả của độ trễ giai đoạn, tốc độ yêu cầu, và tăng trưởng trạng thái, xem tính toán kết nối liên kết UB; chạy
python3 calculations/calc.py ub-fabric --format mdđể tính lại. Độ trễ mỗi giai đoạn lấy từ các giá trị trong Bảng 7 của bài báo OpenURMA, kích thước bản ghi lấy từ Bảng 3, và giá trị tham chiếu mô phỏng lấy từ §8.1 và §8.3. Suy diễn cộng tuần tự tất cả các giai đoạn và không tính đến sự chồng lấp giữa các yêu cầu đồng thời. -
Kịch bản 1024 card cố định, tính toán đầy đủ và so sánh ứng viên, script. Hình dạng đến từ cấu hình Qwen3-32B, xấp xỉ tổng tham số là 32B. Đỉnh BF16 dense của H100 SXM được cho trong bảng phần cứng; con số MFU 41% được lấy từ Bảng 4 của bài báo Llama 3; hệ thống NVLink Switch kết nối tối đa 256 GPU với băng thông chuyển mạch toàn phần 115,2 TB/s được cho trong ảnh chụp blog kiến trúc Grace Hopper; NVLink thế hệ thứ năm 1800 GB/s mỗi GPU (tổng hợp hai chiều) được cho trên trang đặc tả NVLink; con số một công việc 1024 card bị ngắt trung bình mỗi 7,9 giờ một lần, với tỷ lệ ngắt tỷ lệ thuận với số card, được cho trong Hình 7 của bài báo độ tin cậy cụm Meta. Khoảng checkpoint và tạm dừng, và thời gian phục hồi cố định, là các đầu vào cho trước.
-
Clos không chặn 64 cổng, oversubscribe 3:1: switch lá với đường xuống và đường lên, với các tầng trên không chặn so với đường lên của lá, trong cấu trúc fat-tree ba tầng dạng pod; băng thông chia đôi được tính là một nửa dung lượng liên kết tầng trên cùng; phân vùng 1024 card tính tập cắt bằng cách chiếm một số nguyên switch lá; thoát supernode được lấy từ kịch bản 1024 card ở 50 GB/s mỗi card nhân với số card và chia cho tỷ lệ oversubscribe, và byte vượt miền được lấy từ tính toán 1024 card. Switch được lấy là NVIDIA Quantum QM9700 (NDR 400 Gbit/s) được dùng trong kiến trúc tham chiếu DGX SuperPOD H100, với Bảng 3 của nó dùng 64 switch lá và 32 switch spine cho 2048 GPU, khớp với số lượng cho Clos hai tầng 64 cổng. Chạy
python3 calculations/calc.py clos-cut --inputs calculations/scenarios/clos-cut-example.json --format mdđể tính lại. -
So sánh reduction trong mạng: giai đoạn cục bộ giống reduction phân cấp, và giai đoạn liên server có mỗi NIC gửi shard của mình một lần và nhận kết quả một lần; với server, ring tính shard mỗi NIC qua vòng, với 0,833 μs khởi động mỗi vòng; thông lượng của engine reduction trong switch không nằm trong mô hình. Định nghĩa SHARP được lấy từ tài liệu NVIDIA SHARP, và các giá trị đo được lấy từ tóm tắt của bài báo SHArP.
-
Ghép cặp thẳng hàng, ghép cặp lệch: hai server, mỗi server tám NIC, trong đó NIC kết nối với switch lá của rail ; giai đoạn liên server là một ReduceScatter cộng AllGather giữa hai rank, chỉ tính các lần gửi NIC tuần tự và 0,833 μs khởi động mỗi vòng. Cấu trúc liên kết multi-rail, với một nhóm 32 server tới cùng một rail trong một bước nhảy và vượt rail qua tầng spine, được lấy từ trang 8 và 14 của PDF kiến trúc tham chiếu DGX SuperPOD H100.
-
Phản hồi incast, bộ đệm 4 MiB: bên gửi, mỗi bên 50 GB/s hướng tới một đầu ra 50 GB/s, dưới mô hình chất lỏng; khoảng cách phản hồi một bước nhảy là vòng khứ hồi truyền lan của cáp 30 m cộng với tuần tự hóa một gói 1500 B, và khoảng cách phản hồi đầu cuối-đầu cuối được lấy là vòng khứ hồi 20 μs. Định nghĩa PFC tạm dừng một liên kết full-duplex theo lớp lưu lượng được lấy từ mục IEEE 802.1Qbb; MTU 1500 B và headroom 22,4 KB mỗi cổng mỗi mức ưu tiên được lấy từ §4 của bài báo DCQCN.
-
8 luồng trên 32 đường lên, 8 luồng trên 16 đường lên, 32 luồng trên 32 đường lên, 32 luồng trên 16 đường lên, 128 luồng trên 16 đường lên: mỗi luồng trên một switch lá nhất định băm độc lập và đều lên các đường lên của lá đó; phân bố tải cực đại được tính chính xác như một đa thức mũ cắt cụt, và tốc độ tương đối so với phân bổ không va chạm là chia cho tải cực đại kỳ vọng (với , đây là mức cắt hiệu dụng trong tệp kết quả). Phun gói dùng cùng mô hình sắp xếp lại gói trong phần này: một phiên truyền 8 MiB chia thành gói 4 KiB xoay vòng qua tám đường 50 GB/s, với độ trễ từng đường từ 1 đến 8 μs cho trước là đầu vào. Giá trị phun và entropy được lấy từ Ultra Ethernet Specification v1.0.1 §3.6.5.2; chi phí lùi N bước được lấy từ UEC Overview, trang 5.
Tóm tắt chương
Từ các toán tử một card đến supernode và rồi tới trung tâm dữ liệu, phân mảnh và lập lịch luôn xoay quanh cùng một tập phụ thuộc dữ liệu. Để phân tích một tác vụ liên server, hãy bắt đầu bằng cách theo dõi một mẩu dữ liệu: đi theo thuật toán để xác định nó phải được trao cho những bên tham gia nào, rồi đi theo cấu trúc liên kết để xác định nó đi qua những tài nguyên nào. Ví dụ hai server trước tiên thực hiện reduction cục bộ, cắt lượng truyền liên server từ 720 MiB xuống 384 MiB và để tám NIC làm việc đồng thời, nhờ đó rút ngắn thời gian truyền trên liên kết tắc nghẽn. Bản thân mạng chuyển mạch cũng là một tài nguyên cần hạch toán: tỷ lệ oversubscribe quyết định tập cắt rộng bao nhiêu, các rail có thẳng hàng hay không quyết định byte đi một bước nhảy hay phải đi qua tầng spine, va chạm băm và incast quyết định băng thông hiệu dụng và bộ đệm, và reduction trong mạng gập giai đoạn liên server lại thành một vòng duy nhất.
Khi đường truyền thông đã được chọn, các yêu cầu vẫn cần được nộp và xử lý liên tục. Tích băng thông-độ trễ quyết định bao nhiêu byte phải in-flight; lượng dữ liệu mỗi yêu cầu cùng với khoảng cách nộp quyết định lượng dữ liệu có thể nộp mỗi giây; và tốc độ xử lý thông báo hoàn tất quyết định một khe yêu cầu có thể được tái sử dụng nhanh đến đâu. Chia sẻ trạng thái tiết kiệm dung lượng, còn cô lập trạng thái kiểm soát sự can thiệp lẫn nhau; thời điểm dữ liệu có thể đọc và thời điểm nó có thể được giải phóng quyết định trạng thái này phải được giữ trong bao lâu. Cộng các giai đoạn của một lần truy cập từ xa cho thấy việc bộ điều khiển nằm sau PCIe hay trên một bus trên chip quyết định chi phí cố định mỗi lần truy cập, và việc trạng thái kết nối tỷ lệ với số đầu cuối hay với số cặp đầu cuối quyết định liệu nó có thể ở lại trong bộ nhớ đệm trên chip hay không.
Ví dụ 1024 card còn cho thấy quy mô supernode, băng thông trong nút và thoát ngoài là các điều kiện riêng biệt. Mở rộng miền tốc độ cao từ một server tám card lên 64 card giữ nhiều reduction cục bộ hơn, cắt đồng bộ gradient từ khoảng một phần ba thời gian bước xuống còn khoảng một phần mười và tăng thông lượng khoảng 36%; vượt quá mức đó, lợi ích nhanh chóng suy giảm. Khi miền tốc độ cao đã được mở rộng, tổ hợp tensor parallelism và data parallelism có thể được so sánh lại, nhưng giới hạn thoát và chi phí reduction cục bộ hoặc chi phí phục hồi đều có thể làm dịch chuyển lựa chọn. Một công việc dùng toàn bộ card của cụm không có nghĩa là mọi loại truyền thông đều phải trải qua tất cả chúng.
Cuối cùng, vẽ quan hệ thứ tự giữa chuẩn bị dữ liệu, truyền, sử dụng và phục hồi sẽ tạo ra một đồ thị phụ thuộc. Giảm lượng dữ liệu truyền và khối lượng công việc xử lý yêu cầu, khởi động các thao tác độc lập sớm hơn, và rút ngắn đường găng là ba cách tối ưu hóa mạng chuyển thành lợi ích cho tác vụ. Chương tiếp theo sẽ dùng các khả năng thực thi và kết nối liên kết này để xây dựng một dịch vụ suy luận một phiên bản, và Chương 9 sẽ tiếp tục tổ chức việc bàn giao dữ liệu giữa các phiên bản.