Skip to content

llama : wire up ggml_backend_register_host_buffer for mmap'd weights - #26659

Draft
bluechiperic wants to merge 1 commit into
ggml-org:masterfrom
bluechiperic:wire-up-host-buffer-registration
Draft

llama : wire up ggml_backend_register_host_buffer for mmap'd weights#26659
bluechiperic wants to merge 1 commit into
ggml-org:masterfrom
bluechiperic:wire-up-host-buffer-registration

Conversation

@bluechiperic

Copy link
Copy Markdown

Summary

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 calls it. Page-locking of mmap'd model weights is unreachable today.

A code search across master finds 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 the
mapping exactly — llama_model takes ownership of the loader's mappings, so
registering from the loader would unregister too early.

Resolved through ggml_backend_reg_get_proc_address, so src/ gains no
backend-specific dependency and backends without the hook fall through
unchanged. The CUDA backend gates on GGML_CUDA_REGISTER_HOST, so this is a
no-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:

round condition pp8192 tok/s
1 unpinned 996.55 ± 1.25
1 pinned 1675.77 ± 13.32
2 unpinned 1010.15 ± 18.40
2 pinned 1666.20 ± 12.30

~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.30585 with and without.

This is consistent with the ~+64% reported independently by the
fable5/host-register work on an RTX 3060.

Limitations

Stated plainly, since I can only test one configuration:

  • Measured on a single GPU (A2000), a single model, and Windows only. No Linux,
    ROCm, SYCL, or multi-GPU numbers.
  • Page-locking makes pages non-pageable. Registering a mapping that is large
    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.
  • No benefit to decode paths where experts are computed on the CPU; this only
    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.

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.
@ggml-gh-bot

ggml-gh-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

Hi @bluechiperic, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • PR Template not respected: Please respect the template when creating a new pull request. Make sure to fill out all required sections.

  • AI-generated content: While code is allowed to be generated by AI, please write the PR description and commit messages on your own without the help of AI.


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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant