Le streaming est la solution la plus simple en termes d'expérience utilisateur et de coût. Les utilisateurs voient les mots plus tôt, annulent lorsqu'ils en ont assez et vous dépensez moins de jetons. Le streaming réduit la latence, ce qui est essentiel pour une expérience utilisateur fluide. Vous n'avez besoin que de deux choses : un serveur qui diffuse et un client qui lit des morceaux sans mise en mémoire tampon.
Essayez Compute dès aujourd'hui
Lancez un VllM serveur d'inférence activé Calculer. Vous obtenez un point de terminaison HTTPS avec des routes de style OpenAI qui diffusent par défaut. Dirigez votre SDK OpenAI existant vers la nouvelle URL de base et commencez à mesurer le TTFT.
Jetons de streaming : une comparaison entre SSE et WebSockets en anglais clair
Événements envoyés par le serveur (SSE). Diffusion unidirectionnelle via HTTP. SSE transmet les données du serveur au client via une connexion HTTP. Simple, compatible avec les proxys, idéal pour le streaming de jetons. L'API EventSource est normalisée dans le cadre du HTML Living Standard par le WHATWG. Fonctionne avec EventSource dans les navigateurs et avec des réponses en streaming dans la plupart des clients HTTP.
WebSockets. Messages bidirectionnels via un socket persistant. Les WebSockets utilisent le protocole WebSocket et sont gérés via un objet WebSocket, permettant une communication bidirectionnelle en temps réel entre le client et le serveur. Utile lorsque le client doit envoyer des événements en cours de traitement (saisie, synchronisation du curseur, modifications collaboratives). Le streaming de jetons est le mode dans lequel le serveur renvoie les jetons un par un au fur et à mesure que le modèle les génère.
Règle générale : utiliser SSE pour discuter sauf si vous avez vraiment besoin d'une messagerie bidirectionnelle. Avec le streaming de jetons, le serveur peut commencer à renvoyer des jetons avant de générer la réponse complète.
Quand utiliser quel
- VOIR : réponses au chat, résumés, génération de code, tout ce qui est en lecture seule dans le navigateur.
- WebSockets : éditeurs collaboratifs, flux vocaux, outils qui transmettent les mises à jour de milieu de génération du client au serveur, et applications du monde réel nécessitant une communication bidirectionnelle interactive.
- Mélangez : commencez par SSE ; ajoutez WS plus tard pour les quelques endroits qui en ont besoin. Les jetons de streaming sont des informations d'identification uniques et temporaires utilisées par les plateformes vidéo en ligne pour authentifier et autoriser l'accès d'un utilisateur à un flux vidéo spécifique.
Implémenter les événements envoyés par le serveur (SSE)
Node (SDK OpenAI, serveur compatible OpenAI)
importer OpenAI depuis « openai » ;
const client = new OpenAI ({baseUrl : "https://YOUR-ENDPOINT/v1 «, ApiKey : process.env.key}) ;
flux constant = wait client.chat.completions.create ({
modèle : « f3-7b-instruct »,
messages : [{role : « user », content : « Rédiger une brève mise à jour sur l'état du projet. »}],
stream : vrai,
nombre maximum de jetons : 200
}) ;
pour wait (partie constante du flux) {
const delta = chunk.choices ?. [0] ?. delta ?. contenu ;
if (delta) process.stdout.write (delta) ;
}
Python (SDK OpenAI, serveur compatible OpenAI)
depuis openai, importez OpenAI
client = OpenAI (base_url= » https://YOUR-ENDPOINT/v1 «, API_KEY="VOTRE_CLÉ »)
avec client.chat.completions.stream (
modèle="f3-7b-instruct »,
messages= [{"role » :"user », "content » :"Rédigez un résumé en un paragraphe. «}],
max_jetons=200,
) sous forme de flux :
pour l'événement en streaming :
si event.type == « jeton » :
imprimer (event.token, end= "»)
Annulez rapidement lorsque les utilisateurs arrêtent de lire :
contrôleur const = new AbortController () ;
//passe le signal : client.chat.completions.create ({..., stream : true, signal : controller.signal})
//plus tard
contrôleur.abort () ;
Implémenter WebSocket Server (lorsque vous avez besoin d'une solution bidirectionnelle)
Le serveur WebSocket établit une connexion Websocket persistante avec les clients, permettant ainsi une communication bidirectionnelle en temps réel. Lors de la première prise de contact, le serveur et le client échangent des en-têtes HTTP, notamment SEC-WebSocket-Key, SEC-WebSocket-Version et SEC-WebSocket-Protocol, pour mettre à niveau la connexion HTTP vers une connexion WebSocket et garantir la sécurité et la conformité du protocole.
//Esquisse du serveur à l'aide de ws
importer {WebSocketServer} depuis « ws » ;
const wss = nouveau WebSocketServer ({port : 8080}) ;
wss.on (« connexion », (ws) => {
ws.on (« message », async (msg) => {
const {prompt} = JSON.parse (msg.ToString ()) ;
//appelez votre terminal compatible OpenAI avec stream=true
pour await (jeton const de generateStream (prompt)) {
ws.send (token) ;//contre-pression : vérifiez WS.BufferedAmount
}
}) ;
ws.on (« fermer », () => {
//Gestion du nettoyage à la fermeture de la connexion
//Libérez des ressources ou effectuez tout nettoyage nécessaire ici
}) ;
}) ;
Lorsque la connexion se ferme, le serveur WebSocket déclenche un événement de fermeture, vous permettant de gérer le nettoyage et de libérer les ressources associées à cette connexion WebSocket.
Poignée contre-pression: pause lorsque WS.BufferedAmount est volumineux ; reprise lorsqu'il est vide. Dans les navigateurs, utilisez l'API streams avec reader.read () et respectez les signaux ReadableStreamDefaultReader.
Annulations, nouvelles tentatives, contre-pression
- Annulez rapidement. Branchez un bouton d'arrêt qui interrompt la requête HTTP ou ferme le socket. Des blocs de cache KV gratuits côté serveur sont immédiatement disponibles.
- Réessais. Utilisez un retard exponentiel avec de la gigue lors de la connexion et des erreurs au premier jeton. Ne réessayez pas après avoir diffusé du texte visible par l'utilisateur, sauf si vous recommencez clairement la réponse.
- Contre-pression. Dans Node, vérifiez les signaux res.flush () /drain ou BufferedAmount sur WS. Limitez les segments ; préférez les lignes JSON délimitées par\npour les flux personnalisés. Configurez le nombre maximum de requêtes ou de flux simultanés pour éviter la surcharge du serveur.
Passerelles et proxys (évitez les surprises liées à la mise en mémoire tampon)
- Gardez mise en mémoire tampon des réponses désactivée pour les itinéraires de streaming.
- Utiliser HTTP/1.1 ou HTTP/2 avec keep‑alive ; évitez les intermédiaires qui fusionnent des morceaux.
- Set sensible délais d'inactivité afin que les longues générations ne passent pas à mi-chemin.
- Envoyer Type de contenu : texte/flux d'événements pour SSE avec Cache-Control : no-store et Connection : keep-alive.
Des astuces UX pour accélérer le streaming
- Montrez les jetons au fur et à mesure qu'ils arrivent ; maintenez un curseur subtil.
- Permettre aux utilisateurs arrête et copie facilement.
- Imprimez proprement des blocs de code partiels ; fermez les clôtures lorsque les cours d'eau se terminent.
- Veillez à ce que les instructions du système soient courtes ; les limites de sortie serrées empêchent les divagations.
- Enregistrez le horodatage du premier jeton pour repérer les régressions.
Essayez Compute dès aujourd'hui
Déployez un VllM point de terminaison activé Calculer. Le streaming est activé par défaut. Placez-le à proximité des utilisateurs, définissez des limites de sortie strictes et observez l'amélioration du TTFT et du TPS.
Un streaming de jetons rapide et moins coûteux
Utilisez SSE pour la plupart des discussions. N'utilisez WebSockets que lorsque vous avez besoin de messages bidirectionnels. Annulez rapidement, limitez les sorties et désactivez la mise en mémoire tampon du proxy. Mesurer heure d'arrivée du premier jeton et jetons par seconde, puis réglez les plafonds et les limites de lots avant de changer de matériel.
FAQ
Qu'est-ce qu'un événement envoyé par le serveur (SSE) ?
Flux HTTP unidirectionnel que le serveur transmet au client. Le streaming de jetons correspond bien à SSE.
Quelle est la différence entre SSE et WebSockets ?
Le SSE est simple et unidirectionnel ; les WebSockets sont bidirectionnels et conviennent mieux aux applications interactives. Pour la sortie du chat, SSE est généralement suffisant.
L'API compatible avec OpenAI prend-elle en charge le streaming ?
Oui, utilisez stream : true ou un client SSE. Vous recevrez des jetons supplémentaires jusqu'à ce que le modèle s'arrête ou que vous l'annuliez.
Comment annuler un stream ?
Abandonnez la requête HTTP (SSE) ou fermez le WebSocket. Les ressources du serveur sont toujours gratuites en cas d'annulation.
Pourquoi est-ce que je vois la sortie arriver en un seul morceau ?
Un intermédiaire met la réponse en mémoire tampon. Désactivez la mise en mémoire tampon pour l'itinéraire et maintenez la connexion active.
Puis-je diffuser dans des navigateurs sans bibliothèque ?
Oui : EventSource pour SSE, ou fetch () avec l'API Streams pour lire des segments.