El cluster GPU como plataforma: cómo convertir un cluster compartido en un servicio multi-tenant que tus equipos puedan consumir

TL;DR

Tener un cluster de GPUs caro y muchas cargas distintas que lo quieren usar no es un problema de infraestructura: es un problema de producto interno. Lo que separa “tenemos un cluster” de “tenemos una plataforma de inferencia” son cuatro capas que el mercado ha consolidado en 2026: una capa de gateway que centraliza autenticación, routing y políticas (LiteLLM, Portkey, Kong AI Gateway); un modelo de aislamiento GPU apropiado al perfil de los tenants (MIG hardware-isolation para multi-tenant no confiable, MPS para procesos del mismo equipo, time-slicing solo para dev); un sistema de quotas y rate limiting con presupuestos por tenant/equipo/proyecto (LiteLLM lo hace en su core a nivel team/user/api-key con 429s descriptivos); y un plano de observabilidad multi-tenant que permite cost attribution real (showback como paso intermedio, chargeback como destino), tracing por tenant y dashboards diferenciados. Aplicado a un cluster GPU mid-scale típico (un nodo con 4-8 H100 SXM y NVLink, un punto habitual para empezar en producción), esto se traduce en decisiones concretas: con ~640 GB de VRAM agregada en 8 GPUs y dos modelos típicos en producción (un modelo grande de 70B+ con tensor parallel y un modelo mediano replicado), el cluster sirve entre decenas y bajos centenares de sesiones simultáneas según mix; el aislamiento GPU se suele resolver con MIG en cargas inferiores y dedicación per-model en cargas grandes; y la métrica de éxito de la plataforma es la utilización efectiva, que en producción típica está en 30-40% y el objetivo razonable de optimización es subirla a 60-70% sin degradar SLA.

Este es el quinto post de la serie MLOps para LLMs. Es el más operacionalmente orientado y atraviesa varias etapas del pipeline (Deploy + Observe + transversales). El “estás aquí” señala las dos etapas activas porque la noción de plataforma multi-tenant no vive en una sola.

Estás aquí: Deploy + Observe (cluster como producto)

Estás aquí: DEPLOY + OBSERVE · el cluster como plataforma con tenants1 · Data2 · Tune3 · Eval4 · Deploy5 · Observe6 · Retrain

La pregunta que cambia el marco

Cuando un equipo de plataforma adquiere hardware GPU caro y empieza a montar inferencia, la primera versión casi siempre es mononosa: un modelo, un cliente, una latencia objetivo. Funciona. Cuando llega el segundo equipo pidiendo el mismo recurso, la mononosa se vuelve política interna: ¿cuántas réplicas le damos? ¿Qué hacemos si chocan los SLA? ¿Quién paga los tokens del experimento del equipo B? Y cuando llega el tercero, lo que era un proyecto de SRE pasa a ser un proyecto de producto interno.

La distinción no es técnica, es de marco. Un cluster es infra. Una plataforma es un servicio con clientes, contratos y métricas de éxito. El cambio de marco implica:

  • Clientes identificables (tenants), no usuarios anónimos.
  • Contratos (latency SLA, throughput garantizado, modelos disponibles), no “lo que dé tiempo”.
  • Métricas de éxito que no son técnicas sino de producto: adopción, satisfaction, cost per query por tenant, tiempo del primer “hello world”.

Este post recorre cómo se opera ese cambio de marco. Lo aterriza sobre un cluster mid-scale (4-8 H100 SXM con NVLink en un solo nodo), configuración habitual cuando se empieza con inferencia LLM seria; pero los principios se generalizan a cualquier topología, desde un nodo único con dos GPUs hasta clusters multi-nodo con InfiniBand.

Las cuatro capas de una plataforma de inferencia multi-tenant

La arquitectura canónica que se ha establecido en 2026 tiene cuatro capas que cualquier plataforma multi-tenant seria implementa, en orden de afuera hacia adentro:

