Maker ยท Technical Deep-Dive ยท Living Document

ML Desktop: LeRobot Setup & First Pi 5 Dataset

The training half of the pipeline, set up and proven end to end โ€” first entry in what will grow as SmolVLA work continues

Result: Pi 5 record โ†’ transfer โ†’ ML Desktop, proven working end to end. First real dataset off the new rig (28 episodes), GPU confirmed genuinely functional (no Blackwell issue this time), storage/repo policy decided. Next: train on it, then plan SmolVLA's actual data needs properly.

Current system architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Pi 5 (4GB) โ€” hostname "lab" โ€” 192.168.2.110                  โ”‚
โ”‚  User: assistant                                               โ”‚
โ”‚  Role: SO-101 rig host โ€” arms + cameras, recording             โ”‚
โ”‚  Replaces: "brain" (Pi 4, being phased out)                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚  scp (dataset transfer)
                          โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ML Desktop โ€” user iliya-radulov                                โ”‚
โ”‚  Role: GPU training (ACT now, SmolVLA next; also XTTS)          โ”‚
โ”‚  GPU: RTX 5060 Ti 16GB โ€” CUDA 13 stack confirmed working        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚  (planned) archive after training
                          โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Home server โ€” 192.168.2.42 โ€” always-on storage, Samba,        โ”‚
โ”‚  Wake-on-LAN target                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Also on the network:
- Mac โ€” largely superseded by the Pi 5 for this rig (its lack of
  native USB-A caused the camera-hub instability that motivated
  the migration)
- voice (Pi 4) โ€” voice trigger, Vosk STT + Piper TTS

lerobot install on the ML Desktop

Location: ~/Documents/github/active/so101-pickplace-project/lerobot
Venv:     lerobot/robot  (activate: source robot/bin/activate)
Installed: lerobot 0.6.2, torch 2.11.0+cu130, torchvision 0.26.0,
           full CUDA 13 stack (nvidia-cudnn-cu13, nvidia-cublas-13.1.0.3, etc.)
Also required: datasets (installed separately, not pulled in automatically)

GPU verification passed cleanly this time โ€” no Blackwell/sm_120 issue, unlike the original XTTS setup which needed a dedicated fix (full write-up). This venv's torch build already has native Blackwell support:

import torch
print(torch.__version__)          # 2.11.0+cu130
print(torch.cuda.is_available())  # True
x = torch.randn(3,3).cuda()       # works, no errors

Note: torchcodec fails to load on both the Pi and (likely) here too โ€” harmless, silently falls back to the pyav decoder, which works fine. The specific error (libnppicc.so.13: cannot open shared object file) is a missing NVIDIA library, irrelevant since pyav covers everything needed.

Repo structure

~/Documents/github/active/
โ”œโ”€โ”€ arm/                        (private โ€” full documentation)
โ”œโ”€โ”€ iliya-radulov/               (public โ€” profile repo)
โ”œโ”€โ”€ iliya-radulov.github.io/     (public โ€” portfolio site)
โ”œโ”€โ”€ my_db_project/               (public โ€” materials science DB, Stage 2)
โ”œโ”€โ”€ so101-pickplace-project/     (private โ€” THIS project)
โ”‚   โ”œโ”€โ”€ lerobot/                 (NEW today โ€” library clone + venv, gitignored)
โ”‚   โ”œโ”€โ”€ reports/
โ”‚   โ”œโ”€โ”€ roadmap/
โ”‚   โ”œโ”€โ”€ scripts/
โ”‚   โ”œโ”€โ”€ session-notes/
โ”‚   โ”œโ”€โ”€ figs/
โ”‚   โ”œโ”€โ”€ logs/
โ”‚   โ””โ”€โ”€ portfolio/
โ””โ”€โ”€ UselessTools/                (public โ€” utility projects)

Storage policy, decided today

.gitignore added to so101-pickplace-project today:

outputs/
lerobot/outputs/
*.mp4
*.parquet

First real Pi-5-hosted dataset

so101_pi5_act_validation โ€” 28 episodes, 16,758 frames. Schema: 7 positions ร— 4 orientations ร— 1 repetition, deliberately no repeats โ€” this run is pipeline validation, not intended as a robust trained checkpoint. Single-shot coverage trades trajectory-averaging robustness for full spatial breadth.

