deepseek_v4¶
deepseek_v4
¶
DeepSeek-V4 (DeepseekV4ForCausalLM): a hyper-connection residual, compressed attention, all-MoE.
model.{embed_tokens, layers[i].{attn_hc, input_layernorm, self_attn, ffn_hc,
post_attention_layernorm, mlp}, hc_head, norm} and lm_head.
The residual is hc_mult parallel streams, [batch, seq, streams, hidden_size],
between every pair of blocks (the model copies the embedding into each stream
before block 0). Each sublayer reads one collapse of the streams and writes back
into all of them through a hyper-connection (attn_hc before the attention,
ffn_hc before the MLP), which returns (post, comb, collapsed):
collapsed is the pre-weighted sum of the streams that the sublayer's norm
reads, post [batch, seq, streams] how much of the sublayer's output each
stream receives, comb [batch, seq, streams, streams] a doubly stochastic
matrix mixing the streams, consumed transposed. The block, per token::
h = attention_combᵀ · x + attention_post ⊗ self_attn(input_layernorm(collapsed_a))
out = mlp_combᵀ · h + mlp_post ⊗ mlp(post_attention_layernorm(collapsed_f))
layer_outputis the block's own stream tensor, under theStreamslayout, and so islayers[i].input; writes land natively, andskip_layersandsteerwork unchanged (a[hidden_size]steering vector broadcasts over the streams).- The contributions are the sublayers' own outputs,
[batch, seq, hidden_size], unscaled:attention_outputisself_attn.output[0],mlp_outputthe mixture's return (routed plus shared experts). The weights that put them into the streams are the block'sattention_post,attention_comb,mlp_postandmlp_comb, read off the hyper-connections' outputs. The identity is the block's formula above, not a sum; its stream mean is additive (combis doubly stochastic) up to the Sinkhorn projection's residual, about 2e-6 relative in float32: ``layer_output.mean(2) == input.mean(2) + attention_post.mean(-1, keepdim=True) - attention_output + mlp_post.mean(-1, keepdim=True) * mlp_output``.
- The readout collapses the streams once more:
norm(hc_head(streams)),hc_heada learned, content-dependent weighting. The family'sproject_on_vocabdoes the same, so the lens on the last block islogitsexactly.
The attention runs the shared interface, with a per-head sink (s_aux), so
the scores are GPT-OSS's binding. It is multi-query (one key/value head), and
the keys and values are one tensor: the same object is passed as both, so an
in-place edit of one edits the other. On a compressed block
(compressed_sparse_attention, heavily_compressed_attention) the
compressor's entries are concatenated after the token keys once the prompt is
compress_rates[type] tokens long, so the key axis is longer than the
sequence there. The interface's output keeps a rotation on its rotary slice
(the values are the rotated keys); the module rotates it back before the grouped
output projection, and attention_head_outputs is that de-rotated tensor, what
the projection reads. Not latent attention: the plain root sizes hold.
Every MLP is a mixture (DeepseekV4SparseMoeBlock, a Moe; its router, gate,
is aliased router); on the hash_moe blocks the router picks experts from the
token ids (tid2eid[input_ids]), so a run needs input_ids. There the logits only
weight the experts the ids chose: writing router_logits changes expert_weights,
not expert_indices.
RENAME
module-attribute
¶
RENAME = {'model.embed_tokens': 'embed_tokens', 'model.layers': 'layers', 'model.norm': 'norm', 'gate': 'router'}
STREAMS_BOUNDARY
module-attribute
¶
STREAMS_BOUNDARY = "hyper-connection streams: the sublayers read a mix of the streams, not the stream; the block's inner boundaries are not mapped for this family yet"
ENVOYS
module-attribute
¶
ENVOYS = {DeepseekV4DecoderLayer: Layer, DeepseekV4Attention: Attention, DeepseekV4SparseMoeBlock: Mlp}
Mlp
¶
project_on_vocab
¶
project_on_vocab(model: StandardizedTransformer, hidden: Tensor) -> Tensor
The logit lens as the model makes its logits: hc_head over the streams, the final norm, lm_head.
A tensor with the stream axis, [batch, seq, streams, hidden_size] (rank 4)
or one position of it, [streams, hidden_size] (rank 2 with hc_mult
rows), is collapsed by the model's hc_head first; the result drops the
stream axis, [..., vocab_size]. Any other tensor is a plain [..., hidden_size]
stream (a sublayer's output, one stream layer_output[:, :, k]) and goes
through norm and lm_head alone.