0. 概述

Libero数据集是机器人学习领域的重要资源,包含了丰富的机器人操作演示数据。本指南将详细介绍如何使用 libero2lerobot 工具将Libero数据集转换为LeRobot格式,以便在LeRobot框架中进行机器人学习、模仿学习和强化学习研究。

Libero数据集转换的主要目标是将不同格式的机器人演示数据统一转换为LeRobot框架可用的标准格式。这一转换过程不仅涉及数据格式的转换,更重要的是确保数据的完整性和可用性,为后续的机器人学习算法提供高质量的训练数据。
在这里插入图片描述

转换的意义在于:

  • 标准化数据格式:将不同来源的机器人数据统一为LeRobot标准格式
  • 提高数据利用率:使Libero数据集能够在LeRobot生态系统中被广泛使用
  • 支持多种学习范式:为模仿学习、强化学习等提供标准化的数据接口

1. 系统架构设计

转换器的系统架构采用了模块化设计,主要包含以下几个核心组件:

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Libero数据    │───▶│  格式检测器     │───▶│  数据处理器     │
│   (RLDS/HDF5)   │    │                 │    │                 │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                                │                       │
                                ▼                       ▼
                       ┌─────────────────┐    ┌─────────────────┐
                       │   HDF5处理器    │    │   RLDS处理器    │
                       │                 │    │                 │
                       └─────────────────┘    └─────────────────┘
                                │                       │
                                └───────────┬───────────┘
                                            ▼
                       ┌─────────────────────────────────┐
                       │      LeRobot数据集格式         │
                       │                                 │
                       │  ┌─────────────────────────────┐ │
                       │  │     Hugging Face Hub        │ │
                       │  └─────────────────────────────┘ │
                       └─────────────────────────────────┘

1.1 格式检测器设计

格式检测器是转换器的入口组件,负责自动识别输入数据的格式。其核心逻辑如下:

class DatasetFormatDetector:
    @staticmethod
    def detect_format(data_path: Union[str, Path]) -> str:
        data_path = Path(data_path)
        
        # 检查HDF5格式:查找.hdf5或.h5文件
        hdf5_files = list(data_path.rglob("*.hdf5")) + list(data_path.rglob("*.h5"))
        
        # 检查RLDS格式:查找tfrecord文件或dataset_info.json
        rlds_indicators = (
            list(data_path.rglob("*.tfrecord*")) + 
            list(data_path.rglob("dataset_info.json")) +
            list(data_path.rglob("features.json"))
        )
        
        if hdf5_files and not rlds_indicators:
            return "hdf5"
        elif rlds_indicators and not hdf5_files:
            return "rlds"
        elif hdf5_files and rlds_indicators:
            return "hdf5"  # 优先使用HDF5
        else:
            raise ValueError(f"无法检测数据格式:{data_path}")

这种设计确保了转换器能够自动适应不同的数据格式,无需用户手动指定格式类型。

2. 数据格式深度分析

2.1 RLDS格式详解

RLDS(Robot Learning Data Specification)是Google开发的机器人学习数据集格式,基于TensorFlow Records构建。这种格式具有以下特点:

文件结构

libero_dataset/
├── dataset_info.json          # 数据集元信息
├── features.json              # 特征定义文件
├── train/                     # 训练数据分割
│   ├── data-00000-of-00001.tfrecord
│   └── data-00001-of-00001.tfrecord
└── validation/                # 验证数据分割
    └── data-00000-of-00001.tfrecord

支持的数据集类型

  • libero_10_no_noops - 包含10个基础任务的演示数据
  • libero_goal_no_noops - 目标导向的任务演示
  • libero_object_no_noops - 物体操作任务演示
  • libero_spatial_no_noops - 空间关系任务演示

RLDS格式的优势在于其标准化的数据结构和高效的存储格式,特别适合大规模机器人学习数据的存储和传输。

2.2 HDF5格式详解

HDF5(Hierarchical Data Format 5)是一种灵活的科学数据格式,Libero数据集也支持这种格式。HDF5格式的主要优势在于其层次化结构和跨平台兼容性。

目录结构

libero_hdf5_data/
├── episode_001/
│   └── data/
│       └── trajectory.hdf5
├── episode_002/
│   └── data/
│       └── trajectory.hdf5
└── ...

