Huggingface.js documentation
@huggingface/lerobot
@huggingface/lerobot
Hugging Face Hubμ νΈμ€ν λ LeRobot λ‘λ΄ λ°μ΄ν°μ μ μν νμμ λλ€.
λͺ¨λ λ°μ΄ν°λ ranged HTTP μμ²μ ν΅ν΄ μ½νλ―λ‘, λΈλΌμ°μ μ Nodeμμ λͺ¨λ λ³κ²½ μμ΄ μλνλ©°, λ°μ΄ν°μ μ λν μ§λ¬Έμ λ΅νκΈ° μν΄ μ 체 λ°μ΄ν°μ μ λ€μ΄λ‘λνμ§ μμ΅λλ€.
μ
LeRobot λ°μ΄ν°μ
μ λ κ°μ§ λ μ΄μμμΌλ‘ μ‘΄μ¬ν©λλ€. 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μμλ μ¬λ¬ μνΌμλκ° νλμ νμΌμ 곡μ νλ―λ‘ fromSecλ‘ μνΉνκ³ toSecμμ λ©μΆλ©°, v2.xμμλ κ° μνΌμλκ° μ체 νμΌμ κ°μ§λ―λ‘ ν΄λΉ λ²μκ° νμΌμ κ·Έλλ‘ ν¬ν¨ν©λλ€.
dataλ ν΄λΉ μνΌμλμ νλ μ νμ κ°λ¦¬ν€λ©°, observation.state λλ actionλ₯Ό μ§μ μ°¨νΈλ‘ νμνλ €λ νΈμΆμλ₯Ό μν κ²μ
λλ€. fromRowλ ν¬ν¨λκ³ toRowλ μ μΈλ©λλ€. λ λ€ λ°μ΄ν°μ
μ 체μ μΈλ±μ€κ° μλλΌ data.url λ΄λΆμ ν μ€νμ
μ
λλ€. v3μ κ²½μ°, νμ΄μ§κ° λ°μ΄ν° νμΌ μ€κ°μμ μμλλ©΄ μνΌμλλ₯Ό λμ΄ν λ ν΄λΉ νμΌμ parquet νΈν°λ₯Ό μ½μ΄μ μμ μμΉλ₯Ό μ°Ύμ΅λλ€. νμΌμ μ½μ μ μκ±°λ μνΌμλ λ©νλ°μ΄ν°μ μΌμΉνμ§ μμΌλ©΄ dataκ° μμ΅λλ€.
LeRobotDataset νλλ₯Ό μ μ§νλ©΄μ μνΌμλλ₯Ό νμ΄μ§λ³λ‘ νμν©λλ€. info()μ λ§μ°¬κ°μ§λ‘, v3.0 μΈλ±μ€ νμΌ μ€ μ΄λ―Έ νμν νμΌμ κΈ°μ΅νλ―λ‘ μ΄νμ νμ΄μ§λ episode() μ‘°νλ ν΄λΉ λ°μ΄ν°λ₯Ό ν¬ν¨νλ νμΌλ‘ λ°λ‘ μ΄λν©λλ€.
리λΉμ κ³ μ
κ²°κ³Όκ° μ΄λμ μ μ₯λκ±°λ μΊμλλ κ²½μ°, λμ€μ pushλ₯Ό ν΅ν΄ νμ±ν λ΄μ©μ΄ λ³κ²½λμ§ μλλ‘ νμ commit shaλ₯Ό μ λ¬νμΈμ:
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" }),
});fetching μμ΄ νμ±
parseInfoλ μμ ν¨μλ‘, μ΄λ―Έ λ°μ΄νΈλ₯Ό κ°μ§ νΈμΆμμκ² μ ν©ν©λλ€:
import { parseInfo } from "@huggingface/lerobot";
const info = parseInfo(await readFile("meta/info.json", "utf8"));μ¬μ©ν μ μλ info νμΌμ΄ μλ λͺ¨λ νλͺ©μμ μμΈλ₯Ό λ°μμν€λ©°, μ¬κΈ°μλ LFS ν¬μΈν°, μλ¦° μ½κΈ°, μ΄ ν¨ν€μ§κ° ꡬννμ§ μμ codebase_versionμ΄ ν¬ν¨λ©λλ€.