Repository navigation
Conversation
With disk-backed embedding tables, cold long prefill waits on Engram gathers: on a fresh 106k-token prompt the GPUs spent 5.0-5.9 s of 10.1-10.7 s waiting for table rows. The Linux reader submits every gather through one io_uring on the delivery thread, and --embedding-table-workers above one was rejected on Linux. fio with the same pattern (4 KiB direct random reads, 128 per batch, drained per batch) tops out at about 264k reads/s on one ring, independent of depth or refill policy, while several rings sharing the same 128-slot budget reach 386k (2), 499k (4) and 590k (8) reads/s on the same files. Linux now uses the Windows worker design: each of 1, 2, 4, or 8 lanes owns an io_uring and registered staging, the lanes share the 128 slots and 8 MiB of staging per table, large gathers split their planned reads across scoped helper threads, and small gathers stay on the delivery thread. A lane refills its window as reads complete and, after an error or panic, drains reads the kernel still owns before the next gather can reuse the ring. Row planning, coalescing, output ownership and counters are unchanged; worker phase counters sum overlapping intervals as on Windows. The Linux default stays at one worker. The two portable worker tests move from the Windows module to the shared reader tests, so Linux also checks that 1, 2, 4 and 8 workers return identical rows within guard bands with identical read counts and recover after a truncated file. A Linux test checks the shared slot and staging budget. Validation: - Helios with runtime-package,server, memlock unlimited: 1279 passed, 7 failed; cc696a6 without this change: 1276 passed, the same 7 failed (chat-template and Gemma template tests that need checkpoint templates absent here). The 3 additional passes are the moved tests and the new Linux budget test. All 29 Engram tests pass. - GPU: TP4 on four RTX PRO 6000 Blackwell, a DeepSeek-V4.1-Flash-1017 derivative package, disk Engram on Btrfs RAID0 over two PCIe 5.0 NVMe drives, 64 GiB row cache, resident scales. A fresh server per arm (empty row cache) served the same fresh prompts. Workers 1, 2, 4, 8, then 1 again, in two rounds: random 106k tokens: 10.1-10.7 s (1) -> 9.1-10.0 s (2), 9.2-9.7 s (4), 9.1-9.9 s (8) Python stdlib 77k tokens: 6.9-7.0 s -> 6.2 s (2), 6.2-6.4 s (4), 6.3 s (8) GPU wait on Engram, random 106k: 5.0-5.9 s -> 4.1-4.8 s The repeated one-worker arm reproduced the first. Decode throughput and a fixed arithmetic answer were unchanged. Limitations: the end-to-end gain is about 10-12% on cold prefill and does not grow beyond two workers here. Gathers average about 40k reads, and summed lane wait divided by lanes stays near 7 s for 2, 4 and 8 workers, so the remaining disk time is not the single ring. The Linux default is unchanged; the measurements cover one host, one filesystem and one drive pair. Windows was not built or run here: its reader code is unchanged, and only its two portable tests moved. Design-Signed-Off-By: Claude Opus 5.5 (agent for Josh Cartu); design-review=1c01 Signed-off-by: Josh Cartu <j@mail99.me>
Author
|
Closing this. A follow-up test showed the filesystem was the real bottleneck, not the single reader thread. Same package on the same box. The only change was moving the Engram files from Btrfs RAID0 (2× Gen5) to XFS on a single Gen4 drive:
On XFS, extra workers add nothing, so this change only helps Btrfs users. The practical advice for disk Engram on Linux is XFS or ext4, not more workers. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
With disk-backed Engram tables, cold long prefill waits on table-row gathers. On a fresh 106k-token prompt the GPUs spent 5.0–5.9 s of 10.1–10.7 s waiting on Engram (
replay_readiness_wait_ns). This is the slow-prefill-after-compaction issue reported in the LiL "Disk engram prefill problem" thread.On Linux, every gather goes through one
io_uringon the delivery thread, and--embedding-table-workersabove 1 is rejected. fio with the same pattern (4 KiBO_DIRECTrandom reads, 128 per batch, drained per batch) on the package's Engram files shows that one ring is the ceiling:In production Flare measured 270k reads/s during that prefill, at the one-ring ceiling.
Change
Linux uses the existing Windows worker design, with
io_uringlanes:--embedding-table-workersnow works on Linux.docs/cli-design.mdis updated.Tests
reader/windows.rsinto the shared reader tests. Linux now checks that 1, 2, 4 and 8 workers return byte-identical rows within guard bands, issue identical read counts, and recover after a truncated file.runtime-package,server, memlock unlimited):cc696a6b: 1276 passed, the same 7 failed (chat-template and Gemma template tests that need checkpoint templates not present on this host)GPU measurement
Setup:
Results:
Limitations
--embedding-table-workerswas described as a Windows-only setting in Discord. This opens it on Linux, but whether Linux should have it is your decision.Prepared with an AI agent (Claude Opus 5.5); see the
Design-Signed-Off-Bytrailer. This is host I/O in Helios; it touches no CUDA, Triton or GPU-optimization code (design-review principle 14).