lerobot
用lerobot的ur5 dataset。
安装
- 仿照install
- linux没啥问题,有一个报错,用python3-dev代替python-dev
1
2
3
4Package python-dev is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted or is only available from another source
However the following packages replace it:
python2-dev:i386 python2:i386 python2-dev python2 python-dev-is-python3 - pip
install超时,换镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple - 下载会很慢,又超时了,加上--default-timeout=100
数据集下载
- sudo apt-get install git-lfs
- git clone https://hf-mirror.com/datasets/lerobot/berkeley_autolab_ur5
数据集内容
- 官网
- task
- tiger pick and place:任务字符串是“把老虎从红碗里拿出来,放在灰碗里。“填充动物(老虎)总是从红碗开始。两个碗的位置在桌子上是随机的,而夹持器被初始化为固定姿势。从技术上讲,拾取和放置任务只需要夹持器的平移动作。
- cloth sweeping:任务字符串为“将绿色布扫到桌子左侧。“布料随机初始化在桌子右侧的一个地方,抓手需要将其水平推到左侧。通过从固定位置添加噪声来随机初始化夹持器的起始姿态。从技术上讲,清扫任务只需要抓手的平移动作。
- 杯子堆叠:任务字符串是“拿起蓝色杯子并将其放入棕色杯子。“两个杯子的位置在桌子上是随机的,抓手的起始姿势也是随机的。从技术上讲,堆叠任务只需要夹持器的平移动作。
- 瓶子拾取和放置:任务字符串是“将牧场瓶子放入锅中。“锅的位置是固定的,而牧场瓶的位置是随机的。 夹持器的起始姿势是固定的。此任务涉及平移和旋转操作。
数据集可视化
python lerobot/scripts/visualize_dataset.py
--repo-id lerobot/berkeley_autolab_ur5
--root ~/
--local-files-only 1
--episode-index 0
怎么又不支持本地的了???
Berkeley UR5
- google drive下载链接
- 根据pkl,npy比较 选择npy
- 下bottle.npy(流量肉疼)
npy data
这一部分用jupyter 很爽:D
read
1 | import numpy as np |
(1,) object dict_keys(['robot_state', 'action', 'image', 'task', 'other'])
save
robot_state: np.ndarray((L, 15))
- 数据说明
- This stores the robot state at each timestep.
- [joint0, joint1, joint2, joint3, joint4, joint5, x,y,z, qx,qy,qz,qw, gripper_is_closed, action_blocked]
- x,y,z, qx,qy,qz,qw is the end-effector pose expressed in the robot base frame
- gripper_is_closed is binary: 0 = fully open; 1 = fully closed
- action_blocked is binary: 1 if the gripper opening/closing action is being executed and no other actions can be performed; 0 otherwise.
- 有用的是0-5,以及倒数2,倒数1不知道有没有用
- 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
# 假设 metadata['robot_state'] 是形状为 (L,15) 的 numpy 数组
robot_state_data = metadata['robot_state']
# 提取目标字段:joint0-joint5 (索引0-5) + gripper_is_closed (索引13)
target_indices = [0, 1, 2, 3, 4, 5, 13] # 需要提取的列索引
output_lines = []
for state in robot_state_data:
# 提取指定列并转换为列表[6,8](@ref)
extracted = [state[i] for i in target_indices]
# 格式化为字符串(保留4位小数,二进制用整数)
line = " ".join([f"{x:.4f}" if i < 6 else str(int(x)) for i, x in enumerate(extracted)])
output_lines.append(line)
# 写入TXT文件(使用UTF-8编码保证兼容性)[9,11](@ref)
with open("robot_joints_gripper.txt", "w", encoding="utf-8") as f:
f.write("\n".join(output_lines))
使用的时候 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15def read_robot_data(file_path):
data_list = []
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
# 去除换行符并分割数据[6,9](@ref)
raw_values = line.strip().split()
# 转换数据类型:前6个为float,最后1个为int[8](@ref)
converted = [float(x) for x in raw_values[:6]] + [int(raw_values[-1])]
data_list.append(converted)
return data_list
# 使用示例
loaded_data = read_robot_data("robot_joints_gripper.txt")
print(f"加载数据量:{len(loaded_data)} 条")
print("首条数据示例:", loaded_data[0])
image: np.ndarray((L, 480, 640, 3))
- 除了这个image,other里面还有点,只保存这个
- 代码
1
2
3
4
5
6
7from PIL import Image
# 假设 images 是形状为 (L, 480, 640, 3) 的 uint8 数组
for i in range(image_data.shape[0]):
img = Image.fromarray(image_data[i]) # 提取单张图像
# img.save(f"images/image_{i}.jpg") # 保存为JPG
# 或保存为PNG(无损压缩)
img.save(f"images/image_{i}.png", "PNG", compress_level=0)
qpos导入genesis
- 提取qpos
- 提取gripper,就这些
服务器推理
运行结构
lerobot用pi0.5训练pusht
dataset
数据集格式估计不对
Migrate v2.1 → v3.0 https://huggingface.co/docs/lerobot/lerobot-dataset-v3
python -m lerobot.datasets.v30.convert_dataset_v21_to_v30
--repo-id=
但是代码运行之前需要加一个PYTHONPATH=src
现在用root/repo_id表示数据集的位置了,跟以前不一样
好像是v3的特性把所有的episode存到一起 ## model
pip install -e ".[pi]"
准备号pi0_base和pi05_base:huggingface的下载不了就下hf-mirror.com的
这个训练命令行太难看了
hf download repo_id之后不用改变位置,直接pretrained_path_or_name就能用。 除了base模型还需要下载分词器,但是分词器google/paligemma-3b-pt-224需要获取token才能下载,教程:https://hf-mirror.com/login 获得token之后 hf download google/paligemma-3b-pt-224 --token 刚刚复制得到的token
HF_HUB_OFFLINE=1 CUDA_VISIBLE_DEVICES=0 python src/lerobot/scripts/lerobot_train.py --config_path=fscript/finetune/simple_test.yaml
这样断网+只用一个gpu,现在可以加载1. 分词器,2. 基础模型
To run the models in this repository, you will need an NVIDIA GPU
with at least the following specifications. These estimations assume a
single GPU, but you can also use multiple GPUs with model parallelism to
reduce per-GPU memory requirements by configuring
fsdp_devices in the training config. Please also note that
the current training script does not yet support multi-node
training.
根据pi05的要求,恐怕不能微调……
1 | python src/lerobot/scripts/lerobot_train.py \ |
改成 HF_HUB_OFFLINE=1 CUDA_VISIBLE_DEVICES=0 python src/lerobot/scripts/lerobot_train.py --config_path=fscript/finetune/simple_test.yaml
其中simple_test.yaml 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27# 参考pi0 https://huggingface.co/docs/lerobot/pi0
# 用pusht数据finetune pi0
# 已经可以用multi gpu training了:https://huggingface.co/docs/lerobot/multi_gpu_training
# CUDA_VISIBLE_DEVICES=0 PYTHONPATH=src lerobot.scripts.lerobot_train --config_path=fscript/finetune/simple_test.yaml
dataset:
repo_id: pusht
root: local/dataset/pusht
policy:
type: pi0
pretrained_path: lerobot/pi0_base
repo_id: lerobot/pi0_base
compile_model: true
gradient_checkpointing: true
dtype: bfloat16
device: cuda
output_dir: outputs/pi0_training
job_name: pi0_training
steps: 3000
batch_size: 32
原来支持multi-gpu training了multi-gpu training
pip install accelerate
想用指定的卡id训练 1. 直接命令行 1
2
3
4
5
6HF_HUB_OFFLINE=1 CUDA_VISIBLE_DEVICES=0,1,2 accelerate launch \
--multi_gpu \
--num_processes=3 \
src/lerobot/scripts/lerobot_train.py \
--config_path=fscript/finetune/simple_test.yaml
先放在这里:hf-mirror的设置
一、设置 HF_ENDPOINT(一次性示例)
若你已在当前终端执行过本行,可跳过
1 | export HF_ENDPOINT=https://hf-mirror.com |
验证是否设置成功
1 | echo $HF_ENDPOINT |
如果输出:
1 | https://hf-mirror.com |
说明设置已生效。
作用:让 Hugging Face 相关工具通过镜像站点访问与下载。
范围:仅对当前 shell 会话有效(关闭终端失效)。 ## 二、检查是否存在代理设置
下载失败常见原因是 shell 仍保留了代理环境变量。检查方法:
1 | env | grep -i proxy || echo "no proxy env" |
若看到如下变量仍存在(示例):
1 | http_proxy=http://127.0.0.1:7890/ |
说明请求会强制走本地代理(即使你关闭了代理软件),容易触发 Connection refused。
no_proxy/NO_PROXY仅表示“这些地址不走代理”,不会影响你直连外网。
最好选择cli下载方式,http可能需要账户 Make sure hf CLI is installed: pip install -U "huggingface_hub[cli]"
1 | hf download lerobot/pi05_base |
上面设置只在当前客户端有用 下载的模型放在哪里?.cache/huggingface/hub/models--lerobot--pi0_base/snapshots 应该是这个位置,然后挪到自己要的目录里面
hf download下载的文件在哪里?什么格式? hf download lerobot/pi0_base这个命令下载的文件,~/.cache/huggingface/hub/models--lerobot--pi0_base/这个目录里面,有3个文件夹,snapshots,refs和blobs 看起来只有snapshots里面的比较像文件,有文件名而不是奇怪的数字和字母组合,但是,它并不是真正的文件,只是符号链接 ~/.cache/huggingface/hub/models--lerobot--pi0_base/snapshots/e3a5218ef7a5903445baf2cb656912fc35dc8712$ ll 总计 12 drwxrwxr-x 2 zhonglinyue zhonglinyue 4096 10月 24 10:39 ./ drwxrwxr-x 3 zhonglinyue zhonglinyue 4096 10月 24 10:31 ../ lrwxrwxrwx 1 zhonglinyue zhonglinyue 52 10月 24 10:31 config.json -> ../../blobs/58354c004ec619bc0b0d16faccf9a3c8f89e922b lrwxrwxrwx 1 zhonglinyue zhonglinyue 52 10月 24 10:31 .gitattributes -> ../../blobs/a6344aac8c09253b3b630fb776ae94478aa0275b lrwxrwxrwx 1 zhonglinyue zhonglinyue 76 10月 24 10:39 model.safetensors -> ../../blobs/8229fd9a7c3c2aafc1e223567b61b5fe3e25eef873bb4233928dbee4bd836303 lrwxrwxrwx 1 zhonglinyue zhonglinyue 52 10月 24 10:31 policy_postprocessor.json -> ../../blobs/4490f0951e4c146a36b9346d36e49c9b676cee23 lrwxrwxrwx 1 zhonglinyue zhonglinyue 52 10月 24 10:31 policy_preprocessor.json -> ../../blobs/ac2b548a787170b0b6bb355ceb54d6c01370032e lrwxrwxrwx 1 zhonglinyue zhonglinyue 52 10月 24 10:31 README.md -> ../../blobs/55fe0bef62c428ef7319989638938e600874e206
snapshots/... 目录下的文件都是 符号链接(symlink),指向 blobs/... 目录下的实际文件
这是 Hugging Face Hub 的 去重存储(content-addressable storage) 机制
下载到本地以后直接repo_id,pretrained_path_or_name改成id就能直接访问到了
action转换
lerobot里面提供了一个:examples/so100_to_so100_EE,看一下这部分代码做了什么?
四个代码,record,replay,evaluate和teleoperate,分别做
lerobot-kinematics - [ ] 校准,保证坐标系准确 - [ ] 写api直接从lerobotdataset数据集joint space转化成cartesian space
- 校准
lerobot自己提供的pipeline
- record的数据逻辑:
- follower_joints_to_ee:follower当前的状态state(ee格式)
- leader_joints_to_ee:leader的目标动作(ee格式)
- ee_to_follower_joints:没有像lerobot以前那样joint->joint的teleoperate方法,而是用leader的ee action计算follower的joint action。(那岂不是就能验证它能否teleoperate别的?)
- dataset格式:
- record_loop
整理一下: Use so100 joint to ee # calibrate In
record.py , keep calibration followed
lerobot-so100-calibrate huggingface
or github,
then get 2 json file indicating follower_id.json and leadr_id.json whose
id name should be written into
SO100Follower/LeaderConfig(id=)
record
code pipeline
modifiying settings in record.py in
examples/so100_to_so100_EE to set cameras/robots/datasets'
episodes. etc.
Download ursf and tell code where to find it.
Then directly run python record.py to start record. In default the dataset will be saved with state/action in ee type.
The code uses follower_kinematics_solver and
leader_kinematics_solver with ik solver
placo.
Three variables are calculated: - follower_joints_to_ee: change
follower joint_action to action_ee(dataset) -
leader_joints_to_ee: change leader to state_ee(dataset) -
ee_to_follower_joints: change action_ee to
joint_action to control follwer using inverse
kinematics.
Creating dataset using different state and
action setting(old one use joint now use end-effector
position)
Then loop_record using teleoperation..
question about code
- Since the code control follower using
action_eethen calculate action_joint. Is this method useful to teleoperate different type of robots with so100 leader? Since it uses ee to control, how the joint going is decided by ik solver. - Is it right to use so101_urdf? I know there is little difference between so100 and so101
现在已经可以确定,ee的方式是有用的,接下来需要做 1. 可以保存action_joint吗?保存下来之后用长序列动作+一个环境相机效果采集作为视频交差 1. 写new_record.py能结合lerobot-record和ee/record.py的功能 2. 能可视化action,ee和joint都要 2. 保存action_joint之后,train的时候能读取,根据需要读取ee和joint的action/state 3. 模型推理出来的ee能转化到joint
保存joint形式的数据
record里面的调用形式 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# Create the dataset
dataset = LeRobotDataset.create(
repo_id=HF_REPO_ID,
fps=FPS,
features=combine_feature_dicts(
# Run the feature contract of the pipelines
# This tells you how the features would look like after the pipeline steps
aggregate_pipeline_dataset_features(
pipeline=leader_joints_to_ee,
initial_features=create_initial_features(action=leader.action_features),
use_videos=True,
),
aggregate_pipeline_dataset_features(
pipeline=follower_joints_to_ee,
initial_features=create_initial_features(observation=follower.observation_features),
use_videos=True,
),
),
robot_type=follower.name,
use_videos=True,
image_writer_threads=4,
)
feature关键字里面,流程是 1
2
3
4
5
6
7
8
9
10(raw robot data)
↓
create_initial_features()
↓
aggregate_pipeline_dataset_features(pipeline=leader_joints_to_ee)
↓
combine_feature_dicts(...) ← merge leader + follower 的特征
↓
LeRobotDataset.create(...) ← 把特征schema + 数据保存为HF Dataset
create_initial_features()构建初始的特征结构(feature
dict),告诉 pipeline 原始输入有哪些字段。
aggregate_pipeline_dataset_features这个函数主要的功能是把一个数据处理管线(DataProcessorPipeline)输出的特征,整理、筛选并格式化成可用于
Hugging Face LeRobot 数据集的标准特征字典。
combine_feature_dicts(*dicts)把多个 pipeline 的特征
schema 合并
要求同时保存ee和joint形式的action/state,需要修改feature,在原来的pipeline基础上加保存原始数据的,修改dataset的feature