Skip to content

fix: stabilize FASB fine-tuning protocol - #8

Merged
Ian747-tw merged 6 commits into
mainfrom
fix/stabilize-fasb-training
May 23, 2026
Merged

Ian747-tw merged 6 commits into
mainfrom
fix/stabilize-fasb-training

Conversation

@Ian747-tw

@Ian747-tw Ian747-tw commented May 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

Fixes the Axis 1 stabilization protocol after review found an optimizer confound: stable FASB used learning_rate=0.00003, while the old naive/fixed baselines used linear:3.0e-4.

This PR now keeps FASB-PPO as SB3 PPO + failure-aware sampler + adaptive safety penalty, and makes the fair Axis 1 comparison use the same stable optimizer and dev checkpoint-selection policy for all fine-tuned methods.

Codex P1 fairness issue addressed

The previous PR version compared stable FASB against old naive/fixed runs with a different optimizer regime. Optimizer is not the research variable, so that comparison was confounded.

Added fair stable-protocol baseline configs:

  • configs/research_v1/axis1_naive_stable_final.yaml
  • configs/research_v1/axis1_fixed_budget_stable_final.yaml
  • existing configs/research_v1/axis1_fasb_stable_final.yaml

All stable-protocol fine-tuned methods use:

  • base checkpoint: runs/research_v1/base_pretrain_s42/checkpoints/final.zip
  • train steps: 300000
  • train seeds: start_seed=2000, num_scenarios=500
  • horizon=500, traffic_density=0.1
  • vec_env.type=dummy, vec_env.n_envs=1
  • algorithm.params.device=cpu
  • algorithm.params.learning_rate=0.00003
  • dev checkpoint selection on start_seed=4500, num_scenarios=100, eval.n_episodes=100
  • final heldout eval on start_seed=5000, num_scenarios=200, eval.n_episodes=100

Stable FASB config remains:

  • sampler.failure_ratio=0.05
  • safety_budget.d_min=0.10
  • safety_budget.d_max=0.30
  • safety_budget.timeout_budget=0.30
  • penalty_scheduler.lambda_min=0.0
  • penalty_scheduler.lambda_max=0.25

Stable-protocol dev selection

method selected checkpoint success timeout route collision offroad cost safety-eff
Naive stable latest_300000_steps.zip 0.48 0.52 0.6901 0.19 0.40 242.79 -0.370
Fixed-budget stable final.zip 0.50 0.50 0.6962 0.20 0.47 247.28 -0.420
Stable FASB selected_dev_best.zip from fasb_stable_ratio005_penalty025 0.50 0.50 0.7532 0.33 0.25 230.28 -0.330

Stable FASB was not reselected from final heldout. The final heldout was not used for candidate selection.

Final heldout results

method success timeout route collision offroad cost safety-eff
Naive stable 0.44 0.56 0.6828 0.22 0.39 245.06 -0.450
Fixed-budget stable 0.48 0.52 0.7288 0.23 0.41 241.40 -0.420
Stable FASB 0.53 0.47 0.7330 0.30 0.37 230.27 -0.375

Stable FASB still beats naive stable under fair settings on success, timeout, route completion, episode cost, and safety-efficiency. It does not dominate every raw safety metric: collision is higher than naive stable, while offroad is lower.

Historical diagnostics remain visible in the local Axis 1 report:

  • Old naive protocol: success=0.40, timeout=0.60, route=0.6734, cost=267.90, safety-eff=-0.590
  • Old fixed-budget protocol: success=0.00, timeout=1.00, route=0.0029, safety-eff=-1.450
  • Original FASB collapsed: success=0.00, timeout=1.00, route=0.0143, cost=0.00, safety-eff=-0.500
  • Failed v2 collapsed: success=0.00, timeout=1.00, route=0.0121, cost=596.30, safety-eff=-1.270

Other source fixes in this PR

  • MixedFailureSampler filters canonical failure-buffer records to the active trainer seed range and falls back to random sampling when no eligible failure exists.
  • Checkpoint fine-tuning now honors configured SB3 params, including LR and device, when loading a checkpoint.
  • CostFunctionWrapper.reset() calls plugin reset hooks when present.
  • EventDrivingCost was added as an optional event-style cost plugin and tested, but it is not the selected stable default.
  • scripts/select_best_checkpoint.py evaluates saved checkpoints on dev seeds and copies the selected checkpoint to selected_dev_best.zip.
  • Docs now state that fair Axis 1 claims require the same stable optimizer and dev checkpoint-selection protocol across fine-tuned methods.

Validation

  • python -m compileall fasb tests scripts examples -q
  • python -m pytest tests/test_component_validation.py tests/test_failure_buffer.py tests/test_metrics.py tests/test_training_stability_patch.py tests/test_plugin_loading.py tests/test_run_dir.py tests/test_research_plugins.py tests/test_aggregate_results.py tests/test_base_checkpoint_quality.py tests/test_failure_buffer_quality.py tests/test_research_v1_ready.py tests/test_research_v1_artifact_scripts.py tests/test_select_best_checkpoint.py -q
  • python scripts/validate_components.py --config configs/research_v1/axis1_fasb_stable_final.yaml
  • python scripts/validate_components.py --config configs/research_v1/axis1_naive_stable_final.yaml
  • python scripts/validate_components.py --config configs/research_v1/axis1_fixed_budget_stable_final.yaml

