Aura-2B / model_factory.py
alexgichamba's picture
Upload folder using huggingface_hub
2809464 verified
Raw
History Blame Contribute Delete
3.5 kB
"""
model_factory.py — model config builder.
The old presets dict hardcoded vocab_size and max_seq_len per architecture.
That coupled the model to a specific tokenizer and sequence length, which is
exactly the thing we're moving away from now that vocab is selectable
(32k vs 64k) and T may grow.
New API: build_model_config(model_type, size, vocab_size, max_seq_len) returns
a ModelArgs with the architectural shape from the preset table and vocab_size
+ max_seq_len from the caller.
"""
from llama3 import ModelArgs
# ----------------------------------------------------------------------------
# Architectural presets — shape only. No vocab_size, no max_seq_len.
# ----------------------------------------------------------------------------
#
# Each entry holds the model-shape hyperparameters that don't depend on the
# tokenizer or context length: layer count, head count, hidden dim, MLP
# intermediate size, and KV head count.
#
# The "llama-iwslt" entries match the previous model_presets sizes, just with
# vocab_size factored out. The "llama" entries (pre-IWSLT vocab 50304) are
# kept for backward compat with old checkpoints but new training should use
# llama-iwslt.
ARCH_PRESETS: dict[str, dict[str, dict]] = {
"llama-iwslt": {
"124m": dict(n_layers=12, n_heads=12, dim=768, intermediate_size=4 * 768, n_kv_heads=12),
"500m": dict(n_layers=32, n_heads=16, dim=1024, intermediate_size=3072, n_kv_heads=4),
"978m": dict(n_layers=36, n_heads=20, dim=1280, intermediate_size=5120, n_kv_heads=4),
"1b": dict(n_layers=36, n_heads=20, dim=1280, intermediate_size=5120, n_kv_heads=4),
"2b": dict(n_layers=36, n_heads=32, dim=2048, intermediate_size=5120, n_kv_heads=8),
},
}
def build_model_config(
model_type: str,
size: str,
vocab_size: int,
max_seq_len: int,
) -> ModelArgs:
"""Build a ModelArgs combining architectural preset + runtime vocab/seq_len."""
if model_type not in ARCH_PRESETS:
raise ValueError(f"unknown model_type {model_type!r}; "
f"expected one of {list(ARCH_PRESETS)}")
if size not in ARCH_PRESETS[model_type]:
raise ValueError(f"unknown size {size!r} for {model_type}; "
f"expected one of {list(ARCH_PRESETS[model_type])}")
arch = ARCH_PRESETS[model_type][size]
return ModelArgs(
vocab_size=vocab_size,
max_seq_len=max_seq_len,
**arch,
)
# ----------------------------------------------------------------------------
# Checkpoint loader (kept for backward compat with utils.completion etc.)
# ----------------------------------------------------------------------------
def load_model(model, path, load_dict_only=False):
"""Load a model checkpoint into an already-constructed model.
Handles both:
- new checkpoints saved by the new train.py (keys = state_dict layout)
- old checkpoints with torch.compile's '_orig_mod.' prefix
"""
import torch
ckpt = torch.load(path, map_location=torch.device("cpu"), weights_only=False)
sd = ckpt["model"] if "model" in ckpt else ckpt
# Strip torch.compile prefix
sd = {k.replace("_orig_mod.", ""): v for k, v in sd.items()}
# Strip DDP prefix
sd = {k.replace("module.", ""): v for k, v in sd.items()}
model.load_state_dict(sd)
step = ckpt.get("step", 0) if isinstance(ckpt, dict) else 0
if not load_dict_only:
model.train()
return model, step