Skip to content

Commit 9deb766

Browse files
Eugene Vinitskyclaude
authored andcommitted
docs: failure mining operational guide
New docs/mining.md covering the mine_failures workflow: - score_threshold semantics (default -inf saves nothing) - the required --vec.backend Serial flag (pufferl's default Multiprocessing backend forks workers post-torch-import and deadlocks on CUDA) - loading checkpoints with non-default policy.* / rnn.* dims (mine_failures doesn't auto-merge the sibling config.yaml that train() does) - on-cluster submit_cluster.py pattern with --main override - viewer features README.md gains a short pointer paragraph at the end of the existing Failure mining section. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 1560772 commit 9deb766

2 files changed

Lines changed: 169 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ renders/index.html # sortable index of all episodes
148148

149149
Open `renders/index.html` in a browser to triage. The index page filters by "failures only" / "replays only" and sorts by any metric column. Each row links to the per-episode viewer with the scene's full 2D animation.
150150

151+
For the deeper guide — viewer features, `score_threshold` semantics, the required `--vec.backend Serial` flag, loading checkpoints with non-default `policy.*` dims, and the on-cluster `submit_cluster.py` pattern — see [`docs/mining.md`](docs/mining.md).
152+
151153
## Key Configuration (`pufferlib/config/ocean/drive.ini`)
152154

153155
### `[env]` — Simulation

