Skip to content

Adding early stopping to examples and also fix staleness issue with DTDG model embeddings - #397

Merged
shenyangHuang merged 3 commits into
mainfrom
early-stop
Mar 20, 2026
Merged

Adding early stopping to examples and also fix staleness issue with DTDG model embeddings#397
shenyangHuang merged 3 commits into
mainfrom
early-stop

Conversation

@shenyangHuang

Copy link
Copy Markdown
Collaborator

Summary / Description

Added early stopping to all linkproppred, nodeproppred and graphproppred examples

Related Issues: #394

Type of Change

  • Bug fix
  • New feature
  • Breaking Change
  • Refactoring
  • Documentation update

Test Evidence

Requires running integration test to see if anything breaks

Questions / Discussion Points

For graphproppred, it is not clear what metric should use for early stopping @benjaminnNgo

@shenyangHuang shenyangHuang added this to the Beta Release 3 milestone Feb 16, 2026
@shenyangHuang shenyangHuang self-assigned this Feb 16, 2026
@shenyangHuang shenyangHuang linked an issue Feb 16, 2026 that may be closed by this pull request
@codecov

codecov Bot commented Feb 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!


test_results = eval(test_loader, test_labels, encoder, decoder, test_metrics)
log_metrics_dict(test_results, epoch=args.epochs)
val_score = val_results['BinaryAUROC']

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using Binary AUROC here as it is not clear which metric to use @benjaminnNgo

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BinaryAUROC is good

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this fails on integration tests, KeyError for "BinaryAUROC": https://github.com/tgm-team/tgm/actions/runs/22492271186/job/65157420939

Comment thread examples/graphproppred/tgcn.py

@ntgbaoo ntgbaoo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing stale embeddings looks good to me.

For early stopping, I think we are missing "early stop" as the logic added in this PR just evaluates on the test set for the best epoch and does not really stop when over patience. Not sure if we want to support that.

For ICLR experiments, I have implemented the EarlyStopping class, and I remembered seeing @Jacob-Chmura implement something similar. Do we want to add this logic to the core? Or we can have utils.py within examples and have EarlyStopping class there.


test_results = eval(test_loader, test_labels, encoder, decoder, test_metrics)
log_metrics_dict(test_results, epoch=args.epochs)
val_score = val_results['BinaryAUROC']

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BinaryAUROC is good

@shenyangHuang

Copy link
Copy Markdown
Collaborator Author

Fixing stale embeddings looks good to me.

For early stopping, I think we are missing "early stop" as the logic added in this PR just evaluates on the test set for the best epoch and does not really stop when over patience. Not sure if we want to support that.

For ICLR experiments, I have implemented the EarlyStopping class, and I remembered seeing @Jacob-Chmura implement something similar. Do we want to add this logic to the core? Or we can have utils.py within examples and have EarlyStopping class there.

I think it is a good idea to standardize it. I don't think early stopping should be in core as it doesn't relate to core TG workflow. we can discuss next week. For now, yeah this doesn't implement the full early stopping logic.

@Jacob-Chmura Jacob-Chmura left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running some more integration tests, but approving to unblock.

Comment on lines +160 to +162
z = z.detach()
h_0 = h_0.detach()
c_0 = c_0.detach()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed in eval?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe, but I think it is good practice to detach it to ensure no gradient will go into training the model from eval

z = encoder(snapshot_batch, static_node_x)
except StopIteration:
pass
z = z.detach()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, not needed?

@github-actions

Copy link
Copy Markdown

Job: test_dygformer_nodeprop_pred_tgbn-trade

Metric Value
discretize latency 0.004
materialize latency 0.002
execute_active_hooks latency 0.003
train latency 19.563
train peak_gpu_mb 524.286
train alloc_gpu_mb 519.450
eval latency 2.939
eval peak_gpu_mb 190.000
eval alloc_gpu_mb 167.660
Loss epoch 1 251.346
Validation ndcg epoch 1 0.278
Test ndcg epoch 1 0.228

