Repository navigation
cuda : reduce large tensors through the copy engines when NCCL has no peer access - #16
Merged
Merged
Conversation
… peer access Without peer access NCCL stages a reduction through host memory with an SM on each GPU. That SM is missing for a kernel that launches one block per SM (the stream-k MMQ tiles), which then runs a second wave: on an RTX 3060 the matrix multiplications took 1.4-1.8x as long while an NCCL kernel ran. NCCL also does not use both directions of a link at the same time (3060 on PCIe 3.0 x4: 3.3 GB/s each way alone, 2.8 + 2.8 GB/s at once). The new path (allreduce-ce.cu) converts each GPU's F32 part to BF16, copies it to pinned memory in chunks on one copy stream and copies the peer's chunks back on another as they arrive; a small kernel adds the two BF16 values in F32, in the same order on both GPUs. The GPUs are ordered with events only. The buffers (16 MiB VRAM, 8 MiB pinned per GPU) are allocated with the first large reduction, so a draft context allocates nothing; if that fails, NCCL takes the call. With NCCL and no peer access, reductions from 512 KiB go this way (below it the internal pipeline, #14). GGML_CUDA_AR_CE=0 keeps NCCL for them, GGML_CUDA_AR_CE_MIN_BYTES sets the size. docs/multi-gpu.md describes the paths and variables, and --attn-split. Qwen3.8-27B UD-Q4_K_S, RTX 4070 + 3060, -ts 0.625/0.375 -as 1/3, q5_1: pp512 711 -> 831 t/s (+17%), pp2048 @16k 638 -> 732 (+15%), tg and pp3 unchanged. Against F32 reductions (40 x 512 tokens): mean KLD 0.00243 (NCCL 0.00262), same top token 97.81% (NCCL 97.53%). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- MUSA lacks cudaHostAlloc: the file gets the same guard and stubs as allreduce.cu, init returns nullptr there - the copy engines no longer depend on the internal pipeline, which needs Volta or newer - an MTP draft context processes the prompt batches too and allocates its own buffers: docs and comments say so (32 MiB VRAM per GPU with MTP) - docs: GGML_CUDA_AR_NCCL_MIN_BYTES enables only the internal pipeline with peer access and is the default of GGML_CUDA_AR_CE_MIN_BYTES - the header no longer refers to lanes that this change does not have Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Piggidragon
added a commit
that referenced
this pull request
Oct 16, 2026
The paths of #14, #16 and this PR were chosen by the hardware and switched by environment variables. They are now opt-in with one flag, like the other features of this fork, and the default is upstream's NCCL: - --allreduce host: small reductions through the internal pipeline, large ones through the copy engines, through pinned host memory (#14, #16) - --allreduce p2p: the peer-to-peer kernel and the copy engines from GPU to GPU; host without peer access. The paths enable peer access themselves, GGML_CUDA_P2P is not needed - llama_context_params.allreduce_type, passed to the backends through the new reg proc ggml_backend_comm_set_mode before the meta backends of a context are created - llama-bench -ar, test-llama-archs configs "Meta -ar host" and "Meta -ar p2p -so" - GGML_CUDA_AR_CE, GGML_CUDA_AR_CE_P2P and GGML_CUDA_AR_P2P_SMALL are gone; the two size thresholds stay as tuning variables, GGML_CUDA_ALLREDUCE still overrides - README: the features of this fork as one list (what, benefit, how to enable), and a table upstream vs this fork Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Large all-reduces under
-sm tensornow go through the copy engines instead of NCCL, on two GPUs without peer access. Prompt processing gets 15–17% faster, decode is unchanged, and the result is at least as precise as NCCL's.Why
Without peer access, NCCL moves a reduction through host memory with an SM on each GPU. That costs twice:
NCCL_MAX_NCHANNELS=1did not help: one SM is already enough to cause the second wave.Change
ggml/src/ggml-cuda/allreduce-ce.cu, about 300 lines:With NCCL compiled in, two GPUs and no peer access, reductions are now routed like this:
With peer access everything stays on NCCL.
Environment variables:
GGML_CUDA_AR_CE=0: NCCL for the large reductions.GGML_CUDA_AR_CE_MIN_BYTES: the threshold. Used with1below to send every reduction through the copy engines in the tests.docs/multi-gpu.mdnow describes the three paths and their variables, and adds--attn-split(#15) to the argument table.Results
Qwen3.8-27B UD-Q4_K_S, RTX 4070 (PCIe 4.0 x16) + RTX 3060 (PCIe 3.0 x4),
-sm tensor -ts 0.625/0.375 -as 1/3, q5_1 cache, native FA,-ub 512, t/s:GGML_CUDA_AR_CE=0)llama-serverwith the production configuration (262144 tokens of q5_1 cache in 2 slots, MTP):Precision
llama-perplexity --kl-divergence, wikitext, 40 chunks of 512, against F32 reductions everywhere (GGML_CUDA_ALLREDUCE=internal GGML_CUDA_AR_BF16_THRESHOLD=0):Tests
GGML_CUDA_AR_CE_MIN_BYTES=1(every reduction through the copy engines, including the-as 1/0configs with empty slices). 321 OK Meta rows each. The only failure is maion-coder MoE in "Mixed batch", which also fails on a single GPU.Review
A review (reviewer-xhigh) found no bug in the reduction itself:
Four smaller points are fixed in the second commit:
cudaHostAllocis missing there. It now has the same guard and stubs asallreduce.cu.GGML_CUDA_AR_NCCL_MIN_BYTESalso enables the copy engines with peer access. They stay off there, as intended.The copy engines are now also set up when the internal pipeline is not, which needs Volta or newer.
🤖 Generated with Claude Code