Bỏ qua điều hướng
chuanweb.com

Chương 6 · Supernode

Nhiều thiết bị hợp tác trong một supernode: cân bằng dung lượng, thông lượng tính toán và chi phí đồng bộ giữa các accelerator.

~128 phút đọc · Thuật ngữ

Supernode

Chương trước chia ma trận thành các tile nhỏ, cho phép đầu vào được sử dụng lại nhiều lần ngay gần đơn vị tính toán. Giờ hãy trao một trong những tile đó cho một card tăng tốc khác: card đó cần những đầu vào gì, nó tạo ra một đầu ra hoàn chỉnh hay một tổng riêng phần, và ai sử dụng kết quả tiếp theo? Toán học không thay đổi, nhưng dữ liệu trước đây đi qua bộ nhớ dùng chung (shared memory) giờ có thể phải vượt qua interconnect của accelerator, thậm chí là cả mạng dữ liệu trung tâm. Cùng một sơ đồ chia tile như vậy do đó trở thành một sơ đồ song song đa card.

Với tám card, bạn có thể để mỗi card phục vụ yêu cầu riêng lẻ, hoặc để chúng phối hợp tăng tốc một yêu cầu duy nhất; cách chia phải vừa phù hợp với mô hình vừa đáp ứng mục tiêu độ trễ và chi phí. Chương này bắt đầu từ các chiều và phụ thuộc của operator, lần lượt đi qua giao tiếp sinh ra từ mỗi chiến lược song song, và cuối cùng dùng một mô hình cho trước, phần cứng tám card và hạn chót của phiên để lọc giữa các phương án. Sau khi đọc chương này, người đọc nên có thể liệt kê các phương án khả thi cho mô hình và phần cứng của chính mình, loại trừ những phương án bất khả thi, rồi lựa chọn dựa trên nút thắt và đo lường — chứ không chỉ thuộc lòng một vài viết tắt song song.

Chương trước đã xem xét tính toán, tái sử dụng dữ liệu và thực thi nhiệm vụ trong một accelerator duy nhất. Song song đa card đặt ra đúng bộ câu hỏi đó: chia theo chiều nào, mỗi phần đi đâu, mỗi phần cần đầu vào gì, kết quả hội tụ ở đâu, và thứ tự thực thi ra sao. Chương này mở rộng việc chia tile và lập lịch operator từ một card ra nhiều card: trước tiên chia ma trận và trạng thái across các card, rồi suy ra giao tiếp sinh ra, sau đó ánh xạ giao tiếp đó vào các kết nối thực tế, và cuối cùng quyết định một instance dùng bao nhiêu card cùng bao nhiêu instance triển khai song song. Phần cứng trong chương này là máy chủ tám card HGX H100 phổ biến, và hai mô hình được dùng xuyên suốt các suy luận: Qwen3-235B-A22B, trọng lượng lấp đầy toàn bộ một máy chủ, dùng để minh họa dung lượng, phân công chuyên trách chuyên gia (expert) và giao tiếp MoE; cùng Qwen3-32B, trọng lượng vừa một card duy nhất nhưng KV ngữ cảnh dài buộc mô hình phải trải across các card, dùng để so sánh số card song song tensor (tensor parallelism) với số lượng instance. Các mô hình và hệ thống khác được dùng để minh họa cách những thay đổi cấu trúc ảnh hưởng đến thiết kế.

6.1 Từ một card đến nhiều card

6.1.1 Triển khai độc lập và phối hợp qua tám card

Instance suy luận được giới thiệu ở Chương 1 có thể chiếm một card duy nhất, hoặc phân phối mô hình ra nhiều card. Supernode cung cấp tài nguyên vật lý cho sự phối hợp thường xuyên trong một instance: các accelerator bên trong nó được kết nối chặt chẽ qua interconnect băng thông cao, độ trễ thấp.

Một instance suy luận mô tả mô hình được triển khai và thực thi ra sao; một supernode mô tả các accelerator được kết nối với nhau như thế nào. Một supernode tám card có thể chứa tám instance một card, hoặc hai instance bốn card. Ở trường hợp trước, tám yêu cầu độc lập với nhau; ở trường hợp sau, mỗi yêu cầu cần trao đổi kết quả trung gian giữa bốn card. Máy chủ và rack là đơn vị lắp đặt và cấp nguồn; các card của cùng một instance có thể cùng nằm trong một máy chủ, hoặc trải across nhiều máy chủ.

Hình 6-1: Ba cách gộp instance trên cùng tám card. Mỗi hộp ngoài cùng là một instance suy luận độc lập; các đường bên trong thể hiện sự phối hợp cần có để hoàn thành một yêu cầu. Khi mỗi instance xử lý mỗi lần một yêu cầu, ba phương án triển khai có thể xử lý lần lượt tám, hai và một yêu cầu đồng thời.

Việc dùng nhiều card hơn thường do ba nhu cầu thúc đẩy: trọng lượng mô hình vượt quá bộ nhớ của một card, buộc phải phân phối lưu trữ; một yêu cầu thực thi quá chậm, buộc phải chia phép tính ra nhiều card; hoặc quá nhiều yêu cầu đến cùng lúc, cần thêm nhiều instance có thể xử lý yêu cầu độc lập. Ba nhu cầu này tương ứng lần lượt với các mục tiêu dung lượng, độ trễ và thông lượng.

6.1.2 Ví dụ xuyên suốt: Dung lượng và thời gian từng bước của Qwen3-235B-A22B

Ví dụ xuyên suốt của chương này là: chạy Qwen3-235B-A22B trên một máy chủ HGX H100 duy nhất, trong đó mô hình đã xử lý xong đầu vào, bộ đệm chứa 8192 token ngữ cảnh, và quá trình sinh (generation) sắp tiếp tục. HGX H100 là một máy chủ tám card phổ biến: mỗi trong tám card H100 SXM của nó có 80 GB HBM với băng thông đỉnh 3350 GB/s, và độ đậm ma trận nhân (BF16) đỉnh 989.4 TFLOP/s; tám card được kết nối với nhau qua NVSwitch (chip chuyển mạch tổ chức mạng chuyển mạch NVLink) bằng NVLink thế hệ thứ tư, ở 450 GB/s mỗi chiều mỗi card; mỗi card còn được trang bị thêm NIC ConnectX-7 400 Gbit/s (50 GB/s) để kết nối với các máy chủ khác.

Thiết kế đa card trước tiên phải xác định dữ liệu nằm ở đâu. Trọng lượng WiW_i, trạng thái KV KiK_i, kích hoạt AiA_i và phần workspace còn lại UiU_i được giữ đồng thời trên card ii phải thỏa mãn

Wi+Ki+Ai+Ui≤Ci.(6-1)W_i+K_i+A_i+U_i\le C_i. \tag{6-1}

Ở đây CiC_i là bộ nhớ khả dụng cho nhiệm vụ trên card đó. Trọng lượng do mô hình cố định, KV tăng theo ngữ cảnh của phiên, còn kích hoạt và workspace thay đổi theo scheme thực thi. Bốn mục này dùng chung bộ nhớ vật lý của card tại bất kỳ thời điểm nào.

Quy mô mô hình của Qwen3-235B-A22B. Mô hình lưu trọng lượng và KV ở BF16, có 94 lớp và chiều ẩn (hidden dimension) 4096; mỗi lớp có 64 query head và 4 KV head, với chiều head 128. FFN gồm 128 expert được định tuyến (routed expert), trong đó 8 expert được chọn cho mỗi token, và mỗi expert có chiều trung gian 1536. GB và TB dùng đơn vị thập phân, còn MiB và GiB dùng nhị phân.

Bắt đầu với dung lượng. Trọng lượng BF16 của toàn mô hình tổng cộng khoảng 470.2 GB. Mỗi token ngữ cảnh cần lưu K và V cho từng lớp, nên KV của toàn mô hình trên mỗi token là

2×94×4×128×2=188 KiB.2\times94\times4\times128\times2=188\ \mathrm{KiB}.

KV của 8192 token tổng cộng khoảng 1.58 GB. Dự phòng 2 GiB, tức khoảng 2.15 GB, cho kích hoạt và workspace còn lại, tổng nhu cầu một card là khoảng 473.9 GB — gần sáu lần dung lượng của một H100 đơn lẻ.

Để vừa mô hình, những dữ liệu này phải chia ra tám card: các ma trận trọng lượng được chia tám phần theo hàng hoặc cột, mỗi card giữ một phần; workspace vẫn giữ một bản trên mỗi card. KV được chia theo attention head, nhưng mô hình này chỉ có 4 KV head: với tám card, cứ hai card dùng chung một KV head, mỗi card giữ bản của riêng mình, nên mỗi card giữ một phần tư tổng KV. Cách chia này bảo toàn tính đúng đắn của phép tính được trình bày ở Mục 6.2.2. Nhu cầu bộ nhớ trên mỗi card trở thành:

Cách đặtTrọng lượngKVDự phòng kích hoạt & workspaceTổng
Một card470.2 GB1.58 GB2.15 GB473.9 GB
Mỗi card trong tám card58.96 GB0.39 GB2.15 GB61.50 GB

Mỗi card cần khoảng 61.50 GB, thấp hơn 80 GB của H100; cả máy chủ tổng cộng khoảng 492.0 GB, còn lại khoảng 148 GB trên tổng 640 GB. Trọng lượng của mỗi card nhỉnh hơn một phần tám của 470.2 GB một chút vì tham số chuẩn hóa (normalization) và bộ định tuyến (router) đều có một bản trên mỗi card. Khoảng 18.5 GB còn lại trên mỗi card có thể chứa thêm nhiều phiên: với cách chia này, một phiên 8192 token chiếm 0.39 GB mỗi card, nên máy chủ có thể chứa tối đa 47 phiên như vậy đồng thời. Việc phân phối lưu trữ làm giảm nhu cầu bộ nhớ trên mỗi card; tổng dấu chân bộ nhớ của instance vẫn là tổng các dấu chân trên từng card.

Hình 6-2: Nhu cầu bộ nhớ trên mỗi card của instance một card so với instance chia ra tám card. Một card cần khoảng 473.9 GB, vượt xa 80 GB của H100 (đường nét đứt); chia ra tám card, mỗi card cần khoảng 61.50 GB. Workspace 2 GiB được dự phòng riêng trên từng card.

Tiếp theo, xét thời gian thực thi. Dung lượng bộ nhớ quyết định dữ liệu có được giữ không; khối lượng truy cập quyết định bao nhiêu dữ liệu phải đọc hoặc ghi mỗi lần thực thi. Lấy phép tính expert của một lớp làm ví dụ: khi sinh ra một token, bộ định tuyến chọn 8 expert, mỗi expert có ba ma trận, tổng trọng lượng của chúng là 8×3×4096×1536×2=2888\times3\times4096\times1536\times2=288 MiB, tất cả đều phải đọc một lần từ HBM. Ở 3350 GB/s, việc đọc này mất khoảng 90.1 μs; phép nhân ma trận gồm khoảng 302 triệu FLOP, ở 989.4 TFLOP/s chỉ mất khoảng 0.31 μs. Thời gian đọc trọng lượng vượt thời gian tính toán hơn hai bậc độ lớn, nên muốn rút ngắn thời gian của lời gọi này trước tiên phải giảm lượng trọng lượng đọc trên mỗi card. Việc sinh một token cho toàn mô hình đọc khoảng 43.1 GB trọng lượng và 1.58 GB KV; nếu một card duy nhất đọc tất cả, mất khoảng 13.3 ms; chia đều ra tám card như trên, mỗi card đọc khoảng 5.79 GB, mất khoảng 1.73 ms.

Khi phép tính và truy cập bộ nhớ của một operator chồng lấn lên nhau, thời gian thực thi của nó có thể ước tính là

Top=max⁡(FP,VBHBM).(6-2)T_{\mathrm{op}}=\max\left(\frac{F}{P},\frac{V}{B_{\mathrm{HBM}}}\right). \tag{6-2}

FF là độ phức tạp tính toán, PP là hiệu năng nhân ma trận, và VV là khối lượng truy cập HBM tính bằng byte. Tính toán và truy cập bộ nhớ diễn ra đồng thời, và thời gian thực thi do phía nào lâu hơn quyết định. Operator phía sau phải chờ đầu ra của operator phía trước, nên thời gian của các đoạn thực thi tuần tự phải cộng lại. Phương trình (6-2) chính là mô hình Roofline ở Mục 4.8.1. Dùng định nghĩa ở Mục 1.2.2, MFU của lời gọi một token không thể vượt 0.31/90.10.31/90.1, tức khoảng 0.3%. Đây là trần do phần cứng áp đặt ở batch size 1, độc lập với chất lượng hiện thực hóa; các chiến lược song song khác nhau được thảo luận trong chương này đều là những nỗ lực tổ chức lại việc đọc trọng lượng và tái sử dụng trong ràng buộc này. Mục 6.2 sẽ giải thích cách phân phối trọng lượng và phép tính của lớp này ra nhiều card, và Mục 6.4 sẽ tính thời gian các card trao đổi kết quả.

6.1.3 Yêu cầu tài nguyên khác nhau của prefill, decode và huấn luyện

Hai con số 90.1 μs và 0.31 μs ở Mục 6.1.2 tương ứng với một lời gọi một token. Nếu xử lý nhiều token hơn mỗi lần, cùng bộ trọng lượng đó có thể phục vụ nhiều hàng đầu vào, và tỷ lệ giữa thời gian tính toán với thời gian đọc cũng thay đổi. Khi một lời gọi xử lý mm token mỗi lần, độ phức tạp tính toán của một expert tăng theo mm, trong khi trọng lượng của expert được chọn có thể tái sử dụng qua các token đó. Đổi ví dụ trên từ một token sang prefill 8192 token, cả 128 expert đều được chọn, và khối lượng đọc trọng lượng expert của một lớp tăng lên 4.5 GiB, mất khoảng 1.44 ms ở 3350 GB/s; phép tính ma trận tăng lên khoảng 2.47 TFLOP, mất khoảng 2.50 ms ở 989.4 TFLOP/s, vượt thời gian đọc. Ở batch size lớn, một bộ trọng lượng phục vụ nhiều hàng đầu vào, và ràng buộc chính đối với thời gian thực thi chuyển từ đọc trọng lượng sang tính toán ma trận.

Giao tiếp cũng thay đổi theo hình dạng. Tensor ẩn BF16 là m×4096m\times4096; một token chiếm 8 KiB, còn 8192 token chiếm 64 MiB. Hai lời gọi đi qua cùng số lớp với cùng số lần trao đổi, nhưng khối lượng dữ liệu truyền mỗi lần trao đổi chênh nhau hệ số 8192. Việc truyền khối lượng dữ liệu nhỏ nhạy cảm hơn với chi phí khởi tạo, trong khi truyền khối lượng lớn phụ thuộc nhiều hơn vào băng thông liên tục.

Decode còn mang một phụ thuộc thời gian: token đầu ra hiện tại quyết định đầu vào của bước tiếp theo. Một phiên duy nhất phải tiến từng bước một; tuy nhiên, nhiều phiên có thể cùng cung cấp các đầu vào đã sẵn sàng. Nhiều phiên hơn nghĩa là nhiều cơ hội tái sử dụng trọng lượng hơn, nhưng cũng có nghĩa là dung lượng KV và khối lượng đọc lớn hơn, do đó làm thay đổi đồng thời thời gian tính toán, thời gian truy cập bộ nhớ và thời gian xếp hàng.

Huấn luyện còn thực hiện lan truyền ngược (backpropagation) sau lượt truyền xuôi, tính gradient đầu vào và gradient trọng lượng rồi dùng gradient để cập nhật tham số; kích hoạt của lượt truyền xuôi phải được giữ lại cho đến khi lượt truyền ngược sử dụng xong. Song song đa card do đó cũng phải đồng bộ hóa (synchronization) gradient và giữ lại nhiều trạng thái hơn. Chương này trước tiên trình bày cách chia mô hình và trao đổi dữ liệu sinh ra từ đó; Chương 10 thảo luận cách các thao tác này ghép thành một bước huấn luyện hoàn chỉnh.

6.1.4 Tổng quan các chiến lược song song: Chia theo chiều nào

Cả ba nhu cầu ở Mục 6.1.1 đều đòi hỏi phân phối công việc ra nhiều card, nhưng cách chia trong từng trường hợp lại khác nhau. Cách chia phụ thuộc vào dữ liệu mà mô hình xử lý và vào chính cấu trúc của mô hình. Kích hoạt đầu vào của một lớp có ba chiều: số mẫu được xử lý mỗi lần, BB — với suy luận, đây là số yêu cầu được xử lý đồng thời; số vị trí chuỗi (sequence position) trong mỗi mẫu, SS; và số đặc trưng ẩn mỗi vị trí, HH. Nhân ma trận ở Chương 5 đã gộp BB và SS thành số hàng MM, nhưng attention phải phân biệt các vị trí khác nhau trong cùng một chuỗi, nên ở đây hai chiều này được giữ tách riêng. Bản thân mô hình có thêm hai cấu trúc có thể chia: các lớp LL, và, với mô hình MoE, tập expert EE mỗi lớp. Hình 6-3 vẽ cả năm chiều này cùng nhau và đánh dấu nơi mỗi trong sáu chiến lược song song phổ biến thực hiện sự chia.

Hình 6-3: Ở bên trái, kích hoạt đầu vào của một lớp, với ba chiều tương ứng với nơi parallelism dữ liệu, parallelism chuỗi / parallelism ngữ cảnh và parallelism tensor mỗi lược chia; ở bên phải, cấu trúc mô hình, nơi parallelism pipeline chia giữa các lớp và parallelism expert chia giữa các expert của cùng một lớp. Các đường nét đứt dày chỉ vị trí chia, không phải hướng dữ liệu chảy.

Theo chiều chia, sáu chiến lược song song được tóm tắt trong bảng dưới đây. “Trao đổi” trong bảng chỉ dữ liệu phải truyền giữa các card; từng tiểu mục của Mục 6.2 sẽ tính kích thước của chúng lần lượt.

Chiến lược song songChiều chiaMỗi card lưu và tính gìPhải trao đổi gì giữa các card
Parallelism dữ liệu (DP)Mẫu BBMột bản sao mô hình hoàn chỉnh, các mẫu khác nhauKhông trao đổi khi suy luận; khi huấn luyện, gradient từ mỗi card được tổng hợp
Parallelism tensor (TP)Đặc trưng HH: cột hoặc hàng của trọng lượng, attention headPhần của ma trận cùng một lớpCác mảnh đầu ra được gom khi cần; tổng riêng phần phải được cộng
Parallelism chuỗi (SP)Vị trí chuỗi SS cho operator theo tokenMột đoạn vị trí trong cùng chuỗi, với các operator nàyĐược gom across toàn bộ vị trí trước khi vào nhân ma trận; tổng riêng phần được cộng rồi chia lại theo vị trí
Parallelism ngữ cảnh (CP)Vị trí chuỗi SS cho attentionQ, K, V cho một đoạn vị trí trong cùng chuỗiK, V từ xa, hoặc thống kê của attention từng đoạn
Parallelism pipeline (PP)Các lớp LLMột dải lớp liên tụcKích hoạt được trao giữa các giai đoạn liền kề; khi huấn luyện, gradient được trao theo chiều ngược lại
Parallelism expert (EP)Các expert EEMột tập con expertToken được gửi tới card giữ expert được chọn, rồi kết quả được gửi về

Bảng hàm ý một sự phân biệt xuyên suốt cả chương. Khi chia theo mẫu, vị trí chuỗi, lớp hoặc expert, mỗi card có được kết quả hoàn chỉnh cho dữ liệu hoặc lớp khác nhau, chỉ cần gom hoặc trao đổi lại khi cần; khi chia theo đặc trưng, mỗi card thường chỉ có được một đóng góp riêng phần cho cùng một đầu ra, và những tổng riêng phần này phải được cộng trước khi kết quả có thể dùng được. Mục 5.2.4 đã phân biệt cách chia theo chiều đầu ra với cách chia theo chiều reduce trong cùng một card; sự phân biệt vẫn như vậy across các card, chỉ có điều việc cộng tổng riêng phần giờ đi qua interconnect giữa các card.

Các chiến lược này không loại trừ nhau. Parallelism chuỗi thường dùng cùng một nhóm card với parallelism tensor, và parallelism expert có thể chia sẻ cùng một lô card với parallelism dữ liệu ở phần attention; parallelism pipeline chia một đồ thị tính toán có phụ thuộc tuần tự, chứ không phải một chiều bổ sung nào được tách ra khỏi ma trận. Mục 6.3 sẽ giải thích cách kết hợp các chiến lược này và đánh số từng card.

Thí nghiệm 6-1 · Mở rộng: độ dài ngữ cảnh và số hàng đầu vào ảnh hưởng thế nào tới dung lượng và nút thắt thực thi

(a) Tìm dung lượng KV cho một yêu cầu của Qwen3-235B-A22B ở ngữ cảnh 4096, 8192 và 16384 token.

(b) Dùng cách chia tám card của mục này với 2 GiB workspace dự phòng mỗi card, tìm số lượng phiên 32768 token tối đa mà một máy chủ HGX H100 có thể chứa đồng thời; giá trị trọng lượng chính xác được nêu trong chú thích nguồn.

(c) Với 1, 64 và 8192 token, tính khối lượng tính toán ma trận cho phép tính expert của một lớp và thời gian đọc trọng lượng của các expert được chọn (với 64 token, ước tính số expert được chọn bằng phương trình (6-8) ở Mục 6.3.2), và dùng tham số của H100, xác định thời gian thực thi bị hạn chế chủ yếu bởi tính toán hay bởi truy cập bộ nhớ.

(d) Giảm một nửa băng thông HBM và so sánh mức tăng độ trễ lời gọi qua ba số lượng token trên.

6.2 Sáu chiến lược song song

Mục này giới thiệu tuần tự sáu chiến lược song song, theo thứ tự của Hình 6-3. Để làm rõ sự phân công, mỗi tiểu mục trước tiên minh họa với hai card rồi mới tổng quát hóa lên nhiều card hơn.

6.2.1 Parallelism dữ liệu: Nhân bản mô hình, chia mẫu

Parallelism dữ liệu (data parallelism, DP) để mỗi card giữ một bản sao hoàn chỉnh của mô hình, mỗi card xử lý các mẫu khác nhau. Trong Hình 6-4, hai card lần lượt xử lý bốn mẫu đầu và bốn mẫu cuối của batch, mỗi card tạo ra phần đầu ra của riêng mình.

Hình 6-4: Hai card mỗi card giữ một bản sao hoàn chỉnh của mô hình và xử lý các mẫu khác nhau. Khi suy luận, hai card không chờ nhau; khi huấn luyện, gradient từ hai card trước tiên phải được tổng hợp trước khi mỗi card cập nhật bản sao tham số của riêng mình.

Parallelism dữ liệu khi suy luận đơn giản là triển khai nhiều instance. Khi mô hình vừa một card và có nhiều yêu cầu độc lập, cách trực tiếp nhất là gán các yêu cầu khác nhau cho các instance khác nhau. Mỗi instance giữ trọng lượng và trạng thái phiên của riêng mình, và tạo ra đầu ra một cách độc lập. Nếu một card có thể xử lý rr yêu cầu mỗi giây, tám instance một card, với nguồn yêu cầu liên tục, có thể xử lý tổng cộng 8r8r yêu cầu mỗi giây.

Gộp tám card thành một instance duy nhất, giả sử tốc độ tăng tốc cho một yêu cầu là S(8)S(8); instance này khi đó có thể xử lý S(8)rS(8)r yêu cầu mỗi giây. Cả hai cách triển khai đều dùng tám card, và tỷ số thông lượng là S(8)/8S(8)/8: chỉ khi một yêu cầu được tăng tốc đúng hệ số tám thì hai thông lượng mới bằng nhau. Ngay khi có giao tiếp hoặc công việc không thể song song hóa, instance phối hợp đang đánh đổi một phần tổng thông lượng để lấy thời gian một yêu cầu ngắn hơn.

Parallelism dữ liệu khi huấn luyện cũng đặt cùng một bộ tham số lên nhiều card, nhưng gradient từ tất cả các card cùng quyết định lần cập nhật tiếp theo. Ví dụ, nếu hai card mỗi card xử lý bốn mẫu và tính gradient trung bình của riêng mình là g0,g1g_0,g_1, gradient trung bình trên cả tám mẫu là (g0+g1)/2(g_0+g_1)/2. Mỗi card tính trên một nửa số mẫu, rồi gradient được tổng hợp lại để hoàn thành một lần cập nhật. Giữa các instance suy luận không có phụ thuộc như vậy.

6.2.2 Parallelism tensor: Chia các ma trận trong một lớp

Nhiều instance có thể xử lý nhiều yêu cầu đồng thời hơn, nhưng điều này không rút ngắn thời gian thực thi một yêu cầu trên một card, cũng không giúp ích cho những phiên mà một card không thể chứa được. Để hai card cùng xử lý một yêu cầu, phép tính và trạng thái trong một lớp phải được chia. Parallelism tensor (tensor parallelism, TP) phân phối các ma trận trong cùng một lớp ra nhiều card, mỗi card tính một phần trước khi trao đổi kết quả. Hình 6-5 đánh dấu hai điểm chia trong một lớp.

Hình 6-5: Attention được chia theo head ra hai card, và mạng feedforward được chia theo chiều trung gian ra hai card; phép chiếu cuối ở cả hai điểm chỉ tạo ra một tổng riêng phần, mỗi lần cần một AllReduce để cộng các tổng riêng phần từ hai card. m là số token được xử lý mỗi lần, h là chiều ẩn.

Ngữ cảnh dài buộc mô hình dense trải ra nhiều card. Mô hình dense Qwen3-32B có trọng lượng BF16 tổng cộng khoảng 65.52 GB, nằm vừa trong một H100 80 GB. Mô hình hỗ trợ nguyên bản ngữ cảnh 32K token, có thể mở rộng đến 128K qua YaRN, phương pháp ngoại suy mã hóa vị trí lên gấp bốn lần. KV của mỗi token là 2×64×8×128×2=2562\times64\times8\times128\times2=256 KiB, nên một phiên 128K duy nhất cần lưu khoảng 34.36 GB. Trong triển khai một card, trọng lượng, KV của một phiên 128K và workspace 2 GiB cùng tổng cộng khoảng 102.03 GB, vượt 80 GB; chia ra hai card, mỗi card chứa khoảng 52.09 GB, đủ cho hai phiên như vậy; chia ra bốn card, mỗi card chứa khoảng 27.12 GB, đủ cho bảy; chia ra tám card, đủ cho mười sáu. Ở đây parallelism tensor được áp dụng chủ yếu vì dung lượng: TP1 (số sau TP chỉ số card song song tensor; TP1 là một card) thậm chí không thể chứa nổi một phiên 128K.

Nhưng một số mô hình áp dụng cơ chế attention mới hơn giúp giảm nhu cầu lưu trữ KV khi ngữ cảnh dài. Dung lượng KV được quyết định bởi thiết kế attention: số lượng lớp, số KV head, chiều head, và liệu mọi lớp có lưu KV hay không. Bảng dưới đây so sánh ba mô hình quy mô tương tự: Qwen3-32B dạng dense; mô hình MoE Qwen3-30B-A3B cùng thế hệ, vẫn dùng GQA thông thường, có 48 lớp, 4 KV head và chiều head 128; và mô hình MoE Qwen3.6-35B-A3B dùng attention lai (hybrid attention) — trong 40 lớp của nó chỉ 10 lớp là full attention, mỗi lớp 2 KV head và chiều head 256, còn 30 lớp còn lại dùng linear attention, chỉ lưu một trạng thái hồi quy (recurrent state) kích thước cố định.

