| # 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 |