Skip to content

Make the observer LR gate two-channel (entropy + drift)#670

Merged
InauguralPhysicist merged 1 commit into
mainfrom
observer-lr-gate-two-channel
Jul 18, 2026
Merged

Make the observer LR gate two-channel (entropy + drift)#670
InauguralPhysicist merged 1 commit into
mainfrom
observer-lr-gate-two-channel

Conversation

@InauguralPhysicist

Copy link
Copy Markdown
Collaborator

The defect

observer_matrix_scale — the production learning-rate gate in the transformer trainer — throttled a weight matrix to 0.5x whenever its entropy channel was quiet. That entropy is computed over a single SGD step's worth of weight change, which sits far below thresholds calibrated for scalar convergence loops, so the "quiet" test was effectively always true.

Instrumented over 2,597 steps x 42 matrices:

verdict matrix-steps share
0.5x "stable" 108,514 100.0%
0.3x oscillating 14 0.0%
1.0x full rate 0 never fired

An adaptive gate that never adapts is a constant 0.5x drag — and it was applying that drag while the loss was plainly still falling (6.09 -> 0.54).

Why the observer couldn't see it

The observer buffer here carries only entropy-derived state — entropy, dH, last_entropy, obs_age, prev_dH. There is no value channel at all, so slow-but-steady motion is invisible to it. This is the observer's own failure mode: a meter blind to slow motion certifying a moving system as converged.

The fix

Add the missing channel as relative drift ||grad|| / ||w||, and release the "stable" verdict when the weights are still moving. The 0.3x oscillating and 0.1x diverging verdicts are left untouched — those are genuine instability signals the entropy channel reads correctly.

The two channels disagreed on 100% of matrix-steps, and ground truth says drift was right every time. The gate now releases 99.6% and throttles only real oscillation (0.4%).

Three-way A/B

Fixed checkpoint, 400 windows, identical seeds:

step entropy-only (status quo) gate OFF two-channel
100 1.554582 1.205151 1.237571
200 1.405466 1.012344 0.975602
300 0.728710 0.542757 0.553253

Two-channel recovers ~all of the gate-off gain (~25% better loss than the status quo) while retaining the ability to throttle a matrix that genuinely settles — which "off" permanently gives up.

Honest limit: this A/B cannot separate off from two-channel. During active learning "release everything" and "off" are the same policy, so the distinction is structural and would only show in a long run where something actually settles. What it does establish decisively is that the status quo is the worst of the three.

Controls retained

All three arms stay selectable for future A/B: EIGS_OBS_ENTROPY_ONLY=1 (old single-channel), EIGS_OBS_SCALE_OFF=1 (no gating), EIGS_OBS_DRIFT_EPS (release threshold, default 1e-3).

Testing

Suite 3164/3164 on the http+model build; [47c] gradcheck still pins the batched path to the per-position oracle.

🤖 Generated with Claude Code

observer_matrix_scale throttled a weight matrix to 0.5x whenever its
entropy channel was quiet. But that entropy is computed over a single
SGD step's worth of weight change, which sits far below thresholds
calibrated for scalar convergence loops -- so the "quiet" test was
effectively always true.

Instrumented over 2,597 steps x 42 matrices, the gate classified
"stable" for 100.0% of matrix-steps and emitted the 1.0x full-rate
verdict zero times. An adaptive gate that never adapts is a constant
0.5x drag, and it was applying that drag while the loss was plainly
still falling (6.09 -> 0.54).

The observer buffer here carries only entropy-derived state
(entropy, dH, last_entropy, obs_age, prev_dH) -- there is no value
channel at all, so slow-but-steady motion is invisible to it. This
adds that channel as relative drift ||grad|| / ||w|| and releases the
"stable" verdict when the weights are still moving, leaving the
oscillating (0.3x) and diverging (0.1x) verdicts untouched since those
are genuine instability signals the entropy channel reads correctly.

The two channels disagreed on 100% of matrix-steps, and ground truth
says drift was right every time: the gate now releases 99.6% and
throttles only real oscillation (0.4%).

Three-way A/B, fixed checkpoint, 400 windows, identical seeds:

  step        entropy-only   gate off   two-channel
  100          1.554582      1.205151    1.237571
  200          1.405466      1.012344    0.975602
  300          0.728710      0.542757    0.553253

Two-channel recovers ~all of the gate-off gain (~25% better loss than
the status quo) while retaining the ability to throttle a matrix that
genuinely settles -- which "off" permanently gives up. Note the A/B
cannot separate off from two-channel here: during active learning
"release everything" and "off" are the same policy, so the distinction
is structural and would only show in a long run where something
actually settles.

All three arms stay selectable for future A/B:
EIGS_OBS_ENTROPY_ONLY=1 (old single-channel), EIGS_OBS_SCALE_OFF=1
(no gating), EIGS_OBS_DRIFT_EPS (release threshold, default 1e-3).

Suite: 3164/3164 on the http+model build, [47c] gradcheck still pins
the batched path to the per-position oracle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@InauguralPhysicist
InauguralPhysicist merged commit 262556d into main Jul 18, 2026
18 checks passed
@InauguralPhysicist
InauguralPhysicist deleted the observer-lr-gate-two-channel branch July 18, 2026 10:47
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