Requirements
- Python ≥ 3.11. The whole workspace targets it.
- uv for the env and build. The
./Quickstartscript auto-installs it if missing. - No GPU at runtime. Inference is CPU-only via onnxruntime. A GPU (CUDA or Apple MPS) is only needed for the offline training and auto-labeling steps.
tensor-factory is a uv workspace (monorepo) of five packages. One
lockfile, uv.lock, covers them all. See the layout
for what each package does.
Install
Clone and sync the locked workspace:
# clone git clone https://github.com/JimothyJohn/tensor-factory cd tensor-factory # sync every workspace package against the lockfile uv sync --locked --all-packages
That installs the core library plus the inference runtime (onnxruntime, numpy,
pillow) and the MCP/HTTP servers. Heavy extras — torch for training,
GroundingDINO for auto-labeling, google-genai for generation — are
not pulled by a default sync; you add them only when you run those steps
(see CLI › extras).
Just want it running? ./Quickstart with no flags bootstraps the
workspace and launches the MCP detection server on the bundled demo model.
It needs no API keys and no GPU.
Your first detection
The tensor-factory-mcp package bundles two ready-to-run int8 models, so
you can detect against one immediately. Point the core CLI at any image:
# the bundled real-data model (presence head): helicoil-presence-cam-v1.onnx
MODEL=packages/tensor-factory-mcp/src/tensor_factory_mcp/models/helicoil-presence-cam-v1.onnx
uv run tensor-factory detect --model "$MODEL" --image frame.png
Output is the box in both normalized and 8-bit form:
# illustrative — your numbers depend on the image
box (norm xyxy): 0.2106 0.3318 0.7882 0.7901
uint8 (x1 y1 x2 y2): 54 85 201 201
Those four uint8 values are the detection — the whole
on-the-wire contract. See the detection contract
for why four bytes is enough.
Bundled models
| File | Trained on | Head |
|---|---|---|
helicoil-presence-cam-v1.onnx | real camera frames | box + presence (reports present / absent) |
helicoil-mock-v1.onnx | synthetic mock | box only |
The presence model is the default the servers resolve. Both live under
packages/tensor-factory-mcp/src/tensor_factory_mcp/models/.
Benchmark it
Measure CPU throughput on a synthetic gray frame (or a real one with --image):
uv run tensor-factory bench --model "$MODEL"
# 204.3 fps (100 runs, 480px, CPU)
The reference numbers — ~204 fps @ 480 px, 81 KB int8 model — are from the helicoils example. Architecture and throughput hold across models trained from the same recipe.
Serve it
There are two ways to expose the detector to other processes. Both wrap the same core inference, so they return byte-identical JSON.
MCP (stdio)
For MCP clients (editors, agents). The server speaks over stdio and exits on EOF when no client is attached:
uv run tensor-factory-mcp
Register it in a project via .mcp.json:
{ "mcpServers": {
"tensor-factory": {
"command": "uv",
"args": ["run", "--package", "tensor-factory-mcp", "tensor-factory-mcp"]
}
} }
It exposes three read-only detection tools — full signatures in CLI › MCP.
HTTP (stdlib)
When MCP is heavier than you need — a plain JSON endpoint over http.server, zero extra deps. It binds 127.0.0.1 by default:
uv run tensor-factory-http --port 8088 & curl http://127.0.0.1:8088/health # {"status": "ok"} curl http://127.0.0.1:8088/model_info # model + ORT providers curl --data-binary @frame.png http://127.0.0.1:8088/detect # raw bytes -> detection JSON
A detector on a dev box is not public-by-default. tensor-factory-http
binds loopback; pass --host 0.0.0.0 only when you mean to expose it.
Where to next
- The pipeline — synthesize a dataset, auto-label, review, and train your own model for a new object.
- CLI reference — every command and flag across the five packages.
- Python API —
BBox, the codec,Detector, and the training functions. - Internals — the detection contract, the soft-argmax model, quantization, and the review gate.