Las cuatro capas de la plataforma multi-tenantTenant Asoporte chatTenant BRAG legalTenant Cagente codeTenant Ddata extr.Tenant Ebatch ETLnotebooksresearchCapa 1 · AI GatewayAuth (OIDC/API keys) · Routing por modelo · Failover · Caching · Logging · OTel emission · Rate limitingCapa 2 · Policy & Quota PlaneQuotas RPS/TPM por tenant · Budgets mensuales · Whitelist modelos · Priority classes · Admission controlCapa 3 · Isolation PlaneMIG / MPS / time-slicing · Namespaces K8s · NetworkPolicies · ResourceQuotas · Priority + preemptionCapa 4 · Observability Plane (multi-tenant)Traces con tenant_id · Métricas labeled · Cost attribution · Dashboards por tenant · Audit logs

Cada capa resuelve un problema concreto. Vamos a una por una.

Capa 1 — AI Gateway: la puerta de entrada única

El AI Gateway es el componente que tus tenants ven. Es una API HTTP/gRPC compatible con OpenAI (típicamente /v1/chat/completions, /v1/embeddings, /v1/models) que centraliza todo lo que pasa antes de tocar los backends de inferencia.

Por qué centralizar

Sin gateway, los tenants se conectan directamente a vLLM o al modelo que sea. Cada cambio (rotar un endpoint, añadir un modelo, cambiar credenciales, aplicar política) requiere notificar a todos los tenants. Cada tenant tiene su propia lógica de retry, su propio logging, su propio modelo de auth. Es inoperable a partir del tercer cliente.

Con gateway, el cambio se hace en un sitio. Los tenants tienen una URL estable y unas credenciales; el resto es problema del gateway.

Las tres opciones dominantes 2026

LiteLLM es la opción OSS más popular, Python-first, modelo de despliegue como proxy. Soporta 100+ proveedores (OpenAI, Anthropic, Bedrock, vLLM self-hosted, Ollama, etc.) detrás de una API OpenAI-compatible unificada. Hierarchy nativa multi-tenant con Organizations → Teams → Users → API Keys, cada nivel con budget independiente. Versión Apache 2.0 cubre lo básico; RBAC, SSO, audit logs y team-level enforcement requieren versión Enterprise paga. Despliegue en K8s con Helm chart oficial.

Portkey es la opción comercial / SaaS más madura. Single control plane que enforces budgets, quotas, permissions, compliance. Real-time spending tracking con alerting. RBAC, audit, workspaces, SSO incluidos. Trade-off: dependencia de un servicio externo y modelo de pricing por requests.

Kong AI Gateway es la opción para organizaciones que ya tienen Kong como API gateway. Plug-in AI sobre el gateway Kong existente, integra con su modelo de plugins, consumers y rate-limits. Si tu equipo de plataforma ya opera Kong, es la fricción más baja.

Cuándo elegir cada uno

SituaciónGateway
OSS puro, self-host, equipo Python-firstLiteLLM
Necesitas RBAC, SSO, audit log out-of-the-box, presupuesto disponiblePortkey
Ya operas Kong como API gateway corporativoKong AI Gateway
Greenfield enterprise con compliance estrictoPortkey (probablemente)
Empresa media OSS-first sin compliance reguladoLiteLLM (típicamente)

Lo que el gateway tiene que hacer mínimo

Independientemente de la opción, lo que cualquier deployment serio debe enforcer:

  • Auth y identidad: cada request lleva una API key resoluble a un tenant + usuario + equipo.
  • Routing por modelo: el tenant pide model: "gpt-4o"; el gateway decide si va a OpenAI, a Azure OpenAI, a tu vLLM con Qwen3 32B (fallback más barato), según política.
  • Rate limiting: RPS por tenant, TPM (tokens por minuto), concurrency limits.
  • Caching de respuestas idénticas: 5-30% de las queries de RAG son repetidas; cachear ahorra latencia y coste.
  • OTel emission: cada llamada produce un span con gen_ai.* semantic conventions y tenant_id como atributo. Cubierto en post de Evals y MCP observability.
  • Failover: si vLLM se cae, el gateway redirige a OpenAI API. Si OpenAI rate-limita, el gateway tira a Anthropic. Política configurable.

Ejemplo de configuración LiteLLM multi-tenant

# litellm-config.yaml — ejemplo simplificado
model_list:
  - model_name: llama-3-70b
    litellm_params:
      model: openai/llama-3-70b
      api_base: http://vllm-llama3-70b.inference/v1
      api_key: os.environ/VLLM_API_KEY

  - model_name: qwen3-32b
    litellm_params:
      model: openai/qwen3-32b
      api_base: http://vllm-qwen3-32b.inference/v1
      api_key: os.environ/VLLM_API_KEY

  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY

router_settings:
  routing_strategy: usage-based-routing-v2
  fallbacks:
    - llama-3-70b: [qwen3-32b, gpt-4o]      # si vLLM cae, fallback al externo

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  database_url: os.environ/DATABASE_URL     # Postgres para budgets/keys

# Hierarchy: Organizations → Teams → Users → API Keys
# Se crean vía API, no en YAML estático

Crear un team con presupuesto:

curl -X POST http://litellm/team/new \
  -H "Authorization: Bearer ${LITELLM_MASTER_KEY}" \
  -d '{
    "team_alias": "soporte-chat",
    "max_budget": 500,                       # 500 USD/mes
    "budget_duration": "30d",
    "tpm_limit": 100000,                     # 100K tokens/min
    "rpm_limit": 1000,                       # 1000 requests/min
    "models": ["llama-3-70b", "qwen3-32b"]   # acceso a estos
  }'

Y la API key del team:

curl -X POST http://litellm/key/generate \
  -H "Authorization: Bearer ${LITELLM_MASTER_KEY}" \
  -d '{
    "team_id": "<team-id>",
    "duration": "30d",
    "metadata": {"environment": "production", "app": "support-bot"}
  }'

Esa API key es lo que el tenant usa. Cada request que pase con ella consumirá del budget del team. Cuando se agote, LiteLLM devuelve HTTP 429 con descripción.

Capa 2 — Policy & Quota Plane: qué puede hacer cada tenant

El gateway es donde se enforza. La política es lo que se enforza. Cinco ejes de política multi-tenant:

Quotas técnicas

  • TPM (tokens por minuto): el límite duro de consumo. Para un Llama 3 70B en TP=5, ~3000 tokens/s salidos sostenidos = 180K TPM agregados. Si tienes 10 tenants, asignar 18K cada uno como techo.
  • RPS / RPM: control de carga, no de consumo. Una sesión de 4K tokens cuenta como una request; un batch de 100 mini-completions también. Útil contra abuso.
  • Concurrency: cuántas requests simultáneas activas por tenant. Importante para SLA de latencia: 100 RPS con concurrency=50 se traducen en 2 segundos por request.

Budgets económicos

  • Mensual por tenant: hard cap en USD.
  • Diario y por hora: soft caps para evitar runaway en un solo día.
  • Por proyecto / API key: granularidad fina dentro de un mismo tenant.

LiteLLM tiene un campo max_budget en cada nivel de la jerarquía (organization, team, user, api key). Los presupuestos se heredan/restringen hacia abajo.

Whitelist y blacklist de modelos

Tenants con cargas críticas → solo modelos estables (llama-3-70b, gpt-4o). Tenants de investigación → acceso también a modelos experimentales.

Priority classes

No todos los requests son iguales. Tres clases típicas:

  • Guaranteed: cargas con SLA, latencia respetada incluso bajo presión.
  • Best-effort: cargas normales sin SLA estricto.
  • Spot: batches que pueden esperar, evictable si llega un guaranteed.

El paper Token Management in Multi-Tenant AI Inference Platforms (2026) formaliza esto con un modelo de token pools por priority class que se ha empezado a adoptar en producción. Mantiene P99 latency garantizada para guaranteed workloads incluso bajo overload, throttling selectivo sobre spot.

Admission control

Antes de aceptar una request: ¿hay capacidad? Si no, devolver 429 inmediatamente en vez de encolar y degradar a todos. Es la disciplina operacional más infravalorada — un cluster con admission control bien hecho tiene latencia predecible; sin él, catastrophic degradation cuando llega el pico.

El patrón típico en 2026

# Política conceptual para un tenant "soporte-chat"
tenant: soporte-chat
quotas:
  tpm: 50000
  rpm: 500
  max_concurrency: 30
budget:
  monthly_usd: 800
  alert_thresholds: [0.5, 0.8, 0.95]      # avisa cuando llegues
models_allowed:
  - llama-3-70b
  - qwen3-32b
priority: guaranteed
fallback_on_overload:
  - qwen3-32b                              # si guaranteed se llena, fallback
  - gpt-4o-mini                            # último recurso, modelo externo

Capa 3 — Isolation Plane: aislar las cargas físicamente

