Skip to content

0.1.38: UD-Q4_K_XL prompts 15-40% slower on a 96 GB PC, from the unbuffered file tier (STRATA_UNBUFFERED_LOAD=0 restores them) #577

Closed

Description

@brenoperucchi

mise ~/.config/mise/config.toml tools: gh@2.102.0
On 0.1.38 the Unsloth UD-Q4_K_XL model reads prompts noticeably slower than on 0.1.34 on this machine. The log shows
the file tier switching to unbuffered reads (#357/#362), and setting STRATA_UNBUFFERED_LOAD=0 brings the speed back,
slightly above 0.1.34.

Machine: RTX 5090 32 GB, Ryzen 9 5950X (AVX2), 96 GB DDR4-3200, NVMe, Windows 11, driver 616.64. Release binaries
0.1.34 and 0.1.38.
Model and config: UD-Q4_K_XL (hand-made pack, GGUF read in place), the same configs as in #433:
--resident-budget-gib 72|40 --expert-cache auto --prefill auto --spec 4 --spec-min-p 0.5 --max-context 32768 --kv int8. With 72 GiB every expert the GPU cache does not hold (48.94 GiB) is resident in RAM; with 40 GiB the rest
come from the GGUF.
Method: as in #433, public prompts built from this repo, 1 warm-up + 3 measured runs, each run reading its whole
prompt fresh; engine timings, medians.

Prompt reading, tokens/s:

Budget Prompt 0.1.34 0.1.38 0.1.38, STRATA_UNBUFFERED_LOAD=0
72 GiB ~2.7K 890 757 899
72 GiB ~14.7K 1,949 1,658 2,038
40 GiB ~2.7K 803 472 844
40 GiB ~14.7K 1,844 1,105 1,913

Decode is about the same in all of them. At start, 0.1.38 logs:

strata generate: the file tier reads unbuffered (2 of 48 probe reads from the file cache; 83.0 GiB available, 103.7 GiB of files)

and with the variable set:

strata generate: the file tier reads through the file cache (STRATA_UNBUFFERED_LOAD=0)

From experts_unbuffered() in src/core/pinned.cu, the decision is room >= total_bytes with room = available - arena_bytes - 4 GiB, and set_unbuffered() gets the requested budget (o.resident_budget) as arena_bytes. Here that
is 83.0 - 72 - 4 = 7 GiB against 103.7 GiB of files (all four shards), so the reads go unbuffered. With 72 GiB the
requested budget is larger than what is actually resident (48.94 GiB), which makes room smaller than it is. Even at
40 GiB, where the experts outside the budget really do come from the files, the file cache was faster than unbuffered
reads on this PC with 96 GB.

The packs on 0.1.38 got faster on the same machine (Swift IQ3_XXS and IQ3_S, prompt reading +11-20% at 14.7K and
28.9K tokens), so this seems specific to the GGUF-in-place file tier. The numbers will also go into #433.

Activity

  1. added 3 commits that reference this issue on Oct 4, 2026
  2. Niko1221 commented on Oct 4, 2026

    @Niko1221
    Owner

    Fixed in 0.1.39, thank you for the clear numbers and for finding the cause. The file tier decided on unbuffered reads before the RAM copy was built, from the budget you asked for (72 GiB) and against every shard's bytes (103.7 GiB, the dense weights and the PLE table included). Now it compares only the expert bytes the file tier really reads with the RAM left next to the copy. It decides once from the budget, so a low-RAM PC still reads the profile fill unbuffered as in 0.1.38. It then decides again after the copy is built, using the RAM the copy really holds (48.94 GiB in your case). On your 96 GB PC both budgets (72 and 40) now read through the file cache, while 32 and 64 GB PCs stay unbuffered. The start log has a line with the numbers it used (the file tier reads ... (re-checked with the RAM copy built (48.94 GiB): ...)). The tokens are the same either way. STRATA_UNBUFFERED_LOAD=0/1 still forces it. If you can, a run of your 72/40 GiB configs on 0.1.39 without the variable would confirm it on the PC that showed it.

  3. brenoperucchi commented on Oct 5, 2026

    @brenoperucchi
    ContributorAuthor

    Confirmed on the same PC (RTX 5090, Ryzen 9 5950X, 96 GB DDR4-3200), UD-Q4_K_XL, 0.1.39 release build, both configs without STRATA_UNBUFFERED_LOAD. Both now read through the file cache, and the start log shows the second check:

    72 GiB: the file tier reads through the file cache (re-checked with the RAM copy built (48.94 GiB): 33.6 GiB available, 0.0 GiB of it still to be taken by the RAM copy, 22.8 GiB of experts read from the files: the file cache can keep them)
    40 GiB: the file tier reads through the file cache (re-checked with the RAM copy built (40.00 GiB): 41.7 GiB available, 0.0 GiB of it still to be taken by the RAM copy, 31.7 GiB of experts read from the files: the file cache can keep them)
    

    Prompt reading, median of 3 runs after a warm-up, same prompts as in the issue:

    Budget Prompt 0.1.38 0.1.38 + STRATA_UNBUFFERED_LOAD=0 0.1.39
    40 GiB medium (2.7K) 472 tok/s 844 tok/s 857 tok/s
    40 GiB long (14.7K) 1,105 tok/s 1,913 tok/s 1,896 tok/s
    72 GiB medium (2.7K) 757 tok/s 899 tok/s 916 tok/s
    72 GiB long (14.7K) 1,658 tok/s 2,038 tok/s 2,043 tok/s

    0.1.39 with no variable lands where 0.1.38 was with the workaround, so the variable isn't needed anymore on this PC. Thanks for the fix and for the log line, it made this a one-look check. The runs and engine logs are in #433.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions