Repository navigation
Conversation
|
Hi @markkobo, 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. |
AI usage disclosure: |
|
im curious about why use |
For safety,
Also the range of the |
…gml-org#24156) Only applies when tensors are loaded into mmap: --load-mode auto (default) and --load-mode mmap, on Linux. After CPU_REPACK copies a tensor out of mmap into its own buffer, drop the dormant file-backed source pages with madvise(MADV_DONTNEED). The mapping stays valid and re-faults safely if ever accessed. Default on because this is a correctness/efficiency fix for every default-mmap user with repack-eligible quants. Escape hatch for regressions: --no-reclaim-mmap-source. Measured on Qwen3-30B-A3B Q4_K_M (dual-socket EPYC): peak RSS 34.9 GiB -> 21.6 GiB (-13.0 GiB, -37%). Byte-identical output, identical PPL 9.0814 on wikitext-2 chunks=64. Zero major page faults. Rebased after ggml-org#28334 (load flags consolidated into --load-mode) and ggml-org#27837 (TENSOR_READ_LAZY). Plumbing updated for the new llama_model_loader ctor signature; madvise logic unchanged. Fixes ggml-org#16761
aba6323 to
dd73e95
Compare
1. the model loader has no #ifdef and no syscalls. 2. the code moved next to the existing unmap_fragment() and reuses its align_range(). 3. stop at the first failure. 4. fewer headers included. 5. it's a bug fix, so no flag. it's on for --load-mode auto/mmap and a no-op otherwise. 6. also fixes the tied-embedding case (tests below): the previous commit dropped the token_embd pages and they faulted back in. this commit keeps them while a tied model still reads them. Tests: master vs this commit, output identical in every run. CPU = 2x EPYC 9R14, CUDA = L40S. | RSS after load | master | this commit | |---------------------------------|-----------|-------------| | CPU Qwen3-30B-A3B Q4_K_M | 31483 MiB | 18160 MiB | | CPU DeepSeek-V2-Lite Q4_K_M | 16592 MiB | 11024 MiB | | CPU Llama-3.2-3B Q4_0 | 3838 MiB | 2368 MiB | | CUDA Qwen3 -ngl 99 -ot exps=CPU | 17861 MiB | 17322 MiB | | CUDA Llama-3.2-3B -ngl 14 | 2082 MiB | 1772 MiB | | CUDA full offload -ngl 99 | same | same | Unchanged: perplexity (Qwen3, 9.0652), --load-mode none/dio/mmap+mlock, pp512/tg128 speed (CPU and CUDA), peak RSS during load (the drop happens at the end of load). Tied embeddings, token_embd RSS after load -> after a 2000-token prompt: | Llama-3.2-3B | previous commit | this commit | |-------------------------------------|-----------------|----------------| | output on GPU (-ngl 99, RPC device) | 0 -> 71 MiB | 308 -> 308 MiB | | output in CPU_REPACK (Q4_0 embd) | 2 -> 152 MiB | 212 -> 212 MiB | Assisted-by: Claude Opus
|
/bot review |
Automated code reviewReview: PR #24156 - reclaim mmap source pages after loadI checked the diff ( Blocking(point 1) The advertised Will slow the review(point 2) On non-Linux POSIX (macOS/BSD) (point 3) The feature is completely invisible at runtime - no log line reports how much was reclaimed. Since the PR's whole value proposition is an RSS number users cannot easily reproduce, an INFO line after the discard loop (e.g. total bytes dropped, matching the existing (point 4) Nits(point 5) (point 6) The header comment in The design itself is the right shape: per-tensor tracking is genuinely needed here because copied ranges sit interleaved inside the live read-in-place span, so the existing end-of-load This review was generated automatically by pi coding agent using |
addressed points:
Also re-ran all the tests. the results(using Claude Code): SummaryOutput identical to master in every run.
|
TL;DR
After CPU_REPACK copies a tensor out of the mmap, drop the dormant file-backed source pages with
madvise(MADV_DONTNEED)— saves 13.0 GiB (−42%) RSS on Qwen3-30B-A3B, 5.4 GiB (−34%) on DeepSeek-V2-Lite, 1.4 GiB (−38%) on Llama-3.2-3B.No flag: always on for
--load-mode auto(default) /mmapon Linux; a no-op fornone/dio, under mlock, and off Linux. Byte-identical output, identical perplexity, zero major page faults. Fixes #16761.The code fits to the existing coding convention much better now. It's a bug fix so I changed the default behavior with tests covered all types of memory strategies - CPU/CUDA on 3 different models.
Let me know if more tests are needed or a flag for this bugfix is needed. I can add it back with default ON or OFF.
Overview
With
--load-mode auto(default) /mmap, tensors handled by CPU_REPACK are copied out of the mmap into their own buffers at load time, but the file-backed source pages stay resident, every repacked tensor is effectively stored twice (see #16761). This PR drops the dormant source pages withmadvise(MADV_DONTNEED)once loading finishes. The VMA stays valid and re-faults identical bytes from the page cache if needed, so it is safe by construction (unlikemunmap, which would break later readers such as--check-tensors).Default behavior change: no flag — always on for mmap loads without mlock (Linux), a no-op for
--load-mode none/dio, under mlock, and on other platforms. This is a bug fix for the RSS bloat in #16761; an opt-in flag would leave the bug in place for default users. (Earlier revisions had a--reclaim-mmap-sourceflag; dropped on the last rebase.)Implementation notes:
madvise(MADV_DONTNEED)); the code lives next to the existingunmap_fragment()and reuses itsalign_range()to round ranges inward to whole pages, so pages shared with read-in-place neighbors are kept.token_embdalso used asoutput(see the tied-embedding test below).--check-tensorscannot race the reclaim.madvisefailure with a warning — on systems where it fails once (e.g. seccomp) it would fail for every tensor.load_all_data: reclaimed 13323.00 MiB of mmap source pages.Tests: master vs this commit, identical output in every run. CPU = 2x EPYC 9R14, CUDA = L40S.
i.e. −13.0 GiB (−42%) on Qwen3-30B-A3B, −5.4 GiB (−34%) on DeepSeek-V2-Lite, −1.4 GiB (−38%) on Llama-3.2-3B; the saving tracks the CPU_REPACK buffer size and vanishes when nothing is repacked (full GPU offload).
Unchanged: perplexity (Qwen3, 9.0652 on wikitext-2),
--load-mode none/dio/mmap+mlock, pp512/tg128 speed (CPU and CUDA), peak RSS during load (the drop happens at the end of load). No major page faults observed.Tied embeddings —
token_embdRSS after load -> after a 2000-token prompt (an earlier revision dropped these pages and they faulted straight back in; this revision keeps them while a tied model still reads them):Rebased after #28334 (load flags consolidated into
--load-mode) and #27837 (TENSOR_READ_LAZY).Fixes #16761
Requirements