
What to look for in a robot teleoperator, how long training really takes, and the measurable ways operator skill shows up in a LeRobot dataset. With real numbers.
What you need to know
- •Operator skill is measurable in the data, not in the interview. In the robomimic study, behavioral cloning on 100 demonstrations from two "better" operators scored 83.3% on Can and 58.7% on Square; the same budget from two "worse" operators scored 56.7% and 22.0%.
- •More data from weaker operators can be worse than less data from a good one: the 300-demonstration multi-human sets never beat the 200-demonstration single-operator sets on any task, and on Square they trailed 78.0% against 84.0% with BC-RNN.
- •Training a new operator takes hours, not weeks. RoboTurk onboarded 54 remote participants with a 5 minute tutorial and one supervised hour.
- •Episode length and its spread is the cheapest quality signal you have. In robomimic the "worse" group needed 304 frames on Can where the "better" group needed 143, at five times the spread.
- •The LeRobot dataset format has no operator field. Record one dataset per operator, judge each, then merge the survivors with lerobot-edit-dataset.
- •Hire for patience and consistency, but fix the control interface before you screen anyone. In the RoboTurk user study the interface alone moved mean completion time from 79.36 s on a VR controller to 151.45 s on a keyboard.
You have an SO-100 on the bench, a task worth automating, and a policy that needs 30 to 50 episodes before it is useful. The bottleneck is not the GPU or the model. It is the person driving the arm. Every frame of a LeRobot dataset records one human's motor habits, and imitation learning copies them faithfully, bad ones included.
This covers the human side of teleoperation: what to look for in an operator, how long training takes, and which numbers in the finished dataset tell you whether they were any good. The published evidence is thin but consistent.
The evidence: operator skill moves policy success by tens of points
The cleanest study is What Matters in Learning from Offline Human Demonstrations for Robot Manipulation (Mandlekar et al., CoRL 2021). Six operators recorded through RoboTurk in three tiers: two experienced ("better"), two adequate ("okay"), two inexperienced ("worse"), each providing 50 demonstrations per single-arm task. The tiers are size-matched, so the comparison isolates skill from volume. The success rates below are the paper's low-dimensional results, Table 2 for the operator mixtures and Table 1 for the single proficient operator; image observations are reported separately in its Table 3.
| Data subset | Demos | BC on Can | BC on Square | BC-RNN on Can | BC-RNN on Square |
|---|---|---|---|---|---|
| Two "better" operators | 100 | 83.3% | 58.7% | 99.3% | 66.0% |
| Two "okay" operators | 100 | 72.0% | 27.3% | 95.3% | 45.3% |
| Two "worse" operators | 100 | 56.7% | 22.0% | 92.0% | 39.3% |
| Worse + okay mixed | 200 | 74.7% | 28.7% | 98.7% | 55.3% |
| Worse + better mixed | 200 | 76.0% | 46.7% | 100.0% | 73.3% |
| One proficient operator (PH) | 200 | 95.3% | 78.7% | 100.0% | 84.0% |
On the harder task (Square, where the arm picks a square nut and places it on a rod) the gap between best and worst tier is 36.7 points for plain behavioral cloning. A stronger algorithm absorbs some of it: BC-RNN nearly closes the gap on Can, and leaves 26.7 points open on Square. And 200 demonstrations from one proficient operator (84.0%) beat every 200-demonstration mixture containing a weak one.
The earlier Scaling Robot Supervision to Hundreds of Hours with RoboTurk (IROS 2019) hit the same wall from the other side: 111 hours across 54 users on three Sawyer arms in one week. Behavioral cloning on the full Laundry Layout set failed outright, and partial success came only after restricting training to the segments where the arm moves to a corner of the towel and lifts. Fifty-four people solving an open task in fifty-four ways produced a dataset close to untrainable as one policy. More in our RoboTurk write-up.
Operator variance hurts in two ways. Proficiency variance (shaky, hesitant) adds noise the policy reproduces. Strategy variance (two operators solving the task differently) adds multimodality the policy must average over, which is worse. Practice fixes the first. Writing the task down before anyone touches the arm fixes the second.
How operator skill shows up in the data
You do not need a supervisor at the operator's shoulder. The signal is in the dataset. The robomimic authors published average trajectory lengths per tier, and the pattern is blunt enough to use as a screening rule.
| Operator tier | Lift (frames) | Can (frames) | Square (frames) | Transport (frames) |
|---|---|---|---|---|
| Better | 72 +/- 24 | 143 +/- 29 | 185 +/- 46 | 461 +/- 56 |
| Okay | 94 +/- 30 | 181 +/- 47 | 265 +/- 78 | 636 +/- 128 |
| Worse | 145 +/- 40 | 304 +/- 148 | 357 +/- 150 | 778 +/- 221 |
The weaker tier takes roughly twice as long, but the standard deviation is the sharper signal: on Can it goes from 29 frames to 148. A good operator does the same thing every time. A weak one improvises, and improvisation is the multimodality that makes a policy hesitate at the grasp. Compute one number per operator, and make it the coefficient of variation of episode length.
| Signal | Where it comes from | What a weak operator looks like |
|---|---|---|
| Median episode length | meta/episodes length column | Long, from re-approaches and corrections |
| Spread of episode length | same column, standard deviation | Wide: every episode is a different plan |
| Achieved recording rate | the cadence line lerobot-record prints | Drifts below the fps target |
| Re-record rate | how often they press the left arrow | Near zero (they keep bad takes) or very high |
| Gripper transitions per episode | sign changes on the gripper joint in the action column | Many, from repeated open-close attempts |
# Rank operators by episode-length consistency across per-operator datasets.
# Verified against lerobot 0.6.2 (LeRobotDatasetMetadata.episodes has a "length" column).
import statistics
from lerobot.datasets import LeRobotDatasetMetadata
REPOS = {
"anna": "my-org/pick-cube-anna",
"bruno": "my-org/pick-cube-bruno",
"chen": "my-org/pick-cube-chen",
}
for operator, repo_id in REPOS.items():
meta = LeRobotDatasetMetadata(repo_id)
lengths = list(meta.episodes["length"])
median = statistics.median(lengths)
sd = statistics.pstdev(lengths)
print(f"{operator:6s} n={len(lengths):3d} "
f"median={median:6.1f} frames ({median / meta.fps:5.1f} s) "
f"sd={sd:6.1f} cv={sd / median:.2f}")
An honest limitation: none of these separate a slow operator from a hard task instance. A 300-frame episode might be a fumbled grasp, or the one initialisation where the cube started at the far edge. Use the statistics to pick who to watch, then watch the video.
What to look for when you hire an operator
The list below is short because the published evidence supports very little. The original RoboTurk user study reports only that its 8 participants were university students aged 18 to 30; no aptitude screening is described. What it did measure, across those 8 participants and four interfaces, is that the interface dominates: the phone (mean 89.97 seconds on the picking task) and the VR controller (79.36 seconds) were statistically indistinguishable, and both were significantly faster than the 3D mouse (112.57 seconds) and the keyboard (151.45 seconds). Fix the interface before screening people. On an SO-100 that means a calibrated leader-follower pair, not an on-screen pad.
| What to look for | Why it matters | How to test it in 30 minutes |
|---|---|---|
| Tolerance for repetition | A usable dataset is 50 to 200 near-identical episodes | Ask for 20 episodes of one grasp; does episode 20 look like episode 3 |
| Consistency of approach | Strategy variance is the damage algorithms cannot repair | Overlay the gripper trajectories of those 20 episodes |
| Willingness to discard a take | A bad episode kept is worse than one not recorded | Count left-arrow presses. Zero is a red flag |
| Camera-frame awareness | The policy sees only the cameras, never the room | Have them work from the rerun window, not the arm |
| Reporting faults instead of compensating | A drifting servo silently becomes training data | Detune one joint; do they stop or work around it |
| Steady hands under a lag | Remote links add delay operators compensate for badly | Run one block over the real network, not on LAN |

