Coverage for transformer_lens/pretrained/weight_conversions/nanogpt.py: 7%
62 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
1import einops
2import torch
4from transformer_lens.config.hooked_transformer_config import HookedTransformerConfig
7def convert_nanogpt_weights(old_state_dict, cfg: HookedTransformerConfig):
8 """For https://github.com/karpathy/nanoGPT
9 There are two complications with converting nanogpt models:
10 The first is that some state dicts have an unwanted prefix on keys that needs to be removed.
11 The second is that the models can be saved with or without bias. By default, there
12 is no bias. This function can handle both cases."""
13 # Nanogpt models saved after torch.compile() have this unwanted prefix
14 unwanted_prefix = "_orig_mod."
15 for k, v in list(old_state_dict.items()):
16 if k.startswith(unwanted_prefix):
17 old_state_dict[k[len(unwanted_prefix) :]] = old_state_dict.pop(k)
19 new_state_dict = {}
20 new_state_dict["pos_embed.W_pos"] = old_state_dict["transformer.wpe.weight"]
21 new_state_dict["embed.W_E"] = old_state_dict["transformer.wte.weight"]
23 new_state_dict["ln_final.w"] = old_state_dict["transformer.ln_f.weight"]
24 new_state_dict["ln_final.b"] = torch.zeros_like(old_state_dict["transformer.ln_f.weight"])
25 new_state_dict["unembed.W_U"] = old_state_dict["lm_head.weight"].T
27 bias = False
28 if "transformer.ln_f.bias" in old_state_dict:
29 bias = True
30 new_state_dict["ln_final.b"] = old_state_dict["transformer.ln_f.bias"]
31 else:
32 new_state_dict["unembed.b_U"] = torch.zeros(cfg.d_vocab, dtype=cfg.dtype)
34 for layer in range(cfg.n_layers):
35 layer_key = f"transformer.h.{layer}"
37 new_state_dict[f"blocks.{layer}.ln1.w"] = old_state_dict[f"{layer_key}.ln_1.weight"]
38 # A bias of zeros is required for folding layer norm
39 new_state_dict[f"blocks.{layer}.ln1.b"] = torch.zeros_like(
40 old_state_dict[f"{layer_key}.ln_1.weight"]
41 )
42 new_state_dict[f"blocks.{layer}.ln2.w"] = old_state_dict[f"{layer_key}.ln_2.weight"]
43 new_state_dict[f"blocks.{layer}.ln2.b"] = torch.zeros_like(
44 old_state_dict[f"{layer_key}.ln_2.weight"]
45 )
47 new_state_dict[f"blocks.{layer}.attn.IGNORE"] = torch.tensor(-torch.inf)
49 W = old_state_dict[f"{layer_key}.attn.c_attn.weight"]
50 W_Q, W_K, W_V = torch.tensor_split(W, 3, dim=0)
51 W_Q = einops.rearrange(W_Q, "(i h) m->i m h", i=cfg.n_heads)
52 W_K = einops.rearrange(W_K, "(i h) m->i m h", i=cfg.n_heads)
53 W_V = einops.rearrange(W_V, "(i h) m->i m h", i=cfg.n_heads)
54 new_state_dict[f"blocks.{layer}.attn.W_Q"] = W_Q
55 new_state_dict[f"blocks.{layer}.attn.W_K"] = W_K
56 new_state_dict[f"blocks.{layer}.attn.W_V"] = W_V
58 W_O = old_state_dict[f"{layer_key}.attn.c_proj.weight"]
59 W_O = einops.rearrange(W_O, "m (i h)->i h m", i=cfg.n_heads)
60 new_state_dict[f"blocks.{layer}.attn.W_O"] = W_O
62 new_state_dict[f"blocks.{layer}.mlp.W_in"] = old_state_dict[
63 f"{layer_key}.mlp.c_fc.weight"
64 ].T
65 new_state_dict[f"blocks.{layer}.mlp.W_out"] = old_state_dict[
66 f"{layer_key}.mlp.c_proj.weight"
67 ].T
69 if bias:
70 new_state_dict[f"blocks.{layer}.ln1.b"] = old_state_dict[f"{layer_key}.ln_1.bias"]
71 new_state_dict[f"blocks.{layer}.ln2.b"] = old_state_dict[f"{layer_key}.ln_2.bias"]
72 new_state_dict[f"blocks.{layer}.mlp.b_in"] = old_state_dict[
73 f"{layer_key}.mlp.c_fc.bias"
74 ]
75 new_state_dict[f"blocks.{layer}.mlp.b_out"] = old_state_dict[
76 f"{layer_key}.mlp.c_proj.bias"
77 ]
79 B = old_state_dict[f"{layer_key}.attn.c_attn.bias"]
80 B_Q, B_K, B_V = torch.tensor_split(B, 3, dim=0)
81 B_Q = einops.rearrange(B_Q, "(i h)->i h", i=cfg.n_heads)
82 B_K = einops.rearrange(B_K, "(i h)->i h", i=cfg.n_heads)
83 B_V = einops.rearrange(B_V, "(i h)->i h", i=cfg.n_heads)
84 new_state_dict[f"blocks.{layer}.attn.b_Q"] = B_Q
85 new_state_dict[f"blocks.{layer}.attn.b_K"] = B_K
86 new_state_dict[f"blocks.{layer}.attn.b_V"] = B_V
87 new_state_dict[f"blocks.{layer}.attn.b_O"] = old_state_dict[
88 f"{layer_key}.attn.c_proj.bias"
89 ]
90 else:
91 if cfg.d_mlp is None:
92 raise ValueError(
93 "cfg.d_mlp must be set to convert nanoGPT weights for the no-bias case."
94 )
95 new_state_dict[f"blocks.{layer}.mlp.b_out"] = torch.zeros(cfg.d_model, dtype=cfg.dtype)
96 new_state_dict[f"blocks.{layer}.mlp.b_in"] = torch.zeros(cfg.d_mlp, dtype=cfg.dtype)
97 new_state_dict[f"blocks.{layer}.attn.b_Q"] = torch.zeros(
98 (cfg.n_heads, cfg.d_head), dtype=cfg.dtype
99 )
100 new_state_dict[f"blocks.{layer}.attn.b_K"] = torch.zeros(
101 cfg.n_heads, cfg.d_head, dtype=cfg.dtype
102 )
103 new_state_dict[f"blocks.{layer}.attn.b_V"] = torch.zeros(
104 cfg.n_heads, cfg.d_head, dtype=cfg.dtype
105 )
106 new_state_dict[f"blocks.{layer}.attn.b_O"] = torch.zeros(cfg.d_model, dtype=cfg.dtype)
108 return new_state_dict