
บันทึกชุดข้อมูล LeRobot ที่ใช้งานได้ด้วย SO-100: การปรับเทียบ, การควบคุมระยะไกลแบบผู้นำ-ผู้ตาม, แฟล็กและค่าเริ่มต้นของ lerobot-record ที่แท้จริง, การตั้งค่ากล้อง, จำนวนตอน, และข้อบกพร่องที่ทำให้การทำงานล้มเหลว
หุ่นยนต์ SO-100 follower, แขนนำที่มีการออกแบบเดียวกัน และกล้อง USB สองตัวสามารถปรับแต่งนโยบายได้ภายในช่วงบ่าย แท่นทดสอบเดียวกันนี้สามารถสร้างหกสิบตอนที่ดูสมบูรณ์ในตัวจัดการไฟล์ได้อย่างง่ายดาย และสิ้นเปลืองการรัน GPU หกชั่วโมง ความแตกต่างไม่ค่อยอยู่ที่โมเดล แต่มันคือสิ่งที่เกิดขึ้นระหว่างเซอร์โวกับไฟล์ parquet
นี่คือเส้นทางแบบแมนนวล จากนั้นเป็นเส้นทางที่สั้นกว่า ทุกคำสั่งมาจาก lerobot 0.6.1 ซึ่งเปิดตัวเมื่อวันที่ 3 สิงหาคม 2026 และเป็นเวอร์ชันปัจจุบันบน PyPI มันย้ายไปยังจุดเข้าใช้งานคอนโซล ดังนั้นบทเรียนที่รัน python lerobot/scripts/control_robot.py อธิบายไฟล์ที่ไม่มีอยู่อีกต่อไปแล้ว
เวอร์ชันย่อ
- •lerobot 0.6.1 บันทึก v3.0; GR00T N1.7 และ N1.5 ต้องการ v2.1 ตกลงรูปแบบก่อนที่คุณจะกดบันทึก
- •สี่คำสั่ง: lerobot-find-port, lerobot-setup-motors, lerobot-calibrate, lerobot-record. ใช้ --robot.id และ --teleop.id เดียวกันจากการปรับเทียบในการบันทึก
- •ค่าเริ่มต้นจริง: 30 fps, 60 วินาทีต่อตอน, 60 วินาทีรีเซ็ต, 50 ตอน, ประมาณ 100 นาทีของเวลาจริง
- •จำนวนตอนขั้นต่ำที่นี่: 30 สำหรับ SmolVLA, 50 สำหรับที่เหลือ
- •ความหลากหลายสำคัญกว่าปริมาณ ชุดข้อมูลล้มเหลวจากสี่สิ่ง: ดัชนีกล้องสลับกัน, เฟรมที่หลุดหายหรือค้าง, ข้อต่อที่จอดอยู่ที่ขีดจำกัด, สตริงงานที่อ่านไม่ได้
สิ่งที่เซสชันการบันทึกจับภาพได้
ชุดข้อมูล LeRobot dataset ไม่ใช่โฟลเดอร์ของวิดีโอ แต่เป็นตารางที่จัดทำดัชนีตามเวลาพร้อมวิดีโอแนบ: ทุกๆ รอบการควบคุมจะเขียนหนึ่งแถวซึ่งประกอบด้วยการกระทำที่สั่งการ สถานะที่ผู้ติดตามไปถึง หนึ่งเฟรมต่อกล้อง การประทับเวลา และดัชนี นโยบายจะเห็นเฉพาะคอลัมน์เหล่านั้นเท่านั้น โครงสร้างของ lerobot/svla_so100_pickplace, อ่านจาก meta/info.json ของมัน
| คุณสมบัติ | ชนิดข้อมูล | รูปร่าง | คำอธิบาย |
|---|---|---|---|
| action | float32 | [6] | เป้าหมายข้อต่อจากแขนผู้นำ |
| observation.state | float32 | [6] | ตำแหน่งข้อต่อที่ผู้ติดตามไปถึง |
| observation.images.top | video | [480, 640, 3] | กล้องฉาก, MP4 (av1 ที่นี่) |
| observation.images.wrist | video | [480, 640, 3] | กล้องข้อมือ, อัตราเดียวกัน |
| timestamp | float32 | [1] | วินาทีตั้งแต่เริ่มต้นตอน |
| frame_index, episode_index, index, task_index | int64 | [1] | ข้อมูลการบันทึกที่สร้างขึ้นอัตโนมัติ |
ข้อต่อคือ main_shoulder_pan, main_shoulder_lift, main_elbow_flex, main_wrist_flex, main_wrist_roll และ main_gripper: ซึ่งเป็น องศาอิสระ หกข้อของ SO-100 การกระทำและสถานะมีรูปร่างเหมือนกันเนื่องจาก การควบคุมระยะไกลแบบผู้นำ-ผู้ตาม บันทึกเป้าหมายและตำแหน่งที่ไปถึงในขั้นตอนถัดไป ช่องว่างนั้นคือข้อมูล: ที่ซึ่งแขนต่อสู้กับแรงโน้มถ่วงหรือวัตถุที่ติดอยู่ สตริงเหล่านั้นเป็นของชุดข้อมูลนั้น เซสชันที่บันทึกด้วย 0.6.1 ในวันนี้จะเขียน shoulder_pan.pos ไปจนถึง gripper.pos, ID 1 ถึง 6 บนบัส: ข้อต่อหกข้อเดียวกัน, คีย์ต่างกัน, ซึ่งมีความสำคัญในขณะที่การกำหนดค่าอ้างถึงคุณสมบัติด้วยชื่อ
ชุดข้อมูลนั้นมี 50 ตอน และ 19,631 เฟรมที่ 30 fps: ประมาณ 393 เฟรม หรือ 13 วินาทีต่อตอน หากของคุณเฉลี่ยหนึ่งนาที แสดงว่าคุณกำลังทำสิ่งที่ยากขึ้น หรือบันทึกเวลาที่ไม่มีการใช้งานที่ปลายทั้งสองข้าง

