Skip to content

Commit 5ce65fd

Browse files
committed
Initial commit
1 parent df866f6 commit 5ce65fd

24 files changed

+4478
-2798
lines changed

.claude/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"apiKeyHelper": "echo 'sk-Qgob5ZFAqMSHyuwsd8u0d0UWfPqZbgj9dNWsAZL1GkBG3409'",
3+
"env": {
4+
"ANTHROPIC_API_KEY": "sk-Qgob5ZFAqMSHyuwsd8u0d0UWfPqZbgj9dNWsAZL1GkBG3409",
5+
"ANTHROPIC_BASE_URL": "https://code.ppchat.vip"
6+
},
7+
"permissions": {
8+
"allow": [],
9+
"deny": []
10+
}
11+
}

=2.0.2

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Looking in indexes: https://mirrors.aliyun.com/pypi/simple/, https://pypi.ngc.nvidia.com
2+
Collecting pycocotools
3+
Downloading https://mirrors.aliyun.com/pypi/packages/61/d7/32996d713921c504875a4cebf241c182aa37e58daab5c3c4737f539ac0d4/pycocotools-2.0.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (455 kB)
4+
Requirement already satisfied: numpy in /map-vepfs/miniconda3/lib/python3.10/site-packages (from pycocotools) (1.26.4)
5+
Installing collected packages: pycocotools
6+
Successfully installed pycocotools-2.0.10

command.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
uv run scripts/serve_policy.py --env=DROID
2+
export OPENPI_DATA_HOME='/map-vepfs/haoxiao/yijingkun/openpi/.openpi-cache'
3+
4+
/usr/local/bin/clash -d ~/.config/clash
5+
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
6+
7+
nvm use 20
8+
export ANTHROPIC_AUTH_TOKEN=sk-Qgob5ZFAqMSHyuwsd8u0d0UWfPqZbgj9dNWsAZL1GkBG3409
9+
export ANTHROPIC_BASE_URL=https://code.ppchat.vip
10+
claude
11+
12+
uv run examples/libero/convert_libero_data_to_lerobot.py --data_dir ~/.cache/huggingface/hub/datasets--openvla--modified_libero_rlds/snapshots/6ce6aaaaabdbe590b1eef5cd29c0d33f14a08551/
13+
14+
#export HF_LEROBOT_HOME='/map-vepfs/haoxiao/yijingkun/physical-intelligence'
15+
export HF_LEROBOT_HOME='/map-vepfs/haoxiao/yijingkun'
16+
17+
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 uv run scripts/train.py pi0_fast_libero --exp-name=my_experiment --overwrite --batch_size=8
18+
19+
uv run examples/libero/convert_my_data_to_lerobot.py --data_dir {dataset_path} #convert ur3 data to lerobot data
20+
uv run scripts/compute_norm_stats.py --config-name pi0_ur3
21+
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 uv run scripts/train.py pi0_ur3 --exp-name=my_experiment --overwrite
22+
23+
sudo fuser -v /dev/nvidia*

