Aller au contenu

Retrouver les 2,8 T de paramètres

Cet exercice est le meilleur test de compréhension de l'architecture : si vous retrouvez les totaux annoncés à partir du seul fichier de configuration, c'est que vous savez ce que contient chaque couche.

Résultat

2,779 T de paramètres au total et 104,0 G activés par jeton, contre 2,78 T et 104,2 G annoncés. Écart : 0,2 %.

Les constantes de départ

Toutes lues dans config.json :

d      = 7168     # hidden_size
L      = 93       # num_hidden_layers
nMLA   = 24       # len(full_attn_layers)
nKDA   = 69       # L - nMLA
V      = 163840   # vocab_size

ell    = 3584     # routed_expert_hidden_size  (largeur latente)
dm     = 3072     # moe_intermediate_size
E      = 896      # num_experts
k      = 16       # num_experts_per_token
Ns     = 2        # num_shared_experts
Ilarge = 33792    # intermediate_size (FFN dense de la couche 1)

H        = 96     # num_attention_heads
qlora    = 1536   # q_lora_rank
kvlora   = 512    # kv_lora_rank
qk_nope  = 128    # qk_nope_head_dim
qk_rope  = 64     # qk_rope_head_dim
vh       = 128    # v_head_dim
kda_hd   = 128    # linear_attn_config.head_dim
kda_H    = 96     # linear_attn_config.num_heads

Bloc 1 — un expert routé

Un expert est un FFN à porte (gate, up, down) opérant dans l'espace latent de dimension \(\ell\), avec une dimension interne \(d_m\) :

\[ P_{\text{expert}} = 3 \times \ell \times d_m = 3 \times 3584 \times 3072 = 33{,}03 \text{ M} \]

Le piège

Ne pas utiliser \(d = 7168\) ici. Les experts routés travaillent en dimension latente \(\ell = 3584\), c'est tout l'intérêt de LatentMoE. Utiliser \(d\) doublerait le total et donnerait ~5,5 T.

Bloc 2 — une couche MoE complète

Composant Formule Valeur
896 experts routés \(896 \times 33{,}03\) M 29,60 G
\(\mathbf{W}^{\downarrow}\) + \(\mathbf{W}^{\uparrow}\) \(2 \times d \times \ell = 2 \times 7168 \times 3584\) 51,4 M
2 experts partagés \(3 \times d \times (d_m \times N_s) = 3 \times 7168 \times 6144\) 132,1 M
Routeur \(d \times E = 7168 \times 896\) 6,4 M
Total par couche MoE 29,78 G

Le point qui lève l'ambiguïté du rapport

Le rapport ne dit pas quelle dimension intermédiaire ont les experts partagés. Deux lectures possibles :

Hypothèse Experts partagés / couche Total du modèle
intermédiaire = \(I_{\text{large}} = 33792\) 726,7 M > 2,80 T ❌
intermédiaire = \(N_s \times d_m = 6144\) 132,1 M 2,779 T ✅

Seule la seconde reconstitue les totaux annoncés. C'est la contrainte d'arithmétique qui tranche l'ambiguïté du texte.

Sur les 92 couches MoE (toutes sauf la couche 1, dense) :

\[ 92 \times 29{,}78 \text{ G} = 2\,740 \text{ G} = \mathbf{2{,}74\ T} \]

Bloc 3 — une couche Gated MLA

Composant Formule Valeur
Compression Q \(d \times q_{\text{lora}}\) 11,0 M
Décompression Q \(q_{\text{lora}} \times H \times (128+64)\) 28,3 M
Compression KV \(d \times (kv_{\text{lora}} + 64)\) 4,1 M
Décompression KV \(kv_{\text{lora}} \times H \times (128+128)\) 12,6 M
Projection de sortie \(H \times v_h \times d\) 88,1 M
Porte de rang plein \(\mathbf{W}_g\) \(d \times H \times v_h\) 88,1 M
Total par couche MLA 232,2 M

Sur 24 couches : 5,57 G.

La porte coûte autant que la sortie

\(\mathbf{W}_g\) pèse exactement autant que \(\mathbf{W}_o\) : 88 M, soit 38 % de la couche. C'est le prix du passage au rang plein décidé par K3.

Bloc 4 — une couche KDA

Composant Formule Valeur
Projections Q, K, V \(3 \times d \times (H \times 128)\) 264,2 M
Projection de sortie \(H \times 128 \times d\) 88,1 M
Porte de rang plein \(\mathbf{W}_g\) \(d \times H \times 128\) 88,1 M
ShortConv, \(\mathbf{W}_\beta\), \(\mathbf{W}_\alpha\) rang faible — négligeable
Total par couche KDA 440,4 M

Sur 69 couches : 30,4 G.

Pourquoi KDA est presque deux fois plus lourd que MLA