- Strategy variance stays low, which is the variance that hurts most
- Skill compounds: RoboTurk measured completion times falling with experience
- Attribution is trivial, because one operator maps to one dataset
- Matches the robomimic finding that 200 proficient demos beat 300 mixed ones
- Scene and object diversity is bounded by however many settings your team can reach
- One person's idiosyncratic grasp becomes the policy's only grasp
- Illness or churn stops data collection entirely
- DROID reached 564 scenes only by using 50 collectors across 13 institutions
The fix used by DROID is worth copying at any scale: a shared written protocol. Collectors chose their own scenes, but a GUI prompted them with a randomly sampled task per episode so collection would not drift toward the easy objects, periodically demanded scene augmentations such as moving a camera or changing the lighting, and recorded a data collector ID per trajectory. Collectors marked each episode successful or not: the release holds 76k successful episodes plus roughly 16k labelled unsuccessful. See the DROID article for the rest.
How long training an operator actually takes
Shorter than most people assume. RoboTurk's 54 participants got a 5 minute tutorial plus one supervised hour, then collected unsupervised. The learning curve backs that up: completion time fell steadily with previous trials, while measured effort, the squared L2 norm of their phone translations, stayed flat and the orientation change they commanded went up. Operators got faster by rotating the controller more, not by moving it faster.
Here is a curriculum for an SO-100 that mirrors those findings: two hours, ending in a dataset you can train on. Commands are LeRobot 0.6.2 entry points, and the same ground is covered in the operator guide.
- 1Calibrate both arms first, once, together
A first session should not be spent fighting a bad calibration. Run this with the operator watching, so they know what a correct range of motion looks like. See calibration for what the file holds.
bashlerobot-calibrate --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a lerobot-calibrate --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a - 2Fifteen minutes of free teleoperation, nothing recorded
No task, no target, no dataset. Let them find the workspace limits and discover that the gripper closes slower than they expect. The highest-return part of the curriculum.
bashlerobot-teleoperate \ --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \ --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a - 3Fifteen minutes driving from the camera view only
Turn on the visualiser and have them turn their chair away from the robot. The LeRobot docs put it well: you should be able to do the task yourself by only looking at the camera images. If they cannot, the camera placement is wrong, not the operator.
bashlerobot-teleoperate \ --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \ --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} }" \ --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a \ --display_data=true - 4Five throwaway episodes that never reach the Hub
The point is the control flow, not the data. Right arrow or n ends an episode early, left arrow or r cancels and re-records it, Escape or q stops the session. Make them use all three.
bashlerobot-record \ --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \ --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} }" \ --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a \ --display_data=true \ --dataset.repo_id=my-org/warmup-anna \ --dataset.single_task="Pick up the red cube and put it in the bin" \ --dataset.num_episodes=5 \ --dataset.episode_time_s=25 \ --dataset.reset_time_s=15 \ --dataset.push_to_hub=false - 5Read the cadence report out loud
lerobot-record prints an achieved-rate line after every episode and a session summary. If the effective cadence is below the fps target, fix it before recording anything real.
textCadence (episode 0): 29.88 Hz vs 30 Hz target - 600 ticks, 20.0 s measured 8/599 ticks over the 33.3 ms budget (work mean 18.4 ms, worst 45.1 ms) - 6Record the first real block under their own name
One dataset per operator, named after the operator. This is the workaround for the missing operator field, and it is free on day one. lerobot-record appends a date-time tag to the repo id unless you pass
--dataset.no_stamp=true, and the merge step below expects the name you actually typed.bashlerobot-record \ --robot.type=so100_follower --robot.port=/dev/ttyACM1 --robot.id=follower_a \ --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30} }" \ --teleop.type=so100_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_a \ --dataset.repo_id=my-org/pick-cube-anna \ --dataset.no_stamp=true \ --dataset.single_task="Pick up the red cube and put it in the bin" \ --dataset.num_episodes=30 \ --dataset.tags='["operator:anna","session:2026-08-24"]'
A LeRobot frame's timestamp is derived from its index, so a session that actually ran at 25 Hz still produces a dataset claiming 30 Hz. Nothing errors. The recorded motion is simply faster than reality, and a policy trained on it overshoots. A new operator on a laptop with two USB cameras is the likeliest person to trigger it, because the extra camera decode pushes the loop over budget. Read the cadence summary after every session, and if pacing headroom is near zero, drop a camera resolution first. Related: policy only works in one setup, dataset rejected.
LeRobot has no operator field, so build one out of repo ids
This surprises people, so state it plainly. In the LeRobot v3.0 format, meta/episodes holds per-episode records with fields such as episode_index, task_index, length, from_timestamp and to_timestamp. There is no demonstrator identity. DROID stores a collector ID per trajectory; LeRobot does not. Record five operators into one repo id and their data is mixed permanently.
- Give every operator their own
--dataset.repo_id, for examplemy-org/pick-cube-anna, with--dataset.no_stamp=trueso the name survives verbatim. - Add
--dataset.tagswith an operator tag so the provenance survives a push to the Hub. - Score each dataset separately with the length statistics above, and watch the three longest episodes of each.
- Delete the episodes that fail review:
lerobot-edit-dataset --repo_id my-org/pick-cube-anna --operation.type delete_episodes --operation.episode_indices "[3, 11, 27]" - Merge only the datasets that survived:
lerobot-edit-dataset --new_repo_id my-org/pick-cube-merged --operation.type merge --operation.repo_ids "['my-org/pick-cube-anna','my-org/pick-cube-chen']" - Keep the rejected datasets. They are how you check that your review process does anything.
If manual review does not scale, Demo-SCORE (Chen et al., 2025) automates the same decision: train an initial policy on everything, roll it out, train a classifier separating successful rollouts from failed ones, then filter the demonstrations with it. The paper reports over 15 to 35 percent higher absolute success rate than training on all the data, at the cost of robot time for the rollouts.
Getting from an untrained operator to a trained policy
You own the arm, cameras, machine and GPU. Everything above runs locally, and the only external dependency is the Hugging Face Hub, which you can turn off with --dataset.push_to_hub=false.
- Buy or build an SO-100 leader-follower pair, roughly 110 to 150 EUR per arm.
- Install LeRobot from the upstream repo and calibrate both arms.
- Run the two-hour curriculum above with each new operator.
- Record one dataset per operator, review, delete, merge.
- Train with
lerobot-train --policy.type=acton a 24 GB card, or rent one.
lerobot-train \
--dataset.repo_id=my-org/pick-cube-merged \
--policy.type=act \
--policy.device=cuda \
--output_dir=outputs/train/act_pick_cube \
--job_name=act_pick_cubeTime. Port discovery, calibration drift, camera indices that shift between reboots, an evening lost to a USB serial adapter. The upside: you keep every raw frame and owe nobody an account.
The platform takes hardware and GPU off the critical path. It does not take over the operator judgement. That part stays yours.
- Candidates can drive a real arm at /live with no signup, queue-based, which is enough to see whether someone has the patience before you onboard them.
- The desktop client records LeRobot-format datasets straight from a teleop session, so the recording step matches the manual path.
- Each operator's dataset lands separately and can be published to the public dataset directory or kept private.
- Training is a form: model, dataset, hyperparameters. The backend rents a GPU on a spot market by required VRAM and writes checkpoints to object storage.
- SmolVLA needs 30 episodes minimum, ACT and the three larger models need 50. That is your per-operator recording target.
- People looking for the work rather than running the pipeline start at /teleoperator.
| Tier | Models | Typical run | Cost per run |
|---|---|---|---|
| RTX 4090 or any 24 GB card | SmolVLA, ACT | 2 to 5 hours | about 1 to 3 USD |
| A100 80 GB or H100 80 GB | GR00T N1.7, GR00T N1.5, Pi0.5 | 3 to 6 hours | about 4 to 12 USD |
A 1 to 3 USD run is cheap enough to train one policy per operator and compare success rates directly, which is the measurement that settles the argument.
The per-operator training run is the honest version of all of this. Length statistics are a proxy; a trained policy evaluated on the real arm is the answer. At the prices on the 24 GB tier, running ACT on SO-100 once per operator is a rounding error against the recording time.


