Proyectos / LLM Stream Backpressure

LLM Stream Backpressure

Streaming HTTP/SSE con límites de búfer, contrapresión de consumidores lentos, eventos de herramientas intercalados y cancelación medida sobre conexiones locales reales.

Autor: · Python 3.12.11 · Licencia: MIT

Ficha publicada: · Ficha actualizada:

Repositorio · Informe de medición del transporte · Release v0.1.0

Problema y utilidad para agentes

Un cliente lento puede ocultar colas crecientes y trabajo que continúa en el productor. Cerrar la conexión no demuestra que el proveedor haya dejado de calcular.

Los límites de tamaño de eventos, las colas acotadas y los contratos de cancelación permiten observar la limpieza del flujo antes de integrar un proveedor real de modelos.

Arquitectura

  1. Separar cada solicitud. Cada conexión tiene su propio productor, cola FIFO acotada, escritor de conexión y monitor de desconexión. Los eventos de tokens y herramientas comparten un flujo ordenado.
  2. Propagar la contrapresión. Los eventos de tamaño limitado y la espera de vaciado del escritor propagan la espera cuando se llenan los búferes de la conexión. Un tiempo máximo termina las escrituras a un cliente bloqueado.
  3. Tratar explícitamente la cancelación. Los productores cancelables se detienen antes de limpiar el adaptador. Si no admiten cancelación, el trabajo restante y finito se consume y descarta.

Qué demuestra

  • Siete casos congelados ejecutados sobre conexiones locales reales, incluidos fallos y tres solicitudes concurrentes.
  • Dieciocho pruebas cubren carreras de cancelación, escrituras bloqueadas, intercalado, solicitudes inválidas, búferes acotados y alteración de evidencia.
  • Las marcas temporales distinguen el cierre del cliente, la detección del servidor y el trabajo completado por el productor.

Resultados publicados

Se registró una ejecución por caso en un Intel Xeon W-3223 con 48 GiB de RAM, macOS 26.7.1 y Python 3.12.11.

El productor realiza trabajo sintético determinista, no inferencia de un LLM. Las trazas registran ocupación de colas, espera de inserción, búferes de conexión y entrega al cliente. Los conteos recibidos incluyen eventos terminales de error y finalización.

Casos de streaming observados

Informe de medición del transporte ·
CasoProducidos / recibidosMáximo de la colaEventos completados después de detectar la desconexión
Rápido300 / 30140
Lento300 / 30140
Cancelación admitida5 / 510
Cancelación no admitida100 / 5295
Error del productor15 / 1720
Interrupción del cliente12 / 540
Tres solicitudes concurrentes80 / 81 cada una20

El caso lento tardó 1.417 ms frente a 479 ms del consumo rápido; la espera máxima de inserción subió de 2,54 ms a 15,35 ms. Estas mediciones individuales demuestran comportamiento de transporte, no velocidad de inferencia ni garantías estadísticas de latencia.

El máximo observado del búfer de escritura fue de 68.233 bytes. El caso lento registró un máximo de 18.947.008 bytes de memoria de Python trazada, que incluye la salida retenida por el cliente y las trazas; no representa solo la memoria del servidor.

La ejecución inicial reveló un evento residual durante la limpieza del escritor. Se conserva su evidencia original y la implementación corregida se midió nuevamente con la misma matriz. Medición inicial conservada.

La integración continua pasó en Ubuntu 24.04. La evidencia de macOS proviene de la ejecución local real en x86_64; no se verificaron macOS en infraestructura hospedada ni compatibilidad con ARM.

Reproducir

Usá uv 0.8.23 y Python 3.12.11. El comando de preparación crea un entorno dentro del repositorio; uv debe poder encontrar el intérprete indicado. Instalá primero esa versión de Python si no está disponible en el catálogo de descargas de uv. La preparación inicial y las dependencias de pruebas pueden necesitar acceso a Internet. La reproducción y las pruebas con unittest solo usan la biblioteca estándar. No necesitan descargas de modelos, credenciales de API ni servicios externos de inferencia.

Después de preparar el entorno, el comando de reproducción funciona sin conexión. La reproducción funciona sin conexión y recalcula las métricas de las trazas guardadas; las pruebas pequeñas abren conexiones locales. No uses Python -O porque el verificador utiliza aserciones. Para nuevas mediciones en el equipo original, seguí el README y usá el bloqueo compartido de benchmarks.

Verificar la evidencia guardada

git clone https://github.com/lucioduran/llm-stream-backpressure.git
cd llm-stream-backpressure
git checkout b16020bdc459d56d2628b1655fabc3de98f6dd22
UV_CACHE_DIR="$PWD/.tools/uv-cache" UV_PYTHON_INSTALL_DIR="$PWD/.tools/python" uv venv --python 3.12.11 .venv
PYTHONPATH=src .venv/bin/python experiments/replay.py

Ejecutar las pruebas de regresión

PYTHONPATH=src .venv/bin/python -m unittest discover -s tests -v

Alcance y límites

  • El servidor solo acepta GET /events HTTP/1.0 en la interfaz local. TLS, autenticación, proxies, conexiones persistentes y despliegue en producción quedan fuera del alcance.
  • Los búferes del sistema operativo pueden absorber trabajo antes de que la contrapresión llegue al productor. No se establece un límite para toda la memoria del proceso o del núcleo.
  • Los adaptadores sin cancelación deben terminar un presupuesto finito de trabajo. Un adaptador que incumpla el contrato puede bloquear la limpieza, y cerrar una conexión no garantiza cancelar cómputo remoto.
  • El cliente de prueba conserva su salida finita en memoria. Los tiempos incluyen efectos de instrumentación y planificación; no se midieron comportamiento de proveedores, costo ni energía.

Fuentes y revisión

La medición corregida usó el commit ae5a1361b7df99eeab67e5609ca9130fba7ce45d y se ejecutó entre 2026-11-09T20:21:26.925418+00:00 y 2026-11-09T20:21:29.396323+00:00. El informe vincula los hashes del código, la matriz y las trazas. La release final agrega publicación y cambios de integración continua sin modificar la implementación de transporte medida.