Esta es la capa más densa técnicamente. Tienes un nodo con varias GPUs H100 SXM interconectadas por NVLink. ¿Cómo las particionas entre tenants?

Tres mecanismos NVIDIA para compartir GPU

MIG (Multi-Instance GPU) es el aislamiento más fuerte. Particiona la GPU en hasta 7 instancias con memoria HBM separada físicamente y compute units (SMs) dedicados. Los tenants en MIG diferentes no pueden tocarse: una carga no consume memoria que otra necesita, una no degrada el throughput de otra. Aislamiento hardware. Disponible en A100, H100, B100, B200.

MPS (Multi-Process Service) es soft. Múltiples procesos comparten la GPU concurrentemente, NVIDIA reparte SMs según uso. Buen rendimiento si todos los procesos son tuyos y confías en ellos. Peor para multi-tenant entre clientes que no se conocen porque un proceso ruidoso puede degradar a los otros.

Time-slicing es lo más simple: la GPU se asigna alternadamente, slot por slot, a procesos distintos. Latencia mucho peor (waits entre slots); no se recomienda para cargas de producción con SLA.

La elección para multi-tenant 2026

Según el survey de adopción enterprise: 80% usa MIG para multi-tenant no confiable (clientes distintos que no se conocen) y MPS para entornos confiados (procesos del mismo equipo) donde quieres maximizar throughput. Time-slicing solo se usa en dev/staging para que cada developer toque GPU sin coste de exclusividad.

Limitación importante de MIG: aísla compute y memoria HBM, pero el camino PCIe sigue siendo compartido. Para cargas PCIe-bound (mucho tráfico host↔device), tenants en MIG distintos pueden seguir afectándose. Para inferencia LLM, el path principal es HBM, así que esto rara vez es problema. Pero conviene saberlo.

Las particiones MIG en H100

Una H100 (80GB HBM3) se puede particionar en perfiles fijos:

PerfilSMMemoriaInstancias máx por GPU
1g.10gb1410 GB7
1g.20gb1420 GB4
2g.20gb2820 GB3
3g.40gb4240 GB2
7g.80gb9880 GB1 (toda la GPU)

Para un cluster mid-scale con NVLink, MIG tiene un problema fundamental: cuando particionas con MIG, se desactiva el NVLink entre GPUs. Una H100 en MIG no participa en tensor parallel multi-GPU. Si vas a servir un modelo grande con tensor parallel (Llama 3 70B con TP=4 o TP=8, por ejemplo), esas GPUs deben estar enteras, sin MIG.

Esto define la decisión arquitectónica. Hay dos enfoques principales:

Enfoque A — Modelo grande compartido con quotas en gateway

Todas las GPUs del nodo sirven un único modelo grande con tensor parallel que abarca el nodo entero. Todos los tenants comparten esa instancia. El aislamiento se hace en la capa de gateway (quotas, rate limiting) y la capa de policy (priority classes). El kernel del cluster es una sola instancia vLLM enorme con --max-num-seqs=128 o similar; vLLM internamente reparte tiempo de GPU entre las requests activas con continuous batching.

Ventajas: aprovechas todas las GPUs al máximo, NVLink activo, mejor utilización del KV cache. Desventajas: aislamiento blando — un tenant que satura no degrada a otros directamente (vLLM bachea), pero sí compite por slots del batch. Necesitas priority classes serias.

Enfoque B — Dedicar GPUs por modelo / tenant

Divides las GPUs en pools dedicados a modelos distintos. Ejemplos en un nodo de 8 GPUs:

  • 4 GPUs: modelo grande de 70B con TP=4.
  • 2 GPUs: modelo mediano de 32B replicado (2 instancias independientes) para tenants con SLA estricto.
  • 2 GPUs: cargas misceláneas (modelos más pequeños, experimentación).

Ventajas: aislamiento físico entre modelos / tenants críticos. Desventajas: peor utilización agregada; algunas GPUs idle mientras otras saturan.

Enfoque C (avanzado) — MIG en algunas GPUs + dedicar el resto

Si tienes cargas pequeñas (modelos de 4B, 7B), puedes hacer MIG en 1-2 GPUs para servirlas y dedicar las restantes a tensor parallel del modelo grande. Combina aislamiento fuerte para cargas chicas con aprovechamiento del NVLink para el modelo grande.

