Repository navigation
Assemble loader tensors directly into their spill destination - #793
Merged
mkolodner-sc merged 1 commit intoOct 9, 2026
Merged
mkolodner-sc merged 1 commit into
mkolodner-sc merged 1 commit into
Conversation
mkolodner-sc
requested review from
kmontemayor2-sc,
svij-sc,
xgao4-sc,
yliu2-sc and
zfan3-sc
as code owners
October 7, 2026 21:13
kmontemayor2-sc
approved these changes
Oct 9, 2026
kmontemayor2-sc
left a comment
Collaborator
There was a problem hiding this comment.
Thanks Matt! LGTM provided the comments are addressed :)
mkolodner-sc
force-pushed
the
mkolodner-sc/assemble-entity-tensors-into-spill-destination
branch
from
October 9, 2026 18:21
a4e3f18 to
80d9d0c
Compare
yliu2-sc
approved these changes
Oct 9, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 9, 2026
load_as_torch_tensors joined per-batch tensors with tf.concat, which allocates the full result alongside the still-live list of batches -- a transient second full-size copy in anonymous memory. When tensor spilling is enabled, allocate the destination up front via allocate_disk_backed and stream each batch into its slice, freeing the batch as it goes, so the assembled tensor never coexists with a second full-size copy. Fall back to tf.concat unchanged when a disk-backed buffer is not used (spilling disabled, below the size threshold, or an unmapped dtype). Measured on a 7.6 GiB fp32 shard, peak process RSS for the assembly step drops from 16.3 GiB to 8.7 GiB.
mkolodner-sc
force-pushed
the
mkolodner-sc/assemble-entity-tensors-into-spill-destination
branch
from
October 9, 2026 20:14
80d9d0c to
8bf29cd
Compare
mkolodner-sc
deleted the
mkolodner-sc/assemble-entity-tensors-into-spill-destination
branch
October 9, 2026 22:51
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.
What
TFRecordDataLoader.load_as_torch_tensorsassembles each entity's tensor by accumulating per-batch tensors in a list and joining them withtf.concat. The finaltf.concatallocates the whole result while the list of batches is still alive, so the assembled tensor momentarily coexists with a second full-size copy of itself in anonymous memory.When tensor spilling is enabled, this change allocates the full-size destination up front via
allocate_disk_backed(...)and streams each batch into its slice, freeing the batch as it goes — so the result never coexists with a second full-size copy. When a disk-backed buffer is not used (spilling disabled, below the size threshold, or an unmapped dtype), it falls back to the existingtf.concatpath unchanged, so behaviour is identical for callers that do not spill.This is the "buffer that does not exist yet" case
allocate_disk_backedalready documents ("allocating the destination as the file from the start means those bytes never occupy anonymous memory at all") — the loader just wasn't using it for the final assembly yet.Why
The assembly step is a peak-memory hotspot at load time. Measured on a 7.6 GiB fp32 shard (process RSS high-water-mark across the assembly step):
tf.concat(before)The transient second copy is removed — peak drops from ~2× the shard to ~1×.
Tests
Adds
test_load_as_torch_tensors_assembles_into_spilled_destination: with spilling enabled the loaded ids / features / labels are byte-identical to the in-memory (tf.concat) result and are disk-backed; with spilling disabled, behaviour is unchanged. The existingdataloaders_test.pycases continue to cover the non-spilling (fallback) path.