Le model extraction est l'attaque qui transforme une API LLM publique en dataset d'entraînement pour cloner le modèle sous-jacent. Ce n'est plus de la recherche académique : le débat DeepSeek vs OpenAI en janvier 2025 a publiquement illustré la maturité économique et technique de cette classe. Pour 100k-1M de requêtes (selon objectif), un acteur peut produire un modèle élève qui imite à 70-95% les capacités du modèle cible. Les CGU des grands fournisseurs (OpenAI, Anthropic, Google) interdisent explicitement la pratique — mais la détection reste difficile et la juridiction floue.
Cet article documente les 5 vecteurs principaux (distillation comportementale, logit extraction, embedding extraction, equation solving, behavioral cloning multi-tour), les cas publics (Tramèr et al. 2016 pour l'ML classique, Carlini et al. 2021-2023 pour les LLMs, débat DeepSeek/OpenAI 2025), et les défenses côté fournisseur (rate limiting, output perturbation, watermarking, monitoring) et côté consommateur (CGU, audit, traçabilité).
Pour le contexte global model attacks : model poisoning, data poisoning.
Mental model : l'API comme oracle
Une API LLM exposée publiquement est, du point de vue de l'attaquant, un oracle qui prend un input et retourne un output. Si suffisamment de paires (input, output) sont collectées, on peut entraîner un modèle élève qui apprend la fonction sous-jacente.
Trois propriétés rendent l'attaque économiquement viable en 2026 :
- Architectures de distillation efficaces : MiniLM, DistilBERT, et plus récemment LoRA fine-tuning sur sorties de modèles grands rendent l'entraînement d'un élève rentable.
- Coût d'inférence en chute : les API LLM sont moins chères qu'elles ne l'étaient. Le ratio coût d'extraction / valeur du modèle tend vers zéro.
- Modèles open-weights matures : un attaquant peut prendre un modèle open-weights (Llama, Mistral, Qwen) et le fine-tuner sur des sorties d'un modèle cible — la différence de capacité s'estompe rapidement.
Info — Catégorie OWASP : LLM10 Unbounded Consumption dans la v2 2025 (qui inclut explicitement le risque d'extraction). Aussi : LLM03 Supply Chain si l'attaquant utilise le modèle volé en aval.
Cinq vecteurs de model extraction
Vecteur 1 — Behavioral cloning / distillation comportementale
Le scénario le plus courant : l'attaquant émet des centaines de milliers à millions de prompts, collecte les réponses, et fine-tune un modèle de base (open-weights) sur ces paires.
# Pseudocode du pipeline d'extraction
def extract_behavior(target_api, num_prompts: int):
# 1. Génération de prompts diversifiés
prompts = []
for category in CATEGORIES: # code, math, raisonnement, qa, créatif
prompts.extend(generate_prompts(category, count=num_prompts // len(CATEGORIES)))
# 2. Collecte des sorties
pairs = []
for prompt in prompts:
response = target_api.complete(prompt, temperature=0.0) # déterministe
pairs.append({"prompt": prompt, "completion": response})
time.sleep(rate_limit_delay) # rester sous le radar
# 3. Fine-tuning du modèle élève
student = load_model("Llama-3-8B-base")
student.fine_tune(pairs, epochs=3, lr=2e-5)
return studentC'est la mécanique à l'origine de la plupart des allégations d'extraction non-autorisée. Très simple à implémenter, difficile à détecter individuellement.
Vecteur 2 — Logit extraction
Si l'API expose les logits (scores avant softmax) ou les log-probabilities (paramètre logprobs chez OpenAI/Anthropic), l'efficacité de l'extraction augmente significativement. Au lieu d'apprendre seulement le token retenu, l'élève apprend la distribution complète du modèle.
# OpenAI API : récupérer top_logprobs
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
logprobs=True,
top_logprobs=20, # distribution top-20 par token
)
# La response contient maintenant les distributions, pas seulement les tokensAvec les logits, le ratio "queries pour atteindre fidélité X" est divisé par 5-10. C'est pourquoi les fournisseurs limitent souvent l'accès aux logits aux clients enterprise sous contrat.
Recherche académique de référence : Carlini et al., "Stealing Part of a Production Language Model" (2024) — démontre l'extraction partielle de la couche d'embedding de modèles propriétaires via logits.
Vecteur 3 — Embedding extraction
Si l'API expose une fonction d'embedding (text-embedding-3-large, voyage-large-2, etc.), l'attaquant peut extraire la fonction d'embedding elle-même, ou utiliser les embeddings pour reconstruire les documents (cf. Vec2Text — voir pentester base vectorielle).
L'extraction de la fonction d'embedding permet de répliquer un service de retrieval ou de classification sans payer le fournisseur original.
Vecteur 4 — Equation solving (modèles classiques)
Pour les modèles ML classiques (régression, SVM, arbres), Tramèr et al., "Stealing Machine Learning Models via Prediction APIs" (USENIX 2016) ont démontré qu'un nombre fini de requêtes algébriquement choisies suffit à reconstituer exactement les paramètres. Sur les LLMs (millions/milliards de paramètres), cette attaque exacte est inopérante, mais le concept transposé — attaque par requêtes optimisées — reste pertinent pour les composants linéaires (couches d'embedding, classification heads).
Vecteur 5 — Behavioral cloning multi-tour
Variante sophistiquée : au lieu de prompts/réponses isolés, l'attaquant émet des conversations multi-tour complètes pour capturer le comportement contextuel (mémoire de session, raisonnement chaîné, gestion d'instructions complexes).
def extract_multi_turn_behavior(target_api):
pairs = []
for scenario in MULTI_TURN_SCENARIOS:
conversation = []
for turn in scenario.turns:
conversation.append({"role": "user", "content": turn})
response = target_api.chat(messages=conversation)
conversation.append({"role": "assistant", "content": response})
pairs.append({"messages": conversation})
return pairsC'est la méthode la plus "haut signal" pour cloner les capacités conversationnelles avancées.
Cas publics et littérature
| Source | Année | Type |
|---|---|---|
| Tramèr et al. — "Stealing ML Models via Prediction APIs" | 2016 | Fondement (ML classique) |
| Krishna et al. — "Thieves on Sesame Street!" | 2020 | Extraction BERT-like |
| Carlini et al. — "Extracting Training Data from LLMs" | 2021 | Adjacent (training data) |
| Kirchenbauer et al. — "A Watermark for LLMs" | 2023 | Défense par watermark |
| Carlini et al. — "Stealing Part of a Production LM" | 2024 | Extraction couche embedding |
| Débat DeepSeek vs OpenAI | janvier 2025 | Cas industriel public majeur |
| Various academic papers on LLM distillation | 2023-2025 | Méthodes raffinées |
| OpenAI / Anthropic / Google ToS clauses anti-distillation | 2023+ | Réponse contractuelle |
Le débat DeepSeek vs OpenAI (janvier 2025) est devenu la référence industrielle. Au-delà du fond technique, il a relancé trois efforts : watermarking côté OpenAI/Anthropic, monitoring d'extraction côté API gateways, régulation IP IA côté EU AI Act et US Executive Orders.
Défenses côté fournisseur
Six couches indépendantes. Aucune isolément ne suffit.
Couche 1 — Rate limiting progressif
class ProgressiveRateLimiter:
"""Quotas progressifs avec détection de patterns d'extraction."""
BASE_TIER = {"per_minute": 60, "per_hour": 1000, "per_day": 10_000}
def check_and_consume(self, account_id: str, tokens: int) -> bool:
usage = self.get_usage(account_id)
# Quotas hard
if usage.per_minute > self.BASE_TIER["per_minute"]:
return False
if usage.per_hour > self.BASE_TIER["per_hour"]:
self.alert("rate_anomaly", account_id)
return False
# Quotas progressifs : si pattern d'extraction, durcissement
if self.is_extraction_pattern(account_id):
self.alert("extraction_pattern", account_id)
return False
return True
def is_extraction_pattern(self, account_id: str) -> bool:
"""Heuristiques : volume + diversité + temporalité."""
history = self.get_history(account_id, hours=24)
if len(history) < 1000:
return False
# Diversité sémantique élevée (couvre large surface)
if self.semantic_diversity(history) > 0.85:
return True
# Temporalité régulière (script systématique)
if self.temporal_regularity(history) > 0.9:
return True
return FalseCouche 2 — Pas d'exposition de logits par défaut
Réserver logprobs aux comptes enterprise sous contrat avec clauses anti-distillation. Pour les autres : top-1 token uniquement.
Couche 3 — Output perturbation
Ajouter du bruit contrôlé (pas perçu par l'utilisateur final) qui dégrade la qualité de distillation.
def perturbed_sampling(logits: np.ndarray, temperature: float = 1.0,
top_p: float = 0.9, perturbation: float = 0.02) -> int:
"""Sampling avec léger bruit anti-extraction."""
# 1. Apply temperature + top-p classique
probs = softmax(logits / temperature)
probs = top_p_filter(probs, top_p)
# 2. Petite perturbation aléatoire sur les tokens non-top-1
if perturbation > 0:
noise = np.random.uniform(-perturbation, perturbation, size=probs.shape)
# Préserver ordre du top-1 (qualité user)
top1_idx = np.argmax(probs)
noise[top1_idx] = 0.0
probs = probs + noise
probs = np.clip(probs, 0, None)
probs = probs / probs.sum()
return np.random.choice(len(probs), p=probs)L'effet : un attaquant qui distille obtient un modèle bruité. Un utilisateur normal ne perçoit pas la dégradation (qualité top-1 préservée).
Couche 4 — Watermarking statistique
Référence : Kirchenbauer et al. (2023). Mécanisme : à chaque token, séparer le vocabulaire en "green list" et "red list" via hash du contexte. Forcer la génération vers la green list. Statistiquement détectable par celui qui possède la clé.
# Schéma simplifié Kirchenbauer-like
def watermarked_sampling(logits, prev_tokens, secret_key, gamma=0.25, delta=2.0):
"""Soft watermark : biais vers green list."""
h = hash(tuple(prev_tokens[-3:]) + (secret_key,))
rng = np.random.default_rng(h)
n_vocab = len(logits)
green_list_size = int(gamma * n_vocab)
green_indices = rng.choice(n_vocab, green_list_size, replace=False)
# Biais delta sur logits des tokens green
biased_logits = logits.copy()
biased_logits[green_indices] += delta
return sample(biased_logits)
def detect_watermark(text: str, secret_key) -> dict:
"""Test statistique : compter tokens green dans le texte."""
tokens = tokenize(text)
n_green = 0
for i in range(3, len(tokens)):
h = hash(tuple(tokens[i-3:i]) + (secret_key,))
rng = np.random.default_rng(h)
green_indices = rng.choice(VOCAB_SIZE, int(GAMMA * VOCAB_SIZE), replace=False)
if tokens[i] in green_indices:
n_green += 1
expected = (len(tokens) - 3) * GAMMA
z = (n_green - expected) / np.sqrt(expected * (1 - GAMMA))
return {"z_score": z, "is_watermarked": z > 4.0} # seuil 4-sigmaLimites : paraphrasing ou traduction multilingue cassent le signal à coût modéré. Le watermark est un signal de probabilité forte, pas une preuve.
Couche 5 — Monitoring patterns d'extraction
Métriques à pousser au SIEM :
| Signal | Seuil typique | Action |
|---|---|---|
| Volume / compte / 24h | > 50k requêtes | Alerte + review |
| Diversité sémantique | > 0.85 | Alerte |
| Régularité temporelle | > 0.9 | Alerte |
| Demande logits + volume élevé | combiné | Alerte critique |
| Pattern de prompt augmentation | détectable | Alerte |
| Géographie / horaire atypique | hors norme client | Alerte |
Couche 6 — CGU et enforcement légal
Toutes les CGU des grands fournisseurs (OpenAI, Anthropic, Google) interdisent explicitement la distillation/extraction. Côté fournisseur, capacité d'enforcement : suspension de compte, action légale (cease & desist, dommages selon juridiction).
EU AI Act introduit des notions de traçabilité de modèle qui appuient l'enforcement. US Executive Orders 2024-2025 sur l'IA mentionnent le model theft comme préoccupation nationale.
Défenses côté consommateur
Si on est l'utilisateur d'une API LLM tierce :
- Lire et respecter les CGU — exposition juridique sinon.
- Audit trail des requêtes émises (qui, quoi, quand) pour pouvoir prouver usage légitime.
- Pas de pipeline automatisé qui ressemble à de la distillation (volume + diversité + collecte structurée des sorties).
- Si entraînement de modèle interne : utiliser un dataset acquis ou généré sous licence appropriée, pas par scraping d'API tierce.
- Documentation des sources : traçabilité de la provenance des données d'entraînement (exigence EU AI Act pour les modèles à haut risque).
Tests d'audit (côté fournisseur)
Méthodologie en 5 phases :
- Audit des protections en place : rate limiting, perturbation, watermarking, monitoring.
- Test red team : simuler une campagne d'extraction (volume contrôlé) et mesurer si elle est détectée.
- Test de qualité de watermark : paraphraser des sorties, mesurer si le watermark survit.
- Audit de la chaîne d'enforcement : si signal détecté, est-ce que le compte est suspendu rapidement ? Est-ce que le légal est saisi ?
- Documentation conformité : traçabilité des décisions, alignment EU AI Act / NIST / sectoriel.
Mapping OWASP LLM Top 10 v2
| OWASP | Lien model extraction |
|---|---|
| LLM10 Unbounded Consumption | Catégorie centrale (rebaptisée v2 spécifiquement) |
| LLM03 Supply Chain | Modèle volé utilisé en aval |
| LLM07 System Prompt Leakage | Adjacent (extraction de prompts/configs) |
| LLM02 Sensitive Information Disclosure | Si extraction révèle données entraînement |
LLM10 a été spécifiquement renommée en v2 2025 (de DoS à Unbounded Consumption) pour mieux capter cette classe d'attaque longue (consommation de ressources sur la durée).
Points clés à retenir
- Le model extraction est devenu une menace industrielle réelle en 2025-2026. Le débat DeepSeek vs OpenAI (janvier 2025) est le cas public de référence.
- 5 vecteurs : behavioral cloning (distillation classique), logit extraction, embedding extraction, equation solving (modèles classiques), multi-turn cloning.
- Coût économique d'extraction d'un modèle frontier : décennies à des heures, devenu accessible (100k-100M requêtes selon objectif).
- Défense fournisseur en 6 couches : rate limiting progressif, pas de logits par défaut, output perturbation, watermarking statistique (Kirchenbauer 2023), monitoring patterns, CGU + enforcement légal.
- Limites du watermarking : paraphrasing et traduction cassent le signal. C'est un signal fort, pas une preuve juridique seule.
- Côté consommateur : respecter les CGU, audit trail, pas de pipeline ressemblant à de la distillation, documentation des sources d'entraînement.
- OWASP : LLM10 Unbounded Consumption (catégorie centrale, renommée v2 2025 pour capturer cette classe).
- Test minimum d'audit : red team simulation extraction, paraphrasing du watermark, audit chaîne d'enforcement.
Le model extraction n'est plus un risque théorique de papier académique. C'est un risque économique mesurable, un sujet juridique actif, et un travail défensif continu pour les fournisseurs LLM. Pour les consommateurs, le terrain est dual : ne pas être complice involontairement, ne pas être suspecté à tort.