Hạng mụcQwen3-32BQwen3-30B-A3BQwen3.6-35B-A3B
Trọng lượng BF16 thường trú65.52 GB61.06 GB69.32 GB
KV mỗi token256 KiB96 KiB20 KiB (chỉ 10 lớp full attention)
Trạng thái cố định mỗi yêu cầu——62.9 MB trạng thái hồi quy (FP32) + 2.0 MB trạng thái convolution
Trạng thái cho một yêu cầu 128K34.36 GB12.88 GB2.75 GB
Đọc trọng lượng mỗi bước (batch 1, ngữ cảnh 32K)63.97 GB6.08 GB5.89 GB
Đọc trọng lượng mỗi bước (batch 64, ngữ cảnh 32K)63.97 GB60.44 GB68.30 GB
Tính toán ma trận mỗi bước (batch 64, ngữ cảnh 32K)8.49 TFLOP2.04 TFLOP0.73 TFLOP
Đọc trạng thái mỗi bước (batch 64, ngữ cảnh 32K)549.8 GB206.2 GB47.1 GB
Yêu cầu 128K/32K một H100 chứa được0/11/53/11
Yêu cầu 128K/32K hai H100 chứa được2/107/2931/117

Bảng này minh họa ba điểm. Thứ nhất, ở batch size 1, hai mô hình MoE mỗi mô hình chỉ đọc khoảng một phần mười trọng lượng mỗi bước; ở batch size 64, các expert được chọn trong 64 token phủ gần hết tập expert, nên lượng đọc trọng lượng quay về 60–68 GB, tương đương với 64 GB của mô hình dense. Thứ hai, khối lượng tính toán ma trận luôn chỉ bằng 1/12 đến 1/4 so với mô hình dense — một lợi thế MoE giữ suốt cả quá trình. Thứ ba, với ngữ cảnh dài và batch lớn, đọc trạng thái trở thành phần chiếm ưu thế trong mỗi bước: ở 3350 GB/s, với batch 64 và ngữ cảnh 32K, đọc trạng thái mất khoảng lần lượt 164, 62 và 14 ms cho ba mô hình, trong khi đọc trọng lượng chỉ mất 18–20 ms. Khoảng cách này đến từ thiết kế attention, không phải từ MoE: Qwen3-30B-A3B cũng là MoE, vậy mà nó vẫn lưu 96 KiB KV cho mỗi token.

Hình 6-6: Bảng trái thể hiện trạng thái của một yêu cầu ở ngữ cảnh 32K, 128K và 256K; Qwen3-32B và Qwen3-30B-A3B có trần ngữ cảnh 128K. Bảng phải thể hiện thời gian đọc trọng lượng và trạng thái cho một bước decode ở batch 64, ngữ cảnh 32K, tính theo 3350 GB/s của H100. Lượng đọc trọng lượng của ba mô hình tương tự nhau, còn lượng đọc trạng thái chênh nhau hơn mười lần.

Dung lượng vì vậy cũng khác nhau. Với 2 GiB workspace dự phòng mỗi card, một H100 duy nhất lần lượt chứa được 0, 1 và 3 yêu cầu 128K; hai H100 chứa được 2, 7 và 31. Qwen3.6-35B-A3B hỗ trợ nguyên bản 262.144 token, và trạng thái của một yêu cầu như vậy chỉ khoảng 5.43 GB. Vậy việc một dịch vụ hạng 30B có cần TP đa card ở ngữ cảnh 128K hay không phụ thuộc chủ yếu vào thiết kế attention, chứ không phải ở việc mô hình là dense hay MoE. DeepSeek V4-Flash và các mô hình tương tự còn nén KV sâu hơn nữa; Mục 2.6.1 đã so sánh trạng thái và tính toán của năm mô hình ở ngữ cảnh 8K, 200K và 1M, ở đây không mở rộng thêm.

Quay lại hai điểm chia trong một lớp được đánh dấu ở Hình 6-5: bước cuối ở cả hai điểm chỉ tạo ra một tổng riêng phần, đòi hỏi một AllReduce để cộng các tổng riêng phần across các card và đưa đến cho mọi card kết quả tổng. Qwen3-32B làm việc này hai lần mỗi lớp, 128 lần trên 64 lớp — một con số được dùng lại nhiều lần về sau khi tính thời gian thực thi. Để hiểu vì sao một kiểu chia chỉ cần phép nối (concatenation) còn kiểu kia cần phép cộng, hãy xem một phép nhân ma trận tối giản. Khi hai card cùng hoàn thành nó, trước tiên quyết định mỗi card tính gì: hai card có thể tính các phần tử khác nhau của đầu ra, hoặc mỗi card tính một phần của cùng một đầu ra. Kết quả trước cần phép nối, kết quả sau cần phép cộng.

Ví dụ dưới đây minh họa đầy đủ cả hai kiểu chia. Đầu vào là x=[2,3]x=[2,3], ma trận trọng lượng là W=[1425]W=\begin{bmatrix}1&4\\2&5\end{bmatrix}, và đầu ra là xW=[8,23]xW=[8,23]. Chia theo cột của ma trận trọng lượng — tức phân phối các đặc trưng đầu ra ra các card — card 0 giữ cột thứ nhất và tạo ra phần tử đầu ra thứ nhất, 8; card 1 giữ cột thứ hai và tạo ra phần tử thứ hai, 23. Nối hai phần tử cạnh nhau cho ra đầu ra hoàn chỉnh.

Hình 6-7: Khi chia theo cột của ma trận trọng lượng, mỗi card dùng toàn bộ đầu vào và tính các phần tử đầu ra khác nhau. Ký hiệu chuyển vị T trong các ô cho biết các số được liệt kê ngang trong ngoặc được coi là một vector cột.

Còn nếu chia theo hàng của ma trận trọng lượng — tức phân phối các đặc trưng đầu vào của cùng một token ra các card — card 0 nhân đầu vào 2 với hàng thứ nhất, cho [2,8][2,8]; card 1 nhân đầu vào 3 với hàng thứ hai, cho [6,15][6,15]. Mỗi card thu được một vector hai phần tử, nhưng mỗi vector chỉ chứa đóng góp của một hàng trọng lượng; chỉ sau khi cộng các vị trí tương ứng mới có được đầu ra hoàn chỉnh [8,23][8,23].

Hình 6-8: Khi chia theo hàng của ma trận trọng lượng, hai card tạo ra các tổng riêng phần có cùng hình dạng với đầu ra. Cộng các vị trí tương ứng khôi phục được kết quả của phép nhân hoàn chỉnh.

Cả hai kiểu chia có thể được ghép nối tiếp nhau trong FFN, như phần dưới của Hình 6-5. Ở đây ta dùng SwiGLU được mô tả ở Chương 2: đầu vào được đưa vào một gate projection và một up projection, kết quả gate đi qua hàm kích hoạt SiLU, được nhân theo phần tử với nhánh còn lại, và cuối cùng đi qua down projection. Giả sử lời gọi này xử lý mm token mỗi lần, với chiều ẩn hh và chiều trung gian ff. Đầu vào là X∈Rm×hX\in\mathbb{R}^{m\times h}, các up projection là Wg,Wu∈Rh×fW_g,W_u\in\mathbb{R}^{h\times f}, và down projection là Wd∈Rf×hW_d\in\mathbb{R}^{f\times h}:

Y=[SiLU⁡(XWg)⊙(XWu)]Wd.Y=\left[\operatorname{SiLU}(XW_g)\odot(XW_u)\right]W_d.

Chia chiều trung gian ff làm hai nửa. Card 0 giữ nửa trái các cột của cả hai ma trận up projection và nửa trên các hàng của ma trận down projection; card 1 giữ nửa phải các cột của cả hai ma trận up projection và nửa dưới các hàng của ma trận down projection. Cả hai card đều giữ đầu vào hoàn chỉnh XX và mỗi card tạo ra kích hoạt trung gian của riêng mình là Z0,Z1Z_0,Z_1. SiLU và phép nhân theo phần tử thực thi trên từng phần tử, nên mỗi card có thể xử lý trực tiếp nửa của mình.

Down projection nối lại theo cùng một chiều trung gian:

Y=[Z0 Z1][Wd,0Wd,1]=Z0Wd,0+Z1Wd,1.(6-3)Y=[Z_0\ Z_1]\begin{bmatrix}W_{d,0}\\W_{d,1}\end{bmatrix} =Z_0W_{d,0}+Z_1W_{d,1}. \tag{6-3}

Cả hai tích ở vế phải đều có hình dạng m×hm\times h, mỗi tích chỉ chứa đóng góp của một nửa các thành phần của chiều trung gian; chỉ sau khi cộng chúng lại ta mới có được đầu vào cho lớp tiếp theo.

Hình 6-9: Chia SwiGLU ra hai card. Up projection chia các đặc trưng đầu ra theo cột của ma trận trọng lượng, với phép toán theo phần tử vẫn nằm cục bộ; down projection chia các đặc trưng đầu vào theo hàng của ma trận trọng lượng. Cả hai bước đều giữ tất cả m token; cái được chia là chiều đặc trưng của mỗi token. Kích hoạt trung gian của mỗi card là m\times(f/2), tổng riêng phần đầu ra vẫn là m\times h, và bước cuối cộng theo phần tử.

Nếu cả hai card đều cần kết quả hoàn chỉnh, một AllReduce được thực hiện. Nếu operator tiếp theo có thể tiếp tục làm việc với một mảnh, một ReduceScatter được thực hiện thay vào đó: cộng trước, rồi để lại các đoạn khác nhau của kết quả đã cộng trên các card khác nhau. Để khôi phục dữ liệu hoàn chỉnh từ các mảnh, một AllGather được thực hiện, nối các đoạn mà mỗi card đang giữ.

Ví dụ: phép chia bốn chiều giảm được bao nhiêu lượng đọc trọng lượng và thêm bao nhiêu giao tiếp? Lấy h=5120,f=25600h=5120,f=25600 của Qwen3-32B, chia đều chiều trung gian ra bốn card.

Lời giải: Up projection của mỗi card là 5120×64005120\times6400 và down projection là 6400×51206400\times5120. Ba ma trận cùng chiếm 187.5 MiB, một phần tư của 750 MiB ban đầu. Ở 3350 GB/s, thời gian đọc một token giảm từ khoảng 234.8 μs xuống 58.7 μs, tiết kiệm khoảng 176.1 μs mỗi card nhờ đọc ít hơn 562.5 MiB. Cái giá phải trả là các tổng riêng phần 10 KiB của bốn card phải được cộng lại với nhau. Mục 6.4 sẽ dùng một thuật toán cụ thể để suy ra thời gian cho phép tổng hợp này.

Attention cũng có thể chia theo head: các projection Q, K, V chỉ tạo ra những head được gán cho card này, và mỗi card tính toán độc lập attention cho các head này; output projection ánh xạ kết quả của từng head về lại chiều ẩn, và mỗi card vẫn chỉ thu được một tổng riêng phần, phải được cộng mới khôi phục được đầu ra hoàn chỉnh. Do đó Qwen3-32B thực hiện phép reduce cho đầu ra attention và đầu ra FFN mỗi lớp một lần, 128 lần trên 64 lớp. Word embedding được chia theo từ vựng, và phép projection đầu ra từ vựng cũng chia theo cách tương tự.

Các head không thể chia nhỏ hơn nữa; chúng là đơn vị phân bổ tối thiểu. Qwen3-32B có 8 KV head, nên với TP8 mỗi card nhận một head; với TP16, các query head dùng chung cùng một KV head bị chia ra hai card, và cả hai card đều phải lưu trạng thái của KV head đó. Ở ngữ cảnh 128K, trạng thái của mỗi KV head chiếm 4 GiB, tổng cộng 32 GiB trên tám card và 64 GiB trên mười sáu card. Qwen3-235B-A22B chỉ có 4 KV head, và cách chia tám card ở Mục 6.1.2 đã khiến mỗi KV head được lưu một bản trên mỗi của hai card. Một khi số card TP vượt quá số KV head, tăng thêm chỉ nhân bản KV.

Chương này dùng “số instance” để chỉ số lượng dịch vụ suy luận độc lập, và pp để chỉ số card TP của một instance. Với tổng cộng tám card, số instance là 8/p8/p. Các mục sau trước tiên suy ra thời gian T(p)T(p) để một instance sinh ra một token, rồi chuyển giá trị này thành thời gian hoàn thành cho một batch yêu cầu.

Suy ra thời gian của một bước decode hoàn chỉnh từ phép tính một lớp. Lấy một phiên 128K của Qwen3-32B làm ví dụ. Trọng lượng của mỗi projection được đọc từ HBM mỗi bước một lần, KV cũ được đọc một lần, và một token mới được ghi. Trọng lượng BF16 của các projection attention là

2(2×5120×8192+2×5120×1024)=180 MiB.2\left(2\times5120\times8192+2\times5120\times1024\right)=180\ \mathrm{MiB}.

Ở đây hai số hạng 5120×81925120\times8192 tương ứng với Q và output projection, còn hai số hạng 5120×10245120\times1024 tương ứng với K và V projection. Mỗi lớp thêm 750 MiB trọng lượng FFN, tổng cộng 930 MiB. Với ngữ cảnh 131,064 token, KV đọc mỗi lớp khoảng 512 MiB. Từ vựng có 151936 mục, nên tổng trọng lượng output projection khoảng 1.56 GB. Tổng khối lượng truy cập HBM cho một bước đầy đủ có thể viết là

V(s)=64×930 MiB+256 KiB×(s+1)+151936×5120×2 bytes,(6-4)V(s)=64\times930\ \mathrm{MiB} +256\ \mathrm{KiB}\times(s+1) +151936\times5120\times2\ \mathrm{bytes}, \tag{6-4}

ss là độ dài ngữ cảnh trước khi bước này bắt đầu. Thay 131,064 vào được khoảng 98.32 GB, trong đó 63.97 GB là trọng lượng và 34.36 GB là KV. Đọc khối lượng này tại 3350 GB/s của H100 mất khoảng 29.35 ms; các phép toán ma trận cho cùng một bước đạt khoảng 0.34 TFLOP, ở 989.4 TFLOP/s chỉ mất khoảng 0.34 ms, nên cả thời gian thực thi attention và FFN trong từng lớp đều bị hạn chế bởi băng thông bộ nhớ. Với TP pp chiều (p≤8p\le8), trọng lượng và KV được chia đều ra các card, và phần thời gian này trở thành 29.35/p29.35/p ms. Chuẩn hóa, các phép toán theo phần tử và lấy mẫu chỉ đọc, ghi một vài vector ẩn, nên không được tính ở đây. Tính toán và reduce thực thi tuần tự, cho ra mô hình thời gian thực thi được dùng ở các mục sau:

T(p)=Tlocalp+128 TAR(p),Tlocal≈29.35 ms.(6-5)T(p)=\frac{T_{\mathrm{local}}}{p}+128\,T_{\mathrm{AR}}(p), \qquad T_{\mathrm{local}}\approx29.35\ \mathrm{ms}. \tag{6-5}

Ở đây TAR(p)T_{\mathrm{AR}}(p) là thời gian để pp card thực hiện một AllReduce. Phương trình (6-5) tách ảnh hưởng của việc tăng số card TP thành hai số hạng: thời gian thực thi cục bộ giảm khi số card tăng, còn thời gian giao tiếp phụ thuộc vào thuật toán và phương thức kết nối. Tăng gấp đôi số card từ pp lên 2p2p tiết kiệm Tlocal/(2p)T_{\mathrm{local}}/(2p) thời gian cục bộ. Vậy điều kiện để thêm card rút ngắn thời gian thực thi là

128[TAR(2p)−TAR(p)]<Tlocal2p.(6-6)128\left[T_{\mathrm{AR}}(2p)-T_{\mathrm{AR}}(p)\right] <\frac{T_{\mathrm{local}}}{2p}. \tag{6-6}

pp càng lớn, vế phải càng nhỏ. Ngay cả khi mỗi phép reduce chỉ thêm cùng một lượng thời gian nhỏ, chi phí tích lũy cuối cùng cũng sẽ bù lại phần giảm của thời gian thực thi cục bộ.

Với nhiều card hơn, một lớp tuyến tính cũng có thể chia đồng thời hai chiều của ma trận, sắp xếp các card thành các nhóm giao tiếp theo hàng và theo cột. Lấy projection [8192,4096]×[4096,12288][8192,4096]\times[4096,12288] làm ví dụ: chia đầu ra thành 16 mảnh đặt trên 16 card, và mỗi card ban đầu chỉ giữ một mảnh đầu vào 4 MiB và một mảnh trọng lượng 6 MiB. Sắp thành lưới 4×4, mỗi card phải thu thập các mảnh đầu vào của ba card còn lại trong hàng của nó, gửi 12 MiB, và thu thập các mảnh trọng lượng của ba card còn lại trong cột của nó, gửi 18 MiB. Chuyển sang lưới 2×8 cho 28 MiB và 6 MiB theo hai hướng tương ứng; chuyển sang 8×2 cho 4 MiB và 42 MiB. Khi các liên kết cả hai hướng độc lập và nhanh tương đương nhau, thời gian truyền do giá trị lớn hơn trong hai giá trị quyết định, nên 4×4 là nhanh nhất. MeshSlice tiếp tục chia tile theo bố cục này, dùng đường ống hóa việc thu thập và nhân ma trận; hệ thống suy luận Arctic thay vào đó đổi sự phân công giữa các giai đoạn thực thi khác nhau, và việc di trú trạng thái của nó được thảo luận ở Chương 9.

6.2.3 Parallelism chuỗi: Chia nhỏ các operator theo token dọc theo chuỗi

Parallelism tensor để mỗi card chỉ giữ một phần của ma trận, nhưng trong một lớp còn có các operator không thực hiện nhân ma trận, như LayerNorm, Dropout và phép cộng dư (residual). Các operator này làm việc theo từng token: kết quả của mỗi token chỉ phụ thuộc vào vector ẩn của chính nó. Parallelism chuỗi (sequence parallelism, SP) chia nhỏ các operator này theo vị trí chuỗi: mỗi card trong một nhóm TP chỉ xử lý một đoạn vị trí, và không còn giữ bản sao đầy đủ của các kích hoạt. Cuốn sách này theo định nghĩa phổ biến được Megatron, framework huấn luyện mô hình lớn, sử dụng.

Hình 6-10: LayerNorm và phép cộng dư chỉ dùng dữ liệu của token hiện tại, nên hai card mỗi card xử lý một nửa số vị trí; trước khi vào lớp tuyến tính song song cột, AllGather thu thập tất cả vị trí, và các tổng riêng phần từ lớp tuyến tính song song hàng được cộng rồi chia lại theo vị trí bằng ReduceScatter.

Lớp tuyến tính song song cột cần hàng đầu vào hoàn chỉnh, nên trước khi vào nó, AllGather thu thập mảnh chuỗi của từng card; sau khi lớp tuyến tính song song hàng tạo ra các tổng riêng phần, ReduceScatter vừa cộng vừa chia lại theo vị trí trong một bước. AllReduce tương đương với ReduceScatter kế tiếp AllGather; parallelism chuỗi chỉ đơn giản đặt hai nửa đó ở các ranh giới operator khác nhau, nên các operator theo token nằm giữa không còn cần mỗi card giữ bản sao đầy đủ của các kích hoạt.

Ví dụ, một kích hoạt BF16 [8192,4096][8192,4096] chiếm 64 MiB; nếu bốn card mỗi card giữ một mảnh [2048,4096][2048,4096] liên tục, mỗi card chỉ giữ 16 MiB, tổng cộng 64 MiB, còn nếu cả bốn card đều lưu tensor đầy đủ thì tổng là 256 MiB. Khoản tiết kiệm này chỉ xảy ra trong khoảng mà việc chia chuỗi được duy trì — không phải mọi kích hoạt và trọng lượng trong mô hình đều thu nhỏ đi bốn lần. Quan hệ giữa chiều reduce và chiều đầu ra vẫn như trong Hình 6-9; cái thay đổi chỉ là bố cục mà operator tiếp theo nhận được. Thí nghiệm kèm theo chứng minh cả hai đường dẫn FFN giữ nguyên chia nhỏ và gom lại trong JAX (một framework tính toán số học hỗ trợ vi phân tự động và thực thi biên dịch).

6.2.4 Parallelism ngữ cảnh: Chia attention trong cùng một chuỗi

Parallelism chuỗi chỉ xử lý các operator theo token, nhưng attention đòi hỏi mỗi vị trí phải nhìn thấy các vị trí khác trong chuỗi. Parallelism ngữ cảnh (context parallelism, CP) phân phối các vị trí của cùng một chuỗi dài ra nhiều card; mỗi card giữ Q, K, V cho đoạn vị trí của riêng mình và tính đầu ra attention cho đoạn đó. Hình 6-11 minh họa sự phân công giữa hai card bằng tám vị trí.

Hình 6-11: Mỗi card giữ Q, K, V cho đoạn vị trí của riêng mình. Với attention nhân quả (causal), query của card 1 vẫn cần K, V của card 0, nên K, V phải được truyền qua các card; với attention không nhân quả, cả hai hướng đều phải truyền.

Các query trên một card nhất định vẫn cần K, V ở xa trong phạm vi mà mặt nạ (mask) cho phép. Việc này có thể thực hiện bằng cách thu thập toàn bộ K, V cùng một lúc, hoặc luân chuyển các khối K, V theo vòng (ring) qua các card, tích lũy các giá trị cực đại, tổng lũy thừa và vector có trọng số bằng softmax trực tuyến (online softmax) từ Mục 5.3.3 khi mỗi khối đến nơi. Ring Attention là một hiện thực hóa lập lịch và truyền tải; parallelism ngữ cảnh là phương pháp phân chia công việc — hai thứ không phải là từ đồng nghĩa.

Hình 6-12 mô tả phụ thuộc này như quan hệ tầm nhìn giữa tám vị trí.

Hình 6-12: Attention nhân quả trên tám token, với vị trí khóa trên trục ngang và vị trí query trên trục dọc. Các ô đặc là các cặp query–khóa bắt buộc phải tính; bốn hàng đầu thuộc card 0, bốn hàng cuối thuộc card 1. Đường nét đứt chỉ là ranh giới thiết bị — các phụ thuộc từ xa ở vùng dưới-trái không biến mất vì nó.

Việc chia liền mạch làm đôi theo vị trí cũng tạo ra mất cân bằng tính toán. Attention nhân quả trên tám vị trí có tổng cộng 1+⋯+8=361+\cdots+8=36 cặp query–khóa; bốn vị trí đầu chỉ có 10 cặp trong khi bốn vị trí cuối có 26, nên dù hai card có cùng số token, khối lượng công việc của chúng chênh nhau hệ số 2.6. Việc ghép các vị trí sớm và muộn lại với nhau — ví dụ cho card 0 các vị trí 1,2,7,81,2,7,8 và card 1 các vị trí 3,4,5,63,4,5,6 — khiến mỗi card chịu trách nhiệm 18 cặp. Các hiện thực hóa thực tế thường dùng bố cục răng cưa theo khối (chunked zigzag), nhưng các vị trí gốc và mặt nạ nhân quả phải được giữ nguyên, và giao tiếp phải được bố trí lại cho tương ứng; ngữ cảnh ở xa không thể bị vứt bỏ như phần đệm (padding).

Khi decode, query của token mới rất ngắn nhưng K, V lịch sử lại rất dài. Sau khi chia theo các vị trí lịch sử, mỗi card trước tiên tính cực đại cục bộ mrm_r, tổng lũy thừa lrl_r và vector có trọng số chưa chuẩn hóa uru_r cho đoạn của mình, rồi các giá trị này được hợp nhất như

m=max⁡rmr,l=∑remr−mlr,u=∑remr−mur,o=u/l.m=\max_r m_r,\qquad l=\sum_r e^{m_r-m}l_r,\qquad u=\sum_r e^{m_r-m}u_r,\qquad o=u/l.

oo chính là đầu ra attention của token mới trên toàn bộ các vị trí lịch sử. Điều này giống hệt cách hợp nhất softmax theo tile ở Chương 5, ngoại trừ việc các thống kê và vector phải được truyền qua các card. Mỗi card không thể hoàn thành softmax một cách độc lập rồi chỉ đơn giản lấy trung bình các đầu ra. Parallelism ngữ cảnh giảm trạng thái ngữ cảnh mà mỗi card giữ và phép tính attention cục bộ, đổi lại bằng việc trao đổi K, V hoặc reduce các thống kê; phụ thuộc giữa token trước và token sau trong quá trình sinh không vì thế mà biến mất. Tên gọi của parallelism chuỗi và parallelism ngữ cảnh chồng lấn nhau giữa các framework khác nhau; khi đánh giá một cấu hình cụ thể, hãy nhìn vào operator nào, tensor nào và nhóm giao tiếp nào đang được chia, chứ không chỉ nhìn viết tắt.

6.2.5 Parallelism pipeline: Phân chia giai đoạn theo lớp

Các phương pháp trên đều chia công việc trong một lớp. Parallelism pipeline (pipeline parallelism, PP) thay vào đó chia công việc theo lớp: các lớp của mô hình được chia theo thứ tự thành nhiều giai đoạn, mỗi giai đoạn do một card hoặc một nhóm card xử lý. Hình 6-13 chia 64 lớp của Qwen3-32B thành hai giai đoạn.

Hình 6-13: Mỗi trong hai giai đoạn giữ trọng lượng cho các lớp của mình. Chỉ có kích hoạt được trao giữa các giai đoạn liền kề; khi huấn luyện, gradient được chuyển ngược lại qua cùng một ranh giới.

Một khi một giai đoạn tính xong các lớp của mình, nó trao kích hoạt cho giai đoạn tiếp theo để tiếp tục. Mỗi giai đoạn chỉ giữ trọng lượng cho các lớp của mình, và chỉ có kết quả trung gian được truyền giữa các giai đoạn.

Các đầu vào được đưa vào pipeline được tổ chức thành các micro-batch: một batch được chia thành nhiều micro-batch, để các giai đoạn khác nhau có thể xử lý các micro-batch khác nhau cùng lúc. Giả sử mô hình được chia thành qq giai đoạn, thời gian thực thi của mỗi giai đoạn (kể cả việc trao kích hoạt) là tt, và đầu vào gồm bb micro-batch đã sẵn sàng và độc lập lẫn nhau. Xét trường hợp bốn giai đoạn, mỗi giai đoạn mất 1 ms. Micro-batch 0 vào giai đoạn 0 lúc 0 ms, đi qua cả bốn giai đoạn, và hoàn thành lúc 4 ms; giai đoạn 0 có thể nhận micro-batch 1 lúc 1 ms, micro-batch này hoàn thành lúc 5 ms. Các micro-batch còn lại nối tiếp nhau, mỗi micro-batch hoàn thành trễ hơn micro-batch trước đúng 1 ms.

Hình 6-14: Bốn giai đoạn đều nhau xử lý bốn micro-batch độc lập. Mỗi ô là 1 ms; cùng một màu chỉ cùng một micro-batch. Kết quả đầu tiên xuất hiện lúc 4 ms, kết quả cuối lúc 7 ms; các ô trống từ góc trên-trái xuống góc dưới-phải đến từ việc nạp và xả pipeline.

Micro-batch đầu tiên mất qtqt, và mỗi micro-batch thêm sau đó chỉ thêm tt, nên

TPP=(q+b−1)t,ηPP=qb tq(q+b−1)t=bq+b−1.(6-7)T_{\mathrm{PP}}=(q+b-1)t,\qquad \eta_{\mathrm{PP}}=\frac{qb\,t}{q(q+b-1)t}=\frac{b}{q+b-1}. \tag{6-7}

Tử số là tổng thời gian tất cả các giai đoạn thực sự dành cho việc làm việc; mẫu số là số giai đoạn nhân với thời gian cần để xử lý toàn bộ micro-batch. Với bốn giai đoạn và bốn micro-batch, mức sử dụng là 4/74/7, khoảng 57%; tăng lên 16 micro-batch cho 16/1916/19, khoảng 84%. Càng nhiều micro-batch độc lập, phần thời gian nhàn rỗi do việc nạp và xả pipeline càng nhỏ.