KDA projette à pleine largeur (\(7168 \to 12288\)) pour Q, K et V, soit trois matrices de 88 M. MLA compresse par des goulots de rang faible (512 et 1 536).

C'est le compromis : KDA n'a rien à compresser, puisqu'il ne stocke aucun cache qui croisse.

Bloc 5 — le reste

Composant Formule Valeur
Embedding \(V \times d = 163840 \times 7168\) 1,17 G
lm_head (non lié) \(V \times d\) 1,17 G
FFN dense (couche 1) \(3 \times d \times I_{\text{large}}\) 0,73 G
Encodeur visuel — 0,40 G

Le total

\[ \begin{aligned} \text{Total} &= 92 \times 29{,}78 + 24 \times 0{,}232 + 69 \times 0{,}440 + 0{,}73 + 2{,}35 \\ &= 2\,740 + 5{,}57 + 30{,}4 + 0{,}73 + 2{,}35 \\ &= \mathbf{2\,779\ \text{G} = 2{,}779\ \text{T}} \end{aligned} \]

Annoncé : 2,78 T. Écart : 0,04 %.

Les paramètres activés

Seuls 16 des 896 experts travaillent par jeton. Tout le reste est actif.

Composant Valeur
16 experts routés × 92 couches \(92 \times 16 \times 33{,}03\) M = 48,6 G
\(\mathbf{W}^{\downarrow},\mathbf{W}^{\uparrow}\) × 92 4,73 G
Experts partagés × 92 12,15 G
Routeurs × 92 0,59 G
Couches MLA (24) 5,57 G
Couches KDA (69) 30,4 G
FFN dense 0,73 G
lm_head 1,17 G
Total activé 104,0 G

Annoncé : 104,2 G. Écart : 0,2 %.

La vérification est concluante

Deux quantités indépendantes reconstruites à 0,2 % près à partir du seul fichier de configuration. Cela valide à la fois la compréhension de l'architecture et la cohérence de ce que Moonshot a publié.

Les 0,2 % résiduels s'expliquent par les termes négligés : projections de rang faible du gate \(\alpha\) de KDA, noyaux de ShortConv, gains de RMSNorm, biais par tête. Tous marginaux.

Le code

Extrait du script de vérification (verif-kimi-k3.py) :

def param_counts():
    d, L, nMLA, nKDA, V = 7168, 93, 24, 69, 163840
    ell, dm, E, k, Ns = 3584, 3072, 896, 16, 2
    qlora, kvlora, qk_nope, qk_rope, vh, H = 1536, 512, 128, 64, 128, 96
    kda_hd, kda_H, Ilarge = 128, 96, 33792

    exp = 3 * ell * dm                                    # un expert routé
    moe = E * exp + (d * ell + ell * d) \
        + 3 * d * (dm * Ns) + d * E                       # une couche MoE
    mla = (d * qlora + qlora * H * (qk_nope + qk_rope)) \
        + d * (kvlora + qk_rope) \
        + kvlora * H * (qk_nope + vh) \
        + H * vh * d + d * H * vh                         # une couche MLA
    kda = 3 * (d * kda_H * kda_hd) + (kda_H * kda_hd * d) \
        + (d * kda_H * kda_hd)                            # une couche KDA
    dense = 3 * d * Ilarge

    total = 92 * moe + nMLA * mla + nKDA * kda + dense + 2 * V * d
    act = 92 * (k * exp + 2 * d * ell + 3 * d * dm * Ns + d * E) \
        + nMLA * mla + nKDA * kda + dense + V * d
    return total, act

Sortie vérifiée :

total = 2.779 T (papier 2,78 T)
actifs = 104.0 G (papier 104,2 G)

Exercices

Combien pèserait Kimi K3 avec 8 experts actifs au lieu de 16 ?

Les experts routés actifs passeraient de 48,6 G à 24,3 G. Le total activé tomberait à 79,7 G, soit −23 %. Le total de paramètres serait inchangé : c'est un paramètre de routage, pas de taille.

Quelle serait la taille du modèle si les experts opéraient à pleine largeur (\(\ell = d\)) ?

Un expert coûterait \(3 \times 7168 \times 3072 = 66{,}1\) M au lieu de 33,0 M. Les experts routés d'une couche : 59,2 G. Sur 92 couches : 5,45 T. Le modèle ferait environ 5,5 T — soit le double. C'est exactement l'économie que réalise LatentMoE.

Quelle part du modèle un jeton « voit-il » ?

\(104{,}0 / 2\,779 = 3{,}7\ \%\). Un jeton traverse moins de 4 % du modèle. Mais 100 % des paramètres doivent être résidents en mémoire, puisqu'on ne sait pas à l'avance quels experts seront choisis.


Chapitre précédent : Ce qui est public · Chapitre suivant : Implémenter KDA