Repository navigation
Conversation
ormandj
requested review from
BBuf,
Edwardf0t1,
Fridge003,
HaiShaw,
JustinTong0323,
Qiaolin-Yu,
Ying1123,
b8zhong,
ch-wan,
hnyls2002,
ispobock,
merrymercy,
mmangkad,
sogalin,
wisclmy0611,
xiezhq-hermann and
zijiexia
as code owners
October 7, 2026 05:45
17 of 56 tasks
This was referenced Oct 14, 2026
…tream
A model can name the checkpoint tensors it keeps in host memory through
host_resident_weight_patterns. Under --load-format instanttensor, the loader
reads the safetensors headers and streams only files without such tensors to
the GPU. Files that hold them load through the CPU safetensors iterator;
their other tensors are moved to the device, where InstantTensor places
everything else. DeepSeek-V4 and its DSpark draft name the Engram tables
when --engram-config places them on the CPU ("placement": "cpu").
…ed reads
With the Engram host table, each rank owns a row range of the Engram tables
in pinned host memory. The safetensors path copied those rows out of a
memory map, faulting the file in page by page. For files with host-resident
tensors, yield a SafetensorsRowSource for the matching names instead;
EngramEmbedding reads only its own rows with parallel preadv straight into
its shard; for per-rank shards ("replication": "none") it also asks the
kernel to drop the read range from the page cache.
ormandj
force-pushed
the
engram-positioned-reads
branch
from
October 29, 2026 21:50
128e20a to
f415e58
Compare
3 of 5 tasks
This branch has not been deployed
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.
Stacked on #42919 ("[Model Loader] Let InstantTensor load DeepSeek-V4.1 with the Engram host table"): this branch carries its commit, and the diff to review is the last commit, "[DeepSeek-V4.1] Fill host-resident Engram rows with parallel positioned reads". #40453 (InstantTensor loader by YitaoYuan) is now on main. I will rebase this PR when #42919 lands.
Motivation
With
--engram-config '{"placement": "cpu"}', the two Engram tables (188.8 GiB of rows and scales) live in pinned host memory, and each TP rank loads only its own row range. With one shard per rank ("replication": "none"), a rank holds 47.2 GiB at TP4. Under--load-format instanttensor, #42919 loads these files through the CPU safetensors iterator. That iterator returns memory-mapped tensors, soEngramEmbedding._load_rowscopies its rows out of the file mapping one page fault at a time. On the setup below, that phase took 68.3 s (2.8 GiB/s aggregate over 4 ranks). This was more than half of the target model's load time.A rank's rows are one contiguous byte range of the file. Large parallel reads straight into the pinned shard are much faster.
Modifications
weight_utils.SafetensorsRowSource(path, offset, shape, dtype): a row-major checkpoint tensor that can be read by row range.read_rows_into(dst, row_start)checks the destination: contiguous CPU tensor, same dtype and row shape, range in bounds. It then fillsdstwith parallelos.preadvcalls (8 threads, 64 MiB chunks) at the right file offsets, retrying short reads; a premature end of file raises. Withdrop_page_cache=True, it callsposix_fadvise(POSIX_FADV_DONTNEED)after each chunk where available, so the kernel can drop the cached copy. That call is advisory, and its errors are logged at debug level.weight_utils.host_resident_weights_iterator(files, patterns): reads offsets from the safetensors header. It yields aSafetensorsRowSourcefor tensor names that match the model'shost_resident_weight_patterns, and memory-mapped tensors fromsafe_openfor all other names.--load-format instanttensor, files with host-resident tensors now use this iterator. TheSource.host_resident_weight_patternsdocstring states that the matching parameters' weight loaders must accept a row source.--weight-loader-disable-mmapis not applied to these files: the tables are read withpreadv, and the few other tensors in the files come fromsafe_open. With that flag, the previous path could not load these files:safetensors.torch.load(safetensors 0.8.0) has noF8_E8M0dtype.EngramEmbedding._load_rowsreads only its own rows from a row source into the same destination as before: the rank's slice of the full table in thesharedlayout, or its whole shard in theper_ranklayout. It requests page-cache eviction only in theper_ranklayout, where this was measured; thesharedlayout keeps the page cache as before. Tensor inputs keep the existing copy. Row sources are only produced for host tables, so device tables are unchanged. The DSpark draft drops Engram names before it touches the value, so it reads no Engram rows.Accuracy Tests
Load-path change only; the rows loaded are byte-identical. New
test/registered/unit/model_loader/test_host_resident_rows.py(CPU) uses a checkpoint with an FP8 E4M3 table, its E8M0 scales, and an FP32 table:read_rows_intomatch the memory-mapped tensor byte for byte. Small chunks (1-77 bytes) and 1/3/8 threads exercise chunk boundaries inside rows and inside elements.EngramEmbeddingis built for every rank at TP 1-4, with 37 rows (uneven splits). Theper_rankandsharedhost layouts use a plain CPU buffer in place of the pinned host table, so the weight and scale are views into one buffer. The tensor path with CPU parameters is covered too. Loading from row sources gives the same bytes as loading from the memory-mapped tensors. In thesharedlayout, other ranks' rows are left untouched.posix_fadvisedoes not fail the load, and a truncated file raisesEOFError.EngramEmbeddingrequests page-cache eviction in theper_ranklayout only, not insharedor for device tables.test_instanttensor_loader.py, the host-resident names arrive as row sources with the full contents.On this branch (current main plus #40453 and #42919), both files pass (21 tests) on macOS (CPU) and on Linux aarch64 (CPU, PyTorch 2.14.1); the Linux run covers the real
posix_fadvisepath. The rest oftest/registered/unit/model_loader/also passes on macOS (139 passed, 1 skipped in total;test_modelopt_loader.pywas not collected locally becausetvm_ffiis not installed). Mutating the read offset, the chunk ranges, the short-read retry, the rank'srow_start, or the dtype check makes the new tests fail.Earlier, on an older main with the same production diff, a separate check used the real InstantTensor library on one RTX PRO 6000 Blackwell GPU. Rows read into pinned buffers for every rank at TP 1-4 matched the memory map byte for byte and copied to the GPU unchanged. Pinned,
cudaHostRegistered host tables were exercised by the serving runs below.#42787 (column-aligned Engram shards) changes how
row_startandrowsare chosen;_load_rowsonly consumes them, and the two branches merge without conflicts.2026-10-29: rebased onto main
974831643f, where #40453 and #42787 have landed (the branch now carries only the commit of #42919 and this one) and #46893 replaced the host-table variables with--engram-config, so theper_ranklayout is now"placement": "cpu"with"replication": "none"(where page-cache eviction applies) andsharedis"replication": "per_node"; the row test selects them through--engram-configand covers both the column-aligned and the equal-row split, both test files pass on the new head (21 tests, macOS CPU), and the SM120 GPU results in this description are from the previous head and will be re-run.Speed Tests and Profiling
DeepSeek-V4.1-Flash, TP4/EP4, 4x RTX PRO 6000 Blackwell (SM120, PCIe), DSpark draft, host Engram table (per-rank layout), checkpoint on local NVMe (ZFS), on an older main with the same production diff. A/B of this change on the same build, one server start each, timed from the server log. The "Engram files" time runs from the end of the InstantTensor stream to the Engram host-table completion message on TP0:
For reference, the default safetensors loader takes 264.2 s for the target model on the same setup. The time spent on the device files (about 40 s) and the DSpark draft load (40.0 s before, 39.5 s after) did not change.
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciDeveloped with AI assistance.
CI States
Latest PR Test (Base): ❌ Run #40961112832
Latest PR Test (Extra): ❌ Run #40961112286
Latest PR Test (AMD ROCm 10): ❌ Run #40961112526