From ab4fcd2932deae1cb1a8a2e7b622d5483a11d778 Mon Sep 17 00:00:00 2001 From: wassname Date: Sat, 23 May 2026 21:28:06 +0000 Subject: [PATCH] guided: case (c) pmass_allowed=0.0 instead of NaN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the model emits in natural generation but the answer-slot window detection fails, that's coherence collapse — the model "finished thinking" without producing JSON. pmass=0.0 is the honest measurement (no probability mass on allowed tokens at a non-existent slot) and lets the coherence canary see the failure as a real signal rather than propagating NaN through np.mean to crash c_scan. nll_json stays NaN since no JSON was emitted to score. Triggered by qwen3.6-27b nf4 + LoRA at c=1.0: 1/4 samples hit case (c) and the NaN aborted c_scan instead of letting it walk down further. --- src/tinymfv/guided.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tinymfv/guided.py b/src/tinymfv/guided.py index 63e8c26..7543f13 100644 --- a/src/tinymfv/guided.py +++ b/src/tinymfv/guided.py @@ -285,9 +285,15 @@ def _rollout_natural_or_forced( lp_vec = forced_lp_last[i] nll_val = float(forced_nll_json[i].item()) else: - # Case (c) emitted but no natural answer: undefined + # Case (c) emitted but no natural answer slot found. + # Model "finished thinking" without producing JSON — coherence + # collapse at the answer slot. pmass=0.0 is the honest measurement + # (no probability mass on allowed tokens at a non-existent slot) + # and lets c_scan see the failure as a real signal rather than + # crashing on NaN. nll_json stays NaN (genuinely undefined: no + # JSON tokens were emitted to score). slots[i].append({ - "pmass_allowed": float("nan"), + "pmass_allowed": 0.0, "nll_json": float("nan"), "top5_str": "", "lp_gather": [float("nan")] * len(gather_token_ids),