La elección operativa: empieza por A, sube a C si hace falta

En la mayoría de despliegues, el Enfoque A (modelo grande compartido + quotas) es el punto de partida correcto. La utilización es mejor, la operación es más simple, y los aislamientos blandos del gateway funcionan para cargas razonables.

Cuando hay un tenant con SLA estricto que no tolera competir con otros, mueves a Enfoque B para ese tenant en particular (dedicar GPUs a una instancia del modelo solo para él), manteniendo el resto del cluster compartido.

Enfoque C es para cuando tienes 10+ tenants con perfiles muy heterogéneos.

Aislamiento a nivel Kubernetes

Independiente del aislamiento GPU, en K8s se aplica aislamiento de pod:

  • Namespaces por tenant: tenant-soporte, tenant-legal, etc.
  • ResourceQuotas y LimitRanges: límites de CPU/memoria por namespace.
  • NetworkPolicies: tenant A no puede hablar con namespaces de tenant B.
  • PriorityClasses K8s: clases con valor numérico que define preemption order si llega un pod más crítico.
  • PodDisruptionBudgets: cuántos pods de cada deployment pueden caer simultáneamente.

Capa 4 — Observability Plane: ver lo que pasa por tenant

La cuarta capa: observabilidad con dimensión tenant. Sin esto, no puedes hacer cost attribution, no puedes debugear incidentes de un solo tenant, no puedes mostrar dashboards a stakeholders.

Las cuatro propiedades obligatorias

1. tenant_id en todos los spans. El AI gateway resuelve la API key y atribuye un tenant_id. Ese ID se propaga vía params._meta o headers OTel a todos los componentes downstream (vLLM, retrieval, MCP servers, tools). Cualquier span en cualquier sistema lleva ese label. Es lo que permite reconstruir traces tenant-específicos.

2. Métricas labeled por tenant. gen_ai.usage.input_tokens{tenant="soporte-chat"} o equivalentes. Prometheus, Grafana, agrupable por tenant.

3. Cost attribution real. La suma de tokens × cost/token por tenant da el coste. Para vLLM self-hosted, el coste es por hora de GPU + parte proporcional de tokens (puedes calcular un cost-per-1k-tokens equivalente).

4. Audit log inmutable. Cada API key usada, cada modelo invocado, cada cambio de quota, cada budget exceeded. Para compliance.

Showback vs chargeback

Distinción importante de FinOps que ha ganado claridad en 2026:

Showback: visibilidad sin consecuencia. “Equipo de soporte, has consumido $623 este mes en LLM”. Información, no factura. Permite detectar abusos sin penalizar antes de que el equipo entienda.

Chargeback: el coste se imputa al presupuesto del equipo. Cuando se acaba, se acaba. Cambia comportamiento.

La práctica que funciona: 6-18 meses en showback mientras se calibran tags, se identifican misattributions, se forma a los equipos. Después chargeback cuando los números son creíbles. Lanzar chargeback el día 1 cuando los costs aún están sucios crea pelea política inmediata; lanzar showback prepara terreno para que el chargeback aterrice ordenadamente.

Solo 14% de organizaciones tienen chargeback activo según un survey reciente, lo que indica que esto sigue siendo mayoritariamente showback en producción real.

Herramientas

  • Kubecost: cost allocation por namespace, deployment, pod en Kubernetes. Para el coste de la GPU compartida, allocate proporcionalmente a tokens consumidos por tenant.
  • Finout: FinOps platform que combina cloud bills + LLM API costs en una vista unificada con tagging virtual.
  • Langfuse: ya cubierto. Cost tracking por trace, agrupable por usuario o session metadata.
  • LiteLLM tracking nativo: el master DB de LiteLLM mantiene running spend por team, user, API key, accesible vía API o UI.

Dashboard mínimo multi-tenant

Cualquier plataforma debería tener:

  1. Resumen por tenant: spend mensual, RPS actual, TPM consumido, % budget gastado, sesiones activas.
  2. Top usuarios dentro de cada tenant (para detección de abuso interno).
  3. Latencia p95 por tenant: SLA tracking.
  4. Errores 429 / 503: cuántas requests están siendo rate-limitadas o rechazadas por overload.
  5. Cost trend: trayectoria mensual con proyección.
  6. Drift por tenant (de la serie post-tracing): si un tenant empieza a tener peores resultados, alerta.