Job: test_persistant_forecast_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.007
eval latency 0.244
Validation ndcg 0.860
Test ndcg 0.855

Job: test_gcn_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.004
train latency 0.309
train peak_gpu_mb 29.133
train alloc_gpu_mb 14.607
eval latency 0.068
eval peak_gpu_mb 29.108
eval alloc_gpu_mb 11.107
Loss epoch 1 112.194
Validation ndcg epoch 1 0.412
Test ndcg epoch 5 0.420
Loss epoch 2 92.109
Validation ndcg epoch 2 0.438
Loss epoch 3 89.943
Validation ndcg epoch 3 0.460
Loss epoch 4 88.273
Validation ndcg epoch 4 0.463
Loss epoch 5 87.408
Validation ndcg epoch 5 0.479

Job: test_tgcn_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.003
train latency 0.335
train peak_gpu_mb 40.831
train alloc_gpu_mb 24.871
eval latency 0.072
eval peak_gpu_mb 41.211
eval alloc_gpu_mb 21.574
Loss epoch 1 115.459
Validation ndcg epoch 1 0.363
Test ndcg epoch 5 0.353
Loss epoch 2 92.759
Validation ndcg epoch 2 0.369
Loss epoch 3 91.286
Validation ndcg epoch 3 0.361
Loss epoch 4 90.766
Validation ndcg epoch 4 0.394
Loss epoch 5 90.648
Validation ndcg epoch 5 0.374

Job: test_gclstm_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.003
train latency 0.351
train peak_gpu_mb 23.279
train alloc_gpu_mb 7.217
eval latency 0.072
eval peak_gpu_mb 22.988
eval alloc_gpu_mb 3.224
Loss epoch 1 111.865
Validation ndcg epoch 1 0.349
Test ndcg epoch 5 0.421
Loss epoch 2 89.703
Validation ndcg epoch 2 0.409
Loss epoch 3 88.076
Validation ndcg epoch 3 0.450
Loss epoch 4 85.389
Validation ndcg epoch 4 0.497
Loss epoch 5 81.936
Validation ndcg epoch 5 0.558

Job: test_tpnet_nodeprop_pred_tgbn-trade

Metric Value
discretize latency 0.003
materialize latency 0.002
execute_active_hooks latency 0.003
train latency 17.095
train peak_gpu_mb 383.986
train alloc_gpu_mb 379.795
eval latency 2.648
eval peak_gpu_mb 364.905
eval alloc_gpu_mb 343.030
Loss epoch 1 252.953
Validation ndcg epoch 1 0.221
Test ndcg epoch 1 0.188

Job: test_tgat_nodeprop_pred_recency_sampler_tgbn-trade

Metric Value
materialize latency 0.002
execute_active_hooks latency 0.000
train latency 5.064
train peak_gpu_mb 289.341
train alloc_gpu_mb 287.282
eval latency 0.582
eval peak_gpu_mb 155.127
eval alloc_gpu_mb 132.489
Loss epoch 1 242.634
Validation ndcg epoch 1 0.353
Test ndcg epoch 1 0.294

Download raw logs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memory = TGNMemory(
full_data.num_nodes,
test_dg.edge_feats_dim,
args.memory_dim,
args.time_dim,
message_module=IdentityMessage(
test_dg.edge_feats_dim, args.memory_dim, args.time_dim
),
aggregator_module=LastAggregator(),
).to(args.device)
encoder = GraphAttentionEmbedding(
in_channels=args.memory_dim,
out_channels=args.embed_dim,
msg_dim=test_dg.edge_feats_dim,
time_enc=memory.time_enc,
).to(args.device)

unrelated to this PR, but I found that we forgot to update edge_feat_dim -> edge_x_dim. Let's fix this while we are updating this file, thanks

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

@github-actions

github-actions Bot commented Mar 6, 2026

