verl comm-eff research · offline weight-projection analysis · 2026-07-03

Do RLVR weight updates move in one straight line? — testing the rank-1 idea on our own model

Two 2026 papers claim that during RLVR training an LLM’s weights barely wander: they move along essentially one fixed direction in weight space, at a steady pace, so you can predict a far-future checkpoint from a handful of early ones. This page explains what that claim means, then shows — with plots from our own model (Qwen2.5-1.5B, GRPO on GSM8K) — how much of it holds here and how well we can actually project the weights forward. Every plot is labelled with which way is “better.”

Paper B = RELEX, arXiv:2605.2146826/26 self-tests raw-tensor audit PASSindependent verifier PASS @ ~1e-14 EXP-57 fp32 · 160 ticks · 61-matrix panel
On this page: 0 · Primer: delta, "rank-1", direction 1 · Are updates rank-1? 2 · Does the coefficient grow linearly? 3 · Is the direction stable? 4 · How accurate is the projection? 5 · Window size & training stage 6 · What it means for us

0 · Primer — the three words you need

Checkpoint delta  Δθₕ — take the model weights at training step t and subtract the starting weights: Δθₕ = θₕ − θ₀. It is the total change so far, computed per weight tensor (each attention/MLP matrix separately). We saved 160 such checkpoints and work with one tensor at a time.

Rank-1  =  “one direction” — stack a tensor’s deltas from many checkpoints as the rows of a matrix and run an SVD. If a single component explains almost all of it, the deltas are just (one shared unit direction v₁) × (a per-checkpoint number cₕ). So “the update is rank-1” literally means “there is basically ONE direction the weights move along; each checkpoint only differs in how far along it they’ve gone.” Yes — rank-1 ≡ a direction.

The projection — if that holds, predicting a future checkpoint is trivial: θ̂ᴛ = θ₀ + cᴛ·v₁, i.e. keep the direction, extend the number. That is RELEX.

What "rank-1" means: every checkpoint's weight change is (one fixed direction) × (a growing number) 1) per checkpoint, the delta Δθₕ = θₕ − θ₀ θ₀ (base) Δθ₂₅ Δθ₅₀ Δθ₇₅ all point ~the same way, just longer stack + SVD 2) SVD splits them into ONE direction v₁ ... v₁ = the shared direction (unit vector) 3) ... × a coefficient cₕ that grows linearly in t step t cₕ R² ≈ 0.98 ∴ θ̂ᴛ = θ₀ + cᴛ·v₁ — predict any future checkpoint by scaling ONE arrow
Schematic (idea, not measured): the deltas fan only slightly, so one arrow v₁ plus a growing length cₕ describes them all.

1 · Are the updates really rank-1?  (yes — overwhelmingly)

C2 · rank-1 energy share EVR₁ (median 0.9219)→ higher = more rank-1 (1 = pure line)0.900.920.940.960.981.00λ₁/trace(G) per matrix (paper: ~0.81 of a rank-5 window)
F · Linearity of the rank-1 coefficient, by module (W=8)→ higher = more linear0.960.981paper bar 0.98qkvogateupdownnormbiascoef R² (median)
EVR₁ is 0.9987–0.9990 (≈flat) across ALL modules AND depths 0/7/13/20/27 — every tensor is rank-1

Reading it: C2 (left) — for each tensor we take the fraction of its update “energy” captured by the single top direction (EVR₁ = λ₁/Σλ). Median 99.3%: one direction explains essentially the whole change — even more rank-1 than the paper’s ~81% (they measured a different quantity, a rank-5 window). F (right) shows this is uniform: every module type — attention q/k/v/o, MLP gate/up/down, norms, biases — is rank-1 to the same degree, and so is every depth we probed (layers 0/7/13/20/27). Higher = more one-directional; there is no special “non-rank-1” module.

2 · Does the distance along it grow linearly?  (yes — R² ≈ 0.98)

C1 · coef-linearity R² per matrix (median 0.842)→ higher = more linear (1 = perfect)0.400.520.640.760.881.00paper bar: 0.98R² of c(t)=at+b, prefix window, anchor 119

We project each delta onto v₁ to get the scalar cₕ, then fit a straight line c(t)=a·t+b. Median R² = 0.979 across tensors (per-module medians 0.986–0.994, plot F used the same fit). That means the “how far along” number really does grow at a steady rate — the paper’s central claim. We land just under their clean “R²>0.98” bar (49% of tensors clear it here; 37% at early anchors), and we report that honestly rather than rounding up.

