Support Loading Parquet Files in WholeGraph - #497
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
Greptile SummaryAdds bounded, direct Parquet loading for WholeMemory-backed tensors and embeddings.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Sequence DiagramsequenceDiagram
participant API as DistTensor / DistEmbedding
participant Meta as Parquet metadata reader
participant WM as WholeMemory allocator
participant Reader as Bounded Parquet reader
participant Rank as Rank-local partition
API->>Meta: Inspect schemas and row counts
Meta-->>API: Inferred or validated shape
API->>WM: Allocate final distributed tensor
WM-->>API: Rank-local row interval
API->>Reader: Read intersecting row groups in batches
Reader-->>Rank: Convert and copy dense row-major batches
Rank->>WM: Synchronize completed load
Reviews (4): Last reviewed commit: "improve error message" | Re-trigger Greptile |
|
/ok to test 59185e5 |
|
/ok to test 0aa7e8e |
jameslamb
left a comment
There was a problem hiding this comment.
Reviewed for packaging-codeowners, left some very very minor feedback. Do what you want with it, including ignoring it or addressing in a follow-up. Marking this "approve" so you have what you need to merge without another review.
I only lightly skimmed the Python code, deferring to the other reviews on correctness, performance, etc.
| common: | ||
| - output_types: [conda, pyproject, requirements] | ||
| packages: | ||
| - *pyarrow |
There was a problem hiding this comment.
| - *pyarrow |
Since pyarrow is now a hard required dependency, I'd keep it out of the [test] extra. I think we generally prefer to only have that extra provide additional packages on top of what's in dependencies or to provide different constraints.
For example, cudf declares pyarrow in its runtime dependencies but not its [test] extra: https://github.com/rapidsai/cudf/blob/cfb5a7d8ce9c902844e216054a49b36daebc5491/python/cudf/pyproject.toml#L34
| dependencies = [ | ||
| "libwholegraph==26.10.*,>=0.0.0a0", | ||
| "numpy>=2.0,<3.0", | ||
| "pyarrow", |
There was a problem hiding this comment.
Just to write this somewhere... I think it's totally fine to start with this unconstrained and only add constraints as you discover issues, especially with the small slice of the pyarrow API this PR is using.
There was a problem hiding this comment.
Actually now that I think about it - do we have a RAPIDS-wide pyarrow constraint?
There was a problem hiding this comment.
Not that we should apply it here but just as something that's nice to know
There was a problem hiding this comment.
Good question. I think the answer is "not really, everything just kind of follows what pandas / cuDF do".
Looks like cudf today is the only one with an explicit pin on it: https://github.com/search?q=pyarrow+path%3Adependencies.yaml+%28org%3Arapidsai+OR+org%3ANVIDIA%29+AND+NOT+is%3Aarchived&type=code
Co-authored-by: James Lamb <jaylamb20@gmail.com>
|
/ok to test f7bafc5 |
|
/merge |
Summary
Adds direct Parquet input support for WholeMemory tensors and embeddings, including the cuGraph-PyG
DistTensorandDistEmbeddingfile-loading APIs.The implementation is designed for datasets that may be several terabytes: it allocates the final WholeMemory destination first, then decodes and copies only bounded Parquet batches into each rank's local partition. It never loads or concatenates the complete source dataset in host memory.
Implementation
binary,parquet, andautofile formatsexpected_shapeoptional for file input; it is used only for validation and one-column dimensionality disambiguationlast_dim_sizefor Parquet input and requires it for raw binary input(N,)tensor by default;expected_shape=(N, 1)requests the 2-D representationdtypeexplicit and warns when Parquet column types differ before converting bounded batchesfail_on_dtype_mismatch=Trueto turn that warning into a metadata-validation error before allocationtensor_entry_partition/partition_bookvalues; otherwise WholeMemory applies its default partitioningWhy direct PyTorch and NumPy file input are not supported
PyTorch's public file-loading API does not provide a bounded, windowed read interface.
torch.load(..., mmap=True)avoids eagerly copying the complete tensor, but pages touched during a sequential scan can remain resident while the full-file mapping is open. Keeping RSS strictly bounded would therefore depend on platform-specific page-eviction calls, while older PyTorch serialization formats may not support mmap at all.That behavior is not a good fit for a loader whose primary requirement is predictable host-memory use at multi-terabyte scale. Callers should use Parquet for structured input or convert data to the native binary format for the lowest possible overhead.
.ptand.pthfiles are explicitly rejected when format detection is used.The previous
.npypath had the same issue:np.load(..., mmap_mode="c")avoided an eager copy, but pages touched while copying a rank's partition could remain resident and make peak RSS scale with that partition. Direct.npyloading has therefore also been removed. Known.pt,.pth, and.npyextensions are rejected even when callers attempt to force the binary format, preventing serialized headers from being misinterpreted as raw tensor data.Memory behavior and tests
The tests cover:
DistTensorandDistEmbedding(N,)and(N, 1)behavior.pt,.pth, and.npyinputThe scaling tests subtract only the required CPU WholeMemory destination allocation and verify that the remaining reader/conversion overhead stays within a fixed bound and does not grow materially when the dataset size increases 4x.
Local validation
21 passedfrom_fileintegration:4 passedgit diff --check: passed