Shuyang-Yu-808
Add Robometer code + Robometer-4B weights
319eb16
|
Raw
History Blame Contribute Delete
7.92 kB
# Adding New Datasets to Robometer
This guide explains how to add new datasets to the Robometer training pipeline.
## Supported Datasets
### Ready-to-Use Datasets
- **LIBERO**: Built-in HDF5 support β†’ [πŸ“– LIBERO Guide](dataset_guides/LIBERO.md)
- **AgiBotWorld**: βœ… Native streaming support β†’ [πŸ“– AgiBotWorld Guide](dataset_guides/AgiBotWorld.md)
### Custom Datasets
- **Add Your Own**: DROID, Bridge, or any custom dataset β†’ [πŸ“– Custom Dataset Guide](dataset_guides/CustomDataset.md)
## Quick Start
### Use Existing Datasets
```bash
# AgiBotWorld (streaming)
uv run python dataset_upload/generate_hf_dataset.py --config_path=dataset_upload/configs/data_gen_configs/agibot_world.yaml
# LIBERO (local files)
uv run python dataset_upload/generate_hf_dataset.py --config_path=dataset_upload/configs/data_gen.yaml
```
### Add Custom Dataset
1. **Read the guide**: [Custom Dataset Guide](dataset_guides/CustomDataset.md)
2. **Create loader**: `dataset_upload/{dataset_name}_loader.py`
3. **Add config**: `dataset_upload/configs/data_gen_configs/{dataset_name}.yaml`
4. **Test**: Run conversion and training
## Architecture Overview
Each dataset type has its own loader module. The main converter (`generate_hf_dataset.py`) is dataset-agnostic and works with any dataset-specific loader that follows the established interface.
### Output Formats
The converter supports two output formats:
**Video Mode** (`--output.use_video=true`):
- Creates MP4 video files using H.264 encoding
- Videos are stored in organized directories: `trajectory_XXXX/trajectory.mp4`
- Uses `datasets.Video()` feature for proper HuggingFace video display
- Supports configurable frame rate, resolution, and cropping
**Frame Mode** (`--output.use_video=false`):
- Creates individual JPG image files
- Images are stored in organized directories: `trajectory_XXXX/frame_XX.jpg`
- Uses `datasets.Sequence(datasets.Image())` feature for image galleries
- Supports configurable frame count and resolution
### Video Processing Features
The dataset converter includes built-in video processing:
- **πŸ“Ή Automatic Resizing**: Videos resized to consistent dimensions (configurable shortest edge size)
- **⏱️ Frame Interpolation**: Downsamples to configurable frame count (default: all frames preserved)
- **🎬 MP4 Creation**: Creates H.264 encoded MP4 files for optimal HuggingFace compatibility
- **🎯 Quality Preservation**: Maintains visual quality while standardizing format
- **πŸ“ File Organization**: Organizes videos in trajectory-specific directories
## Dataset Structure Requirements
Your dataset loader must produce trajectories in the following format:
```python
{
'frames': Union[str, List[str]], # Video file path (video mode) or list of image file paths (frame mode)
'actions': np.ndarray, # Actions
'is_robot': bool, # Whether this is robot data (True) or human data (False)
'task': str, # Human-readable task description
'optimal': str # Whether this trajectory is optimal
}
```
**Note**: The dataset converter automatically creates MP4 video files or individual frame images based on the `use_video` setting.
## Step-by-Step Guide
### 1. Create Your Dataset Loader
Create a new Python file in the `data/` directory following the naming convention: `{dataset_name}_loader.py`
Example: `droid_loader.py` or `bridge_loader.py`
```python
#!/usr/bin/env python3
"""
DROID dataset loader for the generic dataset converter for Robometer model training.
This module contains DROID-specific logic for loading and processing data.
"""
import os
import numpy as np
from typing import List, Dict
from pathlib import Path
from tqdm import tqdm
def load_droid_dataset(base_path: str) -> Dict[str, List[Dict]]:
"""Load DROID dataset and organize by task.
Args:
base_path: Path to the DROID dataset directory
Returns:
Dictionary mapping task names to lists of trajectory dictionaries
"""
print(f"Loading DROID dataset from: {base_path}")
task_data = {}
# Your dataset-specific loading logic here
# This is where you'll implement the logic to:
# 1. Find and read your data files
# 2. Extract frames, actions, rewards, etc.
# 3. Organize by task
# 4. Convert to the required format
# Example structure (adapt to your dataset):
base_path = Path(base_path)
if not base_path.exists():
raise FileNotFoundError(f"DROID dataset path not found: {base_path}")
# Find your data files (adapt this to your dataset structure)
data_files = list(base_path.glob("**/*.hdf5")) # or whatever format you use
for file_path in tqdm(data_files, desc="Processing DROID dataset"):
task_name = file_path.stem
# Load your data file
# This is where you'll implement your specific loading logic
trajectories = load_trajectories_from_file(file_path)
task_data[task_name] = trajectories
print(f"Loaded {sum(len(trajectories) for trajectories in task_data.values())} trajectories from {len(task_data)} tasks")
return task_data
def load_trajectories_from_file(file_path: Path) -> List[Dict]:
"""Load trajectories from a single DROID data file."""
trajectories = []
# Implement your file loading logic here
# This will depend on your dataset format (HDF5, JSON, pickle, etc.)
# Example for HDF5 format:
import h5py
with h5py.File(file_path, 'r') as f:
# Navigate your HDF5 structure and extract data
# Convert to the required format
pass
return trajectories
```
### 2. Update the Main Converter
Add your dataset type to the main converter in `generate_hf_dataset.py`:
```python
# In the main() function, add your dataset type:
elif cfg.dataset.dataset_type == "droid":
from dataset_loaders.droid_loader import load_droid_dataset
# Load the trajectories using your loader
task_data = load_droid_dataset(cfg.dataset.dataset_path)
trajectories = flatten_task_data(task_data)
```
### 3. Test Your Loader
Create a simple test script to verify your loader works:
```python
# test_droid_loader.py
from droid_loader import load_droid_dataset
from helpers import flatten_task_data
# Test your loader
task_data = load_droid_dataset("/path/to/your/droid/dataset")
trajectories = flatten_task_data(task_data)
print(f"Loaded {len(trajectories)} trajectories")
print(f"Sample trajectory keys: {list(trajectories[0].keys())}")
print(f"Sample task: {trajectories[0].get('task', 'No task found')}")
```
### 4. Run Dataset Conversion
Use the main converter with your new dataset:
```bash
uv run python data/generate_hf_dataset.py \
--config_path=configs/dataset_.yaml \
--dataset.dataset_name=your_dataset \
--dataset.dataset_path=/path/to/your/dataset \
--output.output_dir=your_robometer_dataset \
--output.max_trajectories=1000 \
--output.max_frames=-1 \
--output.use_video=true \
--output.fps=10 \
--output.shortest_edge_size=240 \
--output.center_crop=false
```
### Visualize the Dataset
```bash
uv run python visualize_dataset.py --dataset_path=your_robometer_dataset/your_dataset_name
```
## Dataset-Specific Guides
πŸ“ **[Browse All Dataset Guides](dataset_guides/)** - Complete overview with quick reference table
### Individual Guides
- **[πŸ“– AgiBotWorld Guide](dataset_guides/AgiBotWorld.md)** - Streaming support, webdataset format
- **[πŸ“– LIBERO Guide](dataset_guides/LIBERO.md)** - HDF5 files, simulation data
- **[πŸ“– Custom Dataset Guide](dataset_guides/CustomDataset.md)** - Add DROID, Bridge, or your own dataset
Each guide includes:
- βœ… Prerequisites and setup
- βœ… Configuration examples
- βœ… Troubleshooting tips
- βœ… Performance notes
- βœ… Integration with Robometer training