Experiment #2 by semantic owner: the rotary schedule, and two declarations nothing reads - #375
Merged
Conversation
…he opposite of its name
SmolLM3 and Llama 4 both declare which layers encode position with
no_rope_layers [1,1,1,0, 1,1,1,0, ...]
no_rope_layer_interval 4
and the key is named for what it disables while its values say the
opposite. SmolLM3's config documents it as *"A `1` at an index position
indicates that the corresponding layer will use RoPE, while a `0`
indicates that it's a NoPE layer"*, and both references read it as
`self.use_rope = config.no_rope_layers[layer_idx]`.
So a reader who trusts the name inverts the whole schedule. On SmolLM3-3B
that is 27 of 36 layers rotated that must not be and 9 left unrotated that
must be — and the model still emits fluent text, because NoPE layers are
a minority and attention degrades gracefully rather than failing. The
polarity is honoured exactly once, in `PositionPolicy::rope_enabled_by_flag`,
beside the `layer_rope_theta` zero sentinel it is the sibling of.
The census recorded this as an "alias spelling" of the existing per-layer
NoPE capability. It is not: `ALIAS_KEYS` requires the canonical spelling
present in the SAME config and read there, and SmolLM3 declares no
`layer_rope_theta` at all. The capability is shared; the spelling had no
reader.
**Placed in the trait default, not a family override** — the opposite of
the `position_embedding_type` fix in the previous commit, and by the
criterion `rotary_policy` already states: two unrelated families
(`smollm3`, `llama4`) declare this key with identical semantics, so it is
a config fact rather than a family fact. SmolLM3 resolves to `GenericArch`
and needs no impl of its own.
The schedule is asked BEFORE the rotary shape and composes with it: a
scheduled layer still picks up YaRN, a partial rotary, or a per-layer
theta. Answering the schedule by returning a bare `Rope { theta: default }`
would have silently re-based every rotating layer.
`no_rope_layer_interval` is a FALLBACK GENERATOR, not a redundant
spelling: both references consult it only `if no_rope_layers is None`, so
an explicit mask supersedes it rather than being reconciled with it.
Carried at `Parsed` for that reason — on a checkpoint declaring both it
contributes nothing to the graph, the same way `max_window_layers` is
inert while the window is disabled.
Two malformed cases decline to answer rather than guessing, both in the
direction that preserves existing behaviour: a mask shorter than the stack
says nothing about the layers past its end, and an interval of zero is not
a schedule (upstream divides by it and raises), so it leaves layers
unscheduled instead of turning a bad declaration into a silently NoPE
model.
Calibrated: inverting `rope_enabled_by_flag` fails 5 of the 7 gates,
including the real 36-layer SmolLM3 schedule. The two that survive are
the ones that declare no schedule at all, which is correct.
Census, from cached headers:
HuggingFaceTB/SmolLM3-3B 3 -> 1 blocking (residual: pretraining_tp)
everything else unchanged
`probe_no_rope_layers` and `probe_position_embedding_type` were declared and unexercised, which took carriage.rs to 89.04% against the 90% per-file floor — and, more to the point, left the claim that these rules are CHECKABLE resting on nothing. Each gets the paired arms this file requires: a declaration the graph carries, and a second declaration that changes the carried answer. The second is what makes the first non-vacuous — a probe that echoed its input would pass the positive arm alone. The null arm is the one worth having. A stack whose schedule rotates nowhere answers `null` for `position_embedding_type`, and a checkpoint declaring `rope` over it must stop reading as satisfied. That is exactly the granitemoehybrid case the rule was added for, reproduced on a fixture.
…ed and use_mrope
Both are VESTIGIAL, and that is a distinct gap kind from the
declared-disabled one `use_sliding_window` established. `use_mrope`
appears nowhere in transformers 5.5.0; `rope_interleaved` (exact
spelling) appears nowhere either — SmolLM2-135M declares it under
`model_type: llama`, which has no such field. So unlike
`use_sliding_window`, which HF genuinely consults, there is no upstream
behaviour to agree with. Only this build's.
That makes reading them MORE important, not less. Neither names a
cosmetic fact:
rope_interleaved which dimensions rotate against which partner
use_mrope whether position is one axis or three
and an unread declaration that happens to agree is one value away from a
silent wrong answer. An interleaved rotation produces plausible numbers
of the same magnitude against different partners; nothing downstream
looks wrong.
Each is checked against the EFFECTIVE policy, never against itself:
- `rope_interleaved` against `ROPE_PAIRING_INTERLEAVED`, a new constant
naming this build's one pairing — split-half, `(x[i], x[i + half])`.
- `use_mrope` against whether `mrope_section` + `mrope_interleaved`
actually resolved a `PositionPolicy::MRope`. A probe echoing the flag
back would agree with a checkpoint claiming multi-axis while carrying
no axis geometry to build one from.
`the_executor_pairs_split_half` keeps the constant honest, and does it in
BOTH directions: the expected partner is derived from the constant, so
flipping the constant flips what the test demands and it then fails
against an unchanged executor. Calibrated by making the executor
interleaved for real — the gate goes red, and the constant alone would
not have noticed.
The parser reads these and stops there. Reading a flag must not become
acting on it: this build has one pairing and the planner reports the
disagreement, where a parser that quietly switched operators would turn
a reportable mismatch into exactly the wrong answer the report exists to
prevent.
Census, from cached headers:
HuggingFaceTB/SmolLM2-135M 3 -> 2 blocking
Qwen/Qwen2.5-0.5B 2 -> 1 blocking
Both residuals are pre-existing and outside this cluster: SmolLM2 keeps
`is_llama_config` and `pretraining_tp`; Qwen2.5 keeps the honest
`sliding_window` mismatch C recorded — declared 32768, carried null,
because the graph records the effect and not the reason.
…e census stops counting mysteries
GLM-5.3-Flash was the census's designated falsifier: the cluster where
"this is genuinely new execution work" had to be sayable, because a
taxonomy that scored a learned sparse-attention indexer as another
normalisation gap would be broken rather than impressive.
It could not say it. Every one of those keys graded `unknown`, which
means "nobody has looked" — right as a finding, useless as an estimate.
A report made mostly of `unknown` tells you how much was unexamined, not
how much is left to build.
`SemanticClass::UnsupportedComponent` says the other thing: somebody
looked, and there is a model component behind the key that this build
does not implement. Blocking exactly as before — the class changes what
the report SAYS, never how much it permits, and
`a_key_configuring_an_absent_component_grades_unsupported_and_blocks`
asserts both halves. GLM still blocks 32.
before 24 unknown
after 12 keys -> 2 named components, 13 unknown
**Entries are earned by evidence, not adjacency.** The indexer is grouped
on a geometry separate from the model's own (`index_n_heads: 32`,
`index_head_dim: 128`, against the text stack's `qk_head_dim: 256`), a
selection count rather than a width (`index_topk: 2048`), one coherent
pooling mechanism, and an `indexer_types` array of exactly 45 entries
against `num_hidden_layers: 45` — a per-layer schedule for this component
the way `layer_types` is for attention. Hyper-connections are grouped on
the `hc_` prefix plus `hc_sinkhorn_iters`, which names an algorithm
rather than a generic knob.
`mhc: true` sits directly beside the `hc_*` trio and is very likely part
of the same component. It is NOT listed, and
`a_neighbouring_key_with_no_evidence_stays_unknown` pins that. A bare
boolean whose expansion cannot be checked is exactly what this table must
not swallow, or it becomes the convenient bucket that makes every
estimate look tidier than the evidence supports.
**Nothing here is implemented, deliberately.** There is no reference to
implement against: `glm5_next` is absent from transformers 5.5.0 and the
repo ships no remote modeling code (72 files, zero `.py`) — checked, not
assumed. Every other fix in this cluster leaned on reading the upstream
loader, and that instrument does not exist for this family. So the
component is named and refused, which is the difference between an
engineering estimate and a compatibility claim.
Closes the miscluster the experiment started from:
`indexer_rope_interleave` is the INDEXER's rotary pairing, swept into the
general RoPE cluster by a regex over `rope`. Acting on it there would
have applied an interleaved pairing to the whole model — wrong component
and wrong operator — and the checkpoint declares `true`, so the mistake
would have been live rather than latent.
Review wording, adopted verbatim: the class means a model component has
been POSITIVELY IDENTIFIED from the checkpoint semantics and this build
has no implementation for it. Stated against its neighbours, because the
engineering implication is what differs — not a parser chore, not a
spelling alias, not a checked default, not an inactive declaration.
There is machinery missing.
The registration rule is now written where someone adding an entry will
read it, rather than living in a review thread:
positive evidence of component ownership, never plausible adjacency
with the shortcuts that would make the table cheap to extend ruled out by
name — no prefix-only registration, no regex rule ever, and an adjacent
key stays `unknown`. A pattern is how these keys were FOUND; it may not
be the authority. That distinction is not abstract: a regex over `rope`
is what filed `indexer_rope_interleave` under general RoPE, where acting
on it would have re-paired the whole model's rotary.
The cost of relaxing the rule is not a wrong label. It is an engineering
estimate that reads tidier than the evidence supports, which is worse
than no estimate at all.
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.
Fixes 2, 3 and 4 of census experiment #2, by semantic owner. Three commits, three different treatments — and in every case the recorded classification was wrong.
1.
no_rope_layers— the key means the opposite of its nameSmolLM3 and Llama 4 both declare which layers encode position with
no_rope_layersplus ano_rope_layer_intervalfallback. SmolLM3's config documents it as:and both references read it as
self.use_rope = config.no_rope_layers[layer_idx].A reader who trusts the name inverts the entire schedule. On SmolLM3-3B that is 27 of 36 layers rotated that must not be, and 9 left unrotated that must be — and the model still emits fluent text, because NoPE layers are a minority and attention degrades gracefully. Nothing but a test pinned against the reference catches it.
Honoured exactly once, in
PositionPolicy::rope_enabled_by_flag, beside thelayer_rope_thetazero sentinel it is the sibling of.Not an alias, as recorded:
ALIAS_KEYSrequires the canonical spelling present in the same config, and SmolLM3 declares nolayer_rope_thetaat all. The capability was shared; the spelling had no reader.Placed in the trait default, by the criterion
rotary_policy's doc already states — two unrelated families declare it with identical semantics, so it is a config fact rather than a family fact. The schedule is asked before the rotary shape and composes with it, so a scheduled layer still picks up YaRN, a partial rotary, or a per-layer theta.no_rope_layer_intervalis a fallback generator, not a restatement: both references consult it onlyif no_rope_layers is None. Carried atParsed, because on a checkpoint declaring both it contributes nothing to the graph.Two malformed cases decline to answer, both in the direction that preserves existing behaviour: a short mask says nothing about the layers past its end, and an interval of zero is not a schedule. Clippy's
manual_is_multiple_ofis what surfaced that my first zero-guard fell the wrong way — it would have turned a malformed declaration into a silently NoPE model.Calibrated: inverting the flag fails 5 of 7 gates including the real 36-layer schedule. The two survivors declare no schedule at all — the control.
2.
rope_interleavedanduse_mrope— vestigial, and read anywayA gap kind distinct from the declared-disabled one.
use_mropeappears nowhere in transformers 5.5.0;rope_interleaved(exact spelling) appears nowhere either — SmolLM2-135M declares it undermodel_type: llama, which has no such field. Unlikeuse_sliding_window, which HF genuinely consults, there is no upstream behaviour to agree with.That makes reading them more important, not less. Neither names a cosmetic fact:
Each is checked against the effective policy, never against itself:
rope_interleavedagainstROPE_PAIRING_INTERLEAVED, a new constant naming this build's one pairing — split-half,(x[i], x[i + half]).use_mropeagainst whethermrope_section+mrope_interleavedactually resolved anMRopepolicy. A probe echoing the flag back would agree with a checkpoint claiming multi-axis while carrying no geometry to build one from.the_executor_pairs_split_halfkeeps the constant honest in both directions: the expected partner is derived from the constant, so flipping it flips what the test demands and it then fails against an unchanged executor. Calibrated by making the executor interleaved for real — the gate goes red.The parser reads these and stops. Reading a flag must not become acting on it: this build has one pairing and the planner reports the disagreement, where a parser that quietly switched operators would turn a reportable mismatch into the silent wrong answer the report exists to prevent.
3. Probe coverage
Both new carriage probes from the previous PR were declared and unexercised, which took
carriage.rsunder the 90% floor — and left the claim that these rules are checkable resting on nothing. Each now gets paired arms. The null arm is the one worth having: a stack that rotates nowhere answersnullforposition_embedding_type, and a checkpoint declaringropeover it must stop reading as satisfied — the granitemoehybrid case, reproduced on a fixture.Census
All three residuals are pre-existing and outside this cluster:
pretraining_tpandis_llama_configare training/identity facts, and Qwen2.5 keeps the honestsliding_windowmismatch — declared 32768, carried null, because the graph records the effect and not the reason.Gates
fmt --all --check·check --workspace --all-targets(four newModelConfigfields) · clippy with each touched crate's own CI flags, includinglarql-computewith and without--all-features· full suites for larql-models, larql-compute, larql-vindex, larql-server · coverage policy for all three gated crates, re-measured afterllvm-cov clean.