family ministral
Llama's pre-norm block with grouped-query attention, each block attending either over every earlier position or over a sliding window, as config.layer_types says.
One block of the stack. Hover any part for its nnterp name; click to pin the card. The slider picks a block; this family's blocks differ by layer_types.
identity layers[i].input + self_attn.attention_output + mlp.mlp_output == layer_output
⚠︎ marks a value this checkpoint has only under some load: hover it for the condition.
What print(model) shows on mistralai/Ministral-8B-Instruct-2410: the native modules, standard names and every standard value with its layout.
MinistralForCausalLM(
(lm_head): Linear(in_features=4096, out_features=131072, bias=False)
(generator): Generator(
(streamer): Streamer()
)
(embed_tokens): Embedding(131072, 4096)
(layers): ModuleList(
(0-35): 36 x MinistralDecoderLayer(
(self_attn): MinistralAttention(
(q_proj): Linear(in_features=4096, out_features=4096, bias=False)
(k_proj): Linear(in_features=4096, out_features=1024, bias=False)
(v_proj): Linear(in_features=4096, out_features=1024, bias=False)
(o_proj): Linear(in_features=4096, out_features=4096, bias=False)
(attention_queries) -> Queries [batch num_heads seq qk_head_dim]: The queries entering attention
(attention_keys) -> Keys [batch num_kv_heads seq qk_head_dim]: The keys entering attention
(attention_values) -> Values [batch num_kv_heads seq head_dim]: The values entering attention
(attention_scores) -> Pattern [batch num_heads query key]: The attention scores entering the softmax, masked
(attention_premix) -> HeadOutputs [batch seq num_heads head_dim]: Every head's output side by side, as the output projection takes it
(attention_output) -> Residual [batch seq hidden_size]: What the attention adds to the residual stream
(attention_probabilities) -> Pattern [batch num_heads query key]: The attention pattern the values are mixed with
(attention_head_outputs) -> HeadOutputs [batch seq num_heads head_dim]: The per-head outputs before the output projection
)
(mlp): MinistralMLP(
(gate_proj): Linear(in_features=4096, out_features=12288, bias=False)
(up_proj): Linear(in_features=4096, out_features=12288, bias=False)
(down_proj): Linear(in_features=12288, out_features=4096, bias=False)
(act_fn): SiLUActivation()
(mlp_activation) -> Neurons [batch seq intermediate_size]: The activation function's output
(mlp_neurons) -> Neurons [batch seq intermediate_size]: What the down projection receives: act(gate)·up on a gated MLP, the activation itself otherwise
(mlp_output) -> Residual [batch seq hidden_size]: What the MLP adds to the residual stream
)
(input_layernorm): MinistralRMSNorm((4096,), eps=1e-05)
(post_attention_layernorm): MinistralRMSNorm((4096,), eps=1e-05)
(layer_input) -> Residual [batch seq hidden_size]: The residual stream entering the block
(attention_norm_output) -> Residual [batch seq hidden_size]: The normed stream entering the attention
(layer_mid) -> Residual [batch seq hidden_size]: The residual stream after the attention add
(mlp_norm_output) -> Residual [batch seq hidden_size]: The normed stream entering the MLP
(mlp_input) -> Residual [batch seq hidden_size]: What the MLP is called with
(layer_output) -> Residual [batch seq hidden_size]: The residual stream leaving the block, a tensor even when the block returns a tuple
)
)
(norm): MinistralRMSNorm((4096,), eps=1e-05)
(logits) -> Logits [batch seq vocab_size]: The logits the model returns, after anything it does past lm_head (a softcap, a scale)
(token_embeddings) -> Residual [batch seq hidden_size]: The embedding module's output; layers[0].input is what enters the first block
(final_norm_output) -> Residual [batch seq hidden_size]: The residual stream after the final norm, what lm_head reads
(lm_head_output) -> Logits [batch seq vocab_size]: The head's logits before anything the model does past lm_head (a softcap, a scale)
(next_token_probs) -> NextTokenProbs [batch vocab_size]: The next-token distribution at the last position; derived, read-only
(input_ids) -> Tokens [batch seq]: The token ids the model was called with
(attention_mask) -> Tokens [batch seq]: The attention mask the model was called with; zeros are padding
(input_size): [batch, seq] of the current call; read-only
)h = x + self_attn(input_layernorm(x))
out = h + mlp(post_attention_layernorm(h))
Llama's block: two RMSNorms per block, each before its sublayer, none after, and a SwiGLU MLP.
attention_output is the attention module's output and mlp_output the MLP's, added to the stream
with nothing in between, so the identity holds exactly (float32, pinned checkpoint):
with model.trace(prompt):
x = model.layers[1].input.save()
attn = model.layers[1].self_attn.attention_output.save()
mlp = model.layers[1].mlp.mlp_output.save()
out = model.layers[1].layer_output.save()
torch.testing.assert_close(x + attn + mlp, out)
config.layer_types gives each block full_attention or sliding_attention. On
Ministral-8B-Instruct-2410 block 0 and every fourth after it (0, 4, ..., 32) are full, the other 27
sliding; the window is config.sliding_window, 32768 tokens, which is also the config's
max_position_embeddings. A sliding block's query attends to its own position and the 32767 before
it, so up to that length the sliding mask is the causal mask and the two kinds of block compute the
same function. The window is in the mask the attention receives, so under
attn_implementation="eager" attention_probabilities is exactly zero beyond it (checked on the
pinned checkpoint loaded with sliding_window=3: every entry three or more positions back is
0.0). Each block's own window is on its module:
[layer.self_attn._module.sliding_window for layer in model.layers][:5]
# [None, 32768, 32768, 32768, None] on 8B-Instruct-2410
32 query heads over 8 key/value heads of width 128, 4096 wide together, the stream's width.
attention_keys and attention_values are read before repeat_kv, [batch, 8, seq, 128], and
query head h reads key/value head h // 4: an edit to key/value head j reaches query heads
4j to 4j + 3.
The tokenizer is the 131072-token Tekken vocabulary: " Paris" is ĠParis (6993) and "Paris"
is Paris (42572), two different tokens. Pick the one the prompt's spacing produces:
ids = model.tokenizer(" Paris", add_special_tokens=False).input_ids
assert len(ids) == 1
mistralai/Ministral-8B-Instruct-2410's config.json says model_type mistral and
MistralForCausalLM, with layer_types; transformers' AutoConfig reads a mistral config that
has layer_types as a ministral config, so it loads as MinistralForCausalLM and this family
serves it.
Ministral (MinistralForCausalLM).
Llama's tree and Llama's block: model.{embed_tokens, layers[i].{input_layernorm, self_attn, post_attention_layernorm, mlp}, norm} and lm_head, the residual
added in the block, attention through the shared eager forward.
Every block may take a sliding window (layer_types); the window is a mask
given to the interface, so the values are read as it applies.