lerobot-record \
    --robot.type=so101_follower \
    --robot.port=/dev/ttyUSB1 \
    --robot.id=my_follower_arm \
    --robot.cameras='{"main": {"type": "opencv", "index_or_path": "/dev/video2", "width": 640, "height": 480, "fps": 30}, "gripper": {"type": "opencv", "index_or_path": "/dev/video0", "width": 320, "height": 240, "fps": 30}}' \
    --teleop.type=so101_leader \
    --teleop.port=/dev/ttyUSB0 \
    --teleop.id=my_leader_arm \
    --dataset.repo_id=local/so101_pi5_act_validation \
    --dataset.single_task="Pick up the object and place it in the target" \
    --dataset.num_episodes=28 \
    --dataset.episode_time_s=20 \
    --dataset.reset_time_s=8 \
    --dataset.push_to_hub=false

Note: no fourcc: MJPG in this config โ€” the Innomaker cameras reject MJPG negotiation via OpenCV entirely (set_ok=False, confirmed earlier on the Mac). Running raw format instead; this is fine on the Pi since each camera now has its own dedicated USB 3.0 port, with no bandwidth contention to work around.

A real gotcha: the folder name isn't what you think

lerobot-record appends a timestamp suffix to the actual folder name, even though a clean repo_id was passed in. The real path was so101_pi5_act_validation_20260905_160525, not the bare so101_pi5_act_validation used in the argument. This caused an initial LeRobotDataset lookup failure โ€” it tried the literal repo_id, didn't find a local match, then incorrectly attempted to resolve it against the Hugging Face Hub, producing a 401 error. Lesson: check the actual terminal output from lerobot-record for the real save path immediately after recording, rather than assuming the bare repo_id is the folder name.

Locations:

scp -r assistant@192.168.2.110:/home/assistant/.cache/huggingface/lerobot/local/so101_pi5_act_validation_20260905_160525 ~/.cache/huggingface/lerobot/local/

First transfer attempt was interrupted (Connection closed by 192.168.2.110 port 22) partway through; a second identical run completed successfully. Post-transfer verification (episode/frame count match) confirmed no corruption from the interrupted first attempt.

Housekeeping โ€” not yet done

10 leftover test folders remain on the Pi from earlier pipeline debugging (all named so101_pi5_validation_*, timestamps between 12:09โ€“13:52 on Sept 5) โ€” short validation runs made while chasing the connection/power issues, not real data. Safe to delete once confirmed unneeded:

# On the Pi, after double-checking none are wanted:
rm -rf ~/.cache/huggingface/lerobot/local/so101_pi5_validation_2026090*

Open questions โ€” carried forward, still genuinely unresolved

What should SmolVLA training data actually look like?

Unlike ACT (which benefits from dense position/orientation grids since it learns the task from scratch), SmolVLA starts from a pretrained VLA base with broad visual/language priors. Fine-tuning data needs likely shift toward:

Not yet decided: the concrete episode schema (how many tasks, how many episodes per task, position/orientation coverage per task) โ€” deliberately deferred to a dedicated planning session rather than decided in passing.

Does a checkpoint trained on SO-101 transfer to LeKiwi / XLeRobot?

Empirically partially tested, not fully resolved:

Immediate next steps, in order

  1. Delete the 10 leftover Pi test folders (optional housekeeping, low priority)
  2. Run ACT training on so101_pi5_act_validation (28 episodes) โ€” first real use of the RTX 5060 Ti for this project
  3. Once that validates the full pipeline (Pi record โ†’ transfer โ†’ Desktop train), move to the SmolVLA episode schema planning above โ€” a dedicated session, not a decide-in-passing task
  4. Retest LeKiwi cross-hardware transfer once physically assembled, with the standardized camera/calibration setup
Continued: the camera-framing issue that motivated some of the open questions above turned out to be the real blocker on this dataset's rollout performance, not the training pipeline. Full diagnosis, the fix, and quantified rollout results (86.3% trained / 53.6% novel positions): Camera Fix, Recording & Quantified Rollout Testing. The SmolVLA multi-task planning flagged as deferred above is now underway as part of a three-track roadmap: SO-101 Sim-to-Real Integration Roadmap.

This page will grow/chain forward as ACT training completes and SmolVLA work actually begins, rather than being rewritten from scratch each time.