Skip to main content

Tubeulator Models

Graph neural network models of the London Underground trained on TfL timetable data.

Two models share a GATv2 encoder over the station topology graph and differ in their decoder head:

  • nexthop policy — given a current station and destination, predicts the optimal next station to visit. Greedy rollout achieves 1.09× Dijkstra ratio with 100% success across all 239,610 origin–destination pairs.
  • nexthop value — predicts shortest travel time in minutes between any pair of stations. MAE of ~0.5 min vs. Floyd–Warshall ground truth.

Installation

pip install tubeulator-models[inference]

For the CLI:

pip install tubeulator-models[cli]

Usage

Python API

from tubeulator_models import TubeRouter

router = TubeRouter.from_pretrained("permutans/tube-nexthop-policy")
route = router.route("West Ham", "Shoreditch")
print(route)
# West Ham
#   → [district] Bromley-by-Bow (2.0m)
#   ...
# ✓ 8 hops · 2 lines · 1 transfer · 16.0 min

Route through waypoints:

route = router.route("Camden Town", "Canary Wharf", via=["King's Cross"])

The Route object has .steps, .total_minutes, .lines_used, .n_transfers, .success, and a .to_dict() method.

CLI

tm-infer policy --model permutans/tube-nexthop-policy -o "West Ham" -d Shoreditch
tm-infer policy --model permutans/tube-nexthop-policy -o "Camden Town" -d "Canary Wharf" -v "King's Cross"
tm-infer value  --model permutans/tube-nexthop-value  -o "West Ham" -d Shoreditch

Training from source

Clone the repo and use the justfile recipes:

just all        # fetch data + build graph + train

Or step by step:

just fetch      # pull timetables from TfL API → GTFS zip
just graph      # GTFS → GeoParquet → PyG graph objects
just train nexthop full
just train nexthop full --value-primary --batch-size 1024 --epochs 200

All hyperparameters live in defaults.toml. CLI flags override the TOML but never replace it:

tm-train --model nexthop --profile full --lr 5e-5

Profiles control the training regime:

Profile Epochs Batch size LR Notes
dev 20 512 5e-4 Fast iteration
full 200 256 1e-4 Production, d_model=512, 16-layer encoder

Data pipeline

Step CLI Recipe Output
Fetch timetables tm-build-gtfs just fetch data/tfl_station_data_gtfs.zip
Build graph tm-gtfs2pyg just graph data/graph/, data/pyg/
Plot network tm-plot just plot data/graph/network.png
Train tm-train just train checkpoints/
Export tm-export just upload models/ → HuggingFace

Staged graph conversion is also available:

uv run --group prep    tm-gtfs2graph   # GTFS → GeoParquet
uv run --group pyg     tm-graph2pyg    # GeoParquet → PyG .pt

Configuration

defaults.toml is the single source of truth for all tuneable values. The merge order is:

[base] → [model.<type>] → [profiles.<name>] → [profiles.<name>.model.<type>] → CLI overrides

Development

just lint       # ruff check
just clean      # remove data/ and checkpoints/

Links

Metadata

Release files for tubeulator-models 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tubeulator-models 0.1.5
File Size Uploaded
tubeulator_models-0.1.5.tar.gz 60.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tubeulator-models 0.1.5
File Interpreter ABI Platform
tubeulator_models-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 134.0 kB

Release files / tubeulator_models-0.1.5.tar.gz

Download URL tubeulator_models-0.1.5.tar.gz
Size 60.4 kB
Tags Source
SHA-256 checksum
How to use checksums
4ef62b35fbaa5d9fa2728261221ab6a3f0c14526eac9685b1aa80a749ae86492
BLAKE2b-256 checksum
How to use checksums
3c724f54044af51814382553d8871b1a478a97de66e944be4ba1ac53de1c25f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22","id":"wilma","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / tubeulator_models-0.1.5-py3-none-any.whl

Download URL tubeulator_models-0.1.5-py3-none-any.whl
Size 73.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ace246816098540a0761a8dda19e37b7f525c1fdadd5636295eb4a9cceef377a
BLAKE2b-256 checksum
How to use checksums
10baec713e796b297688fa0eae7ba632be77e8b390f46c0cca2dfea5c19b7e50
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22","id":"wilma","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page