Dimensionado en clusters GPU mid-scale: decisiones concretas

Bajemos a hardware. Tomamos como referencia un nodo con N H100 SXM (entre 4 y 8) con NVLink/NVSwitch, 80 GB HBM3 cada una. Eso da entre 320 GB y 640 GB de VRAM agregada. Conectividad inter-GPU 900 GB/s (NVLink 4) o 600 GB/s (NVLink 3) según generación. Ancho de banda HBM por GPU 3.35 TB/s.

Decisiones por defecto

Empezar con Enfoque A: todas las GPUs del nodo sirviendo un único modelo grande de 70B en BF16 con tensor parallel = N. Capacidad real esperada (calculada para un nodo HGX estándar de 8 GPUs como ejemplo; escala aproximadamente lineal con N):

  • VRAM modelo (70B BF16): ~140 GB (≈ 17.5 GB/GPU en TP=8).
  • VRAM overhead vLLM + activations: ~10 GB/GPU.
  • VRAM libre para KV cache: ~52 GB/GPU. En un nodo de 8 GPUs son ~416 GB agregados; en uno de 4 son ~210 GB.
  • Con --kv-cache-dtype=fp8 y un modelo 70B GQA: ~320 KB/token.
  • Capacidad agregada de cache (nodo de 8 GPUs): ~1.3M tokens repartibles entre sesiones simultáneas.

Esto se traduce en throughput y concurrencia (cifras orientativas para un nodo de 8 GPUs):

Sesiones simultáneasContexto medio por sesiónThroughput agregado (tokens/s)
3216K~5000
648K~8000
1284K~12000

Latencias típicas: TTFT ~150ms a tráfico bajo, TPOT ~15-20 ms/tok. Con concurrencia alta, TTFT sube hasta ~500ms si el queue está saturado.

Esquema de tenants ejemplo

Cluster con 4 tenants y un pool de research:

TenantTPM capRPM capConcurrencyBudgetPriorityModelos
Soporte chat80K800501500 USD/mesGuaranteedllama-3-70b, qwen3-32b
Legal RAG30K20015600 USD/mesGuaranteedllama-3-70b
Agente code50K300251200 USD/mesBest-effortllama-3-70b, qwen-coder
Data extr. batch40K100040400 USD/mesSpotllama-3-70b, qwen3-32b
Research / notebooks10K1005200 USD/mesSpottodos

Suma TPM: 210K. Capacidad agregada del cluster: ~180K TPM sostenidos. Está overcommit del ~15%, asumiendo que no todos los tenants llegan al techo simultáneamente. Es lo normal y deseable; si todos lo hacen al mismo tiempo, las priority classes degradan ordenadamente.

Cuándo añadir hardware

Señales que indican que el nodo se ha quedado pequeño:

  • TTFT p95 sostenida > 500 ms durante horas de pico → el queue se está acumulando.
  • vllm:num_requests_waiting constantemente > 20 → admission control empezando a rechazar.
  • Utilización GPU sostenida > 80% en horas críticas sin caer abajo en horas valle → no hay margen.
  • Tasa de 429 sobre los tenants guaranteed > 1% → la plataforma rompe SLA en producción.

Cuando varios de estos se cumplan, el siguiente paso natural es añadir otro nodo HGX con NVLink interno y montar una segunda instancia vLLM del mismo modelo. El gateway hace load balancing entre las dos instancias. Throughput agregado se duplica; latencia se mantiene.

Trampas operativas comunes

Gateway sin auth: backdoor al cluster

Tu vLLM está en un Service ClusterIP, la app principal habla con él. Algún tenant directo descubre el endpoint y le pega directamente sin pasar por el gateway. Quotas y costs se evaden silenciosamente. NetworkPolicy estricta: solo el gateway puede hablar con los Service vLLM; el resto del cluster no.

Activas MIG en una GPU pensando que tendrás aislamiento + multi-GPU; descubres que MIG desactiva NVLink. Cualquier modelo grande con TP queda inservible. Decide MIG vs NVLink globalmente por cluster, no por GPU individual.

Quotas pegadas al techo del cluster

Sumas los TPM de todos los tenants y dan exactamente la capacidad del cluster. Cuando dos tenants pico simultáneamente, ambos esperan o uno rechaza. Overcommit 10-20% es saludable (asume que no todos pican a la vez); más es peligroso.

