Tenzro
Tutorial — Multi-modal AI

Embed images with DINOv3

The vision runtime exposes DINOv3, SigLIP2, and CLIP families. Use DINOv3 ViT-B/16 for self-supervised image embeddings that work well for similarity, retrieval, and clustering.
Level
Beginner
Time
~10 min
Prerequisites
Tenzro CLI installed, sample image
Stack
CLI · JSON-RPC
01

Load DINOv3 on a provider

DINOv3 is under Meta's commercial-custom terms, so the node operator has to have started tenzro-node with --accept-license for it; otherwise the load is refused. The ONNX graph has to be on the node's filesystem already, and --catalog-id supplies the input size, embedding dimension and normalization from the catalog entry.

tenzro embed-image catalog

tenzro embed-image load \
  --model img \
  --path /models/dinov3-vitb16.onnx \
  --catalog-id dinov3-vitb16
02

Embed a single image

PNG, JPEG and WebP decode, Lanczos3 resize and normalization all happen on the node. --normalize L2-normalizes the returned vector so cosine similarity reduces to a dot product.

tenzro embed-image run --model img --image ./photo.png --normalize
03

Compare two images

The similarity arm is pure cosine over two equal-length vectors, so it scores any pair of embeddings from the same space — the flag names lean cross-modal, but two image embeddings are exactly what DINOv3 is for. Extract the vector from each result with jq, since the arm reads a bare JSON array.

tenzro embed-image run --model img --image ./a.png --normalize | jq '.embedding' > a.json
tenzro embed-image run --model img --image ./b.png --normalize | jq '.embedding' > b.json

tenzro embed-image similarity \
  --image-embedding a.json \
  --text-embedding b.json

Scoring an image against a text query needs a jointly-trained pair, because cosine is only meaningful inside one shared embedding space. DINOv3 is self-supervised and has no text tower — reach for CLIP or SigLIP2 there. Mismatched dimensions are refused outright, so check the catalog's embedding_dim on both sides first.

04

Call from JSON-RPC

Send base64 bytes for server-side embedding when integrating with a backend. model_id is the id you loaded under, not the catalog id.

curl -s https://rpc.tenzro.xyz -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tenzro_imageEmbed","params":{"model_id":"img","image_base64":"","normalize":true}}'
Related
← All tutorials