Ephris / Graph Foundation Model

Put your connections to work

Classify a node using its own data and the network around it. Bring a new graph, without a new training run.
Ephris
Pretrained model

Which equipment needs attention?

Connected equipment

P-08 readings: 76 °C · 4.8 mm/s vibration

Predicted conditionBearing wearPump P-08
Your next step

Schedule an inspection of this pump.

Illustrative data and predictions

Change the graph, keep the model

New topology, new attributes, new labels. Ephris uses the graph you provide as context, with sparse message passing at its core.
Same checkpointNew topology · attributes · labels

Bring a different network

The same pretrained checkpoint takes a new graph as context. Connections, measurements and known labels define the task.

Dense attentionSparse messages

Work with the connections you have

Sparse message passing scales with node-feature entries and edges, instead of dense attention across all node pairs.

Different graphs, measured together

Evaluated across 51 node-classification datasets, with both high- and low-label splits. Compare against tuned GNNs and prior graph in-context learners.
51
Node-classification datasets
1st
Across four aggregate metrics

Both evaluated label regimes

Selected models · Elo axis starts at 1,000

Benchmark details

Train/validation/test: 50/25/25. Five splits per setting across 51 datasets. GNNs select from 200 configurations using validation data; Ephris uses training labels as context. Selected comparison models are shown. The paper contains every model and uncertainty estimates; aggregate rank does not imply a win on every dataset.

Original paper · Complete results

Try it on your own data

Hold out some node labels and predict them from the graph and the remaining labels.
Pass features, edges and context labels directly to predict. Select query nodes from the returned labels.
This four-node example supplies features, edges and context labels. Query labels stay out of the inputs.
Open WeightPython
# pip install ephris
import torch
from ephris import EphrisClassifier

x = torch.tensor([[0.1, 0.2], [0.8, 0.9], [0.2, 0.1], [0.9, 0.8]])
edge_index = torch.tensor([[0, 1, 2, 3], [2, 3, 0, 1]])
context_indices = torch.tensor([0, 1])
query_indices = torch.tensor([2, 3])
context_labels = torch.tensor([0, 1])

model = EphrisClassifier(random_state=42, device="auto")
labels = model.predict(
    x, edge_index,
    context_indices=context_indices, context_labels=context_labels,
)
print(labels[query_indices])