Coverage for transformer_lens/loading_from_pretrained.py: 70%
529 statements
« prev ^ index » next coverage.py v7.10.1, created at 2026-09-01 16:23 +0000
« prev ^ index » next coverage.py v7.10.1, created at 2026-09-01 16:23 +0000
1"""Loading Pretrained Models Utilities.
3This module contains functions for loading pretrained models from the Hugging Face Hub.
4"""
6from __future__ import annotations
8import dataclasses
9import logging
10import math
11import os
12import re
13from pathlib import Path
14from typing import Any
16import torch
17from huggingface_hub import HfApi
18from transformers import (
19 AutoConfig,
20 AutoModel,
21 AutoModelForCausalLM,
22 BertForPreTraining,
23 HubertModel,
24 T5ForConditionalGeneration,
25 Wav2Vec2Model,
26)
27from transformers.utils.quantization_config import Mxfp4Config
29import transformer_lens.utilities as utils
30from transformer_lens.config.hooked_transformer_config import HookedTransformerConfig
31from transformer_lens.pretrained.weight_conversions import (
32 convert_apertus_weights,
33 convert_bert_weights,
34 convert_bloom_weights,
35 convert_coder_weights,
36 convert_gemma_weights,
37 convert_gpt2_weights,
38 convert_gpt_oss_weights,
39 convert_gptj_weights,
40 convert_hubert_weights,
41 convert_llama_weights,
42 convert_mingpt_weights,
43 convert_mistral_weights,
44 convert_mixtral_weights,
45 convert_neel_solu_old_weights,
46 convert_neo_weights,
47 convert_neox_weights,
48 convert_olmo2_weights,
49 convert_olmo3_weights,
50 convert_olmo_weights,
51 convert_olmoe_weights,
52 convert_opt_weights,
53 convert_phi3_weights,
54 convert_phi_weights,
55 convert_qwen2_weights,
56 convert_qwen3_weights,
57 convert_qwen_weights,
58 convert_t5_weights,
59)
60from transformer_lens.supported_models import MODEL_ALIASES, OFFICIAL_MODEL_NAMES
61from transformer_lens.utilities.architectures import POST_NORM_ARCHITECTURES
62from transformer_lens.utilities.heterogeneous_config import het_safe_view
63from transformer_lens.utilities.hf_utils import get_rotary_pct_from_config
64from transformer_lens.utilities.quantization import (
65 quantization_method,
66 unreadable_weight_reason,
67)
69NON_HF_HOSTED_MODEL_NAMES = [
70 "llama-7b-hf",
71 "llama-13b-hf",
72 "llama-30b-hf",
73 "llama-65b-hf",
74]
75"""Official model names for models not hosted on HuggingFace."""
77NEED_REMOTE_CODE_MODELS = (
78 "bigcode/santacoder",
79 "Qwen/Qwen-",
80 "Qwen/Qwen3-",
81 "microsoft/phi-2",
82 "microsoft/phi-4",
83 "apple/OpenELM",
84 "openai/gpt-oss-",
85 "swiss-ai/Apertus-",
86)
89def _get_rope_theta(hf_config: Any, default: float = 10000.0) -> float | int:
90 """Extract rope_theta from a HuggingFace config, handling both old and new formats.
92 In transformers v5+, rope_theta moved from a top-level attribute to
93 hf_config.rope_parameters['rope_theta'].
94 """
95 # Try direct attribute first (transformers < 5.0)
96 rope_theta = getattr(hf_config, "rope_theta", None)
97 if rope_theta is not None:
98 return rope_theta
99 # Try rope_parameters dict (transformers >= 5.0)
100 rope_params = getattr(hf_config, "rope_parameters", None)
101 if rope_params is not None and isinstance(rope_params, dict):
102 return rope_params.get("rope_theta", default)
103 return default
106def _apply_llama3_rope_scaling(cfg_dict: dict[str, Any], hf_config: Any) -> None:
107 """Populate the NTK-by-parts fields when a config requests llama3 rope scaling."""
108 rope_scaling = getattr(hf_config, "rope_scaling", None)
109 if not rope_scaling:
110 return
111 rope_type = (rope_scaling.get("type") or rope_scaling.get("rope_type") or "").lower()
112 if rope_type != "llama3": 112 ↛ 113line 112 didn't jump to line 113 because the condition on line 112 was never true
113 return
114 cfg_dict["use_NTK_by_parts_rope"] = True
115 cfg_dict["NTK_original_ctx_len"] = rope_scaling.get(
116 "original_max_position_embeddings", hf_config.max_position_embeddings
117 )
118 cfg_dict["NTK_by_parts_low_freq_factor"] = rope_scaling.get("low_freq_factor", 1.0)
119 cfg_dict["NTK_by_parts_high_freq_factor"] = rope_scaling.get("high_freq_factor", 4.0)
120 cfg_dict["NTK_by_parts_factor"] = rope_scaling.get("factor", 1.0)
123def make_model_alias_map() -> dict[str, str]:
124 """
125 Converts OFFICIAL_MODEL_NAMES (the list of actual model names on
126 HuggingFace) and MODEL_ALIASES (a dictionary mapping official model names to
127 aliases) into a dictionary mapping all aliases to the official model name.
128 """
129 model_alias_map = {}
130 for official_model_name in OFFICIAL_MODEL_NAMES:
131 aliases = MODEL_ALIASES.get(official_model_name, [])
132 for alias in aliases:
133 model_alias_map[alias.lower()] = official_model_name
134 model_alias_map[official_model_name.lower()] = official_model_name
135 return model_alias_map
138def get_official_model_name(model_name: str) -> str:
139 """
140 Returns the official model name for a given model name (or alias).
141 """
142 model_alias_map = make_model_alias_map()
143 official_model_name = model_alias_map.get(model_name.lower())
144 if official_model_name is None: 144 ↛ 145line 144 didn't jump to line 145 because the condition on line 144 was never true
145 raise ValueError(
146 f"{model_name} not found. Valid official model names (excl aliases): {OFFICIAL_MODEL_NAMES}"
147 )
148 return official_model_name
151def convert_hf_model_config(model_name: str, **kwargs: Any) -> dict[str, Any]:
152 """
153 Returns the model config for a HuggingFace model, converted to a dictionary
154 in the HookedTransformerConfig format.
156 Takes the official_model_name as an input.
157 """
158 # In case the user passed in an alias
159 if (Path(model_name) / "config.json").exists():
160 logging.info("Loading model config from local directory")
161 official_model_name = model_name
162 else:
163 official_model_name = get_official_model_name(model_name)
165 # Load HuggingFace model config. Stays None on the name-based branches
166 # below, which infer the architecture from the model name and never fetch.
167 hf_config: Any = None
168 if "llama" in official_model_name.lower():
169 architecture = "LlamaForCausalLM"
170 elif "gemma-3" in official_model_name.lower() or "medgemma" in official_model_name.lower():
171 # Gemma 3: 270M and 1B are text-only (CausalLM), 4B+ are multimodal (ConditionalGeneration)
172 # Exception: medgemma-27b-text-it is text-only
173 if "270m" in official_model_name.lower() or "1b" in official_model_name.lower():
174 architecture = "Gemma3ForCausalLM"
175 elif "medgemma-27b-text" in official_model_name.lower():
176 # medgemma-27b-text-it is text-only variant
177 architecture = "Gemma3ForCausalLM"
178 else:
179 # 4B, 12B, 27B and medgemma are multimodal
180 architecture = "Gemma3ForConditionalGeneration"
181 elif "gemma-2-" in official_model_name.lower():
182 architecture = "Gemma2ForCausalLM"
183 elif "gemma" in official_model_name.lower(): 183 ↛ 184line 183 didn't jump to line 184 because the condition on line 183 was never true
184 architecture = "GemmaForCausalLM"
185 else:
186 huggingface_token = os.environ.get("HF_TOKEN", "")
187 hf_config = AutoConfig.from_pretrained(
188 official_model_name,
189 token=huggingface_token if len(huggingface_token) > 0 else None,
190 **kwargs,
191 )
192 # het view: transformers>=5.15 per-layer fields raise (not
193 # AttributeError) on global reads, so every hasattr/getattr probe in
194 # the branch chain below is a crash site without it.
195 hf_config = het_safe_view(hf_config)
196 architecture = hf_config.architectures[0]
198 cfg_dict: dict[str, Any]
199 if official_model_name.startswith(
200 ("llama-7b", "meta-llama/Llama-2-7b")
201 ): # same architecture for LLaMA and Llama-2
202 cfg_dict = {
203 "d_model": 4096,
204 "d_head": 4096 // 32,
205 "n_heads": 32,
206 "d_mlp": 11008,
207 "n_layers": 32,
208 "n_ctx": 2048 if official_model_name.startswith("llama-7b") else 4096,
209 "eps": 1e-6 if official_model_name.startswith("llama-7b") else 1e-5,
210 "d_vocab": 32000,
211 "act_fn": "silu",
212 "normalization_type": "RMS",
213 "positional_embedding_type": "rotary",
214 "rotary_adjacent_pairs": False,
215 "rotary_dim": 4096 // 32,
216 "final_rms": True,
217 "gated_mlp": True,
218 }
219 elif official_model_name.startswith("codellama"): # same architecture CodeLlama and Llama-2 219 ↛ 220line 219 didn't jump to line 220 because the condition on line 219 was never true
220 cfg_dict = {
221 "d_model": 4096,
222 "d_head": 4096 // 32,
223 "n_heads": 32,
224 "d_mlp": 11008,
225 "n_layers": 32,
226 "n_ctx": 4096,
227 "eps": 1e-5,
228 "d_vocab": 32016,
229 "act_fn": "silu",
230 "normalization_type": "RMS",
231 "positional_embedding_type": "rotary",
232 "rotary_dim": 4096 // 32,
233 "final_rms": True,
234 "gated_mlp": True,
235 "rotary_base": 1000000,
236 }
237 if "python" in official_model_name.lower():
238 # The vocab size of python version of CodeLlama-7b is 32000
239 cfg_dict["d_vocab"] = 32000
240 elif official_model_name.startswith( 240 ↛ 243line 240 didn't jump to line 243 because the condition on line 240 was never true
241 ("llama-13b", "meta-llama/Llama-2-13b")
242 ): # same architecture for LLaMA and Llama-2
243 cfg_dict = {
244 "d_model": 5120,
245 "d_head": 5120 // 40,
246 "n_heads": 40,
247 "d_mlp": 13824,
248 "n_layers": 40,
249 "n_ctx": 2048 if official_model_name.startswith("llama-13b") else 4096,
250 "eps": 1e-6 if official_model_name.startswith("llama-13b") else 1e-5,
251 "d_vocab": 32000,
252 "act_fn": "silu",
253 "normalization_type": "RMS",
254 "positional_embedding_type": "rotary",
255 "rotary_adjacent_pairs": False,
256 "rotary_dim": 5120 // 40,
257 "final_rms": True,
258 "gated_mlp": True,
259 }
260 elif "llama-30b" in official_model_name: 260 ↛ 261line 260 didn't jump to line 261 because the condition on line 260 was never true
261 cfg_dict = {
262 "d_model": 6656,
263 "d_head": 6656 // 52,
264 "n_heads": 52,
265 "d_mlp": 17920,
266 "n_layers": 60,
267 "n_ctx": 2048,
268 "eps": 1e-6,
269 "d_vocab": 32000,
270 "act_fn": "silu",
271 "normalization_type": "RMS",
272 "positional_embedding_type": "rotary",
273 "rotary_adjacent_pairs": False,
274 "rotary_dim": 6656 // 52,
275 "final_rms": True,
276 "gated_mlp": True,
277 }
278 elif "llama-65b" in official_model_name: 278 ↛ 279line 278 didn't jump to line 279 because the condition on line 278 was never true
279 cfg_dict = {
280 "d_model": 8192,
281 "d_head": 8192 // 64,
282 "n_heads": 64,
283 "d_mlp": 22016,
284 "n_layers": 80,
285 "n_ctx": 2048,
286 "eps": 1e-6,
287 "d_vocab": 32000,
288 "act_fn": "silu",
289 "normalization_type": "RMS",
290 "positional_embedding_type": "rotary",
291 "rotary_dim": 8192 // 64,
292 "rotary_adjacent_pairs": False,
293 "final_rms": True,
294 "gated_mlp": True,
295 }
296 elif "Llama-2-70b" in official_model_name: 296 ↛ 297line 296 didn't jump to line 297 because the condition on line 296 was never true
297 cfg_dict = {
298 "d_model": 8192,
299 "d_head": 128,
300 "n_heads": 64,
301 "d_mlp": 28672,
302 "n_layers": 80,
303 "n_ctx": 4096,
304 "eps": 1e-5,
305 "d_vocab": 32000,
306 "act_fn": "silu",
307 "n_key_value_heads": 8,
308 "normalization_type": "RMS",
309 "positional_embedding_type": "rotary",
310 "rotary_adjacent_pairs": False,
311 "rotary_dim": 128,
312 "final_rms": True,
313 "gated_mlp": True,
314 }
315 elif "Meta-Llama-3-8B" in official_model_name: 315 ↛ 316line 315 didn't jump to line 316 because the condition on line 315 was never true
316 cfg_dict = {
317 "d_model": 4096,
318 "d_head": 128,
319 "n_heads": 32,
320 "d_mlp": 14336,
321 "n_layers": 32,
322 "n_ctx": 8192,
323 "eps": 1e-5,
324 "d_vocab": 128256,
325 "act_fn": "silu",
326 "n_key_value_heads": 8,
327 "normalization_type": "RMS",
328 "positional_embedding_type": "rotary",
329 "rotary_adjacent_pairs": False,
330 "rotary_dim": 128,
331 "final_rms": True,
332 "gated_mlp": True,
333 "rotary_base": 500000.0,
334 }
335 elif "Meta-Llama-3-70B" in official_model_name: 335 ↛ 336line 335 didn't jump to line 336 because the condition on line 335 was never true
336 cfg_dict = {
337 "d_model": 8192,
338 "d_head": 128,
339 "n_heads": 64,
340 "d_mlp": 28672,
341 "n_layers": 80,
342 "n_ctx": 8192,
343 "eps": 1e-5,
344 "d_vocab": 128256,
345 "act_fn": "silu",
346 "n_key_value_heads": 8,
347 "normalization_type": "RMS",
348 "positional_embedding_type": "rotary",
349 "rotary_adjacent_pairs": False,
350 "rotary_dim": 128,
351 "final_rms": True,
352 "gated_mlp": True,
353 "rotary_base": 500000.0,
354 }
355 elif "Llama-3.2-1B" in official_model_name: 355 ↛ 356line 355 didn't jump to line 356 because the condition on line 355 was never true
356 cfg_dict = {
357 "d_model": 2048,
358 "d_head": 64,
359 "n_heads": 32,
360 "d_mlp": 8192,
361 "n_layers": 16,
362 "n_ctx": 2048, # capped due to memory issues
363 "eps": 1e-5,
364 "d_vocab": 128256,
365 "act_fn": "silu",
366 "n_key_value_heads": 8,
367 "normalization_type": "RMS",
368 "positional_embedding_type": "rotary",
369 "rotary_adjacent_pairs": False,
370 "rotary_dim": 64,
371 "final_rms": True,
372 "gated_mlp": True,
373 "rotary_base": 500000.0,
374 "use_NTK_by_parts_rope": True,
375 "NTK_by_parts_low_freq_factor": 1.0,
376 "NTK_by_parts_high_freq_factor": 4.0,
377 "NTK_by_parts_factor": 32.0,
378 "NTK_original_ctx_len": 8192,
379 }
380 elif "Llama-3.2-3B" in official_model_name: 380 ↛ 381line 380 didn't jump to line 381 because the condition on line 380 was never true
381 cfg_dict = {
382 "d_model": 3072,
383 "d_head": 128,
384 "n_heads": 24,
385 "d_mlp": 8192,
386 "n_layers": 28,
387 "n_ctx": 2048, # capped due to memory issues
388 "eps": 1e-5,
389 "d_vocab": 128256,
390 "act_fn": "silu",
391 "n_key_value_heads": 8,
392 "normalization_type": "RMS",
393 "positional_embedding_type": "rotary",
394 "rotary_adjacent_pairs": False,
395 "rotary_dim": 128,
396 "final_rms": True,
397 "gated_mlp": True,
398 "rotary_base": 500000.0,
399 "use_NTK_by_parts_rope": True,
400 "NTK_by_parts_low_freq_factor": 1.0,
401 "NTK_by_parts_high_freq_factor": 4.0,
402 "NTK_by_parts_factor": 32.0,
403 "NTK_original_ctx_len": 8192,
404 }
405 elif "Llama-3.3-70B" in official_model_name: 405 ↛ 406line 405 didn't jump to line 406 because the condition on line 405 was never true
406 cfg_dict = {
407 "d_model": 8192,
408 "d_head": 128,
409 "n_heads": 64,
410 "d_mlp": 28672,
411 "n_layers": 80,
412 "n_ctx": 2048, # capped due to memory issues
413 "eps": 1e-5,
414 "d_vocab": 128256,
415 "act_fn": "silu",
416 "n_key_value_heads": 8,
417 "normalization_type": "RMS",
418 "positional_embedding_type": "rotary",
419 "rotary_adjacent_pairs": False,
420 "rotary_dim": 128,
421 "final_rms": True,
422 "gated_mlp": True,
423 "rotary_base": 500000.0,
424 "use_NTK_by_parts_rope": True,
425 "NTK_by_parts_low_freq_factor": 1.0,
426 "NTK_by_parts_high_freq_factor": 4.0,
427 "NTK_by_parts_factor": 8.0,
428 "NTK_original_ctx_len": 8192,
429 }
430 elif "Llama-3.1-8B" in official_model_name: 430 ↛ 431line 430 didn't jump to line 431 because the condition on line 430 was never true
431 cfg_dict = {
432 "d_model": 4096,
433 "d_head": 128,
434 "n_heads": 32,
435 "d_mlp": 14336,
436 "n_layers": 32,
437 "n_ctx": 2048, # capped due to memory issues
438 "eps": 1e-5,
439 "d_vocab": 128256,
440 "act_fn": "silu",
441 "n_key_value_heads": 8,
442 "normalization_type": "RMS",
443 "positional_embedding_type": "rotary",
444 "rotary_adjacent_pairs": False,
445 "rotary_dim": 128,
446 "final_rms": True,
447 "gated_mlp": True,
448 "rotary_base": 500000.0,
449 "use_NTK_by_parts_rope": True,
450 "NTK_by_parts_low_freq_factor": 1.0,
451 "NTK_by_parts_high_freq_factor": 4.0,
452 "NTK_by_parts_factor": 8.0,
453 "NTK_original_ctx_len": 8192,
454 }
455 elif "Llama-3.1-70B" in official_model_name: 455 ↛ 456line 455 didn't jump to line 456 because the condition on line 455 was never true
456 cfg_dict = {
457 "d_model": 8192,
458 "d_head": 128,
459 "n_heads": 64,
460 "d_mlp": 28672,
461 "n_layers": 80,
462 "n_ctx": 2048, # capped due to memory issues
463 "eps": 1e-5,
464 "d_vocab": 128256,
465 "act_fn": "silu",
466 "n_key_value_heads": 8,
467 "normalization_type": "RMS",
468 "positional_embedding_type": "rotary",
469 "rotary_adjacent_pairs": False,
470 "rotary_dim": 128,
471 "final_rms": True,
472 "gated_mlp": True,
473 "rotary_base": 500000.0,
474 "use_NTK_by_parts_rope": True,
475 "NTK_by_parts_low_freq_factor": 1.0,
476 "NTK_by_parts_high_freq_factor": 4.0,
477 "NTK_by_parts_factor": 8.0,
478 "NTK_original_ctx_len": 8192,
479 }
480 elif architecture == "GPTNeoForCausalLM":
481 cfg_dict = {
482 "d_model": hf_config.hidden_size,
483 "d_head": hf_config.hidden_size // hf_config.num_heads,
484 "n_heads": hf_config.num_heads,
485 "d_mlp": hf_config.hidden_size * 4,
486 "n_layers": hf_config.num_layers,
487 "n_ctx": hf_config.max_position_embeddings,
488 "eps": hf_config.layer_norm_epsilon,
489 "d_vocab": hf_config.vocab_size,
490 "attn_types": hf_config.attention_layers,
491 "act_fn": hf_config.activation_function,
492 "use_attn_scale": False,
493 "use_local_attn": True,
494 "window_size": hf_config.window_size,
495 "scale_attn_by_inverse_layer_idx": False,
496 "normalization_type": "LN",
497 }
498 elif architecture == "GPT2LMHeadModel":
499 cfg_dict = {
500 "d_model": hf_config.n_embd,
501 "d_head": hf_config.n_embd // hf_config.n_head,
502 "n_heads": hf_config.n_head,
503 "d_mlp": hf_config.n_embd * 4,
504 "n_layers": hf_config.n_layer,
505 "n_ctx": hf_config.n_ctx,
506 "eps": hf_config.layer_norm_epsilon,
507 "d_vocab": hf_config.vocab_size,
508 "act_fn": hf_config.activation_function,
509 "use_attn_scale": getattr(hf_config, "scale_attn_weights", True),
510 "use_local_attn": False,
511 "scale_attn_by_inverse_layer_idx": hf_config.scale_attn_by_inverse_layer_idx,
512 "normalization_type": "LN",
513 }
514 elif architecture == "OPTForCausalLM":
515 cfg_dict = {
516 "d_model": hf_config.hidden_size,
517 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
518 "n_heads": hf_config.num_attention_heads,
519 "d_mlp": hf_config.ffn_dim,
520 "n_layers": hf_config.num_hidden_layers,
521 "n_ctx": hf_config.max_position_embeddings,
522 "eps": 1e-5,
523 "d_vocab": hf_config.vocab_size,
524 "act_fn": hf_config.activation_function,
525 "use_attn_scale": True,
526 "use_local_attn": False,
527 "scale_attn_by_inverse_layer_idx": False,
528 "normalization_type": "LN",
529 }
530 elif architecture == "GPTJForCausalLM":
531 cfg_dict = {
532 "d_model": hf_config.n_embd,
533 "d_head": hf_config.n_embd // hf_config.n_head,
534 "n_heads": hf_config.n_head,
535 "d_mlp": 4 * hf_config.n_embd,
536 "n_layers": hf_config.n_layer,
537 "n_ctx": hf_config.n_positions,
538 "eps": 1e-5,
539 "d_vocab": hf_config.vocab_size,
540 "act_fn": hf_config.activation_function,
541 "use_attn_scale": True,
542 "use_local_attn": False,
543 "scale_attn_by_inverse_layer_idx": False,
544 "parallel_attn_mlp": True,
545 "positional_embedding_type": "rotary",
546 "rotary_dim": hf_config.rotary_dim,
547 "rotary_adjacent_pairs": True,
548 "normalization_type": "LN",
549 }
550 elif architecture == "GPTNeoXForCausalLM":
551 cfg_dict = {
552 "d_model": hf_config.hidden_size,
553 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
554 "n_heads": hf_config.num_attention_heads,
555 "d_mlp": hf_config.intermediate_size,
556 "n_layers": hf_config.num_hidden_layers,
557 "n_ctx": hf_config.max_position_embeddings,
558 "eps": hf_config.layer_norm_eps,
559 "d_vocab": hf_config.vocab_size,
560 "act_fn": hf_config.hidden_act,
561 "use_attn_scale": True,
562 "use_local_attn": False,
563 "scale_attn_by_inverse_layer_idx": False,
564 # GPTNeoX ships sequential variants too (use_parallel_residual=False).
565 "parallel_attn_mlp": getattr(hf_config, "use_parallel_residual", True),
566 "positional_embedding_type": "rotary",
567 "rotary_adjacent_pairs": False,
568 "normalization_type": "LN",
569 "default_prepend_bos": False,
570 }
571 rotary_pct = get_rotary_pct_from_config(hf_config)
572 cfg_dict["rotary_dim"] = round(rotary_pct * cfg_dict["d_head"])
573 elif architecture == "HubertModel":
574 # Basic transformer configuration
575 cfg_dict = {
576 "d_model": hf_config.hidden_size,
577 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
578 "n_heads": hf_config.num_attention_heads,
579 "d_mlp": hf_config.intermediate_size,
580 "n_layers": hf_config.num_hidden_layers,
581 # HuBERT operates on audio frames, not tokens — n_ctx is flexible
582 "n_ctx": getattr(hf_config, "max_position_embeddings", 8192),
583 "eps": hf_config.layer_norm_eps,
584 "act_fn": getattr(hf_config, "hidden_act", "gelu"),
585 "attention_dir": "bidirectional",
586 "d_vocab": -1, # no text vocabulary
587 }
588 elif "wav2vec2-base" in official_model_name or "wav2vec2-large" in official_model_name: 588 ↛ 590line 588 didn't jump to line 590 because the condition on line 588 was never true
589 # Basic transformer configuration
590 cfg_dict = {
591 "d_model": hf_config.hidden_size,
592 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
593 "n_heads": hf_config.num_attention_heads,
594 "d_mlp": hf_config.intermediate_size,
595 "n_layers": hf_config.num_hidden_layers,
596 # HuBERT operates on audio frames, not tokens — n_ctx is flexible
597 "n_ctx": getattr(hf_config, "max_position_embeddings", 8192),
598 "eps": hf_config.layer_norm_eps,
599 "act_fn": getattr(hf_config, "hidden_act", "gelu"),
600 "attention_dir": "bidirectional",
601 "d_vocab": -1, # no text vocabulary
602 }
603 elif architecture == "HubertForCTC": 603 ↛ 605line 603 didn't jump to line 605 because the condition on line 603 was never true
604 # Basic transformer configuration
605 cfg_dict = {
606 "d_model": hf_config.hidden_size,
607 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
608 "n_heads": hf_config.num_attention_heads,
609 "d_mlp": hf_config.intermediate_size,
610 "n_layers": hf_config.num_hidden_layers,
611 "n_ctx": getattr(hf_config, "max_position_embeddings", 8192),
612 "eps": hf_config.layer_norm_eps,
613 "act_fn": getattr(hf_config, "hidden_act", "gelu"),
614 "attention_dir": "bidirectional",
615 # For CTC models:
616 "d_vocab": hf_config.vocab_size, # text vocab from tokenizer
617 }
618 elif architecture == "BertForMaskedLM":
619 # All supported Bert architectures have the same config,
620 # so we can use the BertForMaskedLM config for all of them
621 cfg_dict = {
622 "d_model": hf_config.hidden_size,
623 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
624 "n_heads": hf_config.num_attention_heads,
625 "d_mlp": hf_config.intermediate_size,
626 "n_layers": hf_config.num_hidden_layers,
627 "n_ctx": hf_config.max_position_embeddings,
628 "eps": hf_config.layer_norm_eps,
629 "d_vocab": hf_config.vocab_size,
630 "act_fn": "gelu",
631 "attention_dir": "bidirectional",
632 }
633 elif architecture == "MistralForCausalLM": 633 ↛ 634line 633 didn't jump to line 634 because the condition on line 633 was never true
634 use_local_attn = True if hf_config.sliding_window else False
635 cfg_dict = {
636 "d_model": hf_config.hidden_size,
637 "d_head": (
638 hf_config.head_dim
639 if hasattr(hf_config, "head_dim")
640 and hf_config.head_dim is not None
641 and hf_config.head_dim > 0
642 else hf_config.hidden_size // hf_config.num_attention_heads
643 ),
644 "n_heads": hf_config.num_attention_heads,
645 "d_mlp": hf_config.intermediate_size,
646 "n_layers": hf_config.num_hidden_layers,
647 "n_ctx": 2048, # Capped due to memory issues
648 "d_vocab": hf_config.vocab_size,
649 "act_fn": hf_config.hidden_act,
650 "window_size": hf_config.sliding_window, # None if no sliding window was used
651 "attn_types": ["local"] * hf_config.num_hidden_layers if use_local_attn else None,
652 "eps": hf_config.rms_norm_eps,
653 "rotary_base": _get_rope_theta(hf_config),
654 "n_key_value_heads": hf_config.num_key_value_heads,
655 "use_local_attn": use_local_attn,
656 "normalization_type": "RMS",
657 "positional_embedding_type": "rotary",
658 "gated_mlp": True,
659 }
660 elif architecture == "MixtralForCausalLM":
661 cfg_dict = {
662 "dtype": torch.bfloat16,
663 "d_model": hf_config.hidden_size,
664 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
665 "n_heads": hf_config.num_attention_heads,
666 "d_mlp": hf_config.intermediate_size,
667 "n_layers": hf_config.num_hidden_layers,
668 "n_ctx": hf_config.max_position_embeddings, # Capped due to memory issues
669 "d_vocab": hf_config.vocab_size,
670 "act_fn": hf_config.hidden_act,
671 "normalization_type": "RMS",
672 "positional_embedding_type": "rotary",
673 "rotary_base": _get_rope_theta(hf_config),
674 # None on the released 8x7B, but a variant that sets it must window.
675 "window_size": hf_config.sliding_window,
676 "attn_types": (
677 ["local" if hf_config.sliding_window else "global"] * hf_config.num_hidden_layers
678 ),
679 "eps": hf_config.rms_norm_eps,
680 "n_key_value_heads": hf_config.num_key_value_heads,
681 "gated_mlp": True,
682 "use_local_attn": bool(hf_config.sliding_window),
683 "rotary_dim": hf_config.hidden_size // hf_config.num_attention_heads,
684 "num_experts": hf_config.num_local_experts,
685 "experts_per_token": hf_config.num_experts_per_tok,
686 # MixtralTopKRouter renormalizes the top-k weights unconditionally
687 # (modeling_mixtral.py: `router_top_value /= router_top_value.sum(...)`),
688 # and MixtralConfig has no norm_topk_prob field to read it from — so
689 # this is pinned to HF's behavior rather than sourced from the config.
690 # TL's MoE skips the renormalization unless this is set, which would
691 # leave routing weights unnormalized and the outputs silently wrong.
692 "norm_topk_prob": True,
693 }
694 elif architecture == "GptOssForCausalLM":
695 cfg_dict = {
696 "dtype": torch.bfloat16,
697 "d_model": hf_config.hidden_size,
698 "d_head": hf_config.head_dim,
699 "n_heads": hf_config.num_attention_heads,
700 "d_mlp": hf_config.intermediate_size,
701 "n_layers": hf_config.num_hidden_layers,
702 "n_ctx": hf_config.max_position_embeddings,
703 "d_vocab": hf_config.vocab_size,
704 "act_fn": hf_config.hidden_act,
705 "normalization_type": "RMS",
706 "positional_embedding_type": "rotary",
707 "rotary_base": _get_rope_theta(hf_config),
708 "eps": hf_config.rms_norm_eps,
709 "n_key_value_heads": hf_config.num_key_value_heads,
710 "gated_mlp": True,
711 "final_rms": True,
712 "rotary_dim": hf_config.head_dim,
713 "num_experts": hf_config.num_local_experts,
714 "experts_per_token": hf_config.num_experts_per_tok,
715 "use_attention_sinks": True,
716 # Alternating sliding_attention / full_attention layers; HT's local
717 # attention mask (last window_size keys) matches HF's sliding window.
718 "use_local_attn": True,
719 "window_size": hf_config.sliding_window,
720 "attn_types": [
721 "local" if layer_type == "sliding_attention" else "global"
722 for layer_type in hf_config.layer_types
723 ],
724 }
725 rope_params = getattr(hf_config, "rope_parameters", None) or {}
726 if rope_params.get("rope_type") == "yarn": 726 ↛ 1642line 726 didn't jump to line 1642 because the condition on line 726 was always true
727 yarn_factor = rope_params["factor"]
728 attention_factor = rope_params.get("attention_factor")
729 if attention_factor is None: 729 ↛ 732line 729 didn't jump to line 732 because the condition on line 729 was always true
730 # HF's default: get_mscale(factor) = 0.1 * ln(factor) + 1
731 attention_factor = 0.1 * math.log(yarn_factor) + 1.0 if yarn_factor > 1 else 1.0
732 cfg_dict.update(
733 {
734 "use_yarn_rope": True,
735 "yarn_factor": float(yarn_factor),
736 "yarn_attention_factor": float(attention_factor),
737 "yarn_beta_fast": float(rope_params.get("beta_fast") or 32.0),
738 "yarn_beta_slow": float(rope_params.get("beta_slow") or 1.0),
739 "yarn_original_max_position_embeddings": rope_params[
740 "original_max_position_embeddings"
741 ],
742 "yarn_truncate": rope_params.get("truncate", True),
743 }
744 )
745 elif architecture == "BloomForCausalLM":
746 cfg_dict = {
747 "d_model": hf_config.hidden_size,
748 "d_head": hf_config.hidden_size // hf_config.n_head,
749 "n_heads": hf_config.n_head,
750 "d_mlp": hf_config.hidden_size * 4,
751 "n_layers": hf_config.n_layer,
752 "n_ctx": 2048, # Capped due to HF Tokenizer Constraints
753 "d_vocab": hf_config.vocab_size,
754 "act_fn": "gelu_fast",
755 "eps": hf_config.layer_norm_epsilon,
756 "normalization_type": "LN",
757 "post_embedding_ln": True,
758 "positional_embedding_type": "alibi",
759 "default_prepend_bos": False,
760 }
761 elif architecture == "GPT2LMHeadCustomModel": 761 ↛ 763line 761 didn't jump to line 763 because the condition on line 761 was never true
762 # santacoder
763 cfg_dict = {
764 "d_model": hf_config.n_embd,
765 "d_head": hf_config.n_embd // hf_config.n_head,
766 "n_heads": hf_config.n_head,
767 "d_mlp": hf_config.n_embd * 4,
768 "n_layers": hf_config.n_layer,
769 "n_ctx": hf_config.n_positions,
770 "eps": hf_config.layer_norm_epsilon,
771 "d_vocab": hf_config.vocab_size,
772 "act_fn": hf_config.activation_function,
773 "use_attn_scale": True,
774 "use_local_attn": False,
775 "trust_remote_code": "santacoder"
776 in official_model_name, # Only santacoder needs trust_remote_code
777 "scale_attn_by_inverse_layer_idx": hf_config.scale_attn_by_inverse_layer_idx,
778 "normalization_type": "LN",
779 }
780 elif architecture == "LlamaForCausalLM":
781 cfg_dict = {
782 "d_model": hf_config.hidden_size,
783 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
784 "n_heads": hf_config.num_attention_heads,
785 "d_mlp": hf_config.intermediate_size,
786 "n_layers": hf_config.num_hidden_layers,
787 "n_ctx": hf_config.max_position_embeddings,
788 "eps": hf_config.rms_norm_eps,
789 "d_vocab": hf_config.vocab_size,
790 "act_fn": hf_config.hidden_act,
791 "n_key_value_heads": (
792 hf_config.num_key_value_heads
793 if hf_config.num_key_value_heads != hf_config.num_attention_heads
794 else None
795 ),
796 # This is done because the current implementation of GQA will use Grouped-Query Attention if
797 # n_key_value_heads is not None, but hf_config.num_key_value_heads is sometimes specified as
798 # the same as hf_config.num_attention_heads, in which case GQA should not be used.
799 "normalization_type": "RMS",
800 "positional_embedding_type": "rotary",
801 "rotary_adjacent_pairs": False,
802 "rotary_dim": hf_config.hidden_size // hf_config.num_attention_heads,
803 # Llama-arch checkpoints without a name-matched branch above (Yi ships
804 # 5e6) reach here; the config default would silently be 10000.
805 "rotary_base": _get_rope_theta(hf_config),
806 "final_rms": True,
807 "gated_mlp": True,
808 }
809 _apply_llama3_rope_scaling(cfg_dict, hf_config)
810 elif architecture == "QWenLMHeadModel":
811 cfg_dict = {
812 "d_model": hf_config.hidden_size,
813 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
814 "n_heads": hf_config.num_attention_heads,
815 "d_mlp": hf_config.intermediate_size // 2,
816 "n_layers": hf_config.num_hidden_layers,
817 # QWenLMHeadModel uses seq_length in its remote-code attention/rotary logic.
818 "n_ctx": hf_config.seq_length,
819 "use_logn_attn": getattr(hf_config, "use_logn_attn", False),
820 "use_dynamic_ntk_rope": getattr(hf_config, "use_dynamic_ntk", False),
821 "train_seq_length": hf_config.seq_length,
822 "eps": hf_config.layer_norm_epsilon,
823 "d_vocab": hf_config.vocab_size,
824 "act_fn": "silu",
825 "use_attn_scale": hf_config.scale_attn_weights,
826 "initializer_range": hf_config.initializer_range,
827 "normalization_type": "RMS",
828 "positional_embedding_type": "rotary",
829 "rotary_dim": hf_config.kv_channels,
830 "rotary_adjacent_pairs": False,
831 "tokenizer_prepends_bos": True,
832 "trust_remote_code": True,
833 "final_rms": True,
834 "gated_mlp": True,
835 "default_prepend_bos": False,
836 }
837 elif architecture == "Qwen2ForCausalLM":
838 # Note that Qwen1.5 models have architecture type Qwen2ForCausalLM.
839 cfg_dict = {
840 "d_model": hf_config.hidden_size,
841 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
842 "n_heads": hf_config.num_attention_heads,
843 "n_key_value_heads": hf_config.num_key_value_heads,
844 "d_mlp": hf_config.intermediate_size,
845 "n_layers": hf_config.num_hidden_layers,
846 "n_ctx": hf_config.max_position_embeddings,
847 "eps": hf_config.rms_norm_eps,
848 "d_vocab": hf_config.vocab_size,
849 "act_fn": hf_config.hidden_act,
850 "use_attn_scale": True,
851 "initializer_range": hf_config.initializer_range,
852 "normalization_type": "RMS",
853 "positional_embedding_type": "rotary",
854 "rotary_base": int(_get_rope_theta(hf_config)),
855 "rotary_adjacent_pairs": False,
856 "rotary_dim": hf_config.hidden_size // hf_config.num_attention_heads,
857 "tokenizer_prepends_bos": True,
858 "final_rms": True,
859 "gated_mlp": True,
860 "default_prepend_bos": False,
861 }
862 elif architecture == "Qwen3ForCausalLM": 862 ↛ 863line 862 didn't jump to line 863 because the condition on line 862 was never true
863 cfg_dict = {
864 "d_model": hf_config.hidden_size,
865 "d_head": hf_config.head_dim
866 if hasattr(hf_config, "head_dim")
867 and hf_config.head_dim is not None
868 and hf_config.head_dim > 0
869 else hf_config.hidden_size // hf_config.num_attention_heads,
870 "n_heads": hf_config.num_attention_heads,
871 "n_key_value_heads": (
872 hf_config.num_key_value_heads
873 if hf_config.num_key_value_heads != hf_config.num_attention_heads
874 else None
875 ),
876 "d_mlp": hf_config.intermediate_size,
877 "n_layers": hf_config.num_hidden_layers,
878 "n_ctx": 2048,
879 "eps": hf_config.rms_norm_eps,
880 "d_vocab": hf_config.vocab_size,
881 "act_fn": hf_config.hidden_act,
882 "use_attn_scale": True,
883 "initializer_range": hf_config.initializer_range,
884 "normalization_type": "RMS",
885 "positional_embedding_type": "rotary",
886 "rotary_base": int(_get_rope_theta(hf_config)),
887 "rotary_adjacent_pairs": False,
888 "rotary_dim": hf_config.head_dim
889 if hasattr(hf_config, "head_dim") and hf_config.head_dim > 0
890 else hf_config.hidden_size // hf_config.num_attention_heads,
891 "tokenizer_prepends_bos": True,
892 "final_rms": True,
893 "gated_mlp": True,
894 "default_prepend_bos": False,
895 "use_qk_norm": True,
896 "trust_remote_code": True,
897 }
898 elif architecture == "PhiForCausalLM": 898 ↛ 900line 898 didn't jump to line 900 because the condition on line 898 was never true
899 # Architecture for microsoft/phi models
900 cfg_dict = {
901 "d_model": hf_config.hidden_size,
902 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
903 "n_heads": hf_config.num_attention_heads,
904 "d_mlp": hf_config.intermediate_size,
905 "n_layers": hf_config.num_hidden_layers,
906 "n_ctx": hf_config.max_position_embeddings,
907 "eps": hf_config.layer_norm_eps,
908 "d_vocab": hf_config.vocab_size,
909 "act_fn": hf_config.hidden_act,
910 "initializer_range": hf_config.initializer_range,
911 "normalization_type": "LN",
912 "positional_embedding_type": "rotary",
913 "trust_remote_code": True,
914 "rotary_base": _get_rope_theta(hf_config),
915 "use_attn_scale": True,
916 "parallel_attn_mlp": True,
917 "default_prepend_bos": False,
918 }
919 partial_rotary_factor = hf_config.partial_rotary_factor
920 cfg_dict["rotary_dim"] = round(partial_rotary_factor * cfg_dict["d_head"])
921 elif architecture == "Phi3ForCausalLM":
922 # Architecture for microsoft/phi3 models
923 cfg_dict = {
924 "d_model": hf_config.hidden_size,
925 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
926 "n_heads": hf_config.num_attention_heads,
927 "d_mlp": hf_config.intermediate_size,
928 "n_layers": hf_config.num_hidden_layers,
929 "n_key_value_heads": (
930 hf_config.num_key_value_heads
931 if hf_config.num_key_value_heads != hf_config.num_attention_heads
932 else None
933 ),
934 "n_ctx": hf_config.max_position_embeddings,
935 "eps": hf_config.rms_norm_eps,
936 "d_vocab": hf_config.vocab_size,
937 "act_fn": hf_config.hidden_act,
938 "initializer_range": hf_config.initializer_range,
939 "normalization_type": "RMS",
940 "positional_embedding_type": "rotary",
941 "rotary_base": _get_rope_theta(hf_config),
942 "use_attn_scale": True,
943 "gated_mlp": True,
944 "parallel_attn_mlp": False,
945 "rotary_dim": hf_config.hidden_size // hf_config.num_attention_heads,
946 # Phi-3-mini-4k ships sliding_window=2047 inside its 4096 n_ctx, and
947 # HF windows every layer (no layer_types).
948 "window_size": getattr(hf_config, "sliding_window", None),
949 "use_local_attn": bool(getattr(hf_config, "sliding_window", None)),
950 "attn_types": (
951 ["local"] * hf_config.num_hidden_layers
952 if getattr(hf_config, "sliding_window", None)
953 else None
954 ),
955 }
956 elif architecture == "ApertusForCausalLM":
957 n_heads = hf_config.num_attention_heads
958 d_head = hf_config.hidden_size // n_heads
959 num_kv_heads = getattr(hf_config, "num_key_value_heads", n_heads)
960 n_kv_heads = num_kv_heads if num_kv_heads != n_heads else None
961 cfg_dict = {
962 "d_model": hf_config.hidden_size,
963 "d_head": d_head,
964 "n_heads": n_heads,
965 "n_key_value_heads": n_kv_heads,
966 "d_mlp": hf_config.intermediate_size,
967 "n_layers": hf_config.num_hidden_layers,
968 "n_ctx": hf_config.max_position_embeddings,
969 "eps": hf_config.rms_norm_eps,
970 "d_vocab": hf_config.vocab_size,
971 "act_fn": hf_config.hidden_act,
972 "normalization_type": "RMS",
973 "positional_embedding_type": "rotary",
974 "rotary_dim": d_head,
975 "rotary_base": _get_rope_theta(hf_config),
976 "gated_mlp": False,
977 "final_rms": True,
978 "use_qk_norm": True, # HF applies q_norm/k_norm unconditionally; no config gate exists
979 }
980 rope_scaling = getattr(hf_config, "rope_scaling", None)
981 if rope_scaling:
982 rope_type = (rope_scaling.get("type") or rope_scaling.get("rope_type") or "").lower()
983 else:
984 rope_type = ""
985 if rope_type == "llama3":
986 assert rope_scaling is not None
987 cfg_dict["use_NTK_by_parts_rope"] = True
988 cfg_dict["NTK_original_ctx_len"] = rope_scaling.get(
989 "original_max_position_embeddings", hf_config.max_position_embeddings
990 )
991 cfg_dict["NTK_by_parts_low_freq_factor"] = rope_scaling.get("low_freq_factor", 1.0)
992 cfg_dict["NTK_by_parts_high_freq_factor"] = rope_scaling.get("high_freq_factor", 4.0)
993 cfg_dict["NTK_by_parts_factor"] = rope_scaling.get("factor", 1.0)
995 elif official_model_name.startswith("google/gemma-2b"): 995 ↛ 997line 995 didn't jump to line 997 because the condition on line 995 was never true
996 # Architecture for Gemma 2b and Gemma 2b Instruct models
997 cfg_dict = {
998 "d_model": 2048,
999 "d_head": 256,
1000 "n_heads": 8,
1001 "d_mlp": 16384,
1002 "n_layers": 18,
1003 "n_ctx": 8192,
1004 "eps": 1e-06,
1005 "d_vocab": 256000,
1006 "act_fn": "gelu",
1007 "initializer_range": 0.02,
1008 "normalization_type": "RMS",
1009 "rotary_base": 10000,
1010 "rotary_dim": 256,
1011 "positional_embedding_type": "rotary",
1012 "use_attn_scale": True,
1013 "n_key_value_heads": 1,
1014 "gated_mlp": True,
1015 "final_rms": True,
1016 }
1017 elif official_model_name.startswith("google/gemma-7b"): 1017 ↛ 1019line 1017 didn't jump to line 1019 because the condition on line 1017 was never true
1018 # Architecture for Gemma 7b and Gemma 7b Instruct models
1019 cfg_dict = {
1020 "d_model": 3072,
1021 "d_head": 256,
1022 "n_heads": 16,
1023 "d_mlp": 24576,
1024 "n_layers": 28,
1025 "n_ctx": 8192,
1026 "eps": 1e-06,
1027 "d_vocab": 256000,
1028 "act_fn": "gelu",
1029 "initializer_range": 0.02,
1030 "normalization_type": "RMS",
1031 "rotary_base": 10000.0,
1032 "rotary_dim": 256,
1033 "positional_embedding_type": "rotary",
1034 "use_attn_scale": True,
1035 "n_key_value_heads": 16,
1036 "gated_mlp": True,
1037 "final_rms": True,
1038 }
1039 elif official_model_name.startswith("google/gemma-2-2b"):
1040 # Architecture for Gemma-2 2b and Gemma-2 2b Instruct models
1041 cfg_dict = {
1042 "d_model": 2304,
1043 "d_head": 256,
1044 "n_heads": 8,
1045 "d_mlp": 9216,
1046 "n_layers": 26,
1047 "n_ctx": 8192,
1048 "eps": 1e-06,
1049 "d_vocab": 256000,
1050 "act_fn": "gelu_pytorch_tanh",
1051 "initializer_range": 0.02,
1052 "normalization_type": "RMS",
1053 "rotary_base": 10000.0,
1054 "positional_embedding_type": "rotary",
1055 "use_attn_scale": True,
1056 "n_key_value_heads": 4,
1057 "window_size": 4096,
1058 "use_local_attn": True,
1059 "attn_types": ["local", "global"] * 13, # HF makes even layers sliding
1060 "attn_scores_soft_cap": 50.0,
1061 "output_logits_soft_cap": 30.0,
1062 "gated_mlp": True,
1063 "final_rms": True,
1064 "use_normalization_before_and_after": True,
1065 }
1066 elif official_model_name.startswith("google/gemma-2-9b"):
1067 # Architecture for Gemma-2 9b and Gemma-2 9b Instruct models
1068 cfg_dict = {
1069 "d_model": 3584,
1070 "d_head": 256,
1071 "n_heads": 16,
1072 "d_mlp": 14336,
1073 "n_layers": 42,
1074 "n_ctx": 8192,
1075 "eps": 1e-06,
1076 "d_vocab": 256000,
1077 "act_fn": "gelu_pytorch_tanh",
1078 "initializer_range": 0.02,
1079 "normalization_type": "RMS",
1080 "rotary_base": 10000.0,
1081 "positional_embedding_type": "rotary",
1082 "use_attn_scale": True,
1083 "n_key_value_heads": 8,
1084 "window_size": 4096,
1085 "use_local_attn": True,
1086 "attn_types": ["local", "global"] * 21, # HF makes even layers sliding
1087 "attn_scores_soft_cap": 50.0,
1088 "output_logits_soft_cap": 30.0,
1089 "gated_mlp": True,
1090 "final_rms": True,
1091 "use_normalization_before_and_after": True,
1092 }
1093 elif official_model_name.startswith("google/gemma-2-27b"):
1094 # Architecture for Gemma-2 27b and Gemma-2 27b Instruct models
1095 cfg_dict = {
1096 "d_model": 4608,
1097 "d_head": 128,
1098 "n_heads": 32,
1099 "d_mlp": 36864,
1100 "n_layers": 46,
1101 "n_ctx": 8192,
1102 "eps": 1e-06,
1103 "d_vocab": 256000,
1104 "act_fn": "gelu_pytorch_tanh",
1105 "initializer_range": 0.02,
1106 "normalization_type": "RMS",
1107 "rotary_base": 10000.0,
1108 "positional_embedding_type": "rotary",
1109 "use_attn_scale": True,
1110 "attn_scale": 12.0,
1111 "n_key_value_heads": 16,
1112 "window_size": 4096,
1113 "use_local_attn": True,
1114 "attn_types": ["local", "global"] * 23, # HF makes even layers sliding
1115 "attn_scores_soft_cap": 50.0,
1116 "output_logits_soft_cap": 30.0,
1117 "gated_mlp": True,
1118 "final_rms": True,
1119 "use_normalization_before_and_after": True,
1120 }
1121 elif official_model_name.startswith("google/gemma-3-270m"):
1122 # Architecture for Gemma-3 270m and Gemma-3 270m Instruct models
1123 cfg_dict = {
1124 "d_model": 640,
1125 "d_head": 256,
1126 "n_heads": 4,
1127 "d_mlp": 2048,
1128 "n_layers": 18,
1129 "n_ctx": 8192, # Safe default (model supports up to 32K). Override: cfg_kwargs={"n_ctx": 32768}
1130 "eps": 1e-06,
1131 "d_vocab": 262144,
1132 "act_fn": "gelu_pytorch_tanh",
1133 "initializer_range": 0.02,
1134 "normalization_type": "RMS",
1135 "rotary_base": 1000000, # Global attention layers
1136 "rotary_base_local": 10000, # Local attention layers (per Gemma 3 paper)
1137 "positional_embedding_type": "rotary",
1138 "use_attn_scale": True,
1139 "n_key_value_heads": 1,
1140 "gated_mlp": True,
1141 "final_rms": True,
1142 "use_normalization_before_and_after": True,
1143 "use_qk_norm": True,
1144 "window_size": 512,
1145 "use_local_attn": True,
1146 "attn_types": [
1147 "local",
1148 "local",
1149 "local",
1150 "local",
1151 "local",
1152 "global",
1153 "local",
1154 "local",
1155 "local",
1156 "local",
1157 "local",
1158 "global",
1159 "local",
1160 "local",
1161 "local",
1162 "local",
1163 "local",
1164 "global",
1165 ],
1166 }
1167 elif official_model_name.startswith("google/gemma-3-1b"):
1168 # Architecture for Gemma-3 1b-pt and Gemma-3 1b-it models
1169 cfg_dict = {
1170 "d_model": 1152,
1171 "d_head": 256,
1172 "n_heads": 4,
1173 "d_mlp": 6912,
1174 "n_layers": 26,
1175 "n_ctx": 8192, # Safe default (model supports up to 32K). Override: cfg_kwargs={"n_ctx": 32768}
1176 "eps": 1e-06,
1177 "d_vocab": 262144,
1178 "act_fn": "gelu_pytorch_tanh",
1179 "initializer_range": 0.02,
1180 "normalization_type": "RMS",
1181 "rotary_base": 1000000, # Global attention layers
1182 "rotary_base_local": 10000, # Local attention layers (per Gemma 3 paper)
1183 "positional_embedding_type": "rotary",
1184 "use_attn_scale": True,
1185 "n_key_value_heads": 1,
1186 "gated_mlp": True,
1187 "final_rms": True,
1188 "use_normalization_before_and_after": True,
1189 "use_qk_norm": True,
1190 "window_size": 512,
1191 "use_local_attn": True,
1192 "attn_types": [
1193 "local",
1194 "local",
1195 "local",
1196 "local",
1197 "local",
1198 "global",
1199 "local",
1200 "local",
1201 "local",
1202 "local",
1203 "local",
1204 "global",
1205 "local",
1206 "local",
1207 "local",
1208 "local",
1209 "local",
1210 "global",
1211 "local",
1212 "local",
1213 "local",
1214 "local",
1215 "local",
1216 "global",
1217 "local",
1218 "local",
1219 ],
1220 }
1221 elif official_model_name.startswith("google/gemma-3-4b") or official_model_name.startswith(
1222 "google/medgemma-4b"
1223 ):
1224 # Architecture for Gemma-3 4b and MedGemma 4b models (multimodal, text-only extraction)
1225 cfg_dict = {
1226 "d_model": 2560,
1227 "d_head": 256,
1228 "n_heads": 8,
1229 "d_mlp": 10240,
1230 "n_layers": 34,
1231 "n_ctx": 8192, # Safe default (model supports up to 128K). Override: cfg_kwargs={"n_ctx": 131072}
1232 "eps": 1e-06,
1233 "d_vocab": 262208,
1234 "act_fn": "gelu_pytorch_tanh",
1235 "initializer_range": 0.02,
1236 "normalization_type": "RMS",
1237 "rotary_base": 1000000, # Global attention layers
1238 "rotary_base_local": 10000, # Local attention layers (per Gemma 3 paper)
1239 "rotary_scaling_factor": 8.0, # Linear RoPE scaling for global layers
1240 "positional_embedding_type": "rotary",
1241 "use_attn_scale": True,
1242 "n_key_value_heads": 4,
1243 "gated_mlp": True,
1244 "final_rms": True,
1245 "use_normalization_before_and_after": True,
1246 "use_qk_norm": True,
1247 "window_size": 1024,
1248 "use_local_attn": True,
1249 "attn_types": [
1250 "local",
1251 "local",
1252 "local",
1253 "local",
1254 "local",
1255 "global",
1256 "local",
1257 "local",
1258 "local",
1259 "local",
1260 "local",
1261 "global",
1262 "local",
1263 "local",
1264 "local",
1265 "local",
1266 "local",
1267 "global",
1268 "local",
1269 "local",
1270 "local",
1271 "local",
1272 "local",
1273 "global",
1274 "local",
1275 "local",
1276 "local",
1277 "local",
1278 "local",
1279 "global",
1280 "local",
1281 "local",
1282 "local",
1283 "local",
1284 ],
1285 }
1286 elif official_model_name.startswith("google/gemma-3-12b"): 1286 ↛ 1288line 1286 didn't jump to line 1288 because the condition on line 1286 was never true
1287 # Architecture for Gemma-3 12b models (multimodal, text-only extraction)
1288 cfg_dict = {
1289 "d_model": 3840,
1290 "d_head": 256,
1291 "n_heads": 16,
1292 "d_mlp": 15360,
1293 "n_layers": 48,
1294 "n_ctx": 8192, # Safe default (model supports up to 128K). Override: cfg_kwargs={"n_ctx": 131072}
1295 "eps": 1e-06,
1296 "d_vocab": 262208,
1297 "act_fn": "gelu_pytorch_tanh",
1298 "initializer_range": 0.02,
1299 "normalization_type": "RMS",
1300 "rotary_base": 1000000, # Global attention layers
1301 "rotary_base_local": 10000, # Local attention layers (per Gemma 3 paper)
1302 "rotary_scaling_factor": 8.0, # Linear RoPE scaling for global layers
1303 "positional_embedding_type": "rotary",
1304 "use_attn_scale": True,
1305 "n_key_value_heads": 8,
1306 "gated_mlp": True,
1307 "final_rms": True,
1308 "use_normalization_before_and_after": True,
1309 "use_qk_norm": True,
1310 "window_size": 1024,
1311 "use_local_attn": True,
1312 "attn_types": [
1313 "local",
1314 "local",
1315 "local",
1316 "local",
1317 "local",
1318 "global",
1319 "local",
1320 "local",
1321 "local",
1322 "local",
1323 "local",
1324 "global",
1325 "local",
1326 "local",
1327 "local",
1328 "local",
1329 "local",
1330 "global",
1331 "local",
1332 "local",
1333 "local",
1334 "local",
1335 "local",
1336 "global",
1337 "local",
1338 "local",
1339 "local",
1340 "local",
1341 "local",
1342 "global",
1343 "local",
1344 "local",
1345 "local",
1346 "local",
1347 "local",
1348 "global",
1349 "local",
1350 "local",
1351 "local",
1352 "local",
1353 "local",
1354 "global",
1355 "local",
1356 "local",
1357 "local",
1358 "local",
1359 "local",
1360 "global",
1361 ],
1362 }
1363 elif official_model_name.startswith("google/gemma-3-27b") or official_model_name.startswith(
1364 "google/medgemma-27b"
1365 ):
1366 # Architecture for Gemma-3 27b and MedGemma 27b models (multimodal/text-only extraction)
1367 # Note: medgemma-27b-text-it uses Gemma3ForCausalLM (text-only), others use Gemma3ForConditionalGeneration
1368 cfg_dict = {
1369 "d_model": 5376,
1370 "d_head": 128,
1371 "n_heads": 32,
1372 "d_mlp": 21504,
1373 "n_layers": 62,
1374 "n_ctx": 8192, # Safe default (model supports up to 128K). Override: cfg_kwargs={"n_ctx": 131072}
1375 "eps": 1e-06,
1376 "d_vocab": (
1377 262144 if official_model_name == "google/medgemma-27b-text-it" else 262208
1378 ), # text-only variant uses 262144
1379 "act_fn": "gelu_pytorch_tanh",
1380 "initializer_range": 0.02,
1381 "normalization_type": "RMS",
1382 "rotary_base": 1000000, # Global attention layers
1383 "rotary_base_local": 10000, # Local attention layers (per Gemma 3 paper)
1384 "rotary_scaling_factor": 8.0, # Linear RoPE scaling for global layers
1385 "positional_embedding_type": "rotary",
1386 "use_attn_scale": True,
1387 "n_key_value_heads": 16,
1388 "gated_mlp": True,
1389 "final_rms": True,
1390 "use_normalization_before_and_after": True,
1391 "use_qk_norm": True,
1392 "window_size": 1024,
1393 "use_local_attn": True,
1394 "attn_types": [
1395 "local",
1396 "local",
1397 "local",
1398 "local",
1399 "local",
1400 "global",
1401 "local",
1402 "local",
1403 "local",
1404 "local",
1405 "local",
1406 "global",
1407 "local",
1408 "local",
1409 "local",
1410 "local",
1411 "local",
1412 "global",
1413 "local",
1414 "local",
1415 "local",
1416 "local",
1417 "local",
1418 "global",
1419 "local",
1420 "local",
1421 "local",
1422 "local",
1423 "local",
1424 "global",
1425 "local",
1426 "local",
1427 "local",
1428 "local",
1429 "local",
1430 "global",
1431 "local",
1432 "local",
1433 "local",
1434 "local",
1435 "local",
1436 "global",
1437 "local",
1438 "local",
1439 "local",
1440 "local",
1441 "local",
1442 "global",
1443 "local",
1444 "local",
1445 "local",
1446 "local",
1447 "local",
1448 "global",
1449 "local",
1450 "local",
1451 "local",
1452 "local",
1453 "local",
1454 "global",
1455 "local",
1456 "local",
1457 ],
1458 }
1459 elif official_model_name.startswith("allenai/OLMo-1B") and official_model_name.endswith("hf"): 1459 ↛ 1460line 1459 didn't jump to line 1460 because the condition on line 1459 was never true
1460 cfg_dict = {
1461 "d_model": 2048,
1462 "d_head": 128,
1463 "n_heads": 16,
1464 "d_mlp": 8192,
1465 "n_layers": 16,
1466 "n_ctx": 2048,
1467 "eps": 1e-05,
1468 "d_vocab": 50304,
1469 "act_fn": "silu",
1470 "initializer_range": 0.02,
1471 "normalization_type": "LN",
1472 "rotary_base": 10000.0,
1473 "attn_types": ["global"] * 16,
1474 "positional_embedding_type": "rotary",
1475 "gated_mlp": True,
1476 "clip_qkv": getattr(hf_config, "clip_qkv", None),
1477 }
1478 elif official_model_name.startswith("allenai/OLMo-7B") and official_model_name.endswith("hf"): 1478 ↛ 1479line 1478 didn't jump to line 1479 because the condition on line 1478 was never true
1479 cfg_dict = {
1480 "d_model": 4096,
1481 "d_head": 128,
1482 "n_heads": 32,
1483 "d_mlp": 11008,
1484 "n_layers": 32,
1485 "n_ctx": 2048,
1486 "eps": 1e-05,
1487 "d_vocab": 50304,
1488 "act_fn": "silu",
1489 "initializer_range": 0.02,
1490 "normalization_type": "LN",
1491 "rotary_base": 10000.0,
1492 "attn_types": ["global"] * 32,
1493 "positional_embedding_type": "rotary",
1494 "gated_mlp": True,
1495 "clip_qkv": getattr(hf_config, "clip_qkv", None),
1496 }
1497 elif official_model_name.startswith("allenai/OLMo-2-0425-1B"):
1498 cfg_dict = {
1499 "d_model": 2048,
1500 "d_head": 128,
1501 "n_heads": 16,
1502 "d_mlp": 8192,
1503 "n_layers": 16,
1504 "n_ctx": 4096,
1505 "eps": 1e-06,
1506 "d_vocab": 100352,
1507 "act_fn": "silu",
1508 "initializer_range": 0.02,
1509 "normalization_type": "RMS",
1510 "rotary_base": 500000.0,
1511 "attn_types": ["global"] * 16,
1512 "positional_embedding_type": "rotary",
1513 "gated_mlp": True,
1514 }
1515 elif official_model_name.startswith("allenai/OLMo-2-1124-7B"): 1515 ↛ 1516line 1515 didn't jump to line 1516 because the condition on line 1515 was never true
1516 cfg_dict = {
1517 "d_model": 4096,
1518 "d_head": 128,
1519 "n_heads": 32,
1520 "d_mlp": 11008,
1521 "n_layers": 32,
1522 "n_ctx": 4096,
1523 "eps": 1e-06,
1524 "d_vocab": 100352,
1525 "act_fn": "silu",
1526 "initializer_range": 0.02,
1527 "normalization_type": "RMS",
1528 "rotary_base": 500000.0,
1529 "attn_types": ["global"] * 32,
1530 "positional_embedding_type": "rotary",
1531 "gated_mlp": True,
1532 }
1533 elif architecture == "Olmo3ForCausalLM":
1534 cfg_dict = {
1535 "d_model": hf_config.hidden_size,
1536 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
1537 "n_heads": hf_config.num_attention_heads,
1538 "n_key_value_heads": hf_config.num_key_value_heads,
1539 "d_mlp": hf_config.intermediate_size,
1540 "n_layers": hf_config.num_hidden_layers,
1541 "n_ctx": hf_config.max_position_embeddings,
1542 "eps": hf_config.rms_norm_eps,
1543 "d_vocab": hf_config.vocab_size,
1544 "act_fn": hf_config.hidden_act,
1545 "initializer_range": hf_config.initializer_range,
1546 "normalization_type": "RMS",
1547 "positional_embedding_type": "rotary",
1548 "rotary_base": _get_rope_theta(hf_config, default=500000.0),
1549 "gated_mlp": True,
1550 "tie_word_embeddings": hf_config.tie_word_embeddings,
1551 }
1552 # OLMo 3 uses per-layer-type rope (transformers 5.x): plain rope on
1553 # sliding_attention layers, YARN on full_attention layers.
1554 rope_params = getattr(hf_config, "rope_parameters", None)
1555 rope_scaling = getattr(hf_config, "rope_scaling", None)
1556 if isinstance(rope_params, dict) and "full_attention" in rope_params: 1556 ↛ 1574line 1556 didn't jump to line 1574 because the condition on line 1556 was always true
1557 full_rope = rope_params["full_attention"] or {}
1558 sliding_rope = rope_params.get("sliding_attention") or {}
1559 cfg_dict["rotary_base"] = full_rope.get("rope_theta", 500000.0)
1560 sliding_theta = sliding_rope.get("rope_theta")
1561 if sliding_theta is not None and sliding_theta != cfg_dict["rotary_base"]: 1561 ↛ 1562line 1561 didn't jump to line 1562 because the condition on line 1561 was never true
1562 cfg_dict["rotary_base_local"] = sliding_theta
1563 if full_rope.get("rope_type") == "yarn":
1564 cfg_dict["use_yarn_rope"] = True
1565 cfg_dict["yarn_global_attn_only"] = True
1566 cfg_dict["yarn_factor"] = float(full_rope.get("factor", 8.0))
1567 cfg_dict["yarn_attention_factor"] = float(full_rope.get("attention_factor", 1.0))
1568 cfg_dict["yarn_beta_fast"] = float(full_rope.get("beta_fast") or 32.0)
1569 cfg_dict["yarn_beta_slow"] = float(full_rope.get("beta_slow") or 1.0)
1570 cfg_dict["yarn_original_max_position_embeddings"] = full_rope.get(
1571 "original_max_position_embeddings", 4096
1572 )
1573 cfg_dict["yarn_truncate"] = full_rope.get("truncate", True)
1574 elif rope_scaling and rope_scaling.get("rope_type") == "yarn":
1575 # transformers < 5.0 flat rope_scaling dict
1576 cfg_dict["use_yarn_rope"] = True
1577 cfg_dict["yarn_factor"] = rope_scaling.get("factor", 8.0)
1578 cfg_dict["yarn_attention_factor"] = rope_scaling.get("attention_factor", 1.0)
1579 cfg_dict["yarn_beta_fast"] = rope_scaling.get("beta_fast", 32.0)
1580 cfg_dict["yarn_beta_slow"] = rope_scaling.get("beta_slow", 1.0)
1581 cfg_dict["yarn_original_max_position_embeddings"] = rope_scaling.get(
1582 "original_max_position_embeddings", 4096
1583 )
1584 layer_types = getattr(hf_config, "layer_types", None)
1585 if layer_types: 1585 ↛ 1595line 1585 didn't jump to line 1595 because the condition on line 1585 was always true
1586 cfg_dict["attn_types"] = [
1587 "local" if t == "sliding_attention" else "global" for t in layer_types
1588 ]
1589 # Without use_local_attn, attn_types is inert and every layer runs
1590 # global attention with no sliding mask.
1591 if "sliding_attention" in layer_types and hf_config.sliding_window: 1591 ↛ 1642line 1591 didn't jump to line 1642 because the condition on line 1591 was always true
1592 cfg_dict["use_local_attn"] = True
1593 cfg_dict["window_size"] = hf_config.sliding_window
1594 else:
1595 cfg_dict["attn_types"] = ["global"] * hf_config.num_hidden_layers
1596 elif architecture == "OlmoeForCausalLM":
1597 cfg_dict = {
1598 "d_model": hf_config.hidden_size,
1599 "d_head": hf_config.hidden_size // hf_config.num_attention_heads,
1600 "n_heads": hf_config.num_attention_heads,
1601 "d_mlp": hf_config.intermediate_size,
1602 "n_layers": hf_config.num_hidden_layers,
1603 "n_ctx": hf_config.max_position_embeddings,
1604 "eps": hf_config.rms_norm_eps,
1605 "d_vocab": hf_config.vocab_size,
1606 "act_fn": hf_config.hidden_act,
1607 "num_experts": hf_config.num_experts,
1608 "experts_per_token": hf_config.num_experts_per_tok,
1609 "norm_topk_prob": hf_config.norm_topk_prob,
1610 "n_key_value_heads": hf_config.num_key_value_heads,
1611 "rotary_base": _get_rope_theta(hf_config),
1612 "tie_word_embeddings": hf_config.tie_word_embeddings,
1613 "initializer_range": hf_config.initializer_range,
1614 "positional_embedding_type": "rotary",
1615 "rotary_dim": hf_config.hidden_size // hf_config.num_attention_heads,
1616 "gated_mlp": True,
1617 "normalization_type": "RMS",
1618 "clip_qkv": getattr(hf_config, "clip_qkv", None),
1619 }
1620 elif architecture == "T5ForConditionalGeneration": 1620 ↛ 1640line 1620 didn't jump to line 1640 because the condition on line 1620 was always true
1621 cfg_dict = {
1622 "d_model": hf_config.d_model,
1623 "d_head": hf_config.d_kv,
1624 "n_heads": hf_config.num_heads,
1625 "d_mlp": hf_config.d_ff,
1626 "d_vocab": hf_config.vocab_size,
1627 "n_layers": hf_config.num_layers,
1628 "n_ctx": getattr(hf_config, "max_length", None) or hf_config.n_positions,
1629 "eps": hf_config.layer_norm_epsilon,
1630 "act_fn": hf_config.feed_forward_proj,
1631 "positional_embedding_type": "relative_positional_bias",
1632 "relative_attention_max_distance": hf_config.relative_attention_max_distance,
1633 "relative_attention_num_buckets": hf_config.relative_attention_num_buckets,
1634 "decoder_start_token_id": hf_config.decoder_start_token_id,
1635 "attention_dir": "bidirectional",
1636 "use_attn_scale": False,
1637 "tie_word_embeddings": hf_config.tie_word_embeddings,
1638 }
1639 else:
1640 raise NotImplementedError(f"{architecture} is not currently supported.")
1641 # All of these models use LayerNorm
1642 cfg_dict["original_architecture"] = architecture
1643 # Carried on the cfg so the loader can act on the quantization without a
1644 # second AutoConfig fetch (which would be a Hub round trip per load).
1645 cfg_dict["quantization_method"] = quantization_method(hf_config)
1646 # The name such that AutoTokenizer.from_pretrained works
1647 cfg_dict["tokenizer_name"] = official_model_name
1648 if kwargs.get("trust_remote_code", False):
1649 cfg_dict["trust_remote_code"] = True
1650 # TinyStories models were trained with seq_len=512, but the HuggingFace config
1651 # reports max_position_embeddings=2048. Override n_ctx so the positional embedding
1652 # weights are trimmed during weight conversion.
1653 # See: https://github.com/TransformerLensOrg/TransformerLens/issues/492
1654 if official_model_name.startswith("roneneldan/TinyStories"):
1655 cfg_dict["n_ctx"] = 512
1656 return cfg_dict
1659def convert_neel_model_config(official_model_name: str, **kwargs: Any) -> dict[str, Any]:
1660 """
1661 Loads the config for a model trained by me (NeelNanda), converted to a dictionary
1662 in the HookedTransformerConfig format.
1664 AutoConfig is not supported, because these models are in the HookedTransformer format, so we directly download and load the json.
1665 """
1666 official_model_name = get_official_model_name(official_model_name)
1667 cfg_json: dict = utils.download_file_from_hf(official_model_name, "config.json", **kwargs)
1668 cfg_arch = cfg_json.get(
1669 "architecture", "neel" if "_old" not in official_model_name else "neel-solu-old"
1670 )
1671 cfg_dict = {
1672 "d_model": cfg_json["d_model"],
1673 "n_layers": cfg_json["n_layers"],
1674 "d_mlp": cfg_json["d_mlp"],
1675 "d_head": cfg_json["d_head"],
1676 "n_heads": cfg_json["n_heads"],
1677 "n_ctx": cfg_json["n_ctx"],
1678 "d_vocab": cfg_json["d_vocab"],
1679 "tokenizer_name": cfg_json.get("tokenizer_name", None),
1680 "act_fn": cfg_json["act_fn"],
1681 "attn_only": cfg_json["attn_only"],
1682 "final_rms": cfg_json.get("final_rms", False),
1683 "original_architecture": cfg_arch,
1684 }
1685 if "normalization" in cfg_json:
1686 cfg_dict["normalization_type"] = cfg_json["normalization"]
1687 else:
1688 cfg_dict["normalization_type"] = cfg_json["normalization_type"]
1689 if "shortformer_pos" in cfg_json:
1690 cfg_dict["positional_embedding_type"] = (
1691 "shortformer" if cfg_json["shortformer_pos"] else "standard"
1692 )
1693 else:
1694 cfg_dict["positional_embedding_type"] = "standard"
1695 return cfg_dict
1698def get_pretrained_model_config(
1699 model_name: str,
1700 hf_cfg: dict[str, Any] | None = None,
1701 checkpoint_index: int | None = None,
1702 checkpoint_value: int | None = None,
1703 fold_ln: bool = False,
1704 device: str | torch.device | None = None,
1705 n_devices: int = 1,
1706 default_prepend_bos: bool | None = None,
1707 dtype: torch.dtype = torch.float32,
1708 first_n_layers: int | None = None,
1709 n_ctx: int | None = None,
1710 **kwargs: Any,
1711) -> HookedTransformerConfig:
1712 """Returns the pretrained model config as an HookedTransformerConfig object.
1714 There are two types of pretrained models: HuggingFace models (where
1715 AutoModel and AutoConfig work), and models trained by me (NeelNanda) which
1716 aren't as integrated with HuggingFace infrastructure.
1718 Args:
1719 model_name: The name of the model. This can be either the official
1720 HuggingFace model name, or the name of a model trained by me
1721 (NeelNanda).
1722 hf_cfg (dict, optional): Config of a loaded pretrained HF model,
1723 converted to a dictionary.
1724 checkpoint_index (int, optional): If loading from a
1725 checkpoint, the index of the checkpoint to load. Defaults to None.
1726 checkpoint_value (int, optional): If loading from a checkpoint, the
1727 value of
1728 the checkpoint to load, ie the step or token number (each model has
1729 checkpoints labelled with exactly one of these). Defaults to None.
1730 fold_ln (bool, optional): Whether to fold the layer norm into the
1731 subsequent linear layers (see HookedTransformer.fold_layer_norm for
1732 details). Defaults to False.
1733 device (str, optional): The device to load the model onto. By
1734 default will load to CUDA if available, else CPU.
1735 n_devices (int, optional): The number of devices to split the model across. Defaults to 1.
1736 default_prepend_bos (bool, optional): Default behavior of whether to prepend the BOS token when the
1737 methods of HookedTransformer process input text to tokenize (only when input is a string).
1738 Resolution order for default_prepend_bos:
1739 1. If user passes value explicitly, use that value
1740 2. Model-specific default from cfg_dict if it exists (e.g. for bloom models it's False)
1741 3. Global default (True)
1743 Even for models not explicitly trained with the BOS token, heads often use the
1744 first position as a resting position and accordingly lose information from the first token,
1745 so this empirically seems to give better results. Note that you can also locally override the default behavior
1746 by passing in prepend_bos=True/False when you call a method that processes the input string.
1747 dtype (torch.dtype, optional): The dtype to load the TransformerLens model in.
1748 kwargs: Other optional arguments passed to HuggingFace's from_pretrained.
1749 Also given to other HuggingFace functions when compatible.
1751 """
1752 if Path(model_name).exists(): 1752 ↛ 1754line 1752 didn't jump to line 1754 because the condition on line 1752 was never true
1753 # If the model_name is a path, it's a local model
1754 cfg_dict = convert_hf_model_config(model_name, **kwargs)
1755 official_model_name = model_name
1756 else:
1757 official_model_name = get_official_model_name(model_name)
1758 if (
1759 official_model_name.startswith("NeelNanda")
1760 or official_model_name.startswith("ArthurConmy")
1761 or official_model_name.startswith("Baidicoot")
1762 ):
1763 cfg_dict = convert_neel_model_config(official_model_name, **kwargs)
1764 else:
1765 if official_model_name.startswith(NEED_REMOTE_CODE_MODELS) and not kwargs.get(
1766 "trust_remote_code", False
1767 ):
1768 logging.warning(
1769 f"Loading model {official_model_name} requires setting trust_remote_code=True"
1770 )
1771 kwargs["trust_remote_code"] = True
1772 cfg_dict = convert_hf_model_config(official_model_name, **kwargs)
1773 # Processing common to both model types
1774 # Remove any prefix, saying the organization who made a model.
1775 cfg_dict["model_name"] = official_model_name.split("/")[-1]
1776 # Don't need to initialize weights, we're loading from pretrained
1777 cfg_dict["init_weights"] = False
1779 if (
1780 "positional_embedding_type" in cfg_dict
1781 and cfg_dict["positional_embedding_type"] == "shortformer"
1782 and fold_ln
1783 ):
1784 logging.warning(
1785 "You tried to specify fold_ln=True for a shortformer model, but this can't be done! Setting fold_ln=False instead."
1786 )
1787 fold_ln = False
1789 # Post-norm blocks normalize the sublayer output, so folding the norm weights
1790 # into adjacent linear layers is not mathematically valid.
1791 architecture = cfg_dict.get("original_architecture")
1792 if architecture in POST_NORM_ARCHITECTURES and fold_ln:
1793 logging.warning(
1794 f"fold_ln=True is incompatible with {architecture}'s post-norm architecture. "
1795 "Setting fold_ln=False."
1796 )
1797 fold_ln = False
1799 if device is not None:
1800 cfg_dict["device"] = device
1802 cfg_dict["dtype"] = dtype
1804 if fold_ln:
1805 if cfg_dict["normalization_type"] in ["LN", "LNPre"]:
1806 cfg_dict["normalization_type"] = "LNPre"
1807 elif cfg_dict["normalization_type"] in ["RMS", "RMSPre"]: 1807 ↛ 1810line 1807 didn't jump to line 1810 because the condition on line 1807 was always true
1808 cfg_dict["normalization_type"] = "RMSPre"
1809 else:
1810 logging.warning("Cannot fold in layer norm, normalization_type is not LN.")
1812 if checkpoint_index is not None or checkpoint_value is not None: 1812 ↛ 1813line 1812 didn't jump to line 1813 because the condition on line 1812 was never true
1813 checkpoint_labels, checkpoint_label_type = get_checkpoint_labels(
1814 official_model_name,
1815 **kwargs,
1816 )
1817 cfg_dict["from_checkpoint"] = True
1818 cfg_dict["checkpoint_label_type"] = checkpoint_label_type
1819 if checkpoint_index is not None:
1820 cfg_dict["checkpoint_index"] = checkpoint_index
1821 cfg_dict["checkpoint_value"] = checkpoint_labels[checkpoint_index]
1822 elif checkpoint_value is not None:
1823 assert (
1824 checkpoint_value in checkpoint_labels
1825 ), f"Checkpoint value {checkpoint_value} is not in list of available checkpoints"
1826 cfg_dict["checkpoint_value"] = checkpoint_value
1827 cfg_dict["checkpoint_index"] = checkpoint_labels.index(checkpoint_value)
1828 else:
1829 cfg_dict["from_checkpoint"] = False
1831 cfg_dict["device"] = device
1832 cfg_dict["n_devices"] = n_devices
1834 if default_prepend_bos is not None:
1835 # User explicitly set prepend_bos behavior, override config/default value
1836 cfg_dict["default_prepend_bos"] = default_prepend_bos
1837 elif "default_prepend_bos" not in cfg_dict:
1838 # No config value or user override, set default value (True)
1839 cfg_dict["default_prepend_bos"] = True
1841 if hf_cfg is not None:
1842 cfg_dict["load_in_4bit"] = hf_cfg.get("quantization_config", {}).get("load_in_4bit", False)
1843 # A user-supplied hf_model is the more authoritative source: it says how
1844 # the weights in hand are actually stored, not how the Hub repo declares
1845 # them. .get, not []: convert_neel_model_config builds cfg_dict without
1846 # ever seeing an HF config, so the key need not be there.
1847 cfg_dict["quantization_method"] = quantization_method(hf_cfg) or cfg_dict.get(
1848 "quantization_method"
1849 )
1850 cfg_dict["d_vocab"] = hf_cfg.get("vocab_size", cfg_dict["d_vocab"])
1851 if cfg_dict["original_architecture"] == "Qwen2ForCausalLM": 1851 ↛ 1852line 1851 didn't jump to line 1852 because the condition on line 1851 was never true
1852 rope_params = hf_cfg.get("rope_parameters", {}) or {}
1853 cfg_dict["rotary_base"] = hf_cfg.get(
1854 "rope_theta", rope_params.get("rope_theta", cfg_dict["rotary_base"])
1855 )
1856 if first_n_layers is not None: 1856 ↛ 1857line 1856 didn't jump to line 1857 because the condition on line 1856 was never true
1857 cfg_dict["n_layers"] = first_n_layers
1859 if n_ctx is not None:
1860 default_n_ctx = cfg_dict.get("n_ctx")
1861 if default_n_ctx is not None and n_ctx > default_n_ctx:
1862 logging.warning(
1863 f"You are setting n_ctx={n_ctx} which is larger than this model's "
1864 f"default context length of {default_n_ctx}. The model was not "
1865 f"trained on sequences this long and may produce unreliable results. "
1866 f"Ensure you have sufficient memory for this context length."
1867 )
1868 cfg_dict["n_ctx"] = n_ctx
1870 cfg = HookedTransformerConfig.from_dict(cfg_dict)
1871 return cfg
1874def get_num_params_of_pretrained(model_name: str) -> int:
1875 """
1876 Returns the number of parameters of a pretrained model, used to filter to only run code for sufficiently small models.
1877 """
1878 cfg = get_pretrained_model_config(model_name)
1879 if cfg.n_params is None:
1880 raise ValueError(f"n_params not calculated for model {model_name}")
1881 return cfg.n_params
1884# %% Load checkpointed model state dicts
1885# The steps for which there are checkpoints in the stanford crfm models
1886STANFORD_CRFM_CHECKPOINTS = (
1887 list(range(0, 100, 10))
1888 + list(range(100, 2000, 50))
1889 + list(range(2000, 20000, 100))
1890 + list(range(20000, 400000 + 1, 1000))
1891)
1893# Linearly spaced checkpoints for Pythia models, taken every 1000 steps.
1894# Batch size 2,097,152 tokens, so checkpoints every 2.1B tokens
1895PYTHIA_CHECKPOINTS = [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512] + list(
1896 range(1000, 143000 + 1, 1000)
1897)
1898# Pythia V1 has log-spaced early checkpoints (see line above), but V0 doesn't
1899PYTHIA_V0_CHECKPOINTS = list(range(1000, 143000 + 1, 1000))
1902def get_checkpoint_labels(model_name: str, **kwargs: Any) -> tuple[list[int], str]:
1903 """Returns the checkpoint labels for a given model, and the label_type
1904 (step or token). Raises an error for models that are not checkpointed."""
1905 official_model_name = get_official_model_name(model_name)
1906 if official_model_name.startswith("stanford-crfm/"):
1907 return STANFORD_CRFM_CHECKPOINTS, "step"
1908 elif official_model_name.startswith("EleutherAI/pythia"):
1909 if "v0" in official_model_name:
1910 return PYTHIA_V0_CHECKPOINTS, "step"
1911 else:
1912 logging.warning(
1913 "Pythia models on HF were updated on 4/3/23! add '-v0' to model name to access the old models."
1914 )
1915 return PYTHIA_CHECKPOINTS, "step"
1916 elif official_model_name.startswith("NeelNanda/"):
1917 api = HfApi()
1918 files_list = api.list_repo_files(
1919 official_model_name,
1920 **utils.select_compatible_kwargs(kwargs, api.list_repo_files),
1921 )
1922 labels = []
1923 for file_name in files_list:
1924 match = re.match(r"checkpoints/.*_(\d*)\.pth", file_name)
1925 if match:
1926 labels.append(int(match.group(1)))
1927 if labels[-1] > 1e9:
1928 label_type = "token"
1929 else:
1930 label_type = "step"
1931 return labels, label_type
1932 else:
1933 raise ValueError(f"Model {official_model_name} is not checkpointed.")
1936# %% Loading state dicts
1937def _mxfp4_dequantize_config(cfg: HookedTransformerConfig) -> Any | None:
1938 """Return ``Mxfp4Config(dequantize=True)`` for packed-MXFP4 checkpoints.
1940 Reads the method captured on ``cfg`` (no refetch). Blind spot by
1941 construction: llama/gemma names never fetch a config, so their
1942 quantization_method is always None there — such checkpoints are refused by
1943 ``_refuse_unsupported_quantization`` rather than auto-dequantized.
1944 """
1945 if cfg.quantization_method != "mxfp4":
1946 return None
1947 return Mxfp4Config(dequantize=True)
1950def _refuse_unsupported_quantization(cfg: HookedTransformerConfig, hf_model: Any) -> None:
1951 """Refuse a quantized checkpoint before the weight converters read it.
1953 Same-shape int8/FP8 converts silently AND survives load_state_dict (cast
1954 to fp32), so refusal must happen here. Reads the LOADED model's config —
1955 cfg.quantization_method is structurally None for name-based llama/gemma —
1956 and refuses on stored weights, not the declaration, so dequantized loads
1957 that still advertise a quant_method keep working.
1958 """
1959 if hf_model is None: 1959 ↛ 1960line 1959 didn't jump to line 1960 because the condition on line 1959 was never true
1960 return
1961 method = quantization_method(getattr(hf_model, "config", None))
1962 if method is None:
1963 return
1964 # The one supported quantized HookedTransformer flow (weight conversion and
1965 # abstract_attention's matmul_4bit both handle it).
1966 if cfg.load_in_4bit and method == "bitsandbytes":
1967 return
1968 # Refuse on the stored weights, not the declaration: a checkpoint loaded
1969 # with dequantize=True still advertises its original quant_method while
1970 # holding perfectly readable bf16 tensors. Meta params are skipped — an
1971 # offloaded load is a different problem with a different message.
1972 offender = next(
1973 (
1974 (name, unreadable_weight_reason(param))
1975 for name, param in hf_model.named_parameters()
1976 if param.device.type != "meta" and unreadable_weight_reason(param) is not None
1977 ),
1978 None,
1979 )
1980 if offender is None:
1981 return
1982 name, reason = offender
1983 raise NotImplementedError(
1984 f"HookedTransformer cannot convert this {method!r}-quantized checkpoint: "
1985 f"{name} cannot be read because {reason}. The weight converters read "
1986 "weights directly, so packed or scale-separated storage silently "
1987 "produces wrong values. Load the model dequantized, or use "
1988 "TransformerBridge for a quantized forward pass."
1989 )
1992def get_pretrained_state_dict(
1993 official_model_name: str,
1994 cfg: HookedTransformerConfig,
1995 hf_model: Any | None = None,
1996 dtype: torch.dtype = torch.float32,
1997 **kwargs: Any,
1998) -> dict[str, torch.Tensor]:
1999 """
2000 Loads in the model weights for a pretrained model, and processes them to
2001 have the HookedTransformer parameter names and shapes. Supports checkpointed
2002 models (and expects the checkpoint info to be stored in the config object)
2004 hf_model: Optionally, a HuggingFace model object. If provided, we will use
2005 these weights rather than reloading the model.
2006 dtype: The dtype to load the HuggingFace model in.
2007 kwargs: Other optional arguments passed to HuggingFace's from_pretrained.
2008 Also given to other HuggingFace functions when compatible.
2009 """
2010 if "torch_dtype" in kwargs: 2010 ↛ 2011line 2010 didn't jump to line 2011 because the condition on line 2010 was never true
2011 dtype = kwargs["torch_dtype"]
2012 del kwargs["torch_dtype"]
2013 if Path(official_model_name).exists(): 2013 ↛ 2014line 2013 didn't jump to line 2014 because the condition on line 2013 was never true
2014 official_model_name = str(Path(official_model_name).resolve())
2015 logging.info(f"Loading model from local path {official_model_name}")
2016 else:
2017 official_model_name = get_official_model_name(official_model_name)
2018 if official_model_name.startswith(NEED_REMOTE_CODE_MODELS) and not kwargs.get( 2018 ↛ 2021line 2018 didn't jump to line 2021 because the condition on line 2018 was never true
2019 "trust_remote_code", False
2020 ):
2021 logging.warning(
2022 f"Loading model {official_model_name} state dict requires setting trust_remote_code=True"
2023 )
2024 kwargs["trust_remote_code"] = True
2025 if (
2026 official_model_name.startswith("NeelNanda")
2027 or official_model_name.startswith("ArthurConmy")
2028 or official_model_name.startswith("Baidicoot")
2029 ):
2030 api = HfApi()
2031 repo_files = api.list_repo_files(
2032 official_model_name,
2033 **utils.select_compatible_kwargs(kwargs, api.list_repo_files),
2034 )
2035 if cfg.from_checkpoint: 2035 ↛ 2036line 2035 didn't jump to line 2036 because the condition on line 2035 was never true
2036 file_name = list(
2037 filter(lambda x: x.endswith(f"{cfg.checkpoint_value}.pth"), repo_files)
2038 )[0]
2039 else:
2040 file_name = list(filter(lambda x: x.endswith("final.pth"), repo_files))[0]
2041 state_dict = utils.download_file_from_hf(official_model_name, file_name, **kwargs)
2043 state_dict = {k: v.to(dtype) for k, v in state_dict.items()}
2045 if cfg.original_architecture == "neel-solu-old":
2046 state_dict = convert_neel_solu_old_weights(state_dict, cfg)
2047 elif cfg.original_architecture == "mingpt":
2048 state_dict = convert_mingpt_weights(state_dict, cfg)
2049 return state_dict
2050 else:
2051 if cfg.from_checkpoint: 2051 ↛ 2052line 2051 didn't jump to line 2052 because the condition on line 2051 was never true
2052 huggingface_token = os.environ.get("HF_TOKEN", "")
2053 if official_model_name.startswith("stanford-crfm"):
2054 hf_model = AutoModelForCausalLM.from_pretrained(
2055 official_model_name,
2056 revision=f"checkpoint-{cfg.checkpoint_value}",
2057 dtype=dtype,
2058 token=huggingface_token if len(huggingface_token) > 0 else None,
2059 **kwargs,
2060 )
2061 elif official_model_name.startswith("EleutherAI/pythia"):
2062 hf_model = AutoModelForCausalLM.from_pretrained(
2063 official_model_name,
2064 revision=f"step{cfg.checkpoint_value}",
2065 dtype=dtype,
2066 token=huggingface_token,
2067 **kwargs,
2068 )
2069 else:
2070 raise ValueError(f"Checkpoints for model {official_model_name} are not supported")
2071 elif hf_model is None: 2071 ↛ 2146line 2071 didn't jump to line 2146 because the condition on line 2071 was always true
2072 huggingface_token = os.environ.get("HF_TOKEN", "")
2073 if official_model_name in NON_HF_HOSTED_MODEL_NAMES: 2073 ↛ 2074line 2073 didn't jump to line 2074 because the condition on line 2073 was never true
2074 raise NotImplementedError("Model not hosted on HuggingFace, must pass in hf_model")
2075 elif "hubert" in official_model_name:
2076 hf_model = HubertModel.from_pretrained(
2077 official_model_name,
2078 dtype=dtype,
2079 token=huggingface_token if len(huggingface_token) > 0 else None,
2080 **kwargs,
2081 )
2082 elif "wav2vec2" in official_model_name: 2082 ↛ 2083line 2082 didn't jump to line 2083 because the condition on line 2082 was never true
2083 hf_model = Wav2Vec2Model.from_pretrained(
2084 official_model_name,
2085 dtype=dtype,
2086 token=huggingface_token if len(huggingface_token) > 0 else None,
2087 **kwargs,
2088 )
2089 elif "bert" in official_model_name:
2090 hf_model = BertForPreTraining.from_pretrained(
2091 official_model_name,
2092 dtype=dtype,
2093 token=huggingface_token if len(huggingface_token) > 0 else None,
2094 **kwargs,
2095 )
2096 elif "t5" in official_model_name:
2097 hf_model = T5ForConditionalGeneration.from_pretrained(
2098 official_model_name,
2099 dtype=dtype,
2100 token=huggingface_token if len(huggingface_token) > 0 else None,
2101 **kwargs,
2102 )
2103 elif cfg.original_architecture == "Gemma3ForConditionalGeneration": 2103 ↛ 2105line 2103 didn't jump to line 2105 because the condition on line 2103 was never true
2104 # Multimodal Gemma 3 models - use AutoModel
2105 hf_model = AutoModel.from_pretrained(
2106 official_model_name,
2107 dtype=dtype,
2108 token=huggingface_token if len(huggingface_token) > 0 else None,
2109 **kwargs,
2110 )
2111 else:
2112 if "quantization_config" not in kwargs: 2112 ↛ 2117line 2112 didn't jump to line 2117 because the condition on line 2112 was always true
2113 mxfp4_dequantize = _mxfp4_dequantize_config(cfg)
2114 if mxfp4_dequantize is not None: 2114 ↛ 2115line 2114 didn't jump to line 2115 because the condition on line 2114 was never true
2115 kwargs = {**kwargs, "quantization_config": mxfp4_dequantize}
2116 # Older models may lack pad_token_id (required in newer transformers)
2117 try:
2118 hf_model = AutoModelForCausalLM.from_pretrained(
2119 official_model_name,
2120 dtype=dtype,
2121 token=huggingface_token if len(huggingface_token) > 0 else None,
2122 **kwargs,
2123 )
2124 except AttributeError as e:
2125 if "pad_token_id" in str(e):
2126 hf_config = AutoConfig.from_pretrained(
2127 official_model_name,
2128 token=huggingface_token if len(huggingface_token) > 0 else None,
2129 )
2130 hf_config.pad_token_id = getattr(hf_config, "pad_token_id", None)
2131 hf_model = AutoModelForCausalLM.from_pretrained(
2132 official_model_name,
2133 config=hf_config,
2134 dtype=dtype,
2135 token=huggingface_token if len(huggingface_token) > 0 else None,
2136 **kwargs,
2137 )
2138 else:
2139 raise
2141 # Load model weights, and fold in layer norm weights
2142 if hf_model is not None: 2142 ↛ 2146line 2142 didn't jump to line 2146 because the condition on line 2142 was always true
2143 for param in hf_model.parameters():
2144 param.requires_grad = False
2146 _refuse_unsupported_quantization(cfg, hf_model)
2148 if cfg.original_architecture == "GPT2LMHeadModel":
2149 state_dict = convert_gpt2_weights(hf_model, cfg)
2150 elif cfg.original_architecture == "GPTNeoForCausalLM":
2151 state_dict = convert_neo_weights(hf_model, cfg)
2152 elif cfg.original_architecture == "OPTForCausalLM":
2153 state_dict = convert_opt_weights(hf_model, cfg)
2154 elif cfg.original_architecture == "GPTJForCausalLM": 2154 ↛ 2155line 2154 didn't jump to line 2155 because the condition on line 2154 was never true
2155 state_dict = convert_gptj_weights(hf_model, cfg)
2156 elif cfg.original_architecture == "GPTNeoXForCausalLM":
2157 state_dict = convert_neox_weights(hf_model, cfg)
2158 elif cfg.original_architecture == "LlamaForCausalLM": 2158 ↛ 2159line 2158 didn't jump to line 2159 because the condition on line 2158 was never true
2159 state_dict = convert_llama_weights(hf_model, cfg)
2160 elif cfg.original_architecture == "HubertModel":
2161 state_dict = convert_hubert_weights(hf_model, cfg)
2162 elif ( 2162 ↛ 2166line 2162 didn't jump to line 2166 because the condition on line 2162 was never true
2163 cfg.original_architecture == "Wav2Vec2Model"
2164 or cfg.original_architecture == "Wav2Vec2ForPreTraining"
2165 ):
2166 state_dict = convert_hubert_weights(hf_model, cfg)
2167 elif cfg.original_architecture == "HubertForCTC": 2167 ↛ 2168line 2167 didn't jump to line 2168 because the condition on line 2167 was never true
2168 state_dict = convert_hubert_weights(hf_model, cfg)
2169 elif cfg.original_architecture == "BertForMaskedLM":
2170 state_dict = convert_bert_weights(hf_model, cfg)
2171 elif cfg.original_architecture == "T5ForConditionalGeneration":
2172 state_dict = convert_t5_weights(hf_model, cfg)
2173 elif cfg.original_architecture == "MistralForCausalLM": 2173 ↛ 2174line 2173 didn't jump to line 2174 because the condition on line 2173 was never true
2174 state_dict = convert_mistral_weights(hf_model, cfg)
2175 elif cfg.original_architecture == "MixtralForCausalLM": 2175 ↛ 2176line 2175 didn't jump to line 2176 because the condition on line 2175 was never true
2176 state_dict = convert_mixtral_weights(hf_model, cfg)
2177 elif cfg.original_architecture == "GptOssForCausalLM": 2177 ↛ 2178line 2177 didn't jump to line 2178 because the condition on line 2177 was never true
2178 state_dict = convert_gpt_oss_weights(hf_model, cfg)
2179 elif cfg.original_architecture == "BloomForCausalLM": 2179 ↛ 2181line 2179 didn't jump to line 2181 because the condition on line 2179 was always true
2180 state_dict = convert_bloom_weights(hf_model, cfg)
2181 elif cfg.original_architecture == "GPT2LMHeadCustomModel":
2182 state_dict = convert_coder_weights(hf_model, cfg)
2183 elif cfg.original_architecture == "QWenLMHeadModel":
2184 state_dict = convert_qwen_weights(hf_model, cfg)
2185 elif cfg.original_architecture == "Qwen2ForCausalLM":
2186 state_dict = convert_qwen2_weights(hf_model, cfg)
2187 elif cfg.original_architecture == "Qwen3ForCausalLM":
2188 state_dict = convert_qwen3_weights(hf_model, cfg)
2189 elif cfg.original_architecture == "PhiForCausalLM":
2190 state_dict = convert_phi_weights(hf_model, cfg)
2191 elif cfg.original_architecture == "Phi3ForCausalLM":
2192 state_dict = convert_phi3_weights(hf_model, cfg)
2193 elif cfg.original_architecture == "GemmaForCausalLM":
2194 state_dict = convert_gemma_weights(hf_model, cfg)
2195 elif cfg.original_architecture == "Gemma2ForCausalLM":
2196 state_dict = convert_gemma_weights(hf_model, cfg)
2197 elif cfg.original_architecture == "ApertusForCausalLM":
2198 state_dict = convert_apertus_weights(hf_model, cfg)
2199 elif cfg.original_architecture == "Gemma3ForCausalLM":
2200 state_dict = convert_gemma_weights(hf_model, cfg)
2201 elif cfg.original_architecture == "Gemma3ForConditionalGeneration":
2202 state_dict = convert_gemma_weights(hf_model, cfg)
2203 elif cfg.original_architecture == "OlmoForCausalLM":
2204 state_dict = convert_olmo_weights(hf_model, cfg)
2205 elif cfg.original_architecture == "Olmo2ForCausalLM":
2206 state_dict = convert_olmo2_weights(hf_model, cfg)
2207 elif cfg.original_architecture == "OlmoeForCausalLM":
2208 state_dict = convert_olmoe_weights(hf_model, cfg)
2209 elif cfg.original_architecture == "Olmo3ForCausalLM":
2210 state_dict = convert_olmo3_weights(hf_model, cfg)
2211 else:
2212 raise ValueError(
2213 f"Loading weights from the architecture is not currently supported: {cfg.original_architecture}, generated from model name {cfg.model_name}. Feel free to open an issue on GitHub to request this feature."
2214 )
2216 return state_dict
2219def fill_missing_keys(
2220 model: torch.nn.Module, state_dict: dict[str, torch.Tensor]
2221) -> dict[str, torch.Tensor]:
2222 """Takes in a state dict from a pretrained model, and fills in any missing keys with the default initialization.
2224 This function is assumed to be run before weights are initialized.
2226 Args:
2227 model: The model to fill missing keys for
2228 state_dict: State dict from a pretrained model
2230 Returns:
2231 dict: State dict with missing keys filled in
2232 """
2233 default_state_dict = model.state_dict()
2234 missing_keys = set(default_state_dict.keys()) - set(state_dict.keys())
2235 # A missing attention weight matrix means a converter/component naming
2236 # mismatch (e.g. W_K written where GroupedQueryAttention expects _W_K).
2237 # Filling it with an empty tensor silently zeroes the sublayer while every
2238 # downstream number still looks plausible — fail loudly instead.
2239 # W_in/W_gate/W_out join the attention set: zero-filling an MLP matrix is
2240 # the same silent-sublayer-death, just on the other branch.
2241 fail_loud_weight_names = {
2242 "W_Q",
2243 "W_K",
2244 "W_V",
2245 "W_O",
2246 "_W_K",
2247 "_W_V",
2248 "W_in",
2249 "W_gate",
2250 "W_out",
2251 }
2252 missing_fail_loud = sorted(
2253 key
2254 for key in missing_keys
2255 if "hf_model" not in key and key.rsplit(".", 1)[-1] in fail_loud_weight_names
2256 )
2257 if missing_fail_loud:
2258 raise ValueError(
2259 f"Pretrained state dict is missing weight matrices the model "
2260 f"expects: {missing_fail_loud}. This usually means the weight "
2261 f"converter and the instantiated module disagree on parameter "
2262 f"naming (e.g. GQA's underscore-prefixed _W_K/_W_V vs W_K/W_V). Refusing "
2263 f"to zero-fill them, which would silently produce wrong outputs."
2264 )
2265 # Norm weights fill with DEFAULTS (w=1, b=0), which is frequently correct
2266 # (models without biases) but silently wrong when the checkpoint really has
2267 # them — so the fill is named, not silent.
2268 norm_key_names = {"w", "b"}
2269 for key in missing_keys:
2270 if "hf_model" in key: 2270 ↛ 2272line 2270 didn't jump to line 2272 because the condition on line 2270 was never true
2271 # Skip keys that are from the HuggingFace model, if loading from HF.
2272 continue
2273 leaf = key.rsplit(".", 1)[-1]
2274 if "W_" in key:
2275 logging.warning(
2276 "Missing key for a weight matrix in pretrained, filled in with an empty tensor: {}".format(
2277 key
2278 )
2279 )
2280 elif leaf in norm_key_names and ("ln" in key or "norm" in key):
2281 logging.warning(
2282 "Missing normalization key in pretrained, filled with its default "
2283 "(identity norm): {}".format(key)
2284 )
2285 state_dict[key] = default_state_dict[key]
2286 return state_dict
2289@dataclasses.dataclass
2290class Config:
2291 d_model: int = 768
2292 debug: bool = True
2293 layer_norm_eps: float = 1e-5
2294 d_vocab: int = 50257
2295 init_range: float = 0.02
2296 n_ctx: int = 1024
2297 d_head: int = 64
2298 d_mlp: int = 3072
2299 n_heads: int = 12
2300 n_layers: int = 12
2303def get_basic_config(model_name: str, **kwargs: Any) -> Config:
2304 """Returns the configuration parameters of the model as a basic Config dataclass."""
2305 return Config(
2306 **{
2307 k: v
2308 for k, v in get_pretrained_model_config(model_name, **kwargs).to_dict().items()
2309 if k
2310 in [
2311 "d_model",
2312 "debug",
2313 "layer_norm_eps",
2314 "d_vocab",
2315 "init_range",
2316 "n_ctx",
2317 "d_head",
2318 "d_mlp",
2319 "n_heads",
2320 "n_layers",
2321 ]
2322 }
2323 )