GraniteMoeHybridForCausalLM
GraniteMoeHybridForCausalLM at 40 layers and hidden size 2048. 2 published checkpoints share this shape.
Layer map
One character per layer, input on the left.
mmmmmAmmmmmmmmmAmmmmmmmmmAmmmmmmmmmAmmmm
| layer kind | count | |
|---|---|---|
| m | state space | 36 |
| A | attention | 4 |
Implementing it
One forward, written out, per checkpoint whose arithmetic actually differs. A shape groups checkpoints by class, depth, width and layer stack — none of which decides an activation, a rope base or a routing rule — so where the members of this shape disagree there is a block each, and each names the checkpoint it was generated from.
No forward was recorded for this shape, so there is no pass above to compare it against — this block is what the published configuration says the arithmetic is, not a transcript of a run. Where the configuration does not say, the line says that instead of guessing.
The names are the ones the published checkpoint uses where a name is published, and canonical otherwise. A checkpoint loader may store them differently — fusing a gate/up pair into one matrix, or splitting one published projection in two — and those are that loader's names, not the model's. Everything spelled here is what the download contains.
Generated from granite-4.0-h-micro, which covers all 2 checkpoints of this shape — they agree on every field below.
x = embed[ids] * 12 # [T, 2048] <- embedding_multiplier
for i in 0 .. 39:
# layer_types[i] decides the mixer; both share the block shape
h = rmsnorm(x, layers[i].input_layernorm, eps=1e-05)
if layer_types[i] == "mamba":
zxbcdt = h @ layers[i].mamba.in_proj.T
z, xBC, dt = split(zxbcdt, [4096, 4352, 64])
xBC = silu(causal_conv1d(xBC, layers[i].mamba.conv1d, width=4, bias=layers[i].mamba.conv1d.bias))
u, B, C = split(xBC, [4096, 128, 128])
dt = softplus(dt + layers[i].mamba.dt_bias)
A = -exp(layers[i].mamba.A_log)
S = dA * S + dt * outer(u, B) # dA = exp(dt * A), in (0,1]
y = S @ C + D * u # per token, in order
# ^ ssd_scan, written out: one state [64 x 128] per head,
# a scalar decay per head, and one B/C pair shared across
# every head in a group the way GQA shares a KV head.
y = group_rmsnorm(y * silu(z), layers[i].mamba.norm,
groups=1, width=4096, eps=1e-5)
# ^ gate first. Normalising before the gate is a different
# function and reads exactly as fluent.
# (`mamba_chunk_size: 256` is published and is not used
# above: the recurrence is sequential. The chunked kernel
# is a throughput variant with its own rounding.)
y = y @ layers[i].mamba.out_proj.T
else:
q = h @ layers[i].self_attn.q_proj.T # [T, 32*64]
k = h @ layers[i].self_attn.k_proj.T # [T, 8*64]
v = h @ layers[i].self_attn.v_proj.T # [T, 8*64]
# No position signal: position_embedding_type is "nope".
# Not rotary_dim == 0 — a flag, and the only thing that says so.
k, v = repeat_kv(k, v, 4) # 32 query heads share 8 key/value heads
a = softmax(q @ k.T * 0.015625, mask=causal) @ v # <- attention_multiplier
a = a @ layers[i].self_attn.o_proj.T
x = x + (y if layer_types[i] == "mamba" else a) * 0.22
h = rmsnorm(x, layers[i].post_attention_layernorm)
g, u = split(h @ shared_mlp.input_linear.T, 2) # width 8192
y = (silu(g) * u) @ shared_mlp.output_linear.T
# `num_local_experts: 0` — the expert names are the template's,
# there is no router here and nothing is routed.
x = x + y * 0.22
x = rmsnorm(x, model.norm)
logits = (x @ embed.T) / 8 # tied to the input embedding; <- logits_scaling
head_dim is not published; 2048 / 32 = 64 is used.
The Granite multipliers are the part with no Llama analogue: embedding_multiplier, attention_multiplier, residual_multiplier, logits_scaling. They are ordinary floats and a port that ignores them still produces fluent text, which is what makes them worth printing where they act.
position_embedding_type: "nope" — the attention layers rotate nothing. It is a flag and not a rotary width of zero, and it is the only thing in the configuration that says so. Position is carried by the state-space layers instead, which is why the handful of attention layers can do without it.
num_local_experts: 0 on a class whose tensors are named for a mixture of experts. The MLP is the shared expert alone; nothing is routed.
Geometry
| layers | 40 |
| hidden size | 2,048 |
| attention heads | 32, 8 key/value |
| feed-forward width | 8,192 |
| vocabulary | 100,352 |
| trained context | 131,072 tokens |
| largest checkpoint | 3.2B |
Other shapes of GraniteMoeHybridForCausalLM
Only the columns that differ are shown; a cell with several values means the checkpoints of that shape disagree.
| shape | layers | width | stack | heads | KV heads | FFN width | experts | active | vocabulary | context | checkpoints |
|---|---|---|---|---|---|---|---|---|---|---|---|
40L x 4,096 | 40 | 4,096 | 36 state space + 4 attention | 32 | 8 | 768 | 72 | 10 | 100,352 | 131,072 | 2 |
40L x 2,560 | 40 | 2,560 | attention | 40 | 8 | 8,192 | — | — | 100,352 | 131,072 | 3 |
40L x 2,048 | 40 | 2,048 | attention | 16 | 4 | 4,096 | — | — | 100,352 | 131,072 | 2 |
40L x 2,048 (this sheet) | 40 | 2,048 | 36 state space + 4 attention | 32 | 8 | 8,192 | — | — | 100,352 | 131,072 | 2 |
40L x 1,536 | 40 | 1,536 | 36 state space + 4 attention | 12 | 4 | 512 / 4,096 | — / 62 / 64 | — / 6 | 49,160 / 50,304 / 100,352 | 131,072 | 6 |
32L x 768 | 32 | 768 | 28 state space + 4 attention | 12 | 4 | 2,048 | — | — | 100,352 | 32,768 | 2 |
28L x 1,024 | 28 | 1,024 | attention | 16 | 4 | 2,048 | — | — | 100,352 | 32,768 | 2 |
How this was checked
implemented, evidence grade class, per the assessment, for each checkpoint of this shape: the architecture class is implemented; nothing specific to this checkpoint was measured. The implementation meant here and below is an unpublished independent inference implementation by the author.
What stands behind the block above, beyond the published configuration it is read from:
- a decoder implemented from the published configuration
- a state-space mixer implemented from the published configuration
- a checkpoint loader, which is where published tensor names are read
- an independent reference implementation of this architecture in Python, driving the published modelling code — an executable statement of what the model should compute, written against the publication rather than against any one implementation of it
Where an independent implementation and the published configuration disagree, the configuration is what this page reports and the disagreement is what it says.
Checkpoints with this architecture
| model | parameters | context |
|---|---|---|
granite-4.0-h-micro | 3.2B | 131,072 |
granite-4.0-h-micro-base | 3.2B | 131,072 |