この記事はフィジカルAIxロボティクス Advent Calendar 2025 の 5日目の記事です。
「ロボット初心者がLeRobot SO-101に挑戦」シリーズの2回目となります。 模倣学習があと一歩というところで奮闘中なのですが、いったんQiitaで晒します。
前回の記事はこちら
準備
LeRobot は、スマートフォンのカメラ、ノートPC内蔵カメラ、外付けWebカメラなど、複数の映像キャプチャ方法に対応している。
カメラから効率的にフレームを記録するには、OpenCVCamera クラスまたは RealSenseCamera クラスを使用できる。
カメラを見つける方法
カメラを利用するには、まず カメラ識別子(ID) が必要。
自分のPCに接続されているカメラのインデックスを調べるには、次のスクリプトを実行。
lerobot-find-cameras opencv
outputs/captured_images に画像が保存される。
MacとiPhoneのカメラが認識しなかったが、
iPhoneの「設定」>「一般」>「AirPlayとHandoff」>「連係カメラ」をオンにしたら、カメラを認識するようになった。
セッティング
ロボットアームに消しゴムを左側のケースに移動させることを学習させる。
カメラを使ったテレオペレーション(遠隔操作)
模倣学習ではカメラを使ったテレオペレーションをする。
本番前に慣れる前に以下のコマンドを打つ。
※robot.camerasの「index_or_path」に、さきほど調べたカメラのIDを入れる。
lerobot-teleoperate \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90689241 \
--robot.id=my_awesome_follower_arm \
--robot.cameras="{ front: {type: opencv, index_or_path: 1, width: 1920, height: 1080, fps: 30}}" \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem5AB90691591 \
--teleop.id=my_awesome_leader_arm \
--display_data=true
Rerunというアプリケーションが立ち上がる。
(参考)rerunをデフォルトの画面構成に戻したい場合
Rerun はいろいろ動かしているとビュー配置が崩れたり、カメラが消えたりするので、デフォルト構成に戻す方法は以下。
左側の Blueprint パネルの右上にある「…」(三点メニュー) をクリックし、「Reset to heuristic blueprint」 を選択する。
これで全レイアウト(チャート・画像ビューなど)が初期状態に戻る。
データセットの記録
テレオペレーションに慣れたら、最初のデータセットを記録してみよう。
データセットのアップロードには Hugging Face Hub の機能を使用する。
もし Hub を使うのが初めての場合は、書き込み権限つきのアクセストークンを使って CLI からログインできるようにすること。
このトークンは Hugging Face の設定ページから生成できる。
https://huggingface.co/security-checkup?cookieId=2d182f05-78ef-4a82-a88e-21f4f7869575
CLI にトークンを追加するには、次のコマンドを実行。
huggingface-cli login --token ${HUGGINGFACE_TOKEN} --add-to-git-credential
次に、Hugging Face リポジトリ名を変数に保存。
HF_USER=$(hf auth whoami | head -n 1)
echo $HF_USER
これでデータセットを記録できるようになった。
データセットをHubにアップロードするには、以下のコマンドを実行する。
(もちろんロボットのポートなどは、データセットのレポジトリIDなどは自分のに修正すること)
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90689241 \
--robot.id=my_awesome_follower_arm \
--robot.cameras="{ front: {type: opencv, index_or_path: 1, width: 1920, height: 1080, fps: 30}}" \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem5AB90691591 \
--teleop.id=my_awesome_leader_arm \
--display_data=true \
--dataset.repo_id=tatsuya1970/record-test \
--dataset.root=./record-test-v3 \
--dataset.single_task="Grab the eraser" \
--dataset.num_episodes=20 \
--dataset.episode_time_s=30 \
--dataset.reset_time_s=10
コマンド説明
--dataset.episode_time_s=30
各データ収録エピソードの長さを指定する(デフォルトは 60 秒)。
--dataset.num_episodes=20
記録するエピソードの総数を指定する(デフォルトは 50)。
--dataset.reset_time_s=10
次のエピソードまでのインターバル
エラー
こんなエラーが出たら
FileExistsError: [Errno 17] File exists: 'record-test'
既存ファイルを消して取り直し
rm -rf record-test
途中から再開する場合
先ほどのコマンドの一番下に以下をつけて実行
--resume=true
つまり
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90689241 \
--robot.id=my_awesome_follower_arm \
--robot.cameras="{ front: {type: opencv, index_or_path: 1, width: 1920, height: 1080, fps: 30}}" \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem5AB90691591 \
--teleop.id=my_awesome_leader_arm \
--display_data=true \
--dataset.repo_id=tatsuya1970/record-test-v2 \
--dataset.root=./record-test \
--dataset.single_task="Grab the eraser" \
--dataset.num_episodes=20 \
--dataset.episode_time_s=30 \
--dataset.reset_time_s=10 \
--resume=true
※なお、
dataset.num_episodes は。「今から何回する」ということなので、注意。
例えば当初と同じ20にすると、今から20回記録することになる。
やり直しする場合
別のDataset を作成する。
(Hugging Face に空の Dataset を作る)
Hugging Faceの上部メニューの
「+ New」→「dataset」
Repo name を入力、
Private / Public はどちらでもOK(後で変えらる)
最後に「Create」 を押す。
ターミナルで、先ほどのデータセットを記録するコマンドをうつ。
つまり以下
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90689241 \
--robot.id=my_awesome_follower_arm \
--robot.cameras="{ front: {type: opencv, index_or_path: 1, width: 1920, height: 1080, fps: 30}}" \
--teleop.type=so101_leader \
--teleop.port=/dev/tty.usbmodem5AB90691591 \
--teleop.id=my_awesome_leader_arm \
--display_data=true \
--dataset.repo_id=tatsuya1970/record-test \
--dataset.root=./record-test \
--dataset.single_task="Grab the eraser" \
--dataset.num_episodes=20 \
--dataset.episode_time_s=30 \
--dataset.reset_time_s=10
もしこんなエラーが出たら
RevisionNotFoundError: Your dataset must be tagged with a codebase version.
Assuming _version_ is the codebase_version value in the info.json, you can run this........
Hugging Face データセットに codebase_version 用のタグがないということなので、以下のコマンド実行してタグをつける。
python - << 'EOF'
from huggingface_hub import HfApi
from lerobot.datasets.lerobot_dataset import CODEBASE_VERSION
repo_id = "tatsuya1970/record-test"
print("CODEBASE_VERSION =", CODEBASE_VERSION)
api = HfApi()
api.create_tag(
repo_id,
tag=CODEBASE_VERSION,
repo_type="dataset",
)
print("Tagged", repo_id, "with", CODEBASE_VERSION)
EOF
データセット
ローカルでは、データセットは次のフォルダに保存される:
~/.cache/huggingface/lerobot/{repo-id}
データ記録が終わると、データセットは自分の Hugging Face ページにアップロードされる
(例: https://huggingface.co/datasets/${HF_USER}/record-test )。
その URL は次のコマンドを実行することで取得できる。
echo https://huggingface.co/datasets/${HF_USER}/record-test
アップロードが済んだあとのエラー
アップロード済んだ後にエラーが出たら、
以下のプログラムで手動アップロード
python upload_dataset.py
from huggingface_hub import HfApi, create_repo
repo_id = "tatsuya1970/record-test"
folder_path = "./record-test"
api = HfApi()
# まだリポジトリがなければ作成(あっても OK)
create_repo(repo_id, repo_type="dataset", exist_ok=True)
api.upload_folder(
folder_path=folder_path,
repo_id=repo_id,
repo_type="dataset",
)
学習(Google Colab)
まず、学習中PCがスリープしないようにPCの設定をする。
いよいよ、収集したデータを模倣学習にて学習する。
私はGoogle Colab Pro(A100 GPU)を使用して学習を行った。
なお、Hagging Face上のチュートリアルのリンク先
https://colab.research.google.com/github/huggingface/notebooks/blob/main/lerobot/training-act.ipynb
は古いらしく、以下からは、ChatGPTに聞きながらやった。
Google Colab
Google Colabを開き、
まず、GPUの設定
Colab メニューから
「ランタイム」→「ランタイムのタイプを変更」
ハードウェア アクセラレータGPU「A100 GPU」を選択する。
Lerobot をインストールする。
!git clone https://github.com/huggingface/lerobot.git
%cd lerobot
!pip install -e .
依存関係の最新版を更新。
!pip install torch torchvision --upgrade
huggingface-hubをインストール(バージョン指定、Lerobot 0.4.x は 0.34〜1.0 未満しか対応していないため)
!pip install "huggingface-hub>=0.34.0,<1.0.0" --force-reinstall
Hugging Face にログイン
from huggingface_hub import login
login()
Hugging Face のアクセストークン(Write 以上、前に作ったもの)を貼り付けて Enter
学習
以下のコマンドを実行。
stepsはデフォルトで10万、今回は5万でやってみた。
!lerobot-train \
--dataset.repo_id=tatsuya1970/record-test \
--dataset.video_backend=pyav \
--batch_size=2 \
--num_workers=0 \
--policy.type=act \
--policy.device=cuda \
--steps=50000 \
--output_dir=/content/lerobot/outputs/train/fast_run0 \
--policy.repo_id=tatsuya1970/lerobot-fast-policy \
--policy.push_to_hub=true \
--wandb.enable=false
エラー
以下のエラーが出たら、
RevisionNotFoundError: Your dataset must be tagged with a codebase version.
LeRobot はローカルのデータセットのフォルダ内のmeta/info.json の "codebase_version" と同じ名前の タグ が、Hugging Face 上のデータセットに付いていないと、学習を始めてくれない。
例えば、"codebase_version": "v3.0"と記載の場合、Google Colabで以下のコマンドを打つ。
from huggingface_hub import HfApi
api = HfApi()
api.create_tag(
repo_id="tatsuya1970/record-test", # データセット名
tag="v3.0", # info.json の codebase_version と同じ
repo_type="dataset",
)
学習中のログ(例)
INFO 2025-11-30 04:57:50 ot_train.py:354 step:20K smpl:41K ep:137 epch:68.57 loss:0.120 grdn:26.451 lr:1.0e-05 updt_s:0.078 data_s:0.093
INFO 2025-11-30 04:58:24 ot_train.py:354 step:21K smpl:41K ep:138 epch:69.24 loss:0.114 grdn:25.154 lr:1.0e-05 updt_s:0.078 data_s:0.092
INFO 2025-11-30 04:58:59 ot_train.py:354 step:21K smpl:42K ep:140 epch:69.92 loss:0.112 grdn:24.538 lr:1.0e-05 updt_s:0.080 data_s:0.094
step — 学習ステップ数(反復回数)
smpl — 観測サンプル(フレーム)の累計数
ep — 擬似エピソードカウント
epch — エポック数(=何周したか)
loss — 損失(訓練誤差)
grdn — 勾配ノルム(gradient norm)
lr — 学習率(learning rate)
updt_s — 学習(モデル更新)にかかる時間 / step
data_s — データロードにかかる時間 / step
学習終了 (約3時間30分)
NFO 2025-12-04 08:21:18 ot_train.py:357 step:50K smpl:100K ep:111 epch:5.57 loss:0.122 grdn:12.082 lr:1.0e-05 updt_s:0.087 data_s:0.151
INFO 2025-12-04 08:21:18 ot_train.py:367 Checkpoint policy after step 50000
INFO 2025-12-04 08:21:19 ot_train.py:438 End of training
Processing Files (0 / 0) : | | 0.00B / 0.00B
New Data Upload : | | 0.00B / 0.00B
PCのスリープ設定をもとに戻す。
推論実行・ポリシー評価(ロボット制御)
改めてlerobot 環境を作る(Python 3.10)
conda deactivate # いったん抜ける(今 lerobot 環境の中なら)
conda env remove -n lerobot
conda create -n lerobot python=3.10 -y
conda activate lerobot
lerobotをインストール
pip install "lerobot[teleop]"
インストール確認
python -c "import lerobot, inspect; print('lerobot', lerobot.__version__); "
サーボモーターのSDKをインストール
pip install feetech-servo-sdk
古いデータセットのローカルフォルダやキャッシュが残っていると、LeRobot がデータを読み込む際にエラーになる場合があるので、以下を削除する。
rm -rf eval_fast_policy_so101
rm -rf ~/.cache/huggingface/lerobot/tatsuya1970/eval_fast_policy_so101
カメラをPCに接続し、以下のコマンドを実行
※robot.camerasの「index_or_path」には冒頭調べたカメラのIDを入れる。
lerobot-record \
--robot.type=so101_follower \
--robot.port=/dev/tty.usbmodem5AB90689241 \
--robot.id=my_awesome_follower_arm \
--robot.cameras='{front: {type: opencv, index_or_path: 1, width: 1920, height: 1080, fps: 30}}' \
--dataset.repo_id=tatsuya1970/eval_fast_policy_so101 \
--dataset.single_task="Grab the eraser" \
--dataset.num_episodes=5 \
--dataset.episode_time_s=30 \
--dataset.reset_time_s=0 \ #ゼロ超だと不具合になる
--dataset.push_to_hub=false \
--policy.path=tatsuya1970/lerobot-fast-policy \
--policy.device=mps
動いた!!
けど、あまり、うまく行かなかった。
データセットが少ない(20セット)のか、学習量が少ない(5万steps)のか、カメラの位置が悪いのか?
引き続き、試行錯誤します。
今日のSO-101。
— たつや (@tatsuya1970) December 4, 2025
消しゴムを掴んで左のケースに持っていくという模倣学習をしてて、昨日は全く動かなかったけど再度データセットを収録して学習し直したら、動いた!(データセット20、5万Step学習)
まだ、消しゴムを掴みそうで掴めないけど、大きな前進!… pic.twitter.com/i1joRlINqt
P.S.モーターが機能してるか調べるには
モータが機能してるか疑義がある場合、以下のコードをそのままターミナルへコピペしてエンター。
python - << 'EOF'
from scservo_sdk import *
import time
port = "/dev/tty.usbmodem5AB90689241"
baud = 1000000
portHandler = PortHandler(port)
packetHandler = PacketHandler(2.0)
portHandler.openPort()
portHandler.setBaudRate(baud)
print("Scanning for motors...")
for i in range(1, 20):
dxl_model, dxl_comm_result, dxl_error = packetHandler.ping(portHandler, i)
if dxl_comm_result == COMM_SUCCESS:
print(f"Found motor ID={i}, model={dxl_model}")
time.sleep(0.05)
portHandler.closePort()
EOF
これが以下の結果ならモーターは正常。
Found motor ID=1, model=2307
Found motor ID=2, model=2307
Found motor ID=3, model=2307
Found motor ID=4, model=2307
Found motor ID=5, model=2307
Found motor ID=6, model=2307
違ってたら、モーターIDを再度セットする。
セット方法はこちら
以上



