superpoint-p150

SuperPoint (Magic Leap's self-supervised interest-point detector and descriptor) running entirely on one Tenstorrent Blackhole p150a via tt-nn: image in, keypoints with scores and 256-d descriptors out. Weights: magic-leap-community/superpoint · Paper: arXiv:1712.07629 · Upstream code: magicleap/SuperPointPretrainedNetwork · Port: changh95/tt-superpoint

Runs on p150 (mesh P150).

Packaged and published with tt-model-manager 0.1.0 (manifest schema 5.1).

Quickstart

tt-model pull  changh95/superpoint-p150 --with-weights
tt-model serve changh95/superpoint-p150
  • Weights magic-leap-community/superpoint at 734450e9ffe2 go to your HF cache; the image does not contain them.
  • Serves on port 20000 (or the next free port); ready when the log says Application startup complete.

Run with tt-cli

tt serve changh95/superpoint-p150
printf '{"image":"%s"}' "$(base64 -w0 code/sample_data/house_in_field_1080p.jpg)" > req.json
curl -s localhost:20000/predict -H 'Content-Type: application/json' -d @req.json
tt model stop changh95/superpoint-p150
  • POST /predict: image (base64 PNG/JPEG); optional max_keypoints (1024, -1 = all above threshold), keypoint_threshold (0.005), nms_radius (4), return_descriptors (true).
  • GET /health, GET /info.

Response

{"num_keypoints": 539,
 "keypoints": [[610.0, 703.125], [1042.5, 446.25], [1122.5, 442.5]],
 "scores": [0.609375, 0.589844, 0.582031],
 "original_size": {"height": 900, "width": 1600}, "image_size": {"height": 480, "width": 640}, "scale": {"x": 2.5, "y": 1.875},
 "descriptors": {"format": "npz", "key": "descriptors", "dtype": "float16", "shape": [539, 256], "data": "..."},
 "serving_path": {"traced": true, "device_nms": true},
 "timing_ms": {"preprocess": 17.7, "device_forward": 5.3, "postprocess": 1.3, "total": 24.3}}
  • keypoints are [x, y] in original image pixels, sorted by descending scores; the network frame is 480×640 and scale = original / network.
  • descriptors.data is a base64 NPZ: np.load(io.BytesIO(base64.b64decode(data)))["descriptors"] gives (N, 256) float16 rows, L2-normalised, in keypoint order.

Demo

Top-500 keypoints on the 480×640 network frame of code/sample_data/house_in_field_1080p.jpg (media/sample.png, natural image)

Accuracy and speed

Metric Value
Pre-NMS score map · descriptor map PCC vs fp32 torch reference 0.9971 · 0.9991
Keypoint set vs reference (natural image, top-500, 2 px) recall 98.20% · precision 99.40% · F1 98.80%
Inference, served over HTTP (warm, batch 1, 480×640, 1600×900 JPEG in; median of 50 requests) 5.3 ms device (trace + device NMS) · 1.3 ms host post-processing · 18 ms JPEG decode/resize · 24.7 ms end-to-end (~40 FPS)
Same, legacy path (TT_FUSED=0: untraced, host NMS) 12.4 ms device · 26.5 ms host NMS · 56.8 ms end-to-end (~18 FPS)
Same forward on an RTX 5090 (same host, port's torch reference, eager PyTorch, batch 1, incl. H2D/D2H; bf16 / fp16 autocast) 1.6 / 1.5 ms → GPU 3.2–3.4× faster than the p150a's 5.1 ms device forward (incl. device NMS); fp32-strict 2.9 ms (1.7×); best torch.compile 1.2 ms. End-to-end both sides are bound by the ~18 ms JPEG decode/resize (GPU 21.5 vs p150a 23.9 ms)

Caveats

  • Every image is resized to 480×640 (bilinear, /255, channel 0); one image per request, batch 1, requests serialised on the chip.
  • This server runs the whole device graph as one metal trace per request with a standard-op device NMS (radius 4; bit-identical to the host single-pass NMS) and an rms_norm descriptor L2-norm (bf16-rounding-level vs the legacy chain; PCC 0.9991 either way). bf16 + HiFi2 + fp32 accumulate throughout (bfloat8/LoFi drop score PCC to ~0.91). No custom kernel: the port README's sp_eq_mul_mask path is not built into this image.
  • nms_radius other than 4 falls back to the host NMS on the traced scores (same keypoints, ~25 ms slower); TT_FUSED=0 in the environment restores the untraced legacy path (validated 2026-09-12).
  • Weights are research-only: the Magic Leap SuperPoint licence allows academic or non-profit organisation NONCOMMERCIAL research use.
  • Not an OpenAI-compatible API; GET /v1/models is a stub so the tt-model ready card does not 404.
  • Validated on tt-metal v0.78.0-dev20260820 (main 8b98410e730), single p150a only; numbers above measured 2026-09-13 through this container image (DEVICE_VALIDATION.md).
  • GPU comparison: GPU bf16/fp16 3.2–3.4× faster on the device forward, but the served request is host-bound on both sides (JPEG decode/resize ~18 ms), so end-to-end the GPU is only 1.1× faster. RTX 5090 rows (2026-09-14): same host, the port's own torch reference (same weights) run eagerly in PyTorch 2.11 cu128 with fp32 weights + autocast unless stated, no TensorRT; medians of 50 iterations after warm-up, H2D/D2H included; the p150a rows are the served bf16 fused path incl. upload/readback. p150a power was not measured, so no efficiency comparison is made. Full table: GPU_COMPARISON.md.

Licensing

Provenance

The exact sources the image was built from — code/ in this repo is byte-identical to the model code inside the image:

component built from
tt-metal 8b98410e730bb504fea43a88609756e34821d91d
code/ digest ae768681d4aa677d (sha256, first 16 hex digits)
built 2026-09-13T15:21:44+00:00 by tt-model 0.1.0
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for changh95/superpoint-p150

Finetuned
(1)
this model

Paper for changh95/superpoint-p150