File size: 1,786 Bytes
89bd096 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | """Phase 0 — vérifie que les tailles de modèle annoncées dans les docs sont vraies.
Un chiffre de paramètres écrit dans la documentation peut dériver : ce test
recalcule les valeurs à partir de `configs/model.yaml` et échoue en cas d'écart.
"""
from pathlib import Path
import pytest
yaml = pytest.importorskip("yaml")
ROOT = Path(__file__).resolve().parents[1]
@pytest.fixture(scope="module")
def cfg():
return yaml.safe_load((ROOT / "configs" / "model.yaml").read_text(encoding="utf-8"))
def count_params(vocab: int, n_embd: int, n_layer: int, tie: bool, ffn_mult: int = 4) -> int:
"""Compte les paramètres d'un transformer decoder-only pre-norm sans biais."""
embed = vocab * n_embd
per_layer = 4 * n_embd * n_embd + 2 * n_embd * (ffn_mult * n_embd) + 2 * n_embd
total = embed + n_layer * per_layer + n_embd
if not tie:
total += vocab * n_embd
return total
def test_default_profile_matches_documented_size(cfg):
tm, tk = cfg["text_model"], cfg["tokenizer"]
n = count_params(tk["vocab_size"], tm["n_embd"], tm["n_layer"], tm["tie_embeddings"])
assert round(n / 1e6, 1) == 22.9, f"profil défaut = {n/1e6:.1f}M, attendu 22.9M"
def test_50m_profile_is_actually_about_50m(cfg):
tm, tk = cfg["text_model_50m"], cfg["tokenizer"]
n = count_params(tk["vocab_size"], tm["n_embd"], tm["n_layer"], tm["tie_embeddings"])
assert 48e6 <= n <= 53e6, f"profil 50m = {n/1e6:.1f}M, hors de la cible ~50M"
def test_docs_state_the_real_default_size(cfg):
arch = (ROOT / "docs" / "architecture.md").read_text(encoding="utf-8")
assert "22.9 M" in arch, "architecture.md doit annoncer la vraie taille du profil défaut"
assert "51.6 M" in arch, "architecture.md doit annoncer la vraie taille du profil 50M"
|