G RI NN DER : B REAKING THE M EMORY C APACITY WALL IN F ULL -G RAPH GNN T RAINING WITH S TORAGE O FFLOADING
arXiv:2605.11517v1 [cs.DC] 12 May 2026
Jaeyong Song 1 Seongyeon Park 1 Hongsun Jang 1 Jaewon Jung 1 Hunseong Lim 1 Junguk Hong 1 Jinho Lee 1 https://github.com/AIS-SNU/GriNNder
A BSTRACT Full-graph training of graph neural networks (GNNs) is widely used as it enables direct validation of algorithmic improvements by preserving complete neighborhood information. However, it typically requires multiple GPUs or servers, incurring substantial hardware and inter-device communication costs. While existing single-server methods reduce infrastructure requirements, they remain constrained by GPU and host memory capacity as graph sizes increase. To address this limitation, we introduce GriNNder, which is the first work to leverage storage devices to enable full-graph training even with limited memory. Because modern NVMe SSDs offer multi-terabyte capacities and bandwidths exceeding 10 GB/s, they provide an appealing option when memory resources are scarce. Yet, directly applying storage-based methods from other domains fails to address the unique access patterns and data dependencies in full-graph GNN training. GriNNder tackles these challenges by structured storage offloading (SSO), a framework that manages the GPU-host-storage hierarchy through coordinated cache, (re)gather, and bypass mechanisms. To realize the framework, we devise (i) a partition-wise caching strategy for host memory that exploits the observation on cross-partition dependencies, (ii) a regathering strategy for gradient computation that eliminates redundant storage operations, and (iii) a lightweight partitioning scheme that mitigates the memory requirements of existing graph partitioners. In experiments performed over various models and datasets, GriNNder achieves up to 9.78× speedup over state-of-the-art baselines and throughput comparable to distributed systems, enabling previously infeasible large-scale full-graph training even on a single GPU. 1
I NTRODUCTION
Graph neural networks (GNNs) have emerged as essential tools for learning from graph-structured data, targeting social networks (Sharma et al., 2024), molecular interactions (Réau et al., 2023), and computer vision (Chen et al., 2024). As graphs can capture arbitrary relationships among entities, GNNs hold broad potential across diverse domains. Among GNN training paradigms, full-graph training (Wan et al., 2022b;a; Jia et al., 2020a; Fey et al., 2021; Shi et al., 2023; Peng et al., 2022; Song et al., 2024) processes the entire graph per iteration, avoiding information loss. This provides high accuracy and theoretical guarantees, simplifying algorithmic validation. Our survey on recent GNN publications (Appendix A) reveals that many of them select full-graph training for these advantages, especially when the accuracy upper bound is unknown for new tasks or methods. However, full-graph training requires storing all node activations and gradients across all GNN layers in memory, 1
Department of Electrical and Computer Engineering, Seoul National University, Seoul, South Korea. Correspondence to: Jinho Lee <[email protected]>. Proceedings of the 9 th MLSys Conference, Bellevue, WA, USA, 2026. Copyright 2026 by the author(s).
easily exceeding modern GPU capacity. Some single-server methods (Yang et al., 2023; Wang et al., 2023a) have been proposed, but remain fundamentally limited by GPU or host memory capacity for large graphs (Appendix B). While distributing workload across multiple GPUs is possible, this introduces significant hardware cost and inter-device communication overhead, often leading to poor scalability (Peng et al., 2022; Wan et al., 2022b). These hardware-imposed limitations constrain researchers from flexibly designing and validating algorithms. Many studies in our survey (Appendix A) either co-design complicated memory-saving algorithms (e.g., sampling (Hamilton et al., 2017)) to fit data in memory (Bajaj et al., 2025), or report out-of-memory failures with large graphs rather than scaling to distributed environments. To address this, we introduce GriNNder, the first framework that breaks through GPU and host memory limitations by leveraging storage as an additional memory hierarchy tier. Modern NVMe SSDs provide TB-scale storage and exceed 10 GB/s in bandwidth, making them practical for storing large volumes of intermediate training data. However, no prior full-graph training system has effectively exploited this storage tier—not because of fundamental hardware constraints, but because of the rigidity of existing frameworks.
3. Memory-Hungry Partitioning: Full-graph training requires partitioning the graph until memory requirements fit GPU capacity. However, the standard partitioner (Karypis & Kumar, 1998; Karypis et al., 1997; LaSalle & Karypis, 2013) used in prior approaches (Yang et al., 2023; Wang et al., 2023a) often exceeds host memory limits during partitioning itself, necessitating a separate large-memory server that may harm practicality. To address these challenges, we propose GriNNder, which introduces structured storage offloading (SSO), a general framework for managing the GPU-host-storage memory hierarchy in full-graph GNN training. SSO orchestrates three coordinated mechanisms—cache, (re)gather, and bypass— to enable efficient storage-aware training. This strategy is realized through the following specialized methods: • Partition-wise graph caching: We observe that crosspartition dependencies follow a power-law distribution, similar to the degree distributions of real-world graphs. Exploiting this, we design partition-wise caching that uses host memory as an efficient cache with optimized I/O policies, minimizing inefficient storage access. • Grad-engine activation regathering: A regathering strategy for the automatic gradient computation engine. It eliminates inefficient activation snapshotting in existing offloading solutions, thereby minimizing redundant data storage and movement.
d
e
f
i
a b g h i e f c d
1st layer propagation a b for a, b
(a) Toy graph W2
W2
Backward
W1
a
a b g
a
a
a b g
a
Aggregate g h i
i
g h i
i
i
g h i
Scatter & Acc.
Forward
Gather
a b g
(b) Full-graph dependency & message passing
W1
Snapshot a b g
...
2. Data Amplification: Existing frameworks (Paszke et al., 2017; Fey & Lenssen, 2019; Wang et al., 2023a) utilize activation snapshots to enable sequential accesses. However, this becomes impractical when used with storage, substantially inflating both memory usage and I/O traffic.
c
h
...
1. Storage I/O Bottlenecks: Despite improved NVMe SSD bandwidth, storage remains far slower than host memory and suffers from inefficient I/O due to fixed page granularity and random access patterns.
b
g
...
When employing storage for full-graph GNN training, three key system-level challenges emerge:
a
...
One might expect that storage-based methods from other domains could alleviate GPU and host memory limits. However, these solutions cannot be directly applied to full-graph GNN training. LLM frameworks (Rajbhandari et al., 2021; Sheng et al., 2023) mainly offload model weights, but the weights’ memory is negligible in GNNs because parameters are shared across all vertices. Similarly, mini-batch-based GNN training systems with storage (Park et al., 2022; Waleffe et al., 2023; Liu et al., 2025; Jiang et al., 2024) leverage storage only to cache input features rather than intermediate activations and gradients. Extending them to full-graph settings (so-called micro-batch training (Yang et al., 2023)) inherits the same constraints while still suffering from GPU out-of-memory due to neighbor explosion (Appendix C).
Message Passing
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading
i
g h i
Act. Gather Scatter Accum. Gathered : 1st Layer : 2nd Layer
(c) Full-graph training procedure
Figure 1. Full-graph training procedure with a two-layer GNN.
• Switching-aware partitioning: A lightweight, memoryefficient partitioning algorithm specifically designed for host-memory-limited environments, avoiding the high memory footprint of standard graph partitioners. We implement GriNNder as PyGriNNder, enabling users to leverage existing PyTorch Geometric (Fey & Lenssen, 2019) code by simple inheritance. Notably, GriNNder does not modify the training algorithm itself, ensuring seamless migration without risk of accuracy degradation. Our experiments demonstrate that GriNNder achieves up to 9.78× speedup over the state-of-the-art and throughput comparable to distributed baselines, enabling previously infeasible large-scale full-graph training even on a single GPU.
2
BACKGROUND : F ULL -G RAPH GNN T RAINING
Full-graph GNN training (Jia et al., 2020a; Tripathy et al., 2020; Peng et al., 2022; Wan et al., 2022a;b) processes the entire graph in each training iteration without sampling, propagating information through message passing across multiple layers. Unlike subgraph training (e.g., minibatch (Hamilton et al., 2017)), it uses all edge connections, preserving complete neighborhood information. This approach simplifies algorithmic validation but requires storing intermediate activations/gradients for all |V | vertices across all |L| layers simultaneously with |H| hidden dimensions— often TBs for large graphs. Figure 1 illustrates full-graph training using a two-layer GNN on the toy graph in Figure 1a. Figure 1b shows the two-layer dependency structure derived from this topology. Starting from input features (denoted with circled vertex IDs), features are propagated via message passing to destination vertices in the intermediate layer (e.g., a , b , g , h , e → − a , b , shaded blue). The second layer applies the same process using these intermediate features to produce the final output embeddings.
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading Save Snapshot
Act. Gather
Snapshot
: Redundancy
Scatter Accum.
: 1st Layer Act/Grad
Random Gather
GPU Storage
a
a
a b g
a
g h i
a
③ i
i
(Sec. 6)
a b g a b g g h i
Storage Graph G a
i
a b g g h i
Figure 2. Naı̈ve storage extension of full-graph training.
Figure 1c illustrates the layer-by-layer training procedure. Forward Pass. To compute an output feature vector, features from source vertices in the previous layer must be aggregated (e.g., averaged). For example, vertex feature a depends on a , b , and g , including an implicit selfloop. After aggregation, the features are multiplied with the shared weight matrix (e.g., W1 ), then processed through operations such as normalization and activation to produce the layer’s output features (denoted by ). For the next layer, these output features are gathered to create inputs for aggregation following the same dependency structure (blue arrows). The gathered activations are saved as snapshots in GPU or host memory for use in the backward pass. Backward Pass. During backpropagation, the dependency flow is inverted. The gradient of vertex feature a is propagated to a , b , and g to compute their gradients. This requires loading the previously saved snapshots (red arrows), then scatter-accumulating the computed gradients to the vertices of the previous layer (green arrows). When workloads fit in GPU memory, this procedure enables fast training through massive parallelism and high memory bandwidth. However, severe capacity pressure arises: the entire intermediate data, including activations/gradients, must fit within GPU memory. A straightforward solution is distributed training (Tripathy et al., 2020; Peng et al., 2022), but this incurs substantial hardware costs and inter-device communication overhead (often 80–98%, see Appendix B). To mitigate GPU memory constraints, single-server methods (Yang et al., 2023; Wang et al., 2023a) have been recently proposed. However, they remain limited by GPU and host memory capacity and require memory-hungry partitioning operations that consume hundreds of GBs. We provide a detailed analysis of these limitations in Appendix B. Naı̈ve Storage Employment. Given full-graph training as described in Figure 1, a straightforward method would place the small weights (and gradients) on the GPU and large activations (and gradients) on storage. Figure 2 illustrates an example procedure for processing a single vertex, a . Since
For Each Partition p
Forward-Pass
Fit Yes Partition-Wise Gather Cache Manager GAl-1 GPU? p GAl-1 p (Sec. 4) No
G
...
a b g
...
i
②
W2
...
g h i
a
...
a b g
GriNNder Partitioner
Backward W2
Host
: 2nd Layer Act/Grad
Forward ①
For Each Layer l
Gathered
Partition-Wise Caching
Partitions Tp
A
l p
GPU Activation Regathering @ BW (Sec. 5)
l
Direct Offload (Bypass) Ap
Act. of l-1 A
l-1 p
Act. of l A
l p
Figure 3. Overall workflow with cache-(re)gather-bypass.
the neighbors of a ( a , b , and g ) fit within GPU memory, training can proceed. However, this approach yields sub-optimal performance for three main reasons: 1 Ensuring gathered neighbor features fit within GPU memory is challenging due to power-law degree distributions. Memory requirements per partition vary dramatically, making GPU capacity violations difficult to avoid without memory-aware partitioning. 2 Gathering feature vectors requires random reads from storage. Since storage devices operate at page granularity (e.g., 16 KiB for NVMe SSDs), random access leads to severe read amplification and bandwidth saturation. 3 While existing snapshot features in PyTorch (Paszke et al., 2017) and prior methods (Wang et al., 2023a) enable sequential access, they introduce significant redundancy, inflating write traffic. For instance, g appears redundantly in snapshots of all neighboring vertices— a , h , and i .
3
S TRUCTURED S TORAGE O FFLOADING : C ACHE -(R E )G ATHER -B YPASS
To address the limitations identified in Section 2, we propose GriNNder, the first framework enabling storage-offloaded full-graph GNN training to break the GPU and host memory wall. As naı̈ve storage employment demonstrates, efficient storage-based full-graph training requires a fundamentally different approach than simple offloading. We introduce structured storage offloading, a systematic framework for orchestrating data movement across the GPU-host-storage hierarchy, specifically designed for full-graph GNN training. The core of structured storage offloading is the cache(re)gather-bypass mechanism. The workflow is illustrated in Figure 3 (see Appendix D for the procedure). Assuming that the graph G is partitioned into small subgraphs (Tp ) (Section 6), the workflow is organized as follows: • Cache. To avoid frequent fine-grained random accesses, the vertex activations are loaded from storage and cached in the host memory at per-partition and per-layer granularity. For processing layer l, only the partitions from layer l − 1 need to be accessed from the storage. Thus, we can significantly reduce the working set, enabling efficient caching despite the limited capacity of host memory (Section 4). • (Re)gather. In the GPU, the vertices in a single destination partition of layer l are processed in a batch, which re-
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading
d
e 2 3f
(A0)
g 2 3 h 4i
a b e g h
Vertex Act.
d
(A0~A3)
e 2 3f
g 2 3 h 4i
Storage
Storage
Pt.0
c
b
h GA0
4 Gradient Scatter & Accum.
c d
g 2 3 h 4i
e 2 3f
(A0)
Vertex Act.
Pt.0
a
c
b
d
(A0~A3)
e 2 3f
g 2 3 h 4i
20k 1 8 15 22 29 36 Sorted Partitio 43 50 57 n IDs
Pt.3
a
a
b e g
b
Pt.2
xα
h
c d e
Pt.1
c d
...
Intra-Layer Reuse
f
Expansion Ratio
Partition 0
Partition 1
Time
(a) Partition dependency profile (b) Expansion & intra-layer reuse
Host Cache b
Pt.2
40k Pa rti tio ns
h A1 GA0
a
#Required Vertices from Others
b e g
a
c
b
d
e 2 3f
( A0)
g 2 3 h 4i
Storage Page #Vertices in a Page: 2
Vertex Grad.
1 Partition-Wise Caching
① Partition-Wise Caching a
b e g
5
a c e 2 g 2 h b d 3f 3 ( A1~ A0) 4i
Topologies Vertex Activations
Topologies Vertex Activations Vertex Gradients
(a) Forward pass of GriNNder.
(b) Backward pass of GriNNder.
Figure 4. GriNNder forward and backward procedures for layer 1.
quires their source vertex activations in layer l − 1. Because transferring the source vertex data in a partition granularity would be too costly, the host processor gathers and transfers the union of the source vertices of all destination vertices in the current partition (GAl−1 p ), from the cached data. Unlike existing approaches, which snapshot the gathered input activation for the backward, we opt to regather it just-in-time at the backward. This significantly reduces the redundant I/O and memory pressure on the host/storage (Section 5). • Bypass. Meanwhile, some data do not benefit from caching, such as the topology and the resulting output activation (Alp ) for the destination partition. These data bypass the host memory, and are written directly to the storage to prevent pressure on the host memory cache. Detailed Procedure. Figure 4 details the forward/backward passes (we use A0 to denote A0 for brevity). Figure 4a depicts the forward pass for partition 0 of layer 1. 1 (Cache) Layer 0 activations (A0) are loaded into the host cache at partition granularity. 2 Partitioned graph structure T0 uploads to GPU. 2 ’ (Gather) Required vertex activations GA0 are gathered in host memory and transferred to GPU. 3 GPU executes the forward pass to output A1. 4 (Bypass) Computed activations A1 are offloaded to storage via GPU Direct Storage (GDS) (NVIDIA, 2021), skipping snapshots to reduce redundancy (Section 5). Figure 4b illustrates backward for the same partition. The procedure mirrors forward in reverse with added complexity from activation gradients (∇A1, ∇GA0). 1 (Cache) Activations (A0) are cached in host memory partition-wise for frequent reuse. 2 (Bypass) Activations A1 and gradients ∇A1 load directly from storage. Backward takes A1, ∇A1, GA0 as inputs producing ∇GA0. 2 ’ (Regather) GA0 is fetched from the host cache through regathering, not snapshots (Section 5). 3 GPU computes activation gradients (∇GA0) using loaded activations/gradients. 4
Buffer e
a
f
g
b
c
a
b
h
i
e
g
a
b
h
Host
c
b
b
GA0
d
e
f
g
i
Target: Partition 0
: Out-of-Scope Vertices Buffer e
Reuse
Discard h
Storage
h
a
a
Bypass
Host Cache Act. Gather
a b e g
a
Host
Bypass
2 ②’ 2
A1
a
Storage
Bypass
Host
GPU
(Skip Snapshot)
b
Act. Regather
A1
Host
GPU
h GA0
a
∆
② ②’
④
GA0 T0 A1 A1
Pt.0
60k
∆
b
A1
GPU - Storage
∆
b e g
Backward
∆
T0
GA0
Host - GPU
3
∆
a
a
Host - Storage
∆
∆
Weight
③ Forward
∆
Intra-Device Op.
A / A Act. / Grad.
f
g
c
d
h
i
e
f c
d
Partition-Wise Upload a
b
c
d
e
f
g
h
i
Target: Partition 1
(c) Partition-wise cache management
Figure 5. Details and rationales of partition-wise graph caching. Pt.1 denotes Partition 1.
Source vertex gradients (∇GA0) update in host memory via scattered accumulation, ensuring correctness for vertices shared across partitions. Host memory serves as a write-back buffer for vertex activation gradients. 5 After processing the entire layer, gradients are offloaded to storage.
4
PARTITION -W ISE G RAPH C ACHING
Key takeaway: Similar to vertex degrees in real-world graphs, cross-partition dependencies also follow a powerlaw distribution. Exploiting this characteristic enables efficient storage I/O management through targeted caching. Structured storage offloading manages host memory cache at partition granularity, exploiting locality while avoiding fine-grained storage access patterns. The cache replacement policy operates in two modes. Under sufficient host memory capacity, the cache retains complete layers, maximizing reuse across partition iterations. When host memory cannot accommodate all layers, the policy evicts entire layers in LRU order. For extreme cases where a single layer exceeds host memory capacity (observed only in Papers dataset in Section 8.2 and IGBM with reduced cache in Section 8.3), the policy degrades gracefully to partition-wise eviction. We now present the design rationale and mechanisms underlying this hierarchical cache management strategy. Cross-partition access patterns exhibit power-law distributions analogous to vertex degree distributions in realworld graphs, emerging from inherent clustering tendencies (Leskovec et al., 2005). Figure 5a validates this on the IGBM dataset. For each partition (y-axis), we measure the required vertices from other partitions. Sorting these counts (x-axis) reveals that among 64 partitions, dependencies concentrate within approximately 10 partitions
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading
One of the key challenges for employing storage in fullgraph GNN training is data amplification, where repeated snapshots of input activations inflate memory capacity and storage I/O demands. As described in the previous sec-
Host
a b
A0
g 2 3 h 4i
a
e
g
b
f
h i
A1
Feat.
A1
e 2 3 h 4i
a b
I0’
a
a
b
b
I0
I0’
a
Agg.
Norm.
A1 e 2 3f
b
b
I0
a
a
b e g
b e g
h
Load Intermed. GA0
h
GA0
Snapshot Load
Snap. Intermed.
I0’
a
b
b
b
A1 Host
GA0 Load Features
Snapshot Store
a b
A1 e 2 3f
A0
g 2 3 h 4i
a
e
g
b
f
h i
A1
Feat.
a
A1
b
I0’
e 2 3 h 4i
a b
a
a
I0
b e g
b e g
Recompute
GA0
a
Agg.
a
Act.
b
a
Norm.
I0
h
b
Backward a
Act.
b
Norm.
a
b
a
(a) PyTorch autograd engine
Forward Agg.
b e g
b
A1
Load Features Snapshot Store
a
a
Act.
Act.
Agg.
Norm.
I0’
Store Intermed.
GA0
a
b
h
h
GA0
Snapshot Load
Snap. Intermed.
(b) HongTu’s gradient engine
I0’
3 h 4i
Host
Load Features
a b
A0
e 2 3f
g 2 3 h 4i
e
g
b
f
h i
A1
Feat.
a
a
b
b
A1
A1
a b
I0’
b e 2
A1
Snap. Intermed.
b
I0
a
a
b e g
b e g
h
a
Feat.
a
Agg.
a
Act.
b
A1
a b e 2
a
Norm.
I0
h
GA0
b
Storage
b
a
Act.
a
Norm.
Agg.
b e g
Backward
Forward
a
∆
Key takeaway: PyTorch’s autograd engine requires redundant snapshot storage, causing α-fold1 data amplification. Our grad-engine activation regathering, a regatheringbased gradient engine for just-in-time activation reconstruction, eliminates snapshots and reduces storage I/O.
I0
h
b
a
3 h 4i
Recomp. GA0
∆
G RAD -E NGINE ACTIVATION R EGATHERING
b
Backward a
∆
5
a
∆
Partition-Wise Cache Management: GriNNder uses partitions as the load/evict granularity for host memory cache. Alternatively, vertex granularity would require reading single vertex features (64–1,024B) on cache misses. Since storage devices access data at page granularity (e.g., 16KiB), this incurs substantial unnecessary I/O. Partition-wise management reduces this overhead as partition sizes are typically a few GBs. For instance, processing partition 0 (vertices a, b) with dependencies to a, b, e, g, h loads three partitions (0, 2, 3) to host memory (Figure 5c). For partition 1 with dependencies to c, d, e, f spanning partitions 1 and 2, we reuse cached partition 2 and only load partition 1, evicting unused partition 0. This reuses vertex features without fine-grained random accesses. During this procedure, we keep a small buffer to send each partition’s input activations from the host to the GPU. In the worst case, partition-wise management incurs overhead when dependencies are uniformly distributed across many partitions. However, as shown in Figure 5a, the dependencies within a partition are concentrated in a few partitions, enabling stable caching performance. For the detailed comparison between the partition-wise and vertexwise management, see Appendix F. We further minimize latency by overlapping processing with cache management and maximizing sequential GPU access (Appendix G).
b e g
∆
Layer-Wise Partition Caching: Within a layer, partitions share activations and gradients due to cross-partition edges. In Figure 5b, vertex e’s activation is used in both partitions 0 and 1. With average expansion ratio α (#required/#target), activations are reused α − 1 times within that layer, causing redundant storage accesses. To mitigate this inefficiency, we introduce intra-layer reuse, caching frequently reused partitions in host memory. Data with minimal intra-layer reuse (graph topology, output activations) are placed in storage and bypass host memory using GPUDirect Storage (NVIDIA, 2021) (GDS), reducing I/O traffic and cache conflicts. Note that this design can be used in general even when GDS is unavailable (see Appendix S).
Forward
a
∆
(additional datasets in Appendix E). We exploit this skewed distribution through two mechanisms.
h
GA0
Load Features
Regather (c) Grad-engine activation regathering (Ours)
Gather
Figure 6. Advantage of (c) grad-engine activation regathering compared to (a) PyTorch autograd and (b) HongTu.
tion, GriNNder partitions the graph and caches graph features/gradients in the host memory at partition granularity. However, existing autograd engines (Paszke et al., 2017; Fey & Lenssen, 2019) such as torch.autograd from PyTorch, even with generic activation checkpointing (Chen et al., 2016), are not designed with such optimizations and require substantial host memory when employing offloading, as illustrated in Figure 6a. The vanilla autograd engine stores activation snapshots (‘Snap.’) and intermediate snapshots of all operations (‘Intermed.’), such as normalization (I0) and activation function (I0′ ). While this design is reasonable for vision or language models with bounded activation sizes, it incurs significant memory overhead for GNNs, where activation (snapshot) sizes scale with graph size and the number of partitions with the magnitude of α. The amplification problem reveals three core challenges. First, GNN propagation requires graph-topology-aware reconstruction rather than generic recomputation of tensor operations. Second, partition-wise caching necessitates coordinated optimization across the GPU-host-storage memory hierarchy. Third, the α-fold snapshot amplification (where α ≈ 8 for large graphs) incurs a huge memory footprint, as all partition snapshots are required during backpropagation. Prior techniques address related but distinct problems. Generic activation checkpointing (Chen et al., 2016) trades computation for memory but cannot account for graph topology or partition granularity. HongTu (Wang et al., 2023a) recomputes intermediate activations but still requires storing 1
While α, the average expansion ratio of partitions (#required/#target), was used to express the reusability in Section 4, it becomes a critical amplification factor here.
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading
α-fold amplified snapshots, which will be discussed in the next paragraph. Ginex (Park et al., 2022) optimizes cache management for mini-batch training but does not address full-graph training’s snapshot amplification. HongTu (Wang et al., 2023a) (Figure 6b) mitigates PyTorch autograd’s issue of snapshotting intermediates (e.g., I0 and I0′ ) by recomputing intermediate activations on demand. It employs a gradient engine to snapshot the gathered activations to reduce latency (by enabling sequential access to snapshots), but at the cost of increased snapshots and redundant vertex data across partitions. As a result, each vertex may be stored up to α times, which adversely impacts memory consumption and bandwidth requirements, particularly for large datasets. This is because it assumes abundant host memory and does not consider the use of storage, which has much lower bandwidth than host memory. To address these limitations, we introduce grad-engine activation regathering, illustrated in Figure 6c, which eliminates snapshot redundancy through three optimizations. First, we observe that the activation snapshot GA0 is essentially a reorganization of activations A0 according to graph topology. Rather than pre-storing these reorganized snapshots, we regather them on-demand during backpropagation from the original activations A0 by applying the gather operation. While this introduces an additional regather operation at the host, it eliminates snapshot storage (proportional to α) and the associated I/O overhead. Critically, since storing all snapshots would overflow typical host memory capacity, pre-storing snapshots mandates additional storage I/O, which incurs far greater overhead than our regathering approach. Second, intermediate values are removed from the host memory and recomputed just in time from the regathered GA0. In the figure, I0 is recomputed by aggregation using the topology, and I0′ is obtained by further applying normalization. This shares the same principle as existing recomputation techniques (Wang et al., 2023a; Chen et al., 2016), but is merged with the regathering mechanism. Finally, to further reduce host memory pressure, the output feature A1 is bypassed and written directly to storage. The combination of these optimizations enables grad-engine activation regathering to operate with minimal host memory footprint while substantially reducing storage I/O volume. It is also worth mentioning HongTu’s additional optimization, which is specific to GCN-like models. On top of the default HongTu engine depicted in Figure 6b, the optimization stores a snapshot of the aggregated intermediate activations (I0) instead of gathered activations (GA0) to reduce host-GPU traffic from αD to D. This is only possible because ∇GA0 can be directly computed from I0 in GCN. Therefore, this is infeasible for GAT-like models that apply additional attention operations during aggregation. Moreover, this additional method still requires D × L of
additional host memory (D = |V ||H|). In host-memoryconstrained settings, this can easily cause OOM, thereby converting host-GPU traffic into slower storage traffic. We can analyze the advantage of grad-engine activation regathering compared to this additional optimization as follows. In the forward pass, HongTu is slower than GriNNder because it additionally snapshots D activations, whereas grad-engine activation regathering eliminates snapshotting by regathering in the backward pass. In the backward pass, assuming HongTu’s D × L additional memory usage forces host-GPU traffic to spill into slow OS swap storage traffic, HongTu loads 2D activations and D gradients from storage, while offloading αD gradients to storage. On the other hand, GriNNder loads (α+1)D activations and D gradients from host memory, offloading αD gradients to host memory. Omitting computation, which is often negligible compared to I/O in resource-limited environments, and denoting hostGPU bandwidth as Bhost (typically x16 lanes) and SSD bandwidth as BSSD (typically x4 lanes), GriNNder is faster in the backward pass if: (2D + D + αD)/BSSD > [(α + 1)D + D + αD]/Bhost This simplifies to Bhost /BSSD > 2(α+1)/(α+3) ≈ 1.2− 1.6 for practical α = 2 − 8. Since physical lane differences typically yield Bhost /BSSD ≥ 2−4, grad-engine activation regathering is usually preferable. HongTu’s intermediate snapshotting is only effective when host memory is abundant or when graphs are small (i.e., when the host memory can accommodate the additional D × L). I/O Volume and Memory Footprint. Let D = |V ||H|. During the forward pass of a layer, the baseline autograd engine consumes (2α + 3)D traffic between the GPU and the host, for the gathered input activations (αD), snapshots (αD), intermediate values (2D), and outputs (D). Since the baseline easily exceeds the host memory limit, it mandates using OS swap memory with storage, and most of that traffic becomes the IO between the GPU/host and the storage. GriNNder only consumes αD between the GPU and the host, D between the GPU and the storage, and D between the host and the storage while caching (when only cold misses exist). In other words, while the baseline suffers from huge and slow storage traffic proportional to α, grad-engine activation regathering only requires a 2D amount of storage traffic. In terms of the memory footprint during the forward, the baseline stores snapshots (αD), activations (D), and intermediate values (2D) per layer. On the other hand, grad-engine activation regathering only occupies D space in the host memory, and D in the storage for the outputs without redundancy. In the worst case, where the baseline utilizes OS swap memory with storage, this represents a 2α+3 ≈ 8.5× reduction in storage I/O for typical α ≈ 8. 2 For more in-depth analyses (with another baseline (Wang et al., 2023a)), see Appendix H.
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading
S WITCHING -AWARE PARTITIONING
Key takeaway: Existing partitioning algorithms (e.g., METIS-based) often incur a significant memory footprint, harming the practicality of iterative partitioning workflows in full-graph GNN training environments. Graph partitioning is a critical enabler that allows GriNNder to efficiently utilize GPU memory, manage caches with minimal storage bandwidth, and minimize the traffic between host and GPU by reducing the expansion ratio (α). Although existing partitioners used in GNN domains produce nearoptimal partitions, they often exceed single-server memory limits (Figure 7a, measured with MT-METIS (LaSalle & Karypis, 2013)) for large datasets such as Papers (Hu et al., 2020). Crucially, partitioning must be performed iteratively to find an adequate #partitions that fit within GPU memory constraints—a process that becomes prohibitively expensive when each iteration requires external servers with sufficient host memory. This could harm the practicality of full-graph GNN training workflows, clearly demonstrating the need for a lightweight partitioner. Inspired by streaming partitioning approaches for distributed cloud systems (Spinner (Martella et al., 2017)), we devise a lightweight switching-aware partitioning with low memory consumption. The key is to minimize the use of auxiliary data structures, whose size often largely surpasses that of the graph itself. From an arbitrary initial partition, we iteratively refine the partition assignments to reduce the number of dependent partitions until convergence. Detailed procedures and design insights are provided in Appendix I. Algorithm Overview. Figure 7 outlines switching-aware partitioning’s procedure and implementation, with exact preference scores and objective functions omitted for clarity. At a high level, the algorithm attempts to move vertices to the partition with the most neighbors to reduce the number of dependent partitions while keeping partition sizes similar. Figure 7b illustrates an example intermediate state during partitioning. Following the CSR format, our data structure comprises source pointers (SrcPtr) and destination indices (DstIdx). We manage an additional array (Dst’s Partition) and fill this array with the partition ID of each destination index in DstIdx. For example in Figure 7b, vertex 0 has neighbors {1, 2, 5, 7, 4, 3}, and we fill Dst’s Partition with their partition IDs: {2, 2, 2, 0, 1, 1}. In this state, vertex 0 prefers partition 2 (denoted as ‘1st Pref.’ in Figure 7c) because most of its neighbors reside in partition 2. We compute such preferences for each source vertex in parallel using source-level parallelism without additional memory usage, as illustrated in Figure 7c. After computing preferences, we relocate each source vertex to its preferred partition (label propagation). For example, vertex 0 moves to partition 2, as depicted in Figure 7d. Since
1000 800 600 400 200 0
Mem. Req. (GB)
6
Host Limit Products IGBM
Papers
(a) METIS mem. requirement. Pt.0 Thread
0 1 2 0 1 2
VertexId 0
3
Partition 0
1
SrcPtr
10
DstIdx
7
0
1
3 0 2
Pt.1
3
6
1
3
SrcPtr
0
10
18
DstIdx
1 2 5 7 4 3
8 10 9
6
Dst’s 2 2 2 0 1 1 Partition
2 1 2
3
3
7
0
1
2
4 5
Pt.2
(b) Intermediate partition and data structure. Pt.1
4 5
Pt.0
VertexId 0 Partition 0
VertexId 0
3
0
1
2
2
0
10
Partition Pt.2
Source-Level Parallelism
1 2 5 7 4 3
8 10 9
Dst’s 2 2 2 0 1 1 Partition 1st Pref.
2 1 2
SrcPtr
Pt.0
0
Destination-Level Parallelism
Thread
0 1 2 0 1 2
1 2 0
DstIdx
1 2 5 7 4 3
8 10 9
Dst’s Partition
2 2 2 0 1 1 1 0
2 1 2
2 2 2 0 1 3 1 2 0
0 2 1
(c) Thread-wise preference calculation.
Pt.2
0
(d) Thread-wise partition update.
Figure 7. Motivation and a high-level overview of switching-aware partitioning.
vertex 0 now belongs to partition 2, all entries in Dst’s Partition pointing to vertex 0 must be updated to reflect this change. We perform this update efficiently using destination-level parallelism (Figure 7d), where threads independently update entries corresponding to different destination vertices. By iteratively updating preferred partitions following this procedure until convergence, we minimize the average expansion ratio (α) across partitions. For the initial state, we randomly assign vertices to partitions and observe stable behavior across runs, with partition quality largely insensitive to this random initialization. In other words, while starting from a good initial state could reduce the number of iterations required for convergence, the final converged state is empirically independent of the initial state. Additionally, the partition sizes across partitions are balanced via an explicit size-based penalty in the partition scoring function as follows (see Appendix I for details). Given state Si and partition Pj : P enalty(i,j) = |Pj |/(αbalance × |V |/p), (0 ≤ j < p) where |Pj | is the current partition size, |V | is the total number of vertices, p is the number of partitions, and αbalance controls balance strictness (default αbalance = 1.1, allowing partitions to be ∼10% larger than the equal size). This discourages the growth of oversized partitions and maintains balance during partitioning. Memory Usage and Convergence. Switching-aware partitioning uses only a CSR representation (SrcPtr, DstIdx) and a Dst’s Partition array to record each neighbor’s current partition. This totals O(2|V | + 2|E|) space com PS pared to METIS’ O(2|V | + |E| + i=1 |Ei | + |Vi | ) requirement (Kaur & Gupta, 2021), where S is the number of partitioning stages in METIS. In practice, this achieves 7.10–24.37× memory reduction on large graphs (Table 4).
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading User Level
wrapped by TensorNVMe (tensornvme) for host-storage transfers, and Kvikio (kvikio) for GPU-storage transfers via GPUDirect Storage (GDS) (NVIDIA, 2021).
User’s Custom Code GriNNder Base
GriNNder Dataloader
PyG Model
PyG Dataloader
Middleware
GriNNder Offloading Engine
AIO Engine (e.g. Tensor NVMe)
Stoarge Offloader S
GDS Engine (e.g. KvikIO)
Cache Handler
GriNNder Partitioner
Pytorch Geometric Kernels Hardware
W
Model
Host A
Activation
∆
FW/BW
Gradient
Storage A
Activation
Topology
∆
GPU
Gradient
Dataloader
Figure 8. Framework structure of GriNNder.
Switching-aware partitioning converges in 30–50 iterations, consuming only 0.07%/0.02%/0.39% of total training time on Products/IGBM/Papers datasets (Appendix O)—a negligible overhead for practical workflows. Despite its lightweight design, switching-aware partitioning achieves competitive partitioning quality compared to state-of-the-art lightweight partitioners (Section 8.5). Integration with Training. We use METIS when host memory is sufficient, as it produces high-quality partitions. However, when memory constraints mandate partitioning on external infrastructure, switching-aware partitioning offers a fast and memory-efficient alternative with competitive partition quality. For detailed comparisons with Spinner (Martella et al., 2017) and state-of-the-art out-of-core partitioner (2PS-L (Mayer et al., 2022)), see Section 8.5.
7
G RI NN DER API AND I MPLEMENTATION
We implement GriNNder as an extension to PyTorch’s torch.nn.Module (Paszke et al., 2017), providing a minimal-modification API for existing PyG (Fey & Lenssen, 2019) applications. Users inherit the GriNNderGNN base class and implement a single layer forward method to enable layer-wise execution required for partition-based full-graph training. This design decouples GNN model logic from the underlying offloading infrastructure, requiring typically several lines of code changes from standard PyG implementations (see Appendix K for API details). Figure 8 illustrates the framework architecture. The userlevel provides the base GNN module and a custom dataloader that manages partition-aware data serving, maintains cross-partition dependency metadata, and coordinates I/O scheduling. The middleware integrates partition-wise caching (Section 4), gradient regathering (Section 5), and lightweight partitioning (Section 6). It implements the offloading engine, which orchestrates data movement through two specialized I/O engines: the Linux AIO interface
The engine tracks each activation’s location and coordinates I/O operations across three hardware tiers. Since offloaded training is typically I/O-bound, we implement aggressive I/O overlap to hide transfer latency. Leveraging bidirectional PCIe bandwidth, the offloading engine pipelines the write of the previous partition’s activations with the prefetch of the current partition’s required activations. We implement the dataloader and partitioner in C++ for high performance and expose them to Python through pybind11 (pybind11).
8
E VALUATION
8.1
Experimental Settings and Baselines
Hardware: We run main experiments on a single GPU workstation with an AMD Ryzen9 7950X 3D CPU (16C 32T), 128GB DDR5-5600 RAM, one RTX A5000 (24GB) GPU, a PCIe 5.0 NVMe SSD (4TB), and a total 4TB swap space for swap-based experiments. We chose a single GPU setup to demonstrate how GriNNder breaks through the host/GPU memory limitations. For the multi-GPU extension, we utilized a multi-GPU server with four RTX4090 GPUs, 2×Intel Xeon Gold 6442Y, 512GB DDR5 DRAM, and 2TB PCIe5.0 NVMe SSD. For distributed baselines, we use a 4-server cluster; each node has four RTX A6000 GPUs interconnected by NVLink (NVIDIA, 2023b) and Infiniband SDR (NVIDIA, 2023a). For IGBM/Papers, we needed all 16 GPUs to fit the data in the GPU memory. For Products, using fewer GPUs could yield better performance, but we used all GPUs to maintain consistency among datasets. Models/Datasets: We use 3-/5-layer GCN (Kipf & Welling, 2016) with a hidden dimension of 256. We also test GAT (Veličković et al., 2018) and GraphSAGE (Hamilton et al., 2017). Datasets range from medium to large scale: Products (Hu et al., 2020), IGBM (Khatua et al., 2023), and Papers (Hu et al., 2020). We also utilized Kronecker graphs (Leskovec et al., 2010) (average degree=10) with random initial features of dimension 128 and #classes of ten. Baselines: (Training) We compare GriNNder (GRD) against various single-server/distributed methods (detailed in Appendix B): 1 Micro-batch training (Betty (Yang et al., 2023)), 2 Micro-batch training with storage extension (Ginex (Park et al., 2022)), 3 Host memory offloaded training (HongTu (Wang et al., 2023a)) with OS swap memory, 4 Distributed full-graph training (CAGNET (Tripathy et al., 2020)), 5 Distributed full-graph training with communication skipping (Sancus (Peng et al., 2022)), 6 Naı̈ve storage extension of full-graph training (ROC (Jia et al., 2020a)). We showed 6 only in Appendix X due to its
GriNNder: Breaking the Memory Capacity Wall in Full-Graph GNN Training with Storage Offloading
100M
PAPERS
|L| = 3 Limited
B ETTY G INEX H ONG T U GRD
0.61 9.00 0.17 0.12
28.71
GPU OOM
Dist.
C AGNET S ANCUS
0.21 0.19
1.41 ∗ 0.77
B ETTY G INEX H ONG T U GRD
1.05 15.10 0.32 0.23
GPU OOM GPU OOM
C AGNET S ANCUS
GPU OOM
17.72
6.46 0.93
Swap OOM
14.90 1.52
∗
10.01
GPU OOM
12.03 ∗
0.38 2.10 GPU OOM ∗ ∗ 0.36 1.41 GPU OOM S ANCUS: Non-exact full-graph (with staleness)
4.2M
8.4M
16.8M
33.6M
H ONG T U GRD
0.43 0.29
0.83 0.59
7.25 1.93
36.31 3.73
H ONG T U GRD
0.83 0.57
1.99 1.14
19.15 3.71
96.99 7.76
|L|=5 |L|=3
|H|=512
|H|=1024
0.75 $ S IZE
0.5 $ S IZE
0.25 $ S IZE
H ONG T U GRD-G GRD-GC
12.53 1.20 1.41
18.67 1.51 1.91
39.32 20.68 3.98
H ONG T U GRD-G GRD-GC
25.07 10.26 2.54
31.81 12.50 3.37
93.42 42.14 13.65
GPU OOM GPU OOM Swap OOM
# nodes
much slower performance. In the appendix, we also tested two storage-based mini-batch training ( 7 DiskGNN (Liu et al., 2025), 8 GNNDrive (Jiang et al., 2024)) with microbatch extension2 (Appendix C). For out-of-memory issues in distributed baselines, we add host-memory checkpointing (∗ ) to enable execution. Since GriNNder does not change the training algorithm itself, GriNNder achieves equal final accuracy with all the baselines (see Appendix W) except 5 , which is non-exact due to its staleness. All baselines use the state-of-the-art partitioner MT-METIS (LaSalle & Karypis, 2013). For fairness, if MT-METIS exceeds our setting’s memory, we assume it was preprocessed elsewhere following standard practice, except for partitioning experiments. (Partitioning) We also compared switching-aware partitioning with other alternative lightweight partitioners. We chose Spinner (Martella et al., 2017) and 2PS-L (Mayer et al., 2022), a state-of-the-art out-of-core partitioner. Large Graph Training Results
Table 1 presents per-epoch training time for GriNNder (GRD) compared to five baselines—Betty, Ginex, HongTu, CAGNET, and Sancus—using 3-/5-layer GCNs (hidden dimension 256) on Products, IGBM, and Papers. 2
|H|=384
Method
9.07 ∗
Table 2. Training time (min)/epoch sensitivity for graph sizes with synthetic graphs. For results with ablation, see Appendix M.
8.2
# hiddens
|L|=3
10M
IGBM
Dist.
2.4M
P RODUCTS
|L| = 5 Limited
# nodes Method
Table 3. Sensitivity on effective cache size with ablation (training time (min)/epoch).
|L|=5
Table 1. Results of training time (min)/epoch.
Since these systems are not designed for full-graph training workflows, extensions may deviate from their original performance characteristics.
Micro-Batch (Betty, Ginex): Despite Betty’s memory-only design (no storage), GRD achieves up to 30.98× faster training, largely due to Betty’s redundant computation from the message flow graph’s neighbor explosion. Ginex uses storage to extract message flow graphs, yet still suffers from the same issue, which GRD improves by up to 77.92×. Products (Medium): Since HongTu can fit Products entirely in host memory, one might expect it to outperform storage-based GRD. In practice, HongTu’s redundant snapshots slow it down, allowing GRD to beat it by 1.44/1.40× on 3-/5-layer GCNs. IGBM (Large): Micro-batch methods suffer from GPU OOM on deeper models—Betty/Ginex often cannot handle the neighbor explosion. HongTu must manage large volumes of data in host memory, drastically increasing overhead. In contrast, GRD is 6.97/9.78× faster than HongTu with caching and non-redundancy. Even against multi-GPU CAGNET, GRD achieves 1.52/1.38× speedup because the distributed baselines are bottlenecked by inter-server communication over a slow 10Gbps interconnect. Papers (100M): This highlights GRD’s scalability on larger datasets. Betty and Ginex often fail on deeper models with OOM from neighbor explosion, and HongTu fails from activation snapshots. GRD avoids these with efficient caching and no redundant snapshots. Ginex can run the 3-layer model but is 1.95× slower than GRD. Notably, GRD is faster than CAGNET (1.10×) despite using a single GPU. Synthetic Graphs: In Table 2, we tested various-sized Kronecker graphs to validate scalability, where GriNNder provides stable speedup over HongTu (1.41–12.50×). 8.3
Ablation by Decreasing Effective Cache Size and Cache Hit Rate
Table 3 analyzes GriNNder ’s sensitivity to effective cache size by varying the hidden dimension on IGBM. We ablated GriNNder: HongTu, HongTu + grad-engine activation regathering (GRD-G), and GRD-G + partition-wise graph caching (GRD-GC). GriNNder outperforms HongTu by 6.84–12.34×. When host memory can cache most data (in 3