สิ่งที่คุณต้องมีบนโต๊ะทำงาน
| รายการ | รายละเอียด | หมายเหตุ |
|---|---|---|
| แขนผู้ตาม | SO-100, เซอร์โว Feetech STS3215 หกตัว | ประมาณ 110 ถึง 150 EUR สำหรับชิ้นส่วน |
| แขนผู้นำ | SO-100 ตัวที่สอง, ถอดเฟืองออก | ถอดเฟืองออกจากมอเตอร์ผู้นำทั้งหกตัว: ใช้เฉพาะตัวเข้ารหัส, ลดแรงเสียดทาน |
| แหล่งจ่ายไฟ | ตรงกับรุ่น STS3215 7.4 V ในรายการวัสดุ | ดูคำเตือนด้านล่าง |
| กล้อง | กล้อง USB สองตัว, 640x480 ที่ 30 fps | หนึ่งตัวสำหรับมุมมองฉาก, หนึ่งตัวบนข้อมือ |
| โฮสต์ | Python 3.12 หรือใหม่กว่า, ffmpeg | requires-python >= 3.12 |
| บัญชี Hub | Hugging Face write token | optional with --dataset.push_to_hub=false |
STS3215 มีสองเวอร์ชัน: SO-ARM100 README ระบุว่าเวอร์ชัน 7.4 V มีแรงบิดหยุดนิ่ง 16.5 kg.cm เมื่อวัดที่ 6 V และเวอร์ชัน 12 V มีแรงบิด 30 kg.cm และระบุว่าการใช้มอเตอร์ 12 V หมายถึงการซื้อแหล่งจ่ายไฟ 12 V 5 A+ แทนที่จะเป็น 5 V รายการวัสดุระบุเซอร์โว 7.4 V การจ่ายไฟ 12 V ให้กับเซอร์โวที่ระบุ 7.4 V จะทำให้เสียหาย ดังนั้นควรอ่านฉลากมอเตอร์ก่อนที่คุณจะต่อสายใดๆ เซอร์โวไม่ตอบสนอง
หากแขนกลยังไม่ได้ประกอบ นั่นเป็นอีกเรื่องหนึ่ง: เริ่มต้นที่ เริ่มต้นใช้งาน SO-100 และ คู่มือการตั้งค่า SO-100 ฉบับสมบูรณ์. หากคุณยังไม่ได้ซื้ออะไร ให้อ่าน การเปรียบเทียบ SO-100 กับ SO-101 ก่อน: SO-101 เป็นรุ่นปรับปรุงใหม่ที่มีการเดินสายที่ดีขึ้นและไม่มีขั้นตอนการถอดเฟือง และขั้นตอนการบันทึกข้อมูลก็เหมือนกัน
ติดตั้ง lerobot 0.6.1
conda create -y -n lerobot python=3.12
conda activate lerobot
# TorchCodec is the default video decoder and needs ffmpeg
conda install ffmpeg -c conda-forge
# core_scripts = dataset + hardware + viz extras (record, replay, calibrate)
# feetech = SDK for the STS3215 bus servos in the SO-100
pip install 'lerobot[core_scripts,feetech]'
lerobot-infoส่วนเสริมมักทำให้คนสับสนมากที่สุด pip install lerobot ติดตั้งเฉพาะส่วนประกอบหลักของ ML เท่านั้น ไม่ใช่ส่วนที่สื่อสารกับหุ่นยนต์ แขนกล Koch ต้องการ dynamixel แทน feetech. หากเชลล์ของคุณไม่รู้จัก lerobot-record นี่คือเหตุผล
พอร์ต, ID มอเตอร์ และการปรับเทียบ
มีสามขั้นตอนที่ต้องทำเพียงครั้งเดียวเพื่อเชื่อมต่อชิ้นส่วนต่างๆ เข้ากับวงจร teleop ที่ใช้งานได้ ช่วยให้ policy ที่ฝึกบนแขนของคุณสามารถทำงานบนแขนของคนอื่นได้ โดยจะแมปค่า encoder ดิบเข้ากับข้อกำหนดร่วมของข้อต่อ
- 1ค้นหาพอร์ต USB ของแขนแต่ละข้าง
รันคำสั่งนี้โดยเสียบแขนทั้งสองข้างไว้ ถอดปลั๊กแขนที่คุณต้องการระบุเมื่อได้รับแจ้ง และจดบันทึกว่าพอร์ตใดหายไป บน Linux คุณอาจต้องใช้
sudo chmod 666 /dev/ttyACM0.bashlerobot-find-port # Finding all available ports for the MotorsBus. # Ports before disconnecting: ['/dev/ttyACM0', '/dev/ttyACM1'] # Remove the USB cable from your MotorsBus and press Enter when done. # The port of this MotorsBus is '/dev/ttyACM1' # Reconnect the USB cable. - 2เขียน ID มอเตอร์และอัตราบอด
ID จะถูกเขียนทีละมอเตอร์ และเอกสารระบุไว้อย่างเคร่งครัดว่า: ให้เชื่อมต่อมอเตอร์เพียงตัวเดียวเข้ากับบอร์ดควบคุม โดยยังไม่ต้องต่อแบบ daisy-chain กับตัวอื่น สคริปต์จะเดินย้อนกลับไปตามสายโซ่ โดยจะแจ้งให้ระบุ gripper ก่อนและกำหนด ID เป็น 6 จากนั้นเป็น wrist_roll เป็น 5 ไล่ลงไปจนถึง shoulder_pan เป็น 1 ทำขั้นตอนนี้ก่อนการประกอบ
bashlerobot-setup-motors \ --robot.type=so100_follower \ --robot.port=/dev/ttyACM0 lerobot-setup-motors \ --teleop.type=so100_leader \ --teleop.port=/dev/ttyACM1 - 3ปรับเทียบแขนทั้งสองข้าง
ขยับข้อต่อทุกข้อไปยังตำแหน่งกึ่งกลางของช่วงการเคลื่อนที่ กด Enter จากนั้นกวาดแต่ละข้อต่อให้เคลื่อนที่ตลอดช่วง
idจะกลายเป็นชื่อไฟล์โปรไฟล์bashlerobot-calibrate \ --robot.type=so100_follower \ --robot.port=/dev/ttyACM0 \ --robot.id=my_so100_follower lerobot-calibrate \ --teleop.type=so100_leader \ --teleop.port=/dev/ttyACM1 \ --teleop.id=my_so100_leader - 4ควบคุมระยะไกลก่อนบันทึกสิ่งใดๆ
การทดสอบการยอมรับสำหรับทุกสิ่งที่กล่าวมาข้างต้น หากการควบคุมระยะไกลกระตุก, กลับด้าน, หรือข้อต่อใดข้อหนึ่งไม่ทำงาน การบันทึกจะเก็บข้อมูลนั้นไว้ใน 50 ตอน
bashlerobot-teleoperate \ --robot.type=so100_follower \ --robot.port=/dev/ttyACM0 \ --robot.id=my_so100_follower \ --teleop.type=so100_leader \ --teleop.port=/dev/ttyACM1 \ --teleop.id=my_so100_leader \ --display_data=true
โปรไฟล์จะถูกเก็บไว้ที่ $HF_LEROBOT_CALIBRATION ซึ่งโดยค่าเริ่มต้นคือ ~/.cache/huggingface/lerobot/calibration และ id จะเป็นคีย์สำหรับค้นหา หากคุณให้ lerobot-record ด้วย ID ที่ปรับเทียบแล้ว มันจะเสนอให้กด Enter เพื่อใช้โปรไฟล์เดิมซ้ำ หรือกด c เพื่อทำใหม่ หากให้ ID ที่ไม่รู้จัก จะไม่มีไฟล์อยู่ ดังนั้นมันจะเข้าสู่โหมดการปรับเทียบกลางคัน
กล้องเป็นตัวกำหนดว่านโยบายเห็นอะไร
lerobot-find-cameras opencv # or: lerobot-find-cameras realsense
# --- Detected Cameras ---
# Camera #0:
# Name: OpenCV Camera @ 0
# Type: OpenCV
# Id: 0
# Backend api: AVFOUNDATION
# Default stream profile:
# Format: 16.0
# Width: 1920
# Height: 1080
# Fps: 15.0มุมมองสองแบบ และตำแหน่งที่ตั้งมีความสำคัญ: กล้องฉากแบบตายตัวที่ครอบคลุมพื้นที่ทำงาน และกล้องข้อมือที่อยู่ใกล้ ส่วนปลายแขนกล ซึ่งแสดงสิ่งที่กริปเปอร์กำลังจะสัมผัส รายการตรวจสอบชุดข้อมูลชุมชนของ LeRobot แนะนำให้ใช้มุมมองสองแบบที่ความละเอียด 480x640 / 720p หรือดีกว่า โดยมีพื้นหลังคงที่ แสงสว่างคงที่และเป็นกลาง และแขนนำและอวัยวะของมนุษย์อยู่นอกเฟรม คู่มือการบันทึกข้อมูลยังเพิ่มกฎง่ายๆ ว่า: คุณควรจะสามารถทำงานนั้นได้ด้วยตัวเองโดยดูจากภาพกล้องเท่านั้น
ดัชนี OpenCV มาจากลำดับการแจงนับ ดังนั้นการรีบูตหรือเสียบใหม่สามารถทำให้ดัชนี 0 และ 2 สลับตำแหน่งกัน และวางมุมมองข้อมือไว้ในช่องบนสุดตลอดเซสชัน lerobot กล่าวเองว่าคลาสกล้องของมันรับทั้ง device path และจำนวนเต็ม และเตือนว่าดัชนีไม่เสถียรเมื่อมีการรีบูตหรือเปลี่ยนพอร์ต โดยเฉพาะบน Linux ชี้ index_or_path ไปยัง udev symlink ภายใต้ /dev/v4l/by-id/ ซึ่งจะตามอุปกรณ์แทนที่จะเป็นลำดับการแจงนับ นี่เป็นวิธีที่พบบ่อยที่สุดที่ทำให้ชุดข้อมูลไม่สอดคล้องกันภายใน และการฝึกอบรมไม่สามารถแก้ไขได้ ไม่พบกล้อง
คำสั่ง record และแฟล็กทุกตัว
HF_USER=$(NO_COLOR=1 hf auth whoami | awk -F': *' 'NR==1 {print $2}')
lerobot-record \
--robot.type=so100_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=my_so100_follower \
--robot.cameras="{ top: {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/ttyACM1 \
--teleop.id=my_so100_leader \
--display_data=true \
--dataset.repo_id=${HF_USER}/so100_pick_cube \
--dataset.single_task="Pick the red cube and drop it in the box" \
--dataset.num_episodes=50 \
--dataset.fps=30 \
--dataset.episode_time_s=25 \
--dataset.reset_time_s=10 \
--dataset.streaming_encoding=true \
--dataset.encoder_threads=2ค่าเริ่มต้นด้านล่างมาจาก src/lerobot/configs/dataset.py บน main ไม่ใช่จากบทช่วยสอน หลายค่าไม่ใช่สิ่งที่คนส่วนใหญ่คิด
| แฟล็ก | ค่าเริ่มต้น | หน้าที่ |
|---|---|---|
| --dataset.repo_id | ว่างเปล่า | ชื่อ; มีการเพิ่มการประทับเวลาโดยค่าเริ่มต้น |
| --dataset.single_task | ว่างเปล่า | สตริงงานที่จัดเก็บไว้ในทุกตอน |
| --dataset.root | $HF_LEROBOT_HOME/repo_id | พาธสำหรับเขียน, ค่าเริ่มต้น ~/.cache/huggingface/lerobot/ |
| --dataset.fps | 30 | อัตราการวนซ้ำควบคุมและอัตราเฟรมของชุดข้อมูล |
| --dataset.episode_time_s | 60 | วินาทีก่อนที่ตอนจะดำเนินไปโดยอัตโนมัติ |
| --dataset.reset_time_s | 60 | รีเซ็ตฉาก; แขนเคลื่อนที่, ไม่มีอะไรถูกจัดเก็บ |
| --dataset.num_episodes | 50 | จำนวนตอนที่บันทึกในเซสชันนี้ |
| --dataset.push_to_hub | true | อัปโหลดเมื่อสิ้นสุดเซสชัน; false จะเก็บไว้ในเครื่อง |
| --dataset.streaming_encoding | false ใน dataclass, true ในตารางเอกสาร | เข้ารหัสระหว่างการจับภาพ; กำหนดค่าอย่างชัดเจน |
| --dataset.encoder_queue_maxsize | 30 | เฟรมที่บัฟเฟอร์ต่อกล้อง, ประมาณ 1 วินาทีที่ 30 fps |
| --dataset.encoder_threads | null (โคเดกเป็นผู้ตัดสินใจ) | เธรดต่อตัวเข้ารหัส; ลดลงหากการจับภาพกระตุก |
| --dataset.no_stamp | false | เก็บ repo_id ให้ตรงตามที่พิมพ์ |
| --resume | false | เพิ่มข้อมูลลงในชุดข้อมูลที่มีอยู่; ต้องใช้ --dataset.root |
ชุดข้อมูลของคุณไม่ได้ชื่อตามที่คุณพิมพ์ lerobot จะเพิ่มแท็กวันที่-เวลาเข้าไป ดังนั้น so100_pick_cube จะกลายเป็น so100_pick_cube_20260823_141530 ใช้ --dataset.no_stamp=true เพื่อให้ได้ชื่อที่คงที่ การดำเนินการต่อจะนับส่วนที่เพิ่ม ไม่ใช่ยอดรวม เมื่อใช้ --resume=true, --dataset.num_episodes จะนับจำนวน ตอนที่เพิ่มขึ้น และ --dataset.root จะกลายเป็นสิ่งที่จำเป็น หากขอ 50 ตอนจากชุดข้อมูลที่มี 30 ตอน คุณจะได้ 80 ตอน
การควบคุมด้วยคีย์บอร์ดระหว่างเซสชัน
- ลูกศรขวา หรือ
n: จบตอนหรือรีเซ็ตเฟสก่อนกำหนด เป็นปุ่มที่คุณใช้บ่อยที่สุด เพราะการจับที่สะอาดแทบไม่เคยต้องใช้เวลาถึง 25 วินาที - ลูกศรซ้าย หรือ
r: ทิ้งตอนนั้นแล้วทำใหม่ การบันทึกที่ไม่ดีไม่มีค่าใช้จ่ายตอนนี้ แต่จะมีค่าใช้จ่ายมากในภายหลัง - Escape หรือ
q: หยุดเซสชัน, สิ้นสุดการเข้ารหัส, อัปโหลด - สิ่งเหล่านี้ใช้งานได้บน X11, Wayland และ headless SSH: โดยไม่มีแบ็กเอนด์คีย์สากล lerobot-record จะอ่านคีย์เดียวกันจากเทอร์มินัลควบคุม ตัวอักษรจะยังคงใช้งานได้แม้ในลิงก์ SSH ที่มีความหน่วง ซึ่งลำดับลูกศรอาจแยกออกจากกัน
- การควบคุมระยะไกลด้วยคีย์บอร์ดนั้นแตกต่างกันและจำเป็นต้องมีแบ็กเอนด์สากล: X11, Windows หรือ macOS ที่มี Accessibility
จำนวนตอน และลักษณะของตอนที่ดี
คู่มือการบันทึกแนะนำอย่างน้อย 50 ตอนสำหรับงานแรก โดยประมาณ 10 ตอนต่อตำแหน่งวัตถุ หน้าข้อมูลนโยบาย ระบุจำนวนขั้นต่ำต่อโมเดล ซึ่งหากต่ำกว่านั้น การรันจะไม่คุ้มค่ากับเวลา GPU
| นโยบาย | จำนวนตอนขั้นต่ำ | รูปแบบชุดข้อมูล | ระดับ GPU | ค่าใช้จ่ายต่อการรัน |
|---|---|---|---|---|
| SmolVLA | 30 | LeRobot v3.0 | RTX 4090 or any 24 GB card | about 1 to 3 USD |
| ACT | 50 | LeRobot v3.0 | RTX 4090 or any 24 GB card | about 1 to 3 USD |
| GR00T N1.7 | 50 | LeRobot v2.0 or v2.1 | A100 80 GB or H100 80 GB | about 4 to 12 USD |
| GR00T N1.5 | 50 | LeRobot v2.0 or v2.1 | A100 80 GB or H100 80 GB | about 4 to 12 USD |
| Pi0.5 | 50 | LeRobot v3.0 | A100 80 GB or H100 80 GB | about 4 to 12 USD |
คำถามที่ดีกว่าคือ ควรมีจำนวนเท่าไรและของอะไร Data Scaling Laws in Imitation Learning for Robotic Manipulation (Lin และคณะ, 2024) ได้รวบรวมการสาธิตกว่า 40,000 ครั้ง และดำเนินการทดสอบในโลกจริงมากกว่า 15,000 ครั้ง การสรุปผลเป็นไปตามความสัมพันธ์แบบกฎกำลังโดยประมาณกับจำนวนสภาพแวดล้อมและวัตถุ และเมื่อเกินเกณฑ์ที่กำหนดต่อสภาพแวดล้อมหรือวัตถุ การสาธิตเพิ่มเติมจะมีผลน้อยมาก สำหรับการทดสอบหนึ่งครั้ง: ให้ย้ายวัตถุ เปลี่ยนแสง สลับลูกบาศก์ แทนที่จะทำซ้ำการสาธิตเดิม
- วิถีการเคลื่อนที่ของข้อต่อแบบต่อเนื่องที่เซอร์โวสามารถทำซ้ำได้ ไม่เหมือนการใช้คีย์บอร์ดหรือเกมแพด
- การกระทำและสถานะใช้ข้อตกลงพิกัดร่วมกัน ดังนั้นนโยบายจึงเรียนรู้เป้าหมายที่สามารถสั่งการได้โดยตรง
- ตอนละ 25 วินาที บวกกับการรีเซ็ต 10 วินาที จะได้ประมาณ 100 ตอนต่อชั่วโมง
- ผู้ควบคุมจะรู้สึกได้เมื่อ follower หยุดชะงักหรือติดขัด ดังนั้นข้อผิดพลาดจะปรากฏขึ้นก่อนที่จะมีการบันทึกข้อมูล
- แขนกลที่สองจะเพิ่มค่าใช้จ่ายชิ้นส่วนประมาณสองเท่า
- การสาธิตจะสืบทอดพฤติกรรมของผู้ควบคุม; Mandlekar และคณะ พบว่าคุณภาพของนโยบายขึ้นอยู่กับคุณภาพของการสาธิตอย่างมาก
- Leader จะถูกสุ่มตัวอย่างที่อัตราการวนซ้ำ ดังนั้นการหยุดชั่วคราวจะกลายเป็นแถวที่เกือบจะเหมือนกัน ซึ่งสอนให้นโยบายรอ
- ไม่มีสิ่งใดบังคับใช้ความสอดคล้องกันระหว่างเซสชัน: กล้องที่ขยับไป 5 ซม. คือการเปลี่ยนแปลงการกระจายข้อมูลที่ซ่อนอยู่
ตอนที่ดีคือตอนที่น่าเบื่อ: ท่าเริ่มต้นที่ทำซ้ำได้, ทำสิ่งเดียวเสร็จ, จบลงเมื่อวัตถุอยู่ในถัง, สตริงงานมีความยาว 25 ถึง 50 ตัวอักษรตามที่รายการตรวจสอบแนะนำ Pick the red cube and drop it in the box เป็นสตริงงาน; task1 เป็นรูปแบบที่ไม่พึงประสงค์ที่รายการตรวจสอบระบุไว้อย่างชัดเจน คำอธิบายประกอบที่คลุมเครือเป็นปัญหาอันดับต้นๆ และมีความสำคัญที่สุดสำหรับ โมเดลการมองเห็น-ภาษา-การกระทำ โดยที่สตริงเป็นอินพุตของโมเดล ไม่ใช่ชื่อไฟล์
ข้อบกพร่องที่ทำลายชุดข้อมูลอย่างเงียบๆ
ไม่มีข้อบกพร่องใดที่ทำให้เกิดข้อยกเว้น ทุกข้อบกพร่องจะยังคงอยู่ในการฝึกอบรม โดยปรากฏเป็นกราฟการสูญเสียที่ดูปกติและหุ่นยนต์ที่ไม่ทำงาน ตรวจสอบในขณะที่ตั้งค่าฉาก
| ข้อบกพร่อง | ลักษณะที่ปรากฏ | ที่มา | วิธีตรวจจับ |
|---|---|---|---|
| มุมมองกล้องสลับกัน | ภาพจากกล้องข้อมืออยู่ใต้คีย์ด้านบน | การกำหนดดัชนีใหม่หลังจากการเสียบใหม่ | lerobot-find-cameras ในแต่ละเซสชัน; ใช้พาธแบบ by-id |
| เฟรมค้าง | ภาพเดียวกันสำหรับหลายสิบแถว | กล้องหยุดส่งข้อมูล; ลูปจะทำซ้ำเฟรมสุดท้าย | ตรวจสอบใน lerobot-dataset-viz |
| เฟรมตกหล่น | จำนวนแถวน้อยกว่า fps คูณด้วยวินาที | คิวล้น, ทิ้งข้อมูลแทนที่จะบล็อก | 'Encoder queue full' ในบันทึก; จำนวนแถวเทียบกับ fps คูณด้วยระยะเวลา |
| ข้อต่อถึงขีดจำกัด | ข้อต่อหนึ่งราบเรียบที่ค่าต่ำสุดหรือสูงสุด | ช่วงของตัวนำเกินช่วงของตัวตาม, หรือท่ากลางที่ไม่ดี | per-joint min/max in ds.meta.stats; lerobot-find-joint-limits ล่วงหน้า |
| ภาพและการกระทำไม่ตรงกัน | นโยบายคาดการณ์ล่วงหน้าหรือล่าช้า | กล้องมี fps ที่แตกต่างจากลูป | รักษากล้องทุกตัวที่ --dataset.fps |
| เวลาที่ไม่มีการใช้งาน | การกระทำซ้ำๆ กันเป็นแถวยาว | ผู้ปฏิบัติงานหยุดชั่วคราวขณะที่เครื่องบันทึกกำลังทำงาน | สัดส่วนของแถวการกระทำที่เหมือนกันติดต่อกัน |
| สตริงงานที่ใช้ไม่ได้ | task1, demo2, test | พิมพ์เร็ว | meta/tasks.parquet in v3.0 (it was meta/tasks.jsonl in v2.1); แก้ไขด้วย lerobot-edit-dataset modify_tasks |
ตัวเข้ารหัสจะเก็บคิวแบบจำกัดต่อกล้องแต่ละตัว โดยค่าเริ่มต้นคือ 30 เฟรม เมื่อไม่สามารถประมวลผลได้ทัน เฟรมจะถูกทิ้งแทนที่จะถูกบล็อก: การจับภาพจะดำเนินต่อไปและไม่มีอะไรขัดข้อง คุณจะได้รับข้อความ Encoder queue full for {camera}, dropped N frame(s) และยอดรวมต่อกล้องเมื่อสิ้นสุดตอน เกณฑ์ของ lerobot: ประมาณ 5 เปอร์เซ็นต์ที่หายไปหมายถึงระบบทำงานเกินกำลัง, 2 เปอร์เซ็นต์เป็นโหลดที่คาดไว้เมื่อเริ่มต้น วิธีแก้ไขตามลำดับ: --display_data=false, ลด --dataset.encoder_threads, vcodec=h264, ปิดการสตรีมมิ่ง
ข้อควรระวัง: ตารางในคู่มือการเข้ารหัสแบบสตรีมมิ่งระบุค่าเริ่มต้นเป็น True, ในขณะที่ dataclass บน main อ่านว่า streaming_encoding: bool = False. เอกสารและโค้ดไม่ตรงกัน ดังนั้นควรกำหนดค่าอย่างชัดเจน; lerobot จะบันทึกคำแนะนำเมื่อใดก็ตามที่เริ่มต้นโดยไม่ได้เปิดแฟล็กนี้
ตรวจสอบชุดข้อมูลก่อนเช่า GPU
การทดสอบการยอมรับจากเอกสาร: เปรียบเทียบระยะเวลาวิดีโอกับระยะเวลาของตอนที่ CLI รายงาน และยืนยันว่าจำนวนแถวเท่ากับ fps คูณด้วยระยะเวลา ต่อตอน ไม่ใช่ยอดรวม
from lerobot.datasets import LeRobotDataset
ds = LeRobotDataset("your-user/so100_pick_cube_20260823_141530")
print("fps:", ds.fps, "frames:", ds.num_frames)
# In v3.0 the per-episode records live in meta/episodes/ as chunked parquet:
# lengths, tasks and offsets into the shared parquet and mp4 shards.
# They load through the datasets stack, so this is a datasets.Dataset --
# use .column_names and integer indexing, not pandas .columns / .head().
eps = ds.meta.episodes
print(eps.column_names)
print(eps[0])
# Global feature statistics, including per-joint min and max.
# A joint whose min equals its max never moved. A joint sitting at a
# hard limit for most of the run is the one that will stall the policy.
print(ds.meta.stats["observation.state"])จากนั้นให้ดูที่มัน lerobot-dataset-viz จะเล่นตอนหนึ่งซ้ำแบบเฟรมต่อเฟรมพร้อมรอยการเคลื่อนที่ของข้อต่อข้างมุมมองกล้อง ใน Rerun หรือ Foxglove กล้องที่สลับกันและเฟรมที่ค้างจะปรากฏขึ้นภายในสิบวินาที ผู้คนมักจะข้ามขั้นตอนนี้ไป
# Replay one episode with camera views and joint traces
lerobot-dataset-viz \
--repo-id your-user/so100_pick_cube_20260823_141530 \
--episode-index 0
# Foxglove instead, for a seekable, scrubbable timeline
lerobot-dataset-viz \
--repo-id your-user/so100_pick_cube_20260823_141530 \
--episode-index 0 \
--display-mode foxglove
# Drop the episodes that did not survive review
lerobot-edit-dataset \
--repo_id your-user/so100_pick_cube_20260823_141530 \
--new_repo_id your-user/so100_pick_cube_clean \
--operation.type delete_episodes \
--operation.episode_indices "[3, 17, 41]"
v2.1 หรือ v3.0: ตัดสินใจก่อนบันทึก
v2.1 เขียนไฟล์ parquet และ MP4 อย่างละหนึ่งไฟล์ต่อตอน v3.0 จะรวมหลายตอนเข้าด้วยกันใน shard ที่ใช้ร่วมกัน และสร้างขอบเขตใหม่จากเมตาดาต้า ดังนั้น info.json จึงมีเทมเพลตพาธเช่น data/chunk-{chunk_index:03d}/file-{file_index:03d}.parquet แทนที่จะเป็นหมายเลขตอน เหตุผลเบื้องหลังคือการมีไฟล์น้อยลงแต่มีขนาดใหญ่ขึ้น: ทำให้เริ่มต้นได้เร็วขึ้นและลดภาระของระบบไฟล์เมื่อขยายขนาด
| LeRobot v2.1 | LeRobot v3.0 | |
|---|---|---|
| โครงสร้าง | หนึ่ง parquet และหนึ่ง MP4 ต่อตอน | หลายตอนต่อ shard |
| เมตาดาต้าของตอน | ไฟล์ JSONL | parquet แบบแบ่งส่วนภายใต้ meta/episodes/ ผ่าน datasets stack |
| การสตรีมจาก Hub | ไม่ | ใช่ ผ่าน StreamingLeRobotDataset |
| เขียนโดย lerobot 0.6.1 | ไม่ | ใช่ สิ่งที่คุณได้รับในวันนี้ |
| อ่านโดย GR00T N1.7 และ N1.5 | ใช่ | ไม่ ต้องแปลงลง |
lerobot 0.6.1 เขียน v3.0 แต่ GR00T N1.7 และ N1.5 อ่าน v2.0 หรือ v2.1 และจะเกิดข้อผิดพลาด โปรดสังเกตทิศทางการพัฒนา: src/lerobot/scripts/ มี convert_dataset_v21_to_v30.py และไม่มีอะไรที่ไปในทิศทางตรงกันข้าม จัดการเรื่องนี้ให้เรียบร้อยก่อนเริ่มเซสชัน การแก้ไข: ชุดข้อมูลถูกปฏิเสธเนื่องจากเป็น v3.
# Upgrade an older v2.1 dataset to v3.0
python -m lerobot.scripts.convert_dataset_v21_to_v30 \
--repo-id=your-user/so100_pick_cube
# By default it pushes the converted dataset back to the hub and tags it v3.0.
# To convert a local copy and keep it off the hub:
python -m lerobot.scripts.convert_dataset_v21_to_v30 \
--repo-id=your-user/so100_pick_cube \
--root=/path/to/dataset/directory \
--push-to-hub=falseสองเส้นทางสู่ชุดข้อมูลเดียวกัน
ทุกอย่างที่กล่าวมาข้างต้น บนเครื่องของคุณเอง: คุณเป็นเจ้าของ USB enumeration, การสร้าง ffmpeg, การปรับแต่ง encoder และไฟล์ calibration นี่คือเส้นทางที่ถูกต้องในการทำความเข้าใจ pipeline, รันชุดกล้องที่ไม่ธรรมดา, หรือเก็บข้อมูลไว้ในเครื่อง
เวลา: หนึ่งคืนต่อแขนสำหรับการประกอบ, การปรับเทียบครั้งแรกที่ยุ่งยาก, และเซสชันแรกที่คุณต้องทิ้งไปเพราะกล้องอยู่ในช่องที่ไม่ถูกต้อง
ไคลเอนต์เดสก์ท็อปบันทึกชุดข้อมูลรูปแบบ LeRobot, ตอน, สตรีมกล้อง และสถานะข้อต่อ โดยตรงจากเซสชันteleoperation ชุดข้อมูลนั้นจะป้อนเข้าสู่ฟอร์มการฝึก: เลือกโมเดล, ชุดข้อมูล และไฮเปอร์พารามิเตอร์, และแบ็กเอนด์จะเช่า GPU ที่มีขนาดตาม VRAM ของโมเดล, รันเทรนเนอร์ และเขียนcheckpoints ไปยังที่เก็บอ็อบเจกต์
- 1ติดตั้งไคลเอนต์
บน หน้าดาวน์โหลด; การตั้งค่าใน เอกสารไคลเอนต์
- 2บันทึกจากเซสชัน teleop
ขับเคลื่อนแขน; ไคลเอนต์จะบันทึกตอนในรูปแบบ LeRobot คำแนะนำ: บันทึกชุดข้อมูลแรกของคุณ
- 3หรือนำข้อมูลของคุณมาเอง
ชุดข้อมูลยังสามารถมาจาก Hugging Face repo id หรือเครื่องของคุณเอง: เอกสารชุดข้อมูล, ไดเรกทอรีสาธารณะ
- 4ฝึกและรันกลับ
เลือกการรวมกันบน เมทริกซ์การฝึก, จากนั้นรันนโยบายกลับบนแขน ประมาณ 1 ถึง 3 USD สำหรับระดับ 24 GB, 4 ถึง 12 สำหรับระดับ A100 หรือ H100
มันไม่ได้ประกอบหรือปรับเทียบแขนของคุณ และไม่ได้ซ่อมแซมตอนที่บกพร่อง ดังนั้นขั้นตอนการตรวจสอบยังคงใช้ได้ นอกจากนี้ยังมีข้อจำกัดที่ปลายอีกด้านหนึ่ง: สำหรับงานที่รวดเร็ว การอนุมานจะต้องอยู่ใกล้กับเซอร์โว วงจรควบคุมทำงาน 20 ถึง 485 ms ต่อขั้นตอนการกระทำ และการเดินทางไปกลับผ่านอินเทอร์เน็ตสาธารณะจะเปลี่ยนนโยบายที่ทำงานได้ให้กลายเป็นนโยบายที่ลังเล
บันทึกชุดข้อมูล LeRobot โดยไม่ต้องเชื่อมต่อ pipeline ด้วยตัวเอง
ไคลเอนต์เดสก์ท็อป AY-Robots บันทึกตอน, สตรีมกล้อง และสถานะข้อต่อในรูปแบบ LeRobot จากเซสชัน teleoperation จากนั้นส่งชุดข้อมูลให้กับเทรนเนอร์
รับไคลเอนต์เดสก์ท็อปจากชุดข้อมูลสู่โมเดลนโยบาย
ห้าสิบตอนที่สะอาดจะป้อนทุกๆ ที่รันที่นี่ ฝึกจากศูนย์สำหรับงานของคุณโดยเฉพาะ มีพารามิเตอร์ประมาณ 80 ล้านตัวที่ประมาณ 20 ms ต่อขั้นตอนการกระทำ เป็นเพียงหนึ่งในห้าที่รองรับการเคลื่อนไหวที่รวดเร็วได้ดี มีพารามิเตอร์ประมาณ 450 ล้านตัวบนการ์ด 24 GB เป็นโมเดลพื้นฐานที่มีพารามิเตอร์ประมาณ 3 พันล้านตัว ซึ่ง ใช้พารามิเตอร์ประมาณ 40 ล้านตัว ต้องการ A100 หรือ H100 และต้องการชุดข้อมูล v2.1 นั้น
ถัดไป คู่มือสำหรับชุดค่าผสมของคุณ: , หรือ ; สำหรับการรันครั้งแรก จะสั้นกว่า เมื่อโมเดลนโยบายทำงานได้บนโต๊ะทดสอบ แต่ล้มเหลวทันทีที่คุณขยับโต๊ะ นั่นคือปัญหาข้อมูล: และ จะเจาะลึกเรื่องความหลากหลายมากขึ้น
ฉันต้องการจำนวนตอนเท่าไรจริงๆ สำหรับโมเดลนโยบายที่ใช้งานได้ครั้งแรก?▾
สามสิบสำหรับ SmolVLA, ห้าสิบสำหรับ ACT, Pi0.5, GR00T N1.5 และ N1.7 ซึ่งเป็นค่าต่ำสุดที่ผู้ฝึกสอน AY-Robots กำหนด คู่มือ LeRobot แนะนำอย่างอิสระว่าอย่างน้อย 50 สำหรับงานแรก ประมาณ 10 ต่อตำแหน่งวัตถุ งานวิจัยด้านการปรับขนาดข้อมูลพบว่าการสรุปผลจะปรับขนาดตามสภาพแวดล้อมและวัตถุมากกว่าจำนวนการสาธิต ดังนั้นการบันทึกร้อยครั้งในฉากเดียวจึงแย่กว่าห้าสิบครั้งในห้าตำแหน่ง
ฉันจำเป็นต้องมีแขนนำทาง หรือสามารถควบคุมระยะไกลด้วยคีย์บอร์ดได้หรือไม่?▾
lerobot มาพร้อมกับอุปกรณ์ควบคุมระยะไกลแบบคีย์บอร์ดและเกมแพด ดังนั้นแขนนำทางจึงไม่จำเป็นอย่างเคร่งครัด แต่เป็นที่ต้องการอย่างยิ่ง: ระบบผู้นำ-ผู้ตามให้วิถีการเคลื่อนที่ของข้อต่อแบบต่อเนื่องตามข้อตกลงพิกัดของการกระทำที่บันทึกไว้ ในขณะที่การป้อนข้อมูลด้วยคีย์บอร์ดจะสร้างการเคลื่อนที่แบบขั้นบันไดที่โมเดลนโยบายเรียนรู้ว่าเป็นกระตุก การควบคุมระยะไกลด้วยคีย์บอร์ดก็ต้องการแบ็กเอนด์คีย์ส่วนกลางด้วย ดังนั้นจึงล้มเหลวบน Wayland และ headless
ฉันสามารถบันทึกบน Raspberry Pi หรือมินิพีซีขนาดเล็กได้หรือไม่?▾
ได้ ด้วยการปรับแต่ง คู่มือการเข้ารหัสแบบสตรีมมิ่งมีส่วนที่ครอบคลุมเครื่องจักร 4 คอร์สมัยใหม่และ Raspberry Pi 5 ที่มีทรัพยากรต่ำ และระบุกล้องสองตัวที่ 640x480 และ 30 fps ในคอลัมน์ที่ต้องการการปรับแต่งบางอย่าง คำแนะนำคือ: หยุดตัวเข้ารหัสไม่ให้แข่งขันกับลูปการจับภาพ โดยใช้ --dataset.rgb_encoder.vcodec=h264 และ --dataset.streaming_encoding=false มันประเมินกล้องสองตัวที่ 640x480 ว่าประมาณ 55 ล้านพิกเซลต่อวินาที และสองตัวที่ 1920x1080 ว่าประมาณ 373 ล้าน
ฉันจะรู้ได้อย่างไรว่าชุดข้อมูลที่ฉันเพิ่งบันทึกนั้นสมบูรณ์ดีจริง?▾
สามการตรวจสอบง่ายๆ เปรียบเทียบระยะเวลาวิดีโอของแต่ละตอนกับระยะเวลาที่ CLI รายงาน และยืนยันว่าจำนวนแถวเท่ากับ fps คูณระยะเวลานั้น โดยคิดเป็นแต่ละตอน ไม่ใช่รวมทั้งหมด นั่นคือการทดสอบการยอมรับที่คู่มือการเข้ารหัสของ lerobot ให้ไว้ อ่าน ds.meta.stats ซึ่งข้อต่อที่มีค่า min เท่ากับ max ไม่เคยเคลื่อนที่ จากนั้นเล่นซ้ำสองหรือสามตอนใน lerobot-dataset-viz ซึ่งเป็นวิธีเดียวที่จะแสดงมุมมองที่สลับกันและเฟรมที่ค้างได้ สำหรับเฟรมที่ตกหล่น คู่มือกำหนดเส้นที่ประมาณ 5 percent ที่หายไป; ประมาณ 2 percent เป็นโหลดชั่วคราวปกติ ซึ่งมักจะเป็นแค่การเริ่มต้น
งานฝึกอบรมของฉันปฏิเสธชุดข้อมูลว่าเป็น v3.0 แล้วจะทำอย่างไร?▾
GR00T N1.7 และ N1.5 อ่าน LeRobot v2.0 หรือ v2.1 และจะล้มเหลวเมื่อเจอ v3.0 ซึ่งเป็นสิ่งที่ lerobot 0.6.1 บันทึกไว้ ไม่ว่าจะกำหนดรูปแบบก่อนการฝึกอบรม หรือใช้โมเดลนโยบายที่อ่าน v3.0 ได้โดยตรง: Pi0.5, SmolVLA หรือ ACT lerobot มีตัวแปลงจาก v2.1 เป็น v3.0 และไม่มีตัวแปลงย้อนกลับ
Sources
- LeRobot: การเรียนรู้แบบเลียนแบบบนหุ่นยนต์จริง
- LeRobot: การประกอบ SO-100, การตั้งค่ามอเตอร์ และการปรับเทียบ
- LeRobot: กล้องและ lerobot-find-cameras
- LeRobot: การติดตั้งและเมทริกซ์ส่วนเสริม
- LeRobotDataset v3.0: โครงสร้างและการย้ายข้อมูลจาก v2.1
- LeRobot: การเข้ารหัสวิดีโอแบบสตรีมมิ่งและเฟรมที่ตกหล่น
- LeRobot: การย้ายชุดข้อมูลขนาดใหญ่ไปยัง v3.0 (DROID)
- lerobot v0.6.1 release, 3 สิงหาคม 2026
- DatasetRecordConfig: ค่าเริ่มต้นการบันทึกจริง
- lerobot_record.py: ลูปการบันทึกและการจัดการการดำเนินการต่อ
- TheRobotStudio/SO-ARM100: รีโพสร้างและรายการวัสดุ
- Hugging Face: รายการตรวจสอบชุดข้อมูลชุมชน LeRobot
- lerobot/svla_so100_pickplace: 50 ตอน, 19,631 เฟรม
- Lin et al. (2024), กฎการปรับขนาดข้อมูลในการเรียนรู้แบบเลียนแบบ
- Mandlekar et al. (2021), สิ่งสำคัญในการเรียนรู้จากการสาธิตของมนุษย์แบบออฟไลน์
Sources
- LeRobot: Imitation Learning on Real-World Robots
- LeRobot: SO-100 assembly, motor setup and calibration
- LeRobot: Cameras and lerobot-find-cameras
- LeRobot: Installation and the extras matrix
- LeRobotDataset v3.0: layout and v2.1 migration
- LeRobot: Streaming video encoding and dropped frames
- LeRobot: Porting large datasets to v3.0 (DROID)
- lerobot v0.6.1 release, 3 August 2026
- DatasetRecordConfig: the real recording defaults
- lerobot_record.py: record loop and resume handling
- TheRobotStudio/SO-ARM100: build repo and bill of materials
- Hugging Face: LeRobot Community Datasets checklist
- lerobot/svla_so100_pickplace: 50 episodes, 19,631 frames
- Lin et al. (2024), Data Scaling Laws in Imitation Learning
- Mandlekar et al. (2021), What Matters in Learning from Offline Human Demonstrations
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started