kempnerforge.model.transformer¶
Transformer model for KempnerForge.
- Architecture: Llama-style pre-norm transformer.
Token Embedding → [TransformerBlock × N] → Final Norm → Output Head
- Design choices:
ModuleDict (not ModuleList) for layers — preserves FQNs for DCP checkpointing.
Embedding and output head are optional (can be None for PP middle stages).
Forward is a simple loop over blocks — pipeline-parallelism friendly.
Classes
Full transformer model built from ModelConfig. |
|
Single transformer block with pre-norm architecture. |
- class kempnerforge.model.transformer.TransformerBlock[source]¶
Bases:
ModuleSingle transformer block with pre-norm architecture.
Structure: norm → attention → residual, norm → mlp → residual
- __init__(config, layer_idx)[source]¶
- Parameters:
config (ModelConfig)
layer_idx (int)
- Return type:
None
- forward(x, rope_cos, rope_sin, *, kv_cache=None, attn_mask=None)[source]¶
Run attention and the MLP over the residual stream.
- Parameters:
x (torch.Tensor) – Residual stream, shape
(batch, seq_len, dim).rope_cos (torch.Tensor) – RoPE cosine frequencies for this block’s positions.
rope_sin (torch.Tensor) – RoPE sine frequencies for this block’s positions.
kv_cache (KVCache | None) – Optional KV cache for incremental generation.
attn_mask (torch.Tensor | BlockMask | None) – The one mask from
kempnerforge.model.masking.build_attention_mask, built once per forward and shared by every block.
- Returns:
The updated residual stream, shape
(batch, seq_len, dim).- Return type:
- class kempnerforge.model.transformer.Transformer[source]¶
Bases:
ModuleFull transformer model built from ModelConfig.
Embedding → TransformerBlocks → Norm → Output Head
include_token_embedding=False/include_output_head=Falsebuild the model without that module: the attribute isNoneand registers no state-dict keys. Without the embedding, pass pre-embedded inputs viamodality.inputs_embeds; without the head,forwardreturns the final hidden states.tie_embeddings=Truerequires both modules.generate()rejects a model built without either module. Tensor parallelism is not supported for such a model.- __init__(config, *, vlm_config=None, num_image_tokens=0, include_token_embedding=True, include_output_head=True)[source]¶
- Parameters:
config (ModelConfig)
vlm_config (VLMConfig | None)
num_image_tokens (int)
include_token_embedding (bool)
include_output_head (bool)
- Return type:
None
- init_weights_and_freqs()[source]¶
Initialize weights and RoPE frequencies after meta-device materialization.
Called after
model.to_empty(device=...)to fill in parameter values and compute RoPE frequency table. Safe to call on already-initialized models (skips if freqs are already computed).- Return type:
None
- set_moe_step(step, max_steps)[source]¶
Set training step on all MoE routers for adaptive bias scheduling.
Reaches every sigmoid router, including each MoT modality’s.
- get_moe_aux_loss()[source]¶
Sum the auxiliary losses of every MoE router. Returns 0 if dense.
A MoT layer contributes one term per modality, so an image + text MoT model sums twice as many terms as a text model with the same MoE layers.
- Return type:
- get_moe_router_z_loss()[source]¶
Sum the router z-losses (ST-MoE) of every MoE router. Returns 0 if dense.
Like
get_moe_aux_loss, a MoT layer contributes one term per modality.- Return type:
- get_expert_counts()[source]¶
Collect per-layer expert utilization for flat MoE layers.
Returns
{layer_idx: (num_experts,) tensor}for layers whose MLP is aMoEMLP(the standard, single-pool MoE). Returns{}for dense models, for MoT and for MoMa, whose per-modality routers surface throughget_mot_expert_countsandget_moma_expert_countsinstead.- Return type:
- get_mot_expert_counts()[source]¶
Collect per-layer, per-modality expert utilization for MoT MoE layers.
Returns
{layer_idx: {modality: (num_experts,) tensor}}for every MoT layer whose per-modality FFNs areMoEMLP``s; returns ``{}otherwise. Each tensor holds the token count per expert from that modality’s router in the most recent forward, so the image and text counts of a layer sum to different totals.- Return type:
dict[int, dict[str, torch.Tensor]]
- get_moma_expert_counts()[source]¶
Collect per-layer, per-modality expert utilization for MoMa layers.
Returns
{layer_idx: {modality: (num_experts_for_modality,) tensor}}for every layer whose MLP is aMoMaFFN; returns{}otherwise. Each modality’s expert count tensor reflects the most recent forward through that layer’s expert-choice router (paper Figure 5-style utilization). Counts on a fresh model (no forward yet) are the router’s init zeros.- Return type:
dict[int, dict[str, torch.Tensor]]
- forward(tokens=None, *, modality=None, kv_caches=None, doc_ids=None, position_ids=None, attention_group_ids=None)[source]¶
Forward pass.
Exactly one of
tokensormodality.inputs_embedsmust be provided. Modality-injection routes (prefix_embeds,output_slice,image_features,image_mask,modality_ids,inline_embeds) are grouped on the optionalModalityContextarg; seekempnerforge/model/modality.pyfor the full intra-context invariant table.inline_embedsare written over the embeddedtokensat(inline_rows, inline_positions)before the first layer, which is how a packed row carries each document’s image tokens before its own text, andoutput_rows/output_positionspick the positions the head runs on, giving(1, M, vocab)logits.- Parameters:
tokens (torch.Tensor | None) – Integer token ids, shape
(batch, seq_len).modality (ModalityContext | None) – Optional
ModalityContextbundling pre-embedded inputs, prefix embeds, output slicing, image features, and modality routing tags for VLM arches.Noneis the pure text-only forward. It may also carryposition_idsandattention_group_ids(see those arguments) or the rotation itself asrope_cosandrope_sin,(batch, seq_len, head_dim // 2)over the residual, or(1, seq_len, head_dim // 2)shared by every row, for position schemes that are not one integer per token; the rotation excludesposition_ids, covers the appended tokens underkv_cachesasposition_idsdoes, is applied without the model’s own tables, and is unsupported for MoT.kv_caches (list[KVCache] | None) – Optional list of KVCache (one per layer) for generation. The tokens of this forward are appended after the cached ones; without caller positions or a rotation their RoPE positions continue from the cache fill level. Cross-arg invariant:
kv_cachesforbidsmodality.prefix_embeds,modality.output_slice,modality.image_features,modality.modality_ids,modality.key_padding_mask,doc_idsandattention_group_ids, by argument or asmodality.attention_group_ids(all training-only).doc_ids (torch.Tensor | None) – Optional per-token document IDs for packed sequences, shape
(batch, seq_len)over the residual stream. Enables block-diagonal causal attention that isolates documents within packed sequences.position_ids (torch.Tensor | None) – Optional explicit per-token RoPE positions, shape
(batch, seq_len)matching the residual reaching attention (including anymodality.prefix_embeds), dtype int64, values in[0, model.max_seq_len). Rows may differ, so positions can e.g. restart at zero at each document of a packed sequence.None(default) assigns contiguous positions starting at the KV-cache fill level, exactly as before. Withkv_cachesthe tensor covers the tokens of this forward alone, the ones being appended, so a caller that positions its own tokens does so at prefill and at every decode step alike. Unsupported for MoT, which derives per-modality positions internally. AModalityContextmay carry the same tensor asmodality.position_idsinstead, which is how a strategy chooses the positions of the residual it lays out; passing both raises.attention_group_ids (torch.Tensor | None) – Optional per-token visibility group ids over the residual stream, shape
(batch, seq_len), int64; negative means no group. Tokens sharing a nonnegative id see each other bidirectionally (e.g. prefix-LM spans):visible(q, k) = same_document AND (k <= q OR same_nonnegative_group). Withoutdoc_idsthe row is one document.Noneleaves attention unchanged; all-negative ids give the same visibility asNonebut still build a mask, soNoneis the unmasked fast path. On MoT,doc_idsand group ids needvlm.mot_modalitiesin residual order,("image", "text"). May likewise come frommodality.attention_group_ids, not both.
- Returns:
Logits tensor of shape
(batch, out_seq_len, vocab_size)whereout_seq_len == seq_lennormally or the sliced length whenmodality.output_sliceis set, or(1, M, vocab_size)over theMpositionsmodality.output_rowsandoutput_positionspick. Built withinclude_output_head=False, returns the final hidden states(batch, out_seq_len, dim)instead.- Return type: