Réponse Rapide : En 2026, Fill-in-the-Middle (FIM) permet l'autocomplétion de code en temps réel (ghost text) dans les IDE en structurant les prompts avec des tokens de préfixe, de suffixe et de milieu (ex. <|fim_prefix|>, <|fim_suffix|>, <|fim_middle|>). Pour une inférence sous les 100 ms, Qwen 2.5 Coder 1.5B mène la précision sur une seule ligne (84,6% SantaCoder FIM) à 42 ms de TTFT, tandis que Qwen 2.5 Coder 7B domine la synthèse multiligne (76,8%) à 84 ms.
1. Introduction : Exigences de latence et de précision de l'autocomplétion Ghost-Text
L'ai code completion (autocomplétion de code par IA) et l'ai autocomplete en temps réel constituent les cas d'usage les plus exigeants en matière de latence dans l'intelligence artificielle appliquée. Alors que les agents conversationnels (tels que Claude Code, Aider ou OpenCode) peuvent allouer 1,5 à 5,0 secondes à la planification de refactorisations complexes, les suggestions inline dans l'éditeur (« ghost text ») doivent impérativement s'afficher en moins de 100 millisecondes pour préserver l'état de concentration du développeur.
+-----------------------------------------------------------------------------------------------+
| Budget de latence pour l'autocomplétion de code dans l'IDE |
+-----------------------------------------------------------------------------------------------+
| Debounce de frappe : 30ms - 50ms |
| Assemblage contexte : 10ms - 15ms (Tree-sitter AST, découpage préfixe/suffixe) |
| Réseau / Transport IPC: 5ms - 20ms (vLLM / llama.cpp local ou WebSocket d'entreprise) |
| Time-To-First-Token : 35ms - 55ms (Plafond sub-100ms pour le premier caractère) |
| Streaming de tokens : 15ms - 25ms (15-40 tokens à plus de 120 tokens/sec pour la ligne) |
+-----------------------------------------------------------------------------------------------+
| BUDGET TOTAL : 95ms - 145ms (Seuil de perception humaine pour une complétion directe) |
+-----------------------------------------------------------------------------------------------+
Chaque frappe au clavier déclenche un événement de modification du fichier. Si la suggestion met plus de 150 ms à apparaître, le développeur aura déjà tapé le caractère suivant, provoquant des scintillements et une dégradation sensible de l'expérience utilisateur.
Les modèles causaux classiques apprennent uniquement la prédiction du token suivant de gauche à droite :
$$P(W) = \prod_{i=1}^{n} P(w_i \mid w_1, w_2, \dots, w_{i-1})$$
Dans un éditeur de code, le développeur écrit rarement de manière strictement séquentielle. Il y a souvent du code existant après le curseur (fonctions, fermetures de blocs, imports). Si le modèle ne reçoit que le préfixe, il générera des doublons de parenthèses ou des signatures en conflit avec le code situé en aval.
D'où la nécessité de la génération de code Fill-in-the-Middle (FIM) : une approche qui conditionne l'inférence à la fois sur le Préfixe (code avant le curseur) et sur le Suffixe (code après le curseur) pour prédire exactement le bloc central manquant (Middle).
2. Architecture interne : Fonctionnement du Fill-in-the-Middle (FIM)
Introduit par les chercheurs d'OpenAI (Bavarian et al.) et démocratisé par StarCoder, DeepSeek Coder et Qwen 2.5 Coder, FIM transforme les modèles autorégressifs en moteurs bidirectionnels sans modifier la structure des couches d'attention du Transformer.
+-----------------------------------------------------------------------------------------------+
| Transformation Fill-in-the-Middle (FIM) |
+-----------------------------------------------------------------------------------------------+
| Document de code source original : |
| [ CODE AVANT LE CURSEUR (Prefix) ] [ CURSEUR (Middle) ] [ CODE APRÈS LE CURSEUR (Suffix) ] |
| |
| Transformation FIM (Mode PSM) : |
| <PRE> [ Tokens Préfixe ] <SUF> [ Tokens Suffixe ] <MID> ===> Le modèle prédit [ Middle ] |
| |
| Transformation FIM (Mode SPM) : |
| <SUF> [ Tokens Suffixe ] <PRE> [ Tokens Préfixe ] <MID> ===> Le modèle prédit [ Middle ] |
+-----------------------------------------------------------------------------------------------+
Modes PSM vs SPM
- Mode PSM (Prefix-Suffix-Middle) :
- Mode SPM (Suffix-Prefix-Middle) :
En intégrant 50% de données d'entraînement au format FIM, le modèle prédit mid_1 en prêtant attention à la totalité du préfixe et du suffixe simultanément.
3. Tokens Spéciaux FIM par Modèle (2026)
+-------------------------------------------------------------------------------------------------------------+
| Correspondance des Tokens FIM par Famille |
+--------------------+--------------------------+--------------------------+--------------------------+-------+
| Famille de modèle | Token Préfixe | Token Suffixe | Token Début Middle | Mode |
+--------------------+--------------------------+--------------------------+--------------------------+-------+
| Qwen 2.5 Coder | <|fim_prefix|> | <|fim_suffix|> | <|fim_middle|> | PSM |
| DeepSeek Coder V1/2| <|fim begin|> | <|fim hole|> | <|fim end|> | SPM |
| StarCoder / SC2 | <fim_prefix> | <fim_suffix> | <fim_middle> | PSM |
| Mistral Codestral | [PREFIX] | [SUFFIX] | [MIDDLE] | PSM |
| CodeLlama | <PRE> | <SUF> | <MID> | PSM |
+--------------------+--------------------------+--------------------------+--------------------------+-------+
4. Benchmarks des Modèles Sub-100ms
+---------------------------------------------------------------------------------------------------------------+
| BENCHMARK DES MODÈLES GHOST-TEXT SOUS LA BARRE DES 100MS |
+-----------------------+--------------------+-------------------+------------------+-------------+-------------+
| Modèle testé | Précision FIM | Précision Infill | Time-To-First- | Débit | Empreinte |
| | 1 ligne (Pass@1) | Multiligne(Pass@1)| Token (TTFT p50) | (Tokens/s) | VRAM (FP16) |
+-----------------------+--------------------+-------------------+------------------+-------------+-------------+
| Qwen 2.5 Coder 1.5B | 84,6% | 64,2% | 42 ms | 188 tok/s | 3,2 Go |
| Qwen 2.5 Coder 7B | 89,2% | 76,8% | 84 ms | 112 tok/s | 15,2 Go |
| DeepSeek Coder 1.3B | 78,4% | 56,1% | 39 ms | 196 tok/s | 2,8 Go |
| StarCoder2 3B | 81,1% | 60,5% | 58 ms | 144 tok/s | 6,4 Go |
+-----------------------+--------------------+-------------------+------------------+-------------+-------------+
5. Intégration IDE : Stratégie de Fenêtrage Asymétrique
Pour éviter d'exploser le budget de 100 ms sur de gros fichiers :
- Préfixe : 60% à 70% du contexte (1 500 à 3 000 tokens avant le curseur).
- Suffixe : 30% à 40% du contexte (500 à 1 500 tokens après le curseur).
- Définitions inter-fichiers : 300 tokens de types et signatures extraits via Tree-sitter AST.
6. Serveur de Complétion FIM en Python (FastAPI + vLLM)
import os, time
from typing import Optional, List
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx
app = FastAPI(title="FIM Fast Engine")
BACKEND_URL = os.getenv("INFERENCE_BACKEND_URL", "http://127.0.0.1:8000/v1/completions")
MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-Coder-1.5B")
class FIMRequest(BaseModel):
prefix: str
suffix: str
max_tokens: int = 48
temperature: float = 0.1
@app.post("/v1/autocomplete")
async def autocomplete(req: FIMRequest):
t0 = time.perf_counter()
prompt = f"<|fim_prefix|>{req.prefix}<|fim_suffix|>{req.suffix}<|fim_middle|>"
stops = ["<|fim_prefix|>", "<|fim_suffix|>", "<|fim_middle|>", "<|endoftext|>", "\n\n"]
payload = {
"model": MODEL_NAME, "prompt": prompt, "max_tokens": req.max_tokens,
"temperature": req.temperature, "stop": stops, "stream": False
}
async with httpx.AsyncClient(timeout=1.5) as client:
resp = await client.post(BACKEND_URL, json=payload)
data = resp.json()
return {
"completion": data["choices"][0]["text"],
"latency_ms": round((time.perf_counter() - t0) * 1000, 2)
}
7. Gestion des Arrêts & Filtres Anti-Doublons
- Toujours déclarer les tokens spéciaux FIM dans l'array
stop. - Arrêter la génération au double saut de ligne (
\n\n) pour les suggestions courtes. - Filtrer côté client les doublons de parenthèses ou d'accolades avec le suffixe existant.
8. Analyse des Coûts (TCO) pour 100 Développeurs
- 100 Développeurs : ~120 000 requêtes/jour (2,64M/mois).
- Abonnement Copilot : 1 900 $/mois (19 $/utilisateur).
- API Serverless (DeepInfra) : ~115,40 $/mois (0,05 $/1M tokens entrée).
- GPU Dédié Cloud (A10G) : 730 $/mois (confidentialité totale, latence <70ms).
- Exécution Locale (Mac M4 / RTX 4090) : 0 $/mois de frais cloud.
9. Conclusion et Recommandations
- Usage individuel en local : Qwen 2.5 Coder 1.5B avec
llama.cpp(42 ms TTFT, 3,2 Go de VRAM). - Serveur d'équipe centralisé : Qwen 2.5 Coder 7B sur vLLM (76,8% sur le multiligne).
- Plafonner le contexte : Moins de 2 000 tokens en préfixe et 800 en suffixe pour garantir un TTFT inférieur à 100 ms.