P3: SnAp-n — generalise recurrence_scope to an n-step neighbourhood - #143
Merged
Conversation
Adds `recurrence_scope='sparse_n'` and the `braintrace.SnAp` preset (Menick et al., 2021). The n-step influence sparsity pattern is *derived* from the compiler's jaxpr rather than declared: `_compiler/position_graph.py` reads the hidden group's transition, extracts the one-step position adjacency from the recurrent mixing primitive, closes it n-1 times, and hands back the retained neighbourhood. The trace's trailing `num_state` axis S widens to a `(neighbour, state)` axis of width M = K*S; no per-primitive kernel changed. Both ends of the scale were already in the codebase: n=1 canonicalises to `recurrence_scope='coupled'` (OSTLRecurrent's rule), and n at or above a group's position-graph diameter saturates to full within-group RTRL. `diagonal` sits below the scale rather than on it — it deletes the mixing primitive before differentiating, which is not any n. Measured on `sparse_ring_rnn(n_rec=6)` (diameter 5), chunk 3, T=8, ETP parameter only: rel. deviation from BPTT falls 2.32e-01 (n=1) -> 4.96e-03 -> 5.93e-04 -> 2.22e-04 -> 8.03e-08 (n=5, saturated), with trace memory exactly linear in K and saturating with it. - `snap_anchor` is a declared per-primitive capability, default-deny: a trace slot must have one well-defined hidden position its instantaneous term lands on. Nine primitives declare it; `etp_emb` and shared-axis `etp_einsum` are rejected with a message naming the legal scopes. - Primitives whose adjacency cannot be read (unregistered, more than one mixing equation, control flow, non-position-preserving tail) widen to all-to-all and emit `SNAP_PATTERN_CONSERVATIVE`; `K == 1` emits `SNAP_PATTERN_DEGENERATE` rather than silently computing `coupled` under a `sparse_n` label. - The widened block Jacobian is budgeted at P*(K*S)**2 elements, overridable via `snap_max_jacobian_elements`. 122 new tests. Acceptance is a two-sided squeeze (n=1 == OSTLRecurrent, saturation == BPTT) plus an independent masked-RTRL reference for the interior orders, all eleven anchored primitives executed at a saturating order on both solve paths, and a directed fixture pinning that the neighbourhood runs downstream of its anchor. Also documents F-31: on a group whose y -> hidden tail relabels positions, no within-group scope reaches BPTT — saturated SnAp included. Pre-existing and structural, detected and warned about rather than silent; the conservative diagnostic's wording was corrected accordingly.
There was a problem hiding this comment.
Sorry @chaoming0625, your pull request is larger than the review limit of 150000 diff characters
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
recurrence_scope='sparse_n'and thebraintrace.SnAppreset — SnAp-n(Menick et al., 2021), the interpolation between the cheap and the exact end of
the recurrence-scope axis.
The point of doing this in a compiler rather than a library: the n-step
influence sparsity pattern is derived, not declared.
position_graph.pyreads the hidden group's transition jaxpr, extracts the one-step position
adjacency from the recurrent mixing primitive, closes it
n-1times, and handsback the retained neighbourhood. The trace's trailing
num_stateaxisSwidens to a
(neighbour, state)axis of widthM = K·S, and not one of thenine ETP primitive rules needed changing.
Both ends of the scale turned out to be in the codebase already:
n=1canonicalises to
recurrence_scope='coupled'(OSTLRecurrent's rule), and anynat or above a group's position-graph diameter saturates to full within-groupRTRL.
diagonalsits below the scale rather than on it.Measured
sparse_ring_rnn(n_rec=6)(diameter 5),chunk_size=3,T=8, against the BPTToracle on the ETP parameter:
Memory exactly linear in
Kand saturating with it; accuracy monotone, reachinground-off at
n = diameter.Safety properties
snap_anchoris declared per primitive and defaults to deny. A trace slotmust have one well-defined hidden position its instantaneous term lands on.
Nine primitives declare it;
etp_emband shared-axisetp_einsumarerejected with a message naming the legal scopes.
primitive, more than one mixing equation, control flow, or a
non-position-preserving tail all fall back to all-to-all with
SNAP_PATTERN_CONSERVATIVE.K == 1emitsSNAP_PATTERN_DEGENERATEratherthan quietly computing
coupledunder asparse_nlabel.paths and wraps, which would under-approximate the neighbourhood — the one
error direction a conservative analysis may never have.
P·(K·S)²elements, withsnap_max_jacobian_elementsto raise it deliberately.Tests
122 new tests; full suite 2388 passed,
mypy braintraceclean.Acceptance is a two-sided squeeze —
n=1equalsOSTLRecurrentelement-wiseand saturation equals BPTT, both through the finite-window oracle since the
full-window path is blind to every axis (F-23) — plus:
(
n = 2,3,4match to<1e-6; a deliberately narrower reference misses by1.2e-1), because the endpoints are no evidence about the middle;fast and legacy solve paths;
of its anchor — the orientation no size-based assertion can see.
Also
Documents F-31 in the known-limitations list: on a hidden group whose
y → hiddentail relabels positions, no within-group scope reaches BPTT,saturated SnAp included, and the saturated rule is further from BPTT than the
cheaper ones (1.30 vs 1.03, against 1.3e-07 for the same model with the
relabelling removed). Pre-existing and structural — it hits
diagonalandcoupledidentically — detected and warned about rather than silent. Theconservative diagnostic previously read "the gradient stays correct", which is
true of the pattern but over-claims about the returned gradient; it now says the
approximation is not degraded and points at F-31.
Roadmap lessons 18–30 record what generalises, including the five findings an
adversarial review of the finished implementation turned up.
🤖 Generated with Claude Code