UniAD unifies perception, prediction, occupancy, and planning in one BEV-centric model. After stage-2
end-to-end training, the planning head outputs six future ego waypoints — but the objective is primarily
supervised L2 / ADE. That leaves little room to optimize comfort, collision avoidance, or multi-modal
uncertainty without expensive full-model fine-tuning.
Following the spirit of Thinking Machines' LoRA work, we freeze the entire UniAD backbone and post-train
only low-rank adapters plus a small Gaussian policy head on the planner. GRPO (group-relative policy
optimization) lets us sample multiple waypoint trajectories per frame and reinforce the best ones relative
to the group — without re-running the frozen perception stack.
The throughline is simple: preserve the scene representation, introduce the smallest
trainable policy correction, branch it into candidate futures, learn from their relative quality, and
finally judge the one deterministic path that deployment will use.
The experiment revealed a distinction that is easy to lose in a training dashboard. GRPO can move
probability mass toward a good future without moving the center of the distribution by the same amount.
A purple rollout can nearly touch the expert path while the blue trajectory actually shipped at inference
remains several meters away. The curriculum after phase 3 is an attempt to close precisely that gap.
Sample-best
$\mathbb{E}_b[\min_g\mathrm{ADE}_{b,g}]$ from training JSONL.
It measures whether one of $G$ stochastic rollouts found a good future.
Mean-path
$\mathrm{ADE}(\mathrm{cumsum}(\mu),\tau^{\star})$ on 12 fixed frames.
It measures the deterministic blue path used at deployment.
Scope. All numbers below are open-loop metrics on nuScenes v1.0-mini
(sample-best minADE/minFDE over G stochastic trajectories during training logs, and mean-path ADE in
waypoint plots). This is not the official nuScenes planning benchmark on trainval.
Thread continuesTo change only the planner, the codebase needs an
explicit boundary between frozen scene understanding and trainable future selection.
2. Preserve the invariant: fork only the planner path
We kept the default UniAD training path intact. GRPO post-training is an opt-in fork activated by config
(PlanningHeadGRPO, planner_posttrain_only=True). No changes to
PlanningHeadSingleMode or stage-2 configs unless you explicitly switch. The integration follows
the repository’s MMDetection3D registry and config conventions [mmdet3d].
The only architectural branch is the configuration guard. Turning GRPO off leaves
PlanningHeadSingleMode and the native stage-2 path intact.
Step 3 — Gaussian waypoint policy. reg_branch output (pre-cumsum) = mean μ of 6×2 increments. Learn log_std[T,2]. Trajectory = cumsum(Δ).
Step 4 — GRPO training forward. Sample G trajectories without re-running frozen backbone. Compute group-relative advantages and clipped surrogate.
Step 5 — Reference policy KL. Disable LoRA adapters; compute ref log-prob on same samples. Anchor to stage-2 SFT planner.
Step 6 — planner_posttrain_only on UniAD. Freeze all parameters; re-enable LoRA + log_std. Run track/motion under torch.no_grad(); optimize planning only.
Step 7 — Configs + hooks. Register head/loss/hooks in mmcv. Add phased configs and JSONL experiment logging.
Step 8 — Validation. pytest unit tests + mini campaign + waypoint export for qualitative BEV plots.
Design constraints we preserved
Frozen backbone: track, map, motion, occupancy run under torch.no_grad().
Thread continuesThe boundary is safe. Now we need to understand
the exact shape of the small correction allowed to cross it.
3. Adapt the map, not the world: LoRA on the planner
Post-training a full UniAD stack is expensive and risks catastrophic forgetting of
perception. Following the PEFT intuition in [lora] and the “low-regret LoRA” regime
emphasized by [lora-noregret], we freeze stage-2 weights and train only low-rank adapters on the
planning head — plus a tiny log_std for the Gaussian policy.
LoRA replaces each selected Linear with W′ = W + (α/r)BA. Only A and B train; disabling the adapter recovers the SFT reference used for KL.
The useful mental shape is a narrow corridor. $A$ first compresses a planner feature
from $d_{\mathrm{in}}$ coordinates into only $r$ coordinates; $B$ expands that compact
correction back to $d_{\mathrm{out}}$. The base transformation $W$ remains the wide,
frozen road. The adapter can steer the output, but only through an $r$-dimensional subspace.
For a frozen linear layer $W$:
$$W' = W + \frac{\alpha}{r} B A,\quad
B\in\mathbb{R}^{d_{\mathrm{out}}\times r},\;
A\in\mathbb{R}^{r\times d_{\mathrm{in}}}$$
1def forward(self, x):2 out =self.base(x)frozen route W(x)3ifself.lora_enabled:4 lora_out =self.dropout(x)@self.lora_A.t()@self.lora_B.t()low-rank residual BAx5 out = out +self.scale * lora_outmerge without replacing W6return out
Forward pass of LoRALinear. base stays requires_grad=False; lora_B is init ~ N(0,1e-3) (zero-init killed GRPO/KL at step 0).
reg_branch — predicts waypoint-increment means $\mu$
bev_adapter stays in the forward path but is frozen and LoRA-free,
so the reference policy (LoRA off) matches deployed SFT [uniad].
Thread continuesLoRA gives the planner a narrow steering
surface. GRPO turns that surface into a distribution over complete futures and asks which branch is better.
4. Explore futures, then turn preference into a gradient
Group Relative Policy Optimization [grpo][trl] lets us improve a planner with
reinforcement learning without a value network. We treat each nuScenes frame
[nuscenes] as a contextual bandit: one state, $G$ sampled trajectories, group-normalized
advantages, PPO-style clipping [ppo], and a LoRA-off SFT reference for KL.
MDP → bandit mapping for open-loop waypoint planning. The whole 6-step trajectory is one action.
4.1 Why GRPO (not L2-only, not full PPO)?
Supervised ADE fits the mean expert path — no comparison among futures.
PPO needs $V(s)$; GRPO uses the group mean reward as baseline [grpo].
Rewards can blend ADE / FDE / collision / comfort in one scalar.
The action tensor is not six absolute map points. It is six local 2D increments. Cumulative summation gives each sample its visible path; only the blue mean path ships.
Gaussian rollout over increments — matches UniAD’s native cumsum parameterization.
4.3 Rollout pipeline (the interesting part)
Yes: run UniAD once → define $s$ → encode plan_query → sample
$G$ noisy trajectories → reward → group advantages → losses.
The backbone is not re-executed per sample.
Open-loop GRPO rollout. Purple dashed = G samples; blue = deterministic mean μ used at deploy.
Live examples from our checkpoint
Real open-loop rollouts from the phase4 checkpoint (same legend as §11):
green = GT, gray dashed = SFT, blue = GRPO mean $\mu$, purple dashed = $G$ stochastic samples.
Notice how purple samples can hug GT even when the blue mean is off — that is exactly what
grouped rewards are intended to prefer. The campaign audit in §4.6 shows why that intent must be
separated from the gradient path actually observed.
Live rollout · sample 96easy fit
ADE: SFT 0.34 m → GRPO mean 0.09 m ·
min sample 0.58 m · mean sample 1.58 m
Live rollout · sample 8typical
ADE: SFT 10.24 m → GRPO mean 1.34 m ·
min sample 1.15 m · mean sample 1.95 m
Live rollout · sample 240hard outlier
ADE: SFT 4.67 m → GRPO mean 19.50 m ·
min sample 18.42 m · mean sample 20.30 m
ADE, FDE, occupancy collision, and comfort are four measurements on one sampled path—not four unrelated objectives. Their weighted negative sum is the scalar used for ranking.
Reference, behavior, and current policy are conceptually different distributions. The campaign used one forward pass for old and new log-probabilities, collapsing their ratio to one.
The full learning circuit. All three loss terms meet at L, but autograd can update only the LoRA matrices and log σ; the frozen UniAD representation is a hard stop.
Gradients: LoRA $\{A,B\}$ + log_std only. Curriculum dials
$(\lambda,\beta,G,\varepsilon)$ are documented in §6b.
Thread continuesThe equations now form one circuit. The next
section follows that circuit in repository order before the experiment changes any of its dials.
5. Follow one batch through the actual implementation
Best mean-path checkpoint: projects/work_dirs/planner_posttrain/campaign/phase4_fit_gt/latest.pth
6b. Why the question changes phase by phase
The campaign is a deliberate curriculum, not a single long GRPO run. Early phases buy
correctness and a usable LoRA basin; middle phases unlock group-relative RL at scale; late
phases close the gap between sample-best training metrics and the
deterministic mean path used at inference.
Every phase resolves one uncertainty and hands a narrower question to the next.
Phase 5 is a branch that failed; phase 6 deliberately returns to the phase-4 basin.
1. Phase 0 — Smoke (pipeline verification)
Role: Sanity gate before any real optimization
Why this phase exists. Before spending GPU hours on curriculum training, we need a one-iteration proof that the LoRA+GRPO stack is wired correctly: frozen backbone, LoRA-only gradients, reward tensors, JSONL logging, and evidence hooks. A single fixed frame (smoke_index=8) makes failures cheap and deterministic.
Design choices.
1 sample × 1 epoch × G=4 — minimal compute; fails in minutes, not hours.
strict PlannerGRPOEvidenceHook — asserts base weights frozen, LoRA grads non-zero.
Default-ish GRPO knobs (clip=0.2, kl=0.01, aux=1.0, rank=8) — exercise the full loss, not a stripped stub.
Cold start from uniad_base_e2e.pth — also catches LoRA key remapping / checkpoint load bugs.
Success criterion / observed: Train completes with returncode 0; evidence JSON shows LoRA grads live; JSONL has one row with finite loss / reward / minADE. Metric quality is irrelevant here.
Lesson: Zero-init LoRA-B made GRPO/KL identically zero at step 0 — discovered and fixed before later phases.
Next questionWith the gradient path proven, the next question is whether LoRA can recover a useful mean.
2. Phase 1 — Warmup (stabilize LoRA via imitation)
Role: Move the adapter into a useful basin without aggressive RL
Why this phase exists. Fresh LoRA adapters start near the SFT planner. Jumping straight into high-G GRPO with strong reward weights produces noisy advantages and can push μ far from GT. We first warm LoRA with a high auxiliary ADE loss (supervised mean-path imitation) on a small 50-frame subset, with weak RL signal and tiny KL.
Design choices.
50 samples × 2 epochs — enough diversity to move LoRA, small enough to iterate quickly.
aux_loss_weight=2.0 — mean trajectory μ is pulled toward GT via PlanningLoss.
reward weights halved (ADE/FDE 0.5) — GRPO is present but not dominant.
kl_coef=0.001 — allow the policy to leave the SFT reference gently.
lr=5e-5, rank=8 — conservative capacity; avoid overfitting the 50-frame pocket.
G=4 — cheap exploration while the mean path learns.
Success criterion / observed: Sample-best minADE drops below ~1 m on the warmup set; loss_ade becomes the primary driver; KL stays small and non-pathological.
Lesson: Warmup is the hinge of the curriculum: without it, phase2/3 need many more iters to recover a usable mean path.
Next questionWith a stable mean, the next question is whether grouped futures add useful preference information.
3. Phase 2 — GRPO (balanced policy optimization)
Role: Turn on real group-relative RL with more capacity
Why this phase exists. Once LoRA can imitate, we introduce a balanced GRPO recipe: more samples G, higher LoRA rank, and reward weights that care about FDE and collision — not only ADE. Data grows to 100 frames so advantages are estimated on a richer set of scenes, still short of the full mini.
Design choices.
Resume from phase1 checkpoint — continue adapters, do not reset exploration.
rank 8→16, α 16→32 — extra capacity for multi-scene waypoint corrections.
G=6 — better group statistics for relative advantages without full-campaign cost.
aux=0.5 — imitation still anchors μ; GRPO can improve sample-best without ignoring the mean.
Success criterion / observed: Training log sample-best minADE/minFDE keep improving vs phase1; reward_mean rises; no NaN / dead LoRA grads.
Lesson: Collision reward stayed ~0 on mini — sparse positives; keep the term for API compatibility but do not claim safety gains yet.
Next questionWith balanced sampling working, the next question is whether the recipe survives full-mini scale.
4. Phase 3 — Full mini (maximum exploration budget)
Role: Scale the balanced recipe to all 323 mini frames
Why this phase exists. This is the campaign’s strongest full-mini checkpoint under open-loop sample-best metrics. We use the full nuScenes mini train split, G=8 for richer groups, and a slightly higher KL to keep the policy from drifting too far from SFT while grouped sampling tests whether any rollout reaches a better future.
Design choices.
Resume from phase2 — curriculum continuity across data scale jumps.
323 samples × 3 epochs (~969 iters) — full mini coverage.
G=8 — largest group size in the campaign (VRAM ~7.3 GiB on 4060 Ti).
aux=0.3 — lean more on GRPO sample-best; mean path still supervised lightly.
Success criterion / observed: Sample-best minFDE reaches ~0.05 m in logs; best minADE hits 0 on easy frames. This is the headline phase-3 mini result — not yet mean-path GT fit.
Lesson: Sample-best ≠ deployable mean. Waypoint export showed mean-path ADE still ~4 m with outliers 240/280. The later ratio audit also showed clip_fraction=0 throughout, so no causal gain should be assigned to clipping.
Next questionWith a strong sampled future found, the next question becomes the article’s central one: where is μ?
5. Phase 4 — GT fit (optimize the inference mean path)
Role: Close the train/deploy gap: make μ hug GT
Why this phase exists. Inference uses the deterministic mean μ (cumsum), not the best of G samples. Phase3 was selected by sample-best logs, so purple rollouts can look great while the blue mean path lags. Phase4 flips the objective mix toward aux ADE and tighter σ so the deployed trajectory is the thing we improve.
Design choices.
Resume phase3 epoch_3 — keep the best sample-search adapters as a warm start.
aux_loss_weight=2.5 — strong PlanningLoss on μ (imitation dominates again).
reward ADE/FDE = 2.0 / 3.0 — even the GRPO branch prefers endpoint-accurate samples.
max_log_std=-1.0 (was up to +2) — shrink exploration; force samples near μ.
kl_coef=0.005 — freer adaptation of LoRA away from SFT when GT pull is strong.
Success criterion / observed: Best mean-path eval so far: mean ADE 3.60 m, median 0.98 m on 12 frames. Most scenes look good; hard outliers remain.
Lesson: Median ≈ 1 m is encouraging; max ADE ≈ 19 m (idx 240/280) proves we need either hard-example mining or even stronger mean supervision.
Next questionWith μ improved, the next question is whether simply increasing imitation closes the outlier tail.
6. Phase 5 — Tight fit (more imitation, less entropy)
Role: Stress-test whether “more aux + less KL” beats phase4
Why this phase exists. Hypothesis: if phase4’s bottleneck is residual exploration / weak imitation, raising aux to 4.0 and clamping σ further should improve mean-path ADE. This phase is an ablation-style continuation, not a guaranteed upgrade.
Design choices.
Resume phase4 latest — continue the GT-fit direction.
aux=4.0, ADE/FDE rewards 3/4 — near-imitation with GRPO as a secondary nudge.
kl_coef=0.002, clip=0.08 — very conservative policy updates.
max_log_std=-2.0 — almost deterministic sampling.
lr=3e-5 — smaller steps to avoid overshooting the phase4 basin.
Same 323×5 schedule for a fair comparison to phase4.
Success criterion / observed: Did not beat phase4 on mean-path ADE (3.65 m vs 3.60 m). Confirms that simply cranking aux is not enough when a few hard frames dominate the mean.
Lesson: Keep phase4 as the best mean-path checkpoint. Next steps should target outliers (oversampling / hard mining) rather than globally higher aux alone.
Next questionWhen that ablation regresses, the evidence says to resume the best branch instead of the latest one.
7. Phase 6 — GT anchor (near-imitation marathon)
Role: Long, low-LR push of μ toward GT from the best phase4 weights
Why this phase exists. Phase5 overshot the phase4 basin. Phase6 therefore resumes phase4 epoch_5 (not phase5), sets aux=8.0 (almost pure imitation), nearly zeros KL, and runs 8 epochs at lr=2e-5 so μ can slowly absorb remaining easy/medium errors while GRPO remains a light regularizer via G=4.
Success criterion / observed: In progress / pending eval. Target is mean-path ADE that visually overlays GT on the eval set, including former outliers if possible.
Lesson: Curriculum principle: when a later phase regresses, branch from the best prior checkpoint — never blindly resume the latest failed experiment.
Next questionThe remaining question moves outside this campaign: strict behavior-policy replay and hard-frame mining.
6c. Read the curriculum as signal allocation
Thinking Machines–style exploration of the knobs we actually swept across phases.
Hover a point to read exact values. These are not a full factorial rank×G grid (that is
future work on trainval), but they show how the curriculum moves $G$, rank, $\lambda$,
$\beta$, and $\varepsilon$ as we go from smoke → full-mini sample search → mean-path GT fit.
Group size $G$ & LoRA rank
Loss dials: aux $\lambda$, KL $\beta$, clip $\varepsilon$
Mean-path ADE after GT-fit phases (12 eval frames)
Per-sample GRPO mean ADE (live waypoint export)
How to read this.
Capacity ($G$, rank) peaks at phase3 for sample-best hunting; GT-fit phases raise
$\lambda$ and shrink $\varepsilon$/exploration. The right-hand ADE strip shows the
remaining hard outliers (often idx 240 / 280) that dominate mean ADE even when
the median is already near 1 m.
7. What the implementation learned from the evidence
Chronological changes and what we observed on mini:
v0 — Initial GRPO + LoRA stack
PlanningHeadGRPO with Gaussian policy on 6×2 increments
LoRA on mlp_fuser, decoder FFN/out_proj, reg_branch
Columns are intentionally labeled by statistic: sample-best training minima are not directly comparable
to deterministic mean-path averages. The table keeps both because the gap is the central campaign finding.
10b. Chase the metric that deployment actually uses
After phase3, we run additional GRPO phases optimizing the deterministic mean trajectory
(inference path), not just sample-best minADE over G rollouts. Evaluation uses 12 held-out frame indices
on nuScenes mini.
Phase
Mean ADE
Median ADE
Max ADE
Mean FDE
Target met?
Checkpoint
phase4_fit_gt
3.599 m
0.976 m
19.497 m
6.833 m
—
latest.pth
phase5_tight_fit
3.653 m
1.047 m
20.052 m
6.994 m
—
latest.pth
phase6_gt_anchor
mean-path evaluation pending; training status: incomplete
Stop target: mean ADE ≤ 0.5 m,
max ADE ≤ 1.5 m,
mean FDE ≤ 1.0 m. Best so far: phase4_fit_gt —
projects/work_dirs/planner_posttrain/campaign/phase4_fit_gt/latest.pth Key finding: median ADE ≈ 1 m on most frames, but hard scenes (idx 240, 280) remain outliers.
11. Put the blue deployment path under a microscope
Each panel shows 6 future waypoints in the ego LiDAR frame
(x forward, y left). The black dot is the ego origin.
We compare three planners on identical frozen backbone features:
Green solid — ground-truth expert trajectory from nuScenes.
Blue solid — GRPO post-trained planner (deterministic mean μ, no sampling).
Purple dashed — 8 stochastic GRPO rollouts
(same μ, learned σ; used only during training for group advantages).
Reading the plots: The campaign headline
sample-best metric comes from training JSONL. The purple minimum shown here is a separate,
seeded export-time diagnostic over G rollouts. At inference we deploy the blue mean path only.
Sample index 8 · ADE SFT 10.243 m → GRPO mean 1.340 m
· exported G-rollout minADE 1.147 mSample index 24 · ADE SFT 5.012 m → GRPO mean 0.707 m
· exported G-rollout minADE 2.442 mSample index 48 · ADE SFT 13.772 m → GRPO mean 1.551 m
· exported G-rollout minADE 1.234 mSample index 96 · ADE SFT 0.343 m → GRPO mean 0.092 m
· exported G-rollout minADE 0.578 mSample index 160 · ADE SFT 0.493 m → GRPO mean 0.306 m
· exported G-rollout minADE 1.749 mSample index 240 · ADE SFT 4.667 m → GRPO mean 19.497 m
· exported G-rollout minADE 18.418 mSample index 32 · ADE SFT 3.328 m → GRPO mean 1.136 m
· exported G-rollout minADE 1.854 mSample index 64 · ADE SFT 13.077 m → GRPO mean 0.976 m
· exported G-rollout minADE 1.738 mSample index 128 · ADE SFT 4.728 m → GRPO mean 0.399 m
· exported G-rollout minADE 1.376 mSample index 192 · ADE SFT 20.269 m → GRPO mean 0.546 m
· exported G-rollout minADE 1.469 mSample index 280 · ADE SFT 3.879 m → GRPO mean 16.463 m
· exported G-rollout minADE 16.003 mSample index 300 · ADE SFT 0.704 m → GRPO mean 0.176 m
· exported G-rollout minADE 1.333 m
Quantitative comparison (open-loop, 6 steps)
Sample
ADE SFT
ADE GRPO mean
FDE SFT
FDE GRPO mean
export G minADE
export G mean ADE
8
10.243
1.340
17.417
2.007
1.147
1.951
24
5.012
0.707
7.749
1.630
2.442
4.744
48
13.772
1.551
23.559
2.573
1.234
2.305
96
0.343
0.092
0.678
0.232
0.578
1.583
160
0.493
0.306
0.735
0.460
1.749
2.377
240
4.667
19.497
1.995
37.646
18.418
20.299
32
3.328
1.136
5.968
1.856
1.854
2.416
64
13.077
0.976
22.907
1.985
1.738
3.223
128
4.728
0.399
7.745
0.535
1.376
2.542
192
20.269
0.546
34.977
0.672
1.469
2.244
280
3.879
16.463
1.788
31.949
16.003
17.256
300
0.704
0.176
1.123
0.453
1.333
2.288
Per-step waypoint tables
Per-step coordinates — sample 8
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.02, 3.38)
(0.13, 0.03)
(-0.16, 2.74)
0.667
2
(-0.01, 6.27)
(0.11, 0.51)
(-0.41, 5.71)
0.687
3
(-0.09, 9.42)
(0.37, 0.69)
(-0.54, 8.19)
1.312
4
(-0.29, 12.40)
(0.72, 0.70)
(-0.64, 10.80)
1.639
5
(-0.62, 15.25)
(0.74, 0.87)
(-0.71, 13.53)
1.728
6
(-1.14, 18.24)
(1.18, 0.98)
(-0.62, 16.30)
2.007
Per-step coordinates — sample 24
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(-0.12, 1.84)
(0.10, 0.18)
(-0.13, 1.56)
0.283
2
(-0.37, 3.78)
(-0.00, 0.57)
(-0.29, 3.25)
0.529
3
(-0.63, 5.24)
(0.05, 0.58)
(-0.68, 4.92)
0.327
4
(-0.92, 6.57)
(0.25, 0.73)
(-0.51, 6.68)
0.422
5
(-1.16, 7.57)
(0.30, 0.98)
(-0.71, 8.52)
1.052
6
(-1.44, 8.77)
(0.40, 1.25)
(-0.67, 10.21)
1.630
Per-step coordinates — sample 48
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.01, 4.25)
(0.23, 0.27)
(0.14, 4.88)
0.646
2
(0.01, 8.59)
(0.46, 0.91)
(0.18, 9.66)
1.089
3
(0.04, 12.83)
(0.87, 1.09)
(0.41, 14.03)
1.257
4
(0.12, 17.09)
(1.13, 1.27)
(0.38, 18.79)
1.721
5
(0.23, 21.24)
(1.12, 1.48)
(0.56, 23.23)
2.022
6
(0.36, 25.22)
(1.35, 1.68)
(0.45, 27.79)
2.573
Per-step coordinates — sample 96
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.00, 0.00)
(0.23, 0.01)
(-0.01, -0.03)
0.026
2
(-0.00, 0.00)
(0.03, 0.29)
(-0.04, 0.04)
0.057
3
(0.00, 0.00)
(0.05, 0.13)
(-0.02, 0.04)
0.042
4
(-0.00, 0.00)
(0.39, -0.09)
(0.01, -0.02)
0.017
5
(-0.00, 0.00)
(0.31, 0.07)
(-0.18, 0.00)
0.180
6
(-0.00, 0.00)
(0.68, 0.06)
(-0.19, 0.13)
0.232
Per-step coordinates — sample 160
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(-0.00, -0.00)
(0.28, -0.06)
(0.03, 0.08)
0.083
2
(0.00, 0.00)
(0.28, 0.31)
(0.16, 0.23)
0.282
3
(0.00, 0.00)
(0.24, 0.32)
(0.11, 0.27)
0.288
4
(0.00, 0.00)
(0.55, 0.03)
(0.15, 0.33)
0.360
5
(0.00, 0.00)
(0.58, -0.03)
(-0.02, 0.36)
0.364
6
(0.00, 0.00)
(0.73, -0.04)
(0.04, 0.46)
0.460
Per-step coordinates — sample 240
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.13, 7.54)
(0.26, 0.15)
(0.00, 6.24)
1.299
2
(0.38, 15.12)
(0.47, 0.81)
(0.17, 12.68)
2.449
3
(0.00, 0.00)
(0.70, 0.96)
(0.12, 18.82)
18.825
4
(0.00, 0.00)
(0.94, 1.12)
(0.26, 25.15)
25.156
5
(0.00, 0.00)
(1.04, 1.29)
(0.31, 31.61)
31.608
6
(0.00, 0.00)
(1.37, 1.45)
(0.05, 37.65)
37.646
Per-step coordinates — sample 32
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.00, 1.17)
(0.15, 0.16)
(0.13, 0.74)
0.452
2
(-0.00, 2.29)
(0.03, 0.78)
(0.15, 1.69)
0.625
3
(-0.05, 3.42)
(0.28, 0.81)
(0.05, 2.52)
0.906
4
(-0.16, 4.64)
(0.39, 0.89)
(0.02, 3.47)
1.187
5
(-0.40, 6.04)
(0.44, 1.08)
(-0.13, 4.27)
1.789
6
(-0.64, 7.04)
(0.49, 1.18)
(-0.03, 5.28)
1.856
Per-step coordinates — sample 64
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.04, 3.80)
(0.22, 0.32)
(0.18, 4.03)
0.268
2
(0.13, 7.88)
(0.28, 0.96)
(0.42, 7.94)
0.299
3
(0.29, 12.11)
(0.57, 1.14)
(0.47, 11.39)
0.745
4
(0.44, 16.41)
(0.75, 1.31)
(0.33, 15.39)
1.029
5
(0.62, 20.66)
(0.88, 1.60)
(0.71, 19.13)
1.532
6
(0.78, 24.82)
(1.13, 1.91)
(0.52, 22.85)
1.985
Per-step coordinates — sample 128
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.06, 1.78)
(0.18, 0.08)
(-0.06, 1.52)
0.284
2
(0.12, 3.49)
(0.28, 0.75)
(-0.16, 3.22)
0.390
3
(0.16, 4.99)
(0.47, 0.94)
(-0.13, 4.61)
0.483
4
(0.21, 6.35)
(0.74, 0.89)
(-0.03, 6.29)
0.252
5
(0.27, 7.56)
(0.83, 0.94)
(-0.18, 7.53)
0.450
6
(0.31, 8.63)
(1.11, 0.93)
(-0.16, 8.87)
0.535
Per-step coordinates — sample 192
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.03, 6.01)
(0.38, 0.31)
(0.08, 6.42)
0.405
2
(0.10, 12.15)
(0.38, 0.83)
(0.01, 12.61)
0.467
3
(0.16, 18.19)
(0.57, 0.87)
(-0.05, 18.66)
0.512
4
(0.20, 24.28)
(0.68, 1.00)
(-0.00, 24.81)
0.568
5
(0.24, 30.31)
(0.79, 1.33)
(0.09, 30.95)
0.652
6
(0.30, 36.35)
(1.25, 1.39)
(0.06, 36.98)
0.672
Per-step coordinates — sample 280
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.04, 6.27)
(0.07, 0.20)
(0.03, 5.32)
0.949
2
(0.08, 12.62)
(0.17, 0.85)
(0.25, 11.07)
1.557
3
(0.00, 0.00)
(0.52, 0.90)
(0.36, 16.24)
16.239
4
(0.00, 0.00)
(0.78, 0.93)
(0.21, 21.38)
21.383
5
(0.00, 0.00)
(0.86, 1.10)
(0.24, 26.70)
26.700
6
(0.00, 0.00)
(1.20, 1.33)
(-0.12, 31.95)
31.949
Per-step coordinates — sample 300
Step
GT (x, y)
SFT
GRPO mean
|GRPO−GT|
1
(0.01, 0.12)
(0.27, -0.08)
(0.06, 0.02)
0.107
2
(0.01, 0.16)
(0.23, 0.48)
(0.04, 0.02)
0.138
3
(0.01, 0.15)
(0.27, 0.48)
(-0.07, 0.07)
0.115
4
(0.02, 0.15)
(0.98, 0.44)
(0.03, 0.20)
0.047
5
(0.07, 0.37)
(1.03, 0.48)
(0.05, 0.18)
0.195
6
(0.14, 0.69)
(1.24, 0.46)
(0.10, 0.24)
0.453
12. What the blue path lets us conclude
Open-loop sample-best minADE improved from 9.80 m (phase0 smoke) to 0.00 m (phase3 best over G samples).
Sample-best minFDE improved from 16.99 m → 0.052 m on nuScenes mini.
Mean-path ADE on 12 eval frames: 3.60 m mean, 0.98 m median (best: phase4_fit_gt). Outliers idx 240/280 still ~16–20 m.
Phase4 GT-fit: last-10% sample-best minADE 0.87 m.
Phased curriculum matters: phase1 warmup on 50 frames drops minADE below 1 m before full GRPO.
Collision reward stayed at zero on mini — collision signal is sparse; trainval needed for safety claims.
Negative raw KL in late training indicates policy–reference density inversion; use KL floor or lower kl_coef.
Only LoRA parameter tensors plus log_std train; peak VRAM was ~7.3 GiB with G=8 on the RTX 4060 Ti 16GB campaign host.
Claims we can defend on mini:
The frozen-backbone planner-only recipe runs on a single 16 GB GPU with G=8.
Observed sample-best minFDE fell from 16.99 m to 0.052 m.
The staged curriculum changed both sampled and mean-path metrics, but the logs do not isolate
a causal contribution from PPO clipping.
Default UniAD stage-2 path remains unchanged when GRPO configs are not used.
Not yet claimed: trainval planning SOTA, closed-loop collision rate, alignment with VAD/STP3 official metrics.
Roadmap
Make the policy update strict: cache a behavior-policy snapshot, detach actions / advantages,
and replay multiple updates so $r$ can move and clipping can activate.
Add a KL floor or adaptive $\beta$ when raw KL goes negative (policy denser than reference).
Run nuScenes trainval and report L2 @ 3 s and collision rate with official eval scripts.
Hard-example mining for idx 240 / 280, then export LoRA-only deployment weights.
13. Reproduce
cd UniAD
# Full campaign + GT-fit iterations
/root/miniconda3/envs/uniad2.0/bin/python tools/run_planner_grpo_experiments.py \
--work-root projects/work_dirs/planner_posttrain/campaign --gpu 0
/root/miniconda3/envs/uniad2.0/bin/python tools/run_grpo_until_fit.py --gpu 0
# Aggregate metrics + render blog
/root/miniconda3/envs/uniad2.0/bin/python tools/analyze_planner_grpo_campaign.py
/root/miniconda3/envs/uniad2.0/bin/python tools/export_planner_waypoints.py \
--grpo-checkpoint projects/work_dirs/planner_posttrain/campaign/phase4_fit_gt/epoch_5.pth
/root/miniconda3/envs/uniad2.0/bin/python tools/render_planner_grpo_report.py
# Serve (WSL → Windows browser)
cd docs/planner_grpo_lora && python -m http.server 8765 --bind 0.0.0.0
# Open http://localhost:8765/index.html