Wiki IA
LLM et IA Générative

Small Language Models (SLM)

Modèles compacts pour l'edge AI - Phi, Gemma, Qwen et l'inférence on-device

Small Language Models (SLM)

Les Small Language Models sont des modèles de langage compacts (1-7B paramètres) optimisés pour fonctionner sur des appareils avec des ressources limitées : smartphones, ordinateurs portables, objets connectés.

Pourquoi les SLM ?

┌─────────────────────────────────────────────────────────────────┐
│                 LLM vs SLM : COMPROMIS                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  LARGE LANGUAGE MODELS (70B+)     SMALL LANGUAGE MODELS (1-7B) │
│  ┌─────────────────────────┐      ┌─────────────────────────┐  │
│  │ ✓ Capacités maximales   │      │ ✓ Fonctionne localement │  │
│  │ ✓ Raisonnement complexe │      │ ✓ Latence < 100ms       │  │
│  │ ✓ Multilingue complet   │      │ ✓ Vie privée totale     │  │
│  │ ✗ Cloud obligatoire     │      │ ✓ Gratuit à l'usage     │  │
│  │ ✗ Latence réseau        │      │ ✓ Fonctionne hors-ligne │  │
│  │ ✗ Coût par requête      │      │ ✗ Capacités réduites    │  │
│  │ ✗ Données envoyées      │      │ ✗ Contexte limité       │  │
│  └─────────────────────────┘      └─────────────────────────┘  │
│                                                                  │
│  GPU REQUIS:                       GPU REQUIS:                  │
│  A100/H100 (80GB VRAM)             RTX 3060 ou M1/M2/M3        │
│  ~$2-4/heure cloud                  Gratuit (votre matériel)   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Panorama des SLM en 2024

Microsoft Phi

┌─────────────────────────────────────────────────────────────────┐
│                    FAMILLE MICROSOFT PHI                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  PHI-1 (1.3B) ─────► PHI-2 (2.7B) ─────► PHI-3 (3.8B)          │
│     │                   │                    │                  │
│     │                   │                    ├── Phi-3-mini     │
│  Juin 2023          Déc 2023                ├── Phi-3-small    │
│  Code only          General                 └── Phi-3-medium   │
│                                                                  │
│  INNOVATION CLÉ: "Textbooks Are All You Need"                  │
│  - Données synthétiques de haute qualité                        │
│  - Filtrage agressif du contenu web                            │
│  - Curriculum learning (simple → complexe)                     │
│                                                                  │
│  PERFORMANCES (Phi-3-mini 3.8B):                               │
│  - MMLU: 69% (vs GPT-3.5: 70%)                                 │
│  - HumanEval: 58.5%                                             │
│  - Fonctionne sur iPhone                                        │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Google Gemma

# Gemma 2 - Modèle open source de Google
# Disponible en 2B, 9B et 27B paramètres

from transformers import AutoModelForCausalLM, AutoTokenizer

# Gemma 2B - fonctionne sur CPU
model = AutoModelForCausalLM.from_pretrained(
    "google/gemma-2-2b-it",  # "it" = instruction-tuned
    device_map="auto",
    torch_dtype="auto",
)
tokenizer = AutoTokenizer.from_pretrained("google/gemma-2-2b-it")

messages = [
    {"role": "user", "content": "Explique la photosynthèse en 3 phrases."}
]
prompt = tokenizer.apply_chat_template(messages, tokenize=False)
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)

outputs = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

Qwen (Alibaba)

┌─────────────────────────────────────────────────────────────────┐
│                      FAMILLE QWEN 2.5                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Qwen2.5-0.5B    Qwen2.5-1.5B    Qwen2.5-3B    Qwen2.5-7B       │
│      │              │              │              │              │
│  500M params     1.5B params    3B params     7B params         │
│  ~300MB          ~900MB         ~2GB          ~4GB              │
│                                                                  │
│  SPÉCIALISATIONS:                                               │
│  ├── Qwen2.5-Coder (code, 6 langages)                          │
│  ├── Qwen2.5-Math (mathématiques)                              │
│  └── Qwen2.5-VL (vision-langage)                               │
│                                                                  │
│  ATOUTS:                                                        │
│  ✓ Excellent support multilingue (29 langues)                  │
│  ✓ Contexte jusqu'à 128K tokens                                │
│  ✓ Licence Apache 2.0 (commercial OK)                          │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Llama 3.2 (Meta)

