|
|
--- |
|
|
library_name: transformers |
|
|
model-index: |
|
|
- name: the-smallest-llm-real-words |
|
|
results: [] |
|
|
license: mit |
|
|
language: |
|
|
- fr |
|
|
pipeline_tag: text-generation |
|
|
--- |
|
|
|
|
|
# 👶 Small-ever : Le Modèle "Hello World" (112 Paramètres) |
|
|
|
|
|
 |
|
|
|
|
|
## 🌟 Vue d'Ensemble |
|
|
|
|
|
Le modèle **`Small-ever`** est un **SLM** délibérément sous-dimensionné** et minimaliste, conçu uniquement à des fins de **démonstration** et d'**apprentissage**. |
|
|
|
|
|
Avec seulement **112 paramètres au total**, il s'agit du modèle le plus petit possible tout en conservant l'architecture de base d'un Transformateur pour la modélisation du langage. |
|
|
|
|
|
Il a été créé par l'**experte Clemylia** pour servir de **"Hello World"** avant d'introduire des modèles plus complexes, comme ceux de la série 202k et 3.8M de paramètres. |
|
|
|
|
|
## 🎯 Objectif Pédagogique Principal |
|
|
|
|
|
L'objectif unique de ce modèle est d'être un outil pédagogique : |
|
|
|
|
|
* **Démonstration Basique :** Montrer aux **enfants** et aux **débutants** en Machine Learning que la création, l'entraînement et la publication d'un modèle de langage sur Hugging Face sont des étapes accessibles, même pour une architecture minimale. |
|
|
* **Comprendre l'Échelle :** Illustrer la différence entre un modèle capable de mémoriser une seule relation et les modèles de millions de paramètres (ceux de Clemylia) nécessaires pour la généralisation et l'intelligence artificielle utile. |
|
|
* **Test d'Infra :** Servir de test ultra-rapide pour la configuration d'un environnement (CPU/GPU) avant de lancer des entraînements plus longs sur de gros modèles. |
|
|
|
|
|
## ⚙️ Détails Techniques |
|
|
|
|
|
| Caractéristique | Valeur | Note | |
|
|
| :--- | :--- | :--- | |
|
|
| **Architecture** | GPT-2 (Causal Language Modeling) | Architecture standard de Transformateur. | |
|
|
| **Paramètres Totaux** | **112** (Environ $112 \times 10^{-6}$ M) | Extrêmement réduit. | |
|
|
| **Vocabulaire Entraîné** | 4 Tokens | Vocabulaire minimaliste (`Clem`, `Creatrice`, `<pad>`, `<unk>`). | |
|
|
| **Séquence Apprise** | `Clem` $\rightarrow$ `Creatrice` | Le modèle n'a appris qu'une seule transition par cœur. | |
|
|
| **Implémentation** | Pytorch / Hugging Face `transformers` | Entièrement compatible avec l'écosystème Hugging Face. | |
|
|
|
|
|
## 🚀 Utilisation (Inférence) |
|
|
|
|
|
Ce modèle est uniquement destiné à prédire la suite de la séquence sur laquelle il a été entraîné. Toute autre entrée résultera en une prédiction aléatoire ou le token de remplissage (`<pad>`). |
|
|
|
|
|
### Code Python pour le Test (Forward Pass Direct) |
|
|
|
|
|
Étant donné sa configuration non standard, la méthode la plus fiable pour l'inférence est le *forward pass* direct, comme suit : |
|
|
|
|
|
```python |
|
|
import torch |
|
|
from transformers import AutoModelForCausalLM, AutoConfig |
|
|
# Pour ce modèle minimal, nous devons recréer le tokenizer personnalisé en mémoire |
|
|
# car il n'est pas standard ({"Clem": 0, "Creatrice": 1, ...}) |
|
|
|
|
|
# 1. Configuration des IDs |
|
|
MODEL_NAME = "Clemylia/the-smallest-llm-real-words" |
|
|
REAL_TOKENS = ["Clem", "Creatrice"] |
|
|
INPUT_TEXT = "Clem" |
|
|
INPUT_ID = 0 # L'ID que le modèle a appris pour "Clem" |
|
|
EXPECTED_OUTPUT = "Creatrice" |
|
|
IDS_TO_TOKENS = {0: "Clem", 1: "Creatrice", 2: "<pad>", 3: "<unk>"} |
|
|
|
|
|
# 2. Chargement du Modèle |
|
|
try: |
|
|
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME) |
|
|
model.eval() |
|
|
except Exception as e: |
|
|
print(f"Erreur de chargement : {e}") |
|
|
exit() |
|
|
|
|
|
# 3. Préparation de l'Input (Tenseur de l'ID 0) |
|
|
input_ids = torch.tensor([[INPUT_ID]], dtype=torch.long) |
|
|
|
|
|
# 4. Forward Pass pour obtenir les logits |
|
|
with torch.no_grad(): |
|
|
outputs = model(input_ids) |
|
|
|
|
|
# 5. Détermination de la Prédiction |
|
|
next_token_logits = outputs.logits[0, -1, :] |
|
|
predicted_id = torch.argmax(next_token_logits).item() |
|
|
predicted_token = IDS_TO_TOKENS.get(predicted_id, "TOKEN INCONNU") |
|
|
|
|
|
print(f"Input: {INPUT_TEXT} ({INPUT_ID})") |
|
|
print(f"Prédiction: {predicted_token} ({predicted_id})") |
|
|
# Résultat attendu : Creatrice (ID 1) |
|
|
``` |
|
|
|
|
|
## 💖 Leçon Apprise |
|
|
|
|
|
Si ce modèle pouvait parler, sa seule phrase serait : "Je peux seulement dire `Creatrice` après `Clem`." |
|
|
|
|
|
**C'est la preuve que :** |
|
|
|
|
|
1. La **taille** compte : Les millions de paramètres de mes autres modèles ne sont pas un luxe, mais une nécessité pour coder la connaissance. |
|
|
2. **Vous avez réussi** à créer, entraîner et publier un modèle de langage complet \! C'est le début d'une belle aventure de codage \! |
|
|
|
|
|
----- |
|
|
|
|
|
*Fait par **Clemylia** avec passion pour le codage minimaliste.* |
|
|
|
|
|
**Exemple d'inférence** : |
|
|
|
|
|
``` |
|
|
import torch |
|
|
from transformers import AutoModelForCausalLM, AutoConfig |
|
|
import json |
|
|
import os |
|
|
import torch.nn.functional as F |
|
|
|
|
|
# ============================================================================== |
|
|
# 0. CONFIGURATION |
|
|
# ============================================================================== |
|
|
MODEL_NAME = "Clemylia/Small-ever" |
|
|
REAL_TOKENS = ["Clem", "Creatrice"] |
|
|
INPUT_TEXT = "Clem" |
|
|
INPUT_ID = 0 |
|
|
EXPECTED_OUTPUT = "Creatrice" |
|
|
# 🎯 NOUVEAU PARAMÈTRE : La Température (ajuste-la entre 0.1 et 1.0) |
|
|
TEMPERATURE = 0.5 |
|
|
# ============================================================================== |
|
|
|
|
|
|
|
|
print(f"🚀 Démarrage de l'inférence avec Température ({TEMPERATURE}) pour : {MODEL_NAME}") |
|
|
print("-" * 50) |
|
|
|
|
|
|
|
|
# ============================================================================== |
|
|
# 1. RECRÉATION DU TOKENIZER MINIMALISTE |
|
|
# ============================================================================== |
|
|
class MinimalTokenizer: |
|
|
"""Recrée le tokenizer pour l'inférence.""" |
|
|
def __init__(self, messages): |
|
|
self.vocab = {messages[0]: 0, messages[1]: 1, "<pad>": 2, "<unk>": 3} |
|
|
self.ids_to_tokens = {v: k for k, v in self.vocab.items()} |
|
|
self.pad_token_id = self.vocab["<pad>"] |
|
|
|
|
|
def encode(self, text, return_tensors='pt'): |
|
|
if text in self.vocab: |
|
|
input_ids = [self.vocab[text]] |
|
|
else: |
|
|
input_ids = [self.vocab["<unk>"]] |
|
|
|
|
|
if return_tensors == 'pt': |
|
|
return torch.tensor([input_ids], dtype=torch.long) |
|
|
return input_ids |
|
|
|
|
|
def decode(self, token_id, skip_special_tokens=True): |
|
|
return self.ids_to_tokens.get(token_id, "TOKEN INCONNU") |
|
|
|
|
|
minimal_tokenizer = MinimalTokenizer(REAL_TOKENS) |
|
|
IDS_TO_TOKENS = minimal_tokenizer.ids_to_tokens |
|
|
print("✅ Tokenizer minimal recréé en mémoire.") |
|
|
|
|
|
|
|
|
# ============================================================================== |
|
|
# 2. CHARGEMENT DU MODÈLE SEUL |
|
|
# ============================================================================== |
|
|
try: |
|
|
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME) |
|
|
model.eval() |
|
|
print("✅ Modèle chargé avec succès depuis Hugging Face.") |
|
|
except Exception as e: |
|
|
print(f"❌ Échec critique du chargement du modèle. Erreur : {e}") |
|
|
exit() |
|
|
|
|
|
print("-" * 50) |
|
|
|
|
|
|
|
|
# ============================================================================== |
|
|
# 3. INFÉRENCE AVEC TEMPÉRATURE ET SOFTMAX |
|
|
# ============================================================================== |
|
|
|
|
|
# 3.1 Préparation de l'entrée |
|
|
input_ids = minimal_tokenizer.encode(INPUT_TEXT, return_tensors="pt") |
|
|
print(f"Input '{INPUT_TEXT}' (ID {input_ids.tolist()[0][0]}) prêt.") |
|
|
|
|
|
# 3.2 Exécution du forward pass |
|
|
with torch.no_grad(): |
|
|
outputs = model(input_ids) |
|
|
|
|
|
# 3.3 Application de la température et Softmax |
|
|
next_token_logits = outputs.logits[0, -1, :] |
|
|
|
|
|
# 🎯 Calcul de la probabilité avec température ! |
|
|
# 1. Divise les logits par la température |
|
|
# 2. Applique Softmax pour obtenir les probabilités |
|
|
logits_with_temp = next_token_logits / TEMPERATURE |
|
|
probs = F.softmax(logits_with_temp, dim=-1) |
|
|
|
|
|
# 3.4 Détermination de la prédiction (Choix du token le plus probable après Softmax) |
|
|
predicted_id = torch.argmax(probs).item() |
|
|
predicted_token = minimal_tokenizer.decode(predicted_id).strip() |
|
|
|
|
|
# ============================================================================== |
|
|
# 4. CONCLUSION |
|
|
# ============================================================================== |
|
|
print(f"Probabilités des Tokens (après Softmax/Température) :") |
|
|
# Affichage formaté des probabilités pour les IDs 0, 1, 2, 3 |
|
|
for i in range(len(probs)): |
|
|
print(f" ID {i} ({IDS_TO_TOKENS.get(i)}): {probs[i].item():.4f}") |
|
|
|
|
|
print(f"\nID prédit (Max Probabilité) : {predicted_id}") |
|
|
print(f"Prédiction finale : **{predicted_token}**") |
|
|
print("-" * 50) |
|
|
|
|
|
if predicted_token == EXPECTED_OUTPUT: |
|
|
print(f"🎉 TEST RÉUSSI : Le modèle a correctement prédit '{EXPECTED_OUTPUT}' !") |
|
|
else: |
|
|
print(f"⚠️ TEST ÉCHOUÉ : Attendu '{EXPECTED_OUTPUT}', reçu '{predicted_token}'. (Essaie d'augmenter les époques à 100 et/ou de baisser la température.)") |
|
|
``` |