Copy link
Copy Markdown

Job: test_dygformer_nodeprop_pred_tgbn-trade

Metric Value
discretize latency 0.004
materialize latency 0.002
execute_active_hooks latency 0.003
train latency 19.115
train peak_gpu_mb 524.286
train alloc_gpu_mb 519.450
eval latency 2.938
eval peak_gpu_mb 190.000
eval alloc_gpu_mb 167.660
Loss epoch 1 251.346
Validation ndcg epoch 1 0.278
Test ndcg epoch 1 0.228

Job: test_tgat_nodeprop_pred_recency_sampler_tgbn-trade

Metric Value
materialize latency 0.002
execute_active_hooks latency 0.000
train latency 4.993
train peak_gpu_mb 289.341
train alloc_gpu_mb 287.282
eval latency 0.572
eval peak_gpu_mb 155.127
eval alloc_gpu_mb 132.489
Loss epoch 1 242.634
Validation ndcg epoch 1 0.353
Test ndcg epoch 1 0.294

Job: test_tgcn_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.003
train latency 0.251
train peak_gpu_mb 40.831
train alloc_gpu_mb 24.871
eval latency 0.072
eval peak_gpu_mb 41.211
eval alloc_gpu_mb 21.574
Loss epoch 1 115.459
Validation ndcg epoch 1 0.363
Test ndcg epoch 5 0.353
Loss epoch 2 92.759
Validation ndcg epoch 2 0.369
Loss epoch 3 91.286
Validation ndcg epoch 3 0.361
Loss epoch 4 90.766
Validation ndcg epoch 4 0.394
Loss epoch 5 90.648
Validation ndcg epoch 5 0.374

Job: test_gcn_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.003
train latency 0.273
train peak_gpu_mb 29.133
train alloc_gpu_mb 14.607
eval latency 0.064
eval peak_gpu_mb 29.108
eval alloc_gpu_mb 11.107
Loss epoch 1 112.194
Validation ndcg epoch 1 0.412
Test ndcg epoch 5 0.420
Loss epoch 2 92.109
Validation ndcg epoch 2 0.438
Loss epoch 3 89.943
Validation ndcg epoch 3 0.460
Loss epoch 4 88.273
Validation ndcg epoch 4 0.463
Loss epoch 5 87.408
Validation ndcg epoch 5 0.479

Job: test_tpnet_nodeprop_pred_tgbn-trade

Metric Value
discretize latency 0.003
materialize latency 0.002
execute_active_hooks latency 0.003
train latency 17.657
train peak_gpu_mb 383.986
train alloc_gpu_mb 379.795
eval latency 2.687
eval peak_gpu_mb 364.905
eval alloc_gpu_mb 343.030
Loss epoch 1 252.953
Validation ndcg epoch 1 0.221
Test ndcg epoch 1 0.188

Job: test_gclstm_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.003
train latency 0.253
train peak_gpu_mb 23.279
train alloc_gpu_mb 7.217
eval latency 0.070
eval peak_gpu_mb 22.988
eval alloc_gpu_mb 3.224
Loss epoch 1 111.865
Validation ndcg epoch 1 0.349
Test ndcg epoch 5 0.421
Loss epoch 2 89.703
Validation ndcg epoch 2 0.409
Loss epoch 3 88.076
Validation ndcg epoch 3 0.450
Loss epoch 4 85.389
Validation ndcg epoch 4 0.497
Loss epoch 5 81.936
Validation ndcg epoch 5 0.558

Job: test_persistant_forecast_nodeprop_pred_tgbn-trade

Metric Value
materialize latency 0.005
eval latency 0.254
Validation ndcg 0.860
Test ndcg 0.855

Download raw logs

@ntgbaoo
ntgbaoo dismissed their stale review March 20, 2026 13:19

Unblock

@shenyangHuang
shenyangHuang merged commit 0600303 into main Mar 20, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adding Early Stopping to all examples

3 participants