Thời gian thực thi không đều giữa các giai đoạn cũng khiến card bị nhàn rỗi. Nếu bốn giai đoạn cần lần lượt 1, 1, 2 và 1 ms, micro-batch đầu tiên hoàn thành lúc 5 ms, và từ đó về sau tối đa mỗi 2 ms mới hoàn thành một micro-batch. Đầu vào đến giai đoạn 2 ms nhanh hơn khả năng xử lý của nó, nên hàng đợi dần dồn lại; một khi bộ đệm đầy, các giai đoạn thượng nguồn phải dừng lại. Việc phân chia giai đoạn theo thời gian thực thi thực tế của từng lớp có thể làm các độ dài giai đoạn gần nhau hơn và giảm sự dồn lại này.

Đầu vào tiếp theo cho một cuộc hội thoại tự hồi quy chỉ sẵn sàng khi token hiện tại đã được sinh ra. Bốn cuộc hội thoại độc lập có thể cung cấp bốn micro-batch, trong khi bốn token tương lai của cùng một cuộc hội thoại tạo thành một chuỗi phụ thuộc tuần tự. Mức sử dụng pipeline vì vậy phụ thuộc trực tiếp vào việc có bao nhiêu micro-batch có thể bắt đầu thực thi cùng một lúc.

6.2.6 Parallelism expert: Chia tập expert

Phương pháp cuối cùng chia tập expert vốn chỉ có ở MoE. Trong mô hình dense, mọi token dùng cùng một bộ trọng lượng FFN; mô hình MoE chuẩn bị nhiều mạng feedforward làm expert, và một bộ định tuyến (router) tính điểm chọn để quyết định chạy những expert nào cho mỗi token. Mỗi token chỉ dùng các expert được chọn cho nó, nhưng toàn bộ tập expert vẫn phải được giữ trên các accelerator, sẵn sàng cho các token tương lai lựa chọn. MoE vì vậy giới thiệu một cách phân công mới: parallelism expert (expert parallelism, EP) đặt các expert khác nhau lên các card khác nhau, và mỗi card xử lý đầu vào được định tuyến đến nó. Hình 6-15 chia tám expert ra hai card.

Hình 6-15: Attention và bộ định tuyến chạy trên card nơi token cư trú; đầu vào được gửi đến card giữ các expert được chọn, và sau khi các expert hoàn thành, kết quả được gửi về card gốc và hợp nhất theo trọng số định tuyến. Cả hai lần trao đổi đều là All-to-All, tức mỗi card gửi các dữ liệu khác nhau đến từng card khác một cách riêng lẻ.

Parallelism expert trước tiên phải giải quyết các trọng lượng expert được đặt ở đâu, rồi mới đến việc token hiện tại được thực thi như thế nào.

Hãy minh họa sự phân công này bằng bốn card và tám expert. Card 0 giữ expert 0 và 1, card 1 giữ expert 2 và 3, và cứ thế. Card 0 hiện giữ token A, và bộ định tuyến chọn expert 1 và 6 cho A: expert 1 nằm trên card cục bộ, expert 6 nằm trên card 3. Card 0 vừa phải chạy expert cục bộ 1 của mình vừa phải gửi đầu vào của A đến card 3, rồi thu thập cả hai đầu ra và hợp nhất chúng theo trọng số định tuyến.

Quá trình gửi đầu vào expert đến các card giữ các expert đó được gọi là dispatch; quá trình gửi các đầu ra về lại card xuất xứ và hợp nhất chúng được gọi là combine. Tiếp tục với token A: nếu đầu ra của hai expert là y1,y6y_1,y_6 và trọng số định tuyến là a1,a6a_1,a_6, đầu ra MoE hoàn chỉnh là a1y1+a6y6a_1y_1+a_6y_6. Card gửi giữ định danh token và thông tin định tuyến, card nhận chạy expert, và kết quả trả về sau đó được gán lại cho đúng token đó.

Hình 6-16: Card 0 giữ token A, chọn expert cục bộ 1 và expert 6 trên card 3. Dispatch gửi đầu vào theo đường trên, và combine gửi các đầu ra expert trở lại theo đường dưới để hợp nhất có trọng số. Một token được tính một lần cho mỗi expert nó chọn; expert nằm trên card nào quyết định đầu vào phải được gửi đến đâu.

Khi nhiều expert nằm trên cùng một card, chỉ cần gửi một bản sao đầu vào. Nếu tám expert được chọn của một token phân bố hai chiếc mỗi card trên bốn card ở xa, một đầu vào BF16 4096 chiều là 8 KiB: gửi theo từng expert cần 64 KiB, nhưng gửi theo từng card đích chỉ cần 32 KiB, vì hai expert trên cùng một card dùng chung một bản sao đầu vào này.

Khi xử lý nhiều token cùng nhau, mỗi card phải gửi lượng dữ liệu khác nhau đến các card khác nhau — đây là All-to-All thể hiện ở Hình 6-15. Phía nhận trước tiên sắp xếp lại các hàng đầu vào đã nhận theo expert, thực hiện nhân ma trận, rồi sắp xếp lại các đầu ra về đúng thứ tự token ban đầu. Card nhận nhiều đầu vào nhất nói chung cũng thực hiện nhiều phép tính expert nhất.

Qwen3-235B-A22B phóng to ví dụ này lên 128 expert được định tuyến mỗi lớp, mỗi token chọn 8 expert, trải qua 94 lớp. Mỗi expert chứa ba projection, với chiều ẩn 4096 và chiều trung gian 1536, cho trọng lượng BF16 là 3×4096×1536×2=363\times4096\times1536\times2=36 MiB. Tập expert đầy đủ của một lớp chiếm 4.5 GiB, và trên 94 lớp tổng cộng khoảng 423 GB. Chia đều các expert ra tám card cho khoảng 52.9 GiB mỗi card; mỗi card cũng phải giữ trọng lượng, KV và workspace cho các lớp attention, bộ định tuyến, và các lớp đầu vào/đầu ra. Tập expert có thể được phân phối ra các card, trong khi các head attention và trạng thái đi theo sự phân công riêng của attention.

Bài tập 6-2 · Nòng cốt: Chia tensor và pipelining micro-batch thay đổi thời gian thực thi như thế nào

(a) Viết ra hình dạng của sáu mảnh trọng lượng và hai tổng riêng phần đầu ra cho SwiGLU hai card, và dùng phương trình (6-3) để giải thích vì sao các tổng riêng phần từ cả hai card phải được cộng lại.

(b) Với TP1, TP2, TP4 và TP8, tính thời gian truy cập bộ nhớ cục bộ cho một phiên ngữ cảnh 128K của Qwen3-32B, tạm thời bỏ qua chi phí giao tiếp; tìm thời gian tiết kiệm được mỗi lần số card tăng gấp đôi.

(c) Dùng các thời gian reduce ở Mục 6.4, thay chúng vào phương trình (6-5) và tính lại mức tăng tốc; giải thích khoảng cách đó đến từ đâu.

(d) Vẽ đường thời gian cho một pipeline bốn giai đoạn xử lý tám micro-batch, xét cả trường hợp bốn giai đoạn đều mất 1 ms lẫn trường hợp độ dài lần lượt là 1, 1, 2, 1 ms; so sánh thời gian hoàn thành trong hai trường hợp, và xác định micro-batch sẽ dồn lại trước giai đoạn nào.

(e) Nâng cao: với cùng một FFN, so sánh dữ liệu phải truyền giữa các operator liền kề theo hai cách tiếp cận xuất ra tensor đầy đủ so với giữ các mảnh đầu ra; tùy chọn, áp dụng sơ đồ lưới hai chiều kèm theo và tiếp tục suy ra cách dữ liệu trao đổi được chia tile.

6.3 Kết hợp song song và quy mô mô hình

Sáu phương pháp hiếm khi được dùng một mình. Mục này trước tiên giải thích cách kết hợp các phương pháp và gán tọa độ cho từng card, rồi thảo luận hai vấn đề riêng của MoE: việc chọn expert của một batch thay đổi lượng đọc trọng lượng và tải trên mỗi card ra sao, và tổ hợp thay đổi thế nào khi mô hình tiếp tục lớn lên.

6.3.1 Các sơ đồ kết hợp và tọa độ thiết bị

Parallelism tensor và parallelism pipeline có thể kết hợp: ví dụ, chia tám card thành bốn giai đoạn pipeline, với hai card trong mỗi giai đoạn thực hiện parallelism tensor. Việc reduce hai card cho từng lớp được hoàn thành trong giai đoạn, và các kích hoạt được truyền giữa các giai đoạn liền kề. Nếu mỗi trong hai card trong một giai đoạn giữ vector ẩn 8 KiB hoàn chỉnh và trao nó riêng lẻ cho card tương ứng trong giai đoạn kế tiếp, hai giai đoạn cùng gửi tổng cộng 16 KiB; nếu thứ được truyền giữa các giai đoạn là một mảnh, giai đoạn kế tiếp sẽ lắp ráp lại nó khi cần cho phép tính. Vì vậy khi kết hợp hai phương pháp, cần xác định rõ từng giai đoạn xuất ra những mảnh nào và mỗi card trong giai đoạn kế tiếp nhận những mảnh nào.

Khi kết hợp nhiều phương pháp, trước tiên gán tọa độ cho từng card, rồi với mỗi operator, viết ra các mảnh đầu vào, trọng lượng và đầu ra, cùng nhóm card cần giao tiếp. Ví dụ, một sơ đồ với parallelism dữ liệu 2, parallelism pipeline 2 và parallelism tensor 4 được viết DP2×PP2×TP4, chiếm 2×2×4=162\times2\times4=16 card; nếu parallelism chuỗi được bật trong cùng nhóm TP4, số card không đổi, và ta không nhân thêm hệ số SP4. Sự chia quyết định ai sở hữu mỗi phần công việc; lập lịch quyết định thứ tự sẵn sàng, thực thi, giao tiếp và thu hồi — cùng nhau, hai thứ này tạo thành một sơ đồ song song hoàn chỉnh.

Parallelism expert cũng có thể kết hợp với parallelism tensor trong một expert. Ví dụ, bốn nhóm expert mỗi nhóm sở hữu 32 expert, và mỗi nhóm tiếp tục chia chiều trung gian của expert ra hai card, mỗi card xử lý 768 chiều. Toàn bộ instance vẫn trải trên tám card, và mỗi card được xác định bằng hai tọa độ: số nhóm expert chỉ định card chịu trách nhiệm cho những expert nào, và số song song tensor trong nhóm chỉ định card xử lý nửa nào của các ma trận expert đó. Phần thảo luận sau suy ra giao tiếp theo bố cục TP2×EP4 này.

Nguồn đầu vào expert như sau: để cả bốn nhóm expert chạy attention cho cùng một yêu cầu, mỗi nhóm giữ bản sao KV của yêu cầu đó của riêng mình; một khi attention xong, mỗi nhóm đã giữ đầu vào expert hoàn chỉnh, và có thể trực tiếp chọn ra các hàng mà expert của mình cần mà không cần dispatch đầu vào chéo nhóm; kết quả từ mỗi nhóm cuối cùng được tổng hợp qua phép reduce.

Nhóm expertCardID expertChiều trung gian expert mỗi cardKV head mỗi card
00, 10–31768Card chẵn 0, 1; card lẻ 2, 3
12, 332–63768Như trên
24, 564–95768Như trên
36, 796–127768Như trên

Hình 6-17: Tám card được sắp thành bốn nhóm expert, mỗi nhóm hai card chia công việc theo chiều trung gian expert. Các head attention và KV được nhân bản bốn lần trong cùng một cột; mỗi nhóm vì vậy có thể lấy được cùng một đầu vào expert ngay tại chỗ.

Một khi việc đặt dữ liệu đã được chốt, bước tiếp theo là truy vết các đầu ra được hợp nhất thế nào. Hai card trong một nhóm mỗi card tính một nửa chiều trung gian của expert, trước tiên được cộng trong nhóm để có được đóng góp đầy đủ của nhóm đó; rồi các đóng góp của bốn nhóm được cộng lại với nhau.

Hình 6-18: Các mũi tên ngang thể hiện phép cộng trong nhóm trên hai card; các mũi tên dọc thể hiện phép cộng trên bốn nhóm. Các số trong ô là giá trị của một phần tử đầu ra nhất định sau phép cộng trong nhóm; cả hai cột đều đi đến cùng một kết quả hoàn chỉnh, 10.

Bước cộng thứ hai diễn ra giữa các card có cùng chỉ số. Ví dụ, nếu các đóng góp của bốn nhóm cho một phần tử đầu ra nhất định là 1, 2, 3 và 4, bốn card chẵn reduce chung với nhau để được 10, và bốn card lẻ reduce riêng cũng được 10. Đến lúc này mỗi card giữ cùng một đầu ra hoàn chỉnh và có thể sang lớp tiếp theo.

Việc tránh dispatch phải trả giá bằng lưu trữ và tính toán thêm. Dưới bố cục này, trọng lượng trên mỗi card đạt khoảng 64.8 GB, tổng cộng 518.6 GB trên tám card — nhiều hơn khoảng 48.4 GB so với 470.2 GB cần có nếu mỗi tham số chỉ được lưu một lần. Với ngữ cảnh 8192 token, KV trên mỗi card là 752 MiB, tổng cộng 5.875 GiB trên tám card, gấp bốn lần KV thực tế của yêu cầu đó. Mỗi nhóm chạy attention một cách dư thừa, đổi lại việc đầu vào expert đã nằm cục bộ.

Ví dụ làm việc: bố cục attention nhân bản và expert chia nhỏ cần bao nhiêu giao tiếp reduce? Việc reduce dùng FP32, nên vector ẩn hoàn chỉnh của một token là 4096×4=164096\times4=16 KiB. Dùng thuật toán vòng (ring) ở Mục 6.4.2 để reduce giữa hai card, mỗi card gửi kích thước của một vector đầy đủ; reduce trên bốn card gửi 1.5 lần lượng đó. Mỗi lớp liên quan ba bước hợp nhất — reduce trong nhóm cho attention, reduce trong nhóm cho expert, và reduce trên bốn nhóm expert — nên mỗi card gửi

16+16+24=56 KiB.16+16+24=56\ \mathrm{KiB}.

Trên tám card tổng cộng 448 KiB; với một prefill 8192 token dùng cùng sự phân công, mỗi card gửi 448 MiB.

6.3.2 Tái sử dụng trong batch và mất cân bằng tải

Tiểu mục trước đã chốt các expert nằm trên những card nào, nhưng chưa chốt card nào bận nhất tại một bước bất kỳ — điều đó phụ thuộc vào việc batch hiện tại chọn những expert nào. Một token chỉ chọn tám expert, nhưng một batch có thể phủ toàn bộ tập expert. Giả sử 64 token mỗi token chọn tám expert, cho 512 phép gán token–expert tổng cộng.

Nếu các phép gán này tình cờ phủ đều 128 expert, mỗi expert xử lý bốn vector đặc trưng của token; nếu tất cả token đều chọn cùng tám expert, mỗi expert xử lý 64 vector đặc trưng của token. Phép tính ma trận thực tế trong cả hai trường hợp là như nhau. Giả định trong một batch, trọng lượng của mỗi expert được chọn chỉ được đọc từ HBM một lần, trường hợp trước cần 128×36128\times36 MiB, tức 4.5 GiB; trường hợp sau cần 8×368\times36 MiB, tức 288 MiB — chênh lệch gấp 16 lần lượng đọc.

Hình 6-19: 64 token, mỗi token tám expert, tổng cộng 512 phép gán. Việc phủ đều và việc chọn tập trung có phép tính hiệu dụng như nhau, nhưng lượng đọc trọng lượng của các expert được chọn chênh nhau gấp 16 lần. Trọng lượng BF16 của mỗi expert là 36 MiB, được đọc một lần mỗi batch.

Càng ít expert hoạt động, càng nhiều hàng đầu vào có thể tái sử dụng trọng lượng của mỗi expert, vừa giảm số lần đọc lặp vừa tăng số hàng trong phép nhân ma trận. Nhưng card nào thực thi các hàng này cũng ảnh hưởng đến thời gian hoàn thành. Trong bố cục TP2×EP4, việc phủ đều cho mỗi nhóm 32×4=12832\times4=128 phép gán; nếu tám expert hoạt động đều rơi vào một nhóm expert duy nhất, nhóm đó phải xử lý tất cả 512 phép gán — gấp bốn lần phép tính của trường hợp đều — trong khi ba nhóm còn lại chỉ biết chờ.

Vì vậy phân tích thời gian thực thi cần tính cả khối lượng đọc trọng lượng của toàn batch lẫn phép tính của nhóm expert chịu tải nặng nhất. Các phép toán ma trận nhỏ của decode dễ bị giới hạn bởi tốc độ đọc trọng lượng, trong khi các phép toán ma trận lớn của prefill dễ bị giới hạn hơn bởi thời gian tính toán của nhóm expert chịu tải nặng nhất. Việc trải các expert điểm nóng (hotspot) ra các nhóm EP khác nhau giữ được sự tái sử dụng trong batch trong khi giảm bớt gánh nặng tính toán trên bất kỳ nhóm expert đơn lẻ nào.

Hình 6-20: Với việc dùng đều 128 expert, bốn nhóm EP mỗi nhóm xử lý 128 phép tính token–expert, cùng nhau đọc 4.5 GiB trọng lượng.

Hình 6-21: Tám expert được chọn đều nằm trong nhóm 0: lượng đọc trọng lượng giảm còn 288 MiB, nhưng toàn bộ 512 phép tính dồn lên cùng một nhóm.

Hình 6-22: Trải cùng tám expert đó ra bốn nhóm giữ lượng đọc ở mức 288 MiB trong khi cho mỗi trong bốn nhóm 128 phép tính. Dải trục tung giống nhau ở cả ba hình.

Hai bố cục cuối trong các hình đọc cùng một lượng trọng lượng, vậy mà thời gian hoàn thành của chúng có thể khác nhau, vì số card tham gia tính toán là khác nhau. Vậy sự tái sử dụng trong batch phải được phân tích cùng với cách các expert được phân phối ra các card.

Bên cạnh hai trường hợp phủ đều và chọn tập trung ở trên, ta còn có thể tính kết quả trung bình khi chọn expert ngẫu nhiên đều. Giả sử mỗi token chọn kk trong số EE expert, với các token được chọn độc lập. Xác suất một expert nhất định bị một token bỏ qua là 1−k/E1-k/E, và xác suất nó bị cả một batch mm token bỏ qua là (1−k/E)m(1-k/E)^m. Với mỗi expert, định nghĩa một biến chỉ báo bằng 1 nếu expert được chọn ở đâu đó trong batch và bằng 0 nếu ngược lại. Cộng các biến này và lấy kỳ vọng cho ra số expert hoạt động kỳ vọng trong batch:

E[Eactive]=E[1−(1−kE)m].(6-8)\mathbb{E}[E_{\mathrm{active}}]=E\left[1-\left(1-\frac{k}{E}\right)^m\right]. \tag{6-8}

Lấy E=128,k=8,m=8E=128,k=8,m=8 cho khoảng 52 expert hoạt động theo kỳ vọng, với lượng đọc lý tưởng khoảng 1.8 GiB; nếu cả tám token đều chọn cùng tám expert, lượng đọc vẫn chỉ 288 MiB. Khi batch lớn dần, số expert được chọn dần tiến tới tổng số expert, và việc tăng thêm số hàng đầu vào chủ yếu cải thiện sự tái sử dụng của mỗi bộ trọng lượng.

Kết quả định tuyến thực tế được quyết định đồng thời bởi đầu vào và mô hình. Các bản ghi định tuyến của DeepSeek V4-Flash trong tài liệu kèm theo phủ bốn đầu vào trên 43 lớp, tổng cộng khoảng 1.31 triệu lần chọn expert, và tần suất từng expert được chọn biến động đáng kể. Chuyển số token mỗi expert nhận được thành số hàng ma trận, rồi cộng theo tập expert trên mỗi card, cho ra phân bố tải tính toán trên mỗi card từ các bản ghi này. Các heatmap theo lớp được cung cấp trong tài liệu kèm theo.

6.3.3 Từ hàng trăm tỷ đến nghìn tỷ tham số: tổ hợp song song thay đổi ra sao

Phân tích tái sử dụng và tải ở Mục 6.3.2 giả định toàn bộ tập expert đã vừa trong bộ nhớ accelerator. Khi mô hình lớn dần, trước tiên ta cần xem lại tổng dung lượng lưu trữ trước khi quyết định cách kết hợp TP, PP và EP. Toàn bộ trọng lượng BF16 của Qwen3-235B-A22B khoảng 470 GB, tính mỗi tham số một lần; DeepSeek V4-Flash có khoảng 284B tham số, tức khoảng 568 GB ở cùng định dạng. Một HGX H100 duy nhất với tám card H100 cung cấp tổng cộng 640 GB, còn rất ít chỗ cho trạng thái và không gian làm việc. DeepSeek V4-Flash có 256 expert được định tuyến mỗi lớp, mỗi token chọn 6 trong số đó, và các expert dùng chung (shared expert) cũng chạy; với tập expert lớn hơn, việc phân bổ trọng lượng phải tính cả expert dùng chung lẫn expert được định tuyến.

DeepSeek V4-Pro có khoảng 1.6T tham số, và ngay cả ở nửa byte mỗi tham số, trọng lượng đã lên tới khoảng 800 GB; khoảng 2.8T tham số của Kimi K3 tương ứng khoảng 1.4 TB. Nhu cầu lưu trữ của các mô hình này đã vượt quá tổng dung lượng của một HGX H100 đơn lẻ. Tăng số nhóm EP có thể trải các expert ra nhiều card hơn; tăng số card TP trong một expert có thể thu nhỏ ma trận expert lưu trên mỗi card; tăng số giai đoạn PP có thể giảm số lớp mô hình lưu trên mỗi giai đoạn.

Cách biểu diễn đầu vào expert cũng thay đổi khối lượng giao tiếp chéo card. Các expert được định tuyến của Kimi K3 hoạt động trong không gian tiềm ẩn 3584 chiều, trong khi vector ẩn xương sống (backbone) là 7168 chiều. Chiếu trước rồi gửi sẽ thu một vector BF16 từ 14 KiB xuống 7 KiB; gửi trước rồi chiếu sau sẽ truyền đầu vào chưa giảm chiều. Với cùng một phép tính expert, việc projection xảy ra trước khi gửi hay sau khi nhận sẽ quyết định chiều vector được truyền qua các card. Mô hình chọn 16 trong số 896 expert được định tuyến mỗi lớp, cộng thêm hai expert dùng chung xử lý toàn bộ vector xương sống, mỗi expert xử lý một phép tính khác nhau; trong số 93 lớp, 69 lớp KDA dùng một phép truy hồi ma trận kích thước cố định để tóm tắt ngữ cảnh, và 24 lớp MLA dùng một biểu diễn chiều thấp để lưu ngữ cảnh. Nhu cầu lưu trữ trạng thái KDA được quyết định chủ yếu bởi chiều cố định của nó, còn nhu cầu lưu trữ trạng thái MLA cũng tăng theo ngữ cảnh của phiên.

Những thay đổi mô hình vì vậy tác động đến thiết kế hệ thống theo hai chiều: nhiều trọng lượng hơn mở rộng tổng dung lượng lưu trữ cần thiết, còn một đồ thị tính toán khác thay đổi dữ liệu phải trao đổi. Cái trước quyết định tài nguyên tối thiểu phải cam kết; cái sau quyết định các tài nguyên này nên được kết nối như thế nào.

Thí nghiệm 6-3 · Nòng cốt: dispatch và vị trí expert thay đổi tải mỗi card và khối lượng giao tiếp ra sao

(a) Theo Hình 6-16, viết ra thứ tự gửi đầu vào, hai lần thực thi expert và bước tổng hợp có trọng số cho token A.

(b) Tính lại hai sơ đồ dispatch expert cho 64 token, tìm lượng đọc trọng lượng và số nhiệm vụ của nhóm EP chịu tải nặng nhất.

(c) Trải đều tám expert điểm nóng ra bốn nhóm EP, so sánh tổng lượng đọc với phép tính của nhóm expert chịu tải nặng nhất, và giải thích sự thay đổi đến từ đâu.

(d) Dùng bảng TP2×EP4 của mục này, tìm dung lượng KV mỗi card phải lưu cho độ dài ngữ cảnh 8192 và 16384, và suy ra lượng gửi để tổng hợp ba kết quả.

(e) Nâng cao: với DeepSeek V4-Flash, DeepSeek V4-Pro hoặc Kimi K3, chọn một định dạng lưu trữ cụ thể và liệt kê vị trí đặt của expert được định tuyến, expert dùng chung, trạng thái attention và không gian làm việc.

6.4 Hiện thực hóa giao tiếp tập thể và chi phí thực thi

6.4.1 Xác định nhu cầu giao tiếp từ cách chia mô hình

Mục 6.2 đã định nghĩa các phép toán giao tiếp tập thể (collective communication) như AllReduce và All-to-All; mục này thảo luận cách hiện thực hóa và chi phí thực thi của chúng. Trước tiên xét bốn card cộng một vector bốn phần tử. Mỗi card giữ một đóng góp cục bộ bốn phần tử, và mục tiêu là để mọi card thu được tổng theo phần tử hoàn chỉnh. Việc này có thể làm trong hai bước: trước tiên cộng, để card 0 giữ tổng hoàn chỉnh của phần tử 0, card 1 giữ tổng hoàn chỉnh của phần tử 1, và cứ thế; rồi trao đổi các phần tử đã cộng này để cả bốn card thu được vector hoàn chỉnh.

Bước thứ nhất là ReduceScatter, bước thứ hai là AllGather, và cùng nhau hai bước hoàn thành một AllReduce. Hai bước lần lượt thay đổi các giá trị và vị trí của các giá trị. Mô hình dense và MoE cũng cần nối các mảnh và gửi đầu vào expert đến các card khác nhau; dựa trên những gì mỗi card giữ lúc đầu và lúc cuối của quá trình giao tiếp, ta có thể phân biệt bốn loại giao tiếp tập thể sau.

Phép toánMỗi card giữ lúc bắt đầuMỗi card giữ khi hoàn thànhCông dụng
AllReduceKết quả riêng phần của cùng một tensorKết quả reduce hoàn chỉnhTổng riêng phần TP, gradient huấn luyện
ReduceScatterKết quả riêng phần của cùng một tensorCác mảnh khác nhau của kết quả đã reduceĐầu ra đã chia mảnh, chia mảnh gradient
AllGatherCác mảnh khác nhau của một tensorKết quả nối hoàn chỉnhKhôi phục đầu vào đầy đủ
All-to-AllDữ liệu dành cho các đích khác nhauDữ liệu do mọi card nguồn gửi đến card nàyDispatch đầu vào expert và trả về kết quả

Broadcast gửi dữ liệu của một card được chỉ định cho toàn nhóm, và Reduce chỉ giao kết quả đã reduce cho một card được chỉ định; cả hai đều không đưa kết quả cho toàn nhóm như các phép toán trong bảng. AllGather nối dữ liệu theo rank (chỉ số của mỗi card trong nhóm giao tiếp) mà không cộng; All-to-All phân phối lại dữ liệu theo đích và không tự động tổng hợp đầu ra expert theo trọng số định tuyến. Bước combine của MoE vì vậy gồm trả kết quả về, khôi phục thứ tự token, và cộng theo trọng số định tuyến — ba bước — nên nó không thể được coi đơn giản là một AllReduce chỉ dựa trên cái tên.

Tên phép toán chỉ rõ giá trị gì được tính và card nào cuối cùng giữ kết quả; thuật toán cụ thể chỉ rõ dữ liệu được chia thành bao nhiêu vòng và được truyền theo cách nào. Tiểu mục kế tiếp truy vết quá trình một khối dữ liệu như vậy di chuyển dọc theo một vòng.