docs/mining.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Failure mining workflow
2+
3+
How to roll a trained policy out, capture compact replays, and produce a
4+
browser-viewable HTML index of episodes. Pairs with `pufferl.mine_failures`
5+
and `pufferlib/mining_viz.py`.
6+
7+
## TL;DR
8+
9+
```bash
10+
# Roll the policy out for 100 episodes, save compact replays for episodes
11+
# whose episode_return falls below the threshold, render HTML for each +
12+
# a sortable index.
13+
puffer mine_failures puffer_drive \
14+
--load-model-path /path/to/model_011000.pt \
15+
--mine.output-dir ./failure_mining/baseline_011000 \
16+
--mine.num-episodes 100 \
17+
--mine.score-threshold 1e9 \
18+
--vec.backend Serial
19+
```
20+
21+
Outputs:
22+
23+
```
24+
./failure_mining/baseline_011000/
25+
replays/episode_NNNNNN.replay.zlib one per saved episode
26+
renders/episode_NNNNNN.html per-replay viewer
27+
renders/index.html sortable summary
28+
episodes.csv all episodes, all metrics
29+
```
30+
31+
Open the index in a browser:
32+
33+
```bash
34+
open ./failure_mining/baseline_011000/renders/index.html
35+
```
36+
37+
## What gets captured
38+
39+
A compact replay bundle is a pickled+zlib'd `schema_version=2` dict containing
40+
per-step agent state, traffic state, and observation arrays for a single
41+
episode. Bundles are produced C-side when `capture_compact_replay=True` is
42+
passed to `Drive(...)`. `mine_failures` sets this automatically.
43+
44+
Each saved bundle is paired with a metadata row in `episodes.csv` including
45+
`episode_return`, `collision_rate`, `offroad_rate`, `num_goals_reached`,
46+
`avg_distance_per_infraction`, etc. The HTML viewer (`pufferlib/mining_viz.py`)
47+
reads the bundle and replays it in-browser on a top-down canvas, with optional
48+
overlays for the agent's observed FOV, partner circle, goal route, and waypoint
49+
markers.
50+
51+
## `mine.score_threshold` selection
52+
53+
The save rule is "write replay if and only if `episode_return < score_threshold`".
54+
55+
- `--mine.score-threshold 1e9` captures every episode (any real return is
56+
less than 1e9).
57+
- `--mine.score-threshold 0` captures only negative-return ("true failure")
58+
episodes.
59+
- Default `-inf` captures **nothing** — useful only if you want `episodes.csv`
60+
metrics without the bundle overhead.
61+
62+
`episodes.csv` always contains all N episodes' metadata regardless of
63+
threshold; only the bundle save + HTML render is gated.
64+
65+
## `--vec.backend Serial`
66+
67+
Mining must use `--vec.backend Serial`. The drive.ini default
68+
`Multiprocessing` backend forks workers post-torch-import, which deadlocks on
69+
CUDA in the child process. Symptom is a parent process at 100% CPU with no
70+
visible progress and no `[mine_failures] target episodes=...` print.
71+
72+
`Serial` keeps the env in the same process as the policy. Mining is a single
73+
env / single rollout workflow, so the throughput cost is negligible.
74+
75+
## Tuning the rollout config
76+
77+
The mining env config comes from drive.ini's `[mine]` section plus per-CLI
78+
overrides:
79+
80+
```bash
81+
# Larger output (slower):
82+
--mine.num-episodes 500
83+
84+
# Replay mode (drive recorded nuPlan / Waymo scenarios):
85+
--env.simulation-mode replay \
86+
--env.control-mode control_sdc_only \
87+
--env.map-dir /path/to/recorded_bins \
88+
--env.init-steps 10 \
89+
--env.scenario-length 200
90+
91+
# Looser goal radius (default 2 m, up to 12 m under reward randomization):
92+
--env.goal-radius 6
93+
94+
# Closer-spaced goals:
95+
--env.min-waypoint-spacing 10 \
96+
--env.max-waypoint-spacing 15
97+
```
98+
99+
## Loading checkpoints with non-default architecture
100+
101+
`mine_failures` does not read the sibling `config.yaml` next to
102+
`load_model_path` (only `pufferl.train` does). If the checkpoint was trained
103+
with non-default `policy.*` or `rnn.*` dimensions (e.g. `input_size=128`,
104+
`backbone_num_layers=4`), pass them on the CLI to match the saved state dict:
105+
106+
```bash
107+
--policy.input-size 128 \
108+
--policy.actor-hidden-size 512 \
109+
--policy.actor-num-layers 0 \
110+
--policy.backbone-hidden-size 512 \
111+
--policy.backbone-num-layers 4 \
112+
--policy.critic-hidden-size 512 \
113+
--policy.critic-num-layers 0 \
114+
--policy.encoder-gigaflow True \
115+
--policy.split-network False \
116+
--rnn.hidden-size 512 \
117+
--rnn.input-size 512
118+
```
119+
120+
You can read the right values out of the checkpoint's sibling `config.yaml`
121+
(under `policy:` and `rnn:`) and pass them through. The error if you forget
122+
is a wall of `size mismatch for ...` lines from `policy.load_state_dict`.
123+
124+
## On the cluster
125+
126+
Mining is GPU-bound on the policy forward pass but memory-light compared to
127+
training (single env, no rollout buffer, no PPO update). 48 GB RAM and a
128+
60-minute time limit are plenty for 100 episodes. The same `submit_cluster.py`
129+
flow as training works — override `--main` to invoke `mine_failures`:
130+
131+
```bash
132+
python3 scripts/submit_cluster.py \
133+
--save_dir /scratch/$USER/runs \
134+
--prefix mine \
135+
--compute_config scripts/cluster_configs/nyu_greene.yaml \
136+
--account <acct> --partition <gpu-partition> --time 60 \
137+
--mem 48gb --cpus 8 \
138+
--container \
139+
--main "-m pufferlib.pufferl mine_failures puffer_drive" \
140+
--args \
141+
load_model_path=<path-to-ckpt> \
142+
mine.output_dir=/scratch/$USER/failure_mining/out \
143+
mine.num_episodes=100 \
144+
mine.score_threshold=1e9 \
145+
vec.backend=Serial
146+
```
147+
148+
See [`docs/cluster_training.md`](cluster_training.md) for one-time setup of
149+
the login-side submitit (`python3 -m pip install --user submitit pyyaml
150+
cloudpickle`).
151+
152+
Outputs land on `/scratch`; pull them down with `rsync` for in-browser viewing.
153+
154+
## Viewer features (`mining_viz.py`)
155+
156+
The per-episode HTML viewer supports:
157+
158+
- Frame scrubber + play/pause + speed control.
159+
- Toggle observation overlay (FOV rectangle, partner circle, observed-entity
160+
highlights, goal route, waypoint markers).
161+
- Toggle road segment / road edge / lane line rendering.
162+
- Map background (CARLA / nuPlan / Waymo road graph from the bundle's
163+
embedded `simulation_mode`).
164+
165+
The index (`renders/index.html`) is a sortable table linking to each per-episode
166+
HTML, with the metadata columns from `episodes.csv` (failure metrics, scenario
167+
ID, map name).

0 commit comments

Comments
 (0)