Repository navigation
flashnext cuda: experts load past the page cache with core's direct_gather, and a load keeps its shards open (cold load 74 → 48 s) - #1901
Conversation
|
Thanks @jschmied, this is a nice result: the same device bytes and replies, with a cold start from about 74 s to 48 s. We've queued it on our GB10 with the FP4-Local checkpoint, main against this branch, and will post the numbers. Three questions from reading it:
|
|
A closer read of point 1, @jschmied. On the other two: more than 64 held shards in one gather fails the load with no fallback, and the earlier chunks' views point into reused memory but nothing reads them after packing. A guard or a comment would cover the second. The equality is shown by your mapped-against-direct packed-word test on a 36-shard fixture and four equal reply hashes. That's good, and a real-checkpoint byte comparison would make it airtight. Our GB10 A/B will show whether decode moves. |
|
Thanks, all three are right. Fixed in
Checks on For the real-checkpoint byte comparison, I'll load every expert layer of the FP4-Local checkpoint mapped and direct on the test driver, compare the packed bytes, and post the result here. |
|
Here's the real-checkpoint byte comparison. A scratch test (not in the PR) runs All 48 layers give identical hashes in both modes. Layer 0, for example: up |
|
Thanks @jschmied, the fixes are exactly right. Our GB10 run on |
…; nvfp4_slice.shapes checks without reading bytes
…s shards open instead of reparsing them (ashhart#1873)
…t one gather's shards reads through the mapping, packed chunks' views cleared
750a556 to
b61527f
Compare
|
Thank you @jschmied. This is merged into main with your commits under your own name, so you're listed as a TensorFold contributor. It ships in the next release, credited to you in the changelog and the release notes. |
|
Thanks @jschmied! This is in TensorFold 1.2.2, out now: https://github.com/ashhart/TensorFold/releases/tag/v1.2.2 |
Closes #1873. Flash-Next's CUDA cold load on a GB10 goes from about 74 s to 48 s (−35 %), and the served replies stay identical.
A/B (GB10,
nvidia/Qwen3.8-Flash-Next-FP4-Local,--parallel 1 --context 16384 --prompt-cache-gib 0; every shard dropped from the page cache before each start; order main, branch, branch, main; the branch was then rebased onto main58375fe00):Four greedy replies per run hash the same in all four runs.
TF_LOAD_DIRECT=0(the mapped path, with the store fix below) takes 58 s.What the time was. Direct reads alone were slower than main (76 vs 70 s), because main's
MADV_WILLNEEDread-ahead overlaps with its views loop. Phase timers then found two other costs:nvfp4_slice.dimensionsrunscsf.Plane.init, which read about 7 GB of CSF scale planes through the mapping on the main thread before any pack thread started.Changes
core/direct_gather.zig(new): it reads the bytes of views a loader borrowed from its mapped files again with O_DIRECT, on a few threads in 8 MiB pieces. Ranges that sit within 1 MiB of each other are joined. The views are then pointed at the copies, and the bytes stay the same. It usesdirect_io, so a file system without O_DIRECT falls back to the page cache.TF_LOAD_DIRECT=0turns it off. Any loader that hands out mapped views can use it.core/nvfp4_slice.zig:shapes()makes every metadata checkdimensions()makes, without reading plane bytes.dimensions()is nowshapes()plus the CSFPlane.init.flashnext/cuda_prompt_wt.zig: a load keeps every shard it released open (with its pages dropped) untilloaded(), instead of the last two.flashnext/cuda_modelopt_threads.zig: with direct reads, a chunk's codes, scales, fixed parts, exceptions and global scales are gathered before it is packed. The CSF planes are still checked byPlane.initduring packing, on the gathered bytes.Tests: host tests for
direct_gathercover views across pieces, a 1-byte view, an unaligned tail, an empty view and a refused unmapped view. Existing tests that now run both ways:loaded().Left out: the gather (about 405 ms a layer) doesn't overlap with packing yet; about 22 s of the load is outside the experts; the store's
use()path still reopens shards (116 opens, 4.1 s).Checks (GB10, on main
58375fe00): lean 0 new,zig build testand the CI set pass,git diff --checkclean.