agi.diy: Robot policies, served over an API.

license: Apache 2.0 params: 450M weights: 4-bit · 254 MB actions per call: 50 at 30 Hz held-out RMSE: 16.44 (4-bit) over 1.67 s price: $0.0001 per action api.agi.diy: listed as `agi-smolvla/so101` collection: agi

agi-smolvla/so101 · 4-bit

Robot policies, served over an API. agi.diy serves robot policies over the LeRobot remote-inference protocol: you send camera frames and joint state, you get back a chunk of 50 actions, you pay one token per action. This repo is the 4-bit export of agi-smolvla/so101 for the SO-101 arm. It scores 16.44 held-out RMSE over 1.67 s of motion, where the stock checkpoint scores 41.07 on the same frames over the same span, and the full-precision parent scores 14.45. A chunk error only means something next to the seconds it covers, so every figure on this card carries its span.

/play with `agi-smolvla/so101` selected: the same checkpoint against a MuJoCo SO-101 in the browser.Session trace `ses_3WmhwXtsgW05H3pMgm6BTp`: 3 probe calls, 50 actions each, 286–886 ms round trip over `tls/zenoh.api.agi.diy:7447`, 150 tokens billed.
/play with `agi-smolvla/so101` selected: the same checkpoint against a MuJoCo SO-101 in the browser.Session trace `ses_3WmhwXtsgW05H3pMgm6BTp`: 3 probe calls, 50 actions each, 286–886 ms round trip over `tls/zenoh.api.agi.diy:7447`, 150 tokens billed.

Real captures from api.agi.diy at 1440 px, 2026-10-25 10:58Z. The probe sends zero images, so the chunks shown are not a task.

What agi.diy is

  • An API for robot policies. POST /v1/sessions leases a running policy server; your robot streams observations to it and executes the returned action chunks. One token per action, $0.0001 each. Your robot stays yours: no firmware, no cloud control loop, the client is the stock LeRobot RemoteClient.
  • Any checkpoint. agi.diy's own post-tuned models (this family), the stock community checkpoints, or any LeRobot policy on the Hub via hf:<org>/<repo> (bring your own).
  • Reproducible in a browser. api.agi.diy/play runs the same checkpoints against a MuJoCo SO-101 so a stranger can watch a policy work before paying for a call.

agi.diy · docs · play · the agi collection

This model

Offline held-out evaluation on lerobot/svla_so101_pickplace, episodes 45–49 (never seen in training), one observation every 30 frames (36 windows), the recorded future actions at the matching instants as the target, through the same PolicyRunner the server uses (agi_wfm/eval/offline_mse.py). Units: so101-normalized-v1 (arm joints −100…100, gripper 0…100). Lower is better. The first two columns were measured in the SAME run (36 windows, horizon 50, Jetson AGX Thor, cuda): this repo's weights dequantised, and the parent's weights as shipped, so the two are comparable to each other. The parent's own card reports a separate run on different hardware, so its numbers there differ slightly; the stock column comes from that run too, which is why it has no latency cell here.

Read a chunk RMSE together with its span. This model returns 50 actions at 30 Hz, so one chunk is 1.67 s of motion, and every figure below scores exactly that much: action k of the chunk is compared with the recorded action at the same instant, k/30 s ahead. Scores over different spans are not comparable with each other, which is why the family table further down puts every model over one span.

this repo (4-bit) full precision parent stock checkpoint hold current action
RMSE over the 50-step chunk (1.67 s of motion) 16.44 14.25 41.07 29.51
RMSE of the first action (span has no effect on this one) 3.31 2.53 28.33 0.00
MAE over the chunk (1.67 s) 9.31 7.63 30.96 —
latency per call (median, cuda) 197 ms 182 ms — —

The stock column is edge-inference/smolvla-so101-pick-orange, the public checkpoint agi.diy served as smolvla/so101 before this one. "Hold current action" repeats the last commanded action for the whole chunk; a policy must beat it to be worth a call. These 4-bit weights beats it over the same 1.67 s of motion: 16.44 vs 29.51, 1.8x lower error, and its first action is 3.31. This policy samples its actions and runs unseeded, so this is one run: two identical runs of it over 1.67 s differed by 0.54 RMSE, which is the precision to read the figure at. The baseline is measured on the same episodes over the same span (36 windows), because repeating an action for 1.67 s is a different task than repeating it for half as long: on this split the same baseline scores 29.51 over 1.67 s. Per joint, the full-precision parent (RMSE over the 1.67 s chunk): shoulder_pan 26.6 · shoulder_lift 13.2 · elbow_flex 11.0 · wrist_flex 8.0 · wrist_roll 12.3 · gripper 6.0.

