Spaces:
Running
Running
stouchinglhh
Claude
sync processor from GitLab c697b6e: 版本 1.19.4 / 前端 1.12.4 —— 服务端 i18n(首屏不再闪英文)、推理模块并入模型页、前端抽出 shared/、缓存键改用前端号
bb59211 Download processor/app/training/datasets.py from Stouching-Robotics/DataFlowing: direct link, hf CLI and curl.
- Browser
- Download file 2.95 kB
-
https://huggingface.co/spaces/Stouching-Robotics/DataFlowing/resolve/main/processor/app/training/datasets.py
- Command line
-
hf download hf://spaces/Stouching-Robotics/DataFlowing/processor/app/training/datasets.py
-
curl -L -o datasets.py https://huggingface.co/spaces/Stouching-Robotics/DataFlowing/resolve/main/processor/app/training/datasets.py
2.95 kB
| """可训练数据集的发现 —— ``state/datasets/<名字>``。 | |
| 这些是**在视频审核页选中「已通过」的集、导出后留下来的成品**(落盘见 | |
| ``app/routes/export.py: _persist_trainable_dataset``)。 | |
| """ | |
| from __future__ import annotations | |
| import json | |
| from pathlib import Path | |
| from app.localstore import STATE_ROOT | |
| # 与 `app/routes/export.py` 的 DATASETS_DIR 是同一个目录。从 STATE_ROOT 推出来 | |
| # 而不是 import 那个模块:写进去的和读出来的必须指向同一处,而"唯一真源"本来 | |
| # 就是 STATE_ROOT。两边若哪天分叉,导出落下的数据集训练页就会看不见 —— | |
| # 改其中一处时记得对照另一处。 | |
| DATASETS_DIR = STATE_ROOT / "datasets" | |
| def list_datasets() -> dict: | |
| """``{"datasets": [...], "root": str, "exists": bool}``。 | |
| **不列 ``sessions/<项目>`` 原始项目。** 原始项目里混着未审核的集,而且 | |
| 留出集(UMIGripper_Action_AI 的 52–73)就在里面 —— 按项目选等于同时踩两个 | |
| 坑,UI 上只能报警拦不住。导出那一步才是唯一能明确控制"到底训了哪些集"的 | |
| 地方,所以以导出产物为准。 | |
| **也不列 ``state/exports/*``。** 那边是按 run_id 命名的**处理产物**,实测 | |
| 168 条里每条 ``total_episodes`` 都是 1(单集),凑不成训练集。 | |
| """ | |
| root = DATASETS_DIR | |
| if not root.is_dir(): | |
| return {"datasets": [], "root": str(root), "exists": False} | |
| datasets: list[dict] = [] | |
| try: | |
| for entry in sorted(root.iterdir()): | |
| # 跳过 .staging / .old 这类交换中间态 —— 它们只在替换过程中短暂出现。 | |
| if not entry.is_dir() or entry.name.startswith("."): | |
| continue | |
| info_path = entry / "meta" / "info.json" | |
| if not info_path.is_file(): | |
| continue | |
| try: | |
| info = json.loads(info_path.read_text(encoding="utf-8")) | |
| except (OSError, ValueError): | |
| continue | |
| if not isinstance(info, dict): | |
| continue | |
| episodes = int(info.get("total_episodes") or 0) | |
| if episodes <= 0: | |
| continue | |
| try: | |
| mtime = int(info_path.stat().st_mtime) | |
| except OSError: | |
| mtime = 0 | |
| datasets.append({ | |
| "name": entry.name, | |
| "path": str(entry), | |
| "total_episodes": episodes, | |
| "total_frames": int(info.get("total_frames") or 0), | |
| "fps": float(info.get("fps") or 0), | |
| "codebase_version": str(info.get("codebase_version") or ""), | |
| "mtime": mtime, | |
| }) | |
| except OSError: | |
| return {"datasets": [], "root": str(root), "exists": True} | |
| datasets.sort(key=lambda d: (-d["total_episodes"], d["name"])) | |
| return {"datasets": datasets, "root": str(root), "exists": True} | |