はじめに
こんにちは!ABEJAでエンジニアをしている宇留嶋です。2025年5月にオープンソース化されたSO‑101ロボットアームとHugging FaceのLeRobotライブラリを活用し今回Vision‑Language‑Action(VLA)モデルSmolVLA をファインチューニングして「色付きキューブを所定エリアに運ぶ」タスクに挑戦しました。本記事では、データセット作成から学習・評価までの手順と結果をご紹介します。
SO‑101アームの組み立て・模倣学習やTPU製グリッパー検証については、以前公開した以下の記事もぜひご覧ください。
tech-blog.abeja.asia
tech-blog.abeja.asia
tech-blog.abeja.asia
SmolVLAの非同期推論はこちらの記事で検証しております。
tech-blog.abeja.asia
SmolVLAとは
SmolVLA
SmolVLAは小型で効率的なオープンソースのVision‑Language‑Actionモデルです。450Mパラメータで単一GPU/CPUでも学習・推論でき、巨大モデルの高コスト問題を避けることができます。LeRobotコミュニティデータの約2.29万エピソードだけで事前学習されており、層スキップや視覚トークン削減、フローマッチングで高速化しています。また非同期推論スタックにより「知覚 → 行動予測 → 実行」をパイプライン化し、高い制御レートを実現している点も特徴です。(arXiv , Hugging Face )
タスク設定とデータセット作成
タスク概要
今回タスクは以下を設定しました。
対象物:赤・青 2 色のキューブ(各 2 cm³)
目標:キューブを黒い四角形エリアの内部へ移動させる
タスク
環境
カメラは以下の3台を使用しました。
MacBook M3 内蔵カメラ
iPhone 14
InnoMaker UVCカメラ(SO-ARMのリストカメラとして利用)
カメラ位置は以下画像の通りです。
カメラ位置
データセット作成
データセット作成には30fps, 1エピソード30秒で記録しました。収集したデータはHugging Faceへ公開しました。
データの視覚的な確認には公式スペースのLeRobot Dataset Visualizer を活用すると便利です。
実際にデータセット作成に使用したコマンド
uv run python -m lerobot.record \
--robot.type = so101_follower \
--robot.port =" /dev/tty.usbmodem5A4B0468471 " \
--robot.cameras =" {
top: {type: opencv, index_or_path: 1, width: 640, height: 480},
iphone: {type: opencv, index_or_path: 2, width: 1280, height: 720},
wrist: {type: opencv, index_or_path: 0, width: 640, height: 360}
} " \
--robot.id = main_follower \
--dataset.repo_id =" repo_id "
--dataset.single_task =" Move the red cube into the black square area. "
--dataset.num_episodes = 5
--dataset.episode_time_s = 30
--dataset.reset_time_s = 5
--dataset.fps = 30
--dataset.video =true \
--dataset.push_to_hub =true \
--teleop.type = so101_leader \
--teleop.port =" /dev/tty.usbmodem5A4B0468211 "
--teleop.id = main_leader \
--display_data =true \
--play_sounds =true
今回作成したデータセット
LeRobot Dataset Visualizerを使った可視化
https://huggingface.co/spaces/lerobot/visualize_dataset?path=%2Fyuto-urushima%2Fso101_move_blue_cube_001_020%2Fepisode_0
データセットビューワ
テキストプロンプトはデータセットのメタデータとして meta/episodes.jsonl および meta/tasks.jsonl に、
"task": "Move the blue cube into the black square area."
という形で保存されます。
SmolVLA のファインチューニング
ベースモデル lerobot/smolvla_base を起点として、今回作成したデータセットでファインチューニングしました。主要パラメータは以下のとおりです。
学習ステップ数:20k
バッチサイズ:64
計算資源:Google Colab A100 × 1
コマンドは以下になります。
!python lerobot/src/lerobot/scripts/train.py \
--policy.path = lerobot/smolvla_base \
--dataset.repo_id =" yuto-urushima/so101_move_cube "
--batch_size = 64
--steps = 20000
--output_dir =" output_dir "
--job_name =" job_name "
--policy.device =" cuda "
--wandb.enable =" true "
--policy.repo_id =" repo_id "
スパイクはあるもののLossは下がっていました。
wandb log
ファインチューニングには約5時間かかりました。
モデルはsmolvla-move-cube にて公開しています。
評価と結果
評価はMacBook(Apple Silicon, mps)上でSmolVLAモデルを動作させて実施しました。
ファインチューニング済みモデルを SO‑101にデプロイし、各タスクを25エピソードづつテストを行いました。
以下実際にSmolVLAを使ってSO-ARMを動かすコマンドになります。
uv run python -m lerobot.record \
--robot.type = so101_follower \
--robot.port =" /dev/tty.usbmodem5A4B0468471 "
--robot.cameras =" {} "
--robot.id = main_follower \
--dataset.repo_id =" repo_id "
--dataset.single_task =" Move the red cube into the black square area. "
--dataset.num_episodes = 25
--dataset.episode_time_s = 30
--dataset.reset_time_s = 5
--dataset.fps = 30
--dataset.push_to_hub =true \
--policy.path =" yuto-urushima/smolvla-move-cube "
--policy.device =" mps "
--display_data =true
結果としては以下のように70%以上タスクを完了することができました。
キューブの色
検証回数
成功
成功率
赤
25
19
76%
青
25
18
72%
失敗ケースでは、
キューブを把持できない
episode timeをオーバーしてしまう
といったパターンが観察されました。
一度は把持に失敗しましたが、再試行で掴み直しに成功しました。データ収集時にキューブの位置を約1 cmずつ意図的にずらしていたことが、わずかな誤差への耐性を学習させ、結果としてこのリカバリ動作につながった可能性があります。
汎用性の評価
SmolVLAモデルの汎用性を検証するため、白色と青色のキューブを並べて「Move the white cube into the black square area.」というテキストプロンプトでタスクを実行しました。
結果は5回実行して5回ともアームは微動だにせず、汎用性は現れていませんでした。
実験結果の動画
VIDEO www.youtube.com
考察とまとめ
SmolVLAを自作データでファインチューニングした結果、SO‑101アームは赤・青キューブ移動タスクをそれぞれ76%、72%の成功率でこなせました。
以前公式チュートリアルの公開データセットをそのまま使い、環境も可能な限り再現してファインチューニングを行いましたが、タスクは一度も達成できませんでした。そこで今回学習用データの収集から推論までを同一環境・同一セッティングで統一し自前で高品質なデータを集めたところ、モデルは比較的安定してタスクをこなすようになりました。手間を惜しまずタスク固有のデータを整えることが最終的な性能に直結すると身をもって確認できました。
キューブの初期位置を少しずらしながらデータセットを作成しており、把持の再トライなど細かな挙動を学習させる上で一定の効果を持ったと推測しています。
一方で把持に失敗して再取得できない、episode timeをオーバーしてしまうといった典型的な失敗パターンがありました。
また白キューブタスクの実験によって今回のケースでは汎用性は見られませんでした。
リカバリ挙動を十分に含んだデータ、多様な言語表現・外観条件をカバーするデータを拡充すると改善するかもしれません。
今後はデータ拡充による再実験を行い、今回同期処理で動かした推論部分については、知覚・行動予測・実行をパイプライン化する非同期推論へ移行し評価する予定です。こうした改良を重ねることでSmolVLAのポテンシャルをより引き出していきたいと思います。
We Are Hiring!
ABEJAは、テクノロジーの社会実装に挑戦する仲間を募集しています。AI・ロボティクスの最前線で一緒にチャレンジしたい方は、ぜひ採用ページをご覧ください!
http://careers.abejainc.com