This is an offline action error, not a task success rate. The closed-loop sim numbers live on the agi.diy bench as they are measured; nothing here claims a success rate.

  • Cameras: front + wrist at 480×640. State: 6 joints. Output: 50 actions per call at 30 Hz (1.67 s of motion), so one call costs $0.0050.
  • Serving: agi-smolvla/so101 on api.agi.diy today (the old id smolvla/so101 still resolves as an alias), from a Jetson AGX Thor demo runner.

4-bit vs the bf16/fp32 weights, same frames, same harness, same 1.67 s span (one run, both formats): 907 MB → 254 MB (-72% bytes), held-out RMSE 14.25 → 16.44 (+15%), latency 182 → 197 ms. Method: int4 weight-only, symmetric, group 32, fp16 scales, packed 2 per byte (agi_wfm.hub.quantize). Two runs in opposite order on the same 36 held-out windows: 4-bit costs +15% and +17% chunk RMSE (16.44 and 17.14 vs 14.25 and 14.59 full precision) and +31%/+29% first-step RMSE for a 72% smaller download. SmolVLA samples its actions, so the same weights move by 0.3–0.7 RMSE between runs; the 4-bit gap is larger than that noise. Latency is the same within noise (183–206 ms vs 197 ms best of two; the 332 ms in run 1 was the second model in the process, not the format). Use the full-precision repo when the download size does not matter.

Use it today

1. Through api.agi.diy (no GPU, no server; one token per action):

pip install agi-diy "lerobot[remote] @ git+https://github.com/huggingface/lerobot"
agi login                      # key from https://api.agi.diy/dashboard
agi run agi-smolvla/so101 --probe     # one real call: 50 actions back, the trace URL printed
import agi

with agi.Policy("agi-smolvla/so101") as session:
    actions = session.predict(
        {"observation.state": state, "observation.images.front": front, "observation.images.wrist": wrist},
        task="pick up the orange and put it on the plate",
    )  # np.ndarray [50, 6] in so101-normalized-v1
# a real SO-101 (LeRobot follower), the policy on agi.diy:
agi rollout agi-smolvla/so101 -- --robot.type=so101_follower --robot.port=/dev/ttyACM0 --robot.use_degrees=false

Lease without the SDK: curl -s https://api.agi.diy/v1/sessions -H "Authorization: Bearer $AGI_API_KEY" -d '{"model":"agi-smolvla/so101"}' returns the zenoh endpoint and deployment id for lerobot.remote_inference.RemoteClient. Cost: 50 tokens per call, $0.0050; a 30-second rollout at 30 Hz is about $0.090.

2. Run the open weights yourself. This repo is a download format: model-q4.safetensors holds int4 weights + fp16 scales. dequantize.py (in this repo, torch + safetensors only) rebuilds a stock LeRobot checkpoint in the original dtype, which the unmodified lerobot-policy-server then serves exactly like cagataydev/agi-smolvla-so101:

pip install "lerobot[remote] @ git+https://github.com/huggingface/lerobot"
hf download cagataydev/agi-smolvla-so101-4bit --local-dir ./agi-smolvla-so101-4bit
python ./agi-smolvla-so101-4bit/dequantize.py materialize ./agi-smolvla-so101-4bit ./agi-smolvla-so101-fp32   # 3.0 s measured
zenohd &
lerobot-policy-server --config_path=./agi-smolvla-so101-4bit/serve/deployment.yaml --deployment=d_local &
lerobot-rollout --inference.type=remote --inference.endpoint=tcp/127.0.0.1:7447 --inference.deployment=d_local \
  --inference.semantics=so101-normalized-v1 --robot.type=so101_follower --robot.port=/dev/ttyACM0 --robot.use_degrees=false

3. Bring your own checkpoint through the same API: any LeRobot act, smolvla or diffusion repo on the Hub (the full-precision repo; this 4-bit format is for downloads, not for hf:).

curl -s https://api.agi.diy/v1/sessions -H "Authorization: Bearer $AGI_API_KEY" \
  -H "content-type: application/json" -d '{"model":"hf:cagataydev/agi-smolvla-so101"}'

The Worker validates config.json on the Hub, warms a server for it (state: warming → leased) and bills it like any other model. Docs: api.agi.diy/docs#custom-checkpoint. MCP: POST https://api.agi.diy/mcp lists models and quickstarts to an agent.

Recipe