# Llama 3.2 - Versions légères pour mobile
# 1B et 3B paramètres optimisés pour l'edge

import torch
from transformers import pipeline

# Llama 3.2 1B - Ultra léger
pipe = pipeline(
    "text-generation",
    model="meta-llama/Llama-3.2-1B-Instruct",
    torch_dtype=torch.bfloat16,
    device_map="auto",
)

response = pipe(
    "Écris une fonction Python pour trier une liste.",
    max_new_tokens=200,
    do_sample=True,
    temperature=0.7,
)
print(response[0]["generated_text"])

Comparatif des SLM

ModèleTailleMMLUHumanEvalContexteLicence
Phi-3-mini3.8B69%58.5%128KMIT
Gemma-2-2B2B51%26%8KGemma
Qwen2.5-3B3B65%45%128KApache 2.0
Llama-3.2-3B3B63%48%128KLlama 3.2
Mistral-7B7B62%30%32KApache 2.0

Edge AI et inférence on-device

Architecture Edge

┌─────────────────────────────────────────────────────────────────┐
│                    ARCHITECTURE EDGE AI                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────┐                                               │
│  │   CLOUD      │  ← Modèles 70B+, entraînement                │
│  │   (backup)   │    Fallback pour tâches complexes            │
│  └──────┬───────┘                                               │
│         │ API (si nécessaire)                                   │
│         │                                                        │
│  ┌──────▼───────┐                                               │
│  │   EDGE       │  ← Serveur local, NAS, Raspberry Pi          │
│  │   SERVER     │    Modèles 7-13B, cache partagé              │
│  └──────┬───────┘                                               │
│         │ LAN                                                    │
│         │                                                        │
│  ┌──────▼───────┐                                               │
│  │   DEVICE     │  ← Smartphone, laptop, IoT                   │
│  │   (on-chip)  │    Modèles 1-3B, temps réel                  │
│  └──────────────┘                                               │
│                                                                  │
│  CRITÈRES DE ROUTAGE:                                           │
│  - Complexité de la tâche                                       │
│  - Sensibilité des données                                      │
│  - Latence requise                                              │
│  - Disponibilité réseau                                         │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Runtimes pour l'edge

# 1. LLAMA.CPP - C++ ultra-optimisé
# Installation: brew install llama.cpp (macOS)

# Depuis le terminal:
# ./llama-cli -m phi-3-mini-4k-instruct-q4_K_M.gguf \
#   -p "Explique le machine learning" \
#   -n 200

# 2. OLLAMA - Simplifié pour développeurs
"""
# Installation et utilisation Ollama
ollama pull phi3
ollama run phi3 "Qu'est-ce que l'edge computing?"

# API REST
curl http://localhost:11434/api/generate -d '{
  "model": "phi3",
  "prompt": "Hello!"
}'
"""

# 3. MLX (Apple Silicon)
import mlx.core as mx
from mlx_lm import load, generate

model, tokenizer = load("mlx-community/Phi-3-mini-4k-instruct-4bit")
response = generate(
    model,
    tokenizer,
    prompt="Écris un haiku sur l'IA",
    max_tokens=50
)
print(response)

Optimisations pour mobile