HDF5文件内部结构

trajectory.hdf5
├── data/
│   ├── demo_0/
│   │   ├── actions          # 机器人动作数据 [N, 7]
│   │   └── obs/
│   │       ├── joint_states     # 关节状态数据 [N, 7]
│   │       ├── agentview_rgb    # 前视相机图像 [N, H, W, 3]
│   │       └── eye_in_hand_rgb  # 腕部相机图像 [N, H, W, 3]
│   └── demo_1/
│       └── ...

HDF5格式的灵活性使其能够存储复杂的层次化数据结构,这对于机器人学习数据特别有用,因为机器人数据通常包含多种类型的观察和动作信息。

3. 转换器核心实现

3.1 HDF5处理器实现

HDF5处理器负责解析和转换HDF5格式的数据。其核心实现包括数据读取、格式转换和LeRobot格式生成。

class HDF5Processor:
    def __init__(self, image_size: Tuple[int, int] = (256, 256), use_videos: bool = False):
        self.image_size = image_size
        self.use_videos = use_videos
    
    def get_default_features(self, use_videos: bool = True) -> Dict[str, Dict[str, Any]]:
        """获取Libero数据集的默认特征配置"""
        image_dtype = "video" if use_videos else "image"
        
        return {
            "observation.images.front": {
                "dtype": image_dtype,
                "shape": (*self.image_size, 3),
                "names": ["height", "width", "channel"],
            },
            "observation.images.wrist": {
                "dtype": image_dtype,
                "shape": (*self.image_size, 3),
                "names": ["height", "width", "channel"],
            },
            "observation.state": {
                "dtype": "float32",
                "shape": (7,),
                "names": [f"state_{i}" for i in range(7)],
            },
            "action": {
                "dtype": "float32",
                "shape": (7,),
                "names": [f"action_{i}" for i in range(7)],
            }
        }

处理器支持多种HDF5文件格式,包括新的Libero demo格式。对于每种格式,处理器都会相应地调整数据读取逻辑。

3.2 RLDS处理器实现

RLDS处理器利用TensorFlow Datasets库来读取和转换RLDS格式的数据:

class RLDSProcessor:
    def __init__(self):
        if not HAS_TF:
            raise ImportError("需要安装tensorflow和tensorflow-datasets来支持RLDS格式")
    
    def process_dataset(self, dataset: LeRobotDataset, data_source: Union[str, Path]):
        """处理RLDS数据集"""
        try:
            # 加载RLDS数据集
            rlds_dataset = tfds.load(str(data_source), split='train')
            
            for episode_idx, episode in enumerate(rlds_dataset):
                # 处理每个episode
                frames = []
                for step_idx, step in enumerate(episode['steps']):
                    frame_data = {
                        "task": "libero_task",
                        "action": step['action'].numpy(),
                        "observation.state": step['observation']['state'].numpy(),
                        "observation.images.front": step['observation']['images']['front'].numpy(),
                        "observation.images.wrist": step['observation']['images']['wrist'].numpy(),
                    }
                    frames.append(frame_data)
                
                # 添加episode到数据集
                for frame in frames:
                    dataset.add_frame(frame)
                dataset.save_episode()
                
        except Exception as e:
            logger.error(f"处理RLDS数据集时出错: {str(e)}")
            raise

3.3 统一转换器

统一转换器是整个系统的核心,它协调各个处理器的工作,并提供完整的转换流程:

class UnifiedConverter:
    def __init__(self, num_workers: int = 4):
        self.num_workers = num_workers
    
    def convert_dataset(
        self,
        data_dir: Union[str, Path],
        repo_id: str,
        output_dir: Optional[Union[str, Path]] = None,
        push_to_hub: bool = False,
        use_videos: bool = True,
        robot_type: str = "panda",
        fps: int = 20,
        task_name: str = "default_task",
        hub_config: Optional[Dict[str, Any]] = None,
        clean_existing: bool = True,
        image_writer_threads: int = 10,
        image_writer_processes: int = 5,
        run_compute_stats: bool = False,
        **kwargs
    ) -> LeRobotDataset:
        
        # 检测数据格式
        format_type = DatasetFormatDetector.detect_format(data_dir)
        
        # 创建相应的处理器
        if format_type == "hdf5":
            processor = HDF5Processor(use_videos=use_videos)
        else:
            processor = RLDSProcessor()
        
        # 创建LeRobot数据集
        dataset = LeRobotDataset(
            repo_id=repo_id,
            output_dir=output_dir,
            features=processor.get_default_features(use_videos),
            hub_config=hub_config or self._get_default_hub_config(),
            clean_existing=clean_existing,
            image_writer_threads=image_writer_threads,
            image_writer_processes=image_writer_processes,
        )
        
        # 处理数据
        self._process_hdf5_data(processor, dataset, Path(data_dir), task_name)
        
        # 完成转换
        dataset.finish()
        
        # 推送到Hub
        if push_to_hub:
            dataset.push_to_hub()
        
        return dataset