examples/libero/convert_libero_data_to_lerobot.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,29 @@
1919
"""
2020

2121
import shutil
22+
from pathlib import Path
2223

2324
from lerobot.common.datasets.lerobot_dataset import HF_LEROBOT_HOME
2425
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
2526
import tensorflow_datasets as tfds
2627
import tyro
2728

2829
REPO_NAME = "your_hf_username/libero" # Name of the output dataset, also used for the Hugging Face Hub
30+
# RAW_DATASET_NAMES = [
31+
# "libero_10_no_noops",
32+
# "libero_goal_no_noops",
33+
# "libero_object_no_noops",
34+
# "libero_spatial_no_noops",
35+
# ] # For simplicity we will combine multiple Libero datasets into one training dataset
36+
2937
RAW_DATASET_NAMES = [
30-
"libero_10_no_noops",
3138
"libero_goal_no_noops",
32-
"libero_object_no_noops",
33-
"libero_spatial_no_noops",
34-
] # For simplicity we will combine multiple Libero datasets into one training dataset
35-
39+
]
3640

3741
def main(data_dir: str, *, push_to_hub: bool = False):
3842
# Clean up any existing dataset in the output directory
39-
output_path = HF_LEROBOT_HOME / REPO_NAME
43+
#output_path = HF_LEROBOT_HOME / REPO_NAME
44+
output_path = Path("/map-vepfs/haoxiao/yijingkun/libero")
4045
if output_path.exists():
4146
shutil.rmtree(output_path)
4247

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
"""
2+
Minimal example script for converting a dataset to LeRobot format.
3+
4+
We use the Libero dataset (stored in RLDS) for this example, but it can be easily
5+
modified for any other data you have saved in a custom format.
6+
7+
Usage:
8+
uv run examples/libero/convert_libero_data_to_lerobot.py --data_dir /path/to/your/data
9+
10+
If you want to push your dataset to the Hugging Face Hub, you can use the following command:
11+
uv run examples/libero/convert_libero_data_to_lerobot.py --data_dir /path/to/your/data --push_to_hub
12+
13+
Note: to run the script, you need to install tensorflow_datasets:
14+
`uv pip install tensorflow tensorflow_datasets`
15+
16+
You can download the raw Libero datasets from https://huggingface.co/datasets/openvla/modified_libero_rlds
17+
The resulting dataset will get saved to the $HF_LEROBOT_HOME directory.
18+
Running this conversion script will take approximately 30 minutes.
19+
"""
20+
import os
21+
import shutil
22+
from pathlib import Path
23+
from PIL import Image
24+
import numpy as np
25+
26+
from lerobot.common.datasets.lerobot_dataset import HF_LEROBOT_HOME
27+
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
28+
import tensorflow_datasets as tfds
29+
import tyro
30+
31+
REPO_NAME = "ur3" # Name of the output dataset, also used for the Hugging Face Hub
32+
# RAW_DATASET_NAMES = [
33+
# "libero_10_no_noops",
34+
# "libero_goal_no_noops",
35+
# "libero_object_no_noops",
36+
# "libero_spatial_no_noops",
37+
# ] # For simplicity we will combine multiple Libero datasets into one training dataset
38+
39+
RAW_DATASET_NAMES = [
40+
"libero_goal_no_noops",
41+
]
42+
43+
def main(data_dir: str, *, push_to_hub: bool = False):
44+
# Clean up any existing dataset in the output directory
45+
#output_path = HF_LEROBOT_HOME / REPO_NAME
46+
output_path = Path("/map-vepfs/haoxiao/yijingkun/ur3")
47+
if output_path.exists():
48+
shutil.rmtree(output_path)
49+
50+
# Create LeRobot dataset, define features to store
51+
# OpenPi assumes that proprio is stored in `state` and actions in `action`
52+
# LeRobot assumes that dtype of image data is `image`
53+
img = Image.open(f'{data_dir}/0/images/front_images/0.png')
54+
front_image = np.array(img)
55+
width, height = front_image.shape[1], front_image.shape[0]
56+
dataset = LeRobotDataset.create(
57+
repo_id=REPO_NAME,
58+
robot_type="panda",
59+
fps=10,
60+
features={
61+
"image": {
62+
"dtype": "image",
63+
"shape": (width, height, 3),
64+
# "shape": (224, 224, 3),
65+
# "shape": (480, 640, 3),
66+
"names": ["height", "width", "channel"],
67+
},
68+
"wrist_image": {
69+
"dtype": "image",
70+
"shape": (width, height, 3),
71+
# "shape": (224, 224, 3),
72+
# "shape": (480, 640, 3),
73+
"names": ["height", "width", "channel"],
74+
},
75+
"state": {
76+
"dtype": "float32",
77+
"shape": (8,),
78+
"names": ["state"],
79+
},
80+
"actions": {
81+
"dtype": "float32",
82+
"shape": (8,),
83+
"names": ["actions"],
84+
},
85+
},
86+
image_writer_threads=10,
87+
image_writer_processes=5,
88+
)
89+
90+
# Loop over raw Libero datasets and write episodes to the LeRobot dataset
91+
# You can modify this for your own data format
92+
# for raw_dataset_name in RAW_DATASET_NAMES:
93+
# raw_dataset = tfds.load(raw_dataset_name, data_dir=data_dir, split="train")
94+
# for episode in raw_dataset:
95+
# for step in episode["steps"].as_numpy_iterator():
96+
# dataset.add_frame(
97+
# {
98+
# "image": step["observation"]["image"],
99+
# "wrist_image": step["observation"]["wrist_image"],
100+
# "state": step["observation"]["state"],
101+
# "actions": step["action"],
102+
# "task": step["language_instruction"].decode(),
103+
# }
104+
# )
105+
# dataset.save_episode()
106+
107+
for i in range(64):
108+
len_frame = len(os.listdir(f'{data_dir}/{i}/joint_states'))
109+
for j in range(len_frame):
110+
img = Image.open(f'{data_dir}/{i}/images/front_images/{j}.png')
111+
front_image = np.array(img)
112+
113+
img = Image.open(f'{data_dir}/{i}/images/ee_images/{j}.png')
114+
ee_image = np.array(img)
115+
116+
state = np.load(f'{data_dir}/{i}/joint_states/{j}.npy').astype(np.float32)
117+
state = np.insert(state, 6, 0.0)
118+
119+
actions = np.load(f'{data_dir}/{i}/joint_states/{j}.npy').astype(np.float32)
120+
actions = np.insert(actions, 6, 0.0)
121+
122+
dataset.add_frame(
123+
{
124+
"image": front_image,
125+
"wrist_image": ee_image,
126+
"state": state,
127+
"actions": actions,
128+
"task": "pick up the blue cube and place on the top of red cube",
129+
}
130+
)
131+
dataset.save_episode()
132+
133+
# Optionally push to the Hugging Face Hub
134+
if push_to_hub:
135+
dataset.push_to_hub(
136+
tags=["libero", "panda", "rlds"],
137+
private=False,
138+
push_videos=True,
139+
license="apache-2.0",
140+
)
141+
142+
143+
if __name__ == "__main__":
144+
tyro.cli(main)
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
"""
2+
Minimal example script for converting a dataset to LeRobot format.
3+
4+
We use the Libero dataset (stored in RLDS) for this example, but it can be easily
5+
modified for any other data you have saved in a custom format.
6+
7+
Usage:
8+
uv run examples/libero/convert_libero_data_to_lerobot.py --data_dir /path/to/your/data
9+
10+
If you want to push your dataset to the Hugging Face Hub, you can use the following command:
11+
uv run examples/libero/convert_libero_data_to_lerobot.py --data_dir /path/to/your/data --push_to_hub
12+
13+
Note: to run the script, you need to install tensorflow_datasets:
14+
`uv pip install tensorflow tensorflow_datasets`
15+
16+
You can download the raw Libero datasets from https://huggingface.co/datasets/openvla/modified_libero_rlds
17+
The resulting dataset will get saved to the $HF_LEROBOT_HOME directory.
18+
Running this conversion script will take approximately 30 minutes.
19+
"""
20+
import os
21+
import shutil
22+
from pathlib import Path
23+
from PIL import Image
24+
import numpy as np
25+
26+
from lerobot.common.datasets.lerobot_dataset import HF_LEROBOT_HOME
27+
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
28+
import tensorflow_datasets as tfds
29+
import tyro
30+
31+
REPO_NAME = "ur3" # Name of the output dataset, also used for the Hugging Face Hub
32+
# RAW_DATASET_NAMES = [
33+
# "libero_10_no_noops",
34+
# "libero_goal_no_noops",
35+
# "libero_object_no_noops",
36+
# "libero_spatial_no_noops",
37+
# ] # For simplicity we will combine multiple Libero datasets into one training dataset
38+
39+
RAW_DATASET_NAMES = [
40+
"libero_goal_no_noops",
41+
]
42+
43+
def main(data_dir: str, *, push_to_hub: bool = False):
44+
# Clean up any existing dataset in the output directory
45+
#output_path = HF_LEROBOT_HOME / REPO_NAME
46+
output_path = Path("/map-vepfs/haoxiao/yijingkun/ur3")
47+
if output_path.exists():
48+
shutil.rmtree(output_path)
49+
50+
# Create LeRobot dataset, define features to store
51+
# OpenPi assumes that proprio is stored in `state` and actions in `action`
52+
# LeRobot assumes that dtype of image data is `image`
53+
dataset = LeRobotDataset.create(
54+
repo_id=REPO_NAME,
55+
robot_type="panda",
56+
fps=10,
57+
features={
58+
"image": {
59+
"dtype": "image",
60+
"shape": (224, 224, 3),
61+
"names": ["height", "width", "channel"],
62+
},
63+
"wrist_image": {
64+
"dtype": "image",
65+
"shape": (224, 224, 3),
66+
"names": ["height", "width", "channel"],
67+
},
68+
"state": {
69+
"dtype": "float32",
70+
"shape": (8,),
71+
"names": ["state"],
72+
},
73+
"actions": {
74+
"dtype": "float32",
75+
"shape": (8,),
76+
"names": ["actions"],
77+
},
78+
},
79+
image_writer_threads=10,
80+
image_writer_processes=5,
81+
)
82+
83+
# Loop over raw Libero datasets and write episodes to the LeRobot dataset
84+
# You can modify this for your own data format
85+
# for raw_dataset_name in RAW_DATASET_NAMES:
86+
# raw_dataset = tfds.load(raw_dataset_name, data_dir=data_dir, split="train")
87+
# for episode in raw_dataset:
88+
# for step in episode["steps"].as_numpy_iterator():
89+
# dataset.add_frame(
90+
# {
91+
# "image": step["observation"]["image"],
92+
# "wrist_image": step["observation"]["wrist_image"],
93+
# "state": step["observation"]["state"],
94+
# "actions": step["action"],
95+
# "task": step["language_instruction"].decode(),
96+
# }
97+
# )
98+
# dataset.save_episode()
99+
# Get list of available episode directories
100+
episode_dirs = [d for d in os.listdir(data_dir) if d.isdigit() and os.path.isdir(os.path.join(data_dir, d))]
101+
episode_dirs.sort(key=int) # Sort numerically
102+
103+
for episode_dir in episode_dirs:
104+
i = int(episode_dir)
105+
episode_path = os.path.join(data_dir, episode_dir)
106+
joint_states_path = os.path.join(episode_path, 'joint_states')
107+
108+
# Check if required directories exist
109+
if not os.path.exists(joint_states_path):
110+
print(f"Skipping episode {i} - joint_states directory not found")
111+
continue
112+
113+
len_frame = len(os.listdir(joint_states_path))
114+
episode_frame_count = 0
115+
116+
for j in range(len_frame):
117+
try:
118+
front_img_path = f'{episode_path}/images/front_images/{j}.png'
119+
ee_img_path = f'{episode_path}/images/ee_images/{j}.png'
120+
joint_state_path = f'{episode_path}/joint_states/{j}.npy'
121+
122+
# Check if all required files exist
123+
if not all(os.path.exists(path) for path in [front_img_path, ee_img_path, joint_state_path]):
124+
print(f"Skipping episode {i}, frame {j} - missing files")
125+
continue
126+
127+
img = Image.open(front_img_path)
128+
front_image = np.array(img)
129+
130+
img = Image.open(ee_img_path)
131+
ee_image = np.array(img)
132+
133+
state = np.load(joint_state_path).astype(np.float32)
134+
state = np.insert(state, 6, 0.0)
135+
136+
actions = np.load(joint_state_path).astype(np.float32)
137+
actions = np.insert(actions, 6, 0.0)
138+
139+
dataset.add_frame(
140+
{
141+
"image": front_image,
142+
"wrist_image": ee_image,
143+
"state": state,
144+
"actions": actions,
145+
"task": "pick up the red cube and place on the top of blue cube",
146+
}
147+
)
148+
episode_frame_count += 1
149+
except (OSError, IOError) as e:
150+
print(f"Skipping corrupted image at episode {i}, frame {j}: {e}")
151+
continue
152+
153+
# Only save episode if we have at least one valid frame
154+
if episode_frame_count > 0:
155+
dataset.save_episode()
156+
print(f"Saved episode {i} with {episode_frame_count} frames")
157+
else:
158+
print(f"Skipping episode {i} - no valid frames")
159+
160+
# Optionally push to the Hugging Face Hub
161+
if push_to_hub:
162+
dataset.push_to_hub(
163+
tags=["libero", "panda", "rlds"],
164+
private=False,
165+
push_videos=True,
166+
license="apache-2.0",
167+
)
168+
169+
170+
if __name__ == "__main__":
171+
tyro.cli(main)

0 commit comments

Comments
 (0)