┌─────────────────────────────────────────────────────────────────┐
│              OPTIMISATIONS POUR MOBILE                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. QUANTIZATION                                                │
│     ├── FP32 → FP16 (÷2 mémoire)                               │
│     ├── FP16 → INT8 (÷2 mémoire)                               │
│     └── INT8 → INT4 (÷2 mémoire)                               │
│                                                                  │
│     Phi-3 3.8B:                                                 │
│     - FP32: 15.2 GB ❌                                          │
│     - FP16: 7.6 GB ❌                                           │
│     - INT8: 3.8 GB ⚠️                                           │
│     - INT4: 1.9 GB ✓ (iPhone 15 Pro)                           │
│                                                                  │
│  2. PRUNING (élagage)                                           │
│     Suppression des poids proches de zéro                       │
│     → 50-90% de sparsité possible                              │
│                                                                  │
│  3. DISTILLATION                                                │
│     Grand modèle → Petit modèle                                │
│     → Transfère les connaissances                              │
│                                                                  │
│  4. SPECULATIVE DECODING                                        │
│     Petit modèle génère drafts                                  │
│     Grand modèle valide en batch                                │
│     → 2-3x speedup                                              │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Cas d'usage edge

Assistant hors-ligne

import ollama

class OfflineAssistant:
    """Assistant fonctionnant entièrement hors-ligne"""

    def __init__(self, model="phi3"):
        self.model = model
        self.conversation = []

    def chat(self, message: str) -> str:
        self.conversation.append({
            "role": "user",
            "content": message
        })

        response = ollama.chat(
            model=self.model,
            messages=self.conversation,
            options={
                "num_ctx": 4096,  # Contexte limité pour la vitesse
                "temperature": 0.7,
            }
        )

        assistant_message = response["message"]["content"]
        self.conversation.append({
            "role": "assistant",
            "content": assistant_message
        })

        return assistant_message

# Utilisation
assistant = OfflineAssistant()
print(assistant.chat("Bonjour! Peux-tu m'aider avec Python?"))
# Fonctionne sans internet, données restent locales

Classification locale de documents

from transformers import pipeline
import torch

# Modèle léger pour classification
classifier = pipeline(
    "zero-shot-classification",
    model="MoritzLaworski/mDeBERTa-v3-base-mnli-xnli",  # 278M params
    device="mps" if torch.backends.mps.is_available() else "cpu"
)

def classify_document(text: str, labels: list[str]) -> dict:
    """Classifie un document localement"""
    result = classifier(
        text,
        candidate_labels=labels,
        multi_label=True
    )
    return {
        label: score
        for label, score in zip(result["labels"], result["scores"])
        if score > 0.3
    }

# Exemple
doc = "Le nouveau modèle Tesla atteint 600km d'autonomie"
categories = ["automobile", "technologie", "finance", "sport"]
print(classify_document(doc, categories))
# {'automobile': 0.92, 'technologie': 0.45}

IoT et capteurs intelligents

# Modèle minuscule pour microcontrôleurs
# TinyML avec TensorFlow Lite

"""
Exemple conceptuel pour ESP32 ou Raspberry Pi Pico
"""

class TinyPredictor:
    """Prédicteur ultra-léger pour microcontrôleur"""

    def __init__(self, model_path: str):
        # Modèle TFLite quantifié INT8 (~100KB)
        import tflite_runtime.interpreter as tflite
        self.interpreter = tflite.Interpreter(model_path=model_path)
        self.interpreter.allocate_tensors()

    def predict_anomaly(self, sensor_data: list[float]) -> bool:
        """Détecte anomalies sur données capteur"""
        input_details = self.interpreter.get_input_details()
        output_details = self.interpreter.get_output_details()

        # Préparer l'entrée
        import numpy as np
        input_data = np.array([sensor_data], dtype=np.float32)
        self.interpreter.set_tensor(input_details[0]['index'], input_data)

        # Inférence (~10ms sur ESP32)
        self.interpreter.invoke()

        # Résultat
        output = self.interpreter.get_tensor(output_details[0]['index'])
        return output[0][0] > 0.5  # Anomalie si > 0.5

# Déploiement sur device
predictor = TinyPredictor("anomaly_detector.tflite")
is_anomaly = predictor.predict_anomaly([23.5, 45.2, 1.02])

Déploiement d'un SLM

Application mobile avec Llama.cpp

// iOS - Utilisation de llama.cpp via Swift
import Foundation

class LocalLLM {
    private var context: OpaquePointer?

    init(modelPath: String) {
        // Initialiser llama.cpp
        var params = llama_model_default_params()
        params.n_gpu_layers = 1  // Utiliser le GPU si disponible

        let model = llama_load_model_from_file(modelPath, params)
        self.context = llama_new_context_with_model(model, llama_context_default_params())
    }