4. 安装与配置

4.1 环境准备

转换器的运行需要特定的Python环境和依赖包。建议使用conda创建隔离的环境:

# 创建虚拟环境
conda create -n lerobot python=3.10
conda activate lerobot

# 安装基础依赖
pip install opencv-python h5py tqdm numpy

# 安装RLDS支持(可选)
pip install tensorflow tensorflow-datasets

# 安装LeRobot核心包
pip install lerobot

4.2 获取转换工具

# 克隆项目
git clone https://github.com/lovelyyoshino/libero2lerobot.git
cd libero2lerobot

# 验证安装
python run_converter.py --help

5. 转换操作流程

5.1 数据格式检测

转换器首先会自动检测输入数据的格式。检测逻辑基于文件扩展名和目录结构:

def detect_format(data_path: Union[str, Path]) -> str:
    data_path = Path(data_path)
    
    # 检查HDF5格式:查找.hdf5或.h5文件
    hdf5_files = list(data_path.rglob("*.hdf5")) + list(data_path.rglob("*.h5"))
    
    # 检查RLDS格式:查找tfrecord文件或dataset_info.json
    rlds_indicators = (
        list(data_path.rglob("*.tfrecord*")) + 
        list(data_path.rglob("dataset_info.json")) +
        list(data_path.rglob("features.json"))
    )
    
    if hdf5_files and not rlds_indicators:
        logger.info(f"检测到HDF5格式,找到{len(hdf5_files)}个HDF5文件")
        return "hdf5"
    elif rlds_indicators and not hdf5_files:
        logger.info(f"检测到RLDS格式,找到相关文件:{[f.name for f in rlds_indicators[:3]]}")
        return "rlds"
    elif hdf5_files and rlds_indicators:
        logger.warning("同时发现HDF5和RLDS文件,优先使用HDF5格式")
        return "hdf5"
    else:
        raise ValueError(f"无法检测数据格式:{data_path}")

5.2 数据预处理

5.2.1 HDF5数据预处理

对于HDF5格式的数据,转换器会分析文件结构并提取相应的数据:

def analyze_hdf5_structure(file_path):
    with h5py.File(file_path, 'r') as f:
        print("HDF5文件结构:")
        for key in f.keys():
            print(f"  {key}")
            if hasattr(f[key], 'keys'):
                for subkey in f[key].keys():
                    print(f"    {subkey}: {f[key][subkey].shape}")
5.2.2 RLDS数据预处理

对于RLDS格式的数据,转换器会使用TensorFlow Datasets库来读取数据:

def analyze_rlds_dataset(data_path):
    dataset = tfds.load(data_path, split='train')
    for example in dataset.take(1):
        print("RLDS数据结构:")
        for key, value in example.items():
            print(f"  {key}: {value.shape}")

5.3 执行转换

5.3.1 基本转换命令
# 自动检测格式并转换
python run_converter.py \
  --data-dir /path/to/libero/data \
  --repo-id username/libero_dataset \
  --push-to-hub \
  --use-videos \
  --num-workers 4
5.3.2 HDF5格式转换
# HDF5格式,指定配置
python run_converter.py \
  --data-dir /path/to/hdf5/data \
  --repo-id username/hdf5_dataset \
  --config config.json \
  --task-name "pick_and_place" \
  --num-workers 8
5.3.3 RLDS格式转换
# RLDS格式转换
python run_converter.py \
  --data-dir /path/to/rlds/data \
  --repo-id username/libero_dataset \
  --use-videos \
  --fps 20

…详情请参照古月居

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