family doge
Llama's pre-norm block whose residual stream is multiplied by a learned per-channel gate before each add, and whose attention adds a learned bias per key, computed from the values, to the scores.
One block of the stack. Hover any part for its nnterp name; click to pin the card.
One block of the stack. Hover any part for its nnterp name; click to pin the card.
One block of the stack. Hover any part for its nnterp name; click to pin the card.
identity post_attention_residual * (input_residual * 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.
⚠︎ marks a value this checkpoint has only under some load: hover it for the condition.
What print(model) shows on SmallDoge/Doge-20M: the native modules, standard names and every standard value with its layout.
DogeForCausalLM(
(lm_head): Linear(in_features=256, out_features=32768, bias=False)
(generator): Generator(
(streamer): Streamer()
)
(embed_tokens): Embedding(32768, 256)
(layers): ModuleList(
(0-7): 8 x DogeDecoderLayer(
(input_layernorm): DogeRMSNorm((256,), eps=1e-06)
(self_attn): DogeAttention(
(q_proj): Linear(in_features=256, out_features=256, bias=False)
(k_proj): Linear(in_features=256, out_features=128, bias=False)
(v_proj): Linear(in_features=256, out_features=128, bias=False)
(dt_proj): Linear(in_features=128, out_features=1, bias=False)
(o_proj): Linear(in_features=256, out_features=256, bias=False)
(q_norm): DogeRMSNorm((128,), eps=1e-06)
(k_norm): DogeRMSNorm((128,), eps=1e-06)
(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
)
(post_attention_layernorm): DogeRMSNorm((256,), eps=1e-06)
(mlp): DogeMLP(
(gate_proj): Linear(in_features=256, out_features=512, bias=False)
(up_proj): Linear(in_features=256, out_features=512, bias=False)
(down_proj): Linear(in_features=512, out_features=256, 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
)
(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): DogeRMSNorm((256,), eps=1e-06)
(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
)What print(model) shows on SmallDoge/Doge-40M: the native modules, standard names and every standard value with its layout.
DogeForCausalLM(
(lm_head): Linear(in_features=256, out_features=128256, bias=False)
(generator): Generator(
(streamer): Streamer()
)
(embed_tokens): Embedding(128256, 256, padding_idx=128001)
(layers): ModuleList(
(0-7): 8 x DogeDecoderLayer(
(input_layernorm): DogeRMSNorm((256,), eps=1e-06)
(self_attn): DogeAttention(
(q_proj): Linear(in_features=256, out_features=256, bias=False)
(k_proj): Linear(in_features=256, out_features=128, bias=False)
(v_proj): Linear(in_features=256, out_features=128, bias=False)
(dt_proj): Linear(in_features=128, out_features=1, bias=False)
(o_proj): Linear(in_features=256, out_features=256, bias=False)
(q_norm): DogeRMSNorm((128,), eps=1e-06)
(k_norm): DogeRMSNorm((128,), eps=1e-06)
(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
)
(post_attention_layernorm): DogeRMSNorm((256,), eps=1e-06)
(mlp): DogeMLP(
(gate_proj): Linear(in_features=256, out_features=1024, bias=False)
(up_proj): Linear(in_features=256, out_features=1024, bias=False)
(down_proj): Linear(in_features=1024, out_features=256, 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
)
(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): DogeRMSNorm((256,), eps=1e-06)
(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
)What print(model) shows on SmallDoge/Doge-260M: the native modules, standard names and every standard value with its layout.
DogeForCausalLM(
(lm_head): Linear(in_features=768, out_features=128256, bias=False)
(generator): Generator(
(streamer): Streamer()
)
(embed_tokens): Embedding(128256, 768, padding_idx=128001)
(layers): ModuleList(
(0-23): 24 x DogeDecoderLayer(
(input_layernorm): DogeRMSNorm((768,), eps=1e-06)
(self_attn): DogeAttention(
(q_proj): Linear(in_features=768, out_features=768, bias=False)
(k_proj): Linear(in_features=768, out_features=384, bias=False)
(v_proj): Linear(in_features=768, out_features=384, bias=False)
(dt_proj): Linear(in_features=384, out_features=3, bias=False)
(o_proj): Linear(in_features=768, out_features=768, bias=False)
(q_norm): DogeRMSNorm((128,), eps=1e-06)
(k_norm): DogeRMSNorm((128,), eps=1e-06)
(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
)
(post_attention_layernorm): DogeRMSNorm((768,), eps=1e-06)
(mlp): DogeMLP(
(gate_proj): Linear(in_features=768, out_features=2304, bias=False)
(up_proj): Linear(in_features=768, out_features=2304, bias=False)
(down_proj): Linear(in_features=2304, out_features=768, 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
)
(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): DogeRMSNorm((768,), eps=1e-06)
(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
)What print(model) shows on SmallDoge/Doge-40M-MoE: the native modules, standard names and every standard value with its layout.
DogeForCausalLM(
(lm_head): Linear(in_features=256, out_features=128256, bias=False)
(generator): Generator(
(streamer): Streamer()
)
(embed_tokens): Embedding(128256, 256, padding_idx=128001)
(layers): ModuleList(
(0-7): 8 x DogeDecoderLayer(
(input_layernorm): DogeRMSNorm((256,), eps=1e-06)
(self_attn): DogeAttention(
(q_proj): Linear(in_features=256, out_features=256, bias=False)
(k_proj): Linear(in_features=256, out_features=128, bias=False)
(v_proj): Linear(in_features=256, out_features=128, bias=False)
(dt_proj): Linear(in_features=128, out_features=1, bias=False)
(o_proj): Linear(in_features=256, out_features=256, bias=False)
(q_norm): DogeRMSNorm((128,), eps=1e-06)
(k_norm): DogeRMSNorm((128,), eps=1e-06)
(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
)
(post_attention_layernorm): DogeRMSNorm((256,), eps=1e-06)
(mlp): DogeCDMoE(
(act_fn): SiLUActivation()
(gate_proj): Linear(in_features=256, out_features=1024, bias=False)
(up_proj): Linear(in_features=256, out_features=1024, bias=False)
(down_proj): Linear(in_features=1024, out_features=256, bias=False)
(router_gate): Linear(in_features=256, out_features=64, bias=False)
(down_embed): Embedding(1024, 256)
(up_embed): Embedding(1024, 256)
(mlp_activation): Unavailable: routed experts; read per-expert via the Moe component
(mlp_neurons) -> Neurons [batch seq intermediate_size]: What the down projection receives: act(gate)·up on a gated MLP, the activation itself otherwise
(router_logits) -> RouterLogits [batch seq num_experts]: The router's logits, one per expert, before the scoring
(expert_weights) -> ExpertWeights [batch seq top_k]: The weight each selected expert's output is scaled by
(expert_indices) -> ExpertIndices [batch seq top_k]: The expert each routing slot sends the token to
(expert_outputs) -> ExpertOutputs [batch seq top_k hidden_size]: Each routing slot's weighted expert output
(routed_output) -> Residual [batch seq hidden_size]: The routed experts' combined output
(shared_expert_output) -> Residual [batch seq hidden_size]: The shared expert's output
(mlp_output) -> Residual [batch seq hidden_size]: What the MLP adds to the residual stream
)
(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): DogeRMSNorm((256,), eps=1e-06)
(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
)What print(model) shows on SmallDoge/Doge-180M-MoE: the native modules, standard names and every standard value with its layout.
DogeForCausalLM(
(lm_head): Linear(in_features=512, out_features=128256, bias=False)
(generator): Generator(
(streamer): Streamer()
)
(embed_tokens): Embedding(128256, 512)
(layers): ModuleList(
(0-15): 16 x DogeDecoderLayer(
(input_layernorm): DogeRMSNorm((512,), eps=1e-06)
(self_attn): DogeAttention(
(q_proj): Linear(in_features=512, out_features=512, bias=False)
(k_proj): Linear(in_features=512, out_features=256, bias=False)
(v_proj): Linear(in_features=512, out_features=256, bias=False)
(dt_proj): Linear(in_features=256, out_features=2, bias=False)
(o_proj): Linear(in_features=512, out_features=512, bias=False)
(q_norm): DogeRMSNorm((128,), eps=1e-06)
(k_norm): DogeRMSNorm((128,), eps=1e-06)
(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
)
(post_attention_layernorm): DogeRMSNorm((512,), eps=1e-06)
(mlp): DogeCDMoE(
(act_fn): SiLUActivation()
(gate_proj): Linear(in_features=512, out_features=1536, bias=False)
(up_proj): Linear(in_features=512, out_features=1536, bias=False)
(down_proj): Linear(in_features=1536, out_features=512, bias=False)
(router_gate): Linear(in_features=512, out_features=128, bias=False)
(down_embed): Embedding(4096, 512)
(up_embed): Embedding(4096, 512)
(mlp_activation): Unavailable: routed experts; read per-expert via the Moe component
(mlp_neurons) -> Neurons [batch seq intermediate_size]: What the down projection receives: act(gate)·up on a gated MLP, the activation itself otherwise
(router_logits) -> RouterLogits [batch seq num_experts]: The router's logits, one per expert, before the scoring
(expert_weights) -> ExpertWeights [batch seq top_k]: The weight each selected expert's output is scaled by
(expert_indices) -> ExpertIndices [batch seq top_k]: The expert each routing slot sends the token to
(expert_outputs) -> ExpertOutputs [batch seq top_k hidden_size]: Each routing slot's weighted expert output
(routed_output) -> Residual [batch seq hidden_size]: The routed experts' combined output
(shared_expert_output) -> Residual [batch seq hidden_size]: The shared expert's output
(mlp_output) -> Residual [batch seq hidden_size]: What the MLP adds to the residual stream
)
(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): DogeRMSNorm((512,), eps=1e-06)
(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 = input_residual * x + self_attn(input_layernorm(x))
out = post_attention_residual * h + mlp(post_attention_layernorm(h))
input_residual and post_attention_residual are [hidden_size] parameters of the block. They
multiply the stream the block carries, not what the sublayers add: attention_output is o_proj's
output and mlp_output the MLP's, unscaled.
The plain sum layers[i].input + attention_output + mlp_output does not give layer_output; the
identity multiplies the stream by each gate where the block does. It is exact in float32 on every
Doge-260M block:
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()
block = model.layers[1]._module
h = block.input_residual * x + attn
torch.testing.assert_close(block.post_attention_residual * h + mlp, out)
On Doge-260M the gates are below one almost everywhere: input_residual averages 0.73 to 0.94 per
block (its few negative entries, 0.09% of them, are on block 0), and post_attention_residual 0.87 to
0.96. A term added at block i therefore reaches the last block's output multiplied by every later
gate, channel by channel, which a direct attribution to the logits has to include. Zeroing
attention_output does not leave the block's input in place: the stream still goes on as
input_residual * x.
On Doge-260M channel 524 of the stream is a massive activation: at the last block's input it holds
57,662 at the first position and 5,000 to 6,700 at the others, at least 85% of the stream's squared
norm at every position of a 30-token prompt. The last block's
post_attention_residual is 0.0008 on that channel and at least 0.72 on every other, so the block
removes it before the final norm. Steering or patching that adds to channel 524 is erased the same
way at the last block.
Each attention projects its values through dt_proj to one number per key and key/value head, and
adds exp(A * softplus(dt)) to every query's score for that key. A is a per-head parameter, so a
head with A > 0 raises the keys dt_proj picks out and a head with A < 0 lowers them.
attention_scores carry the bias, and it can be rebuilt from attention_values:
import torch.nn.functional as F
attn = model.layers[1].self_attn
with model.trace(prompt):
values = attn.attention_values.save() # [batch, num_kv_heads, seq, head_dim]
scores = attn.attention_scores.save() # [batch, num_heads, query, key]
module = attn._module
v = values.transpose(1, 2).flatten(2) # [batch, seq, num_kv_heads * head_dim]
dt = F.softplus(module.dt_proj(v)) # [batch, seq, num_kv_heads]
bias = torch.exp(module.A * dt).transpose(1, 2) # [batch, num_kv_heads, key]
On Doge-260M A ranges from −0.29 to 0.29 and the bias from 0 to 8.4. Removing it from the scores
moves 0.02 to 0.47 of each pattern row's mass, averaged per block, on a 30-token prompt; at block 10
the mass on the first token, averaged over heads and queries, is 0.65 with the bias and 0.34 without it. The pinned tiny checkpoint has
A at zero, where the bias is 1 on every key and the pattern is unchanged.
keep_window_size keys, the bias drops keysWhen the prompt has more than keep_window_size keys (1024 on Doge-260M, 2048 on Doge-20M, 4096 on
Doge-40M), each query keeps the keep_window_size keys it can see with the largest bias and masks
the rest. The choice reads the bias alone, not the query's score. A dropped key has the dtype's minimum in attention_scores and zero in
attention_probabilities. Below that length, every causal key is kept.
The attention interior needs attn_implementation="eager". The default sdpa load adds the same
bias and the causal mask: on Doge-260M in float32 the two loads' logits agree to 1.2e-5. Doge-20M,
Doge-40M and Doge-260M load in transformers. In the Instruct checkpoints and in
Doge-60M, -160M and -320M, A and dt_proj are twice num_key_value_heads wide and the attention has
no q_norm or k_norm, so transformers' DogeForCausalLM does not load them (they are greyed out in
the selector). Doge-260M's tokenizer prepends <|begin_of_text|> (id 128000).
On the is_moe checkpoints mlp is DogeCDMoE: a dense SwiGLU MLP of intermediate_size plus
num_experts one-neuron experts (rows of down_embed and up_embed) that router_gate retrieves
by product keys, num_experts_per_tok per token. It returns (hidden_states, router_logits), and the
block adds the hidden states. nnterp serves mlp_output, the dense MLP's output plus the routed
experts', and reports every mixture value unavailable: the product-key routing has no router or experts
module to read them at.
logits is lm_head.output, with no cap or scale, and lm_head shares its weight with
embed_tokens on every listed checkpoint.
Doge (DogeForCausalLM, SmallDoge).
Llama's tree with a gated residual: the block scales the stream it carries,
not what it adds. Each sublayer's output is added to the residual times a learned
per-channel gate (input_residual, then post_attention_residual, both
[hidden_size] parameters of the block)::
h = input_residual * x + self_attn(input_layernorm(x))
out = post_attention_residual * h + mlp(post_attention_layernorm(h))
What each sublayer adds is its module's output, unscaled, so the base holds for
attention_output and mlp_output; the contribution identity is
layer_output == post_attention_residual * (input_residual * input + attention_output) + mlp_output,
which is the plain one only where both gates are one (their initial value). The
gates are layers[i]._module.input_residual / post_attention_residual;
nothing is computed or divided for you. The attention runs the shared eager
forward with q/k norms and a dynamic mask: dt_proj of the values, through
A, gives each key a per-head bias, added to the causal mask (and, past
keep_window_size keys, used to drop all but the top keys), so
attention_scores carry it. The MLP is a gated DogeMLP, or the cross-domain
mixture DogeCDMoE under is_moe, which returns (hidden_states, router_logits).
Doge-20M, -40M and -260M load and run. Of the is_moe checkpoints, Doge-40M-MoE
loads and runs; it needs transformers 5.18 or later, whose block takes the first element
of DogeCDMoE's tuple. Where it runs, mlp_output is the mixture's hidden states
(dense MLP plus routed experts); the six mixture values stay unavailable, since
the product-key routing has no router or experts module to read them at.