Sin observabilidad multi-tenant desde el día 1

Lanzas con quotas y aislamiento pero sin tenant_id en spans. A los 3 meses, tu CFO pregunta “¿cuánto cuesta el agente de soporte vs el de legal?” y no puedes responder. OTel con tenant_id obligatorio desde la primera versión, aunque no haya dashboards aún; tener los datos vale más que tener dashboards perfectos sin datos.

Showback que nunca llega a chargeback

Llevas 18 meses en showback, los equipos saben los números, nadie cambia comportamiento. Sin la presión del chargeback real, el incentivo se diluye. Calendario explícito para la transición a chargeback, con dueño y deadline.

Modelos no whitelisteados consumiendo presupuesto

Un equipo descubre que LiteLLM tiene gpt-4o configurado. Lo usa sin permiso. El budget se quema en API externa cuando la idea era usar el self-hosted barato. Whitelist explícita por team de modelos accesibles.

Priority classes mal calibradas

Todo el mundo se declara “guaranteed”. En el primer pico, no queda nada por degradar y todo sufre. Priority classes solo para casos críticos con justificación. La mayoría debería ser best-effort.

Sin failover desde el gateway

Tu vLLM se cae. El gateway no tiene fallback configurado y devuelve 503 a todos los tenants. Fallback configurado a otro modelo, idealmente externo (OpenAI) para cargas guaranteed, aunque pague más por hora — la disponibilidad vale más que el coste por hora.

Roadmap operativo de arranque

Si parte de cero con un nodo GPU vacío, el orden mínimo es el siguiente. Cada hito es un día de trabajo con margen, no apretado:

Día 1-2 — Infra base K8s. NVIDIA GPU Operator + nvidia-device-plugin + dcgm-exporter + NetworkPolicies cluster-default. Validación: un pod básico con nvidia.com/gpu: 1 se schedulea.

Día 3 — vLLM con un modelo grande y tensor parallel del nodo entero. Helm chart de vLLM Production Stack (o vLLM bare manifests). Pesos del modelo en PVC compartido (CephFS o NFS). Validación: una petición curl contra el Service interno responde.

Día 4 — AI Gateway: LiteLLM. Helm chart, Postgres para budgets, master key, primer model_list pointing a vLLM. Validación: una petición OpenAI-compatible vía LiteLLM responde con el mismo contenido que el vLLM directo.

Día 5 — Multi-tenancy básica. Crear teams, API keys, budget, model whitelist. Probar con dos teams. Validación: el segundo team usando el modelo que no tiene whitelisteado recibe 403.

Día 6 — Observabilidad mínima. Prometheus + Grafana scraping vLLM y LiteLLM. Dashboard con TTFT, TPOT, throughput, num_requests_waiting, budget_consumed_per_team. Validación: visible en Grafana con datos reales.

Día 7-8 — Cliente piloto. Un tenant real (idealmente uno interno controlado) empieza a usar. Mide latencias reales, descubre los primeros incidentes operativos.

Día 9-10 — Tuning. Ajustar --max-num-seqs, --gpu-memory-utilization, priority classes, quotas según lo aprendido del piloto.

Día 11-14 — Onboarding del segundo tenant + iteración. Repeat. Cada nuevo tenant onboarded revela nuevos casos.

A las dos semanas tienes una plataforma operacional con dos tenants reales y datos para decidir si está lista para más. La línea de avance de aquí en adelante es horizontal (más tenants) hasta saturar; a partir de ahí, vertical (más hardware).

Lo que no hemos cubierto (próximos posts)

  • Fine-tuning continuo en producción (post 6, decidido): LoRA/QLoRA/DPO, dataset curation, eval gates, A/B versioning con tráfico real entre versiones del modelo.
  • Constitutional AI y alignment runtime: opción que sigue en la mesa.
  • Edge LLMs: cuando un cluster H100 es demasiado caro para una carga concreta, modelos distillados corriendo en NPUs o GPUs consumer.
  • GPU networking deep dive: NCCL, InfiniBand, GPUDirect, RDMA. Para clusters multi-nodo con tensor parallel cross-host.

Referencias

Multi-tenancy y aislamiento GPU:

AI Gateways:

FinOps multi-tenant:

Cross-references: