GPU para IA — Módulo 11: desplegar tu servicio en la nube
Undécimo módulo del curso de GPU para IA: tu vLLM corriendo en GPU arrendada, por los dos caminos — un pod dedicado con el contenedor oficial y un servicio serverless con Modal. Autenticación obligatoria, el cold start manejado con perillas reales y tus agentes apuntando a la URL pública.
☰ Índice del contenido
Undécimo módulo del Curso de GPU para IA. Ya sabes qué arrendar (Módulo 10); hoy se despliega. El objetivo es uno y lo conoces desde el módulo 5: una API compatible con OpenAI, ahora en una URL pública, servida por una GPU que no es tuya. Los dos caminos del módulo anterior, con las manos en la masa.
La tesis del módulo
Desplegar en nube no es un mundo nuevo: es tu mismo stack con URL pública. El contenedor corre vLLM, la API es la de siempre, tu agente cambia una variable de entorno. Lo genuinamente nuevo son dos disciplinas: autenticación (tu GPU cuesta plata por hora) y el manejo del cold start.
El destino común
tu agente (donde sea que corra)
│ https + api key
▼
endpoint público del proveedor
│
▼
contenedor con vLLM ──── GPU arrendada
Sea pod o serverless, el resultado es ese diagrama. La belleza del diseño contra interfaz OpenAI del Módulo 9: nada de tu aplicación cambia, solo BASE_URL y una API key de verdad.
Camino A: pod dedicado + contenedor oficial
El proyecto vLLM publica la imagen vllm/vllm-openai, que levanta el servidor del Módulo 7 listo para producción. En cualquier proveedor de pods (RunPod y similares) el flujo es: eliges la GPU del catálogo → indicas la imagen → el proveedor te da la URL.
El corazón del asunto es el comando del contenedor:
docker run --gpus all -p 8000:8000 \
vllm/vllm-openai \
--model Qwen/Qwen2.5-7B-Instruct \
--max-model-len 8192 \
--api-key TU_LLAVE_SECRETA
--gpus all— el contenedor ve la GPU del pod (el stack del módulo 3, empaquetado).--model— el id de Hugging Face; los pesos se descargan al primer arranque (por eso conviene un volumen persistente: si el pod se reinicia, no vuelves a bajar decenas de GB).--api-key— no es opcional en la vida real. Un endpoint de GPU abierto es una tarjeta de crédito publicada: los escáneres de internet encuentran puertos abiertos en horas y felices generan tokens a tu costa.
En los proveedores de pods típicamente no escribes el docker run: pegas la imagen y los argumentos en su plantilla. El resultado: https://tu-pod-xxxx.proxy.runpod.net (o equivalente) atendiendo /v1/chat/completions.
Camino B: serverless con Modal
Modal define la infraestructura en el propio Python — imagen, GPU y escalado como código:
import modal
app = modal.App("mi-servicio-llm")
imagen = (
modal.Image.from_registry("nvidia/cuda:12.9.0-devel-ubuntu22.04")
.pip_install("vllm")
)
MINUTOS = 60
@app.server(
image=imagen,
gpu="A100", # la GPU se pide por nombre
scaledown_window=15 * MINUTOS, # cuánto sigue tibio sin tráfico
)
class Servidor:
@modal.enter()
def arrancar(self):
# aquí se lanza vLLM; el ejemplo completo está en la doc de Modal
...
modal deploy servicio.py
Eso es todo el “DevOps”: Modal construye la imagen, la despliega y te entrega la URL pública. Las dos líneas que resumen el modelo serverless:
gpu="A100"— pides el hardware como un parámetro. Cambiar de GPU es cambiar un string.scaledown_window— la perilla del trade-off del módulo 10: cuánto tiempo queda el contenedor tibio tras la última petición. Más ventana = menos cold starts = más segundos facturados.
El cold start, domesticado
El enemigo del serverless tiene dos componentes: levantar el contenedor (segundos) y cargar los pesos a la VRAM (lo lento: gigas desde disco). Las armas, de más simple a más fina:
| Arma | Cómo | Costo |
|---|---|---|
| Ventana de tibieza | scaledown_window amplio | Pagas los minutos tibios |
| Pesos cerca | Modelo en volumen/caché del proveedor, no re-descargado | Almacenamiento |
| Réplica mínima | Mantener 1 contenedor siempre vivo | Ya no escalas a cero |
| Aceptarlo | Para trabajos por lotes, ¿a quién le importa? | Gratis |
La última fila es seria: si tu carga es indexar documentos cada noche, el cold start es irrelevante. La obsesión anti-cold-start es solo para tráfico interactivo.
Conectar y verificar
cliente = OpenAI(
base_url="https://tu-endpoint.ejemplo.com/v1",
api_key=os.environ["LLM_API_KEY"], # secreto en variables de entorno, jamás en el código
)
Y la verificación de despliegue es el ritual de siempre: una petición de prueba, mirar tokens/s, y nvidia-smi en el pod (los proveedores dan terminal web) confirmando que el modelo vive en la VRAM — exactamente lo que aprendiste a leer en el módulo 3, ahora en hardware ajeno.
Errores comunes
- Endpoint sin API key. El error más caro del curso, literalmente: la GPU factura por hora aunque quien la use no seas tú.
- Secretos en el código. La API key va en variables de entorno o en el gestor de secretos del proveedor. Un repo público con llaves es el clásico que no perdona.
- Re-descargar el modelo en cada arranque. Sin volumen persistente, cada cold start baja decenas de GB: lento y a veces facturado.
- Probar “que funciona” y no probar carga. Un endpoint que responde a tu curl no es un endpoint que aguanta 30 usuarios; el módulo 7 te dio las herramientas para la diferencia.
- Olvidar apagar el pod. El pod dedicado cobra mientras exista. El finde largo con la GPU prendida es un rito de iniciación que puedes saltarte.
La frase para llevarse
“Desplegar es cambiar una URL; operar es lo que aprendiste todo el curso: leer la VRAM, medir tokens y no dejar la puerta abierta con la GPU adentro.”
Qué viene
Módulo 12, el cierre: producción y costos — la cuenta del costo por millón de tokens propio contra la API, el punto de equilibrio, monitoreo, y el checklist final para operar con adultos responsables.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.