Aller au contenu

Vérification des paramètres et de la VRAM

Le décompte complet, pas à pas, depuis config.json.


La méthode

Une seule source d'entrée : config.json.

Une seule sortie observée pour contrôle : la taille du dépôt affichée par Hugging Face, 55,6 Go sur 18 fragments.

Tous les calculs sont dans le script joint, en Python pur, sans dépendance.


Étape 1 — La structure

"num_hidden_layers": 64,
"full_attention_interval": 4
\[ n_{\text{complètes}} = \frac{64}{4} = 16 \qquad n_{\text{linéaires}} = 64 - 16 = 48 \]

Confirmé par layer_types, qui contient 64 entrées suivant le motif [linéaire, linéaire, linéaire, complète] répété 16 fois.

Absence de MoE, établie par deux indices

intermediate_size: 17408 désigne un réseau dense classique, et il n'existe aucun champ num_experts, num_experts_per_tok ou moe_intermediate_size.

Le modèle active donc 100 % de ses paramètres à chaque jeton.


Étape 2 — Une couche d'attention complète

"num_attention_heads": 24,
"num_key_value_heads": 4,
"head_dim": 256,
"attn_output_gate": true
Projection Dimensions Paramètres
\(W_Q\) + porte \(5\,120 \times (24 \times 256 \times 2)\) 62 914 560
\(W_K\) \(5\,120 \times 1\,024\) 5 242 880
\(W_V\) \(5\,120 \times 1\,024\) 5 242 880
\(W_O\) \(6\,144 \times 5\,120\) 31 457 280
normalisations \(q\), \(k\) \(2 \times 256\) 512
Total 104 858 112
\[ 16 \times 104\,858\,112 = 1\,677\,729\,792 \approx 1{,}678\ \text{G} \]

Étape 3 — Une couche Gated DeltaNet

"linear_num_value_heads": 48,
"linear_num_key_heads": 16,
"linear_key_head_dim": 128,
"linear_value_head_dim": 128,
"linear_conv_kernel_dim": 4
\[ d_{qk} = 16 \times 128 = 2\,048 \qquad d_v = 48 \times 128 = 6\,144 \]
Composant Paramètres
in_proj_qkvz — \(5\,120 \times (2\,048 + 2\,048 + 6\,144 + 6\,144)\) 83 886 080
in_proj_ba — \(5\,120 \times 96\) 491 520
convolution causale — \(10\,240 \times 4\) 40 960
out_proj — \(6\,144 \times 5\,120\) 31 457 280
normalisation 128
Total 115 875 968
\[ 48 \times 115\,875\,968 = 5\,562\,046\,464 \approx 5{,}562\ \text{G} \]

Étape 4 — Le réseau dense

"intermediate_size": 17408,
"hidden_act": "silu"

SwiGLU à trois matrices :

\[ 3 \times 5\,120 \times 17\,408 = 267\,386\,880 \]
\[ 64 \times 267\,386\,880 = 17\,112\,760\,320 \approx 17{,}113\ \text{G} \]

61,7 % du modèle.


Étape 5 — Embeddings et tête

"vocab_size": 248320,
"hidden_size": 5120,
"tie_word_embeddings": false
\[ 248\,320 \times 5\,120 = 1\,271\,398\,400 \]

Les embeddings n'étant pas liés, la tête de sortie a ses propres poids :

\[ 2 \times 1\,271\,398\,400 = 2\,542\,796\,800 \approx 2{,}543\ \text{G} \]

Étape 6 — L'encodeur visuel

"vision_config": {
  "depth": 27, "hidden_size": 1152, "intermediate_size": 4304,
  "num_heads": 16, "patch_size": 16, "temporal_patch_size": 2,
  "spatial_merge_size": 2, "num_position_embeddings": 2304,
  "out_hidden_size": 5120
}
Composant Paramètres
Projection des carreaux — \(3 \times 2 \times 16^2 \times 1\,152\) 1 770 624
Embeddings de position — \(2\,304 \times 1\,152\) 2 654 208
27 blocs de Transformer 411 404 400
Module de fusion vers 5 120 44 838 656
Total ≈ 460,7 M

Cette étape est une reconstruction

La structure exacte des blocs et du module de fusion n'est pas documentée. Le calcul suppose un Transformer de vision standard et un module de fusion à deux couches.

C'est l'étape la moins certaine du décompte — et c'est l'accord final qui la valide.


Étape 7 — La couche MTP

"mtp_num_hidden_layers": 1,
"mtp_use_dedicated_embeddings": false

Si elle reproduit le motif du modèle — un bloc d'attention complète plus un réseau dense :

\[ 267\,386\,880 + 104\,858\,112 = 372\,244\,992 \approx 0{,}372\ \text{G} \]

mtp_use_dedicated_embeddings: false indique qu'elle réutilise la table d'embeddings principale — pas de 1,27 G supplémentaire.


Étape 8 — Le total et sa vérification

Composant Paramètres Part
Réseaux denses 17 112 760 320 61,7 %
Couches DeltaNet 5 562 046 464 20,1 %
Couches d'attention complète 1 677 729 792 6,1 %
Embeddings + tête 2 542 796 800 9,2 %
Encodeur visuel 460 667 888 1,7 %
Couche MTP 372 244 992 1,3 %
Normalisations ~660 480 ~0 %
Total 27 728 906 736 100 %
\[ \boxed{27{,}729\ \text{G}} \]

Étiquette Hugging Face : 28B. Écart : 0,97 %.

La vérification décisive

\[ 27\,728\,906\,736 \times 2\ \text{octets} = 55\,457\,813\,472\ \text{octets} = 55{,}46\ \text{Go} \]

Le dépôt affiche 55,6 Go. Écart : 0,26 %.

Ce que cet accord établit

Le décompte est cohérent de bout en bout — y compris les deux reconstructions des étapes 6 et 7.

Si l'encodeur visuel ou la couche MTP étaient significativement plus gros ou plus petits que calculés, l'écart de 0,26 % ne tiendrait pas : leurs 0,83 G combinés représentent 3 % du modèle, soit onze fois l'écart observé.

Ce que cet accord n'établit pas

La répartition entre les deux. Un encodeur de 500 M et une couche MTP de 330 M donneraient le même total.

Pour trancher, il faudrait inspecter l'index des safetensors du dépôt.


Étape 9 — La mémoire d'inférence

Le cache clé-valeur

\[ c = 16 \times 2 \times 4 \times 256 \times 2 = 65\,536\ \text{octets} = 64\ \text{KiO par jeton} \]
Contexte Cache
32 768 2,15 Go
262 144 17,18 Go
1 000 000 65,54 Go

Le contrefactuel

\[ 64 \times 4\,096 = 262\,144\ \text{octets} = 256\ \text{KiO par jeton} \]

À 262 144 jetons : 68,72 Go, soit quatre fois le cache réel.

L'état récurrent

\[ 48 \times 48 \times 128 \times 128 \times 4 = 150\,994\,944\ \text{octets} \approx 0{,}159\ \text{Go} \]

Constant, quelle que soit la longueur.


Récapitulatif

Vérification Calculé Référence Écart Statut
Paramètres totaux 27,729 G étiquette « 28B » 0,97 % ✅
Taille du dépôt 55,46 Go 55,6 Go observés 0,26 % ✅

Rejouer les calculs

python3 verif-qwen3-8-27b.py

Le script ne dépend de rien, ne lit rien en réseau, et sort avec un code non nul si une vérification échoue.