Repository navigation
Conversation
…on its own thread The arena load was the start's long pole: a buffered read, then one CUDA registration of the whole arena (registering 63 GiB of 4 KiB pages alone took 6.6 s). - load_experts_direct (pinned.cu): a pack's experts.bin ranges are read with FILE_FLAG_NO_BUFFERING straight into the arena, 16 readers of 8 MiB. When a range is not 4 KiB-aligned it returns without an error and the buffered reader runs as before. - load_experts_gguf (the default native pack, no experts.bin): each chunk's 4 KiB-aligned window is read unbuffered into an aligned buffer and scattered into the blobs. MSVC's std::ifstream read it in 4095-byte pieces (#230: 0.02 GiB/s, 42 minutes); off Windows the old reader stays. - PinnedArena(bytes, bounds, Deferred) + register_slices(): the arena is reserved first and its per-layer slices are registered on a thread ahead of the readers; a reader waits for its slice (writing pages while cudaHostRegister runs on them corrupted the arena under WDDM, even on large pages). - generate.cpp: the arena loads on its own thread while the main thread loads the dense weights, the PLE table, the MTP drafter and the native head; it is joined before anything reads it. - gemm_prewarm(): the cuBLAS handle and its first GEMM are created early, off the critical path. IQ2_XS without experts.bin (setup's default): start to exit of a short generate 11.7 s vs 17.5 s, with main reading from a warm file cache; the arena checksum (STRATA_VERIFY_ARENA) is the same for both loaders. STRATA_BUFFERED_LOAD=1 keeps the old loaders (A/B). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
…rest from experts.bin (Windows) The resident arena holds every expert - with the VRAM cache's share of them a second time - so a PC whose RAM cannot hold them beside the system cannot run it, and --mmap-experts leaves them to the OS file cache. TieredExpertSource keeps host copies only where the engine reads them: a pinned, registered tier (large pages when allowed) sized to the free RAM minus STRATA_RAM_RESERVE_GIB (default 6), filled with the experts outside VRAM by rank, then the VRAM cache's tail that the prompt path borrows. Everything else is read from experts.bin unbuffered: a decode token's misses are prefetched at begin_layer, the prompt path's stager reads them with read_blob, and lent slots are refilled from the file. The adaptive tier keeps it in step: an expert leaving VRAM without a host copy gets a tier slot (copied back from its VRAM slot first), one entering VRAM gives its slot back. - --low-ram / --no-low-ram / --ram-budget GIB; by itself when the pack has experts.bin and the experts plus 16 GiB exceed the RAM installed (one GPU, an --expert-profile, no remote experts). - setup.py: its low-RAM mode passes --low-ram on Windows instead of --mmap-experts. - dispatcher: the PCIe share only for experts with a device alias (dma_capable). - STRATA_TIER_VERIFY / STRATA_TIER_STATS for tests. IQ2_XS: the same 128 tokens as the full arena with the same cache; every host copy equals the file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
|
Thanks! 0.1.31 added a tier for this case: |
|
Benchmarked as you asked, on the same machine: our tier against 0.1.31's Setup:
What the logs show:
Since ours wins here, I'll port it into the existing 0.1.31 tier rather than keep a second tier, and resubmit on top of the #285 split:
🤖 Generated with Claude Code |
|
Ported into 0.1.31's tier as #362 (stacked on #357), so there is no second tier. What moved over: the unbuffered reads of everything outside the RAM budget. They now read the GGUF in place per role, in overlapped batches. What did not need porting:
Results on the same emulated 32 GB PC + 16 GB GPU, 16 GiB budget, same day:
One finding that shapes the rest: NTFS serializes unbuffered reads of a file that is mapped anywhere.
🤖 Generated with Claude Code |
…ot keep it beside the RAM budget (Windows; #286 ported into 0.1.31's tier) With --resident-budget-gib on a PC whose RAM cannot hold the expert files beside the budget, every expert outside the budget comes from the drive anyway. Through the mapped GGUF that costs twice: - the page faults are small requests on the critical path (the prompt path's stager, the profile fill); - the pages they bring in take the RAM the budget was sized for. On an emulated 32 GB PC, the 16 GiB budget was clamped to 11.65 GiB after the profile fill. - FileExpertSource::set_unbuffered: chosen by experts_unbuffered (#357) with the budget as the RAM it keeps: whenever the files could not be kept beside it, cached now or not - a partly cached file's mapped pages would still land in the working set (seen on an emulated 64 GB PC: the budget shrank, then RAM ran out). Each shard is opened FILE_FLAG_NO_BUFFERING | OVERLAPPED. - copy_from_files, the decode prefetch and the complement copy read every role window of a batch at once, then copy it into place. - Windows that are less than 1 MiB apart merge into requests of up to 32 MiB. NTFS runs a file's unbuffered reads one at a time while the file is mapped anywhere, and the engine always maps the shards (token embedding, PLE). Measured on a PCIe 5 drive at queue depth 48: 512 KiB reads give 10.4 GB/s on an unmapped file and 3.4 GB/s on a mapped one; 8 MiB reads give 8.6 GB/s. - The profile fill reads its pairs in batches of 64, the next batch while this one is copied into the slots. - warms() is false when unbuffered. A PrefetchVirtualMemory of the mapping would read the experts through the cache, a second time. - Otherwise nothing changes: the mapped path stays for a keepable set, for no budget, and off Windows. STRATA_UNBUFFERED_LOAD=1/0 forces the choice. Greedy tokens are identical with the reads unbuffered, through the cache, and on 0.1.31. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
setup's low-RAM packs have an experts.bin, and with it 0.1.31's tier mapped it: on an emulated 32 GB PC the mapped reads took the RAM the budget was sized for, and available RAM fell below 1 GB (#286, measured yesterday). - set_unbuffered also takes experts.bin (paths_ is the one file); read_direct reads one window per blob (a blob is contiguous there) and merges near ones as for the GGUF. - blob() hands out the stage buffers for any unbuffered source (staged()), so prefetch, begin_layer and transient work as with the GGUF in place; the mapped experts.bin path is unchanged otherwise. IQ2_XS pack with experts.bin, emulated 32 GB PC + 16 GB GPU, 16 GiB budget, 8K prompt + 256 tokens, two runs: decode 100.2 / 100.6 tok/s, done at 17.2 / 15.5 s, the prompt path's host copies 2.1 s (the GGUF in place: 84-89 tok/s, 21.5-22.1 s, 4.3 s). Greedy tokens identical unbuffered, through the cache and on 0.1.31. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
…ot keep it beside the RAM budget (Windows; #286 ported into 0.1.31's tier) With --resident-budget-gib on a PC whose RAM cannot hold the expert files beside the budget, every expert outside the budget comes from the drive anyway. Through the mapped GGUF that costs twice: - the page faults are small requests on the critical path (the prompt path's stager, the profile fill); - the pages they bring in take the RAM the budget was sized for. On an emulated 32 GB PC, the 16 GiB budget was clamped to 11.65 GiB after the profile fill. - FileExpertSource::set_unbuffered: chosen by experts_unbuffered (#357) with the budget as the RAM it keeps: whenever the files could not be kept beside it, cached now or not - a partly cached file's mapped pages would still land in the working set (seen on an emulated 64 GB PC: the budget shrank, then RAM ran out). Each shard is opened FILE_FLAG_NO_BUFFERING | OVERLAPPED. - copy_from_files, the decode prefetch and the complement copy read every role window of a batch at once, then copy it into place. - Windows that are less than 1 MiB apart merge into requests of up to 32 MiB. NTFS runs a file's unbuffered reads one at a time while the file is mapped anywhere, and the engine always maps the shards (token embedding, PLE). Measured on a PCIe 5 drive at queue depth 48: 512 KiB reads give 10.4 GB/s on an unmapped file and 3.4 GB/s on a mapped one; 8 MiB reads give 8.6 GB/s. - The profile fill reads its pairs in batches of 64, the next batch while this one is copied into the slots. - warms() is false when unbuffered. A PrefetchVirtualMemory of the mapping would read the experts through the cache, a second time. - Otherwise nothing changes: the mapped path stays for a keepable set, for no budget, and off Windows. STRATA_UNBUFFERED_LOAD=1/0 forces the choice. Greedy tokens are identical with the reads unbuffered, through the cache, and on 0.1.31. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
setup's low-RAM packs have an experts.bin, and with it 0.1.31's tier mapped it: on an emulated 32 GB PC the mapped reads took the RAM the budget was sized for, and available RAM fell below 1 GB (#286, measured yesterday). - set_unbuffered also takes experts.bin (paths_ is the one file); read_direct reads one window per blob (a blob is contiguous there) and merges near ones as for the GGUF. - blob() hands out the stage buffers for any unbuffered source (staged()), so prefetch, begin_layer and transient work as with the GGUF in place; the mapped experts.bin path is unchanged otherwise. IQ2_XS pack with experts.bin, emulated 32 GB PC + 16 GB GPU, 16 GiB budget, 8K prompt + 256 tokens, two runs: decode 100.2 / 100.6 tok/s, done at 17.2 / 15.5 s, the prompt path's host copies 2.1 s (the GGUF in place: 84-89 tok/s, 21.5-22.1 s, 4.3 s). Greedy tokens identical unbuffered, through the cache and on 0.1.31. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
…nchronous reads) Niko1221#286's unbuffered file tier existed on Windows alone: on Linux the experts outside the RAM copy were always read through the page cache, as page faults of the mapped GGUF - small requests on the critical path, and pages that a 32 GB PC cannot keep beside a 16 GiB RAM copy anyway, so they were read again and again. - open_direct opens the files with O_DIRECT; read_direct queues every 4 KiB-aligned window of a batch with one io_submit (linux/aio_abi.h, no library; allowed by Docker's default seccomp profile, unlike io_uring) and waits for all of them, each thread with its own context and aligned buffer. Windows merges windows up to 1 MiB apart for NTFS; here only windows that touch are merged. A refused submit or a failed read falls back to the mapping, as on Windows. - The same decision as Windows' `cache_counts = false` arm: unbuffered when the file cache could not keep the expert bytes outside the RAM copy (platform::file_cache_keeps, from MemAvailable and the tightest cgroup limit), re-checked once the copy is built (Niko1221#577). STRATA_UNBUFFERED_LOAD=1 / 0 forces it either way. A pack's experts.bin works too (its Linux open now records the path). - direct_fallbacks() counts the blobs an unbuffered read could not deliver. - Tests: file_expert_source_test reads a synthetic pack unbuffered - one blob at a time, a batch of adjacent experts, copy_blob - and requires the file's bytes and no fallback (a mutation that fails every read is caught). ctest: 63 of 66 pass; the three others need a Q2_0 pack, a higher `ulimit -l` and AVX-512, as before. Measured on an RTX 3080 Ti Laptop 16 GB, i9-12900H, 30 GB RAM, KIOXIA PCIe 4 NVMe, Linux 7.0, ext4: Qwen3.8-Flash-Next Abliterated Q4_K_M in place (--native), --resident-budget-gib 16, --expert-cache auto, 8K context, greedy; three prompts (code, Russian prose, a 7.8K-token summary), each with and without MTP, two rounds of buffered (STRATA_UNBUFFERED_LOAD=0) against unbuffered, the same binary. Decode 4.38 -> 7.90 tok/s on average (x1.80; x1.49-x2.01 per prompt and mode), the 7.8K prompt read at 154/172 -> 184/290 tok/s, startup 36 -> 18-21 s. The code prompt's answer is the same text in all 16 runs; the other two differ between runs of either arm (the adaptive GPU cache changes which experts the CPU computes), as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ide Niko1221#286's unbuffered Windows reads, the CPU tier off when a peer GPU prefills - gemm: upstream's FP16 path below sm_80 replaces the local BF16->FP16 conversion (same effect on sm_70) - expert_source: the RAM copy keeps the per-role passes and read_blob (Linux pread); the unbuffered batches (Niko1221#286) take whole blobs in one pass when direct_ is open - generate: the profile fill keeps upstream's inline fill with prefetch_pairs when the file tier is unbuffered, otherwise the threaded fill_slots - prefill: the CPU tier's rows follow the GPU's (bounds = gpu_rows); it is off with --peer-device (m.pp); the next stage's thread drops the session affinity (run_impl, next_run_) - server: the grammar (response_format) import beside the think-literal helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es the keep set Upstream (v0.1.40, expert_source.cpp file_tier_unbuffered and platform::file_cache_keeps, Niko1221#286 / Niko1221#577 / Niko1221#773): the hottest experts get a RAM copy (our RAM tier); the rest are read through the file cache, or with O_DIRECT when the cache could not keep them (available RAM less 4 GiB below their bytes). It never drops pages after a buffered read (its notes: POSIX_FADV_DONTNEED made decode re-read from the disk). This replaces 7bd95ad's keep set and per-expert DONTNEED. The O_DIRECT reader covers each expert with its 4 KiB-aligned window. expert_stream_test runs both modes on a fake pack whose experts do not start on 4 KiB boundaries: 600 of 600 slots correct each (RTX 3060). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ot keep it beside the RAM budget (Windows; #286 ported into 0.1.31's tier) With --resident-budget-gib on a PC whose RAM cannot hold the expert files beside the budget, every expert outside the budget comes from the drive anyway. Through the mapped GGUF that costs twice: - the page faults are small requests on the critical path (the prompt path's stager, the profile fill); - the pages they bring in take the RAM the budget was sized for. On an emulated 32 GB PC, the 16 GiB budget was clamped to 11.65 GiB after the profile fill. - FileExpertSource::set_unbuffered: chosen by experts_unbuffered (#357) with the budget as the RAM it keeps: whenever the files could not be kept beside it, cached now or not - a partly cached file's mapped pages would still land in the working set (seen on an emulated 64 GB PC: the budget shrank, then RAM ran out). Each shard is opened FILE_FLAG_NO_BUFFERING | OVERLAPPED. - copy_from_files, the decode prefetch and the complement copy read every role window of a batch at once, then copy it into place. - Windows that are less than 1 MiB apart merge into requests of up to 32 MiB. NTFS runs a file's unbuffered reads one at a time while the file is mapped anywhere, and the engine always maps the shards (token embedding, PLE). Measured on a PCIe 5 drive at queue depth 48: 512 KiB reads give 10.4 GB/s on an unmapped file and 3.4 GB/s on a mapped one; 8 MiB reads give 8.6 GB/s. - The profile fill reads its pairs in batches of 64, the next batch while this one is copied into the slots. - warms() is false when unbuffered. A PrefetchVirtualMemory of the mapping would read the experts through the cache, a second time. - Otherwise nothing changes: the mapped path stays for a keepable set, for no budget, and off Windows. STRATA_UNBUFFERED_LOAD=1/0 forces the choice. Greedy tokens are identical with the reads unbuffered, through the cache, and on 0.1.31.
setup's low-RAM packs have an experts.bin, and with it 0.1.31's tier mapped it: on an emulated 32 GB PC the mapped reads took the RAM the budget was sized for, and available RAM fell below 1 GB (#286, measured yesterday). - set_unbuffered also takes experts.bin (paths_ is the one file); read_direct reads one window per blob (a blob is contiguous there) and merges near ones as for the GGUF. - blob() hands out the stage buffers for any unbuffered source (staged()), so prefetch, begin_layer and transient work as with the GGUF in place; the mapped experts.bin path is unchanged otherwise. IQ2_XS pack with experts.bin, emulated 32 GB PC + 16 GB GPU, 16 GiB budget, 8K prompt + 256 tokens, two runs: decode 100.2 / 100.6 tok/s, done at 17.2 / 15.5 s, the prompt path's host copies 2.1 s (the GGUF in place: 84-89 tok/s, 21.5-22.1 s, 4.3 s). Greedy tokens identical unbuffered, through the cache and on 0.1.31.
…ot keep it beside the RAM budget (Windows; Niko1221#286 ported into 0.1.31's tier) With --resident-budget-gib on a PC whose RAM cannot hold the expert files beside the budget, every expert outside the budget comes from the drive anyway. Through the mapped GGUF that costs twice: - the page faults are small requests on the critical path (the prompt path's stager, the profile fill); - the pages they bring in take the RAM the budget was sized for. On an emulated 32 GB PC, the 16 GiB budget was clamped to 11.65 GiB after the profile fill. - FileExpertSource::set_unbuffered: chosen by experts_unbuffered (Niko1221#357) with the budget as the RAM it keeps: whenever the files could not be kept beside it, cached now or not - a partly cached file's mapped pages would still land in the working set (seen on an emulated 64 GB PC: the budget shrank, then RAM ran out). Each shard is opened FILE_FLAG_NO_BUFFERING | OVERLAPPED. - copy_from_files, the decode prefetch and the complement copy read every role window of a batch at once, then copy it into place. - Windows that are less than 1 MiB apart merge into requests of up to 32 MiB. NTFS runs a file's unbuffered reads one at a time while the file is mapped anywhere, and the engine always maps the shards (token embedding, PLE). Measured on a PCIe 5 drive at queue depth 48: 512 KiB reads give 10.4 GB/s on an unmapped file and 3.4 GB/s on a mapped one; 8 MiB reads give 8.6 GB/s. - The profile fill reads its pairs in batches of 64, the next batch while this one is copied into the slots. - warms() is false when unbuffered. A PrefetchVirtualMemory of the mapping would read the experts through the cache, a second time. - Otherwise nothing changes: the mapped path stays for a keepable set, for no budget, and off Windows. STRATA_UNBUFFERED_LOAD=1/0 forces the choice. Greedy tokens are identical with the reads unbuffered, through the cache, and on 0.1.31.
setup's low-RAM packs have an experts.bin, and with it 0.1.31's tier mapped it: on an emulated 32 GB PC the mapped reads took the RAM the budget was sized for, and available RAM fell below 1 GB (Niko1221#286, measured yesterday). - set_unbuffered also takes experts.bin (paths_ is the one file); read_direct reads one window per blob (a blob is contiguous there) and merges near ones as for the GGUF. - blob() hands out the stage buffers for any unbuffered source (staged()), so prefetch, begin_layer and transient work as with the GGUF in place; the mapped experts.bin path is unchanged otherwise. IQ2_XS pack with experts.bin, emulated 32 GB PC + 16 GB GPU, 16 GiB budget, 8K prompt + 256 tokens, two runs: decode 100.2 / 100.6 tok/s, done at 17.2 / 15.5 s, the prompt path's host copies 2.1 s (the GGUF in place: 84-89 tok/s, 21.5-22.1 s, 4.3 s). Greedy tokens identical unbuffered, through the cache and on 0.1.31.
…ot keep it beside the RAM budget (Windows; Niko1221#286 ported into 0.1.31's tier) With --resident-budget-gib on a PC whose RAM cannot hold the expert files beside the budget, every expert outside the budget comes from the drive anyway. Through the mapped GGUF that costs twice: - the page faults are small requests on the critical path (the prompt path's stager, the profile fill); - the pages they bring in take the RAM the budget was sized for. On an emulated 32 GB PC, the 16 GiB budget was clamped to 11.65 GiB after the profile fill. - FileExpertSource::set_unbuffered: chosen by experts_unbuffered (Niko1221#357) with the budget as the RAM it keeps: whenever the files could not be kept beside it, cached now or not - a partly cached file's mapped pages would still land in the working set (seen on an emulated 64 GB PC: the budget shrank, then RAM ran out). Each shard is opened FILE_FLAG_NO_BUFFERING | OVERLAPPED. - copy_from_files, the decode prefetch and the complement copy read every role window of a batch at once, then copy it into place. - Windows that are less than 1 MiB apart merge into requests of up to 32 MiB. NTFS runs a file's unbuffered reads one at a time while the file is mapped anywhere, and the engine always maps the shards (token embedding, PLE). Measured on a PCIe 5 drive at queue depth 48: 512 KiB reads give 10.4 GB/s on an unmapped file and 3.4 GB/s on a mapped one; 8 MiB reads give 8.6 GB/s. - The profile fill reads its pairs in batches of 64, the next batch while this one is copied into the slots. - warms() is false when unbuffered. A PrefetchVirtualMemory of the mapping would read the experts through the cache, a second time. - Otherwise nothing changes: the mapped path stays for a keepable set, for no budget, and off Windows. STRATA_UNBUFFERED_LOAD=1/0 forces the choice. Greedy tokens are identical with the reads unbuffered, through the cache, and on 0.1.31. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
setup's low-RAM packs have an experts.bin, and with it 0.1.31's tier mapped it: on an emulated 32 GB PC the mapped reads took the RAM the budget was sized for, and available RAM fell below 1 GB (Niko1221#286, measured yesterday). - set_unbuffered also takes experts.bin (paths_ is the one file); read_direct reads one window per blob (a blob is contiguous there) and merges near ones as for the GGUF. - blob() hands out the stage buffers for any unbuffered source (staged()), so prefetch, begin_layer and transient work as with the GGUF in place; the mapped experts.bin path is unchanged otherwise. IQ2_XS pack with experts.bin, emulated 32 GB PC + 16 GB GPU, 16 GiB budget, 8K prompt + 256 tokens, two runs: decode 100.2 / 100.6 tok/s, done at 17.2 / 15.5 s, the prompt path's host copies 2.1 s (the GGUF in place: 84-89 tok/s, 21.5-22.1 s, 4.3 s). Greedy tokens identical unbuffered, through the cache and on 0.1.31. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio
Call-scope ResidentExecutor over ResidentSlots: lease-bound submit, committed-progress observation with separate resource/output watermarks, idempotent cancel/drain, generation-fenced synchronous certified snapshot borrow/return. Focused CPU contract regressions. No model issuance, production call-site migration, allocation reduction, real-request qualification, latency/speedup or promotion; Niko1221#286 remains open for the transaction-scoped migration.
Summary
Stacked on #285 (it uses its deferred per-layer registration). Only the last commit is new here.
The resident arena holds every expert, including the VRAM cache's share of them a second time. A PC whose RAM cannot
hold them beside the system has setup's low-RAM mode,
--mmap-experts, which leaves the experts to the OS filecache. On Windows that cache fills RAM and gets trimmed, and decode falls off. On the NVFP4 fork, copying blobs
through the mapped file made Windows trim and decode fell from 72 to 33 tok/s.
TieredExpertSourcekeeps host copies only where the engine reads them:minus
STRATA_RAM_RESERVE_GIB(default 6). They go in by rank: first the experts outside VRAM, then the VRAMcache's tail that the prompt path borrows. The GPU copies them by DMA like the full arena's.
experts.binunbuffered, so the file cache neither grows nor gets trimmed. Adecode token's misses are prefetched per layer (
begin_layer), the prompt path's stager reads them withread_blob, and lent slots are refilled from the file.its VRAM slot first); one entering VRAM gives its slot back.
--low-ram,--no-low-ramand--ram-budget GIBcontrol it. It also switches on by itself when the pack hasexperts.bin(setup writes it only for its low-RAM mode) and the experts plus 16 GiB exceed the RAM installed. Itneeds one GPU, an
--expert-profile, and no remote experts. setup's low-RAM mode passes--low-ramon Windowsinstead of
--mmap-experts. The loader is Windows-only for now, so Linux keeps--mmap-experts.Measured
Measured on current main (0.1.29, d6708a4) with ISTA-DASLab's IQ2_XS, RTX 5090 32 GB, Ryzen 9 9950X3D, 128 GB DDR5, Windows 11. KL is first-token KL divergence (
STRATA_DUMP_FIRST_LOGITS, #276); two runs of main itself differ by 0 on 5 of 6 short prompts and by 0.00013 on the sixth.arena and the tier (
--ram-budget 8) generate the same 128 tokens.STRATA_TIER_VERIFYcompared 5,460 hostcopies with the file, and later 5,604 including the ones copied back from VRAM by the adaptive tier: 0 differ.
149.6 with the full arena (static cache, no PCIe share, 128 tokens).
With 96 GB or more nothing changes: first-token KL to the arena is exactly 0.
Switch
--no-low-ramgives the full arena;--mmap-expertsstill selects the mapped file.🤖 Generated with Claude Code
https://claude.ai/code/session_01VZy1yKaDDiA8a7svdwaHio