Desplegar vLLM en production
Para desplegar vLLM en producción: instálalo en Linux (mediante pip o la imagen Docker vllm/vllm-openai), arranca vllm serve con tu modelo, configura --gpu-memory-utilization y --max-model-len, activa --api-key y, después, coloca un proxy inverso delante. El servidor escucha en el puerto 8000 con una API compatible con OpenAI. Solo sirve un modelo a la vez y está diseñado para ofrecer un alto rendimiento con muchos usuarios simultáneos.
vLLM es el servidor de inferencia diseñado para compartir una GPU entre muchas solicitudes en paralelo. Esta guía cubre el dimensionamiento de la memoria (el verdadero tema), la instalación, el arranque, Docker y systemd, los parámetros que importan, la medición de la tasa de procesamiento y la seguridad, con una corrección importante: la opción --api-key protege solo parte de las rutas.
#Lo que hace vLLM y lo que exige
vLLM es un motor de inferencia de código abierto nacido en el laboratorio Sky Computing de UC Berkeley. Su idea central, PagedAttention, gestiona por páginas la caché de claves y valores de la atención, como la memoria virtual de un sistema operativo. Según el anuncio inicial del proyecto en 2023, los sistemas existentes desperdiciaban una gran parte de su memoria y vLLM alcanzaba hasta 24 veces la tasa de procesamiento de Hugging Face Transformers y hasta 3,5 veces la de TGI, en pruebas de aquella época. Estas cifras son antiguas y específicas de ese banco de pruebas: indican una tendencia, no lo que obtendrás con tu modelo y tu tarjeta.
En cuanto a los requisitos previos, la documentación actual exige Linux y Python entre 3.10 y 3.13; en Mac, existe una vía alternativa, vLLM-Metal, que se basa en MLX. El servidor expone una API compatible con OpenAI, escucha por defecto en el puerto 8000 y solo sirve un modelo a la vez: para múltiples modelos, se necesitan varias instancias.
#¿Cuándo elegir vLLM en lugar de Ollama?
Tu ChatGPT privado y gratuito en tu máquina en 1 hora — LM Studio, Ollama, Open WebUI, tus documentos, sin nube.
- Espacio en línea de por vida
- PDF + archivos
- Reembolsado 30 j
La diferencia no radica en la capacidad de procesar consultas en paralelo, que también ofrece Ollama, sino en la forma en que se comparte la memoria. Según la FAQ de Ollama, el procesamiento en paralelo de un modelo multiplica el tamaño del contexto por el número de consultas: un contexto de 2.000 tokens con 4 consultas en paralelo se convierte en un contexto de 8.000 tokens en memoria, reservado por adelantado. vLLM asigna su caché por bloques, a demanda, y agrupa las consultas en curso en los mismos cálculos.
| Criterio | Ollama | vLLM |
|---|---|---|
| Usuarios simultáneos | De 1 a unos pocos; OLLAMA_NUM_PARALLEL regula el paralelismo | Decenas de consultas simultáneas |
| Modelos servidos | Varios, cargados y descargados según se necesiten | Uno por instancia |
| Implementación | Una orden de instalación | Python, CUDA y parámetros que ajustar |
| Cuantizaciones | GGUF, amplia selección | Formatos del Hub (AWQ, GPTQ, FP8); GGUF parcialmente |
| Métricas de seguimiento | No detalladas en esta guía | Punto de acceso /metrics documentado |
| Uso típico | Equipo personal, equipo pequeño | Servicio interno o producto |
Regla práctica: si menos de tres personas usan el modelo al mismo tiempo, o si quieres cambiar de modelo con frecuencia, Ollama basta. Por encima de ese número de usuarios, o con un solo modelo servido de forma continua, vLLM compensa su complejidad. La guía comparativa detalla la elección.
#Cuando vLLM es una mala opción
vLLM no aporta nada a un único usuario con una GPU de 8 a 12 GB: no hay suficiente memoria para una caché compartida, y Ollama o llama.cpp se ponen en marcha más fácilmente. Resulta poco adecuado si alternas entre cinco modelos a lo largo del día, ya que hay que volver a iniciar una instancia para cada modelo. En un Mac, la vía es distinta y se basa en MLX. Por último, si necesitas una interfaz de chat para el equipo en lugar de una API sometida a una carga elevada, una solución con Ollama y Open WebUI responde mejor a esa necesidad y requiere menos trabajo de administración.
#Dimensionar la memoria: el cálculo que hay que hacer antes que nada
Un servidor vLLM se dimensiona según la caché clave-valor, no según los pesos. Una vez cargado el modelo, vLLM reserva una fracción de la memoria de la GPU, el 92 % por defecto según el código de configuración actual, y dedica todo lo que queda a la caché. Ese espacio restante determina cuántos tokens de conversación pueden coexistir y, por tanto, a cuántos usuarios simultáneos puedes atender.
Tomemos Qwen2.5-7B-Instruct, cuya ficha indica 7,61 mil millones de parámetros, 28 capas y 4 cabezas de clave-valor (atención agrupada). Los pesos en 16 bits ocupan aproximadamente 15,2 GB. La caché de un token ocupa 2 (claves y valores) × 28 capas × 4 cabezas × 128 dimensiones × 2 bytes, es decir, 57 344 bytes, aproximadamente 56 KiB.
| Memoria del GPU | Reserva del 92 % | Memoria restante para la caché | Tokens de caché (límite superior) | Equivalente en consultas de 4.096 tokens |
|---|---|---|---|---|
| 24 GB | 22,1 GB | 6,9 GB | aproximadamente 120.000 | alrededor de 29 |
| 48 GB | 44,2 GB | 28,9 GB | alrededor de 500.000 | alrededor de 120 |
| 80 GB | 73,6 GB | 58,4 GB | aproximadamente 1.000.000 | alrededor de 250 |
Estos límites son elevados: los búferes de cálculo y los grafos CUDA consumen parte de la memoria restante, y el modelo puede tener otro perfil. El método sigue siendo válido para cualquier modelo: consulta los números de capas y de cabezas de clave-valor en la ficha, calcula el coste por token y divide lo que queda. Si los registros indican preempciones, la documentación recomienda aumentar gpu_memory_utilization o reducir max_num_seqs.
Dos mecanismos amplían el caché sin cambiar la tarjeta: cargar una versión cuantizada del modelo, que libera parte de los pesos, o limitar --max-model-len, lo que evita reservar espacio para contextos que nadie utiliza. El primer mecanismo puede costar un poco de calidad; el segundo no cuesta nada siempre que tus consultas sigan siendo cortas.
#1. Instalación
La documentación recomienda uv, que elige automáticamente la versión adecuada de PyTorch según tu controlador CUDA. Para un GPU AMD, la instalación se realiza a través de un índice dedicado; para Intel, TPU o Ascend, existen plugins. En producción, la imagen Docker evita conflictos de versiones CUDA y se actualiza con un simple cambio de etiqueta.
#2. Iniciar el servidor
El comando vllm serve reemplaza la antigua invocación python -m vllm.entrypoints.openai.api_server, que ya no se utiliza en la documentación actual. En el primer arranque, los pesos se descargan desde Hugging Face: prevé espacio en disco (alrededor de 15 GB para un 7B en 16 bits). El servidor aplica por defecto el archivo generation_config.json del repositorio del modelo y, por tanto, los parámetros de muestreo recomendados por su editor; --generation-config vllm restablece los valores por defecto de vLLM.
#3. Docker y systemd
La imagen oficial vllm/vllm-openai es la vía más segura. Monta la caché de Hugging Face para no volver a descargar los pesos y un volumen para la caché de compilación: de lo contrario, cada nuevo contenedor arranca con una caché vacía y recompila los artefactos de su modelo. Ten en cuenta que la imagen se ejecuta como root por defecto; la documentación describe cómo ejecutarla con un usuario sin privilegios (--user 2000:0).
#4. Los parámetros que importan
| Parámetro | Rol | Consejo |
|---|---|---|
| --gpu-memory-utilization | Fracción de la memoria del GPU reservada (0,92 por defecto) | Bajar si otro proceso utiliza la GPU; subir si los registros muestran preempciones |
| --max-model-len | Contexto máximo aceptado | Lo más bajo posible: cada token de contexto consume espacio en la caché |
| --max-num-seqs | Número máximo de solicitudes en un lote | Bajar en caso de falta de memoria |
| --tensor-parallel-size | Distribuye el modelo entre varios GPUs de un nodo | Solo si el modelo no cabe en una GPU |
| --api-key | Requiere una clave para ciertas rutas | Ver la sección de seguridad: insuficiente por sí solo |
| --generation-config vllm | Ignora generation_config.json del modelo | Usar si las respuestas difieren de tus expectativas |
Un principio de la documentación: si el modelo cabe en una sola GPU, la distribución probablemente sea innecesaria; si no cabe en una GPU pero sí en un nodo, se utiliza el paralelismo tensorial con --tensor-parallel-size. Los modelos ya cuantizados se cargan directamente desde el Hub, sin ninguna opción especial: la opción --quantization solo sirve para la cuantización dinámica.
#5. Medir correctamente la tasa de procesamiento
El comando vllm bench serve envía solicitudes al servidor e informa de la tasa de procesamiento, el tiempo hasta el primer token (TTFT) y la latencia entre tokens. La documentación especifica que estos benchmarks sirven principalmente para evaluar funciones y detectar regresiones, y recomienda GuideLLM para probar un servidor de producción.
#Puesta en servicio y operación
Una vez realizado el dimensionado, la puesta en servicio sigue siempre la misma secuencia. Se aplica a un equipo de unas veinte personas que consultan un mismo modelo de 7 a 8 mil millones de parámetros en una tarjeta de 24 o 48 GB.
- 01Elegir el modelo y el formatoUn solo modelo por instancia. Prefiere un repositorio ya cuantizado o en 16 bits, según la memoria disponible.
- 02Calcular el cachéAplica el cálculo por token de la sección de dimensionado para fijar --max-model-len y --max-num-seqs.
- 03Iniciar en DockerUsa la imagen oficial con la caché de Hugging Face montada y una etiqueta de versión fija en lugar de latest, para evitar que una actualización cambie el comportamiento.
- 04Añadir el proxyProxy inverso con lista blanca de rutas, TLS y limitación de la frecuencia de solicitudes, y después la clave de API como complemento.
- 05MedirEjecuta una prueba de carga con vllm bench serve variando la semilla y anota el TTFT y el rendimiento total.
- 06SupervisarConecta la recopilación de datos del endpoint /metrics a tu herramienta de supervisión.
Las señales que debes vigilar son las que anuncian una falta de caché: preempciones en los registros, un TTFT que aumenta y colas que se alargan. La documentación indica que la preempción, cuyo modo predeterminado es el recálculo, protege el servicio pero empeora la latencia de extremo a extremo. Si se vuelve frecuente, aumenta gpu_memory_utilization, reduce el contexto o limita el número de solicitudes simultáneas. Como último recurso, añade una GPU y reparte el modelo mediante el paralelismo tensorial.
#6. Seguridad y exposición: --api-key no basta
Contrario a lo que a menudo se lee, vLLM sabe verificar una clave de API, con --api-key o la variable VLLM_API_KEY. Pero la documentación de seguridad insiste: la clave solo protege las rutas bajo /v1, /v2, /inference y /cohere. Otras rutas permanecen sin autenticación, como rutas de inferencia fuera de /v1, rutas de control como /pause o /abort_requests, y /health. Por lo tanto, nunca confíes únicamente en --api-key.
- Reverse proxy
- Coloca nginx, Envoy o una puerta de enlace de Kubernetes delante de vLLM, con una lista blanca que incluya únicamente las rutas que se deben exponer, y bloquea todas las demás.
- Red
- Una VPN o una red aislada: la comunicación entre los nodos de un despliegue distribuido no está protegida de forma predeterminada.
- Modo de desarrollo
- Nunca actives VLLM_SERVER_DEV_MODE=1 en producción: expone rutas peligrosas.
- Límites
- Aplica la limitación de la tasa de solicitudes y la validación de las peticiones en el proxy, como recomienda la documentación.
- Registros
- Registra quién envía qué, para depuración y auditoría.
- Fuente: inicio rápido de vLLM
- Fuente: seguridad de vLLM
- Fuente: vLLM con Docker
- Fuente: anuncio de vLLM y PagedAttention
¿Es vLLM mejor que Ollama en producción?+
¿Cómo lanzar un servidor vLLM con una API compatible con OpenAI?+
¿Cuánta VRAM se necesita para vLLM?+
¿Basta con la opción --api-key para proteger vLLM?+
¿Funciona vLLM en Mac o con una tarjeta AMD?+
¿Un comentario, un error, una precisión? Avísanos, eso mejora la guía para todos.