Coverage for transformer_lens/model_bridge/supported_architectures/nemotron.py: 100%
16 statements
« prev ^ index » next coverage.py v7.10.1, created at 2026-08-11 18:50 +0000
« prev ^ index » next coverage.py v7.10.1, created at 2026-08-11 18:50 +0000
1"""Nemotron architecture adapter.
3NVIDIA's dense Nemotron-3/4 and Minitron families (``NemotronForCausalLM``):
4llama-shaped GQA decoder with three quirks — LayerNorm1P normalization
5(zero-centered gamma, applied as ``weight + 1``), a non-gated squared-ReLU
6MLP (``up_proj``/``down_proj`` only), and partial rotary embeddings
7(rotary factor 0.5).
8"""
10from typing import Any
12from transformer_lens.model_bridge.architecture_adapter import ArchitectureAdapter
13from transformer_lens.model_bridge.generalized_components import (
14 BlockBridge,
15 EmbeddingBridge,
16 LinearBridge,
17 NormalizationBridge,
18 PositionEmbeddingsAttentionBridge,
19 RotaryEmbeddingBridge,
20 UnembeddingBridge,
21)
24class NemotronArchitectureAdapter(ArchitectureAdapter):
25 """Architecture adapter for NemotronForCausalLM models."""
27 _testing_eager = "config"
29 def __init__(self, cfg: Any) -> None:
30 """Initialize the Nemotron architecture adapter."""
31 super().__init__(cfg)
33 self.cfg.normalization_type = "LN"
34 self.cfg.positional_embedding_type = "rotary"
35 self.cfg.final_rms = False
36 self.cfg.gated_mlp = False
37 self.cfg.attn_only = False
39 # LayerNorm1P applies gamma as (weight + 1); standard LN folding would
40 # fold the stored weight without the offset. Keep raw weights.
41 self.supports_fold_ln = False
42 self.supports_center_writing_weights = False
44 self.weight_processing_conversions = {
45 **self._qkvo_weight_conversions(),
46 }
48 self.component_mapping = {
49 "embed": EmbeddingBridge(name="model.embed_tokens"),
50 "rotary_emb": RotaryEmbeddingBridge(name="model.rotary_emb", config=self.cfg),
51 "blocks": BlockBridge(
52 name="model.layers",
53 submodules={
54 # LayerNorm1P applies gamma as (weight + 1); delegate to the
55 # native module rather than reimplementing LN without the offset.
56 "ln1": NormalizationBridge(
57 name="input_layernorm",
58 config=self.cfg,
59 use_native_layernorm_autograd=True,
60 ),
61 "attn": PositionEmbeddingsAttentionBridge(
62 name="self_attn",
63 config=self.cfg,
64 submodules={
65 "q": LinearBridge(name="q_proj"),
66 "k": LinearBridge(name="k_proj"),
67 "v": LinearBridge(name="v_proj"),
68 "o": LinearBridge(name="o_proj"),
69 },
70 requires_attention_mask=True,
71 requires_position_embeddings=True,
72 ),
73 "ln2": NormalizationBridge(
74 name="post_attention_layernorm",
75 config=self.cfg,
76 use_native_layernorm_autograd=True,
77 ),
78 "mlp": self._ungated_mlp(),
79 },
80 ),
81 "ln_final": NormalizationBridge(
82 name="model.norm", config=self.cfg, use_native_layernorm_autograd=True
83 ),
84 "unembed": UnembeddingBridge(name="lm_head", config=self.cfg),
85 }