Axis 2-5 status

Approved to proceed from the calibrated stable FASB default if review agrees the optimizer-confound is resolved. Axis 2/3 should vary sampler and budget/penalty around this default while preserving the shared stable optimizer/checkpoint-selection protocol for compared methods.

@Ian747-tw

Copy link
Copy Markdown
Owner Author

@codex review this PR. Focus on whether FASB stabilization avoids timeout collapse scientifically, uses dev checkpoint selection instead of final-heldout tuning, and preserves fair Axis 1 comparison.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: edf969a2e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

mode: fasb_ppo
metadrive: {env_class: metadrive.envs.MetaDriveEnv, config: {start_seed: 2000, num_scenarios: 500, traffic_density: 0.1, random_traffic: true, use_render: false, horizon: 500, log_level: 50, crash_vehicle_done: false, crash_object_done: false, out_of_road_done: false}}
vec_env: {type: dummy, n_envs: 1, start_method: forkserver}
algorithm: {backend: sb3, name: PPO, policy: MlpPolicy, checkpoint_path: runs/research_v1/base_pretrain_s42/checkpoints/final.zip, params: {learning_rate: 0.00003, n_steps: 128, batch_size: 64, n_epochs: 10, gamma: 0.99, gae_lambda: 0.95, clip_range: 0.2, ent_coef: 0.0, vf_coef: 0.5, max_grad_norm: 0.5, verbose: 1, device: cpu, policy_kwargs: {net_arch: [256, 256]}}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep PPO hyperparameters fixed across Axis 1 methods

This config changes FASB’s optimizer regime (learning_rate: 0.00003) while the Axis 1 naive and fixed-budget baselines still use the original linear:3.0e-4 schedule, so the reported timeout-collapse recovery is no longer attributable to FASB stabilization alone. Because this PR’s stated goal is a fair Axis 1 method comparison, per-method optimizer retuning introduces a direct confound unless the same dev tuning/checkpoint-selection policy is applied to all compared methods.

Useful? React with 👍 / 👎.

@Ian747-tw

Copy link
Copy Markdown
Owner Author

@codex review this PR again. I addressed the optimizer-confound by rerunning Axis 1 baselines under the same stable learning rate and dev checkpoint-selection protocol as stable FASB. Please check whether the comparison is now scientifically fair and whether Axis 2–5 can proceed from the calibrated default.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3048bc2bbd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +201 to +205
if selected is None:
print("No checkpoint passed hard reject screen")
else:
print(f"Selected checkpoint: {selected['checkpoint']}")
return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exit with error when no checkpoint is selected

When every candidate is hard-rejected, the script only prints a message and still returns success, leaving selected_dev_best.zip absent. The documented next step evaluates that path, and Evaluator._load_policy() falls back to RandomPolicy if the checkpoint file is missing, so an entire method can be scored as random behavior without the pipeline failing. This silently corrupts the fairness comparison in exactly the low-performing cases the hard-reject screen is meant to catch.

Useful? React with 👍 / 👎.

@Ian747-tw

Copy link
Copy Markdown
Owner Author

@codex review this PR again. I addressed the remaining P1 by making checkpoint selection exit nonzero when all candidates are hard-rejected, and by making explicit missing checkpoint evaluation raise instead of falling back to RandomPolicy. Tests now cover both cases. Please confirm whether there are no remaining issues.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Ian747-tw

Copy link
Copy Markdown
Owner Author

@codex review this PR again. I aligned Axis 2–5 final configs/docs with the stable FASB protocol and moved/marked old unstable configs as screening/historical. Please check that teammates cannot accidentally run the old failed FASB defaults for final axes.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Ian747-tw

Copy link
Copy Markdown
Owner Author

@codex review this PR again. CI failed because a lightweight test imported stable_baselines3 directly; I replaced it with a sys.modules fake so lightweight CI remains dependency-light while still testing checkpoint-load param forwarding. Please check for remaining blockers.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89fd225be7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +98 to +99
with pytest.raises(FileNotFoundError):
Evaluator(cfg, tmp_path)._load_policy(tmp_path / "missing.zip", env)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid SB3 dependency in missing-checkpoint unit test

This new lightweight test still depends on stable_baselines3: calling Evaluator._load_policy(tmp_path / "missing.zip", env) imports SB3 before checking whether the checkpoint exists, so environments without SB3 raise ModuleNotFoundError instead of the expected FileNotFoundError. That means dependency-light CI can still fail even though other tests were switched to sys.modules fakes. Please stub SB3 in this test (as done in test_checkpoint_finetune_honors_configured_algorithm_params) or avoid this code path in the lightweight suite.

Useful? React with 👍 / 👎.

@Ian747-tw

Copy link
Copy Markdown
Owner Author

@codex review this PR again. I addressed the lightweight-CI blocker by checking explicit missing eval checkpoints before importing stable_baselines3, so the missing-checkpoint unit test no longer needs SB3 installed. Please confirm there are no remaining blockers.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Ian747-tw
Ian747-tw merged commit f3bac0f into main May 23, 2026
2 checks passed
@Ian747-tw
Ian747-tw deleted the fix/stabilize-fasb-training branch May 23, 2026 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant