Huggingface.js documentation
@c1
@c1
Hugging Face Hub上でホストされているLeRobotロボティクスデータセット用のパーサーです。
すべては範囲指定HTTPリクエストによって読み取られるため、ブラウザでもNodeでも変更なしで動作し、データセット全体をダウンロードせずにそのデータセットに関する質問に答えることができます。
なぜ
LeRobotのデータセットには2つのレイアウトがあります。v2.0 / v2.1では、各エピソードに専用の動画ファイルとparquetファイルがあり、エピソードのインデックスはJSON Linesファイルです。一方、v3.0ではエピソードが共有ファイルに連結され、インデックスはparquet形式となるため、エピソードはより大きなファイル内のバイト範囲と時間範囲として定義されます。
このパッケージは、その違いをLeRobotEpisodeという単一の形状の背後に隠しています。
インストール
npm install @huggingface/lerobot
hyparquet が同梱されており、v3.0 のエピソードインデックスおよびフレームデータの読み取りに使用されます。fzstd は、hyparquet に組み込まれている SNAPPY に加えて ZSTD を追加します。どちらもオンデマンドでインポートされるため、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 noneoffset はインデックス内の位置を数えますが、データセットがエピソードを 0, 1, 2, … と番号付けしている場合のみ、エピソードのインデックスと一致します。10 から始まるものや、削除されたエピソードをスキップするものもあるため、指定されたエピソードを開くには episode(index) を使用してください。0, 1, 2, … と番号付けされたデータセットでは、episodes({ offset: index, limit: 1 }) と同じコストです。
videos[].fromSec / toSec は、url 内のエピソードのオフセットです。v3.0 では複数のエピソードが 1 つのファイルを共有するため、fromSec までシークして toSec で停止します。v2.x では各エピソードが独自のファイルを持ち、範囲は単にそのファイル全体をカバーします。
data は、observation.state や action を呼び出し側でプロットしたい場合に、そのエピソードのフレーム行を指します。fromRow は開始行を含み、toRow は終了行を含まない範囲です。両方とも、データセット全体でのインデックスではなく、data.url 内の行オフセットです。v3 では、ページがデータファイルの途中から始まる場合、エピソードの一覧を取得するために、そのファイルの parquet フッターを読み取り、開始位置を特定します。ファイルを読み取れない場合、またはエピソードのメタデータと一致しない場合は、data が存在しません。
エピソードをページングする間、LeRobotDatasetを1つ保持します。info()と同様に、v3.0のインデックスファイルを走査した履歴を保持しているため、後続のページやepisode()の参照では、対象を含むファイルに直接アクセスできます。
リビジョンの固定
結果がどこかに保存またはキャッシュされる場合は、常にコミット 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のブラウザでは、セッションクッキーだけで十分です:
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などに対して例外をスローします。