diff --git a/conditioning.py b/conditioning.py index 404cc186..243b77b5 100644 --- a/conditioning.py +++ b/conditioning.py @@ -10194,23 +10194,15 @@ class FunPackVideoRefinerV2(FunPackVideoRefiner): if _is_h3: try: from . import h3_repr_steering as _rs - from . import trajectory_probe as _tp except ImportError: import h3_repr_steering as _rs - import trajectory_probe as _tp _rs_reward = float(learning_profile.get("reward", 0.0)) - # Same prompt_hash trajectory_probe uses -- block_sweep() groups by it so - # "these are different prompts" cannot masquerade as "these are different - # ratings", the confound that made the FIRST cross-prompt read of this - # project's output value function come out inverted. # Block sweep is NOT printed here -- it's the same computation the # Settings > Refinement & Taste panel already runs on demand and shows as # a table (reinsRows in settings_window.js), and running the full # permutation test on every single rating just to throw the ranked line # into the console was pure noise duplicating what the panel already has. - _rs_outcome = _rs.commit( - refinement_key, _rs_reward, - prompt_hash=_tp.prompt_hash((previous_run or {}).get("conditioning"))) + _rs_outcome = _rs.commit(refinement_key, _rs_reward) # The reward is always correct once computed -- what actually varies run to # run is whether there was a captured generation to PAIR it with, and a log # line that only ever reports the reward cannot tell a real commit apart diff --git a/h3_repr_steering.py b/h3_repr_steering.py index 3b84fadb..03a812ba 100644 --- a/h3_repr_steering.py +++ b/h3_repr_steering.py @@ -105,7 +105,7 @@ def capture(hidden_state, video_mask): # --- persistence ------------------------------------------------------------------------- # -# One row per generation: {"desc": {block: tensor}, "weight": float, "prompt_hash": str|None}. +# One row per generation: {"desc": {block: tensor}, "weight": float}. # Kept as a log and the direction recomputed from it on demand -- same reasoning # trajectory_guidance's train_from_rows gives: this is cheap enough that being able to # re-derive it (a log carried from another box, a fixed weighting formula) is worth more than @@ -154,11 +154,11 @@ def save_pending(refinement_key, descriptors): "this run's capture is not kept") -def commit(refinement_key, reward, prompt_hash=None): - """Pairs the pending capture with a rating's WEIGHT (and the prompt it was rated under, - for block_sweep's cross-prompt guard) and appends it to the log. `reward` is the caller's - already-resolved, already-admissibility-filtered reward -- this function trusts it rather - than re-deriving a verdict, same as the value functions do with the same number. +def commit(refinement_key, reward): + """Pairs the pending capture with a rating's WEIGHT and appends it to the log. `reward` + is the caller's already-resolved, already-admissibility-filtered reward -- this function + trusts it rather than re-deriving a verdict, same as the value functions do with the same + number. -> "recorded" | "no_pending" (nothing generated since the last rating) | "no_key". The caller prints this, not just the reward it computed -- a reward can be correct and still @@ -176,8 +176,7 @@ def commit(refinement_key, reward, prompt_hash=None): pass return "no_pending" try: - data["rows"].append({"desc": pending, "weight": float(reward), - "prompt_hash": prompt_hash}) + data["rows"].append({"desc": pending, "weight": float(reward)}) except (TypeError, ValueError): try: _save(refinement_key, data) @@ -251,13 +250,13 @@ def block_sweep(refinement_key, trials=2000): reusing trajectory_probe's own permutation test (the one that correctly found real signal in the early-schedule work this session, after the centring fix) instead of trusting REINS' 50%-depth heuristic or porting a diagnostic built for a different question (LTXAV's - identity-block search measured cross-scene consistency, not liked-vs-disliked separation). + identity-block search measured cross-scene consistency, not liked-vs-disliged separation). - Grouped by prompt_hash so "these are different prompts" cannot masquerade as "these are - different ratings" -- the same confound that made the first cross-prompt read of this - project's OTHER value function come out backwards. Rows with weight == 0 (a rating that - landed exactly at the scale's neutral midpoint) are dropped -- neither liked nor disliked. - """ + No cross-prompt grouping -- it was tried (prompt_hash on each row) and dropped: the + R2V-wired conditioning this runs on never produced a real hash, so the guard was + permanently inert, and fixing it was declined as not worth the continued attention. Rows + with weight == 0 (a rating exactly at the scale's neutral midpoint) are dropped -- neither + liked nor disliked.""" tp = _trajectory_probe() data = _load(refinement_key) rows = [r for r in data["rows"] @@ -270,10 +269,7 @@ def block_sweep(refinement_key, trials=2000): continue descriptors = [r["desc"][block] for r in have] labels = [r["weight"] > 0 for r in have] - groups = [r.get("prompt_hash") for r in have] - if any(g is None for g in groups): - groups = None # can't stratify by a hash some rows never recorded - result = tp.permutation_test(descriptors, labels, groups=groups, trials=trials) + result = tp.permutation_test(descriptors, labels, trials=trials) if result is not None: out[block] = result return out diff --git a/tests/test_h3_repr_steering.py b/tests/test_h3_repr_steering.py index 079320df..1db8fae0 100644 --- a/tests/test_h3_repr_steering.py +++ b/tests/test_h3_repr_steering.py @@ -200,7 +200,7 @@ def test_block_sweep_ranks_a_real_signal_over_pure_noise(): desc10 = torch.tensor([3.0, 0.0]) if liked else torch.tensor([-3.0, 0.0]) desc20 = torch.randn(2) # unrelated to the rating rs.save_pending("k", {10: desc10, 20: desc20}) - rs.commit("k", 1.0 if liked else -1.0, prompt_hash="same-prompt") + rs.commit("k", 1.0 if liked else -1.0) sweep = rs.block_sweep("k", trials=500) assert 10 in sweep and sweep[10]["p_value"] < 0.2 assert sweep[10]["separation"] > 0