Angshul's picture
Upload 17 files
c675b8d verified
Raw History Blame Contribute Delete
5.28 kB
"""Architecture adapters: tensor names and structure for the supported Hugging Face causal LMs.
Supported model_type: llama, mistral, qwen2 (incl. Llama-2/3/3.1/3.3-70B, Qwen2.5-72B), opt (pre-LN), gpt2.
A linear module is described by (module_name, input_key, role):
input_key in {"ln1", "attn_out", "ln2", "act"} - which activation it reads
role in {"q","k","v","qkv","o","gate","up","down"}
Weights are returned in torch Linear layout (out, in); GPT-2 Conv1D weights are transposed on read.
"""
from dataclasses import dataclass, field
from typing import List, Optional, Tuple
@dataclass
class Linear:
name: str # module path, e.g. "model.layers.3.self_attn.q_proj"
input_key: str
role: str
conv1d: bool = False # stored (in, out)
@dataclass
class Arch:
model_type: str
n_layer: int
d: int
n_head: int
n_kv: int
head_dim: int
inter: int
norm: str # "rms" | "ln"
norm_eps: float
act: str # "swiglu" | "relu" | "gelu_new" | "gelu"
embed: str
pos_embed: Optional[str]
pos_offset: int
final_norm: str
lm_head: Optional[str]
vocab: int
max_pos: int
layers: List[List[Linear]] = field(default_factory=list)
norms: List[Tuple[str, str]] = field(default_factory=list) # per layer: (ln1 prefix, ln2 prefix)
def norm_names(self, L, which):
p = self.norms[L][0 if which == "ln1" else 1]
return p + ".weight", (p + ".bias" if self.norm == "ln" else None)
def from_config(cfg: dict) -> Arch:
mt = cfg.get("model_type")
if mt in ("llama", "mistral", "qwen2"):
d, H = cfg["hidden_size"], cfg["num_attention_heads"]
act = cfg.get("hidden_act", "silu")
if act != "silu":
raise NotImplementedError(f"{mt} with hidden_act={act}")
a = Arch(mt, cfg["num_hidden_layers"], d, H, cfg.get("num_key_value_heads", H), cfg.get("head_dim") or d // H,
cfg["intermediate_size"], "rms", cfg.get("rms_norm_eps", 1e-6), "swiglu",
"model.embed_tokens.weight", None, 0, "model.norm.weight",
None if cfg.get("tie_word_embeddings", False) else "lm_head.weight",
cfg["vocab_size"], cfg.get("max_position_embeddings", 4096))
for L in range(a.n_layer):
p = f"model.layers.{L}."
a.layers.append([Linear(p + "self_attn.q_proj", "ln1", "q"), Linear(p + "self_attn.k_proj", "ln1", "k"),
Linear(p + "self_attn.v_proj", "ln1", "v"), Linear(p + "self_attn.o_proj", "attn_out", "o"),
Linear(p + "mlp.gate_proj", "ln2", "gate"), Linear(p + "mlp.up_proj", "ln2", "up"),
Linear(p + "mlp.down_proj", "act", "down")])
a.norms.append((p + "input_layernorm", p + "post_attention_layernorm"))
return a
if mt == "opt":
if not cfg.get("do_layer_norm_before", True):
raise NotImplementedError("post-LN OPT (opt-350m) is not supported")
if cfg.get("word_embed_proj_dim", cfg["hidden_size"]) != cfg["hidden_size"]:
raise NotImplementedError("OPT with project_in/out is not supported")
d, H = cfg["hidden_size"], cfg["num_attention_heads"]
a = Arch(mt, cfg["num_hidden_layers"], d, H, H, d // H, cfg["ffn_dim"], "ln", 1e-5,
{"relu": "relu"}.get(cfg.get("activation_function", "relu"), cfg.get("activation_function")),
"model.decoder.embed_tokens.weight", "model.decoder.embed_positions.weight", 2,
"model.decoder.final_layer_norm.weight", None if cfg.get("tie_word_embeddings", True) else "lm_head.weight",
cfg["vocab_size"], cfg.get("max_position_embeddings", 2048))
for L in range(a.n_layer):
p = f"model.decoder.layers.{L}."
a.layers.append([Linear(p + "self_attn.q_proj", "ln1", "q"), Linear(p + "self_attn.k_proj", "ln1", "k"),
Linear(p + "self_attn.v_proj", "ln1", "v"), Linear(p + "self_attn.out_proj", "attn_out", "o"),
Linear(p + "fc1", "ln2", "up"), Linear(p + "fc2", "act", "down")])
a.norms.append((p + "self_attn_layer_norm", p + "final_layer_norm"))
return a
if mt == "gpt2":
d, H = cfg["n_embd"], cfg["n_head"]
a = Arch(mt, cfg["n_layer"], d, H, H, d // H, cfg.get("n_inner") or 4 * d, "ln", cfg.get("layer_norm_epsilon", 1e-5),
{"gelu_new": "gelu_new"}.get(cfg.get("activation_function", "gelu_new"), cfg.get("activation_function")),
"transformer.wte.weight", "transformer.wpe.weight", 0, "transformer.ln_f.weight", None,
cfg["vocab_size"], cfg.get("n_positions", 1024))
for L in range(a.n_layer):
p = f"transformer.h.{L}."
a.layers.append([Linear(p + "attn.c_attn", "ln1", "qkv", True), Linear(p + "attn.c_proj", "attn_out", "o", True),
Linear(p + "mlp.c_fc", "ln2", "up", True), Linear(p + "mlp.c_proj", "act", "down", True)])
a.norms.append((p + "ln_1", p + "ln_2"))
return a
raise NotImplementedError(f"model_type={mt!r} is not supported (supported: llama, mistral, qwen2, opt, gpt2)")