Higher = more perfectly linear (1.0 = a flawless line). The red dashed line marks the paper’s 0.98 threshold.

3 · Is that direction stable, or does it drift?  (both: locally rock-solid, slowly rotating)

This is the key question: the paper says the direction barely changes — one shared v₁ for the whole run. We tested it directly by estimating v₁ from a sliding 16-checkpoint window and measuring the angle between v₁ taken at different points in training (|cos| = 1 means identical direction, 0 means fully rotated away).

H · How stable is the rank-1 DIRECTION v₁ over training (probe window W=16)→ higher = more stable (1 = same direction)0.50.60.70.80.91162636465666768696106116training tick where the window ends|cos| between v₁ estimates
consecutive: v₁ now vs v₁ 10 ticks earlier → 0.99 (≈7.6° per 10 ticks: LOCALLY very stable)vs first: v₁ now vs the earliest window → decays to 0.64 over 100 ticks (SLOW global rotation)

Reading it — two curves, two timescales:

So your intuition is right and refined: the direction is very stable step-to-step (as in the paper), but it is not perfectly frozen — it rotates slowly over the whole run. That single fact explains everything downstream: a short recent window sees an almost-fixed direction, while the full-run window (§5) tries to fit one line to a gently curved path and pays for it.

I · Direction drift by depth (v₁ vs first window)→ higher = more stable0.50.70.91162636465666768696106116training tick where window ends|cos| vs earliest v₁
layer 0layer 7layer 13layer 20layer 27deeper layers rotate a bit MORE (L27 → 0.59 vs L0 → 0.72)

Depth effect (plot I): the drift is mild everywhere but slightly larger in deeper layers — layer 27’s direction falls to |cos|≈0.59 vs the start, layer 0’s only to ≈0.72. Early/shallow structure settles into its final direction sooner; later layers keep re-aiming a bit longer. All curves are monotone and smooth — the rotation is a steady curve, not noise.

Sanity: v₁ unit-norm reconstructed from the Gram to max error 2e-15; probe is 11 windows spanning ticks 16–116.

4 · So how accurate is projecting the weights forward?

Now the practical test our comm-eff work cares about: given a stale checkpoint at an anchor, predict where the weights will be h ticks later. We score weight_proj_ratio = ‖prediction − truth‖ / ‖stale-anchor − truth‖: below 1 beats doing nothing, above 1 is worse than just keeping the stale weights.

A · Staleness skill by horizon — global pooled ratio, late anchors (79, 119), W = 8, log axes↓ lower = betterabove the line = HARMFUL (worse than doing nothing)below the line = GOOD (beats holding stale weights)0.50.711.5234125102040ratio = 1 (hold-stale / do nothing)horizon h (ticks ahead of anchor)weight_proj_ratio
hold_stale (=1)naive_last2two_point_window[8]rank1_traj[8] · RELEX formrank2_anchored[8]rank1_anchored[8]
weight_proj_ratio — ↓ LOWER = BETTER · 1.000 = break-even with doing nothing (hold-stale) · <1 beats it · >1 harmful
method [window]h=1 ↓h=2 ↓h=5 ↓h=10 ↓h=20 ↓h=40 ↓
hold_stale[-]1.0001.0001.0001.0001.0001.000
naive_last2[-]0.4630.5340.6860.8931.1931.599
two_point_window[8]0.6770.7090.7950.9331.1531.484
rank1_traj[8]3.9452.4191.5461.2521.1201.076
rank1_traj[prefix]21.71511.2695.2063.1562.1931.805
rank1_anchored[8]0.9910.9920.9930.9951.0051.026
rank1_anchored[16]0.9980.9980.9991.0021.0121.033
rank2_anchored[8]0.6990.7300.8170.9531.1721.506
rank2_traj[8]1.2450.9730.8990.9861.1841.511

Global pooled ratio, median over anchors 79/119. Cell tint: green < 0.98 = beats hold-stale · grey ≈ 1 = neutral · red > 1.05 = harmful. Lower is better in every cell.

What it says: the paper’s own form rank1_traj scores 3.9–22 at short h (way above 1 — clipped ↑) because it re-pays the accumulated drift of §3. Our anchor-pinned variant rank1_anchored is the only arm that is never harmful out to h=40 (0.98–1.06) — but it removes only ~1–2% of the error. Plain recent-step momentum (naive_last2) is the real short-horizon winner (0.43–0.46 at h=1) but turns harmful past h≈15.