base lerobot/smolvla_base (apache-2.0)
data lerobot/svla_so101_pickplace (apache-2.0): 50 episodes, 11,939 frames, 30 fps, 480×640; training episodes 0–44 (45 episodes), episodes 45–49 held out
method LeRobot smolvla, chunk_size 50, n_action_steps 50, lerobot @d3793b7e (the revision the runner serves with)
optimisation 10000 steps × batch 32, lr 0.0001
compute HF Jobs h200, 119 min, $9.88 · job 6addbca1046eb82b1ece3d7f
artefacts runs/20261025T082401Z-smolvla/ on this repo: train config, final checkpoint, eval JSON
4-bit export int4 weight-only, symmetric, group 32, fp16 scales, packed 2 per byte (agi_wfm.hub.quantize) · python -m agi_wfm.hub.quantize --repo cagataydev/agi-smolvla-so101

Command: python jobs/launch.py lerobot --name smolvla --out cagataydev/agi-smolvla-so101 in the agi-wfm repo (private today; the training scripts are released with the weights).

Limitations

  • One task family (pick the orange, place it on the plate) from one dataset. Nothing here generalises to other objects or scenes by evidence.
  • Offline RMSE on held-out frames is the only number on this card, and it is only readable next to the span it covers (this chunk is 1.67 s of motion). Sim-to-real is untested; no physical robot ran this checkpoint for the numbers above.
  • The dataset's two cameras are static (up and side). They are renamed to this checkpoint's front and wrist slots; the wrist slot is fed by a camera that is not on the wrist. A real robot with a true wrist camera shows the policy pixels it never saw.
  • The task string was constant in training (one task family); other instructions are not learned behaviours.
  • Units are so101-normalized-v1: arm joints −100…100 over the calibrated range, gripper 0…100. Feeding degrees moves the arm to the wrong place.

Data and licences

License

Apache-2.0. Weights, exports, eval JSON and this card are © agi.diy, same licence. Credit: LeRobot (smolvla implementation and the dataset), the SmolVLA authors (base).

The family

Three checkpoints, one data split, one eval harness, one span. Each policy runs at its own rate, so the table scores each one over the same 1.67 s of motion: act uses 50 of its 100 actions, smolvla all 50 of its own, agi-wfm 25 of its 32. Held-out episodes 45–49 of lerobot/svla_so101_pickplace, one observation every 15 frames, 74 to 75 windows per row (a 15 Hz chunk needs one frame less of recorded future than a 30 Hz one), on a Jetson AGX Thor. Lower is better.

over 1.67 s of motion serves chunk RMSE first action weights 4-bit status
agi-wfm/so101
25 of its 32 actions at 15 Hz
agi-wfm/so101 14.20 to 16.12 4.31 to 4.62 8.17 GB — flagship · preview, post-training in progress; weights private
agi-smolvla/so101
all 50 of its actions at 30 Hz
agi-smolvla/so101 14.01 to 14.55 2.71 to 2.85 907 MB 254 MB ← this repo default
agi-act/so101
50 of its 100 actions at 30 Hz
agi-act/so101 13.56 5.04 207 MB 29 MB default
hold the current action
the baseline a paid call has to beat
— 28.49 0.00 — — —
the training set's mean action — 33.64 — — — —
all zeros — 59.58 — — — —

The baselines are sampled on the 15 Hz grid; on the 30 Hz grid they are 28.89 / 33.76 / 59.47, the same within noise. agi-wfm's row is measured at the 4 denoise steps the hosted API serves; a denoising policy's figure without its step count is not comparable with anything. Over this near-term span every checkpoint scores between 13.56 and 16.12, which is 1.8x to 2.1x better than repeating the last action; they differ far more in latency and in size than in accuracy. Two of these policies sample their actions and run unseeded, so a single run is a sample, not a score: agi-wfm moves 1.92 RMSE between two identical runs; agi-smolvla moves 0.54 RMSE between two identical runs. Both runs of each are in eval/spans.json and the ranges above are over them, so no order inside a range is claimed here.

The flagship's chunk reaches further than this one, 2.13 s per call, and is scored over that span on its own card with the denoise step count it was measured at. No figure of it is quoted here and no order between it and this checkpoint is claimed: it denoises its actions, so its score moves with the step count the server runs (same weights, same 70 windows, same 2.13 s: 12.71 at 1 denoise step, 13.50 at the 4 the hosted API serves) and again with its unseeded sampler, by more than the checkpoints differ from each other.

Reproduce any row in about three minutes per model:

python -m agi_wfm.eval.offline_mse --root <dataset> --repo lerobot/svla_so101_pickplace \
  --episodes 45 46 47 48 49 --policy <checkpoint> --every 15 --seconds 1.667 --device cuda --out x.json

Every figure above, with its span, rate, window count and the file it came from: eval/spans.json in this repo. All of them: the agi collection.

Links

Downloads last month
-
Video Preview
loading

Model tree for cagataydev/agi-smolvla-so101-4bit

Dataset used to train cagataydev/agi-smolvla-so101-4bit

Collection including cagataydev/agi-smolvla-so101-4bit