    func generate(prompt: String, maxTokens: Int = 100) -> String {
        // Tokenize et génère
        // ... implémentation llama.cpp
        return generatedText
    }
}

// Utilisation dans une app iOS
let llm = LocalLLM(modelPath: Bundle.main.path(forResource: "phi-3-mini", ofType: "gguf")!)
let response = llm.generate(prompt: "Bonjour!")

Serveur edge avec Ollama

# docker-compose.yml pour serveur edge
"""
version: '3.8'
services:
  ollama:
    image: ollama/ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]

volumes:
  ollama_data:
"""

# Client Python
import httpx

class EdgeLLMClient:
    def __init__(self, base_url="http://localhost:11434"):
        self.base_url = base_url
        self.client = httpx.Client(timeout=60.0)

    def generate(self, prompt: str, model: str = "phi3") -> str:
        response = self.client.post(
            f"{self.base_url}/api/generate",
            json={
                "model": model,
                "prompt": prompt,
                "stream": False,
            }
        )
        return response.json()["response"]

    def available_models(self) -> list[str]:
        response = self.client.get(f"{self.base_url}/api/tags")
        return [m["name"] for m in response.json()["models"]]

# Utilisation
client = EdgeLLMClient()
print(client.generate("Résume cet article: ..."))

Benchmarks edge

┌─────────────────────────────────────────────────────────────────┐
│              PERFORMANCES EDGE RÉELLES                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  DEVICE: MacBook Air M2 (8GB RAM)                               │
│  MODEL: Phi-3-mini-4k-instruct (Q4_K_M)                         │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ Métrique              │ Valeur                          │   │
│  ├─────────────────────────────────────────────────────────┤   │
│  │ Tokens/seconde        │ 35-40 tok/s                     │   │
│  │ Time to first token   │ ~200ms                          │   │
│  │ Mémoire utilisée      │ 2.1 GB                          │   │
│  │ Taille modèle         │ 2.2 GB (GGUF Q4)                │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                  │
│  DEVICE: iPhone 15 Pro (8GB RAM)                                │
│  MODEL: Phi-3-mini (CoreML INT4)                                │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ Métrique              │ Valeur                          │   │
│  ├─────────────────────────────────────────────────────────┤   │
│  │ Tokens/seconde        │ 15-20 tok/s                     │   │
│  │ Time to first token   │ ~500ms                          │   │
│  │ Impact batterie       │ Modéré                          │   │
│  │ Taille app            │ ~2 GB avec modèle               │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                  │
│  DEVICE: Raspberry Pi 5 (8GB)                                   │
│  MODEL: Gemma-2B (GGUF Q4)                                      │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ Métrique              │ Valeur                          │   │
│  ├─────────────────────────────────────────────────────────┤   │
│  │ Tokens/seconde        │ 5-8 tok/s                       │   │
│  │ Time to first token   │ ~2s                             │   │
│  │ Utilisable            │ Oui (tâches simples)            │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Limites et considérations

┌─────────────────────────────────────────────────────────────────┐
│                 LIMITES DES SLM                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ⚠ Capacités réduites vs grands modèles                        │
│    - Raisonnement multi-étapes limité                           │
│    - Moins fiable sur tâches complexes                          │
│    - Connaissances moins étendues                               │
│                                                                  │
│  ⚠ Trade-offs de la quantization                               │
│    - Légère perte de qualité (1-3%)                            │
│    - Certaines tâches sensibles à la précision                  │
│                                                                  │
│  ⚠ Maintenance                                                  │
│    - Mises à jour manuelles du modèle                          │
│    - Pas de correction automatique des bugs                     │
│                                                                  │
│  BONNES PRATIQUES:                                              │
│  ✓ Choisir le modèle adapté à la tâche                         │
│  ✓ Prévoir un fallback cloud pour cas complexes                │
│  ✓ Tester sur le hardware cible avant déploiement              │
│  ✓ Monitorer la qualité des réponses                           │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Pour aller plus loin

On this page