Thuật toán quyết định cuộc trao đổi tự nó mất bao lâu, còn thời điểm mỗi card khởi xướng giao tiếp quyết định mỗi card phải chờ bao lâu: cả nhóm phải chờ đến khi card cuối cùng khởi xướng thì cuộc trao đổi mới bắt đầu được, và các card đến sớm hơn đang chờ card đó hoàn thành phép tính phía trước của nó, nên độ trải rộng của các thời điểm khởi xướng càng lớn, lợi ích của việc tăng tốc bản thân cuộc trao đổi càng nhỏ. Mục 7.6.1 sẽ phát triển phép so sánh này bằng cùng bộ dữ liệu.

6.4.2 Vòng (ring), cây (tree) và các vòng giao tiếp

Ring AllReduce sắp xếp các card tham gia thành một vòng có hướng; mỗi vòng, mọi card gửi một khối cho card kế tiếp và nhận khối do card trước gửi đến. Gọi nn là số card tham gia và MM byte là tổng riêng phần hoàn chỉnh của mỗi card, được chia thành nn khối, mỗi khối M/nM/n.

Lấy một vòng bốn card 0→1→2→3→0 làm ví dụ. Ban đầu mọi card giữ đóng góp cục bộ của mình cho các khối 0, 1, 2 và 3. Trong vòng thứ nhất, card rr gửi khối rr; người nhận cộng khối nhận được vào đóng góp tương ứng của mình. Vòng thứ hai chuyển tiếp tổng riêng phần vừa hình thành, và vòng thứ ba tiếp tục chuyển tiếp trong khi cộng đóng góp cuối cùng.

Theo dõi khối 0: nó được gửi từ card 0, đi qua card 1 và card 2, và cuối cùng đến card 3. Nếu các đóng góp của bốn card cho một phần tử của khối 0 là 1, 10, 100 và 1000, giá trị dọc đường lần lượt là 1, 11, 111, 1111. Cuối vòng thứ ba, card 3 giữ tổng hoàn chỉnh của khối 0; đồng thời, cards 0, 1 và 2 giữ các tổng hoàn chỉnh của lần lượt các khối 1, 2 và 3.

Hình 6-23: Chỉ theo dõi một phần tử của khối 0: mỗi lần đi qua một card, đóng góp của card đó được cộng vào. Sau ba vòng nó đạt 1111, được giữ bởi card 3. Ba khối còn lại tiến dọc vòng cùng lúc.

Hình 6-24: Khi ReduceScatter kết thúc, các card 0, 1, 2, 3 lần lượt giữ các khối 1, 2, 3, 0. Mỗi vòng sau đó chuyển tiếp một khối; sau ba vòng, mỗi card giữ cả bốn khối kết quả hoàn chỉnh.

Chỉ cần ba vòng vì một khối đã chứa một đóng góp từ điểm xuất phát của nó, và sau khi đi qua ba card còn lại nó chứa đủ cả bốn. Tổng quát, ReduceScatter cần n−1n-1 vòng. Sau đó mỗi card chuyển tiếp khối mình đã hoàn thành cho card kế tiếp, mỗi vòng thu thêm một khối; sau thêm n−1n-1 vòng nữa, mọi card đã thu thập được tất cả các khối. Tổng lượng gửi trên mỗi card vì vậy là 2(n−1)M/n2(n-1)M/n, trải qua 2(n−1)2(n-1) vòng.

Gọi chi phí cố định mỗi vòng là α\alpha và băng thông hiệu dụng của mỗi cạnh có hướng là BB; mỗi card chờ lần gửi của vòng hiện tại hoàn thành trước khi vào vòng kế tiếp, cho ra mô hình thời gian

Tring=2(n−1)α+2(n−1)MnB.(6-9)T_{\mathrm{ring}}=2(n-1)\alpha+\frac{2(n-1)M}{nB}. \tag{6-9}

Số hạng thứ nhất tăng theo số card, còn số hạng thứ hai dần tiến về 2M/B2M/B. Thuật toán vòng chia dữ liệu lớn thành các khối nhỏ để mọi card truyền đồng thời; khi khối lượng dữ liệu nhỏ, thời gian dành cho chi phí khởi tạo mỗi vòng chiếm ưu thế.

Ví dụ làm việc: sau khi tính cả giao tiếp reduce, việc tăng số card TP còn mang lại bao nhiêu tăng tốc nữa? Vẫn dùng phiên 128K của Qwen3-32B. Đầu vào của mỗi phép reduce là vector ẩn BF16 của một token, M=10M=10 KiB; trên một HGX H100, băng thông mỗi card qua NVSwitch là B=450B=450 GB/s mỗi chiều; lấy chi phí cố định mỗi vòng α\alpha là độ trễ một chiều NVLink 0.822 μs đo được trên cùng máy chủ tám H100 trong bài báo MSCCL++. Tìm thời gian một phép reduce và thời gian của phương trình (6-5) cho TP2, TP4 và TP8.

Lời giải: TP8 cần mười bốn vòng tổng cộng, với chi phí khởi tạo cộng lại là 11.51 μs; mỗi card gửi 17.5 KiB, truyền mất khoảng 0.04 μs, cho một phép reduce khoảng 11.55 μs. Các mức khác tính tương tự bằng cách thay vào phương trình (6-9). Hàng TP1 chỉ đưa vào để so sánh — một card thậm chí không chứa nổi một phiên 128K:

Số card TPTruy cập bộ nhớ cục bộ128 phép reduceThời gian một bước
129.35 ms029.35 ms
214.68 ms0.21 ms14.89 ms
47.34 ms0.64 ms7.97 ms
83.67 ms1.48 ms5.15 ms

Hình 6-25: Thời gian một bước vẽ từ phương trình (6-5) và mô hình reduce vòng. Truy cập bộ nhớ cục bộ giảm khi nhiều card hơn trong khi thời gian reduce tăng; tổng chiều dài thanh là thời gian thực thi một bước. Số hạng cục bộ gồm đọc trọng lượng và KV; số hạng reduce là giao tiếp tập thể giữa các card.

Trong hình, phần màu xanh co lại khi số card tăng, còn phần màu cam dần dài ra. Đi từ hai card lên bốn card, thời gian truy cập bộ nhớ cục bộ giảm khoảng 7.34 ms trong khi giao tiếp tăng khoảng 0.42 ms, tiết kiệm ròng khoảng 6.92 ms. Đi từ bốn card lên tám card, thời gian truy cập bộ nhớ cục bộ chỉ giảm thêm khoảng 3.67 ms trong khi giao tiếp tăng khoảng 0.84 ms, cắt tiết kiệm ròng xuống còn khoảng 2.83 ms. Hai vế của phương trình (6-6) dần tiến lại gần nhau, nhưng tám card vẫn nhanh hơn.

Đến lúc này, tăng băng thông gần như không còn lợi ích. Trong một lần reduce tám card, 11.51 μs đến từ chi phí khởi tạo; dù thời gian truyền giảm về không, ta vẫn phải chờ trọn mười bốn vòng này. Tăng gấp đôi băng thông chỉ tiết kiệm khoảng 2.5 μs cho cả bước; còn giảm một nửa chi phí cố định mỗi vòng lại tiết kiệm khoảng 0.74 ms trên 128 phép reduce.

Thuật toán cây bắt đầu từ số vòng. Bốn card trước tiên ghép cặp và reduce, rồi nút gốc hợp nhất các kết quả — việc reduce mất hai vòng; broadcast rồi mất thêm hai vòng nữa, tổng cộng bốn vòng. Khi nn là lũy thừa của 2, một cây nhị phân không phân đoạn có tổng cộng 2log⁡2n2\log_2n vòng, và mỗi vòng trên đường tới hạn truyền tensor hoàn chỉnh:

Ttree=2log⁡2n(α+MB).(6-10)T_{\mathrm{tree}}=2\log_2n\left(\alpha+\frac{M}{B}\right). \tag{6-10}

Với tám card và 10 KiB, kết quả khoảng 5.07 μs, ngắn hơn 11.55 μs của thuật toán vòng. Khi khối lượng dữ liệu tăng lên 80 MiB của 8192 token, thuật toán vòng cần khoảng 0.34 ms còn cây cần khoảng 1.12 ms: thời gian tiết kiệm được từ ít vòng hơn không còn bù đắp được thời gian thêm ra từ việc truyền đi truyền lại tensor lớn hoàn chỉnh dọc đường tới hạn. Đặt hai phương trình bằng nhau cho điểm giao cắt quanh 680 KiB; một khi khối lượng dữ liệu vượt giá trị này, thuật toán nhanh hơn sẽ chuyển sang phía còn lại.

Hình 6-26: Mô hình thời gian của thuật toán vòng tám card và cây nhị phân không phân đoạn, ở 0.822 μs mỗi vòng và 450 GB/s mỗi chiều. Điểm giao cắt quanh 680 KiB; đầu vào decode 10 KiB nằm ở phía do chi phí khởi tạo chi phối, còn đầu vào prefill 80 MiB nằm ở phía do thời gian truyền dữ liệu chi phối.

Thí nghiệm 6-4 · Mở rộng: ở khối lượng dữ liệu nào reduce vòng nhanh hơn reduce cây?

(a) Theo quy tắc gửi trong Hình 6-23, truy vết ba vòng reduce cho khối 1, viết ra card nào giữ khối ở mỗi vòng và đóng góp của những card nào đã được tích lũy vào khối.

(b) Tìm lượng gửi mỗi card cho reduce vòng bốn card và tám card, rồi suy ra thời gian reduce cây cho cùng khối lượng dữ liệu.

(c) Tìm khối lượng dữ liệu mà tại đó thời gian của hai thuật toán reduce bằng nhau trong triển khai tám card; tính lại sau khi giảm một nửa α\alpha, và giải thích vì sao khối lượng dữ liệu giao cắt thay đổi.

(d) Thay thời gian thuật toán cây để reduce 10 KiB dữ liệu vào ví dụ Qwen3-32B của chương này, tìm thời gian một bước với tám card, và so sánh lợi ích của việc chọn thuật toán với việc tăng gấp đôi băng thông.

6.4.3 Tranh chấp tài nguyên giữa thư viện giao tiếp và tính toán

Cả thuật toán vòng lẫn cây đều phải được phần mềm trên mỗi card thực thi thật sự. Một thư viện giao tiếp (communication library) là phần mềm hiện thực hóa các phép toán giao tiếp tập thể, như Thư viện Giao tiếp Tập thể NVIDIA (NCCL). Hiện thực hóa tương ứng trên Ascend là Thư viện Giao tiếp Tập thể Huawei (HCCL). Ứng dụng trước tiên thiết lập một communicator, gán cho mỗi card trong nhóm một rank, rồi nộp các phép toán xác định bộ đệm, số phần tử, kiểu dữ liệu, phép reduce và CUDA stream tham gia. Các lời gọi trên các card trong nhóm phải khớp nhau theo yêu cầu của giao diện, kể cả thứ tự lời gọi và số lượng dữ liệu; một lời gọi trả về nói chung chỉ có nghĩa phép toán đã được nộp vào stream, chứ không có nghĩa bộ đệm có thể được dùng lại khi dữ liệu vẫn đang trên đường truyền. Ai dùng kết quả phải chờ nhờ thứ tự trong cùng một stream hoặc một phụ thuộc sự kiện tường minh. Giao tiếp tập thể cũng không thể bị coi là một điểm đồng bộ toàn cục dùng được từ mã máy chủ tùy ý.

Trong MoE, số token được dispatch giữa bất kỳ cặp card nào biến đổi theo batch. Một All-to-All độ dài bằng nhau không thể biểu diễn cuộc trao đổi độ dài không đều này, nên runtime phải tự tổ chức các số lượng, offset, đóng gói và không gian nhận. NCCL có thể biểu diễn các trao đổi cặp tùy ý bằng Send/Recv điểm-điểm nhóm (grouped point-to-point); mỗi send phải có một receive khớp, và các giao tiếp cần tiến cùng nhau phải được đặt trong cùng một nhóm, nếu không chúng sẽ tuần tự chờ một phép toán mà phía bên kia chưa phát hành. Các thư viện giao tiếp parallelism expert chuyên dụng còn kết hợp thông tin định tuyến để hiện thực hóa dispatch và combine. Dù chọn hiện thực hóa nào, nên ghi lại phiên bản thư viện và giao diện cụ thể, và một bài thử All-to-All kích thước cố định không nên bị nhầm với giao tiếp MoE thực tế.

Khi đo NCCL, cũng cần phân biệt hai loại băng thông mà nó báo cáo: algbw là khối lượng dữ liệu do bài thử định nghĩa chia cho thời gian, còn busbw được quy đổi dựa trên khối lượng truyền thực tế của phép toán tập thể. Với AllReduce nn card, nếu đầu vào của mỗi card là MM, thì algbw=M/T\mathrm{algbw}=M/T và busbw=2(n−1)M/(nT)\mathrm{busbw}=2(n-1)M/(nT). Ví dụ, trong bản ghi công khai được lưu cho Thí nghiệm 7-3, trên hai HGX H100 với 16 rank tổng cộng, một AllReduce 64 MiB mỗi card mất 466.1 μs, cho algbw 143.99 GB/s và busbw gấp 1.875 lần, tức 269.98 GB/s. busbw là một chỉ số đã chuẩn hóa và không thể được coi trực tiếp là thông lượng thực tế của bất kỳ NIC đơn lẻ nào; giao tiếp phân cấp, reduce trong switch và chia sẻ liên kết vẫn cần được tính từng hạng mục một dọc theo đường vật lý được mô tả ở Chương 7. Với khối lượng dữ liệu nhỏ, độ trễ mới là điều quan trọng; với khối lượng lớn, băng thông liên tục mới là điều quan trọng; và khi được đặt bên trong quá trình thực thi mô hình, điều quan trọng là toàn bộ khoảng từ lúc dữ liệu sẵn sàng đến lúc được tiêu thụ.

Khi Mục 6.4.2 so sánh vòng và cây, nó coi một lần giao tiếp là một phép toán cô lập. Trong thực thi thật, giao tiếp thường được chồng lấn với tính toán từ một micro-batch khác, và hai bên tranh chấp tài nguyên accelerator. Việc reduce đòi hỏi đọc các tổng riêng phần, thực hiện phép cộng, ghi lại kết quả và nâng cấp giao tiếp lên giai đoạn sau. Công việc này chiếm SM, HBM và interconnect của accelerator; các phép nhân ma trận chạy cùng lúc cũng cần những tài nguyên này. Một khi giao tiếp và tính toán chồng lấn, tốc độ mỗi bên có được khi chạy một mình không còn giữ nguyên.

Thí nghiệm 6-5 kèm theo đo hiệu ứng này. Thí nghiệm dùng Gloo (một thư viện giao tiếp tập thể hỗ trợ các môi trường thực thi như CPU) để chạy AllReduce trên bốn tiến trình CPU, đồng thời bắt mỗi tiến trình cũng chạy một phép nhân ma trận, ghi lại thời gian của mỗi thứ khi chạy một mình và khi chạy đồng thời, lấy trung vị của năm lần chạy:

Khối lượng dữ liệu reduceGiao tiếp một mìnhTính toán một mìnhGiao tiếp khi đồng thờiTính toán khi đồng thờiHoàn thành của nhóm đồng thời
4 MiB2.67 ms11.53 ms6.14 ms11.52 ms11.58 ms
64 MiB36.92 ms11.03 ms45.21 ms12.89 ms45.24 ms

Ở 4 MiB, giao tiếp chạy đồng thời với phép nhân ma trận mất hơn gấp đôi thời gian chạy một mình, nhưng vẫn kết thúc trước phép nhân ma trận, nên cả nhóm hoàn thành trong 11.58 ms — gần như với việc chỉ chạy một phép nhân ma trận — vì giao tiếp bị che bởi tính toán. Ở 64 MiB, giao tiếp tăng từ 36.92 ms lên 45.21 ms, và phép nhân ma trận cũng tăng từ 11.03 ms lên 12.89 ms; chạy hai thứ riêng rẽ cộng lại mất khoảng 48.0 ms, nên chạy đồng thời chỉ tiết kiệm khoảng 2.7 ms, chứ không phải trọn 11 ms của phép nhân ma trận. Đánh giá thực thi chồng lấn đòi hỏi so sánh thời gian của hai thứ khi chạy đồng thời, chứ không phải đơn giản trừ các thời gian đo riêng rẽ của từng thứ.

Hình 6-27: Thời gian giao tiếp và nhân ma trận chạy một mình trong Thí nghiệm 6-5, trên bốn tiến trình CPU, trung vị của năm lần chạy. Giao tiếp ở 4 MiB khoảng 2.67 ms, ở 64 MiB khoảng 36.92 ms; phép nhân ma trận khoảng 11 ms.

Hình 6-28: Cùng thí nghiệm với cả hai khởi đầu cùng lúc. Màu cam là giao tiếp, màu xanh là tính toán; các công việc sau đó đều chờ cả hai kết thúc. Giao tiếp 4 MiB tăng lên 6.14 ms và vẫn bị che bên trong phép tính; giao tiếp 64 MiB tăng lên 45.21 ms và phép tính cũng tăng lên 12.89 ms.

Lập luận tương tự cũng áp dụng trên GPU. Tăng số luồng và kênh giao tiếp giúp truyền nhanh hơn khi chạy một mình, nhưng cũng chiếm các tài nguyên thực thi mà tính toán cần, nên việc chọn cấu hình chỉ dựa trên băng thông giao tiếp chạy một mình có thể làm chậm kết quả tổng thể. Hệ thống tự động tinh chỉnh giao tiếp tập thể AutoCCL vì vậy ghi lại thời gian giao tiếp thực tế trong lúc huấn luyện, để phản hồi của nó gồm cả nhiễu do chạy đồng thời; nó trước tiên chọn thuật toán, giao thức và hiện thực hóa vận chuyển, rồi tìm kiếm trên các luồng, kênh và cách chia khối. Bài báo báo cáo rằng dưới ảnh hưởng của việc tính toán lại (recomputation), băng thông AllGather cải thiện từ 18.26 GB/s lên 32.44 GB/s. Bản thân việc tìm kiếm và chuyển đổi cũng tốn thời gian: nếu việc tìm kiếm tốn thêm SS, và mỗi lời gọi sau tiết kiệm Δ\Delta, cần ít nhất S/ΔS/\Delta lời gọi để thu hồi chi phí.

6.4.4 Hợp nhất giao tiếp, giao tiếp khởi tạo từ accelerator và offload chuyên dụng

Chỉ tăng tốc giao tiếp không nhất thiết tăng tốc thực thi tổng thể, nên ta nên phân biệt hai loại cải thiện: giảm số lần khởi tạo giao tiếp và lượng đọc/ghi dữ liệu, và giảm mức chiếm dụng tài nguyên tính toán của giao tiếp. Trong ví dụ tám card Qwen3-32B, chi phí khởi tạo của 128 phép reduce khoảng 1.47 ms. Quanh chi phí này, ba khía cạnh khác nhau có thể thay đổi: một lần khởi tạo làm được bao nhiêu việc, ai khởi xướng nó, và ai thực hiện việc di chuyển và reduce.

Hợp nhất (fusion) cho phép các toán tử liền kề tham gia trong một kernel duy nhất. Ví dụ, sau phép reduce, một phép cộng dư vẫn phải được thực hiện và RMSNorm được tính; thực thi chúng riêng rẽ sẽ ghi lại kết quả rồi đọc vào lần nữa, phát sinh nhiều lần khởi tạo. Sau khi hợp nhất, quá trình xử lý có thể tiếp tục trong khi dữ liệu vẫn nằm gần đơn vị tính toán. Chuẩn hóa phải chờ cho đến khi reduce tạo ra đầu vào hoàn chỉnh: bỏ qua hằng số epsilon nhỏ dùng để tránh chia cho không và tham số tỷ lệ học được, RMSNorm⁡([1,0]+[0,1])=[1,1]\operatorname{RMSNorm}([1,0]+[0,1])=[1,1], trong khi chuẩn hóa riêng rẽ rồi cộng lại lại cho [2,2][\sqrt2,\sqrt2]. Hợp nhất phải giữ nguyên thứ tự thực thi này để thu được cùng một kết quả tính toán.

Giao tiếp khởi tạo từ accelerator loại bỏ hành trình khứ hồi giữa việc nộp trên máy chủ và thực thi trên accelerator: một khi kernel tính xong dữ liệu, nó có thể trực tiếp khởi xướng giao tiếp tiếp theo, rút ngắn khoảng chờ từ lúc tính toán hoàn thành đến lúc giao tiếp bắt đầu. Offload chuyên dụng trao việc di chuyển, reduce hoặc đồng bộ hóa cho một copy engine, một đơn vị xử lý giao tiếp hoặc logic bên trong switch, giải phóng các đơn vị tính toán đa dụng cho phép nhân ma trận.

Đơn vị Giao tiếp Tập thể (CCU) của Ascend tập trung hóa việc di chuyển, reduce, đồng bộ hóa và xử lý hoàn thành vào một đơn vị giao tiếp; một phần các đường dẫn của NCCL dùng Copy Engine trong nút và các luồng proxy CPU giữa các nút (các luồng máy chủ nộp yêu cầu cho NIC thay cho GPU) để xử lý việc di chuyển dữ liệu. Cái mà các cơ chế này thay đổi là ai thực hiện công việc này. Nếu tính toán bị chậm vì tranh chấp SM với giao tiếp, giải phóng các SM sẽ rút ngắn tính toán; nếu nút thắt là một lối ra mạng dùng chung, số byte phải đi qua lối ra đó là không đổi.

Ai khởi xướng một yêu cầu giao tiếp quyết định đường điều khiển đi qua PCIe bao nhiêu lần, và cũng quyết định lõi của ai bị chiếm. Hình 6-29 so sánh ba vị trí. Luồng proxy CPU (CPU proxy thread): sau khi GPU tính xong dữ liệu, nó ghi một cờ sẵn sàng vào bộ nhớ máy chủ; một luồng CPU thăm dò và phát hiện cờ đó, xây dựng một bộ mô tả yêu cầu (một bản ghi mô tả một lần truyền), và rung chuông doorbell của NIC (ghi một thanh ghi NIC để báo cho nó có yêu cầu mới); NIC sau đó đọc bộ mô tả yêu cầu từ bộ nhớ máy chủ. Bản ghi hoàn thành cũng được ghi lại lên máy chủ, và CPU chuyển tiếp nó cho GPU. Đường điều khiển đi qua PCIe ba lần, mỗi lần vài trăm nano giây; một luồng CPU chỉ có thể xử lý được một số lượng yêu cầu giới hạn mỗi giây, nên các batch lớn gồm yêu cầu nhỏ xếp hàng tại đây. SM của GPU: GPU trực tiếp xây dựng bộ mô tả yêu cầu và rung doorbell trong bộ nhớ của chính nó; NIC đọc bộ mô tả yêu cầu từ bộ nhớ GPU, và bản ghi hoàn thành được ghi lại vào bộ nhớ GPU để SM thăm dò. CPU bị loại khỏi đường tới hạn, nhưng đường điều khiển vẫn đi qua PCIe hai lần; cái giá phải trả là một số SM phải được dành cho việc xây dựng yêu cầu và thăm dò hoàn thành, và các SM đó không thể đồng thời làm phép nhân ma trận. GPUDirect Async của NVIDIA và kernel độ trễ thấp của thư viện giao tiếp parallelism expert DeepEP đi theo đường này. Một bộ xử lý trên NIC: các NIC như BlueField có bộ xử lý đường dẫn dữ liệu đa lõi, đa luồng tích hợp sẵn, nên việc xây dựng bộ mô tả yêu cầu, rung doorbell và nạp bộ mô tả yêu cầu đều có thể nằm gọn trong NIC; máy chủ chỉ cần phát một lần kích hoạt duy nhất cho một batch phép toán. Đường điều khiển không còn đi qua PCIe và không chiếm SM lẫn lõi CPU. Trên cả ba vị trí, payload ở đầu khởi xướng phải được chuyển ra khỏi bộ nhớ GPU, và bản ghi hoàn thành được ghi lại vào bộ nhớ GPU, mỗi thứ đi qua PCIe đúng một lần — hai hạng mục này không đổi theo vị trí khởi xướng. NIC nhận đọc và ghi bộ nhớ trên máy chủ của nó, đi qua PCIe thêm một lần nữa ở phía đó. Sự đánh đổi vì vậy là: ai cung cấp các lõi, đường điều khiển dài bao nhiêu, và mỗi giây có bao nhiêu yêu cầu có thể được khởi xướng. Mục 7.3.3 sẽ cộng lại thời gian của mỗi lần đi qua, và Mục 7.3.4 sẽ đưa tốc độ khởi xướng vào mô hình thông lượng.

Hình 6-29: Ba vị trí khởi xướng. Màu cam là thành phần xây dựng bộ mô tả yêu cầu; nét đứt là ranh giới PCIe. Đường điều khiển của luồng proxy CPU đi qua PCIe ba lần, của GPU hai lần, và của bộ xử lý trên NIC không lần nào; payload ở đầu khởi xướng và bản ghi hoàn thành mỗi thứ đi qua PCIe một lần trong cả ba cách tiếp cận.

Quay lại 128 phép reduce khối lượng dữ liệu nhỏ từ đầu mục này. Framework chọn một hiện thực hóa giao tiếp dựa trên khối lượng dữ liệu và phương thức kết nối. Khi Qwen3-32B xử lý 1, 4 hoặc 16 token mỗi lần, đầu vào reduce lần lượt là 10, 40 hoặc 160 KiB, và các framework như vLLM có thể chọn những hiện thực hóa chuyên dụng cho các khối lượng dữ liệu nhỏ này. Điều này cho TART_{\mathrm{AR}} trong phương trình (6-5) hai hướng cải thiện: giảm số vòng thuật toán, hoặc rút ngắn chi phí phần mềm và thực thi trên mỗi vòng.

Thí nghiệm 6-5 · Mở rộng: tối ưu hóa giao tiếp tiết kiệm được bao nhiêu thời gian, và khi nào nó bù đắp được chi phí thiết lập?

(a) Dùng các giá trị đo được từ Hình 6-27 và 6-28, tìm thời gian tiết kiệm được khi chạy đồng thời so với chạy riêng rẽ ở 4 MiB và ở 64 MiB, và chỉ ra trong mỗi trường hợp tính toán hay giao tiếp quyết định thời gian hoàn thành tổng thể.

(b) Giả sử một vòng tinh chỉnh tốn thêm SS thời gian tìm kiếm và chuyển đổi, và mỗi lời gọi sau tiết kiệm Δ\Delta. Viết ra số lời gọi tối thiểu cần để phần tiết kiệm tích lũy lần đầu tiên vượt SS; dùng lợi ích chồng lấn đo được ở 64 MiB làm Δ\Delta, tìm số lời gọi cần khi S=1S=1 s.

(c) Dùng hai vector mỗi vector hai phần tử, so sánh kết quả của việc reduce trước rồi áp dụng RMSNorm với việc áp dụng RMSNorm riêng rẽ rồi mới reduce, và xác định hai thứ tự có thể hoán đổi cho nhau không.

(d) Tuỳ chọn accelerator: so sánh việc thực thi độc quyền và đồng thời với cùng một hình dạng, ghi lại các sự kiện sẵn sàng, bắt đầu và hoàn thành, và giải thích đoạn nào thay đổi nhiều nhất khi tài nguyên bị chia sẻ.

6.5 Tổ chức vật lý của supernode

6.5.1 Kết nối trực tiếp, chuyển mạch và tô pô phân cấp

