llama : wire up ggml_backend_register_host_buffer for mmap'd weights - #26659
Draft
bluechiperic wants to merge 1 commit into
Draft
llama : wire up ggml_backend_register_host_buffer for mmap'd weights#26659bluechiperic wants to merge 1 commit into
bluechiperic wants to merge 1 commit into
Conversation
ggml_backend_cuda_register_host_buffer() is defined and exposed through get_proc_address by both the CUDA and SYCL backends, but nothing in the repository ever calls it. Page-locking of mmap'd model weights is therefore unreachable today. Add the missing call site in llama_mmap. Its ctor/dtor are used because their lifetime matches the mapping exactly -- llama_model takes ownership of the loader's mappings, so registering in the loader would unregister too early. The hook is resolved via ggml_backend_reg_get_proc_address so src/ gains no backend-specific dependency; backends that do not provide it fall through unchanged. The CUDA backend gates on GGML_CUDA_REGISTER_HOST, so this is a no-op unless explicitly requested. Page-locking makes the pages non-pageable. Registering a mapping that is large relative to physical RAM will fail; that case is ignored and the unpinned path is used unchanged.
|
Hi @bluechiperic, thanks for your contribution! Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:
Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below. |
xpire
pushed a commit
to xpire/llama.cpp
that referenced
this pull request
Sep 4, 2026
… pinning - llama.cpp: moe_stream forces load_mode NONE (heap, no mmap) — mmap-backed host tensors measured ~40% slower as the streaming copy source (PP512: 561 t/s mmap vs 790 t/s heap at ub 512) - llama-moe-stream: pin_hosts() page-locks the host expert buffers via the ggml-org#26659 ggml_backend_register_host_buffer hook (env-gated, opt-in) — measured no additional gain (heap copies already saturate PCIe at the 144MB-slab sizes), kept as correct wiring for larger slabs - Correctness unchanged (identical bytes, heap vs mmap)
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.
Summary
ggml_backend_cuda_register_host_buffer()is defined and exposed throughget_proc_addressby both the CUDA and SYCL backends — but nothing in therepository calls it. Page-locking of mmap'd model weights is unreachable today.
A code search across
masterfinds only the two definitions and no consumer.PR #15615 extended the function to HIP in Aug 2025, so it appears intended to be
used rather than deprecated; the call site simply seems never to have landed.
This adds it.
Implementation
The call goes in
llama_mmap's ctor/dtor because their lifetime matches themapping exactly —
llama_modeltakes ownership of the loader'smappings, soregistering from the loader would unregister too early.
Resolved through
ggml_backend_reg_get_proc_address, sosrc/gains nobackend-specific dependency and backends without the hook fall through
unchanged. The CUDA backend gates on
GGML_CUDA_REGISTER_HOST, so this is ano-op unless explicitly requested.
+47/-2 across two files.
Why it helps
Pinned host memory lets host→device copies use DMA instead of the driver's
internal bounce buffer. This matters on MoE offload paths, where expert weights
are uploaded from host memory during batched prefill.
Measurements
OLMoE-1B-7B-0125 Q6_K, RTX A2000 12GB,
-ncmoe 16 -ngl 999 -p 8192, mmap on,alternating rounds to rule out page-cache ordering effects:
~1.67x on prefill. Round 2's unpinned run executes fourth, fully warm, and
still matches the cold first run — so the effect tracks the condition, not
position in the sequence.
Perplexity is unchanged:
PPL = 4.1871 +/- 0.30585with and without.This is consistent with the ~+64% reported independently by the
fable5/host-registerwork on an RTX 3060.Limitations
Stated plainly, since I can only test one configuration:
ROCm, SYCL, or multi-GPU numbers.
relative to physical RAM fails — I hit this directly: a 17.35GB mapping on a
32GB host returns false. That path is handled (registration failure is ignored
and the unpinned path is used unchanged), but it is the reason this is opt-in
rather than default.
helps paths that actually upload weights.
Happy to add Linux and larger-model numbers, or to change the opt-in mechanism
if an env var is not the preferred interface here.