The other job: correcting a policy instead of demonstrating from scratch
Once a first policy exists, the job changes. BC-Z (Jang et al., CoRL 2021) ran this at scale: 7 operators across 12 robots collected 25,877 demonstrations, 125 hours of robot time. Of those, 11,108 were expert-only demonstrations seeding the initial policies and 14,769 were shared-autonomy episodes over 16 rounds, where the policy attempted the task and the human gripped an override switch to correct it. At equal episode count, the correction data helped.
BC-Z also produced the most useful operator metric in the literature: the intervention rate, the average takeovers per episode, correlates negatively with policy success rate. It is a live evaluation signal that costs nothing, because the operator is already there. LeRobot exposes the same mode through lerobot-rollout --strategy.type=dagger.
Log takeovers per episode from the first correction session. Two columns, no extra time, and you get a policy-quality trend line weeks before you have enough rollouts for a real success rate. See the teleoperation docs for how sessions work here.
Where remote operators and this platform do not help
Three limits, stated plainly, because pretending otherwise wastes money.
An operator compensates for lag with slow, over-damped increments, and that compensation is recorded as ground truth. RoboTurk stopped running teleoperation servers on cloud infrastructure and spawned them on machines in close physical proximity to the robots, to minimise the latency of the control commands sent to the arms. The same applies at inference time: the control loop is 20 ms per action step for ACT and up to 485 ms for Pi0.5, and a public-internet round trip on top turns a working policy into a hesitant one. Remote inference suits slow pick-and-place, not fast reactive motion.
- No amount of GPU fixes a bad demonstration. Fine-tuning reproduces what is in the data. If the operator missed the grasp 40% of the time, the policy will too.
- The platform does not judge your operators. There is no per-operator quality score in the product. The repo-id-per-operator discipline above is manual, and it is the part you cannot outsource.
- Diversity has to be deliberate. One operator in one room produces a policy that works in one room. DROID needed 50 collectors in 52 buildings for scene diversity, and no cloud service substitutes for that.
Still choosing a model for the dataset? The policy comparison puts the five trainable options side by side with parameters, GPU tier and minimum episodes, and the arena holds 85 VLA models with 332 benchmark results. On collection specifically, our data-collection guide and the record your first dataset walkthrough go deeper.
How long does it take to train a robot teleoperator?▾
Basic competence arrives fast. RoboTurk gave 54 remote participants a 5 minute tutorial plus one supervised hour before letting them collect unsupervised. For an SO-100 with a leader-follower pair, budget two hours: calibration, fifteen minutes of free driving, fifteen minutes driving from the camera feed only, five throwaway episodes, then a first real block of 30. Skill keeps improving after that through more controller rotation, not faster movement.
Does operator skill really change how well a policy trains?▾
Yes, by tens of percentage points. In the robomimic study, behavioral cloning on 100 demonstrations from two experienced operators scored 58.7% on Square, against 22.0% for the same budget from two inexperienced operators. On the easier Can task the gap was 83.3% against 56.7%. BC-RNN narrowed the Can gap to 7.3 points but left 26.7 open on Square.
Should I just collect more data instead of finding better operators?▾
Not blindly. In the same study, 200 demonstrations from one proficient operator scored 84.0% on Square with BC-RNN, higher than any 200-demonstration mixture containing a weak operator, and the 300-demonstration multi-human sets never beat the 200-demonstration single-operator sets on any task. Scale helps once quality is controlled, not instead.
How do I tell which operator recorded which episodes?▾
You cannot, after the fact. The LeRobot v3.0 per-episode metadata holds episode_index, task_index, length and timestamps, with no demonstrator identity. Record one dataset per operator with its own repo id, add an operator tag via --dataset.tags, review each separately, then merge the survivors with lerobot-edit-dataset --operation.type merge. DROID stores a collector ID per trajectory, which is what LeRobot would need to automate this.
What is the single cheapest quality check on an operator's data?▾
The spread of episode length. In the robomimic trajectory-length table the weaker tier took roughly twice as long per episode, but the standard deviation grew about five-fold on Can, from 29 frames to 148. Consistency is the signal. Compute the coefficient of variation per operator, then watch the three longest episodes before deleting anything.
Is remote teleoperation good enough for training data, or does the lag ruin it?▾
Good enough for slow tasks, with care. The RoboTurk user study found that poor network conditions, low bandwidth and high delay links, did not substantially affect remote users' ability to perform demonstrations successfully; the real-robot follow-up then collected over 111 hours across 54 remote users in one week. But that follow-up also moved teleoperation servers off cloud infrastructure onto machines close to the robots. The risk is subtler than failure: operators compensate for lag with slow over-damped motion, and that is recorded as ground truth. Test on the real network before recording a full block.
Drive a real robot arm from wherever you are
Operator work is the way into robot learning that needs no hardware of your own. See what the job involves and how the data you record gets used.
Become an operatorSources
- RoboTurk: A Crowdsourcing Platform for Robotic Skill Learning through Imitation (CoRL 2018)
- Scaling Robot Supervision to Hundreds of Hours with RoboTurk (IROS 2019)
- What Matters in Learning from Offline Human Demonstrations for Robot Manipulation (CoRL 2021)
- robomimic: What Matters in Learning from Offline Human Demonstrations (study page)
- BC-Z: Zero-Shot Task Generalization with Robotic Imitation Learning (CoRL 2021)
- DROID: A Large-Scale In-the-Wild Robot Manipulation Dataset
- DROID dataset project site and collection guide
- Curating Demonstrations using Online Experience (Demo-SCORE, 2025)
- LeRobot docs: Imitation Learning on Real-World Robots
- LeRobot docs: LeRobotDataset v3.0 format and metadata layout
- Hugging Face blog: LeRobot Community Datasets - The "ImageNet" of Robotics, When and How? (11 May 2025)
- lerobot source: DatasetRecordConfig defaults and the no_stamp flag
- lerobot source: lerobot-edit-dataset delete_episodes and merge operations
- huggingface/lerobot repository
- RoboTurk project site
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started