Các thuật toán và thư viện giao tiếp ở Mục 6.4 quyết định ai gửi gì cho ai, và gửi bao nhiêu, trong mỗi vòng, nhưng chúng không nói gì về những kết nối vật lý mà dữ liệu đi qua. Các thuật toán tập thể xác định người gửi và người nhận logic; tô pô (topology) vật lý quyết định dữ liệu thực sự đi qua những thiết bị và liên kết nào. Hai card có thể kết nối trực tiếp, hoặc chúng có thể đi vòng qua một switch, một card khác, hoặc bộ nhớ máy chủ. Khi nhiều lần truyền dùng chung một cổng, chúng phải xếp hàng cho cùng một băng thông.

Ví dụ làm việc: Thêm một máy chủ nữa có khiến TP16 nhanh hơn TP8 không? Hai máy chủ HGX H100, tổng cộng 16 card, được kết nối giữa các máy chủ bằng NIC ConnectX-7 của từng card. Chuyển một phiên ngữ cảnh 128K của Qwen3-32B sang TP16 nghĩa là một nhóm song song tensor trải qua cả hai máy chủ, và mọi AllReduce của mỗi lớp phải đi qua mạng.

Lời giải: Về truy cập bộ nhớ cục bộ, trọng lượng lại bị chia đôi một lần nữa, nhưng Qwen3-32B chỉ có 8 KV head, nên ở TP16 mỗi KV head được lưu một bản trên mỗi của hai card, và KV mỗi card đọc vẫn như ở TP8 — thời gian cục bộ chỉ giảm từ 3.67 ms xuống 2.48 ms. Về giao tiếp, nếu 16 card tạo thành một vòng, mỗi vòng phải chờ bước nhảy đi qua NIC; lấy độ trễ một chiều InfiniBand (mạng chuyển mạch độ trễ thấp dùng giữa các máy chủ) là 3.76 μs đo được trên cùng nền tảng trong bài báo MSCCL++, một phép reduce mất 30 vòng, khoảng 113 μs. Các thư viện giao tiếp thực tế không làm theo cách này. Kết quả nccl-tests (điểm chuẩn giao tiếp tập thể của NCCL) được lưu trong Thí nghiệm 7-3 tình cờ có một AllReduce đúng trên hai máy chủ HGX H100 với 16 rank; với thông điệp 10 KiB, lấy bucket 16 KiB được ghi lại, giá trị đo được là 32.74 μs:

T(16)≈2.48 ms+128×32.74 μs≈6.67 ms.T(16)\approx2.48\ \mathrm{ms}+128\times32.74\ \mu\mathrm{s}\approx6.67\ \mathrm{ms}.

TP8 trong một máy chủ duy nhất là 5.15 ms, nên TP16 thực tế chậm hơn khoảng 1.52 ms. Các card thêm vào làm giảm lượng đọc trọng lượng trên mỗi card, nhưng cái giá phải trả là đồng bộ hóa chéo máy chủ tốn kém hơn; ngay cả khi dùng thuật toán phân cấp của một thư viện giao tiếp thực tế, mỗi phép reduce vẫn mất khoảng 33 μs — gần gấp ba lần 11.55 μs của một phép reduce vòng trong máy.

Muốn nhiều card hơn phối hợp hiệu quả cần đủ cổng và đủ dung lượng chuyển mạch. Nếu một card kết nối trực tiếp với tất cả N−1N-1 card khác, nó cần N−1N-1 kết nối. Switch hợp nhất các kết nối: một card trước tiên kết nối với tầng chuyển mạch, tầng này rồi chuyển tiếp đến đích. Số cổng mà một chip switch cung cấp được gọi là radix của nó.

Lấy NVSwitch thế hệ thứ ba dùng trong HGX H100 làm ví dụ: một chip có 64 cổng NVLink 4, mỗi cổng 25 GB/s mỗi chiều. Dùng làm leaf switch: 32 cổng kết nối xuống các GPU và 32 cổng còn lại kết nối lên các spine switch, cho 800 GB/s tổng băng thông ở cả phía GPU lẫn phía uplink. Nếu thay vào đó cấu hình 48 cổng xuống và 16 cổng lên, nhiều liên kết GPU có thể gắn hơn, nhưng cùng lúc chúng chỉ có thể gửi tối đa 400 GB/s đi lên — chỉ một phần ba tổng băng thông hạ lưu. Với tổng số cổng cố định, kết nối nhiều GPU hơn đồng nghĩa với ít cổng uplink hơn và ít băng thông uplink hơn. NVLink Switch System của DGX H100 (hệ thống hoàn chỉnh của NVIDIA dựa trên HGX H100) kết nối nhiều máy chủ vào cùng một cấu trúc chuyển mạch NVLink bằng đúng sự đánh đổi này: mỗi nút chỉ phơi ra một nửa tổng băng thông NVLink của nó ra bên ngoài nút, tức hội tụ 2:1.

Hình 6-30: Hai cách phân bổ cùng một chip NVSwitch 64 cổng, mỗi cổng 25 GB/s mỗi chiều. Uplink là lối ra dùng chung cho toàn bộ lưu lượng xuyên switch; phân bổ 32/32 cung cấp 800 GB/s băng thông uplink, còn phân bổ 48/16 chỉ cung cấp 400 GB/s. Số ô trong mỗi thanh màu khớp với số cổng.

Mở rộng tầng chuyển mạch ra ngoài một chip: bốn chip leaf switch mỗi chip 32 cổng hạ lưu cho 128 cổng hạ lưu tổng cộng. Ghép với 32 chip spine switch, mỗi chip kết nối một liên kết với mỗi trong bốn chip leaf switch, lấp đầy đúng 32 uplink của mỗi chip leaf switch. Nếu một hệ thống được chia làm hai phần, tất cả các liên kết nối hai phần lại với nhau được gọi là một tập cắt (cut set). Nếu một giai đoạn nào đó cần VA→BV_{A\to B} byte đi qua tập cắt từ phía A sang phía B, và tổng băng thông của tập cắt theo hướng đó là BA→BB_{A\to B}, việc truyền cần ít nhất VA→B/BA→BV_{A\to B}/B_{A\to B}. Việc phân bổ cổng của switch quyết định tổng băng thông của tập cắt.

Số cổng quyết định tổng cộng có bao nhiêu liên kết; định tuyến quyết định dữ liệu tập trung lên những liên kết nào. Ngay cả khi mọi card gửi cùng một lượng dữ liệu, các đường đi khác nhau tạo ra những nút thắt khác nhau. Nối 16 card thành một vòng vật lý hai chiều và quan sát ba vòng đầu của một ReduceScatter trên đầu vào 8 MiB. Một thuật toán đệ quy nhân đôi khoảng cách đến đồng cấp mỗi vòng; Swing là một thuật toán giao tiếp tập thể thiết kế cho tô pô hình xuyến (torus) giúp trải tải liên kết bằng cách thay đổi đồng cấp mỗi vòng. Cả hai thuật toán đều khiến mỗi card gửi cùng 4, 2, 1 MiB mỗi vòng, nhưng đến các đồng cấp khác nhau:

Ba vòng đầu tiênĐường đi đệ quyĐường đi Swing
Số bước nhảy vật lý mỗi lần truyền1, 2, 41, 1, 3
Lượng truyền tối đa trên một liên kết có hướng4, 4, 4 MiB4, 2, 2 MiB
Tổng truyền tích lũy trên mọi liên kết vật lý64, 64, 64 MiB64, 32, 48 MiB

Trong vòng thứ ba, dữ liệu của thuật toán đệ quy đi bốn bước nhảy, và liên kết bận nhất đồng thời mang bốn lần truyền 1 MiB; dữ liệu của Swing đi ba bước nhảy, và liên kết bận nhất của nó chỉ mang hai. Ở 50 GB/s mỗi chiều mỗi liên kết ICI (inter-chip interconnect) của TPU v4, thời gian truyền do liên kết nút thắt quyết định cho ba vòng đầu lần lượt khoảng 252 và 168 μs. Thời gian truyền giảm một phần ba vì có ít dữ liệu hơn trên liên kết dùng chung.

Hình 6-31: Vòng thứ ba của thuật toán đệ quy, card 0 gửi đến card 4. Các đường mảnh tạo thành vòng vật lý 16 card; các mũi tên đánh dấu bốn liên kết đi qua.

Hình 6-32: Trên cùng một vòng vật lý, vòng thứ ba của Swing có card 0 gửi đến card 3, đi qua ba liên kết. Lượng gửi của mỗi card trong vòng này vẫn là 1 MiB.

Hình 6-33: Cộng dữ liệu của mọi người gửi lên mỗi liên kết có hướng, rồi lấy giá trị lớn nhất mỗi vòng. Ba vòng đầu của thuật toán đệ quy đều là 4 MiB; của Swing là 4, 2, 2 MiB.

Việc đi vòng qua bộ nhớ máy chủ là một dạng khác của cùng một vấn đề. Truy cập bộ nhớ không đồng nhất (non-uniform memory access, NUMA) tổ chức bộ nhớ máy chủ gần các CPU khác nhau, nên việc đọc chéo CPU phải đi qua giao diện giữa các bộ xử lý. Giả sử card 0 và 1 gắn vào nút NUMA A, còn card 2 và 3 gắn vào nút B; một ring reduce trên bốn card gửi 48 MiB tổng cộng. Nếu mọi bộ đệm trung chuyển được đặt trên A, liên kết giữa các CPU phải mang 24 MiB mỗi chiều; nếu bộ đệm được đặt gần card gửi, và các card trên cùng nút NUMA được đặt liền nhau trong vòng, con số này giảm xuống 12 MiB mỗi chiều; nếu vòng thay vào đó xen kẽ qua các nút NUMA, nó lại về 24 MiB mỗi chiều. Máy chủ của DGX H100 là thiết kế hai socket: hai bộ xử lý Xeon 8480C mỗi bộ có nút NUMA riêng, tối đa 4 liên kết UPI (interconnect giữa các bộ xử lý Intel) giữa hai CPU, mỗi liên kết 16 GT/s; mỗi GPU kết nối với máy chủ qua PCIe Gen5 x16 ở 64 GB/s mỗi chiều. Qua ba sơ đồ, lượng dữ liệu mỗi card chuyển vào và ra qua PCIe là như nhau, nhưng lượng dữ liệu qua UPI biến đổi theo tỷ lệ 2:1:2, và thời gian truyền chéo CPU biến đổi tương ứng. Vị trí của bộ đệm và thứ tự của card trong vòng cùng nhau quyết định đường đi của dữ liệu.

Tình huống thiết kế: torus kết nối trực tiếp hay mạng chuyển mạch? Trong các ví dụ trên, dữ liệu hoặc đi thẳng qua một liên kết, hoặc đi qua một switch. Kết nối 64 card thành một supernode có hai cách tiếp cận phổ biến. Một là kết nối mỗi card trực tiếp với các card lân cận: sắp 64 card thành một khối lập phương 4×4×44\times4\times4, mỗi card kết nối với hai lân cận dọc theo mỗi trong ba chiều, và mỗi chiều vòng ngược từ đầu nọ đến đầu kia — đây là một torus ba chiều. Torus là một tô pô được siêu máy tính dùng từ lâu, và TPU kế thừa nó. Cách tiếp cận kia kết nối mỗi card chỉ với các chip switch, chip switch chuyển tiếp đến đích; NVL72 và CloudMatrix384 đi theo hướng này. Cả hai cách đều cho mỗi card cùng sáu cổng ở 50 GB/s mỗi chiều — đúng cấu hình ICI trên mỗi chip của TPU v4; khác biệt là đầu kia của mỗi cổng kết nối với một card lân cận hay với một chip switch. Hình 6-34 cho thấy đường đi của một lần truyền đơn lẻ dưới cả hai sơ đồ kết nối.

Hình 6-34: Bên trái là một lớp của torus 3D, mỗi card kết nối trực tiếp với bốn lân cận, với các đường nét đứt thể hiện mỗi chiều vòng ngược đầu nọ đầu kia; một card ở góc đến một card ở trung tâm mất bốn bước nhảy, cộng thêm tối đa sáu bước nhảy khi tính thêm chiều thứ ba. Bên phải là mạng chuyển mạch, nơi bất kỳ hai card nào cũng cách nhau hai liên kết cộng một bước chuyển mạch. Màu cam đánh dấu cặp card xa nhất; đường đậm là đường đi của lần truyền của chúng.

Trước tiên so sánh số bước nhảy (hop count). Trong torus, hai card xa nhất cách nhau hai bước nhảy mỗi chiều, sáu bước nhảy qua ba chiều; trong mạng chuyển mạch, bất kỳ hai card nào cũng cách nhau hai liên kết cộng một bước chuyển tiếp. Giả sử mỗi lần đi qua bộ định tuyến của một chip hoặc một chip switch thêm 200 ns — đây là mục tiêu độ trễ không tải mà tiêu chuẩn interconnect accelerator mở UALink 2.0 đặt ra cho một chip switch 128 làn (kênh nối tiếp); thời gian truyền lan trên liên kết được bỏ qua. Hai card xa nhất trên torus phải đi qua 5 chip trung gian, so với chỉ 1 chip switch trên mạng chuyển mạch, nên torus tốn thêm 0.8 μs mỗi lần truyền. Khoảng cách giữa các instance đơn lẻ là nhỏ, nhưng decode thực hiện hai phép reduce mỗi lớp, và 64 lớp của Qwen3-32B nghĩa là 128 lần; nếu mọi lần đều phải chờ card xa nhất, torus tích lũy thêm khoảng 0.10 ms chờ đợi — khoảng 7% của 1.48 ms tổng thời gian reduce cho TP tám card. Khi số card tăng lên 83=5128^3=512, khoảng cách xa nhất của torus trở thành mười hai bước nhảy; mạng chuyển mạch chỉ cần thêm một cấp chuyển mạch nữa, trở thành bốn liên kết cộng ba bước chuyển tiếp.

Tiếp theo so sánh các kiểu lưu lượng. Kiểu thứ nhất là reduce theo chiều: tách AllReduce thành ReduceScatter và AllGather dạng vòng dọc theo các hướng x, y và z, chỉ truyền giữa các card liền kề ở mỗi bước, với cả sáu liên kết hoạt động đồng thời. Ở đây torus dùng trọn băng thông của mọi cổng trên mỗi card, ngang bằng tốc độ của mạng chuyển mạch. Trình biên dịch TPU ánh xạ các nhóm song song dữ liệu và song song mô hình đúng lên các chiều của torus. Kiểu thứ hai là All-to-All đều: mỗi card gửi một phần đến mỗi trong 63 card còn lại, đó là kiểu của dispatch MoE. Trên torus, mỗi phần trung bình đi ba bước nhảy (trung bình một bước nhảy mỗi chiều); với 64 card mỗi card gửi MM byte, mọi liên kết cùng nhau phải mang 3×64M3\times64M, trải trên 384 liên kết có hướng, cho M/2M/2 mỗi liên kết. Trên mạng chuyển mạch, mỗi trong sáu cổng của mỗi card mang M/6M/6. Lấy M=32M=32 MiB, torus cần ít nhất khoảng 336 μs và mạng chuyển mạch khoảng 112 μs — chênh gấp ba lần; ở 512 card, trung bình sáu bước nhảy của torus làm khoảng cách rộng ra gấp sáu lần. Hình 6-35 đặt hai kiểu cạnh nhau.

Hình 6-35: Sáu cổng 50 GB/s mỗi card, mỗi card gửi 32 MiB. Cả hai tô pô đều dùng đủ băng thông cổng cho reduce theo chiều; với All-to-All đều, dữ liệu của torus trung bình đi ba bước nhảy, nên lượng dữ liệu do các liên kết dùng chung mang tăng lên, lên sáu bước nhảy ở 512 card. Hình thể hiện cận dưới do tải liên kết quyết định, loại trừ chi phí khởi tạo và xếp hàng; mạng chuyển mạch được tính như không nghẽn, tức tầng chuyển mạch không giới hạn mọi cổng gửi và nhận đồng thời ở tốc độ tối đa.

Cuối cùng so sánh chi phí phần cứng. Một torus 64 card cần 64×6/2=19264\times6/2=192 liên kết và không cần chip switch nào — bộ định tuyến được nhúng ngay trong mỗi chip; mạng chuyển mạch cần 384 liên kết và sáu chip switch 64 cổng. Một khi số card vượt quá số cổng của một chip switch, mạng chuyển mạch cần thêm một cấp: CloudMatrix384 đặt 7 chip switch cấp một trong mỗi 48 nút cho 384 NPU của nó, rồi nối chúng qua 7 sub-plane mỗi sub-plane 16 chip switch cấp hai, tổng cộng 448 chip switch, với các chip switch cấp hai được đặt trong 4 tủ truyền thông. Torus, ngược lại, chỉ cần sáu liên kết mỗi card ở bất kỳ quy mô nào, cái giá là số bước nhảy tăng theo quy mô và băng thông tập cắt trên mỗi card giảm theo quy mô — Mục 6.5.4 sẽ tính điều này.

Cùng nhau, ba phép so sánh này tạo thành cơ sở để chọn tô pô: khối lượng công việc có bị chi phối bởi giao tiếp tập thể đều đặn, hay bởi một lượng lớn các lần truyền nhỏ với đích tùy ý và kiểu All-to-All; miền hợp tác cần bao nhiêu card; và liệu có đáng đánh đổi chip switch cùng hệ thống cáp nhiều hơn để lấy khoảng cách bằng nhau giữa bất kỳ hai card nào. Các Mục 6.5.3 đến 6.5.5 xem xét lần lượt các lựa chọn mà NVIDIA, Google và Huawei từng đưa ra trên ba câu hỏi này.

Thí nghiệm 6-6 · Mở rộng: tô pô giao tiếp và vị trí bộ đệm ảnh hưởng thời gian truyền như thế nào

(a) Tính lại thời gian một bước của TP16 trên hai máy chủ HGX H100, rồi tìm thời gian AllReduce chéo máy chủ cần giảm xuống bao nhiêu để thời gian một bước của TP16 khớp chính xác với TP8 trong một máy chủ duy nhất.

(b) Với một NVSwitch 64 cổng, so sánh hai phân bổ cổng hạ lưu/uplink 32/32 và 48/16, và tính băng thông trung bình khả dụng mỗi liên kết khi mọi liên kết GPU cùng gửi đi lên.

(c) Dùng Hình 6-31, cộng khối lượng dữ liệu đi qua cùng một liên kết có hướng trong vòng thứ ba, và giải thích sự khác biệt giữa số bước nhảy và lượng truyền trên liên kết.

(d) Trong ví dụ NUMA, trước tiên di chuyển bộ đệm, rồi đổi thứ tự vòng, và vẽ sơ đồ các truy cập chéo CPU được thêm vào và loại bỏ trong mỗi trường hợp.

(e) Đổi tình huống thiết kế 64 card thành một torus 8×8×88\times8\times8, tìm số bước nhảy tối đa, tải trên mỗi liên kết có hướng cho All-to-All đều, và mạng chuyển mạch không nghẽn hai cấp cần bao nhiêu chip switch 64 cổng; giải thích đại lượng nào tăng nhanh nhất theo số card.

6.5.2 Môi trường interconnect, cấp nguồn và quy mô vật lý

Mục 6.5.1 coi một liên kết như một kết nối có băng thông và độ trễ cho trước; xây dựng những kết nối này trong một hệ thống thực còn đòi hỏi giải quyết các vấn đề khoảng cách truyền, đi dây cáp và cấp nguồn. Mở rộng sự hợp tác độ trễ thấp ra xa hơn đòi hỏi môi trường kết nối cũng phải thay đổi. Dây đồng khoảng cách ngắn có thể trực tiếp mang các tín hiệu điện tốc độ cao; khoảng cách càng lớn, suy hao tín hiệu và nhiễu xuyên kênh càng tệ, khiến bên nhận khó khôi phục dữ liệu và clock hơn, đòi hỏi các mạch cân bằng hay định thời lại mạnh hơn. Cáp dày hơn và nhiều kết nối hơn cũng chiếm không gian khung máy và đi dây. Chọn môi trường kết nối đòi hỏi cân nhắc cùng lúc khoảng cách truyền, suy hao tín hiệu và mật độ đi cáp.

Kết nối quang điều chế dữ liệu lên một sóng mang quang, phù hợp để vượt qua khoảng cách dài hơn; nhưng chúng cũng thêm chi phí chuyển đổi điện-quang, cấp nguồn thiết bị và bảo trì. Mô-đun quang cắm được (pluggable optical module) đặt việc chuyển đổi trong một mô-đun thay thế được, còn quang học đóng gói chung (co-packaged optics, CPO) đưa engine quang lại gần chip switch hoặc chip tính toán, rút ngắn đường tín hiệu điện tốc độ cao. Cái sau tăng mật độ kết nối trong một gói, nhưng một khi các thiết bị quang được đóng gói chung với chip tính toán hoặc chuyển mạch, việc làm mát, kiểm thử và thay thế linh kiện đều phải được thiết kế cùng nhau. Môi trường kết nối quyết định chi phí hiện thực hóa ở một khoảng cách và băng thông nhất định; tô pô quyết định các kết nối này ghép thành các đường giao tiếp như thế nào.

Việc cấp nguồn còn giới hạn thêm số card có thể lắp đặt. Các card được lắp theo từng máy chủ hoàn chỉnh; gọi ngân sách nguồn của hệ thống là PbP_b, công suất hỗ trợ cố định cho switch, lưu trữ v.v. là P0P_0, và mỗi máy chủ chứa gg card mỗi card tiêu thụ PsP_s, thì

N≤g⌊Pb−P0Ps⌋.(6-11)N\le g\left\lfloor\frac{P_b-P_0}{P_s}\right\rfloor. \tag{6-11}

Với DGX H100, trần công suất hệ thống cho tám H100 cùng CPU, NVSwitch, các NIC và quạt là 10.2 kW, trung bình 1.275 kW mỗi card; bản thân H100 SXM có trần công suất 700 W, phần còn lại đến từ các linh kiện hỗ trợ của máy chủ. Giả sử ngân sách nguồn của một nhóm rack là 120 kW; ví dụ này chỉ tính các máy chủ, lấy P0P_0 bằng 0, cho phép tối đa 11 máy chủ, tức 88 card. 64 card (8 máy chủ) tiêu thụ 81.6 kW, 72 card (9 máy chủ) tiêu thụ 91.8 kW, và 96 card (12 máy chủ) sẽ cần 122.4 kW, vượt ngân sách nguồn; các phương án 64 card và 72 card vẫn cần cấu hình cụ thể của chúng được quyết định bởi số cổng switch và không gian lắp đặt.

Làm mát cho một cận trên khác. Các rack làm mát bằng không khí (air-cooled) mang nhiệt đi bằng quạt đẩy không khí vào phòng: sách trắng làm mát bằng chất lỏng của ASHRAE ghi rằng một rack 40 đến 50 kW cần tới 5.000 cfm (feet khối mỗi phút) luồng khí, trong khi các cửa cấp khí sàn tốt nhất chỉ cung cấp 1.900 cfm; trong một rack 50 kW, riêng quạt đã tiêu thụ ít nhất 5 kW. Ví dụ này lấy 40 kW làm ngưỡng cho rack làm mát bằng không khí: một rack có thể chứa tối đa 3 đơn vị DGX H100, tức 24 card ở 30.6 kW; 4 đơn vị sẽ cần 40.8 kW; các bố cục rack ví dụ trong kiến trúc tham chiếu DGX SuperPOD H100 đều vượt 40 kW mỗi rack. Mức 81.6 kW cho 64 card và 91.8 kW cho 72 card, nếu dồn vào một số ít rack, đều vượt xa ngưỡng này, buộc phải chuyển sang làm mát bằng chất lỏng, loại hình đưa nhiệt trực tiếp vào một chất làm mát thay vì ra không khí phòng.

Nếu một đơn vị chuyển mạch chỉ kết nối được 64 điểm cuối, việc thêm card thứ 65 có thể đòi hỏi một bộ thiết bị chuyển mạch bổ sung hoàn chỉnh. Khi số card tăng từng bước, chi phí cho thiết bị chuyển mạch hỗ trợ không tăng trơn tru, mà nhảy vọt mỗi khi vượt qua một ranh giới nhóm như vậy. Chỉ sau khi dùng công thức (6-11) tìm khoảng sơ bộ, rồi ghép theo các đơn vị lắp đặt như switch, khay và rack, mới có thể đi đến một hệ thống xây dựng được.

Thí nghiệm 6-7 · Mở rộng: ngân sách nguồn và yêu cầu quy mô toàn nhóm giới hạn số accelerator như thế nào

(a) Tính lại tổng công suất cho việc lắp 64, 72 và 96 card, và dùng công thức (6-11), tìm số card tối đa lắp được khi ngân sách nguồn tăng lên 150 kW.

(b) Nếu, sau 64 card, một cấp thiết bị chuyển mạch thứ hai phải dự phòng công suất tương đương một máy chủ, 10.2 kW, tìm số card tối đa lắp được dưới ngân sách nguồn 120 kW.

(c) Giữ nguyên ngân sách nguồn và điều kiện thiết bị chuyển mạch thêm từ (b), giả định các card chỉ có thể được thêm theo từng nhóm bốn máy chủ hoàn chỉnh (32 card), tìm số card tối đa lắp được, và giải thích vì sao các cận trên ở (a) đến (c) khác nhau.

(d) Dùng các thời gian phục vụ một instance thu được trước đó, so sánh năng lực phục vụ của hai trong số các cấu hình accelerator này.

6.5.3 NVIDIA: Từ máy chủ tám card đến quy mô rack

Cổng, khoảng cách và nguồn cùng nhau ràng buộc quy mô hệ thống. Dưới những ràng buộc này, các thế hệ hệ thống kế tiếp của NVIDIA đã tiến hóa interconnect từ kết nối trực tiếp trong khung máy đến mạng chuyển mạch quy mô rack. DGX-1 dùng tám GPU trong một mạng lai khối-lập phương NVLink, nơi một số GPU kết nối trực tiếp còn những GPU khác phải đi vòng qua các trung gian. Việc đặt các tác vụ tính toán giao tiếp thường xuyên lên các GPU liền kề giảm áp lực đi vòng và liên kết dùng chung.

DGX-2 dùng 16 V100 và NVSwitch. Cấu trúc chuyển mạch biến “một cặp GPU nhất định có kết nối trực tiếp hay không” thành “tầng chuyển mạch có thể chuyển tiếp bao nhiêu dữ liệu đồng thời”, mở rộng phạm vi hợp tác khả dụng. DGX A100 lại dùng máy chủ tám card làm đơn vị cơ sở, trang bị NVLink/NVSwitch. Các hệ thống này áp dụng số lượng GPU và cấu trúc interconnect khác nhau để thích ứng với giao diện chip, không gian khung máy và nhu cầu ứng dụng.

GB200 NVL72 đặt 72 GPU và 36 Grace CPU vào một hệ thống NVLink quy mô rack. Nhiều GPU hơn trong rack nhờ vậy có thể trao đổi dữ liệu thường xuyên qua NVLink. Quay lại ví dụ làm việc ở Mục 6.5.1: khi TP16 của Qwen3-32B trải qua hai máy chủ HGX H100, 128 phép reduce qua mạng mất khoảng 4.19 ms, với một bước khoảng 6.67 ms. Nếu 16 card đó nằm trong cùng một miền chuyển mạch NVLink (NVLink Switch System của DGX H100 kết nối tối đa 256 H100), ở khoảng 0.822 μs mỗi vòng, một ring reduce 16 card mất 30 vòng, nên 128 lần mất khoảng 3.16 ms, với một bước khoảng 5.64 ms — vẫn chậm hơn 5.15 ms của TP8 trong một máy chủ duy nhất. Mô hình này chỉ có 8 KV head, nên ở TP16 KV mỗi card đọc không còn giảm, trong khi số vòng ring tăng gấp đôi. Với loại mô hình này, giá trị của một miền interconnect lớn hơn không nằm ở việc cắt một phiên đơn lẻ mịn hơn, mà ở việc chứa được nhiều instance hơn, hoặc chứa một mô hình vượt quá dung lượng của một máy chủ duy nhất.

