Repository navigation
STRATA_ARENA_MMAP=1: the expert arena as a read-only mapped file (Linux), for small-RAM machines - #640
STRATA_ARENA_MMAP=1: the expert arena as a read-only mapped file (Linux), for small-RAM machines#640JeanP00l wants to merge 1 commit into
Conversation
…ux), for small-RAM machines The host expert arena is normally read into pinned (locked) RAM. On a machine whose GPUs already hold most experts, that locks memory the CPU never reads: with the Coder (25 GB arena) on 2x 16 GB GPUs and 32 GB of RAM, ~1 GB stayed available at 128K context, the kernel swapped, and a multi-turn checkpoint took 25-80 s. With STRATA_ARENA_MMAP=1 (opt-in, Linux; off by default, nothing changes without it): - the first start writes the arena to the pack's experts.bin (padded by one blob so a whole-slot copy may start at any expert); later starts map it read-only, not locked, not pinned. The page cache keeps what the CPU pool and the prompt path read and gives the rest back under pressure; a dropped page is re-read from the file, so no result depends on what is resident. The GPUs get no mapped alias of it: run with --pcie-frac 0; - after the VRAM caches are filled, the pages of experts a GPU holds are handed back (MADV_DONTNEED, STRATA_ARENA_RELEASE=0 keeps them) and the rest are prefetched (MADV_WILLNEED); an adaptive swap releases the expert that went to VRAM and prefetches the one that came back; - HIP: ROCclr copies a pageable source of 1 MiB or more by locking its pages in place and keeps them locked, which undid every release. The engine raises GPU_PINNED_MIN_XFER_SIZE (an explicit setting wins) so such copies stage through ROCclr's own buffers, and locks an adaptive swap's source pages itself only until the copy lands (the page ranges are merged first: a copy from a range only part of which is registered fails); - STRATA_RSS_TRACE=1 prints the process's RssFile at the startup steps (madvise reports success on locked pages and frees nothing; RssFile is the honest check). The existing --mmap-experts refuses native packs (the Coder); this path is for them. Measured on 2x AMD Instinct MI50 16 GB + 32 GB DDR4 (gfx906 port, Coder IQ1_M, 128K context, layer split): RAM available while serving ~1 GB -> 25 GB; multi-turn re-read of a checkpoint 25-80 s -> <= 3.2 s; decode unchanged (49.06 vs 49.16 ms per verify window). Not measured on NVIDIA (pin_blobs is a no-op there).
|
Re-run on the cards with this branch, merged with #638 and #639 (current
A correction to the description. The "25-80 s" checkpoint re-reads came from long sessions on the port branch, once the machine ran out of RAM and swapped. This short 4-turn run does not reproduce them: with ~2 GiB available it has not reached that point yet. What it shows directly is RAM: about 23 GiB more is free with the same speed and the same text. Marking ready. |
… follow-up) The adaptive swap loops called srcp->blob() for every swap to collect the spans pin_blobs locks, on every build - pin_blobs is a no-op except on Linux AMD with STRATA_ARENA_MMAP=1. blob() is not free: it counts reads and the file tier (--mmap-experts) may assemble the blob, a second time for the copy. pin_blobs_on() now guards the gathering, so CUDA and the runs without STRATA_ARENA_MMAP do exactly what 0.1.38 did. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…640 follow-up) The first mapped start writes the whole arena (25 GB for the Coder) next to the pack. A drive without that much free space filled up before the write failed. Now the start checks the free space first (the arena plus 2 GiB to spare); without it, it says so and keeps the arena in RAM for this start. Linux opt-in only; nothing changes without the env. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Thanks, the ROCclr pin-in-place finding is useful beyond this PR (#579 and #590 also use
It builds for CUDA on Windows and Linux (the POSIX mapped arena compiles under Linux) and for Windows HIP. Default output is unchanged. We have no Linux AMD machine to run the mapped arena itself. Please post your re-run of this branch on the cards here; we'll keep the PR open until then and close it with the release. |
|
Quick post-merge check: the updated gfx906 candidate built all targets and started with This confirms startup and inference through the mapped-arena path; it is not a new pinned-versus-mapped RAM or throughput A/B. The earlier controlled comparison remains the evidence for that benefit. |
… follow-up) The adaptive swap loops called srcp->blob() for every swap to collect the spans pin_blobs locks, on every build - pin_blobs is a no-op except on Linux AMD with STRATA_ARENA_MMAP=1. blob() is not free: it counts reads and the file tier (--mmap-experts) may assemble the blob, a second time for the copy. pin_blobs_on() now guards the gathering, so CUDA and the runs without STRATA_ARENA_MMAP do exactly what 0.1.38 did.
…640 follow-up) The first mapped start writes the whole arena (25 GB for the Coder) next to the pack. A drive without that much free space filled up before the write failed. Now the start checks the free space first (the arena plus 2 GiB to spare); without it, it says so and keeps the arena in RAM for this start. Linux opt-in only; nothing changes without the env.
…ko1221#640 follow-up) The adaptive swap loops called srcp->blob() for every swap to collect the spans pin_blobs locks, on every build - pin_blobs is a no-op except on Linux AMD with STRATA_ARENA_MMAP=1. blob() is not free: it counts reads and the file tier (--mmap-experts) may assemble the blob, a second time for the copy. pin_blobs_on() now guards the gathering, so CUDA and the runs without STRATA_ARENA_MMAP do exactly what 0.1.38 did.
…iko1221#640 follow-up) The first mapped start writes the whole arena (25 GB for the Coder) next to the pack. A drive without that much free space filled up before the write failed. Now the start checks the free space first (the arena plus 2 GiB to spare); without it, it says so and keeps the arena in RAM for this start. Linux opt-in only; nothing changes without the env.
…ATA_ARENA_MMAP (PR Niko1221#640), make_profile --reorder (Niko1221#587)
…ko1221#640 follow-up) The adaptive swap loops called srcp->blob() for every swap to collect the spans pin_blobs locks, on every build - pin_blobs is a no-op except on Linux AMD with STRATA_ARENA_MMAP=1. blob() is not free: it counts reads and the file tier (--mmap-experts) may assemble the blob, a second time for the copy. pin_blobs_on() now guards the gathering, so CUDA and the runs without STRATA_ARENA_MMAP do exactly what 0.1.38 did. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…iko1221#640 follow-up) The first mapped start writes the whole arena (25 GB for the Coder) next to the pack. A drive without that much free space filled up before the write failed. Now the start checks the free space first (the arena plus 2 GiB to spare); without it, it says so and keeps the arena in RAM for this start. Linux opt-in only; nothing changes without the env. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ATA_ARENA_MMAP (PR Niko1221#640), make_profile --reorder (Niko1221#587) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
What
STRATA_ARENA_MMAP=1(opt-in, Linux; nothing changes without it) maps the host expert arena read-only from the pack'sexperts.bininstead of reading it into pinned, locked RAM. This is for machines whose GPUs already hold most experts and whose RAM is small.--mmap-expertsrefuses native packs (the Coder), so this path is for them.Without it, the Coder (25 GB arena) on 2x 16 GB GPUs with 32 GB of RAM left ~1-3 GB available at 128K context. In long sessions the kernel swapped, and re-reading a multi-turn checkpoint took 25-80 s.
experts.bin(padded by one blob, so a whole-slot copy may start at any expert). Later starts map it.--pcie-frac 0.MADV_DONTNEED;STRATA_ARENA_RELEASE=0keeps them), and the rest are prefetched (MADV_WILLNEED). An adaptive swap releases the expert that went to VRAM and prefetches the one that came back.GPU_PINNED_MIN_XFER_SIZE(an explicit setting wins). It locks an adaptive swap's source pages itself, only until the copy lands. The ranges are merged first, because a copy from a range only partly registered fails withinvalid argument.STRATA_RSS_TRACE=1: printsRssFileat the startup steps.madvisereports success on locked pages and frees nothing, soRssFileis the honest check.cudaHostRegisterReadOnly.Measured
2x AMD Instinct MI50 16 GB + 32 GB DDR4 (gfx906, see #638), Coder IQ1_M, 128K context, layer split:
STRATA_ARENA_MMAP=1Status
Re-run on 2x MI50 with this branch on current
main, results in the comment below.🤖 Generated with Claude Code