E · Where the anchored residual lives↓ lower = better (0 = move fully predicted)00.250.50.7511251020401.0 = residual as large as the whole move (zero skill)horizon h (ticks ahead of anchor)residual component / ||true move||
radial: along the true move (≈0.97 ⇒ the line predicted ~none of it)tangential: sideways error added

Why so little skill (plot E): even anchored, the leftover error stays ≈97% “radial” — pointing straight along the true move — at every horizon. The fitted line’s next step is nearly orthogonal to where the weights actually go over the next ≤40 ticks. The direction is great at describing accumulated position (§1–3) but poor at predicting the next increment, which is dominated by a fast component the window-averaged line can’t see.

5 · The two knobs, and why training stage doesn’t rescue it

B1 · Ratio vs window size (late)↓ lower = betterabove the line = HARMFUL (worse than doing nothing)below the line = GOOD (beats holding stale weights)11.21.51.881632prefixratio = 1 (hold-stale / do nothing)checkpoints feeding the SVD (W)weight_proj_ratio
B2 · Off-v₁ share of accumulated Δθ at anchor↓ lower = smaller unavoidable residual00.10.20.30.481632prefixcheckpoints feeding the SVD (W)fraction of ||Δθ_anchor|| off the line
rank1_anchored h=10rank1_anchored h=40 (dashed)rank1_traj h=40B2: off-line residual share (v₁ rotates ⇒ grows with W)

Window size (how many checkpoints feed the SVD): B2 measures how much of the accumulated delta lies off the single fitted direction — 4.5% for a recent 8-checkpoint window, rising to 33% for the full-run window. That is §3’s slow rotation showing up as cost: the longer the window, the more curve you force onto one line, so bigger windows predict worse here (B1). Lower is better in both.

D · rank1_anchored[8] at four anchors↓ lower = betterabove the line = HARMFUL (worse than doing nothing)below the line = GOOD (beats holding stale weights)0.9511.051.1125102040ratio = 1 (hold-stale / do nothing)horizon h (ticks ahead of anchor)weight_proj_ratio
anchor 39anchor 59anchor 79anchor 119

Training stage: maybe the line only fails late, once training has converged? No — anchors at ticks 39/59 (early, weights still moving fast) give the same neutral profile as 79/119. If anything the full-run window is worse early because it averages over the fast-rotating warm-up. The rank-1 line is a checkpoint-scale object at every stage — good for “where are we,” not “where next.” Lower = better.

6 · What this means for the comm-eff design

Use the line for position, not velocity. A rank-1 “trajectory clock” state (v₁ + two scalars per tensor) is cheap and well-defined, and — confirmed here — the direction is stable enough step-to-step to maintain incrementally. It is excellent for long-range position / reconstruction / regularization. But short-horizon (≤40 optimizer-tick) staleness repair — the regime of our pipeline-parallel anchor design — should keep anchor + recent-delta (momentum) signals: naive_last2 0.43–0.46 at h=1, rank2_anchored 0.69 at h=1 (its 2nd component is the local dynamics, though harmful by h=20), with rank1_anchored as the never-harmful fallback (0.98–1.06 across all h ≤ 40, both training regimes).

Provenance & repro

python3 scripts/rank1_scorecard.py --self-test
python3 scripts/rank1_scorecard.py \
  --trace-root /workspace/trace/EXP-57 \
  --manifest runs/EXP-57/regimeA/weights/full_manifest.jsonl \
  --out runs/RANK1-ANALYSIS/scorecard --scope panel        # late anchors (79,119)
# + --anchors 39,59 --out .../scorecard-early              # early anchors
python3 scripts/rank1_direction.py                         # v1 direction-stability probe (§3)
python3 scripts/rank1_report.py                            # this page

Implementation: scripts/weight_proj/rank1_traj.py + scripts/rank1_scorecard.py (new lane; moat_scorecard.py and the online comm-eff path untouched). Canonical findings: runs/RANK1-ANALYSIS/verdict.md · independent verification: runs/RANK1-ANALYSIS/verify_verdict.md · papers: Paper A arXiv:2601.04537 (linear dynamics / weight extrapolation), Paper B arXiv:2605.21468 (RELEX). Trace: EXP-57 regimeA fp32, 160 ticks (2 optimizer ticks per GRPO step), 61-matrix panel = layers {0,7,13,20,27} + final norm.