Huggingface.js documentation

@huggingface/lerobot

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

@huggingface/lerobot

Парсер для наборов данных робототехники LeRobot, размещённых на Hugging Face Hub.

Все данные читаются через HTTP-запросы с диапазоном, поэтому код работает без изменений как в браузере, так и в Node, и при этом никогда не загружает весь датасет, чтобы ответить на вопрос о нём.

Почему

Наборы данных LeRobot существуют в двух форматах. В v2.0 / v2.1 у каждого эпизода есть собственный видеофайл и файл parquet, а индекс эпизодов — это файл JSON Lines. В v3.0 эпизоды объединяются в общие файлы, а индекс — это parquet, поэтому эпизод представляет собой диапазон байтов и диапазон времени внутри более крупного файла.

Этот пакет скрывает это различие за единой формой LeRobotEpisode.

Установка

npm install @huggingface/lerobot

hyparquet поставляется вместе с ним и используется для чтения индекса эпизодов v3.0 и данных кадров. fzstd добавляет ZSTD в дополнение к встроенному в hyparquet SNAPPY. Оба импортируются по требованию, поэтому вызывающие стороны, которым нужны только info() или список эпизодов v2, никогда не загружают их.

Использование

import { LeRobotDataset } from "@huggingface/lerobot";

const dataset = new LeRobotDataset("lerobot/svla_so101_pickplace");

const info = await dataset.info();
// {
//   codebaseVersion: "v3.0",
//   robotType: "so100_follower",
//   fps: 30,
//   totalEpisodes: 50,
//   totalFrames: 11939,
//   cameras: [{ key: "observation.images.up", width: 640, height: 480, codec: "av1" }, ...],
//   joints: { "observation.state": ["shoulder_pan.pos", "shoulder_lift.pos", ...] },
//   ...
// }

const episodes = await dataset.episodes({ limit: 10 });
// [
//   {
//     index: 0,
//     length: 303,
//     durationSec: 10.1,
//     tasks: ["pink lego brick into the transparent box"],
//     videos: [{ cameraKey: "observation.images.up", url: "https://...", fromSec: 0, toSec: 10.1 }, ...],
//     data: { url: "https://.../data/chunk-000/file-000.parquet", fromRow: 0, toRow: 303 },
//   },
//   ...
// ]

const episode = await dataset.episode(42);
// The episode whose `index` is 42, or undefined when there is none

offset считает позиции в индексе, которые совпадают с индексами эпизодов только в том случае, если датасет нумерует свои эпизоды как 0, 1, 2, … Некоторые датасеты начинают с 10 или пропускают удалённые эпизоды, поэтому для открытия конкретного эпизода используйте episode(index). Для датасета с нумерацией 0, 1, 2, … это стоит столько же, сколько episodes({ offset: index, limit: 1 }).

videos[].fromSec / toSec — это смещения эпизода внутри url. В v3.0 несколько эпизодов размещены в одном файле, поэтому нужно перейти к fromSec и остановиться на toSec; в v2.x у каждого эпизода свой файл, и диапазон просто охватывает его.

data указывает на строки кадров для данного эпизода, для вызывающих сторон, которые хотят самостоятельно построить график observation.state или action. fromRow включительно, а toRow исключительно; оба являются смещениями строк внутри data.url, а не индексами по всему набору данных. Для v3, когда страница начинается в середине файла данных, при перечислении эпизодов также читается футер parquet этого файла, чтобы определить, с чего он начинается. data отсутствует, если этот файл не может быть прочитан или не соответствует метаданным эпизода.

Держите один LeRobotDataset при листании эпизодов: как и info(), он запоминает файлы индекса v3.0, которые уже обработал, поэтому последующее обращение к странице или episode() сразу находит нужный файл.

Фиксация ревизии

Передавайте commit sha каждый раз, когда результат сохраняется или кэшируется где-либо, чтобы последующий push не мог изменить то, что вы проанализировали:

const dataset = new LeRobotDataset("lerobot/svla_so101_pickplace", {
	revision: "f641879e22172be7e8161d5e6c1503c2d2feb657",
});

Частные и закрытые наборы данных

Передайте собственный fetch, чтобы добавить учётные данные:

const dataset = new LeRobotDataset("my-org/private-dataset", {
	additionalFetchHeaders: { Authorization: `Bearer ${accessToken}` },
});

В браузере на huggingface.co достаточно сессионных cookie:

const dataset = new LeRobotDataset(repoId, {
	fetch: (url, init) => fetch(url, { ...init, credentials: "same-origin" }),
});

Разбор без загрузки

parseInfo является чистой функцией для вызывающих сторон, у которых уже есть байты:

import { parseInfo } from "@huggingface/lerobot";

const info = parseInfo(await readFile("meta/info.json", "utf8"));

Он вызывает исключение для любого файла, который не является пригодным для использования файлом информации, включая указатель LFS, усечённое чтение или codebase_version, не поддерживаемый этим пакетом.

Update on GitHub