Aller au contenu
Gridpak

Streaming LLM : définition, frames et marqueur de fin

Maxime Aulne

Le streaming LLM consiste à recevoir une réponse de modèle petit à petit au lieu d’attendre la fin complète. C’est utile pour afficher rapidement le début d’une réponse ou alimenter une interface de chat. Ollama documente le streaming de son API et indique aussi comment le désactiver.

Frame, token et texte

Ne confondez pas les niveaux. Une frame HTTP ou SSE est un morceau transporté. Elle peut contenir un fragment de texte, un token, plusieurs tokens ou une métadonnée. Votre code doit assembler le contenu utile et attendre le marqueur de fin avant de considérer la réponse terminée.

Pourquoi c’est pratique

L’utilisateur voit que le modèle travaille. Pour un long texte, cela améliore l’expérience. Pour un traitement machine strict, le streaming complique parfois la validation JSON. Dans ce cas, désactivez-le ou validez seulement après réception complète.

Erreur fréquente

Beaucoup de scripts déclenchent une action dès qu’un morceau contient un mot attendu. C’est risqué : le modèle peut corriger la phrase ensuite. Attendez le signal de fin, puis parsez la réponse finale.

Bon usage

Chat humain : streaming activé. Extraction structurée : streaming désactivé ou buffer complet. Logs : conservez la réponse finale plutôt que chaque fragment si vous voulez rejouer ou auditer.

Implémentation robuste

Le client doit accumuler les fragments dans un buffer, gérer les lignes vides, ignorer les événements non textuels si l’API en envoie, puis fermer proprement au marqueur final. Si la connexion coupe au milieu, marquez la réponse comme incomplète. Ne sauvegardez pas une réponse partielle comme si elle était validée.

Interface utilisateur

Dans une interface, affichez le flux pour rassurer l’utilisateur, mais gardez les boutons d’action sensibles désactivés tant que la réponse n’est pas terminée. Pour un agent qui déclenche des outils, le streaming doit rester visuel : la décision d’action doit se faire sur une réponse complète et validée.

Stockage

Pour l’audit, stockez la réponse finale et les métadonnées utiles : modèle, heure, prompt, statut terminé ou interrompu. Stocker chaque fragment est rarement utile hors debug et peut rendre les logs illisibles.

Cas JSON

Pour du JSON strict, demandez une réponse non streamée quand c’est possible. Sinon, bufferisez toute la réponse, retirez les marqueurs éventuels, puis parsez une seule fois. Parser fragment par fragment crée des faux échecs.

Découpage réseau et découpage du message

Un morceau reçu sur le réseau peut s’arrêter au milieu d’une ligne JSON. À l’inverse, une lecture réseau peut contenir plusieurs événements. Le parseur doit reconstituer les messages selon le protocole annoncé par l’API, par exemple des objets JSON séparés par des retours à la ligne, et non supposer qu’une lecture égale un token.

La présence d’un début de réponse réduit l’attente perçue, pas nécessairement le temps total de calcul. Mesurez séparément le délai jusqu’au premier fragment et celui jusqu’à la fin si vous comparez des configurations. Un flux interrompu reste incomplet même si le texte affiché paraît grammaticalement terminé.

Sources