Skip to content

Commit 83824f4

Browse files
kmbandyclaude
andcommitted
ml8: make determinism opt-in (ML8_DETERMINISTIC=1) — full-calib Cholesky regression deferred
The default-on determinism from 14bccfa breaks full-model calibration: from the first full-self-attention layer onward (layer 3 on 0.8B), torch.use_deterministic_algorithms(True) makes the SDPA forward yield a degenerate (NaN-suspected) Hessian for that layer's MLP → GPTQ Cholesky throws "not positive-definite" → the tensor is silently skipped → ~130/151 tensors fall back to bf16 in convert (1144 MB "model" with a misleading 18.25 PPL that's mostly bf16). Diagnosis (durable in KG): determinism is the trigger (det-off=151 tensors / det-on=21, same data); the failing tensors never reach batched_gptq (no diag line), and every Hessian the probe DID see is solidly PD (eig_min 0.05-0.15) — so it's not a marginal-conditioning issue, it's the self-attn forward corrupting the downstream Hessian. The "best-of-N + clean ladder" payoff still stands once this is fixed; reverting to opt-in restores the known-good nondeterministic calibrator as the default. Adds diag_soft_determinism.py (proved soft determinism = full coverage but NOT reproducible, so the hard hammer is load-bearing → must fix the SDPA/Cholesky path, not drop it). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 14bccfa commit 83824f4

2 files changed

Lines changed: 49 additions & 9 deletions

File tree

scripts/calibration/calibrate_ml8_paged.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@
5050

5151
print = functools.partial(print, flush=True)
5252

53-
# ── Deterministic calibration — env half (default-on; MUST precede `import torch`) ───
54-
# ml8 GPTQ calibration was nondeterministic: the GPU Hessian forward used unforced reduction
55-
# order and GPTQ's sequential error-feedback amplified the low-bit noise into DIFFERENT weight
56-
# assignments run-to-run (~0.6 PPL spread — swamps the ±0.05 levers). The fix is pinning the GEMM
57-
# workspace (here) + enabling deterministic algorithms (after the torch import). Verified
58-
# bit-identical across back-to-back runs on gfx1201. Opt out with ML8_NONDETERMINISTIC=1.
59-
_DETERMINISTIC = os.environ.get("ML8_NONDETERMINISTIC") != "1"
53+
# ── Deterministic calibration — env half (OPT-IN via ML8_DETERMINISTIC=1; MUST precede `import torch`) ───
54+
# ml8 GPTQ calibration was nondeterministic: the GPU Hessian forward used unforced reduction order
55+
# and GPTQ's sequential error-feedback amplified the low-bit noise into DIFFERENT weight assignments
56+
# run-to-run (~0.6 PPL spread — swamps the ±0.05 levers). These flags pin it bit-identically on the
57+
# linear-attn/MLP path (verified). BUT torch.use_deterministic_algorithms(True) currently breaks
58+
# full-model calibration: from the FIRST full-self-attention layer onward, the SDPA forward under
59+
# the hammer yields a degenerate (NaN-suspected) Hessian → GPTQ Cholesky fails → tensors silently
60+
# skipped → partial-coverage model. Root-cause + fix is deferred (see KG / handoff), so determinism
61+
# is OPT-IN until then; the default path is the known-good nondeterministic calibrator.
62+
_DETERMINISTIC = os.environ.get("ML8_DETERMINISTIC") == "1"
6063
if _DETERMINISTIC:
6164
os.environ.setdefault("CUBLAS_WORKSPACE_CONFIG", ":4096:8") # required for deterministic cuBLAS/hipBLAS GEMM
6265
os.environ.setdefault("HIPBLASLT_DETERMINISTIC", "1")
@@ -82,8 +85,8 @@
8285
("allow_bf16_reduced_precision_reduction", False)):
8386
try: setattr(torch.backends.cuda.matmul, _attr, _val)
8487
except AttributeError: pass
85-
print("[determinism] use_deterministic_algorithms(True) + seeded + pinned GEMM "
86-
"(set ML8_NONDETERMINISTIC=1 to disable)")
88+
print("[determinism] OPT-IN ENABLED: use_deterministic_algorithms(True) + seeded + pinned GEMM "
89+
"— WARNING: breaks full-model coverage at the first self-attn layer (Cholesky/SDPA bug, WIP)")
8790

8891
# Re-use existing calibration helpers (compute_hessian / gptq_quantize_linear / eval_ppl_wikitext / etc.)
8992
sys.path.insert(0, str(Path(__file__).parent))
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env python3
2+
"""Test 'soft' determinism: seed + pinned GEMM workspace + tf32 off, but WITHOUT the strict
3+
torch.use_deterministic_algorithms(True) hammer. Hypothesis: the hammer is what perturbs
4+
cholesky_inverse into a non-PD H^-1 (breaking GPTQ's second Cholesky on 130/151 tensors), while
5+
softer determinism still gives bit-reproducible calibration. Disables the driver's built-in
6+
(hard) determinism block via ML8_NONDETERMINISTIC=1, then sets the soft subset here."""
7+
import os
8+
import sys
9+
10+
os.environ["ML8_NONDETERMINISTIC"] = "1" # skip the driver's hard-determinism block
11+
os.environ.setdefault("CUBLAS_WORKSPACE_CONFIG", ":4096:8")
12+
os.environ.setdefault("HIPBLASLT_DETERMINISTIC", "1")
13+
14+
import torch # noqa: E402
15+
16+
torch.manual_seed(0)
17+
if torch.cuda.is_available():
18+
torch.cuda.manual_seed_all(0)
19+
for _obj, _attr, _val in (
20+
(torch.backends.cudnn, "deterministic", True),
21+
(torch.backends.cudnn, "benchmark", False),
22+
(torch.backends.cudnn, "allow_tf32", False),
23+
(torch.backends.cuda.matmul, "allow_tf32", False),
24+
(torch.backends.cuda.matmul, "allow_fp16_reduced_precision_reduction", False),
25+
(torch.backends.cuda.matmul, "allow_bf16_reduced_precision_reduction", False),
26+
):
27+
try:
28+
setattr(_obj, _attr, _val)
29+
except AttributeError:
30+
pass
31+
print("[soft-determinism] seed + pinned GEMM + tf32 off, NO use_deterministic_algorithms",
32+
file=sys.stderr, flush=True)
33+
34+
_here = os.path.dirname(os.path.abspath(__file__))
35+
sys.argv = [os.path.join(_here, "calibrate_ml8_paged.py")] + sys.argv[1:]
36+
import runpy # noqa: E402
37+
runpy.run_path(sys.argv[0], run_name="__main__")

0 commit comments

Comments
 (0)