Instructions to use AlexWortega/tinyvla with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LeRobot
How to use AlexWortega/tinyvla with LeRobot:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
File size: 5,998 Bytes
1601a2f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | #!/usr/bin/env python
"""Prepare the SO-100/101 slice of HuggingFaceVLA/community_dataset_v3.
Steps:
catalog — fetch all sub-dataset info.json, write catalog.json
select — filter SO100/101 single-arm, rank by episodes, write selection.json
convert — download each selected subdir + convert v2.1 -> v3.0 locally
Usage:
python scripts/prepare_community_v3.py catalog
python scripts/prepare_community_v3.py select --target-episodes 12000
python scripts/prepare_community_v3.py convert [--limit N]
"""
from __future__ import annotations
import argparse
import json
import shutil
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
AGG_REPO = "HuggingFaceVLA/community_dataset_v3"
DISK_BUDGET_GB = 400
DATA_ROOT = Path.home() / "tinyvla_data"
CATALOG = DATA_ROOT / "community_v3_catalog.json"
SELECTION = DATA_ROOT / "community_v3_selection.json"
CONVERTED_DIR = DATA_ROOT / "so101_v3"
SO_ROBOTS = {"so100", "so101", "so100_follower", "so101_follower"}
def cmd_catalog(args):
from huggingface_hub import HfApi, hf_hub_download
api = HfApi()
files = api.list_repo_files(AGG_REPO, repo_type="dataset")
subs = sorted(f.rsplit("/meta/info.json", 1)[0] for f in files if f.endswith("meta/info.json"))
print(f"{len(subs)} sub-datasets")
def fetch(sub):
try:
p = hf_hub_download(AGG_REPO, f"{sub}/meta/info.json", repo_type="dataset")
info = json.load(open(p))
return sub, {
"robot_type": info.get("robot_type"),
"episodes": info.get("total_episodes"),
"frames": info.get("total_frames"),
"fps": info.get("fps"),
"version": info.get("codebase_version"),
"action_shape": info.get("features", {}).get("action", {}).get("shape"),
"cameras": [k for k in info.get("features", {}) if k.startswith("observation.images")],
}
except Exception as e:
return sub, {"error": str(e)[:100]}
catalog = {}
with ThreadPoolExecutor(16) as ex:
futs = [ex.submit(fetch, s) for s in subs]
for i, f in enumerate(as_completed(futs)):
sub, meta = f.result()
catalog[sub] = meta
if (i + 1) % 100 == 0:
print(f"{i+1}/{len(subs)}")
DATA_ROOT.mkdir(parents=True, exist_ok=True)
CATALOG.write_text(json.dumps(catalog, indent=1))
print(f"wrote {CATALOG}")
def cmd_select(args):
catalog = json.loads(CATALOG.read_text())
rows = [
(sub, m)
for sub, m in catalog.items()
if m.get("robot_type") in SO_ROBOTS
and m.get("action_shape") == [6]
and m.get("fps") == 30
and m.get("episodes")
and m.get("cameras")
]
# prefer larger datasets: fewer conversions per episode
rows.sort(key=lambda r: -r[1]["episodes"])
picked, total = [], 0
for sub, m in rows:
if total >= args.target_episodes:
break
picked.append({"sub": sub, **m})
total += m["episodes"]
print(f"{len(rows)} eligible; picked {len(picked)} datasets, {total} episodes")
SELECTION.write_text(json.dumps(picked, indent=1))
print(f"wrote {SELECTION}")
def free_gb(path: Path) -> float:
return shutil.disk_usage(path).free / 1e9
def used_gb_cached(path: Path) -> float:
import subprocess
out = subprocess.run(["du", "-s", "--block-size=1G", str(path)], capture_output=True, text=True)
return float(out.stdout.split()[0]) if out.returncode == 0 else 0.0
def cmd_convert(args):
from huggingface_hub import snapshot_download
from lerobot.scripts.convert_dataset_v21_to_v30 import convert_dataset
picked = json.loads(SELECTION.read_text())
if args.limit:
picked = picked[: args.limit]
CONVERTED_DIR.mkdir(parents=True, exist_ok=True)
raw_dir = DATA_ROOT / "_raw_v21"
done, failed = 0, []
for item in picked:
sub = item["sub"]
name = sub.replace("/", "__")
out = CONVERTED_DIR / name
if (out / "meta" / "info.json").exists():
done += 1
continue
local = raw_dir / name
try:
snapshot_download(
AGG_REPO,
repo_type="dataset",
allow_patterns=[f"{sub}/*"],
local_dir=raw_dir / "_dl",
)
src = raw_dir / "_dl" / sub
if local.exists():
shutil.rmtree(local)
shutil.move(str(src), str(local))
convert_dataset(repo_id=name, root=local, push_to_hub=False, force_conversion=True)
# converter writes v3.0 in place at root
shutil.move(str(local), str(out))
# drop the v2.1 originals the converter stashes as <root>_old
old = local.parent / (local.name + "_old")
if old.exists():
shutil.rmtree(old)
done += 1
print(f"[{done}/{len(picked)}] {sub}: converted -> {out} (free {free_gb(DATA_ROOT):.0f}GB)")
if free_gb(DATA_ROOT) < 150 or used_gb_cached(DATA_ROOT) > DISK_BUDGET_GB:
print("STOP: disk budget reached")
break
except Exception as e:
failed.append(sub)
print(f"FAIL {sub}: {type(e).__name__}: {str(e)[:200]}")
print(f"done={done} failed={len(failed)}")
if failed:
(DATA_ROOT / "convert_failures.json").write_text(json.dumps(failed))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
sub = parser.add_subparsers(dest="cmd", required=True)
sub.add_parser("catalog")
p_sel = sub.add_parser("select")
p_sel.add_argument("--target-episodes", type=int, default=12_000)
p_conv = sub.add_parser("convert")
p_conv.add_argument("--limit", type=int, default=None)
args = parser.parse_args()
{"catalog": cmd_catalog, "select": cmd_select, "convert": cmd_convert}[args.cmd](args)
|