ACT: the Action Chunking with Transformers policy from the ALOHA paper, as a per-call API
ACT is a small imitation learning policy with a long shadow. It teaches a robot arm one task from your recorded demonstrations. It predicts a whole chunk of future actions in a single pass, not one move at a time. It was published in April 2023 with the ALOHA bimanual hardware project. Every newer policy since, diffusion policy, pi 0.5, OpenVLA, gets measured against it. This page explains what ACT is, how many demonstrations it needs, and why it is still the speed baseline. The honest state first: this page is the platform's written record for a metered per call lane for ACT. Its row sits in the platform's model data, rate set, on the public list and serving per call, confirmed by the October 26, 2026 requests.
Last verified: 2026-10-05
What it is
ACT came out of one question. Can cheap, imprecise robot arms do fine manipulation? The paper that answers it is Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware (Zhao, Kumar, Levine, and Finn, RSS 2023). The authors built ALOHA, a two arm rig an operator drives by hand, from low cost off-the-shelf parts. They recorded demonstrations at 50 Hz and trained ACT on them. The result: six hard real world tasks, like slotting a battery and opening a translucent condiment cup, learned at 80 to 90 percent success from about 10 minutes of demonstrations per task.
The policy itself is small. The LeRobot policy page counts about 80 million parameters and calls ACT "the first model we recommend when you're starting out". The reasons: it trains in a few hours on one GPU, it needs little memory, and its defaults work well. It ships in the base LeRobot install, with no extra dependencies, no gated downloads, no license puzzle. That simplicity is why the community made it the default baseline.
| Fact | Value | Owner of the number |
|---|---|---|
| Full name | Action Chunking with Transformers, ACT for short | the 2023 ALOHA paper |
| Class | imitation learning policy (behavior cloning with chunked output) | the 2023 ALOHA paper |
| Size | about 80 million parameters | LeRobot policy page, read 2026-10-05 |
| Vision | a ResNet-18 backbone per camera view | the 2023 ALOHA paper |
| Output | a chunk of k future joint commands, k fixed at 100 in the paper | the 2023 ALOHA paper |
| Demonstrations | 50 per task, about 10 to 20 minutes of recorded motion | the 2023 ALOHA paper |
| Training time | a few hours for 100,000 steps on one GPU, batch size 8 | LeRobot policy page |
| Training memory | the light class, roughly 2 to 6 GB at batch 8 | LeRobot hardware guide |
| Original code | built on a DETR style transformer, open source | the ACT repository |
The name: one policy, two collisions
The word ACT collides with two much bigger things. Search "act" and you get the college admissions test. Search "act api" and you get the Act! CRM product, which owns that phrase outright. The robotics intent lives in longer forms: "act policy", "act policy robotics", "lerobot act", "action chunking transformer". The platform's id for the model is the short alias act. That id is what goes in your API calls, and it is the only place the bare word belongs.
How ACT works: chunks, the style variable, the ensemble
The problem ACT solves is compounding error. A plain cloning policy looks, predicts one action, executes, then looks again. Each slightly wrong action puts the arm somewhere the training data never covered, and the drift accelerates. ACT changes the unit of prediction: from one observation it emits a chunk of up to 100 future actions, generated together into one coherent, smooth path. The paper's ablation makes the point bluntly. In its simulation setting, success went from 1 percent with a chunk of 1 to 44 percent with a chunk of 100.
Three design pieces are worth knowing as a buyer.
First, the style variable. Two humans demonstrate the same task two ways, and a naive model averages them into a motion that matches neither. ACT trains as a conditional VAE. An encoder compresses each demonstration into a latent style variable z, which teaches the decoder the range of valid styles. At test time the encoder is thrown away and z is set to zero. The paper's ablation again: removing that objective dropped a hard task from 35.3 percent to 2 percent.
Second, the temporal ensemble. The policy re-queries before the old chunk finishes. Several overlapping chunks predict the same timestep. ACT blends them with an exponential weighting that favors the freshest predictions. That is what smooths the joins between chunks.
Third, the architecture. Camera images pass through ResNet-18 backbones. A transformer encoder mixes those features with the current joint positions. A transformer decoder, in the DETR lineage, generates the whole chunk in one pass. This also answers the question that follows ACT around search results: ACT contains no U-Net. The U-Net belongs to the CNN version of diffusion policy, its noise prediction network, and the question leaks across because the tutorials rank together. If you are tuning an ACT policy, there is no U-Net to tune.
Use cases
ACT is the right tool when the job is one task, one scene, repeated.
- Repetitive work cells. The same pick and place, connector insertion, or part flip, thousands of times a day, in a fixed setup you control. This is the case the paper was built for.
- Contact rich fine motion. Slotting, threading, and prying need smooth coordinated movement at 50 Hz. Chunked output gives you that smoothness by construction.
- Tight control loops. A cheap inference step means your arm can re-plan often without pausing. Speed is ACT's durable edge. The benchmarks section below puts numbers on it.
- Small data, small budget. Fifty demonstrations and a few GPU hours. If the task is worth fifty recordings, no competent policy costs less than ACT.
- A first run on a new arm. The fastest way to prove the cameras, the dataset, and the evaluation loop all work is an ACT run. The dataset transfers unchanged if you move to a larger policy later. If you run an SO-101 class arm, the record, train, serve loop is written up in the SO-101 cloud brain guide.
It is the wrong tool when you need language instructions, one checkpoint serving several tasks, or tolerance for scenes it never saw. ACT has no language input. A slightly unfamiliar scene can produce an arbitrary action, not a graceful near miss. That is the honest cost of no pretraining. Whatever it does is exactly what you showed it.
The 50-demonstration rule
| What you record | What to expect |
|---|---|
| 50 consistent demonstrations of one task | the paper's own count; the working baseline everywhere |
| 100 for a harder task | the paper used 100 for its hardest task, threading velcro |
| two tasks mixed into one dataset | one averaged, useless policy; ACT cannot tell them apart |
| inconsistent demonstrations of the same task | the style variable tries to cover both styles and the motion degrades |
| jerky or stalling result | train longer before touching anything else; the author's tuning note says smoothness improves after the loss flattens |
The LeRobot docs state the rule from the platform side: ACT "often achieves high success rates with just 50 demonstrations". A third party training platform sets the same floor from the buyer side: below 50, results are usually not worth evaluating. Two independent sources, one number.
ACT versus diffusion policy
Both methods attack compounding error, and both emit action chunks. The machinery differs. ACT generates the whole chunk in one forward pass, with a style variable during training for demonstrations that solve a task two ways. Diffusion policy starts from noise and refines it toward a clean chunk over several denoising passes, naturally tolerant of messy, mixed data, at a higher compute cost.
The practical split follows from that. Use ACT when your data is clean, your task fixed, and you want a fast, cheap run. Use diffusion policy when your demonstrations disagree and you can pay for the extra passes. ACT's training class is 2 to 6 GB; a few hours on one card finishes the default 100,000 step schedule. On inference, one pass is simply fewer passes. Teams that outgrow ACT do so for language control or scene variety. The chunking idea itself rarely fails them.
ACT versus SmolVLA and the large VLAs
The modern comparison comes down to speed against breadth. Both sides have numbers.
On the breadth side, SmolVLA's own announcement states that the 450M parameter model "outperforms much larger VLAs and strong baselines such as ACT". The claim covers simulation benchmarks and SO-100 and SO-101 real arm tasks, the publisher's claim, for its model, and one reason SmolVLA is the other beginner favorite. The smolvla page covers it.
On the speed and independent measurement side, there are two reads. A third party training platform measured ACT at about 20 milliseconds per action step in August 2026; SmolVLA ran at roughly 245 and pi 0.5 at 485 in the same pool. The PhAIL community leaderboard, read live on October 5, 2026, agrees from a different angle. ACT placed third on success at single arm pick and place, and it was the fastest robot per item at 13.8 seconds against 15.7 for the generalists above it. The full read is in the benchmarks section.
A rule falls out of those numbers. If your task fits one fixed scene and fifty demonstrations, ACT gives you the least costly fast loop in the field; no larger model beats it on pace. If you need to follow language or survive an unrecorded scene, pay for a generalist. The VLA category page maps the family; pi 0.5 covers the generalist side.
API usage
The lane's contract speaks the platform's robot action route, POST /v1/action, with a Bearer key from the console. Multipart form data goes in, JSON comes out. The model id is act.
| Form field | Required | Notes |
|---|---|---|
model | yes | act |
instruction | yes | the route requires a non-empty task string on every row. ACT does not read it. The field exists so one client shape serves every model on the route |
state | yes | a JSON array of numbers, your arm's joint positions, same order every call. The empty array [] is the legal stateless case |
image | yes, one or more | camera frames as file parts. One to three in practice: an outer view plus a wrist view |
One served request returns three things. actions is the action chunk, a list of actuator deltas in the checkpoint's own shape and length. normalization is the norm stats the endpoint applied, untouched. Your driver uses them to convert back to your units. Skipping that step is the embodiment detail that most often breaks a real deployment. usage is ours: the call count and the cost, returned with every answer. Metering is per call. One served request is one billed call. A refused request bills nothing. The prepaid wallet is the hard stop on spend.
The honesty line, stated plainly: this alias is on the public list and answers per call. The October 26, 2026 requests confirm it. The tabs below are the contract the lane ships under; client code can be written against the shape now. Every field, error code, and limit is documented in the run-action reference and the action route guide.
curl
curl -X POST "https://api.ironstratum.com/v1/action" \
-H "Authorization: Bearer $KEY" \
-F "model=act" \
-F "instruction=pick up the black cube and place it in the bin" \
-F 'state=[0.0, 0.12, -0.4, 0.0, 0.5, 0.1, 0.0]' \
-F "image=@scene.jpg" \
-F "image=@wrist.jpg"
python
import os
import requests
resp = requests.post(
"https://api.ironstratum.com/v1/action",
headers={"Authorization": "Bearer " + os.environ["KEY"]},
data={
"model": "act",
"instruction": "pick up the black cube and place it in the bin",
"state": "[0.0, 0.12, -0.4, 0.0, 0.5, 0.1, 0.0]",
},
files=[
("image", ("scene.jpg", open("scene.jpg", "rb"), "image/jpeg")),
("image", ("wrist.jpg", open("wrist.jpg", "rb"), "image/jpeg")),
],
timeout=30,
)
resp.raise_for_status()
answer = resp.json()
chunk = answer["actions"] # the action chunk: a list of actuator deltas
stats = answer["normalization"] # the norm stats this endpoint applied
print("actions in this chunk:", len(chunk))
print("cost of this call:", answer["usage"].get("cost"))
lerobot
import os
import requests
from lerobot.cameras.opencv import OpenCVCamera
session = requests.Session()
session.headers["Authorization"] = "Bearer " + os.environ["KEY"]
cam = OpenCVCamera(camera_index=0, fps=30, width=640, height=480)
cam.connect()
instruction = "pick up the black cube and place it in the bin"
state = [0.0] * 7 # your arm's joint positions, same order on every call
running = True
while running:
frame = cam.async_read()
resp = session.post(
"https://api.ironstratum.com/v1/action",
data={
"model": "act",
"instruction": instruction,
"state": "[" + ", ".join(str(s) for s in state) + "]",
},
files={"image": ("scene.jpg", frame, "image/jpeg")},
timeout=30,
)
resp.raise_for_status()
chunk = resp.json()["actions"]
for deltas in chunk:
state, running = arm_step(state, deltas) # your arm driver goes here
if not running:
break
The loop is the whole pattern, and with ACT it runs tight. Send frames and state. Receive a chunk. Execute it at your control rate. Send the new state with the next call. LeRobot's defaults here are a chunk of 100, all 100 executed, and the executed count must never exceed the chunk length. If your scene shifts mid task, execute fewer steps and re-query more often; ACT's inference is cheap enough that re-querying is nearly free. That trade is what a slow generalist cannot make. Hosting versus a local card is worked through in the VLA local versus API break-even guide.
Benchmarks
Three evidence layers, each named and dated. None is this platform's own measurement: nothing serves under the alias, so there is nothing to measure. Our own numbers publish only after they are measured and held, a later dated pass this page does not promise.
The paper, 2023. Six real world tasks at 80 to 90 percent success from 50 demonstrations each. In simulation ablations, chunking moved success from 1 percent at chunk size 1 to 44 percent at chunk size 100. Removing the style variable objective dropped a hard task from 35.3 to 2 percent (the paper, read 2026-10-05). Those two ablations are the whole argument for the design.
PhAIL, the community production benchmark, read live October 5, 2026. PhAIL is run by Positronic Robotics. It measures single arm pick and place on a DROID setup with production metrics. On that day's page, human teleoperation came first. It scored 99.0 percent success at 10.4 seconds per item. GR00T N1.6 scored 46.1 percent and open pi 0.5 scored 44.4 percent. Those two sat in a statistical tie at the front of the robot field, both at 15.7 seconds per item. ACT placed third, at 42.5 percent success within 30 seconds, plus or minus 5.6. It was the fastest robot on the board at 13.8 seconds per item, plus or minus 0.9. SmolVLA placed fourth at 16.3 percent. Read that table honestly. The big generalists clear ACT on success by a few points inside wide error bars. ACT clears them on pace. This is the same live read the pi 0.5 family page carries, on the same date, from the same leaderboard. Community run, single source, named and dated.
Third party latency, August 2026. AY-Robots, a company that sells ACT fine tuning, measures about 20 milliseconds per action step on a 24 GB class card in its own training pool. In the same pool, SmolVLA ran at roughly 245 milliseconds, GR00T N1.7 at 152, and pi 0.5 at 485. Their number, their setup, one source. It matches the design expectation for a one pass decoder. It also matches the PhAIL per item timing. That is why we repeat it with its label on.
Getting started
- Read the primary sources. The paper, the LeRobot policy page, the ALOHA project page, and the original repository are all public. Every identity fact on this page traces to one of them.
- Count your demonstrations before your dollars. Fifty consistent recordings of one task is the entry ticket. Below that, spend your time recording, not tuning. Own an SO-101 class arm? The cloud brain guide walks the loop from box to trained policy.
- Write your client against the contract now. The tabs above are the shape the lane ships under. The run-action reference documents every field and error code. The models index is the live catalog.
- Open the console when you build. The signup flow opens the wallet, the keys, and the billing history. The loaded balance is the spend bound, and each key revokes alone. The models index and the VLA category page show the state of every lane on the platform.