ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s

This commit is contained in:
2026-08-20 13:12:50 +00:00
commit b119135836
10275 changed files with 3284984 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
# 实验 6-10:专家控制建立机器人能力上限
本目录对应实验 6-10;运行器、验证器与证据中的实验标识均已统一为 `6-10`
这是一个可在本机 GPU 上完成的、非致动的桌面操作上限实验。它用批量二维桌面模拟器实现“像遥操作员一样直接把物体移到目标”的专家控制器,目的是建立后续自主策略的上限和基准,不把模拟结果冒充成 XLeRobot 真机结果。
## 运行
```bash
cd chapter6/xlerobot-teleoperation
python teleop.py --episodes 512 --object-counts 1,2,3,4 --seeds 20260808,20260809,20260810,20260811,20260812 --output-dir validation/runs/local-gpu
python validate_evidence.py validation/runs/local-gpu/evidence.json
```
脚本优先使用 CUDA,其次使用 Apple MPS;默认拒绝 CPU 回退。正式协议使用 5 个随机种子、4 种物体数量和每格 512 个回合,共 10240 个回合,并额外重复一个固定条件检查结果是否一致。`--allow-cpu` 只用于调试,不能作为正文实验结果。输出包括 GPU 信息、每个条件的成功率、步数、路径长度、指标文件哈希,以及一份明确标注为“需要硬件和安全条件”的 XLeRobot 真机扩展状态。
## 观察重点
- 专家控制器在随机物体位置上是否稳定完成所有目标;
- 完成时间和路径长度的分布;
- 这个结果只是“硬件加上一个理想控制者”的上限,不代表自主策略已经达到该水平。
## 真机扩展
XLeRobot 的键盘、Xbox、Joy-Con 和 VR 入口仍由 `upstream.lock.json` 记录,但它们需要真实机械臂、校准、急停和现场观察员。本实验的本地 GPU 验收不会打开串口,也不会执行任何真机动作;只有获得明确授权后,才可另行运行硬件 teleop 复现。
@@ -0,0 +1,30 @@
{
"schema_version": "1.0",
"experiment_id": "6-10",
"status": "blocked",
"upstream": {
"repository": "https://github.com/Vector-Wangel/XLeRobot.git",
"commit": "3d14695e40c9c68229c0aacffca6053c75cd3eb6",
"guide_path": "docs/en/source/software/getting_started/XLeRobot_teleop.md",
"guide_blob": "3992358282ff54cfce8d90a525e784aedcf045f7"
},
"run": {
"started_at": null,
"ended_at": null,
"operator": null,
"host": "documentation-only-host",
"actuation_authorized": false
},
"safety": {
"robot_calibrated": false,
"clear_workspace": false,
"emergency_stop_ready": false,
"human_observer_present": false
},
"modes": [],
"task_outcomes": [],
"artifacts": [],
"blockers": [
"No XLeRobot hardware or explicit robot-actuation authorization was available; no physical run was attempted."
]
}
@@ -0,0 +1,18 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ai-agent-book.local/schemas/experiment-6-10-local-gpu.json",
"title": "Experiment 6-10 local GPU expert upper bound evidence",
"type": "object",
"required": ["schema_version", "experiment_id", "status", "kind", "metrics", "artifacts", "hardware_extension", "blockers"],
"properties": {
"schema_version": {"const": "3.0"},
"experiment_id": {"const": "6-10"},
"status": {"const": "complete"},
"kind": {"const": "local_gpu_expert_upper_bound"},
"metrics": {"type": "object"},
"artifacts": {"type": "array"},
"hardware_extension": {"type": "object"},
"blockers": {"type": "array"}
},
"additionalProperties": true
}
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""Read-only preflight for the pinned Experiment 6-10 reproduction track."""
from __future__ import annotations
import argparse
import importlib.util
import json
import platform
import subprocess
from datetime import datetime, timezone
from pathlib import Path
COMMIT = "3d14695e40c9c68229c0aacffca6053c75cd3eb6"
PINNED_BLOBS = {
"docs/en/source/software/getting_started/XLeRobot_teleop.md": "3992358282ff54cfce8d90a525e784aedcf045f7",
"software/examples/4_xlerobot_teleop_keyboard.py": "efbe076dfbda3c6280fa54f0eb5bca1a12518a0d",
"software/examples/5_xlerobot_teleop_xbox.py": "de7bc17d570167e58b15e38c06c0fa23af74632a",
"software/examples/7_xlerobot_teleop_joycon.py": "21a48258d22b1fc002f63555a2f3dc2950bdfb24",
"software/examples/8_xlerobot_teleop_vr.py": "315bb81f13a37746de0f329e3ba11240a2230806",
}
def git(repo: Path, *args: str) -> str:
return subprocess.run(["git", "-C", str(repo), *args], check=False, capture_output=True, text=True).stdout.strip()
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--upstream", type=Path, required=True, help="local checkout of Vector-Wangel/XLeRobot")
parser.add_argument("--serial-port", action="append", default=[], help="expected robot serial device; checked by path only")
parser.add_argument("--safety-checklist-complete", action="store_true", help="operator attests calibration, clear workspace, observer, and E-stop")
parser.add_argument("--output", type=Path)
args = parser.parse_args()
checks: list[dict[str, object]] = []
def add(check_id: str, passed: bool, detail: str, required: bool = True) -> None:
checks.append({"id": check_id, "passed": passed, "required_for_hardware_run": required, "detail": detail})
head = git(args.upstream, "rev-parse", "HEAD")
add("pinned_commit", head == COMMIT, f"expected {COMMIT}; found {head or 'not a git checkout'}")
for path, blob in PINNED_BLOBS.items():
found = git(args.upstream, "rev-parse", f"HEAD:{path}")
add(f"blob:{path}", found == blob, f"expected {blob}; found {found or 'missing'}")
for module in ("numpy", "pygame", "lerobot", "joyconrobotics"):
found = importlib.util.find_spec(module) is not None
add(f"python_module:{module}", found, "installed" if found else "not importable")
add("serial_ports_supplied", bool(args.serial_port), "no serial ports supplied" if not args.serial_port else ", ".join(args.serial_port))
for device in args.serial_port:
add(f"device:{device}", Path(device).exists(), "path exists" if Path(device).exists() else "path missing")
add("safety_checklist", args.safety_checklist_complete, "operator attestation present" if args.safety_checklist_complete else "not attested")
blockers = [str(item["id"]) for item in checks if item["required_for_hardware_run"] and not item["passed"]]
report = {
"schema_version": "1.0",
"experiment_id": "6-10",
"kind": "non_actuating_preflight",
"generated_at": datetime.now(timezone.utc).isoformat(),
"host": platform.node() or "unknown",
"upstream_path": str(args.upstream.resolve()),
"status": "ready" if not blockers else "blocked",
"checks": checks,
"blockers": blockers,
"actuation_attempted": False,
}
rendered = json.dumps(report, indent=2) + "\n"
if args.output:
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(rendered, encoding="utf-8")
print(f"wrote {args.output}")
else:
print(rendered, end="")
return 0 if not blockers else 1
if __name__ == "__main__":
raise SystemExit(main())
+146
View File
@@ -0,0 +1,146 @@
#!/usr/bin/env python3
"""Experiment 6-10: local GPU expert-control upper-bound benchmark.
This is the reproducible, non-actuating companion for the chapter. It uses a
small batched tabletop simulator to measure what a perfect teleoperator-like
controller can do. The pinned XLeRobot hardware path remains an optional,
explicitly gated extension documented in README.md.
"""
from __future__ import annotations
import argparse
import json
import sys
import time
from pathlib import Path
import torch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from robotics_lab_common import device_info, relative_or_absolute, select_device, seed_everything, sha256, write_json
def run_upper_bound(episodes: int, objects: int, seed: int, device: torch.device) -> dict[str, object]:
if objects < 1 or objects > 4:
raise ValueError("objects must be between 1 and 4")
generator = torch.Generator(device=device).manual_seed(seed)
object_xy = torch.rand((episodes, objects, 2), generator=generator, device=device) * 0.60 + 0.20
target_xy = torch.rand((episodes, objects, 2), generator=generator, device=device) * 0.60 + 0.20
ee = torch.full((episodes, 2), 0.50, dtype=torch.float32, device=device)
current = torch.zeros(episodes, dtype=torch.long, device=device)
phase = torch.zeros(episodes, dtype=torch.long, device=device) # 0=approach, 1=carry, 2=advance
finished = torch.zeros(episodes, dtype=torch.bool, device=device)
path = torch.zeros(episodes, dtype=torch.float32, device=device)
steps = torch.zeros(episodes, dtype=torch.long, device=device)
max_steps = 900
speed = 0.018
tolerance = 0.025
for _ in range(max_steps):
active = ~finished
if not bool(active.any().item()):
break
idx = current.clamp(max=objects - 1)
obj = object_xy[torch.arange(episodes, device=device), idx]
target = target_xy[torch.arange(episodes, device=device), idx]
destination = torch.where((phase == 1).unsqueeze(1), target, obj)
delta = destination - ee
distance = torch.linalg.vector_norm(delta, dim=1)
step = delta / distance.clamp_min(1e-6).unsqueeze(1) * speed
step = torch.where((distance < speed).unsqueeze(1), delta, step)
step = torch.where(active.unsqueeze(1), step, torch.zeros_like(step))
ee = ee + step
path += torch.linalg.vector_norm(step, dim=1)
steps += active.to(torch.long)
arrived = distance <= tolerance
phase = torch.where(active & (phase == 0) & arrived, torch.ones_like(phase), phase)
arrived_target = active & (phase == 1) & arrived
phase = torch.where(arrived_target, torch.full_like(phase, 2), phase)
current = torch.where(arrived_target, current + 1, current)
phase = torch.where((phase == 2) & (current < objects), torch.zeros_like(phase), phase)
finished = current >= objects
phase = torch.where(finished, torch.full_like(phase, 3), phase)
success = finished
return {
"seed": seed,
"episodes": episodes,
"objects_per_episode": objects,
"max_steps": max_steps,
"control_hz": 20,
"successes": int(success.sum().item()),
"success_rate": float(success.float().mean().item()),
"mean_steps": float(steps.float().mean().item()),
"p95_steps": float(torch.quantile(steps.float(), 0.95).item()),
"mean_path_length_m": float(path.mean().item()),
"device": device_info(device),
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--episodes", type=int, default=512, help="episodes per seed/object-count cell")
parser.add_argument("--object-counts", default="1,2,3,4")
parser.add_argument("--seeds", default="20260808,20260809,20260810,20260811,20260812")
parser.add_argument("--output-dir", type=Path, default=Path(__file__).parent / "validation" / "runs" / "local-gpu")
parser.add_argument("--allow-cpu", action="store_true", help="debug only; the book gate requires an accelerator")
args = parser.parse_args()
if args.episodes < 128:
parser.error("--episodes must be at least 128 for the benchmark protocol")
try:
object_counts = [int(value) for value in args.object_counts.split(",")]
seeds = [int(value) for value in args.seeds.split(",")]
except ValueError:
parser.error("--object-counts and --seeds must be comma-separated integers")
if not object_counts or any(value < 1 or value > 4 for value in object_counts):
parser.error("object counts must be in 1..4")
if len(seeds) < 3:
parser.error("at least three independent seeds are required")
if args.episodes < 1:
parser.error("--episodes must be positive")
seed_everything(seeds[0])
try:
device = select_device(not args.allow_cpu)
except RuntimeError as exc:
parser.error(str(exc))
started = time.perf_counter()
cells = [run_upper_bound(args.episodes, objects, seed, device) for seed in seeds for objects in object_counts]
replay_a = run_upper_bound(128, object_counts[0], seeds[0], device)
replay_b = run_upper_bound(128, object_counts[0], seeds[0], device)
deterministic = replay_a == replay_b
metrics = {
"device": device_info(device),
"protocol": {"seeds": seeds, "object_counts": object_counts, "episodes_per_cell": args.episodes, "total_episodes": len(cells) * args.episodes},
"cells": cells,
"aggregate_success_rate": sum(cell["success_rate"] for cell in cells) / len(cells),
"worst_cell_success_rate": min(cell["success_rate"] for cell in cells),
"max_p95_steps": max(cell["p95_steps"] for cell in cells),
"deterministic_replay": deterministic,
"wall_time_ms": round((time.perf_counter() - started) * 1000, 3),
}
args.output_dir.mkdir(parents=True, exist_ok=True)
metrics_path = args.output_dir / "metrics.json"
cells_path = args.output_dir / "cells.json"
write_json(metrics_path, metrics)
write_json(cells_path, {"cells": cells})
receipt = {
"schema_version": "3.0",
"experiment_id": "6-10",
"status": "complete",
"kind": "local_gpu_expert_upper_bound",
"seed": seeds[0],
"run": {"accelerator_required": not args.allow_cpu},
"metrics": metrics,
"artifacts": [{"kind": "metrics", "path": relative_or_absolute(metrics_path, args.output_dir), "sha256": sha256(metrics_path)}, {"kind": "cells", "path": relative_or_absolute(cells_path, args.output_dir), "sha256": sha256(cells_path)}],
"hardware_extension": {"status": "gated", "actuation_attempted": False, "upstream": "Vector-Wangel/XLeRobot"},
"blockers": [] if not args.allow_cpu else ["CPU debug mode is not a GPU acceptance run"],
}
evidence_path = args.output_dir / "evidence.json"
write_json(evidence_path, receipt)
print(json.dumps(receipt, indent=2))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,38 @@
import json
import subprocess
import sys
import unittest
from pathlib import Path
from validate_evidence import validate
class EvidenceGateTests(unittest.TestCase):
def test_local_gpu_evidence_is_accepted(self):
run = Path(__file__).parent / "validation" / "runs" / "local-gpu" / "evidence.json"
if not run.is_file():
self.skipTest("run the local GPU experiment first")
data = json.loads(run.read_text(encoding="utf-8"))
self.assertEqual(validate(data, run.parent), [])
def test_cpu_claim_is_rejected(self):
data = {
"schema_version": "3.0",
"experiment_id": "6-10",
"status": "complete",
"kind": "local_gpu_expert_upper_bound",
"metrics": {"device": {"device": "cpu"}, "protocol": {"seeds": [1, 2, 3], "object_counts": [1, 2, 3], "total_episodes": 2048}, "cells": [], "worst_cell_success_rate": 1.0, "deterministic_replay": True},
"artifacts": [],
"hardware_extension": {"actuation_attempted": False},
}
self.assertTrue(validate(data))
def test_runner_requires_accelerator_by_default(self):
runner = Path(__file__).with_name("teleop.py")
result = subprocess.run([sys.executable, str(runner), "--help"], capture_output=True, text=True, check=False)
self.assertEqual(result.returncode, 0)
self.assertIn("local GPU", result.stdout)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,29 @@
{
"experiment_id": "6-10",
"repository": "https://github.com/Vector-Wangel/XLeRobot.git",
"commit": "3d14695e40c9c68229c0aacffca6053c75cd3eb6",
"guide": {
"published_url": "https://xlerobot.readthedocs.io/en/latest/software/getting_started/XLeRobot_teleop.html",
"path": "docs/en/source/software/getting_started/XLeRobot_teleop.md",
"git_blob": "3992358282ff54cfce8d90a525e784aedcf045f7"
},
"entrypoints": {
"keyboard": {
"path": "software/examples/4_xlerobot_teleop_keyboard.py",
"git_blob": "efbe076dfbda3c6280fa54f0eb5bca1a12518a0d"
},
"xbox": {
"path": "software/examples/5_xlerobot_teleop_xbox.py",
"git_blob": "de7bc17d570167e58b15e38c06c0fa23af74632a"
},
"joycon": {
"path": "software/examples/7_xlerobot_teleop_joycon.py",
"git_blob": "21a48258d22b1fc002f63555a2f3dc2950bdfb24"
},
"vr": {
"path": "software/examples/8_xlerobot_teleop_vr.py",
"git_blob": "315bb81f13a37746de0f329e3ba11240a2230806"
}
},
"verified_at": "2026-07-29"
}
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""Validate the honest local GPU evidence for Experiment 6-10."""
from __future__ import annotations
import argparse
import hashlib
import json
import sys
from pathlib import Path
from typing import Any
def file_sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def validate(data: dict[str, Any], evidence_dir: Path | None = None) -> list[str]:
errors: list[str] = []
def expect(condition: bool, message: str) -> None:
if not condition:
errors.append(message)
expect(data.get("schema_version") == "3.0", "schema_version must be 3.0")
expect(data.get("experiment_id") == "6-10", "experiment_id must be 6-10")
expect(data.get("kind") == "local_gpu_expert_upper_bound", "wrong evidence kind")
expect(data.get("status") == "complete", "local evidence must be complete")
metrics = data.get("metrics", {})
expect(metrics.get("device", {}).get("device") in {"mps", "cuda"}, "evidence must use a local GPU accelerator")
protocol = metrics.get("protocol", {})
expect(len(protocol.get("seeds", [])) >= 3, "at least three seeds are required")
expect(len(protocol.get("object_counts", [])) >= 3, "at least three object-count conditions are required")
expect(protocol.get("total_episodes", 0) >= 2000, "at least 2000 benchmark episodes are required")
cells = metrics.get("cells", [])
expect(len(cells) == len(protocol.get("seeds", [])) * len(protocol.get("object_counts", [])), "one result cell is required per seed/object-count pair")
expect(metrics.get("worst_cell_success_rate") == 1.0, "expert upper bound must solve every benchmark cell")
expect(metrics.get("deterministic_replay") is True, "repeating a fixed seed must reproduce the same metrics")
artifacts = data.get("artifacts", [])
expect(len(artifacts) == 2, "metrics and episode-cell artifacts are required")
if evidence_dir is not None:
for artifact in artifacts:
path = evidence_dir / str(artifact.get("path", ""))
expect(path.is_file(), f"artifact does not exist: {path}")
if path.is_file():
expect(file_sha256(path) == artifact.get("sha256"), f"artifact hash mismatch: {path.name}")
extension = data.get("hardware_extension", {})
expect(extension.get("actuation_attempted") is False, "local run must not claim hardware actuation")
return errors
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("evidence", type=Path)
args = parser.parse_args()
try:
data = json.loads(args.evidence.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
print(f"INVALID: {exc}", file=sys.stderr)
return 2
errors = validate(data, args.evidence.resolve().parent)
if errors:
print("INVALID")
for error in errors:
print(f"- {error}")
return 1
print("VALID: experiment 6-10 local GPU evidence")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,90 @@
{
"schema_version": "1.0",
"experiment_id": "6-10",
"kind": "non_actuating_preflight",
"generated_at": "2026-07-29T15:32:08.929534+00:00",
"host": "bojMacBook-Pro.local",
"upstream_path": "/private/tmp/xlerobot-audit-20260729",
"status": "blocked",
"checks": [
{
"id": "pinned_commit",
"passed": true,
"required_for_hardware_run": true,
"detail": "expected 3d14695e40c9c68229c0aacffca6053c75cd3eb6; found 3d14695e40c9c68229c0aacffca6053c75cd3eb6"
},
{
"id": "blob:docs/en/source/software/getting_started/XLeRobot_teleop.md",
"passed": true,
"required_for_hardware_run": true,
"detail": "expected 3992358282ff54cfce8d90a525e784aedcf045f7; found 3992358282ff54cfce8d90a525e784aedcf045f7"
},
{
"id": "blob:software/examples/4_xlerobot_teleop_keyboard.py",
"passed": true,
"required_for_hardware_run": true,
"detail": "expected efbe076dfbda3c6280fa54f0eb5bca1a12518a0d; found efbe076dfbda3c6280fa54f0eb5bca1a12518a0d"
},
{
"id": "blob:software/examples/5_xlerobot_teleop_xbox.py",
"passed": true,
"required_for_hardware_run": true,
"detail": "expected de7bc17d570167e58b15e38c06c0fa23af74632a; found de7bc17d570167e58b15e38c06c0fa23af74632a"
},
{
"id": "blob:software/examples/7_xlerobot_teleop_joycon.py",
"passed": true,
"required_for_hardware_run": true,
"detail": "expected 21a48258d22b1fc002f63555a2f3dc2950bdfb24; found 21a48258d22b1fc002f63555a2f3dc2950bdfb24"
},
{
"id": "blob:software/examples/8_xlerobot_teleop_vr.py",
"passed": true,
"required_for_hardware_run": true,
"detail": "expected 315bb81f13a37746de0f329e3ba11240a2230806; found 315bb81f13a37746de0f329e3ba11240a2230806"
},
{
"id": "python_module:numpy",
"passed": true,
"required_for_hardware_run": true,
"detail": "installed"
},
{
"id": "python_module:pygame",
"passed": true,
"required_for_hardware_run": true,
"detail": "installed"
},
{
"id": "python_module:lerobot",
"passed": false,
"required_for_hardware_run": true,
"detail": "not importable"
},
{
"id": "python_module:joyconrobotics",
"passed": false,
"required_for_hardware_run": true,
"detail": "not importable"
},
{
"id": "serial_ports_supplied",
"passed": false,
"required_for_hardware_run": true,
"detail": "no serial ports supplied"
},
{
"id": "safety_checklist",
"passed": false,
"required_for_hardware_run": true,
"detail": "not attested"
}
],
"blockers": [
"python_module:lerobot",
"python_module:joyconrobotics",
"serial_ports_supplied",
"safety_checklist"
],
"actuation_attempted": false
}
@@ -0,0 +1,344 @@
{
"cells": [
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2301437109708786,
"mean_steps": 12.97265625,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5379001498222351,
"mean_steps": 30.263671875,
"objects_per_episode": 2,
"p95_steps": 48.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8478867411613464,
"mean_steps": 47.666015625,
"objects_per_episode": 3,
"p95_steps": 71.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1540141105651855,
"mean_steps": 64.80859375,
"objects_per_episode": 4,
"p95_steps": 94.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.23004719614982605,
"mean_steps": 12.966796875,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5500189065933228,
"mean_steps": 30.943359375,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8587707281112671,
"mean_steps": 48.28515625,
"objects_per_episode": 3,
"p95_steps": 72.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1936140060424805,
"mean_steps": 67.0859375,
"objects_per_episode": 4,
"p95_steps": 97.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2288360595703125,
"mean_steps": 12.904296875,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5454419851303101,
"mean_steps": 30.68359375,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8452757596969604,
"mean_steps": 47.515625,
"objects_per_episode": 3,
"p95_steps": 72.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1632212400436401,
"mean_steps": 65.373046875,
"objects_per_episode": 4,
"p95_steps": 95.44998168945312,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2274591028690338,
"mean_steps": 12.8359375,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5360898971557617,
"mean_steps": 30.140625,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8582804799079895,
"mean_steps": 48.23828125,
"objects_per_episode": 3,
"p95_steps": 71.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1563987731933594,
"mean_steps": 64.9453125,
"objects_per_episode": 4,
"p95_steps": 93.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.22869494557380676,
"mean_steps": 12.8984375,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5435010194778442,
"mean_steps": 30.57421875,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8587590456008911,
"mean_steps": 48.322265625,
"objects_per_episode": 3,
"p95_steps": 74.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1580641269683838,
"mean_steps": 65.076171875,
"objects_per_episode": 4,
"p95_steps": 94.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
}
]
}
@@ -0,0 +1,399 @@
{
"artifacts": [
{
"kind": "metrics",
"path": "metrics.json",
"sha256": "97690371d6876141e335ee4864888d261050a86096d5ca53f112004c8bcf5ea9"
},
{
"kind": "cells",
"path": "cells.json",
"sha256": "ee306b9b2d7dc2e3f559e73d88660bbecbbb11c6e697759a5be974a82e1a3a72"
}
],
"blockers": [],
"experiment_id": "6-10",
"hardware_extension": {
"actuation_attempted": false,
"status": "gated",
"upstream": "Vector-Wangel/XLeRobot"
},
"kind": "local_gpu_expert_upper_bound",
"metrics": {
"aggregate_success_rate": 1.0,
"cells": [
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2301437109708786,
"mean_steps": 12.97265625,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5379001498222351,
"mean_steps": 30.263671875,
"objects_per_episode": 2,
"p95_steps": 48.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8478867411613464,
"mean_steps": 47.666015625,
"objects_per_episode": 3,
"p95_steps": 71.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1540141105651855,
"mean_steps": 64.80859375,
"objects_per_episode": 4,
"p95_steps": 94.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.23004719614982605,
"mean_steps": 12.966796875,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5500189065933228,
"mean_steps": 30.943359375,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8587707281112671,
"mean_steps": 48.28515625,
"objects_per_episode": 3,
"p95_steps": 72.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1936140060424805,
"mean_steps": 67.0859375,
"objects_per_episode": 4,
"p95_steps": 97.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2288360595703125,
"mean_steps": 12.904296875,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5454419851303101,
"mean_steps": 30.68359375,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8452757596969604,
"mean_steps": 47.515625,
"objects_per_episode": 3,
"p95_steps": 72.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1632212400436401,
"mean_steps": 65.373046875,
"objects_per_episode": 4,
"p95_steps": 95.44998168945312,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2274591028690338,
"mean_steps": 12.8359375,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5360898971557617,
"mean_steps": 30.140625,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8582804799079895,
"mean_steps": 48.23828125,
"objects_per_episode": 3,
"p95_steps": 71.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1563987731933594,
"mean_steps": 64.9453125,
"objects_per_episode": 4,
"p95_steps": 93.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.22869494557380676,
"mean_steps": 12.8984375,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5435010194778442,
"mean_steps": 30.57421875,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8587590456008911,
"mean_steps": 48.322265625,
"objects_per_episode": 3,
"p95_steps": 74.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1580641269683838,
"mean_steps": 65.076171875,
"objects_per_episode": 4,
"p95_steps": 94.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
}
],
"deterministic_replay": true,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"max_p95_steps": 97.0,
"protocol": {
"episodes_per_cell": 512,
"object_counts": [
1,
2,
3,
4
],
"seeds": [
20260808,
20260809,
20260810,
20260811,
20260812
],
"total_episodes": 10240
},
"wall_time_ms": 2806.997,
"worst_cell_success_rate": 1.0
},
"run": {
"accelerator_required": true
},
"schema_version": "3.0",
"seed": 20260808,
"status": "complete"
}
@@ -0,0 +1,371 @@
{
"aggregate_success_rate": 1.0,
"cells": [
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2301437109708786,
"mean_steps": 12.97265625,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5379001498222351,
"mean_steps": 30.263671875,
"objects_per_episode": 2,
"p95_steps": 48.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8478867411613464,
"mean_steps": 47.666015625,
"objects_per_episode": 3,
"p95_steps": 71.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1540141105651855,
"mean_steps": 64.80859375,
"objects_per_episode": 4,
"p95_steps": 94.0,
"seed": 20260808,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.23004719614982605,
"mean_steps": 12.966796875,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5500189065933228,
"mean_steps": 30.943359375,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8587707281112671,
"mean_steps": 48.28515625,
"objects_per_episode": 3,
"p95_steps": 72.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1936140060424805,
"mean_steps": 67.0859375,
"objects_per_episode": 4,
"p95_steps": 97.0,
"seed": 20260809,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2288360595703125,
"mean_steps": 12.904296875,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5454419851303101,
"mean_steps": 30.68359375,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8452757596969604,
"mean_steps": 47.515625,
"objects_per_episode": 3,
"p95_steps": 72.0,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1632212400436401,
"mean_steps": 65.373046875,
"objects_per_episode": 4,
"p95_steps": 95.44998168945312,
"seed": 20260810,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.2274591028690338,
"mean_steps": 12.8359375,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5360898971557617,
"mean_steps": 30.140625,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8582804799079895,
"mean_steps": 48.23828125,
"objects_per_episode": 3,
"p95_steps": 71.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1563987731933594,
"mean_steps": 64.9453125,
"objects_per_episode": 4,
"p95_steps": 93.0,
"seed": 20260811,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.22869494557380676,
"mean_steps": 12.8984375,
"objects_per_episode": 1,
"p95_steps": 20.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.5435010194778442,
"mean_steps": 30.57421875,
"objects_per_episode": 2,
"p95_steps": 49.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 0.8587590456008911,
"mean_steps": 48.322265625,
"objects_per_episode": 3,
"p95_steps": 74.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
},
{
"control_hz": 20,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"episodes": 512,
"max_steps": 900,
"mean_path_length_m": 1.1580641269683838,
"mean_steps": 65.076171875,
"objects_per_episode": 4,
"p95_steps": 94.0,
"seed": 20260812,
"success_rate": 1.0,
"successes": 512
}
],
"deterministic_replay": true,
"device": {
"device": "mps",
"name": "Apple Metal Performance Shaders",
"torch": "2.7.0"
},
"max_p95_steps": 97.0,
"protocol": {
"episodes_per_cell": 512,
"object_counts": [
1,
2,
3,
4
],
"seeds": [
20260808,
20260809,
20260810,
20260811,
20260812
],
"total_episodes": 10240
},
"wall_time_ms": 2806.997,
"worst_cell_success_rate": 1.0
}