Interconnect quy mô rack cho phép nhiều GPU hơn tham gia cùng một instance. Với các mô hình nhỏ vừa một card, số instance có thể được chọn theo yêu cầu độ trễ và thông lượng; với các mô hình lớn có trọng lượng vượt tổng dung lượng một máy chủ, có thể dùng nhiều GPU hơn để giữ trọng lượng, với giao tiếp của mỗi lớp chạy qua interconnect trong rack.

6.5.4 TPU: Đồng thiết kế tô pô và khối lượng công việc

Cách tiếp cận của NVIDIA dùng một tầng chuyển mạch để mở rộng phạm vi kết nối của GPU. Đơn vị Xử lý Tensor của Google thay vào đó đi theo hình xuyến từ tình huống thiết kế ở Mục 6.5.1, khiến việc phân chia mô hình, bố cục của trình biên dịch và giao tiếp vật lý tương ứng với nhau. Một hình xuyến hai chiều kết nối các chip dọc theo hai chiều, mỗi chiều vòng ngược đầu nọ đầu kia; hình xuyến ba chiều bổ sung thêm một chiều, cho phép dữ liệu đi theo nhiều hướng hơn.

TPU v4 dựa trên một đơn vị kết nối điện 4×4×44\times4\times4, 64 chip, với các công tắc quang (OCS, vốn thay đổi đường quang để kết nối cổng thiết bị) sau đó nối nhiều đơn vị lại với nhau. Sự phân chia này tính đến cả tô pô mạng lẫn lắp đặt vật lý: 64 chip và 16 CPU máy chủ vừa vào một rack, còn đơn vị 838^3 lớn hơn, chứa 512 chip, đòi hỏi các kết nối xuyên rack.

Băng thông tập cắt có thể được dùng để phân tích năng lực giao tiếp của tô pô đều đặn này khi nó mở rộng. Cắt hai một hình xuyến ba chiều k×k×kk\times k\times k dọc theo một chiều, số liên kết vật lý đi qua hai nửa (tức tập cắt này, được gọi là các liên kết bisection) là 2k22k^2 tổng cộng. Khi kk tăng từ 4 lên 8, số chip tăng từ 64 lên 512 — gấp tám lần — nhưng các liên kết tập cắt chỉ tăng từ 32 lên 128 — gấp bốn lần. Nếu mỗi chip phải gửi cùng một lượng dữ liệu sang nửa còn lại, băng thông tập cắt trung bình mỗi chip bị giảm đi một nửa. Sự khác biệt về tốc độ tăng giữa số chip và băng thông tập cắt quyết định những bố cục song song nào phù hợp với hình dạng này.

Hình 6-36: Cắt hai một mạng xuyến ba chiều dọc theo một chiều đòi hỏi cắt cả các kết nối giữa và các kết nối vòng ngược. Mỗi vị trí chứa k² liên kết, tổng cộng 2k².

Hình 6-37: Khi k tăng từ 4 lên 8, số chip tăng từ 64 lên 512, và các liên kết bisection tăng từ 32 lên 128. Cả hai đường tăng trưởng được chuẩn hóa về k = 4. k biểu thị số nút mỗi chiều của hình xuyến ba chiều, với tổng số nút k³.

Một tô pô cố định quyết định băng thông xuyên phân vùng, nhưng vị trí của các chip nhàn rỗi cũng quyết định một công việc có thể có được hình dạng nó cần hay không. OCS kết nối lại các đơn vị kết nối điện này ở quy mô lớn hơn, gán các tập con chip có hình dạng phù hợp cho các công việc khác nhau — một tập con như vậy được gọi là một slice. Lấy một lưới chip 4×4 làm ví dụ: nếu hai hàng liên tiếp nhàn rỗi, nó có thể chứa hai công việc mỗi công việc cần một khối 2×2 chip liền kề; nhưng nếu cùng tám chip nhàn rỗi đó nằm rải rác theo kiểu bàn cờ, không thể tìm thấy bất kỳ khối 2×2 liền kề nào. Việc nối lại có thể thay đổi các hình dạng khả dụng để phân bổ.

Việc nối lại chỉ đáng làm nếu thời gian thực thi tiết kiệm được vượt quá chi phí thời gian của chính việc nối lại. Nghiên cứu Morphlux cấu hình lại tô pô interconnect quang cho từng nhiệm vụ, làm cho kết nối khớp với nhu cầu giao tiếp của nhiệm vụ. Giả sử tám chip TPU v4 thực hiện một ring AllReduce trên đầu vào 8 MiB, mỗi chip gửi 14 MiB. Nếu slice này ban đầu chỉ có một liên kết ICI 50 GB/s khả dụng cho nhóm giao tiếp đó, và việc nối lại cung cấp ba liên kết, số hạng truyền giảm từ khoảng 293.6 μs xuống khoảng 97.9 μs, tiết kiệm khoảng 195.7 μs mỗi lần. OCS của TPU v4 mất thời gian cấp mili giây để bật chuyển đường quang: nếu việc nối lại mất 1 ms, lặp lại 6 lần sẽ thu hồi được chi phí; nếu nó mất 100 ms, cần 511 lần. Công việc chạy càng lâu, việc thiết lập một kết nối phù hợp hơn càng đáng giá.

6.5.5 Unified Bus và CloudMatrix

Các hệ thống NVIDIA và TPU bắt đầu chủ yếu từ interconnect accelerator. UB của Huawei mở rộng vấn đề hơn nữa sang truy cập tài nguyên: sau khi nối hai máy chủ, một thiết bị trên máy chủ này có thể trực tiếp dùng bộ nhớ của một máy chủ khác không? Suy nghĩ ban đầu của tôi về Unified Bus xuất phát từ ranh giới giữa các bus trong máy chủ và mạng giữa các máy chủ. Đọc cùng một khối dữ liệu trông khác đi một khi nó vượt qua ranh giới máy chủ — phần mềm thường phải chuyển sang một giao diện chuyển thông điệp và sắp xếp lại các bộ đệm, và mỗi lớp trừu tượng hóa thêm vào đều cộng thêm độ trễ. UB nhắm đến việc loại bỏ những lớp trừu tượng này và mở rộng phạm vi truy cập tài nguyên trực tiếp, để tính toán, bộ nhớ và lưu trữ có thể được kết hợp lại theo từng nhiệm vụ.

Cuốn sách này thảo luận UB ở hai nơi. Mục này coi UB như một dạng interconnect của supernode và trả lời ba câu hỏi liên quan đến quy mô: bộ điều khiển nằm ở đâu, bộ đệm trên chip có thể giữ bao nhiêu trạng thái interconnect, và việc thiết lập tất cả các kết nối mất bao lâu. Chương 7 thay vào đó theo dõi đường đi của một lần truy cập từ xa đơn lẻ: Mục 7.1.3 giải thích động lực thiết kế của giao diện thống nhất, Mục 7.3.3 suy ra độ trễ của một lần đọc bằng mô hình từng giai đoạn, Mục 7.3.4 tính tốc độ yêu cầu, Mục 7.4.2 suy ra sự tăng trưởng của trạng thái kết nối và điểm tràn của bộ đệm trên chip, và Mục 7.4.3 thảo luận về thứ tự theo yêu cầu. Cả hai nơi dùng cùng một bộ tham số và cùng một script tính toán, và các kết quả suy ra được kiểm chứng với các giá trị tôi đo trong mô phỏng cho hiện thực hóa UB của riêng tôi, OpenURMA.

Loại thống nhất này trước tiên phải trả lời hai câu hỏi khác nhau: với một phép toán nhất định, nó truy cập ai, đọc hoặc ghi gì, và khi nào kết quả có thể được dùng; và dữ liệu của phép toán đó đi qua mạng và đến nơi một cách tin cậy như thế nào. UB đặt trách nhiệm thứ nhất trong tầng giao dịch (transaction layer) và trách nhiệm thứ hai trong tầng vận chuyển (transport layer). “Giao dịch” ở đây chỉ một phép toán giao tiếp đơn lẻ, không phải giao dịch cơ sở dữ liệu với ngữ nghĩa commit và rollback.

Jetty của tầng giao dịch cung cấp cho các ứng dụng các trừu tượng điểm cuối cho việc nộp, nhận và thông báo hoàn thành, giữ lại định danh ứng dụng và ngữ cảnh mà một phép toán cần; kênh vận chuyển của tầng vận chuyển (gọi là TP Channel trong UB, trong đó TP viết tắt cho Transport Protocol và không liên quan gì đến parallelism tensor) duy trì số thứ tự gói, xác nhận (acknowledgment), truyền lại và trạng thái kiểm soát tắc nghẽn. Khi nhiều điểm cuối ứng dụng truy cập cùng một đích từ xa, chúng có thể dùng chung kênh vận chuyển bên dưới, để mỗi mối quan hệ ứng dụng không cần mang bộ trạng thái vận chuyển tin cậy đầy đủ của riêng mình. Hình 6-38 cho thấy sự tách biệt này. Một QP (queue pair, điểm cuối giao tiếp gồm một hàng đợi gửi và một hàng đợi nhận) kết nối tin cậy truy cập bộ nhớ trực tiếp từ xa truyền thống (Remote Direct Memory Access, RDMA, cho phép một NIC đọc và ghi trực tiếp bộ nhớ từ xa được ủy quyền) ràng buộc khá chặt chẽ mối quan hệ điểm cuối ứng dụng với trạng thái vận chuyển; UB thay vào đó để cho hai loại trạng thái này được định cỡ, định thời và chia sẻ một cách độc lập.

Hình 6-38: Hai ứng dụng cục bộ mỗi ứng dụng giữ Jetty của riêng mình và truy cập các điểm cuối từ xa qua một kênh vận chuyển dùng chung. Tầng giao dịch phân biệt các phép toán và quyền sở hữu hoàn thành của chúng; tầng vận chuyển xử lý việc phân phát gói tin tin cậy. Một kênh dùng chung không loại bỏ các kiểm tra quyền, cũng không tự động thiết lập một thứ tự toàn cục giữa các ứng dụng.

Một lựa chọn quan trọng khác là ngữ nghĩa bộ nhớ (memory semantics). Trong một phép toán một phía (one-sided), bên khởi xướng trực tiếp chỉ định một địa chỉ bộ nhớ từ xa đã được ủy quyền, và ứng dụng từ xa không cần chuẩn bị một yêu cầu nhận khớp cho mỗi phép toán. UB hỗ trợ hai cách khởi xướng các phép toán như vậy: Load/Store, khởi xướng bằng một lệnh của bộ xử lý, và Read/Write, khởi xướng bằng một yêu cầu được nộp tường minh. Cả hai đều có thể truy cập bộ nhớ từ xa, nhưng cả hai đều không hàm ý rằng các bộ đệm trên các thiết bị tự động nhất quán với nhau. Mục 7.3.3 so sánh hai cách tiếp cận, và Mục 7.4.1 giải thích khi nào dữ liệu trở nên hiển thị và khi nào một phép toán được tính là hoàn thành.

Bộ điều khiển nằm ở đâu. Một NIC truyền thống là một thiết bị ngoại vi PCIe; Mục 6.4.4 đã truy vết đường khởi xướng này. Khi một bộ xử lý khởi xướng một lần đọc từ xa, doorbell, bộ mô tả đọc, việc đọc dữ liệu phía đích, việc ghi lại dữ liệu và việc ghi bản ghi hoàn thành mỗi thứ đi qua PCIe một lần — tổng cộng năm lần, mỗi lần tốn vài trăm nano giây. UB thay vào đó gắn bộ điều khiển vào bus trên chip của bộ xử lý: bộ xử lý thực thi một lệnh Load, yêu cầu đến thẳng bộ điều khiển qua bus trên chip, và dữ liệu trả về được ghi thẳng vào một thanh ghi. Hình 6-39 so sánh hai đường khởi xướng này. Mục 7.3.3 cộng từng giai đoạn của hai đường: với độ trễ dây một chiều 100 ns, một lần đọc 64 B qua một NIC gắn PCIe mất khoảng 2.2 μs, trong đó năm lần đi qua PCIe chiếm khoảng 1.65 μs; một lần đọc qua bộ điều khiển trên bus chip mất khoảng 0.42 μs. Thời gian tiết kiệm được không phải kết quả của việc nén các giai đoạn hiện có — nó đến từ việc bộ xử lý và bộ điều khiển chia sẻ một không gian địa chỉ duy nhất, nên các giai đoạn đó đơn giản không còn tồn tại. Loại bỏ lớp trừu tượng để bộ xử lý truy cập bộ nhớ từ xa giống như cách nó truy cập bộ nhớ cục bộ, đó chính là nơi lợi ích của UB đến; 0.42 μs còn lại bị chi phối bởi độ trễ dây và truy cập bộ nhớ từ xa, và đã gần sát mức sàn phần cứng.

Hình 6-39: Trong sơ đồ trái, NIC nằm sau PCIe: doorbell, bộ mô tả yêu cầu, dữ liệu trả về và bản ghi hoàn thành mỗi thứ đi qua PCIe một lần giữa bộ xử lý khởi xướng và NIC, và NIC phía đích đi qua PCIe thêm một lần để đọc dữ liệu. Trong sơ đồ phải, bộ điều khiển nằm trên bus trên chip, và lệnh của bộ xử lý đến thẳng bộ điều khiển. Hai đường giống hệt nhau từ bộ điều khiển ra mạng.

Quy mô interconnect và sức chứa trạng thái trên chip. Một NIC lưu trong bộ đệm trên chip ngữ cảnh của mỗi mối quan hệ giao tiếp; ở đây ta lấy dung lượng bộ đệm là 256 KiB. Giả sử interconnect chứa HH máy chủ, mỗi máy chủ có AA điểm cuối ứng dụng, và các điểm cuối của bất kỳ hai máy chủ nào cũng có thể giao tiếp với nhau. Có hai cách tổ chức trạng thái kết nối. Cách thứ nhất là các kết nối từng cặp (per-pair connections), tiêu biểu là các kết nối tin cậy của RoCE (RDMA chạy trên Ethernet): mỗi điểm cuối cục bộ thiết lập một kết nối với mọi điểm cuối trên mỗi một trong H−1H-1 máy chủ kia, và mỗi kết nối lưu 512 B ngữ cảnh. Cách thứ hai là sơ đồ điểm cuối cộng kênh của UB: mỗi điểm cuối cục bộ lưu một bản ghi Jetty 20 B và một bản ghi đoạn bộ nhớ 32 B, và mỗi máy chủ từ xa tương ứng với một kênh vận chuyển 56 B. Dưới hai sơ đồ, trạng thái lưu trên mỗi NIC là

Spair(H)=512A2(H−1)+32A,SUB(H)=52A+56(H−1).S_{\mathrm{pair}}(H)=512A^{2}(H-1)+32A,\qquad S_{\mathrm{UB}}(H)=52A+56(H-1).

Lấy A=8A=8. Với các kết nối từng cặp, mỗi máy chủ thêm vào 32 KiB trạng thái, nên một bộ đệm 256 KiB chỉ chứa được 8 máy chủ; với điểm cuối cộng kênh, mỗi máy chủ thêm vào chỉ 56 B, và cùng một bộ đệm có thể chứa hơn bốn nghìn máy chủ. Với 192 máy chủ của CloudMatrix384, các kết nối từng cặp cần khoảng 6 MiB — gấp 24 lần dung lượng bộ đệm — còn điểm cuối cộng kênh chỉ cần khoảng 11 KiB. Trạng thái không vừa trong bộ đệm phải được đọc lại từ bộ nhớ máy chủ trong mỗi phép toán; Mục 7.4.2 tính chi phí này: các kết nối từng cặp thêm hai lần đọc DMA PCIe mỗi phép toán, khoảng 1 μs.

Sơ đồ tổ chức thứ ba là interconnect nhất quán bộ đệm, tiêu biểu là NVLink: một accelerator có thể kéo dữ liệu từ bộ nhớ của một đồng cấp trực tiếp vào bộ đệm của chính nó. Để giữ các bản sao nhất quán, một thư mục (directory) phải ghi lại những đồng cấp nào đang giữ mỗi dòng bộ đệm, cần ít nhất 1 bit mỗi đồng cấp mỗi dòng. Giả sử thư mục theo dõi W=220W=2^{20} dòng bộ đệm (64 MiB dữ liệu), với mỗi dòng mang thêm một thẻ 8 B; thư mục khi đó chiếm W ((H−1)/8+8)W\,((H-1)/8+8) B — khoảng 8 MiB cho hai máy chủ, khoảng 136 MiB cho 1024 máy chủ. Mỗi lần ghi cũng phải gửi một thông điệp vô hiệu hóa (invalidation) đến mọi đồng cấp giữ một bản sao, và số thông điệp tăng tuyến tính theo HH. Hai chi phí này giới hạn interconnect nhất quán bộ đệm ở vài chục đồng cấp; 72 GPU của NVL72 nằm ngay trong khoảng này. UB không duy trì tính nhất quán bộ đệm xuyên máy chủ — khi nào dữ liệu hiển thị với các thiết bị khác là điều ứng dụng phải tự sắp xếp (Mục 7.4.1) — nên trong ba đường cong trạng thái, chỉ đường của UB mở rộng được đến hàng nghìn máy chủ. Hình 6-40 vẽ cả ba đường cong.

Hình 6-40: Với 8 điểm cuối mỗi máy chủ, trạng thái trên mỗi NIC dưới ba sơ đồ tổ chức theo số máy chủ trong interconnect. Đường nét đứt là bộ đệm trên chip 256 KiB. Các kết nối từng cặp vượt bộ đệm ở 8 máy chủ; interconnect nhất quán bộ đệm theo thư mục vượt xa bộ đệm ngay từ hai máy chủ; điểm cuối cộng kênh nằm trong bộ đệm kể cả lên tới hàng nghìn máy chủ.

Thời gian thiết lập kết nối. Lượng trạng thái cũng quyết định một công việc phải thực thi bao nhiêu phép toán điều khiển lúc khởi động. Mỗi kết nối từng cặp đòi hỏi việc tạo lập cộng ba lần chuyển trạng thái — tổng cộng 4 lời gọi hệ thống — cộng một lần trao đổi định danh kết nối với đồng cấp, cần một hành trình khứ hồi ngoài băng (out-of-band, hành trình khứ hồi qua một kênh khác đường dữ liệu). Lấy một lời gọi hệ thống là 5 μs và một hành trình khứ hồi ngoài băng là 500 μs, việc thiết lập một kết nối duy nhất mất khoảng 0.52 ms. Với NN điểm cuối cục bộ truy cập MM điểm cuối từ xa, phải thiết lập NMNM kết nối. Điểm cuối cộng kênh chỉ cần 1 lời gọi hệ thống cho mỗi điểm cuối trong số NN điểm cuối, cộng 1 lời gọi hệ thống và 1 hành trình khứ hồi cho mỗi máy chủ từ xa trong số MM. Với N=M=1024N=M=1024, các kết nối từng cặp phải thiết lập 1.048.576 kết nối, mất khoảng 545 s khi tuần tự và vẫn khoảng 17 s khi song song hóa trên 32 lõi; điểm cuối cộng kênh chỉ cần tạo 2048 đối tượng, mất khoảng 16 ms khi song song hóa. Hình 6-41 vẽ toàn bộ quá trình cho NN từ 1 đến 1024. Mỗi lần khởi động lại hoặc tái quy mô công việc đều lặp lại quá trình này, nên nó ảnh hưởng trực tiếp đến thời gian phục hồi sau lỗi được thảo luận ở Mục 6.7.2.

Hình 6-41: Thời gian cần để thiết lập tất cả các kết nối giữa N điểm cuối cục bộ và N điểm cuối từ xa, thực thi song song trên 32 lõi. Thời gian kết nối từng cặp tăng theo N²; điểm cuối cộng kênh tăng theo N. Ở N = 1024 hai bên chênh nhau gần một nghìn lần.

Hiện thân cụ thể của các cơ chế UB này là CloudMatrix384 của Huawei: hệ thống tổ chức 384 NPU Ascend 910C và 192 CPU Kunpeng qua một cấu trúc chuyển mạch UB, với một mạng RDMA được dùng bên ngoài supernode; truy cập doanh nghiệp được xử lý bởi một mạng Đám mây riêng ảo (Virtual Private Cloud, VPC), dùng để cô lập và kết nối tài nguyên của khách thuê. Đặt một kết nối trực tiếp giữa mọi cặp trong 384 NPU sẽ cần 384×383/2=73 536384\times383/2=73\,536 kết nối; tầng chuyển mạch thay vào đó đạt được giao tiếp giữa các thiết bị qua các kết nối cổng và chuyển tiếp định tuyến.

Hình 6-42: Hệ thống kết nối phân cấp của ba hệ thống công khai. NVIDIA kết nối các thiết bị bằng NVLink, TPU v4 kết nối các OCU (đơn vị chuyển mạch quang) bằng OCS, và Unified Bus đưa các tài nguyên tính toán và bộ nhớ phía máy chủ vào một interconnect thống nhất.

Tất cả các hệ thống này đều có thể áp dụng sơ đồ song song TP2×EP4 từ Mục 6.3.1, nhưng sự tương ứng giữa nhóm và ranh giới vật lý là khác nhau. Các phép reduce thường xuyên trong một nhóm song song tensor tốt nhất nên nằm trên các kết nối độ trễ thấp, trong khi việc trao đổi kết quả expert giữa các nhóm expert khác nhau đòi hỏi đủ băng thông xuyên nhóm. Chỉ bằng cách ánh xạ các nhóm giao tiếp của thuật toán lên tầng chuyển mạch vật lý mới có thể xác định mỗi phép thu thập chiếm những cổng nào.

Khi tính thời gian truyền từ băng thông giao diện, cần phân biệt băng thông một chiều với băng thông hai chiều gộp lại. Ví dụ, UB của Ascend 950 có tốc độ đường truyền hai chiều gộp 2016 GB/s; ở 72 làn, mỗi làn 112 Gbit/s, tốc độ một chiều là 1008 GB/s. UBoE là một cách truyền giao tiếp UB qua Ethernet, còn UB Link là phương thức liên kết riêng của UB. Hai phương thức này được cấu hình sẵn để dùng chung cùng một bộ serializer/deserializer (SerDes, các mạch chuyển đổi giữa dữ liệu song song trong chip và tín hiệu nối tiếp trên liên kết), nên cùng một bộ làn vật lý phải được phân bổ giữa hai cách dùng. Cách phân bổ đó được thực hiện ra sao quyết định băng thông thực sự khả dụng cho một nhiệm vụ.

Thí nghiệm 6-8 · Mở rộng: giải thích cấu trúc interconnect của supernode qua các nhu cầu giao tiếp

(a) Chọn DGX-1, DGX-2 hoặc DGX A100, và vẽ các kết nối trực tiếp hoặc các tầng chuyển mạch mà một nhóm giao tiếp đi qua.

(b) Tính lại số chip và số liên kết bisection cân bằng cho các mạng xuyến 4³ và 8³, và giải thích vì sao băng thông xuyên phân vùng khả dụng trên mỗi chip giảm.

(c) Đặt TP2×EP4 trên hai máy chủ, mỗi máy chủ bốn card, và đánh dấu các phép reduce nhóm expert xuyên máy chủ.

(d) Đổi số điểm cuối mỗi máy chủ thành 64, và tìm các kết nối từng cặp có thể chứa được bao nhiêu máy chủ với bộ đệm 256 KiB; rồi phóng to bộ đệm lên 1 MiB và xác định 192 máy chủ của CloudMatrix384 có vừa không.

(e) Đổi hành trình khứ hồi ngoài băng thành 50 μs, tính lại thời gian thiết lập kết nối cho cả hai sơ đồ ở N = M = 1024, và giải thích sơ đồ nào nhạy cảm hơn với độ trễ khứ hồi.

(f) Chọn một thiết kế từ UB hoặc TPU, và giải thích yêu cầu nào — lắp đặt, giao tiếp, hay truy cập tài nguyên — đã định hình cấu trúc của hệ thống đó.

6.6 Gộp bộ nhớ (memory pooling)

6.6.1 Dung lượng cục bộ không đủ và dung lượng nhàn rỗi toàn cục

Một khi UB mở rộng truy cập tài nguyên qua các máy chủ, nó có được một công dụng cụ thể: cho một nút đang thiếu bộ nhớ mượn bộ nhớ nhàn rỗi của một nút khác. Parallelism tensor, parallelism pipeline và parallelism expert ở Mục 6.2 chia phép tính và trọng lượng ra các card khác nhau, làm giảm nhu cầu bộ nhớ trên mỗi card. Một cách tiếp cận khác giữ nguyên vị trí tính toán và thay vào đó đặt một phần dữ liệu lên một nút khác. Đây là mục đích cơ bản của gộp bộ nhớ (memory pooling): cho những dung lượng nhàn rỗi phân tán vào các nhiệm vụ đang cần chúng.

Xét bốn nút, mỗi nút có một H100 80 GB, với nhu cầu nhiệm vụ lần lượt là 100, 60, 40 và 40 GB. Tổng nhu cầu là 240 GB, nhỏ hơn tổng dung lượng 320 GB, nhưng nhu cầu của nhiệm vụ 0 vượt dung lượng nút chứa nó 20 GB. Dung lượng nhàn rỗi trên các nút còn lại lần lượt là 20, 40 và 40 GB, tổng cộng 100 GB.

Chuyển toàn bộ nhiệm vụ 0 sang một nút khác vẫn sẽ vượt quá dung lượng 80 GB của nút đơn lẻ đó. Nếu thay vào đó phần 20 GB dữ liệu thừa của nó được đặt vào vùng nhàn rỗi của nút 1, việc chiếm dụng vật lý trở thành 80, 80, 40 và 40 GB. Tập làm việc của nhiệm vụ 0 vẫn là 100 GB, trong đó 80 GB cục bộ và 20 GB từ xa. Bằng cách này, nhiệm vụ 0 có thể tận dụng bộ nhớ ban đầu nhàn rỗi trên một nút khác.

Hình 6-43: Việc chiếm dụng vật lý trước khi mượn. Mỗi nút có dung lượng 80 GB; nhu cầu của nhiệm vụ 0 là 100 GB, trong đó 20 GB chưa tìm được nơi lưu trữ. Màu chỉ dữ liệu thuộc về nhiệm vụ nào.

Hình 6-44: 20 GB thừa của nhiệm vụ 0 được đặt trên nút 1. 60 GB màu xanh lục trên nút 1 thuộc về nhiệm vụ 1, và 20 GB màu xanh dương thuộc về nhiệm vụ 0; không nút nào vượt 80 GB.

Ta phải phân biệt dung lượng nhàn rỗi trước và sau khi mượn: các nút khác ban đầu có 100 GB bộ nhớ nhàn rỗi; sau khi cho nhiệm vụ 0 mượn 20 GB, bốn nút cùng nhau còn 80 GB. Việc mượn không thêm bộ nhớ vật lý — nó chỉ để một nhiệm vụ dùng không gian nhàn rỗi của một nút khác. Suy nghĩ ban đầu của tôi về gộp bộ nhớ UB tập trung chính vào loại mất cân bằng này giữa các máy chủ; việc tiết kiệm và tái sử dụng KV về sau trở thành một trong những công dụng cụ thể của nó.

6.6.2 Mượn bộ nhớ và các ranh giới truy cập

Một khi 20 GB trong hình đã có nơi lưu trữ, bước tiếp theo là để nút 0 truy cập đúng đắn bộ nhớ đó. Việc mượn trước tiên phải xác định ai cung cấp bộ nhớ và ai sử dụng nó. Nút cung cấp mở ra một vùng, nút mượn thiết lập một ánh xạ địa chỉ tương ứng, hệ thống quản lý các quyền truy cập, và nó ghi lại khi nào bộ nhớ đó có thể được giải phóng và phân bổ lại. Trong mượn độc quyền, quyền sử dụng được trao cho bên mượn, và chủ sở hữu ban đầu chờ đến khi bộ nhớ được trả lại mới dùng tiếp; truy cập chia sẻ thay vào đó cho phép nhiều người dùng truy cập bộ nhớ theo các quy tắc nhất quán và đồng bộ hóa đã thỏa thuận.

