Coverage for transformer_lens/model_bridge/supported_architectures/olmo_hybrid.py: 92%
22 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"""OLMo Hybrid architecture adapter.
3AllenAI's OLMo Hybrid (``OlmoHybridForCausalLM``, Olmo-Hybrid-7B):
4alternating layer types — OLMo2-style full-attention layers (post-norms
5in the residual, full-width QK-norm, NoPE mode when position embeddings
6are withheld) and GatedDeltaNet linear-attention layers (pre-norm, with
7separate q/k/v short convolutions). Attention stays HF-native; the
8OlmoHybrid GatedDeltaNet variant differs from Qwen3Next's (separate
9q/k/v conv states), so it is delegated opaquely rather than through
10GatedDeltaNetBridge's reimplementation. Generation uses the model's own
11OlmoHybridDynamicCache.
12"""
14from typing import Any
16from transformer_lens.model_bridge.architecture_adapter import ArchitectureAdapter
17from transformer_lens.model_bridge.generalized_components import (
18 AttentionBridge,
19 BlockBridge,
20 EmbeddingBridge,
21 LinearBridge,
22 RMSNormalizationBridge,
23 UnembeddingBridge,
24)
25from transformer_lens.model_bridge.generalized_components.base import (
26 GeneralizedComponent,
27)
30class _OlmoHybridBlockBridge(BlockBridge):
31 """BlockBridge without the hook_resid_mid alias.
33 No single target fits both layer types (ln2.hook_in is the mid-point on
34 linear-attention layers but the raw attn-branch output on full-attention
35 layers); dropped type-visibly, as on ParallelBlockBridge.
36 """
38 def __init__(self, *args: Any, **kwargs: Any):
39 super().__init__(*args, **kwargs)
40 if self.hook_aliases is BlockBridge.hook_aliases: 40 ↛ 41line 40 didn't jump to line 41 because the condition on line 40 was never true
41 self.hook_aliases = dict(self.hook_aliases)
42 self.hook_aliases.pop("hook_resid_mid", None)
45class OlmoHybridArchitectureAdapter(ArchitectureAdapter):
46 """Architecture adapter for OlmoHybridForCausalLM models."""
48 # Post-norm attention layers and the linear-attention state are not
49 # fold-safe; compatibility-mode weight processing does not apply.
50 supports_fold_ln = False
52 def __init__(self, cfg: Any) -> None:
53 """Initialize the OLMo Hybrid architecture adapter."""
54 super().__init__(cfg)
56 self._set_rms_rotary_defaults()
57 self.cfg.attn_implementation = "eager"
58 self.cfg.is_stateful = True
60 self.weight_processing_conversions = {
61 **self._qkvo_weight_conversions(),
62 }
64 self.component_mapping = {
65 "embed": EmbeddingBridge(name="model.embed_tokens"),
66 "blocks": _OlmoHybridBlockBridge(
67 name="model.layers",
68 submodules={
69 # Linear-attention layers are pre-norm (input_layernorm);
70 # full-attention layers are OLMo2 post-norm and have
71 # post_feedforward_layernorm instead.
72 "ln1": RMSNormalizationBridge(
73 name="input_layernorm", config=self.cfg, optional=True
74 ),
75 "ln2": RMSNormalizationBridge(name="post_attention_layernorm", config=self.cfg),
76 "ln2_post": RMSNormalizationBridge(
77 name="post_feedforward_layernorm", config=self.cfg, optional=True
78 ),
79 "attn": AttentionBridge(
80 name="self_attn",
81 config=self.cfg,
82 submodules={
83 "q": LinearBridge(name="q_proj"),
84 "k": LinearBridge(name="k_proj"),
85 "v": LinearBridge(name="v_proj"),
86 "o": LinearBridge(name="o_proj"),
87 "q_norm": RMSNormalizationBridge(name="q_norm", config=self.cfg),
88 "k_norm": RMSNormalizationBridge(name="k_norm", config=self.cfg),
89 },
90 maintain_native_attention=True,
91 requires_attention_mask=True,
92 optional=True,
93 ),
94 "linear_attn": GeneralizedComponent(name="linear_attn", optional=True),
95 "mlp": self._gated_mlp(),
96 },
97 ),
98 "ln_final": RMSNormalizationBridge(name="model.norm", config=self.cfg),
99 "unembed": UnembeddingBridge(name="lm_head", config=self.cfg),
100 }
102 def create_stateful_cache(
103 self,
104 hf_model: Any,
105 batch_size: int,
106 device: Any,
107 dtype: Any,
108 ) -> Any:
109 """OLMo Hybrid keeps per-layer q/k/v conv states in its own cache class."""
110 from transformers.models.olmo_hybrid.modeling_olmo_hybrid import (
111 OlmoHybridDynamicCache,
112 )
114 return OlmoHybridDynamicCache(config=hf_model.config)