Download code/tests/test_audit_g2_lora_export_fixes.py from viai957/align: direct link, hf CLI and curl.
- Browser
- Download file 9.24 kB
-
https://huggingface.co/viai957/align/resolve/main/code/tests/test_audit_g2_lora_export_fixes.py
- Command line
-
hf download hf://viai957/align/code/tests/test_audit_g2_lora_export_fixes.py
-
curl -L -o test_audit_g2_lora_export_fixes.py https://huggingface.co/viai957/align/resolve/main/code/tests/test_audit_g2_lora_export_fixes.py
9.24 kB
| """Regression tests for the 2026-10-14 audit findings U03-3, U03-4, U05-1, U11-8, U11-9, U11-18 | |
| (LoRA export fidelity, adapter-to-base binding on resume, export-check gating and GPU pinning). | |
| Run: cd /apps/development/rlhf/align && CUDA_VISIBLE_DEVICES= .venv/bin/python -m pytest \ | |
| tests/test_audit_g2_lora_export_fixes.py -q -p no:cacheprovider | |
| """ | |
| from __future__ import annotations | |
| import importlib.util | |
| import logging | |
| import os | |
| import pytest | |
| import torch | |
| from test_qwen3_parity import make_tiny, rescale_ | |
| REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| def _load(name): | |
| spec = importlib.util.spec_from_file_location(name, os.path.join(REPO, "scripts", f"{name}.py")) | |
| m = importlib.util.module_from_spec(spec) | |
| spec.loader.exec_module(m) | |
| return m | |
| exp = _load("qwen3_export_check") | |
| # --------------------------------------------------------------------------- | |
| # U05-1 / U03-3: the bf16 merge cast is lossy; the export must MEASURE and (optionally) refuse | |
| # --------------------------------------------------------------------------- | |
| def _bf16_lora(b_scale: float): | |
| from align.ppo.lora import LoRAConfig, inject_lora, lora_modules | |
| m = make_tiny().to(torch.bfloat16) | |
| inject_lora(m, LoRAConfig(r=4, alpha=8.0), adapter="sft", generator=torch.Generator().manual_seed(1)) | |
| g = torch.Generator().manual_seed(2) | |
| with torch.no_grad(): | |
| for _, mod in lora_modules(m): | |
| mod.adapters["sft"].B.copy_(b_scale * torch.randn(mod.adapters["sft"].B.shape, generator=g)) | |
| return m | |
| def test_export_reports_retained_delta_and_warns_when_bf16_drops_most_of_it(caplog): | |
| from align.ppo.lora import export_merged_state_dict | |
| m = _bf16_lora(1e-5) # the shipped PPO lr=1e-6 regime: delta << half an ulp of W | |
| rep: dict = {} | |
| with caplog.at_level(logging.WARNING): | |
| export_merged_state_dict(m, {k: v.detach().clone() for k, v in m.state_dict().items()}, "sft", report=rep) | |
| assert rep["cosine"] < 0.5 and rep["dropped_fraction"] > 0.5, rep | |
| assert rep["layers"] > 0 and rep["min_layer_cosine"] <= rep["cosine"] + 1e-6 | |
| assert any("bf16" in r.message and "cosine" in r.message for r in caplog.records) | |
| def test_export_refuses_below_min_cosine_and_passes_a_well_resolved_delta(caplog): | |
| from align.ppo.lora import export_merged_state_dict | |
| full = lambda m: {k: v.detach().clone() for k, v in m.state_dict().items()} # noqa: E731 | |
| small = _bf16_lora(1e-5) | |
| with pytest.raises(ValueError, match="cosine"): | |
| export_merged_state_dict(small, full(small), "sft", min_cosine=0.9) | |
| big = _bf16_lora(5.0) # delta >> ulp: the cast preserves it | |
| rep: dict = {} | |
| with caplog.at_level(logging.WARNING): | |
| export_merged_state_dict(big, full(big), "sft", report=rep, min_cosine=0.9) | |
| assert rep["cosine"] > 0.95 | |
| assert not any("cosine" in r.message for r in caplog.records) | |
| def test_export_of_an_exactly_zero_adapter_is_reported_not_nan(): | |
| from align.ppo.lora import export_merged_state_dict | |
| m = _bf16_lora(0.0) | |
| rep: dict = {} | |
| export_merged_state_dict(m, {k: v.detach().clone() for k, v in m.state_dict().items()}, "sft", report=rep) | |
| assert rep["delta_norm"] == 0.0 and rep["cosine"] == 1.0 | |
| # --------------------------------------------------------------------------- | |
| # U03-4: a LoRA resume binds the adapter to the base it was trained on | |
| # --------------------------------------------------------------------------- | |
| def test_lora_payload_carries_a_base_fingerprint_and_a_foreign_base_is_refused(tmp_workdir, monkeypatch): | |
| import test_qwen3_stage as T | |
| tr, _, _ = T._build(tmp_workdir, "a") | |
| payload = tr.train_module.optim_state_dict() | |
| assert isinstance(payload.get("base_fingerprint"), str) and len(payload["base_fingerprint"]) == 64 | |
| # the same base resumes fine | |
| tr_same, _, _ = T._build(tmp_workdir, "same") | |
| tr_same.train_module.load_optim_state_dict(payload) | |
| # a different base with an identical key set / shapes (repointed snapshot) must not | |
| monkeypatch.setattr(T, "make_tiny", lambda: rescale_(make_tiny(), seed=7)) | |
| tr_other, _, _ = T._build(tmp_workdir, "other") | |
| with pytest.raises(RuntimeError, match="base"): | |
| tr_other.train_module.load_optim_state_dict(payload) | |
| def test_legacy_payload_without_a_fingerprint_still_resumes_with_a_warning(tmp_workdir, caplog): | |
| import test_qwen3_stage as T | |
| tr, _, _ = T._build(tmp_workdir, "a") | |
| payload = tr.train_module.optim_state_dict() | |
| payload.pop("base_fingerprint") | |
| with caplog.at_level(logging.WARNING): | |
| tr.train_module.load_optim_state_dict(payload) | |
| assert any("fingerprint" in r.message for r in caplog.records) | |
| def test_fingerprint_tracks_content_not_just_keys(): | |
| from align.train.qwen3_stage import base_fingerprint | |
| a, b = make_tiny(), make_tiny() | |
| assert base_fingerprint(a.state_dict()) == base_fingerprint(b.state_dict()) | |
| with torch.no_grad(): | |
| b.model.layers[0].attn.q_norm.weight.mul_(1.001) | |
| assert base_fingerprint(a.state_dict()) != base_fingerprint(b.state_dict()) | |
| other = rescale_(make_tiny(), seed=7) | |
| assert base_fingerprint(a.state_dict()) != base_fingerprint(other.state_dict()) | |
| # --------------------------------------------------------------------------- | |
| # U11-8: the exit status gates every check the script advertises | |
| # --------------------------------------------------------------------------- | |
| def _good_report(): | |
| return { | |
| "verdict": {"passed": True}, | |
| "merge_vs_trainer_file": {"bitwise_mismatches": 0}, | |
| "snapshot_mapping_roundtrip": {"bitwise_equal": True}, | |
| "merge_changed_tensors_vs_snapshot": 12, | |
| "merge_relative_weight_change": {"n": 12, "min": 1e-4, "mean": 4e-4, "max": 1e-3}, | |
| "adapter_vs_merged": {"verdict": {"passed": True}}, | |
| } | |
| def test_export_ok_passes_a_complete_report(): | |
| assert exp.export_ok(_good_report()) is True | |
| def test_export_ok_fails_each_unmet_check(mutate): | |
| r = _good_report() | |
| mutate(r) | |
| assert exp.export_ok(r) is False | |
| # --------------------------------------------------------------------------- | |
| # U11-9: merged-bf16 vs adapter-applied forward | |
| # --------------------------------------------------------------------------- | |
| def _lp(t=64, v=50, seed=0): | |
| g = torch.Generator().manual_seed(seed) | |
| return torch.log_softmax(3 * torch.randn(t, v, generator=g), -1) | |
| def test_adapter_vs_merged_passes_identical_and_fails_a_dropped_delta(): | |
| a = _lp() | |
| same = exp.evaluate_adapter_vs_merged(exp.compare_adapter_vs_merged([a], [a.clone()])) | |
| assert same["passed"] is True | |
| other = _lp(seed=5) # an unrelated distribution: what a merge that lost the delta looks like | |
| bad = exp.evaluate_adapter_vs_merged(exp.compare_adapter_vs_merged([a], [other])) | |
| assert bad["passed"] is False | |
| near = a + 0.02 * torch.randn(a.shape, generator=torch.Generator().manual_seed(3)) | |
| ok = exp.evaluate_adapter_vs_merged(exp.compare_adapter_vs_merged([a], [torch.log_softmax(near, -1)])) | |
| assert ok["passed"] is True | |
| def test_adapter_vs_merged_shape_mismatch_raises(): | |
| with pytest.raises(ValueError): | |
| exp.compare_adapter_vs_merged([_lp(8)], [_lp(9)]) | |
| def test_merge_fidelity_stats_expose_the_dead_zone(): | |
| from align.ppo.lora import lora_state_dict | |
| m = _bf16_lora(1e-5) | |
| base = {k: v.detach().clone() for k, v in m.state_dict().items() if ".adapters." not in k} | |
| lora = lora_state_dict(m, "sft") | |
| merged = exp.merge_lora_state(base, lora, 2.0) | |
| st = exp.merge_fidelity_stats(base, merged, lora, 2.0) | |
| assert st["cosine"] < 0.5 and st["dropped_fraction"] > 0.5 and st["layers"] > 0 | |
| # --------------------------------------------------------------------------- | |
| # U11-18: the vLLM child is pinned to the PARENT's first visible device | |
| # --------------------------------------------------------------------------- | |
| def test_first_visible_gpu_follows_the_parent_pinning(cvd, expect): | |
| env = {} if cvd is None else {"CUDA_VISIBLE_DEVICES": cvd} | |
| assert exp._first_visible_gpu(env) == expect | |
| def test_rollout_env_uses_the_pinned_device_not_physical_zero(monkeypatch): | |
| monkeypatch.setenv("CUDA_VISIBLE_DEVICES", "2,3") | |
| assert exp._rollout_env(exp._first_visible_gpu())["CUDA_VISIBLE_DEVICES"] == "2" | |