Ví dụ, giả sử nút 1 cho nút 0 mượn một vùng bộ nhớ, và nút 0 phải ghi KV mới trước khi bắt đầu phép tính attention. Chỉ sau khi việc ghi được xác nhận hoàn tất — một khi KV mới thực sự có thể được đọc — phép tính mới có thể bắt đầu; và nếu nút 1 muốn phân bổ lại vùng đó, nó phải chờ việc mượn kết thúc. Địa chỉ trả lời “truy cập ở đâu”, quyền trả lời “ai được truy cập”, và thứ tự hoàn thành phép toán với giải phóng bộ nhớ trả lời “khi nào nó có thể được dùng”. Địa chỉ, quyền và thứ tự truy cập cùng nhau làm cho bộ nhớ từ xa có thể được dùng một cách đúng đắn.

Hình 6-45: Sau khi một batch yêu cầu đọc được gửi đi, phải trôi qua một khoảng thời gian khứ hồi L trước khi các kết quả đến nơi. Với tối đa u yêu cầu đang bay và q byte trả về trên mỗi yêu cầu, tối đa uq byte có thể được trả về trong một khoảng thời gian khứ hồi. Bốn yêu cầu trong hình chỉ để minh họa; ví dụ làm việc trong văn bản dùng 128 yêu cầu mỗi yêu cầu 256 byte, với thời gian khứ hồi 7.52 μs.

Các quyền và thứ tự hoàn thành giữ cho dữ liệu đúng đắn; quá trình chờ thể hiện trong hình quyết định tốc độ đọc. Một yêu cầu sau khi được gửi cần một khoảng thời gian trước khi kết quả đến; để giữ liên kết bận rộn trong khoảng chờ đó, nhiều yêu cầu phải được phát hành đồng thời. Giả sử mỗi giao dịch đọc trả về qq byte, mất LL từ lúc phát hành đến lúc hoàn thành, và tối đa uu giao dịch có thể cùng ở trạng thái bay (đã phát hành nhưng chưa hoàn thành); thì tối đa uquq byte có thể được trả về mỗi LL giây. Kết hợp giới hạn băng thông đường với giới hạn giao dịch đang bay cho

Bwindow=uqL,Busable=min⁡(Bpath,uqL).(6-12)B_{\mathrm{window}}=\frac{uq}{L},\qquad B_{\mathrm{usable}}=\min\left(B_{\mathrm{path}},\frac{uq}{L}\right). \tag{6-12}

Giả sử hai nút được kết nối qua một đường RDMA bằng NIC ConnectX-7, với băng thông đường 50 GB/s. Một yêu cầu đọc mất một hành trình khứ hồi từ lúc phát hành đến lúc hoàn thành; lấy hai lần độ trễ một chiều InfiniBand 3.76 μs đo cho MSCCL++ trên nền tảng H100/ConnectX-7 cho L=7.52L=7.52 μs. Mỗi giao dịch đọc trả về q=256q=256 byte, đúng bằng kích thước vector K của một KV head (BF16 128 chiều) cho một lớp và một token của Qwen3-32B. Với u=128u=128, dữ liệu đang bay mỗi batch là 32 KiB, và trần băng thông do số giao dịch đang bay đặt ra là khoảng 4.36 GB/s. Để đạt được 50 GB/s của đường, cần ít nhất

u≥⌈50×109×7.52×10−6256⌉=1469.u\ge\left\lceil\frac{50\times10^9\times7.52\times10^{-6}}{256}\right\rceil=1469.

Chỉ nâng tốc độ đường truyền trong khi vẫn cho phép chỉ 128 giao dịch đang bay khiến băng thông đọc hiệu dụng bị giới hạn bởi số giao dịch đang bay; nới lỏng lên 4096 giao dịch đưa trần giao dịch đang bay lên khoảng 139 GB/s, vượt băng thông đường, nên nút thắt chuyển sang chính 50 GB/s của đường. Băng thông đường, kích thước giao dịch và thời gian khứ hồi được buộc với nhau qua lượng dữ liệu đang bay.

6.6.3 Dung lượng dùng chung và bộ đệm KV

Việc bộ nhớ từ xa có thể thay thế bộ nhớ cục bộ hay không còn phụ thuộc vào việc so sánh băng thông đọc suy ra ở Mục 6.6.2 với nhu cầu đọc của ứng dụng. Với cùng 20 GB dữ liệu từ xa, tần suất đọc quyết định băng thông trung bình cần thiết. Đọc đầy một lần mỗi phút cần trung bình khoảng 0.33 GB/s; mỗi giây một lần cần 20 GB/s; hai mươi lần mỗi giây cần 400 GB/s. Với cùng một dung lượng, băng thông đọc trung bình cần thiết có thể chênh lệch tới một nghìn lần.

Hình 6-46: Yêu cầu băng thông trung bình khi đọc đầy 20 GB ở các tần suất khác nhau. Băng thông đường là 50 GB/s; với 256 byte trả về mỗi giao dịch và hành trình khứ hồi 7.52 μs, 128 giao dịch đang bay giới hạn băng thông hiệu dụng ở khoảng 4.36 GB/s.

Khi đủ giao dịch có thể được giữ ở trạng thái bay, một lần đọc đầy đủ trên đường 50 GB/s mất khoảng 0.40 s. Phát hành một lần đọc mỗi giây để trống khoảng 0.60 s giữa các lần đọc; phát hành một lần mỗi 0.05 s nghĩa là công việc mới đến trước khi lần đọc trước kết thúc, và hàng đợi cứ tăng dần. Nếu tối đa 128 giao dịch có thể ở trạng thái bay cùng lúc, một lần đọc mất khoảng 4.59 s, và dù phát hành một lần mỗi giây cũng sẽ dần tích lũy hàng đợi.

Cách KV được dùng quyết định nơi tốt nhất để đặt nó. Trong khi một phiên chờ lượt tiếp theo của người dùng, KV của nó có thể không được đọc trong một thời gian dài, nên bộ nhớ từ xa chủ yếu phục vụ việc giữ gìn trạng thái, để lấy lại khi phiên tiếp tục; một phiên đang hoạt động, ngược lại, phải đọc trạng thái ngữ cảnh của nó trong mỗi bước, và quét đi quét lại nó từ một vị trí từ xa sẽ liên tục tiêu tốn băng thông. Trạng thái đó lớn bao nhiêu phụ thuộc vào cách biểu diễn ngữ cảnh của mô hình: Mục 9.2.2 sẽ so sánh trực tiếp, cho cùng ngữ cảnh 8192 token, số byte và thời gian lấy lại dưới GQA của Qwen3-8B so với thiết kế MLA gọn nhẹ của DeepSeek-V3 — cái sau chỉ khoảng một nửa cái trước.

Dữ liệu cũng có thể được nạp về một lần rồi tái sử dụng lặp lại cục bộ. Nếu cùng một ảnh chụp 20 GB phải được đọc mười lần, đọc mười lần trên đường 50 GB/s liên tiếp mất khoảng 4.0 s; nạp một lần (0.40 s) rồi quét mười lần từ HBM H100 cục bộ ở 3350 GB/s mất khoảng 0.06 s, tổng cộng khoảng 0.46 s. Cách sau chiếm 20 GB không gian bộ nhớ cục bộ và tiết kiệm khoảng 3.54 s thời gian truy cập. Vậy với dữ liệu sẽ được đọc lặp lại, cũng cần so sánh thời gian đọc từ xa với thời gian lưu bộ đệm cục bộ để quyết định khi nào nên nạp dữ liệu về bộ nhớ cục bộ.

Thí nghiệm 6-9 · Mở rộng: khi nào nên đọc trực tiếp bộ nhớ từ xa và khi nào nên lưu vào bộ đệm cục bộ

(a) Tính lại việc chiếm dụng vật lý trên bốn nút trước và sau khi mượn, tính dung lượng nhàn rỗi của các nút còn lại trước khi mượn và dung lượng còn lại trên mọi nút sau khi mượn.

(b) Với mỗi giao dịch truyền 256 byte, và thời gian khứ hồi lần lượt là 7.52 μs và 15.04 μs, tìm số giao dịch đang bay tối thiểu cần để đạt băng thông 50 GB/s trong mỗi trường hợp.

(c) So sánh thời gian cho một lần đọc với 128 so với 4096 giao dịch đang bay, giả định lần đọc kế tiếp chỉ được phát hành sau khi lần đọc trước hoàn thành, và tìm số lần đọc hoàn chỉnh tối đa mỗi giây khi đọc liên tục.

(d) Dùng các băng thông từ xa và cục bộ của mục này, tìm cần bao nhiêu lần đọc lặp trước khi việc nạp về bộ nhớ cục bộ trước mang lại tổng thời gian truy cập thấp hơn; đồng thời nêu dung lượng cục bộ cần có.

6.7 Từ sơ đồ song song đến quy mô supernode

6.7.1 Nhóm hợp tác lớn hơn và nhiều instance suy luận hơn

Mục này dùng các kết quả của các mục trước để sắp xếp nhiều phiên Qwen3-32B lên tám card của một HGX H100. Bốn phiên đều đã hoàn thành prefill, mỗi phiên giữ KV cho 131,064 token ngữ cảnh. Mỗi phiên cũng có một token đã được sinh ra, chưa được ghi vào KV, dùng làm đầu vào của bước tiếp theo. Cả bốn phiên đồng thời yêu cầu thêm tám token được sinh, lấp đầy đúng 131,072 vị trí mà YaRN hỗ trợ. Một instance phục vụ mỗi lần một phiên, chuyển sang phiên kế tiếp chỉ sau khi hoàn thành tám bước này; các yêu cầu được phân phối vòng quanh (round-robin) giữa các instance. Tám card đều nằm trong một máy chủ duy nhất và vẫn được gán cho nhóm nhiệm vụ này cho đến khi cả bốn phiên hoàn thành.

Thời gian mỗi bước đến từ phương trình (6-5). Trong quá trình tiếp tục, độ dài ngữ cảnh trong phương trình (6-4) chạy từ 131,064 lên 131,071 từng bước, với khối lượng truy cập KV tăng dần. Cộng tám bước lại cho thời gian phục vụ của phiên. Một phiên đang chờ chỉ giữ KV của riêng nó; các phiên trên cùng instance dùng chung trọng lượng mô hình. Việc xét dung lượng trước tiên loại bỏ tám instance một card: một card thậm chí không chứa nổi một phiên 128K. Theo thuật toán của Mục 6.2.2, một instance hai card có thể chứa tối đa hai phiên, một instance bốn card bảy phiên, và một instance tám card mười sáu phiên; trong ba cách triển khai, mỗi instance được gán lần lượt một, hai và bốn phiên — tất cả đều nằm trong dung lượng.

Cách triển khaiTám bước cho một phiênThời điểm bốn phiên hoàn thànhToàn bộ phiên hoàn thành
Tám instance một cardKhông chứa được——
Bốn instance hai card119.1 ms119.1, 119.1, 119.1, 119.1 ms119.1 ms
Hai instance bốn card63.8 ms63.8, 63.8, 127.6, 127.6 ms127.6 ms
Một instance tám card41.2 ms41.2, 82.4, 123.5, 164.7 ms164.7 ms

Hình 6-47: Nhu cầu bộ nhớ trên mỗi card dưới bốn cách triển khai cho các phiên 128K, gồm trọng lượng, KV của mọi phiên đang xếp hàng trong instance, và một vùng làm việc 2 GiB. Một instance một card cần 102.03 GB mỗi card, vượt 80 GB của H100 (đường nét đứt); các instance hai card, bốn card và tám card cần lần lượt khoảng 52.09, 35.71 và 27.52 GB.

Hình 6-48: Cả bốn phiên tiến cùng lúc, mỗi phiên hoàn thành quanh 119.1 ms. Các màu khớp với các phiên trong các hình cấu hình lân cận. Hình này dùng bốn instance TP2, hai card mỗi instance, mỗi phiên tiếp tục tám token; đường nét đứt là hạn chót 130 ms.

Hình 6-49: Mỗi instance xử lý tuần tự hai phiên, hoàn thành lần lượt quanh 63.8 ms và 127.6 ms. Hình này dùng hai instance TP4, bốn card mỗi instance, mỗi phiên tiếp tục tám token; đường nét đứt là hạn chót 130 ms.

Hình 6-50: Việc tiếp tục của một phiên đơn lẻ rút ngắn còn khoảng 41.2 ms; bốn phiên thực thi tuần tự, với phiên cuối hoàn thành quanh 164.7 ms. Cả ba hình dùng cùng một thang ngang. Hình này dùng một instance TP8 với tám card tổng cộng, mỗi phiên tiếp tục tám token; đường nét đứt là hạn chót 130 ms.

Hợp tác tám card rút ngắn thời gian tiếp tục của một phiên đơn lẻ từ khoảng 119 ms xuống 41 ms, nhưng với bốn phiên xếp hàng lần lượt, tất cả chúng chỉ hoàn thành quanh 165 ms. Với bốn instance hai card, việc tiếp tục của mỗi phiên lâu hơn, nhưng cả bốn phiên tiến cùng lúc, và tất cả hoàn thành quanh 119 ms. Các instance một card về nguyên tắc có thể mở tám cái cùng lúc, nhưng không cái nào chứa nổi dù chỉ một phiên.

Hai loại song song đang hoạt động đồng thời ở đây: tính toán song song trong mô hình, và thực thi đồng thời giữa các yêu cầu khác nhau. Các ma trận trong một lớp có thể được chia ra nhiều card, và các phiên độc lập có thể được phân phối ra nhiều instance, nhưng cả hai đều tranh giành cùng tám card. Phân biệt hai mối quan hệ này là điều giúp chọn được kích thước nhóm hợp tác theo hạn chót hoàn thành của một yêu cầu. Lập lịch phục vụ quyết định bao nhiêu phiên tiến song song, phân chia mô hình quyết định khối lượng giao tiếp mỗi bước, và tô pô interconnect quyết định thời gian dành cho trao đổi dữ liệu và đồng bộ hóa — cùng nhau, ba điều này quyết định các thời gian hoàn thành trong bảng.

Chiều ngang của mỗi khối màu trong hình biểu thị thời gian thực thi của một phiên đơn lẻ, và số đường chạy dọc biểu thị bao nhiêu phiên có thể tiến song song. Hạn chót hoàn thành quyết định hai thứ này đánh đổi nhau ra sao. Với chỉ một phiên và hạn chót 50 ms, instance tám card đạt mục tiêu. Với bốn phiên và yêu cầu tất cả hoàn thành trong 130 ms, cả hai cách triển khai hai card và bốn card đều thành công, với cách triển khai hai card hoàn thành sớm hơn. Hạn chót của một phiên đơn lẻ càng ngắn, nhóm hợp tác cần càng lớn; khi có đủ phiên độc lập, có thể dùng nhiều instance hơn.

Cùng một công thức áp dụng khi phương thức kết nối thay đổi. Nếu, như ở Mục 6.5.1, 16 card trải qua hai máy chủ tạo thành một TP16, mỗi bước mất khoảng 6.67 ms, và tám bước mất khoảng 53.3 ms — mục tiêu 50 ms không còn đạt được nữa. Máy chủ thứ hai tốt hơn nên được dùng để chạy các instance khác; nếu một phiên đơn lẻ buộc phải dùng nhiều card hơn, chi phí giao tiếp thêm vào phải được giảm: cải thiện kết nối giữa các máy chủ, đổi thuật toán giao tiếp tập thể, hoặc đặt các card đó trong một miền interconnect chặt hơn.

Kiến trúc trọng lượng cố định của Chương 4 thay đổi sự đánh đổi này. Một khi trọng lượng được cung cấp bởi một ROM chuyên dụng, các lần đọc trọng lượng HBM trước đây được giãn ra trên các card giảm đi, và thời gian đồng bộ hóa của TP chiếm phần lớn hơn trong độ trễ mỗi bước. Giảm số card TP tiết kiệm được một phần đồng bộ hóa đó, giải phóng các card có thể tạo thành nhiều instance độc lập hơn; mỗi card khi đó phải giữ phần trạng thái yêu cầu lớn hơn. Bảng dung lượng trên mỗi card và bảng thời gian phiên trong mục này vẫn có thể dùng để so sánh hai thay đổi này; Mục 6.7.4 đưa ra các con số cụ thể.

Áp dụng cùng một phân tích cho một mô hình có trạng thái gọn hơn. Khi tính xem DeepSeek V4.1 cần bao nhiêu card, ngoài 890 B dung lượng trạng thái logic mỗi token, còn phải xét trạng thái đó được phân phối ra các card như thế nào. Hình này chỉ tính trạng thái dùng chung giữa các lớp một lần; nếu các lớp khác nhau nằm trên các card khác nhau, các lớp sau vẫn phải truy cập dữ liệu mà các lớp đã tạo ra nó. Có thể đặt các lớp liên quan lên các card gần nhau, nhân bản trạng thái trên card đích, hoặc xây một đường truy cập từ xa. Lựa chọn đầu tiên ràng buộc vị trí lớp, lựa chọn thứ hai tăng chi phí lưu trữ và cập nhật, lựa chọn thứ ba tăng phụ thuộc giao tiếp — nên yêu cầu tài nguyên phải được tính riêng dựa trên dữ liệu mà mỗi card thực sự lưu và truy cập.

6.7.2 Công suất, chi phí và phạm vi ảnh hưởng của lỗi thay đổi sự lựa chọn ra sao

Đường thời gian cho biết thời gian hoàn thành của mỗi phiên và tám card cần bị chiếm trong bao lâu, nên chi phí có thể được tính trực tiếp từ nó, so sánh cần bao nhiêu tài nguyên để hoàn thành đúng hạn cùng một bộ yêu cầu. Chi phí được đo bằng H100 GPU·s, tức một card bị chiếm trong một giây. Tám card bắt đầu tính phí khi cả bốn phiên đến đồng thời, và việc tính phí tiếp tục cho đến khi mọi phiên hoàn thành. Hạn chót hoàn thành là 130 ms, đòi hỏi ít nhất ba trong bốn phiên hoàn thành đúng hạn.

Tổng chi phí của bốn instance hai card xấp xỉ 8×0.1191≈0.9538\times0.1191\approx0.953 GPU·s; cả bốn phiên hoàn thành đúng hạn, trung bình khoảng 0.238 GPU·s mỗi phiên đúng hạn. Tổng chi phí của hai instance bốn card xấp xỉ 1.021 GPU·s, và cả bốn phiên cũng hoàn thành đúng hạn, trung bình khoảng 0.255 GPU·s mỗi phiên. Một instance tám card hoàn thành ba phiên trong hạn chót, vừa đủ tỷ lệ tối thiểu, nhưng tám card vẫn bị chiếm đến 164.7 ms, tổng chi phí khoảng 1.318 GPU·s, trung bình khoảng 0.439 GPU·s mỗi phiên đúng hạn. Tám instance một card không thể chứa nổi các phiên.

Dùng số phiên đúng hạn làm mẫu số, chi phí trung bình được định nghĩa là

Con time=CoccupiedNon time.(6-13)C_{\mathrm{on\ time}}= \frac{C_{\mathrm{occupied}}} {N_{\mathrm{on\ time}}}. \tag{6-13}

Chi phí chiếm dụng được tính trên toàn bộ khoảng thời gian công việc, gồm cả thời gian dừng do lỗi và làm lại; mẫu số chỉ tính các phiên hoàn thành trong hạn chót. Chi phí của các yêu cầu lỗi, làm lại và hết giờ đều nằm trong tử số, nên nó được chia đều cho các phiên hoàn thành đúng hạn.

Phép so sánh trên giả định mọi card hoạt động bình thường suốt quá trình. Nếu một card bị lỗi, instance chứa card đó bị dừng, và các phiên về sau được gán cho instance đó cũng bị trễ. Bơm một lỗi đơn lẻ vào cùng đường thời gian: card 0 bị lỗi lúc 20 ms, instance chứa nó bị dừng 40 ms, và sau khi hồi phục lúc 60 ms nó làm lại việc tiếp tục tám bước từ điểm bắt đầu của phiên đó; các instance khác tiếp tục thực thi, không bị ảnh hưởng bởi lỗi này.

Trong bốn instance hai card, ba phiên còn lại vẫn hoàn thành quanh 119 ms, và phiên bị ảnh hưởng hoàn thành quanh 60+119.1≈179.160+119.1\approx179.1 ms, cho tỷ lệ đúng hạn 75%. Trong hai instance bốn card, instance không bị ảnh hưởng hoàn thành hai phiên quanh 64 và 128 ms, và instance bị ảnh hưởng hoàn thành hai phiên còn lại quanh 124 và 188 ms, cũng cho tỷ lệ đúng hạn 75%. Bốn phiên trên instance tám card hoàn thành lần lượt quanh 101, 142, 184 và 225 ms — chỉ một phiên hoàn thành trong 130 ms.

Bốn instance hai card vẫn đạt tỷ lệ tối thiểu, với chi phí tăng lên khoảng 8×0.1791≈1.4338\times0.1791\approx1.433 GPU·s, trung bình khoảng 1.433/3≈0.4781.433/3\approx0.478 GPU·s mỗi phiên đúng hạn — gấp 2.0 lần giá trị không lỗi; hai instance bốn card đạt khoảng 0.500 GPU·s. Lỗi được cô lập trong một instance, nên ba phiên còn lại vẫn hoàn thành đúng hạn; nhưng thời gian chiếm dụng bị kéo dài và số phiên đúng hạn giảm, nên chi phí mỗi phiên vẫn tăng gấp đôi.

Hình 6-51: Không có lỗi, chi phí trung bình của các phiên đúng hạn thay đổi theo hạn chót. Instance tám card bị tính phí cho đến khi mọi phiên hoàn thành; đường cong bắt đầu ở nơi ít nhất ba phiên hoàn thành đúng hạn. Các giá trị TP biểu thị số card mỗi instance; chi phí đo bằng H100 GPU·s. TP1 không chứa nổi một phiên 128K, nên nó không có đường cong.

Hình 6-52: Card 0 bị lỗi lúc 20 ms, và instance bị ảnh hưởng thực thi lại từ điểm bắt đầu của phiên hiện tại lúc 60 ms. Cùng phương pháp tính phí và dải trục tung như hình không lỗi được dùng. Các giá trị TP biểu thị số card mỗi instance; chi phí đo bằng H100 GPU·s.

Phạm vi ảnh hưởng của một lỗi phụ thuộc vào việc các instance có dùng chung thiết bị hay không. Nếu hai instance dùng chung cùng một bộ nguồn hoặc switch, cả hai instance đều bị ảnh hưởng khi thiết bị dùng chung đó bị lỗi; việc tách các instance chỉ bảo toàn tiến trình của các instance khác nếu đi kèm với cô lập tài nguyên. Instance dùng càng nhiều thiết bị, việc thực thi yêu cầu càng phụ thuộc vào nhiều thiết bị hoạt động đúng. Vì vậy, việc dùng chung bộ nguồn và switch cũng phải được xét khi phân chia instance.

Công suất cũng có thể được dùng để tính năng lượng tiêu thụ của các phương án triển khai này. Dùng trần công suất hệ thống 10.2 kW của DGX H100 từ Mục 6.5.2, không có lỗi, bốn instance hai card chạy khoảng 119.1 ms, tiêu thụ khoảng 1.21 kJ; hai instance bốn card chạy khoảng 127.6 ms, tiêu thụ khoảng 1.30 kJ. Với phần cứng giống hệt và công suất giống hệt, hoàn thành nhiệm vụ sớm hơn sẽ tiêu thụ ít điện năng hơn.

Các yêu cầu bộ nhớ của mô hình ràng buộc những phương án triển khai nào khả thi. Trong ví dụ này, TP1 bị loại trước tiên: KV của một phiên 128K đưa nhu cầu trên mỗi card lên 102.03 GB. Rút ngắn ngữ cảnh xuống 32K cho phép một card đơn lẻ chứa một phiên, nhưng việc tiếp tục tám bước mất 173.3 ms, vẫn vượt hạn chót 130 ms — ở đây TP1 bị loại bởi thời gian thay vì dung lượng. Trước tiên hãy xác định các phương án triển khai có đủ dung lượng bộ nhớ, rồi so sánh thời gian thực thi và chi phí giữa các phương án đó.

Thí nghiệm 6-10 · Nòng cốt: Chọn cấu hình song song theo hạn chót và chi phí phiên

(a) Bắt đầu từ các phương trình (6-4) và (6-5), suy ra thời gian tiếp tục tám bước cho bốn cấu hình TP, rồi tính thời gian hoàn thành của mỗi phiên trong bốn phiên.

(b) Dùng các hạn chót lần lượt là 100, 130 và 170 ms, đòi hỏi ít nhất 75% phiên hoàn thành đúng hạn, tìm các phương án triển khai thỏa mãn yêu cầu và so sánh chi phí của chúng.

(c) Chuyển sang TP16 trên hai máy chủ HGX H100, lấy giá trị AllReduce chéo máy chủ đo được trong Thí nghiệm 7-3, tính lại thời gian tiếp tục của một phiên, và xác định hạn chót hoàn thành 50 ms có đạt được không.

(d) Tính lại thời gian hoàn thành và chi phí phiên sau một lỗi; đổi thời gian dừng từ 40 ms xuống 10 ms và giải thích các phương án triển khai thỏa mãn yêu cầu thay đổi ra sao.

(e) Đổi ngữ cảnh thành 32K và thêm một ràng buộc công suất, giải thích phương án triển khai nào lần lượt bị loại trước nhất bởi dung lượng, bởi thời gian và bởi công suất.

6.7.3 Với một mô hình và phần cứng cho trước, cách chọn chiến lược chia

Quay lại câu hỏi được đặt ra ở đầu chương. Việc chọn một chiến lược chia có thể được viết thành một bài toán tối ưu hóa với đầu vào và ràng buộc: các phương án ứng viên π\pi bao gồm độ song song, vị trí vật lý, thuật toán giao tiếp, phân chia micro-batch và hiện thực hóa operator cục bộ. Trước tiên cố định một mục tiêu JJ, rồi tìm

π∗=arg⁡min⁡π∈PfeasibleJ(π).\pi^*=\arg\min_{\pi\in\mathcal P_{\mathrm{feasible}}}J(\pi).

Mọi phương án trong tập khả thi Pfeasible\mathcal P_{\mathrm{feasible}} phải thỏa mãn dung lượng trên mỗi card, các phụ thuộc dữ liệu của việc phân chia mô hình, hỗ trợ kernel và hạn chót phục vụ. Mục tiêu JJ có thể là độ trễ của một yêu cầu đơn lẻ, hoặc chi phí mỗi phiên đúng hạn từ mục trước; nếu mục tiêu là thông lượng, so sánh tốc độ yêu cầu bền vững dưới cùng một mục tiêu mức dịch vụ (service-level objective, SLO). Vì khối lượng công việc và mục tiêu không cố định, không có một câu trả lời duy nhất cho “độ song song tối ưu”.

Bước một: ghi lại mô hình, khối lượng công việc và tài nguyên. Về phía mô hình, cần số lớp, các chiều ma trận, attention head và KV head, số expert và số expert được chọn mỗi token, độ chính xác, trọng lượng dùng chung và trạng thái xuyên lớp. Về phía khối lượng công việc, cần độ dài prefill, ngữ cảnh decode, số yêu cầu sẵn sàng đồng thời, phân bố định tuyến, độ trễ mục tiêu và quá trình đến. Về phía phần cứng, cần HBM khả dụng mỗi card, hiệu năng tính toán và băng thông hiệu dụng dưới các hình dạng khác nhau, và các đường đi, chi phí khởi tạo cùng nút thắt dùng chung theo từng hướng trong và giữa các nút. Chương 4 đưa ra các tham số phần cứng, và Chương 5 đưa ra các hình dạng thực tế cùng thời gian thực thi cục bộ; tổng băng thông của cụm không thể đơn giản được chia đều cho mọi nhóm giao tiếp.

