Refine robot milestones and make GPU setup reproducible
This commit is contained in:
Vendored
+43
-112
@@ -1,131 +1,62 @@
|
||||
# 机器拓扑 & 环境 & 协作模型
|
||||
# GPU 环境与机器记录
|
||||
|
||||
> 本文件记录各机器角色、连接方式、软件环境,以及**我和你的协作方式**。**每次改动后更新。**
|
||||
> `[待补]` = 需要你在对应机器上跑命令后回填。
|
||||
基线:LeRobot 0.6.1 / Python 3.12。脚本适用 Ubuntu x86_64 GPU 主机;不用于 Windows 或 RPi。当前 GPU 环境与模型训练均未验收。
|
||||
|
||||
## ⭐ 协作模型(先读这个)
|
||||
## 分工与路径
|
||||
|
||||
| 角色 | 机器 | 谁操作 |
|
||||
| 机器 | 用途 | 环境记录 |
|
||||
|---|---|---|
|
||||
| **主家(开发+臂+推理)** | **② 3080 机(10GB · 本地 Ubuntu · 机器人旁)** | **你**(本地终端) |
|
||||
| **训练专用** | **③ 3090 机(24GB · 远程 SSH)** | **你**(SSH) |
|
||||
| 写字台(写代码/规划/文档) | ① 本 Windows 机 `D:\robot\lerobot` | **我(agent)** |
|
||||
| 富余算力(非关键路径) | ⑤ AWU408 双 Orin | 暂不用 |
|
||||
| 上机驱动板(P3/P4 起) | ④ RPi 5 | P3/P4 前你配 |
|
||||
| Windows | 编辑、静态检查、git 同步 | 本仓库 `D:\robot\lerobot` |
|
||||
| 3080 10GB | USB 遥操、采集、推理,首次解析依赖 | OS/驱动/Python/uv/锁 SHA256:待填 |
|
||||
| 3090 24GB | 训练,同局域网 | OS/驱动/Python/uv/锁 SHA256:待填 |
|
||||
| RPi 5 | P3 起硬件驱动、采图、执行和故障处理 | ARM64 环境另行验证,不复用 x86_64 锁 |
|
||||
| DRIVE Orin | 可选实验 | 不阻塞主线 |
|
||||
|
||||
**关键约束**:我的沙箱**无外网**,够不到你任何一台 GPU 机。工作流:
|
||||
GPU 机统一路径:项目 `~/robot/proj`;专用环境 `~/robot/.venv-lerobot-0.6.1`;数据 `~/robot/data`;模型 `~/robot/models`;训练输出 `~/robot/outputs`;安装报告 `~/robot/reports`。脚本支持 `ROBOT_WORKDIR`,改动后相应调整命令。
|
||||
|
||||
```
|
||||
我(①写字台)写代码/配置 ──你 push──▶ git 库 ──clone/pull──▶ ② 3080 & ③ 3090
|
||||
你在 ②/③ 执行(本地终端 / SSH)──粘回完整输出──▶ 我诊断/迭代
|
||||
```
|
||||
## 首次安装与依赖锁
|
||||
|
||||
**git 仓库**:`https://git.hyonglin.top/ylhan/lerobot_learn.git`(身份 ylhan <ylhan@hyonglin.com>;**匿名可读** → GPU 机 clone 免密,push 才需认证)
|
||||
前置:安装 NVIDIA 驱动、git、uv、FFmpeg。脚本用 uv 创建 Python 3.12 环境(必要时 uv 下载 Python),不自动 sudo 安装系统组件。缺少前置即退出。
|
||||
|
||||
**约定**:
|
||||
1. 我给**自包含、复制即跑**的脚本/命令块(尽量一次给全)。
|
||||
2. **代码/配置**走 git 库(你 push,两机 pull);**数据集/模型**走 HF Hub(hf-mirror)或局域网 rsync(两机互通,大文件直传更快)。
|
||||
3. 两台 GPU 机目录统一 `~/robot/`:本仓库 + lerobot clone + `.venv`。
|
||||
先在 3080:
|
||||
|
||||
---
|
||||
|
||||
## 拓扑总览
|
||||
|
||||
```
|
||||
┌──────────────────────┐ push ┌───────┐ clone/pull ┌─────────────────────────┐
|
||||
│ ① Windows 写字台 │ ──────▶ │ git 库 │ ──────────▶ │ ② 3080 主家 (10GB) │
|
||||
│ D:\robot\lerobot │ └───────┘ ⟨同一库⟩ │ 本地 Ubuntu · 机器人旁 │
|
||||
│ 我写代码/文档/规划 │ ┌────────┴─────────────────────────┐
|
||||
└──────────────────────┘ │ ③ 3090 训练 (24GB) · 远程 SSH │
|
||||
└───────────────────────────────────┘
|
||||
② ↔ ③ 同一局域网:rsync 直传数据集/模型;π0 推理紧张时 3090 可代推
|
||||
|
||||
② 3080 主家(推理芯,挨着机器人 = 低延迟):
|
||||
开发 · 臂 USB 直连 · 遥操 · 采数 · 推理部署 · P4 policy server
|
||||
③ 3090 训练(训练芯):
|
||||
只跑 lerobot-train:ACT / SmolVLA 全量 / π0-FAST LoRA
|
||||
数据流: 采数@② → HF Hub(或 rsync) → 训练@③ → 模型 → 推理@②
|
||||
```
|
||||
|
||||
**为什么这样拆**:训练吃显存(参数+梯度+优化器+激活 ≈ 推理的 4~8 倍),推理不吃。
|
||||
- 3090 24GB:SmolVLA 全量微调 / π0-FAST LoRA —— 只有它干得动。
|
||||
- 3080 10GB:ACT(<1GB) / SmolVLA fp16(~2GB) 推理绰绰有余;遥操/采数几乎不占 GPU。
|
||||
|
||||
---
|
||||
|
||||
## ② 3080 机(主家 · 10GB · 本地 Ubuntu · 机器人旁)
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 位置 | **机器人/工作台旁**(SO-101 臂 USB 直插它) |
|
||||
| 主机名 / IP | `[待补]` |
|
||||
| Ubuntu 版本 | `[待补]`(建议 22.04) |
|
||||
| GPU | **3080(10GB)** —— 开发 + 推理 |
|
||||
| 驱动 / CUDA | `[待补]`(setup 脚本会打印) |
|
||||
| Python | **3.12**(venv,脚本自建) |
|
||||
| LeRobot | `[待补]`(预期 0.6.x) |
|
||||
| HF 账号 | `huggingface-cli login`(HF_ENDPOINT=hf-mirror) |
|
||||
| 目录 | `~/robot/`(本仓库 + lerobot + .venv) |
|
||||
|
||||
**跑什么**:日常开发、`lerobot-teleoperate` / `lerobot-record`(臂插这)、`lerobot-eval|rollout`(推理部署)、P4 的 policy server。
|
||||
**显存预算**:ACT <1GB ✅ / SmolVLA fp16 ~2GB ✅ / π0-FAST ~7GB ⚠️(fallback 见文末)。
|
||||
|
||||
## ③ 3090 机(训练专用 · 24GB · 远程 SSH)
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 访问 | **SSH**(远程,与 ② 同局域网互通) |
|
||||
| 主机名 / IP | `[待补]` |
|
||||
| Ubuntu 版本 | `[待补]` |
|
||||
| GPU | **3090(24GB)** —— 只管训练 |
|
||||
| Python / LeRobot | 与 ② 同一 setup 脚本 |
|
||||
| 目录 | `~/robot/`(同一 git 库) |
|
||||
|
||||
**跑什么**:只跑 `lerobot-train`(拉数据集 → 训 → 推模型回 Hub)。
|
||||
**兜底角色**:π0-FAST 推理在 ② 放不下时**代推**(同局域网+异步分块,多一跳延迟可接受);② 忙时也可顶 ACT / SmolVLA-LoRA 训练。
|
||||
|
||||
### 两机传大文件(同局域网,比 HF Hub 快)
|
||||
```bash
|
||||
# ② → ③ 推数据集
|
||||
rsync -avzP ~/robot/data/ <user>@<3090-ip>:~/robot/data/
|
||||
# ③ → ② 拉训练好的模型
|
||||
rsync -avzP <user>@<3090-ip>:~/robot/outputs/train/<exp>/ ~/robot/models/<exp>/
|
||||
mkdir -p ~/robot
|
||||
git clone https://git.hyonglin.top/ylhan/lerobot_learn.git ~/robot/proj
|
||||
bash ~/robot/proj/env/setup_lerobot.sh --resolve
|
||||
```
|
||||
|
||||
## ① 本 Windows 机(`D:\robot\lerobot` · 我的写字台)
|
||||
产生 `env/requirements-linux-py312.lock` 和 `env/requirements-linux-py312.lock.input.sha256`。第一次解析尚不是经过验证的完整环境锁:先完成脚本检查,再做短视频编码/解码、小样本训练、保存和重新加载模型。
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 角色 | 写代码 / 规划 / 文档;**不跑 LeRobot** |
|
||||
| Python | 3.14(LR 要 3.12;本机只编辑) |
|
||||
| git | 2.51.0 ✅ |
|
||||
| 外网 | ❌ 沙箱无外网 |
|
||||
| 同步 | **你从本机 push 到 git 库** → ② ③ pull |
|
||||
将这两个文件一起传到 3090 同一项目的 `env/` 目录,再运行:
|
||||
|
||||
## ④ RPi 5(上机驱动板 · P3/P4 起)
|
||||
```bash
|
||||
bash ~/robot/proj/env/setup_lerobot.sh
|
||||
source ~/robot/.venv-lerobot-0.6.1/bin/activate
|
||||
```
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| OS | Raspberry Pi OS 64-bit |
|
||||
| 连接 | USB(有源 Hub):2 臂 + 3 轮 + 3 相机;**以太网 → ② 3080**(policy server 在它上面) |
|
||||
| 软件 | LeRobot `.[feetech,lekiwi,dataset]` + thin client(推图/收 chunk/执行/fail-safe) |
|
||||
| 静态 IP | `[待补]` |
|
||||
默认安装严格使用锁与包哈希,不重新解析。两台比较报告中的锁 SHA256;验收通过后把锁、输入指纹与精简环境信息提交 git。**当前仓库尚未包含经过 Ubuntu/GPU 验证的传递依赖锁,默认安装会明确拒绝继续。**
|
||||
|
||||
## ⑤ AWU408(富余算力,非关键路径)
|
||||
- 双 DRIVE Orin(508 TOPS)+ Aurix TC397。默认不用。
|
||||
- 用途:3090 忙训练时顶推理 / 固定台。
|
||||
- **待验证**:能否刷 Ubuntu+CUDA+PyTorch(常出厂 QNX/DRIVE OS);跑不通就不管它。
|
||||
两台尽量统一 Ubuntu 版本,记录 Python 补丁版本、uv 版本与 NVIDIA 驱动;同一 Python 包锁不能锁定系统库或驱动。脚本 `uv pip sync` 仅作用于新命名的项目专用环境,会使其中包与锁一致,请勿把它用于其他项目。
|
||||
|
||||
---
|
||||
更新依赖时修改 `requirements.in`,人工归档旧锁及指纹后重新解析、两机复验;脚本拒绝覆盖已有锁,也不会自动更新 LeRobot。大模型、双臂移动所需新 extras 在对应阶段再加入输入并复验。
|
||||
|
||||
## 国内网络 / 镜像(两台 GPU 机通用,setup 脚本自动处理)
|
||||
| 用途 | 直连不可达时的镜像 |
|
||||
|---|---|
|
||||
| pip | `https://pypi.tuna.tsinghua.edu.cn/simple`(或 Aliyun) |
|
||||
| HF dataset/weights | `HF_ENDPOINT=https://hf-mirror.com` |
|
||||
| git clone lerobot | `https://ghproxy.com/https://github.com/huggingface/lerobot.git` |
|
||||
## 网络与数据
|
||||
|
||||
## π0-FAST 推理在 3080(10GB) 放不下时的 fallback(P5 才需要)
|
||||
1. **4-bit 量化**(权重 6.6GB → ~2GB,立刻宽裕)
|
||||
2. **batch=1 + bf16 硬试**(~8-9GB,可能刚好)
|
||||
3. **3090 代推**:policy server 起在 ③,② 只做遥操/采数(同局域网,异步分块下延迟可接受)
|
||||
默认使用官方索引。若需要镜像,可在安装前显式设置 `UV_DEFAULT_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple`;uv 自身的 Python 下载不由该变量代理。下载失败应按报告排查,不自动切换不明 Git 代理。
|
||||
|
||||
同局域网优先 rsync。HF Hub 可选;登录使用 `hf auth login`,认证上传使用官方端点,勿把下载镜像当作上传服务。Token 保存在机器凭据环境中,不进入 git、报告或聊天。
|
||||
|
||||
```bash
|
||||
# 将占位符替换成自己的 SSH 目标;先停止录制,传完整且不再写入的数据目录。
|
||||
rsync -avP ~/robot/data/ USER@TRAIN_HOST:~/robot/data/
|
||||
rsync -avP USER@TRAIN_HOST:~/robot/outputs/ ~/robot/outputs/
|
||||
```
|
||||
|
||||
每个实验保留数据版本/校验值、模型与处理器、配置、校准备份和评测记录。模型快照记录来源 revision,不自动随 Hub main 更新。同步代码使用 git;当前未配置 GPU 主机远程访问,因此 GPU 执行结果需从目标机器回传。
|
||||
|
||||
## 验收报告
|
||||
|
||||
脚本失败即非零退出,不把 MISS 当通过;输出完整日志、包列表、Python/FFmpeg 版本、CLI 帮助与锁哈希。脚本验证 CUDA 矩阵运算、实际策略模块和视频库导入,不连接电机,也不下载模型权重。
|
||||
|
||||
后续必须记录:录制/解码结果、训练步耗时、训练和推理峰值显存、单次推理 P50/P95/P99,以及 20 次真机评测。不要将包可导入或显存参考值当作任务能力证据。
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
# P0/P1: Ubuntu x86_64 GPU hosts, Python 3.12.
|
||||
# Resolve once on 3080; share the lock and its input fingerprint with 3090.
|
||||
# ACT uses the base dependencies; v0.6.1 has no 'act' extra.
|
||||
lerobot[core_scripts,training,feetech,smolvla]==0.6.1
|
||||
Vendored
+91
-114
@@ -1,116 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================
|
||||
# LeRobot 一键环境 — 3080 主家 / 3090 训练机(两台 Ubuntu 都跑一遍)
|
||||
# 用法:
|
||||
# nano ~/robot/setup_lerobot.sh # 粘入本文件
|
||||
# bash ~/robot/setup_lerobot.sh
|
||||
# 跑完把【整段输出】粘回给助手,我带你走 P1。
|
||||
# ============================================================
|
||||
set -uo pipefail
|
||||
|
||||
WORKDIR="${HOME}/robot"
|
||||
LEROBOT_DIR="${WORKDIR}/lerobot"
|
||||
VENV="${WORKDIR}/.venv"
|
||||
PY=3.12
|
||||
# LeRobot extras:feetech(SO-101) + lekiwi(底盘) + dataset(采数) + smolvla(主力VLA) + pi0(π0/π0-FAST)
|
||||
EXTRAS="feetech,lekiwi,dataset,smolvla,pi0"
|
||||
|
||||
hr(){ echo; echo "========== $* =========="; }
|
||||
|
||||
hr "[1/7] 环境探测"
|
||||
if [ -r /etc/os-release ]; then . /etc/os-release; echo "OS: ${PRETTY_NAME:-?}"; fi
|
||||
if command -v nvidia-smi >/dev/null 2>&1; then
|
||||
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader
|
||||
else
|
||||
echo "!! 未检测到 nvidia-smi —— GPU 驱动可能没装(3090 应能识别)。先装驱动再继续。"
|
||||
fi
|
||||
echo "系统 python3: $(python3 --version 2>&1)"
|
||||
echo "有 python3.12: $([ -x "$(command -v python3.12)" ] && echo 是 || echo 否)"
|
||||
echo "有 uv: $([ -x "$(command -v uv)" ] && echo 是 || echo 否)"
|
||||
echo "有 git: $(git --version 2>&1)"
|
||||
echo "有 ffmpeg: $([ -x "$(command -v ffmpeg)" ] && echo 是 || echo 否)"
|
||||
|
||||
hr "[2/7] 网络/镜像策略(直连 vs 国内镜像)"
|
||||
PIP_URL="https://pypi.org/simple"
|
||||
if curl -fsS --max-time 6 https://pypi.org >/dev/null 2>&1; then
|
||||
echo "pypi 直连可达 → 官方源"
|
||||
else
|
||||
echo "pypi 直连不可达 → 清华镜像"; PIP_URL="https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||
fi
|
||||
if curl -fsS --max-time 6 https://huggingface.co >/dev/null 2>&1; then
|
||||
echo "HF 直连可达 → 官方"; HF_ENDPOINT="https://huggingface.co"
|
||||
else
|
||||
echo "HF 直连不可达 → hf-mirror"; HF_ENDPOINT="https://hf-mirror.com"
|
||||
fi
|
||||
export HF_ENDPOINT
|
||||
echo "→ PIP_URL=$PIP_URL"; echo "→ HF_ENDPOINT=$HF_ENDPOINT"
|
||||
|
||||
hr "[3/7] Python ${PY} venv (${VENV})"
|
||||
mkdir -p "${WORKDIR}"
|
||||
if [ -d "${VENV}" ]; then echo "venv 已存在,复用"; else
|
||||
if command -v uv >/dev/null 2>&1; then
|
||||
uv venv --python ${PY} "${VENV}"
|
||||
elif command -v python3.12 >/dev/null 2>&1; then
|
||||
python3.12 -m venv "${VENV}"
|
||||
elif command -v python3.11 >/dev/null 2>&1; then
|
||||
echo "无 3.12,用 3.11 兜底(LeRobot 要 3.12,可能装不上,建议装 uv 或 deadsnakes 3.12)"
|
||||
python3.11 -m venv "${VENV}"
|
||||
else
|
||||
echo "!! 没有 3.12/3.11/uv。装 uv: curl -LsSf https://astral.sh/uv/install.sh | sh 然后重跑"; exit 1
|
||||
fi
|
||||
fi
|
||||
# shellcheck disable=SC1091
|
||||
source "${VENV}/bin/activate"
|
||||
python -m pip install -U pip -i "${PIP_URL}"
|
||||
echo "venv python: $(python --version) ($(which python))"
|
||||
|
||||
hr "[4/7] clone LeRobot → ${LEROBOT_DIR}"
|
||||
if [ -d "${LEROBOT_DIR}/.git" ]; then
|
||||
echo "已存在 → git pull 更新"; ( cd "${LEROBOT_DIR}" && git pull ) || true
|
||||
else
|
||||
if curl -fsS --max-time 6 https://github.com >/dev/null 2>&1; then
|
||||
git clone https://github.com/huggingface/lerobot.git "${LEROBOT_DIR}"
|
||||
else
|
||||
echo "github 直连慢/不可达 → 走 ghproxy 加速"
|
||||
git clone https://ghproxy.com/https://github.com/huggingface/lerobot.git "${LEROBOT_DIR}"
|
||||
fi
|
||||
fi
|
||||
cd "${LEROBOT_DIR}"
|
||||
echo "当前 commit: $(git log -1 --oneline 2>/dev/null)"
|
||||
|
||||
hr "[5/7] 安装 LeRobot [${EXTRAS}]"
|
||||
pip install -e ".[${EXTRAS}]" -i "${PIP_URL}" 2>&1 | tail -n 25
|
||||
# ffmpeg(LeRobot 编视频需要)
|
||||
if ! command -v ffmpeg >/dev/null 2>&1; then
|
||||
echo "装 ffmpeg ..."; ( sudo apt-get install -y ffmpeg 2>&1 || conda install -y -c conda-forge ffmpeg 2>&1 ) | tail -n 5
|
||||
fi
|
||||
|
||||
hr "[6/7] 验证"
|
||||
python - <<'PY'
|
||||
import importlib, torch
|
||||
print("torch", torch.__version__,
|
||||
"| cuda", torch.cuda.is_available(),
|
||||
"| gpu", (torch.cuda.get_device_name(0) if torch.cuda.is_available() else "N/A"),
|
||||
"| vram_GB", round(torch.cuda.get_device_properties(0).total_memory/1e9,1) if torch.cuda.is_available() else 0)
|
||||
try:
|
||||
import lerobot; print("lerobot", getattr(lerobot, "__version__", "?"))
|
||||
except Exception as e:
|
||||
print("lerobot import 失败:", e)
|
||||
for m in ["lerobot.policies.smolvla","lerobot.policies.pi0","lerobot.policies.act"]:
|
||||
try: importlib.import_module(m); print("OK ", m)
|
||||
except Exception as e: print("MISS", m, "->", e)
|
||||
PY
|
||||
echo "--- CLI 命令 ---"
|
||||
for c in lerobot-find-port lerobot-find-cameras lerobot-calibrate lerobot-teleoperate lerobot-record lerobot-train lerobot-eval lerobot-rollout; do
|
||||
command -v "$c" >/dev/null 2>&1 && echo "OK $c" || echo "MISS $c"
|
||||
# Ubuntu x86_64 GPU hosts. First host: --resolve; second host: same lock.
|
||||
set -Eeuo pipefail
|
||||
trap 'printf "ERROR at line %s: environment NOT verified.\n" "$LINENO" >&2' ERR
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
WORKDIR="${ROBOT_WORKDIR:-${HOME}/robot}"
|
||||
VENV="${WORKDIR}/.venv-lerobot-0.6.1"
|
||||
LOCK="${SCRIPT_DIR}/requirements-linux-py312.lock"
|
||||
INPUT="${SCRIPT_DIR}/requirements.in"
|
||||
RESOLVE=false
|
||||
case "${1:-}" in
|
||||
--resolve) RESOLVE=true ;;
|
||||
--help) echo "Usage: bash $0 [--resolve] (Linux x86_64, uv, NVIDIA driver, ffmpeg)"; exit 0 ;;
|
||||
"") ;;
|
||||
*) echo "Unknown argument: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
[[ $# -le 1 ]] || { echo "Too many arguments" >&2; exit 2; }
|
||||
[[ "$(uname -s)" == Linux && "$(uname -m)" == x86_64 ]] || {
|
||||
echo "Only Linux x86_64 GPU hosts are supported; RPi needs a separate environment." >&2; exit 1;
|
||||
}
|
||||
for cmd in uv nvidia-smi ffmpeg sha256sum; do
|
||||
command -v "$cmd" >/dev/null || { echo "Missing prerequisite: $cmd" >&2; exit 1; }
|
||||
done
|
||||
|
||||
hr "[7/7] 完成 — 之后每次用 3090 前先:"
|
||||
cat <<EOF
|
||||
source ${VENV}/bin/activate
|
||||
cd ${LEROBOT_DIR}
|
||||
export HF_ENDPOINT=${HF_ENDPOINT}
|
||||
huggingface-cli login # 首次: 输你的 HF token
|
||||
EOF
|
||||
echo "✅ 把上面 [1]~[7] 的完整输出粘回给助手。"
|
||||
echo " 若全 OK,我们就进 P1:插第一条 SO-101 → lerobot-find-port → 校准 → 遥操。"
|
||||
if ! $RESOLVE && [[ ! -s "$LOCK" ]]; then
|
||||
echo "Missing lock: use --resolve on 3080 first; transfer the validated lock and .input.sha256 to 3090." >&2; exit 1
|
||||
fi
|
||||
if $RESOLVE && [[ -e "$LOCK" || -e "$LOCK.input.sha256" ]]; then
|
||||
echo "Refusing to overwrite existing lock. Review and archive it before an intentional update." >&2; exit 1
|
||||
fi
|
||||
mkdir -p "$WORKDIR"
|
||||
REPORT="${WORKDIR}/reports/$(date -u +%Y%m%dT%H%M%SZ)-$$"
|
||||
mkdir -p "$REPORT"
|
||||
exec > >(tee "$REPORT/setup.log") 2>&1
|
||||
echo "[1/5] Prerequisites"
|
||||
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader
|
||||
uv --version
|
||||
ffmpeg -version > "$REPORT/ffmpeg.txt"
|
||||
# Set UV_DEFAULT_INDEX explicitly if a mirror is needed. No automatic Hub/token routing.
|
||||
echo "[2/5] Dedicated Python 3.12 environment"
|
||||
if [[ ! -d "$VENV" ]]; then uv venv --python 3.12 "$VENV"; fi
|
||||
PYTHON="${VENV}/bin/python"
|
||||
"$PYTHON" -c 'import sys; assert sys.version_info[:2] == (3, 12), sys.version'
|
||||
if $RESOLVE; then
|
||||
TEMP_LOCK="$(mktemp "${LOCK}.tmp.XXXXXX")"
|
||||
trap 'rm -f -- "$TEMP_LOCK"' EXIT
|
||||
uv pip compile "$INPUT" --python "$PYTHON" --generate-hashes --output-file "$TEMP_LOCK"
|
||||
mv -- "$TEMP_LOCK" "$LOCK"
|
||||
(cd "$SCRIPT_DIR" && sha256sum requirements.in) > "$LOCK.input.sha256"
|
||||
trap - EXIT
|
||||
fi
|
||||
[[ -s "$LOCK.input.sha256" ]] || { echo "Missing input fingerprint" >&2; exit 1; }
|
||||
(cd "$SCRIPT_DIR" && sha256sum --check "${LOCK}.input.sha256")
|
||||
echo "[3/5] Install locked packages (dedicated venv only)"
|
||||
uv pip sync --python "$PYTHON" --require-hashes "$LOCK"
|
||||
uv pip check --python "$PYTHON"
|
||||
echo "[4/5] GPU, policy implementations, video libraries and CLI"
|
||||
"$PYTHON" - <<'PY'
|
||||
import importlib
|
||||
import importlib.metadata
|
||||
import torch
|
||||
assert importlib.metadata.version('lerobot') == '0.6.1'
|
||||
assert torch.cuda.is_available(), 'CUDA unavailable: check driver and torch build'
|
||||
x = torch.ones((32, 32), device='cuda')
|
||||
assert (x @ x).sum().item() == 32768
|
||||
torch.cuda.synchronize()
|
||||
print('torch:', torch.__version__, 'CUDA:', torch.version.cuda, 'GPU:', torch.cuda.get_device_name(0))
|
||||
for module in (
|
||||
'lerobot.policies.act.modeling_act',
|
||||
'lerobot.policies.smolvla.modeling_smolvla',
|
||||
'lerobot.robots.so_follower',
|
||||
'lerobot.teleoperators.so_leader',
|
||||
'av', 'torchcodec',
|
||||
):
|
||||
importlib.import_module(module)
|
||||
print('OK:', module)
|
||||
PY
|
||||
for cli in lerobot-find-port lerobot-find-cameras lerobot-setup-motors lerobot-calibrate lerobot-teleoperate lerobot-record lerobot-train lerobot-rollout; do
|
||||
[[ -x "$VENV/bin/$cli" ]] || { echo "Missing CLI: $cli" >&2; exit 1; }
|
||||
done
|
||||
# find-port ignores --help and starts an interactive USB discovery procedure.
|
||||
# Discovery tools are checked for existence only; never invoke them in setup.
|
||||
for cli in lerobot-setup-motors lerobot-calibrate lerobot-teleoperate lerobot-record lerobot-train lerobot-rollout; do
|
||||
"$VENV/bin/$cli" --help > "$REPORT/$cli-help.txt" 2>&1
|
||||
done
|
||||
echo "[5/5] Save verification evidence"
|
||||
uv pip freeze --python "$PYTHON" > "$REPORT/packages.txt"
|
||||
"$PYTHON" -VV > "$REPORT/python.txt"
|
||||
sha256sum "$LOCK" > "$REPORT/lock.sha256"
|
||||
cp -- "$LOCK" "$LOCK.input.sha256" "$REPORT/"
|
||||
echo "PASS: software smoke checks only; recording, model training and robot safety remain unverified."
|
||||
echo "Report: $REPORT"
|
||||
printf 'Activate: source %q/bin/activate\n' "$VENV"
|
||||
echo "Use hf auth login only if accessing the Hub; use the official endpoint for authenticated uploads."
|
||||
|
||||
Reference in New Issue
Block a user