Bước hai: liệt kê các phương án ứng viên theo nút thắt thay vì chọn một viết tắt trước. Bảng dưới đây liệt kê nên xét những phương án nào dưới mỗi nút thắt; nó chỉ nhằm thu hẹp không gian tìm kiếm — lựa chọn cuối cùng vẫn cần so sánh các thời gian hoàn thành.

Ràng buộc hoặc nút thắt hiện tạiCác phương án ưu tiênChi phí phải tính thêm
Trọng lượng không vừa, hoặc lần đọc trọng lượng lặp lại với batch nhỏ quá chậmTP, PP; MoE có thể dùng EPReduce, tuần tự hóa giai đoạn, lưu lượng expert và workspace
Nhiều yêu cầu độc lập, mô hình hoàn chỉnh đã vừaNhiều bản sao DP/dịch vụ hơn, các nhóm TP nhỏ hơnXếp hàng, tái sử dụng trong batch, dung lượng KV mỗi bản sao
Kích hoạt của một phạm vi cụ thể được lưu dư thừaBật SP trong cùng nhóm TPThu thập và reduce tại các ranh giới bố cục, hỗ trợ kernel
KV và attention chiếm ưu thế với ngữ cảnh dàiKết hợp CP và TPTrao đổi K, V, reduce thống kê, mất cân bằng tải do attention nhân quả
Dung lượng trọng lượng nhiều lớp lớn, reduce chéo nút đắtTP trong nút + PP chéo nútMicro-batch có đủ không, giai đoạn chậm nhất và bong bóng pipeline
Tập expert lớn, định tuyến điểm nóng rõ rệtEP, bản sao expert, tách riêng expert (expert được định tuyến đặt trong một nhóm tài nguyên expert độc lập)Lưu lượng cả hai hướng dispatch và combine, card bận nhất và hàng đợi của nhóm expert

Bước ba: viết ra quyền sở hữu dữ liệu và một đường thời gian cho mỗi phương án. Đánh dấu, với mỗi card, nó giữ những lớp, head, expert, kích hoạt và KV nào; khi tính bộ nhớ đỉnh, cũng cộng thêm các bộ đệm giao tiếp tập thể, double buffering, phần đệm, các micro-batch đang bay và không gian di trú bản sao. Rồi tính thời gian tính toán cục bộ và truy cập bộ nhớ cho mỗi operator, cùng số vòng, số byte và đường dùng chung cho mỗi thao tác chéo card, và đặt cả hai lên một đường thời gian theo các phụ thuộc của chúng. Các lớp liên tiếp của cùng một token không hoàn thành đồng thời chỉ vì có parallelism pipeline, và các kết quả expert được chọn cho cùng một token không trở nên sẵn sàng sớm hơn chỉ vì mạng tình cờ nhàn rỗi. Tính toán MoE nên dùng nhóm expert bận nhất thay vì giá trị trung bình; Mục 9.4 đưa ra một mô hình lệch tải (skew) cụ thể.

Bước bốn: xếp hạng các phương án khả thi theo cùng một mục tiêu. Ví dụ tám card của chương này cố định mô hình dense Qwen3-32B và một phiên 128K, với mỗi instance mỗi lần chỉ xử lý một phiên; phép so sánh đầu tiên là giữa TP1, TP2, TP4 và TP8, với các card còn lại tạo thành các instance độc lập. Parallelism expert không áp dụng cho mô hình dense; parallelism chuỗi chỉ thay đổi việc lưu trữ một đoạn kích hoạt, không mang lại lợi ích bổ sung trong ví dụ theo token, workspace cố định này; nếu parallelism pipeline không xen kẽ nhiều phiên, một phiên đơn lẻ vẫn phải đi qua tuần tự mọi giai đoạn, nên nó không phải lựa chọn đầu tiên để rút ngắn thời gian một phiên. Parallelism ngữ cảnh, pipelining chéo phiên và liên tục đưa batch vào (continuous batching, sắp xếp lại các yêu cầu hoạt động tại ranh giới của mỗi bước lặp) có thể bước vào một tìm kiếm mở rộng, nhưng mỗi cái đều cần thêm các mô hình thời gian cho reduce ngữ cảnh, lập lịch giai đoạn và thay đổi batch tương ứng, và không thể đơn giản tái sử dụng tỷ lệ 1/p1/p của parallelism tensor.

Hai mục trước đã đưa ra các đường thời gian và chi phí mỗi phiên. Lọc theo các giá trị hoàn chỉnh này trực tiếp tạo ra các lựa chọn dưới đây; thay đổi mục tiêu, ranh giới vật lý hoặc dung lượng sẽ làm lựa chọn thay đổi tương ứng.

Điều kiện cho trướcLựa chọn trong các ràng buộcVì sao
Bốn phiên, 128K, ít nhất 75% phải hoàn thành trong 130 msBốn instance TP2TP1 không chứa được; TP2 tất cả hoàn thành quanh 119.1 ms, mỗi phiên đúng hạn tốn khoảng 0.238 GPU·s, thấp hơn 0.255 của TP4 và 0.439 của TP8
Một phiên, 128K, hạn chót 50 msMột instance TP8Khoảng 41.2 ms; TP4 khoảng 63.8 ms, đã vượt hạn chót
Hai máy chủ HGX H100, tổng cộng 16 card, một phiên, 128K, 50 msVẫn chọn một instance TP8TP16 chéo máy chủ mất khoảng 53.3 ms theo AllReduce đo được, vượt hạn chót; máy chủ kia có thể chạy các instance khác
Bốn phiên, 32K, ít nhất 75% phải hoàn thành trong 130 msBốn instance TP2TP1 chứa được, nhưng tám bước mất 173.3 ms; TP2 tất cả hoàn thành quanh 88.3 ms, mỗi phiên đúng hạn tốn khoảng 0.177 GPU·s

Bước năm: dùng đo lường để hiệu chỉnh các ước tính, không coi thứ hạng ước tính là kết luận. Với các phương án được xếp hạng cao nhất, chạy đo lường trong các điều kiện yêu cầu, định tuyến và chất lượng giống hệt, ghi lại bộ nhớ đỉnh, thời điểm sẵn sàng và hoàn thành của từng giai đoạn, khối lượng gửi/nhận của từng cổng, và độ trễ đuôi của dịch vụ. Nếu hiệu suất ma trận thực tế, mức tranh chấp giao tiếp hoặc mức xếp hàng khác với ước tính, hãy xếp hạng lại sau khi thay các tham số đo được; nếu khoảng cách giữa hai phương án nhỏ hơn phương sai đo lường, giữ cả hai và kiểm chứng bằng một khối lượng công việc tiêu biểu hơn. Sản phẩm cuối cùng nên bao gồm phương án được chọn, các phương án bị loại, các ngưỡng mà nếu vượt qua sẽ đảo ngược kết luận, và khoảng đo được. Các script kèm theo có thể tính lại bốn bộ điều kiện trong bảng, nhưng chúng chỉ liệt kê các phương án đã nêu — chúng không phải một bộ lập kế hoạch toàn cục bao trùm các mô hình và framework tùy ý.

Các lựa chọn thiết kế khác nhau ảnh hưởng đến các chi phí thời gian khác nhau. Thay đổi TP chủ yếu thay đổi tính toán mỗi card, khối lượng truy cập bộ nhớ và số card tham gia reduce; thay đổi thuật toán chủ yếu thay đổi số vòng và lượng gửi; thay đổi tô pô chủ yếu thay đổi đường dùng chung và khoảng chờ cố định; thêm instance chủ yếu thay đổi thứ tự xếp hàng của các phiên độc lập. Thay các thay đổi này vào cùng một mô hình thời gian thực thi cho phép bạn so sánh hiệu năng của các thiết kế khác nhau.

Để tối ưu hóa sâu hơn, phân tích độ nhạy có thể được áp dụng cho phương trình (6-5). Trong ví dụ tám card HGX H100 với khối lượng dữ liệu nhỏ, tăng gấp đôi băng thông NVLink chỉ tiết kiệm khoảng 2.5 μs, trong khi giảm một nửa chi phí khởi tạo mỗi vòng tiết kiệm khoảng 0.74 ms; vì vậy, ưu tiên nên là giảm chi phí khởi tạo giao tiếp mỗi vòng. Nếu MoE bị giới hạn bởi nhóm expert chịu tải nặng nhất, việc phân phối cân bằng trực tiếp giảm phép tính của nhóm đó; khi đọc KV từ xa, nếu băng thông bị giới hạn bởi số giao dịch đang bay, tăng độ cạnh tranh giao dịch chính là điều cần để tận dụng hết băng thông liên kết hiện có. Điều này cho phép bạn xác định chi phí nào nên giảm trước và tài nguyên nào nên thêm.

6.7.4 Mở rộng supernode và vị trí đặt trọng lượng, bảng Engram và KV: một ví dụ tổng hợp cho V4.1 Flash

Ba mục trước thảo luận cách chia tám card trong một máy chủ duy nhất ra nhiều instance. Mục này thay vào đó thay đổi chính supernode: trước tiên xem việc mở rộng supernode mang lại gì, rồi cố định trọng lượng vào ROM theo cách tiếp cận của Mục 4.7.3, và cuối cùng thảo luận nên đặt bảng Engram và KV ở đâu. Ví dụ vẫn dùng DeepSeek V4.1 Flash từ Chương 2, với nhiệm vụ là decode ngữ cảnh 200K. Phần cứng là 256 card H100 SXM, với kích thước supernode là 8, 64, 128 và 256 card, và mỗi instance suy luận chiếm đúng một supernode. Trong một instance, attention được đặt theo parallelism dữ liệu, với mỗi card chỉ xử lý và lưu attention cùng KV của phiên nó nhận; các expert được định tuyến và bảng Engram được chia đều ra các card theo parallelism expert, với một dispatch và một combine mỗi lớp.

Kích thước supernode và số phiên mỗi card. Trọng lượng trên mỗi card gồm hai phần: attention, các expert dùng chung và output head mỗi cái lưu một bản trên mỗi card, tổng cộng 9.5 GB; 288.8 GB của các expert được định tuyến và 203.1 GB của bảng Engram được chia sẻ giữa SS card trong instance. Sau khi trừ trọng lượng và workspace UU, toàn bộ HBM còn lại dành cho KV, với mỗi phiên chiếm K=180.7K=180.7 MB, cho

Wcard=9.5 GB+288.8 GB+203.1 GBS,Nsession=⌊C−Wcard−UK⌋.(6-14)W_{\mathrm{card}}=9.5\ \mathrm{GB}+\frac{288.8\ \mathrm{GB}+203.1\ \mathrm{GB}}{S},\qquad N_{\mathrm{session}}=\left\lfloor\frac{C-W_{\mathrm{card}}-U}{K}\right\rfloor. \tag{6-14}

Thời gian bước vẫn được ước tính bằng phương trình (6-2): trọng lượng của card này và KV của mọi phiên trên card này mỗi cái được đọc một lần, và việc đọc và tính toán lấy giá trị lâu hơn trong hai, cộng thêm một dispatch và một combine mỗi lớp, tổng cộng 80 All-to-All. Kết quả cho bốn kích thước supernode được trình bày trong bảng dưới đây.

SupernodeTrọng lượng mỗi cardPhiên mỗi cardThời gian bướcThông lượng mỗi card
8 card71.0 GB3714.1 ms2.632 token/s
64 card17.2 GB33517.3 ms19.420 token/s
128 card13.4 GB35618.4 ms19.392 token/s
256 card11.5 GB36718.9 ms19.378 token/s

Với supernode chỉ 8 card, mỗi card lưu 48 expert mỗi lớp, và gần như tất cả đều được chọn trong một bước, nên việc đọc trọng lượng expert chiếm phần lớn nhất trong thời gian bước. Mở rộng lên 64 card giảm số expert được phân bổ mỗi card xuống một phần tám, cắt thời gian đọc expert xuống còn dưới một phần mười giá trị ban đầu; HBM được giải phóng có thể chứa chín lần nhiều phiên hơn, nên thông lượng mỗi card tăng 7,4 lần. Mở rộng thêm nữa ngoài đó không còn lợi ích: việc đọc expert đã nhỏ, trong khi đọc KV, tính toán và All-to-All đều tăng tỷ lệ thuận với số phiên. Mức tăng 7,4 lần này chủ yếu đến từ dung lượng. Nếu bảng Engram được chuyển sang bộ nhớ máy chủ, một supernode 8 card cũng có thể chứa 178 phiên mỗi card, thu hẹp khoảng cách với trường hợp 64 card còn 1,9 lần.

Tuy nhiên tốc độ cho một người dùng đơn lẻ độc lập với kích thước supernode. Ở batch size 1, đường tới hạn cho một token là card đọc 8.2 GB trọng lượng nhân bản mỗi card một lần, rồi đọc một expert mỗi lớp, tổng cộng 2.76 ms, tức 362 token/s — giống hệt với 8 card và 256 card. Mở rộng supernode mua thêm dung lượng và tổng thông lượng, chứ không phải tốc độ của một phiên; để rút ngắn thời gian một phiên, bản thân attention cũng phải được làm song song tensor, như ở Mục 6.7.1. Ngược lại, nếu cùng 64 card được trải ra tám máy chủ HGX H100, bảy phần tám số byte dispatch và combine phải đi qua NIC, và thời gian giao tiếp tăng từ 3.7 ms lên 29.2 ms, kéo thông lượng mỗi card xuống 7.828 token/s. Đây chính xác là đoạn supernode tiết kiệm được.

Hình 6-53: Thông lượng decode mỗi card của V4.1 Flash trên 256 card H100 thay đổi theo kích thước supernode, với mục tiêu phục vụ 50 ms mỗi token. Đường xanh: các instance đều nằm trong một supernode, tăng khoảng 7,4 lần từ 8 lên 64 card rồi đi ngang; chấm cam: cùng 64 card được trải ra tám máy chủ tạo thành một nhóm parallelism expert.

Cố định trọng lượng vào ROM. Hình 6-54 cho thấy ba vị trí đặt trọng lượng và KV. Một GPU đặt cả hai vào HBM, đọc lại trọng lượng mỗi bước; kiến trúc từ Mục 4.7.3 ghi các trọng lượng không đổi trong quá trình triển khai vào ROM bị che (masked ROM), để HBM chỉ giữ KV; KV còn có thể được đặt trong SRAM trên chip.

Hình 6-54: Ba vị trí đặt trọng lượng và KV. Trái: trọng lượng và KV của GPU cùng ở trong HBM; giữa: trọng lượng được ghi vào ROM lúc sản xuất, KV trong HBM; phải: trọng lượng trong ROM, KV trong SRAM trên chip, với dung lượng nhỏ hơn nhiều. Các mũi tên chỉ dữ liệu phải được đọc mỗi bước; chiều cao hộp gợi ý dung lượng.

Hai vị trí sau được tính theo phân tích của OpenTallas về V4.1 Flash: hai wafer ROM quy trình N5, vẫn ngữ cảnh 200K, batch size 1. Trọng lượng và KV mỗi cái có một đường riêng, nên hai lần đọc và phép tính có thể chồng lấn, nhưng giao tiếp tập thể phải chờ cả ba xong mới bắt đầu được:

Ttoken=max⁡(Tweight,TKV,Tcompute)0.9+Tcomm+Tfixed.(6-15)T_{\mathrm{token}}=\frac{\max(T_{\mathrm{weight}},T_{\mathrm{KV}},T_{\mathrm{compute}})}{0.9}+T_{\mathrm{comm}}+T_{\mathrm{fixed}}. \tag{6-15}

0.9 tính đến việc số lớp được gán cho hai wafer không bao giờ cân bằng hoàn hảo, và TfixedT_{\mathrm{fixed}} là độ trễ pipeline cố định mỗi lớp. Trong hàng GPU, trọng lượng và KV dùng chung HBM, nên hai thời gian đọc được cộng lại với nhau.

MáyLưu trữ và tính toánGiao tiếp tập thểTốc độ một người dùngTỷ lệ giao tiếp
8 card H100, trọng lượng trong HBM2.689 μs76 μs362 token/s3%
58 card B200, song song tensor, trọng lượng trong HBM165 μs562 μs1.357 token/s76%
Hai wafer ROM, trọng lượng trong ROM77 μs159 μs4.070 token/s65%

Một khi trọng lượng rời khỏi HBM, việc đọc trọng lượng rút ngắn từ 2.7 ms xuống 69 μs, nhưng 80 lần AllReduce trên chip vẫn mất 159 μs, chiếm 65% thời gian mỗi token. Chuyển sang 58 card B200 với parallelism tensor, việc đọc trọng lượng cũng có thể được nén xuống 148 μs, nhưng giao tiếp tăng lên 562 μs. Một khi việc đọc trọng lượng không còn là hạng mục dài nhất, tốc độ một người dùng được quyết định bởi giao tiếp tập thể — phương pháp ước tính giao tiếp bằng số bước nhảy và độ trễ mỗi bước nhảy từ Mục 6.5.1 trở nên quyết định ở đây.

Hình 6-55: Cấu thành thời gian mỗi token cho một người dùng V4.1 Flash đơn lẻ trên ba loại máy, ngữ cảnh 200K, batch size 1. Khi trọng lượng ở trong HBM, việc đọc lưu trữ chiếm phần lớn nhất; một khi trọng lượng chuyển sang ROM, giao tiếp tập thể trở thành hạng mục dài nhất.

Nên đặt bảng Engram ở đâu. V4.1 Flash có hai mô-đun Engram, mỗi mô-đun có một bảng 384 triệu hàng, mỗi hàng giữ 256 giá trị FP8 cộng một tỷ lệ 8 byte, tổng cộng 203.1 GB cho cả hai bảng. Với mỗi token được sinh, mỗi mô-đun tra cứu 24 hàng, tổng cộng 12.7 KB. Các bảng này cũng là trọng lượng, không đổi sau khi triển khai; những hàng nào được tra cứu chỉ phụ thuộc vào chuỗi token, không phụ thuộc vào kích hoạt, nên chúng có thể được nạp trước (prefetch) ở đầu mỗi bước. Chỉ cần nạp lại các hàng này trước khi khối Transformer đầu tiên tính xong thì việc tra cứu không tốn thời gian; thời gian khả dụng cho việc nạp là 69 μs trên H100, và chỉ 6.1 μs trên wafer ROM. Hình 6-56 cho thấy ba vị trí và chi phí của chúng.

Hình 6-56: Ba vị trí đặt bảng Engram. Việc tra cứu những hàng nào đã được xác định trước khi phép tính của khối Transformer đầu tiên bắt đầu; sự khác biệt giữa ba vị trí nằm ở đường đi dùng để nạp 48 hàng này, và loại lưu trữ nào giữ bảng.

Vị tríDung lượng chiếmNạp 48 hàng
Bộ nhớ máy chủ, nạp trước qua PCIe hoặc RDMAKhông chiếm HBMMột hành trình khứ hồi, 1.05 μs
Chia nhỏ qua HBM của mỗi card trong supernode8 card: 25.4 GB mỗi card, tương đương 140 phiên; 64 card: 3.2 GB mỗi card, tương đương 18 phiênMột vòng trao đổi NVLink, 0.83 μs
ROM bị che21.651 mm², khoảng nửa waferĐọc trên die

Trên H100, cả hai đường nạp đều ngắn hơn nhiều so với 69 μs, nên việc chọn vị trí chỉ cần xét dung lượng. Một supernode 8 card không cất nổi bảng này; chuyển nó sang bộ nhớ máy chủ tăng số phiên mỗi card từ 37 lên 178. Từ 64 card trở lên, mỗi card chỉ được phân bổ 3.2 GB, nên đặt nó trong HBM giảm số phiên chỉ 5%. Với phục vụ theo batch, bộ nhớ máy chủ cũng không phải nút thắt: một instance 64 card thực hiện 16.080 lần đọc ngẫu nhiên mỗi card mỗi bước, với tốc độ 61 triệu lần đọc mỗi giây đo được ở Mục 7.3.4 chỉ mất 0.26 ms — 1,5% thời gian bước. Triển khai thực tế của DeepSeek đặt bảng trong bộ nhớ máy chủ, nạp trước qua RDMA trong khi khối Transformer đầu tiên tính toán.

Trên wafer ROM, sự đánh đổi thay đổi. Khối đầu tiên chỉ mất 6.1 μs, và một hành trình khứ hồi máy chủ đơn lẻ đã chiếm một phần sáu khoảng đó; một khi thời gian bước giảm xuống dưới 42 μs, nó không còn có thể bị che. Khắc bảng vào ROM tốn thêm nửa wafer, đổi lại việc chỉ đọc 12.7 KB mỗi token; đặt nó trong HBM ở rìa wafer chiếm chỉ không gian của 1.124 phiên, và việc đọc không đi qua interconnect chút nào. Một khi bảng được chuyển ra khỏi ROM, một wafer đơn lẻ đủ cho checkpoint, và tốc độ một người dùng thực tế tăng lên 5.037 token/s. Máy càng nhanh, bảng này càng nên được đặt gần phép tính hơn, trong lưu trữ ghi được.

Đặt KV trong SRAM. SRAM trên chip nhanh hơn nhiều so với HBM, nhưng trước tiên dung lượng phải đủ. Checkpoint của V4.1 Flash là 510.3 GB; ngay cả khi dùng 44 GB SRAM trên chip của một WSE-3 như ở Mục 4.7.2, riêng trọng lượng đã cần 12 wafer, nên việc đặt trọng lượng trong SRAM bị loại bởi dung lượng ngay từ đầu. Với trọng lượng trong ROM, SRAM còn lại trên wafer chỉ giữ được KV của một phiên 200K đơn lẻ; chuyển KV sang HBM thay vào đó cho phép cùng hai wafer giữ 9.637 phiên đồng thời. Tốc độ một người dùng của hai thiết kế giống hệt nhau, vậy mà tổng thông lượng chênh nhau ba bậc độ lớn. Tốc độ của một phiên được quyết định bởi lưu trữ và giao tiếp trên đường tới hạn, còn bao nhiêu phiên có thể được phục vụ đồng thời được quyết định bởi dung lượng của trạng thái ghi được — đúng hai lớp song song được phân biệt ở Mục 6.7.1.

Cả ba bước đều dùng cùng một phương pháp: trước tiên kiểm tra dung lượng theo phương trình (6-1), rồi ước tính thời gian từng hạng mục theo phương trình (6-2), và cuối cùng xác định hạng mục dài nhất trên đường tới hạn. Mở rộng supernode nâng thông lượng, chứ không phải tốc độ của một phiên; một khi trọng lượng được cố định, độ trễ mỗi bước nhảy của interconnect trở thành trần cho tốc độ một người dùng; một bảng chỉ-đọc lớn như bảng Engram nên được đặt càng gần phép tính khi máy càng nhanh; dung lượng SRAM quyết định bao nhiêu phiên có thể được phục vụ đồng thời.

Thí nghiệm 6-11 · Mở rộng: một ví dụ tổng hợp về supernode, ROM và SRAM

(a) Tính lại số phiên trong bảng theo phương trình (6-14), đổi mục tiêu phục vụ thành 20 ms mỗi token, và tìm mỗi card có thể phục vụ bao nhiêu phiên ở mỗi kích thước supernode.

(b) Đổi attention trong instance thành TP8, giữ nguyên mọi thứ khác, và tính lại tốc độ một người dùng ở batch size 1, so sánh với 362 token/s.

(c) Đổi chi phí khởi tạo mỗi vòng chéo máy chủ từ 5 μs xuống 2 μs, và trang bị cho mỗi card hai NIC, xác định instance chéo máy chủ 64 card có thể ngang bằng instance trong supernode không.

(d) Giảm một nửa độ trễ mỗi bước nhảy trên chip, và tính lại tốc độ một người dùng và tỷ lệ giao tiếp của wafer ROM theo phương trình (6-15).

(e) Đổi ngữ cảnh thành 1M, và tính lại số phiên có thể cư trú khi KV ở trong SRAM, cùng số phiên khi KV ở trong HBM.

(f) Đổi hành trình khứ hồi bộ nhớ máy chủ thành 2 μs, và tìm ở tốc độ một người dùng nào việc tra cứu Engram bắt đầu chiếm thời gian bước, cho cả H100 lẫn wafer ROM.

Khi trọng lượng, trạng thái hoặc nhu cầu dịch vụ tiếp tục lớn lên, một supernode đơn lẻ có thể trở nên không đủ để hỗ trợ hoạt động của một instance. Chương tiếp theo theo dõi các đường truyền dữ liệu và phụ thuộc được phân tích trong chương này, thêm vào NIC, mạng chuyển mạch của trung tâm dữ liệu, thông báo hoàn thành cho các phép toán từ xa và tắc nghẽn mạng, để tiếp tục tính toán các lợi ích và chi phí của việc mở rộng phạm vi hợp tác.

Chú thích nguồn

Tóm tắt chương

Song song hóa nhiều thẻ mở rộng việc chia ô (tiling) và lập lịch của toán tử trên thẻ đơn. Việc tách theo mẫu, vị trí chuỗi, đặc trưng, layer và expert khiến mỗi thẻ giữ dữ liệu và phụ thuộc khác nhau; song song dữ liệu, song song tensor, song song chuỗi, song song văn cảnh, song song pipeline và song song expert là những cách phổ biến để tổ chức các phép tách này. Việc tách sinh ra trao đổi, lập lịch quyết định khi nào khởi tạo và khi nào hội tụ, còn thuật toán cùng với đường vật lý quyết định chi phí. Khi chọn phương án, trước tiên kiểm tra tính hợp lệ của dung lượng và thực thi, rồi so sánh các phương án bằng độ trễ, thông lượng hoặc chi phí dưới toàn bộ khối lượng công việc.

Lợi ích của song song hóa suy giảm theo quy mô: lượng tính toán và truy cập bộ nhớ mà mỗi thẻ gánh vác dần giảm đi, nhưng thời gian dành cho xử lý tuần tự vẫn còn, và các vòng reduction cùng thời gian chờ truyền thông giữa các server tiếp tục tiêu tốn thời gian. Tái sử dụng trong batch, phân bố hotspot, giao dịch in-flight và các tập cắt vật lý, mỗi cái tiếp tục thay đổi tốc độ truyền dữ liệu và thời gian thực thi của tầng chậm nhất. Khi phân tích các yếu tố này, bắt đầu từ nơi dữ liệu được tạo ra, được giữ và sẽ được dùng tiếp giúp ta giải thích mỗi chi phí ảnh hưởng đến phép tính tiếp theo như thế nào. Ví dụ UB minh họa điều này: việc trạng thái kết nối cộng theo số endpoint hay nhân theo cặp endpoint quyết định cache trên chip có thể chứa bao nhiêu host và mất bao lâu để thiết lập mọi kết nối; việc bộ điều khiển nằm trên bus trên chip hay sau PCIe quyết định mỗi lần truy cập phải đi ngang bao nhiêu layer.

Trong tác vụ tiếp nối 128K của chương này, một thẻ đơn không chứa nổi một phiên; instance tám thẻ có thời gian tiếp nối một phiên ngắn nhất, trong khi bốn instance hai thẻ có thể hoàn thành cả bốn phiên sớm hơn về tổng thể. Lỗi, độ dài ngữ cảnh và các đường xuyên server tiếp tục làm thay đổi tập phương án triển khai khả dụng. Cuối cùng, quy mô supernode phục vụ một mục tiêu tác vụ rõ ràng: cung cấp đủ dung lượng bộ nhớ, hoàn thành request trong hạn, và hạ chi phí tài nguyên mỗi request.