Guía de serving de LoRAX: adaptadores LoRA en Kubernetes a gran escala
Traducción automática Este artículo se tradujo automáticamente a partir de la versión original en inglés.
Un modelo base y muchos adaptadores LoRA plantean un problema de serving poco habitual. Los pesos base se comparten, pero cada request puede necesitar un conjunto diferente de pesos de adaptador. Un diseño convencional con un deployment por variante desperdicia memoria de GPU cuando la mayoría de las variantes están inactivas.
LoRAX aborda esa cola larga. Carga los adaptadores bajo demanda, agrupa en batches los requests de distintos adaptadores y mueve los pesos de los adaptadores entre la memoria de GPU y la memoria de CPU. El titular atractivo es «miles de modelos fine-tuned en una sola GPU». La cuestión de ingeniería es más concreta: dado tu conjunto de adaptadores activos, el patrón de llegada de requests y el objetivo de latencia, ¿el exchange scheduling aporta lo suficiente como para justificar otro runtime de serving?
Esta guía está dirigida a ingenieros de inferencia y de plataforma que necesitan servir muchas variantes LoRA desde un único modelo base. Muestra cómo probar las APIs documentadas, dimensionar el working set y convertir el chart de Helm inicial en un plan de producción explícito.
Resumen. Elige LoRAX cuando muchos adaptadores LoRA compatibles compartan un único modelo base y el tráfico sea disperso o de cola larga. La capacidad depende del working set activo, no del tamaño del catálogo. Fija la versión del runtime, autentica y crea una allowlist de los IDs de adaptador, añade una caché duradera de artefactos y probes, enruta teniendo en cuenta la localidad de la caché y mide por separado los cold paths y los warm paths.
El problema de serving es el working set
LoRA congela un modelo base y aprende actualizaciones de bajo rango para determinadas matrices de pesos. El adaptador resultante suele ser mucho más pequeño que un checkpoint completo, pero su tamaño sigue dependiendo del rank, los módulos objetivo, el número de capas y el dtype. Afirmaciones fijas como «cada adaptador ocupa 100 MB» son malos datos de partida para dimensionar la capacidad.
En serving, distingue tres cantidades:
- Tamaño del catálogo: todos los adaptadores que una plataforma puede resolver desde el almacenamiento
- Working set activo: adaptadores que reciben requests durante la ventana de retención de la caché
- Conjunto concurrente: adaptadores representados en batches en un mismo instante
Un catálogo puede contener miles de adaptadores sin que sea posible alojar miles en VRAM. Lo importante es la frecuencia con la que cambia el conjunto activo, el tamaño de esos adaptadores y si los requests de distintos adaptadores pueden compartir batches útiles.
LoRAX combina cuatro mecanismos:
- El modelo base permanece residente para todos los adaptadores compatibles.
- Un request identifica un adaptador, que puede resolverse desde Hugging Face, Predibase o un sistema de archivos.
- El exchange scheduling de adaptadores precarga y descarga pesos entre la memoria de GPU y la de CPU.
- El continuous batching heterogéneo agrupa requests dirigidos a distintos adaptadores.
El proyecto LoRAX afirma que el batching heterogéneo mantiene el throughput y la latencia casi constantes a medida que aumenta el número de adaptadores concurrentes en sus benchmarks. Trata ese resultado del proveedor como una hipótesis para tu workload. La longitud del prompt, la longitud de salida, el rank, los módulos objetivo, la ocupación de los batches, el churn de la caché y la generación de la GPU pueden cambiar el resultado.
El gráfico restaurado procede del informe de lanzamiento de LoRAX de Predibase de noviembre de 2023. Predibase evaluó Llama 2 7B con queries distribuidas entre 1 y 128 adaptadores en una NVIDIA A10G. Este gráfico muestra la comparación de costes para entre 1 y 32 adaptadores al procesar un millón de tokens, repartidos a partes iguales entre los adaptadores.

Comparativa archivada del proyecto, reproducida a partir del informe de LoRAX de Predibase de 2023. Los costes de LoRAX y de los deployments dedicados utilizan GPU-hours de aquel experimento. Con el nivel de detalle de la fuente, la línea de GPT-3.5 Turbo utiliza el coste por token del modelo fine-tuned.
Interpreta las barras naranjas planas como un resultado del diseño de ese benchmark, no como una promesa de precios actual. La prueba envió un total fijo de un millón de tokens y permitió que distintos adaptadores compartieran un batch. El baseline dedicado suponía compute alojado por separado para cada modelo, por lo que su coste aumentaba con el número de modelos.
Predibase no publicó estos datos del benchmark:
- proporción de tokens de prompt frente a tokens de salida
- longitudes de los requests
- tamaño del batch
- rank del adaptador
- precio por GPU-hour
- modelo exacto de utilización de los deployments dedicados
- precios históricos exactos de entrada y salida de GPT-3.5
Por tanto, el informe no contiene información suficiente para reproducir de forma independiente los valores monetarios representados.
El gráfico tampoco cubre el tráfico disperso, las descargas en frío, los precios actuales de cloud, las GPUs más recientes, otros modelos base ni adaptadores con ranks diferentes. Sirve para justificar la reproducción del workload, pero no puede sustituirla.
Cuándo encaja LoRAX
Merece la pena hacer un benchmark de LoRAX cuando se cumplan todas estas condiciones:
- los adaptadores se han entrenado contra el mismo modelo base compatible y respetan el mismo contrato del tokenizer
- el tráfico abarca muchos adaptadores, con una cola larga significativa
- cargar un adaptador en frío bajo demanda es preferible a reservar un deployment para él
- el routing por tenant o tarea ya existe en el límite de la aplicación
- el equipo puede operar un runtime de inferencia especializado y gestionar el comportamiento de su caché
Entre los casos habituales están los asistentes específicos por tenant, muchas variantes de dominio y experimentos online que comparten un checkpoint base.
LoRAX encaja peor cuando unos pocos adaptadores concentran la mayor parte del tráfico o cuando los modelos no comparten un modelo base. También encaja peor cuando los objetivos estrictos de latencia no toleran cargas en frío o cuando la plataforma no puede controlar de forma segura qué artefactos carga el servidor. En esos casos, un deployment estándar de vLLM o TGI con un conjunto fijo de adaptadores puede ser más sencillo.
No uses Kubernetes simplemente porque el catálogo sea grande. Primero demuestra el runtime y la compatibilidad de los adaptadores en una sola GPU.
Prueba localmente un modelo base y un adaptador
El README de LoRAX recomienda su contenedor prebuilt. En un entorno real, utiliza un digest de imagen inmutable. main aparece aquí únicamente porque es el tag de quick start documentado en el repositorio. Estos ejemplos son ilustrativos y no se han verificado localmente en este checkout. Confírmalos con las versiones de la imagen y de las dependencias que vayas a desplegar.
mkdir -p data
docker run --rm --gpus all --shm-size 1g \
-p 8080:80 \
-v "$PWD/data:/data" \
ghcr.io/predibase/lorax:main \
--model-id mistralai/Mistral-7B-Instruct-v0.1
Los requisitos mínimos documentados son Linux, Docker, una GPU NVIDIA Ampere o posterior y drivers compatibles con CUDA 11.8. Las licencias de los modelos y los repositorios gated también pueden requerir un token de Hugging Face.
Empieza con el modelo base:
curl http://127.0.0.1:8080/generate \
-H 'Content-Type: application/json' \
-d '{
"inputs": "[INST] Give one reason to measure cold-adapter latency. [/INST]",
"parameters": {"max_new_tokens": 64}
}'
Después, envía un adaptador compatible:
curl http://127.0.0.1:8080/generate \
-H 'Content-Type: application/json' \
-d '{
"inputs": "[INST] Solve: Natalia sold 48 clips in April and half as many in May. What is the total? [/INST]",
"parameters": {
"max_new_tokens": 64,
"adapter_id": "vineetsharma/qlora-adapter-Mistral-7B-Instruct-v0.1-gsm8k"
}
}'
El primer request puede descargar y cargar el adaptador. Los requests posteriores pueden utilizar artefactos en caché y pesos residentes. Registra ambos caminos. Un único request warm aporta poca información sobre el comportamiento de cola larga.
Usa un cliente compatible con OpenAI
LoRAX expone un endpoint de chat compatible con OpenAI. El campo model identifica el adaptador:
from openai import OpenAI
client = OpenAI(
api_key="EMPTY",
base_url="http://127.0.0.1:8080/v1",
)
response = client.chat.completions.create(
model="alignment-handbook/zephyr-7b-dpo-lora",
messages=[
{"role": "user", "content": "Explain cache locality in two sentences."},
],
max_tokens=100,
)
print(response.choices[0].message.content)
Por defecto, el servidor no requiere una API key. Es práctico para localhost, pero inseguro en una configuración expuesta a Internet. Coloca delante autenticación, autorización por tenant, cuotas y una allowlist de adaptadores.
Define un compatibility gate
Antes de incorporar un adaptador al catálogo, verifica al menos:
- modelo base y revisión declarados
- compatibilidad del tokenizer y de la chat template
- rank de LoRA y módulos objetivo compatibles con el runtime
- formato de los artefactos y formas de los tensores
- licencia, procedencia y digest de integridad
- una pequeña suite de pruebas de comportamiento y regresión
Rechaza los artefactos incompatibles durante el registro, no en el primer request de un usuario.
Comprende la residencia antes de desplegar
El modelo base consume la mayor parte fija de la memoria de GPU. Los pesos de los adaptadores, la KV cache, el workspace de los batches y los kernels del runtime compiten por el resto. La RAM de la CPU puede contener adaptadores descargados, mientras que /data almacena los artefactos descargados.
Estos niveles no son intercambiables. Un artefacto de disco o del Hub debe leerse y materializarse antes de convertirse en un adaptador residente en CPU o GPU. Mide las transiciones por separado:
| Camino | Qué incluye | Métrica que registrar |
|---|---|---|
| GPU hit | Adaptador ya residente | tiempo en cola y tiempo hasta el primer token |
| CPU hit | Transferencia o rematerialización a GPU | retraso de carga del adaptador y latencia end-to-end |
| Artifact hit | Lectura desde la caché local /data | retraso de lectura/carga y bytes de caché |
| Remote miss | Descarga, validación y carga | tiempo de descarga, fallos y latencia cold completa |
La planificación de capacidad debe reproducir la distribución real de popularidad de los adaptadores. Unos IDs de adaptador aleatorios uniformes generan un problema de caché distinto al de un workload de tenants con distribución parecida a Zipf.
Despliega el chart del repositorio con cuidado
El repositorio contiene charts/lorax, por lo que el punto de partida reproducible es una revisión fijada del repositorio y un chart local:
git clone https://github.com/predibase/lorax.git
cd lorax
git checkout <reviewed-commit-or-release>
helm dependency update charts/lorax
helm template lorax charts/lorax -f values.production.yaml
helm upgrade --install lorax charts/lorax \
--namespace inference \
--create-namespace \
-f values.production.yaml
Según la revisión del 15 de julio de 2026, los values del chart y la plantilla del Deployment muestran valores por defecto que requieren atención:
- el tag de la imagen es
latest /dataes unemptyDir, por lo que reemplazar el pod descarta los artefactos descargados- los probes de liveness y readiness están vacíos
- el token de Hugging Face se modela como un valor de entorno literal
- por defecto se solicita una GPU
El chart es un buen andamiaje. No es una política de producción.
Parte de la estructura real de values del chart
El chart anida la configuración del runtime bajo deployment, y los argumentos del launcher son una lista de pares nombre/valor. Un overlay mínimo sería:
deployment:
replicas: 1
image:
repository: ghcr.io/predibase/lorax
tag: "<tested-release-tag>"
args:
- name: "--model-id"
value: "mistralai/Mistral-7B-Instruct-v0.1"
- name: "--max-input-length"
value: "2048"
- name: "--max-total-tokens"
value: "3072"
- name: "--max-batch-total-tokens"
value: "8192"
- name: "--max-batch-prefill-tokens"
value: "4096"
resources:
requests:
nvidia.com/gpu: "1"
limits:
nvidia.com/gpu: "1"
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: lorax-hub
key: token
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 5
failureThreshold: 600
service:
serviceType: ClusterIP
port: 80
Los límites de tokens anteriores son valores iniciales de ejemplo, no recomendaciones de dimensionamiento. Derívalos a partir de prompts representativos, concurrencia esperada, memoria de GPU y pruebas de carga.
Corrige explícitamente las carencias
La plantilla actual del chart pasa deployment.env a través de toYaml, por lo que un overlay normal de values puede utilizar valueFrom.secretKeyRef para las credenciales del Hub, como se muestra arriba. La plantilla fija los volúmenes emptyDir, no tiene un hook startupProbe y siempre construye la imagen como repository:tag. Por tanto, un archivo de values por sí solo no puede proporcionar /data duradero, un startup probe ni el pinning mediante digest de imagen; utiliza un fork del chart revisado, un patch post-render o una capa de manifests de nivel superior para esos cambios. Incluye en esa capa de producción:
- un PersistentVolumeClaim o una caché de artefactos local al nodo montada en
/data - un startup probe antes de un liveness probe agresivo
- una política de disrupción de pods y distribución por topología para varias réplicas
- NetworkPolicy, restricciones de la service account y un gateway autenticado
- pinning mediante digest de imagen y comprobaciones de integridad de artefactos
No coloques un token del Hub directamente en un archivo de values versionado. Dos réplicas solo proporcionan alta disponibilidad útil si ambas pueden cargar el modelo base. Además, el router debe evitar enviar cada adaptador en frío a ambos pods.
Enruta teniendo en cuenta la localidad de la caché
El balanceo round-robin puede convertir cada réplica en una caché fría. Un router útil asigna un ID de adaptador permitido a una réplica mediante hash u otra regla estable. Debe mantener un camino de failover para los casos en que esa réplica no esté disponible.
La clave de routing debe proceder del estado autenticado de la aplicación, no de un parámetro arbitrario de una URL pública. De lo contrario, un caller puede forzar descargas remotas, provocar churn en las cachés o sondear nombres de adaptadores privados.
¿LoRAX o vLLM?
La documentación actual de vLLM describe módulos LoRA declarados al arrancar y carga dinámica mediante endpoints o resolver plugins. Advierte de que la actualización de adaptadores en runtime presenta riesgos de seguridad y no debe utilizarse en producción fuera de un entorno aislado y de confianza.
La comparación útil es operativa, no numérica:
| Pregunta | LoRAX | vLLM |
|---|---|---|
| ¿Cómo se descubren los adaptadores de cola larga? | El ID del adaptador puede resolver artefactos de Hugging Face, Predibase o del sistema de archivos bajo demanda | Módulos estáticos, endpoints de gestión dinámica o resolver plugins |
| ¿Cómo se gestiona la residencia? | Exchange scheduling explícito de adaptadores entre GPU y CPU | Límites configurados de LoRA activos y en CPU, además del comportamiento del resolver |
| ¿Cuál es la interfaz de request? | /generate al estilo de TGI, cliente Python y chat compatible con OpenAI | Serving compatible con OpenAI y APIs nativas de Python |
| ¿Qué debería decidir? | Latencia cold/warm, churn de caché, throughput de batching heterogéneo y encaje operativo | La misma reproducción del workload y los mismos criterios operativos |
Evita reglas como «LoRAX para 1.000 adaptadores y vLLM para diez». El tamaño del catálogo por sí solo no determina el rendimiento. Haz un benchmark de ambos con el mismo modelo base, adaptadores, prompts, ranks, traza de llegadas y hardware.
Una prueba de aceptación para producción
Antes de ampliar el catálogo, ejecuta una reproducción que incluya:
- Un conjunto hot fijo para establecer el throughput y la latencia warm.
- Una distribución de cola larga para medir los hits de CPU y de la caché de artefactos.
- Un burst de adaptadores previamente desconocidos pero incluidos en la allowlist.
- El reemplazo de un pod para medir la recuperación del modelo base y de los adaptadores.
- Un adaptador no disponible o corrupto para verificar el aislamiento y el fallback.
- Tenants concurrentes para verificar la autenticación, las cuotas y las etiquetas de las métricas.
Registra estas métricas:
- tasa de requests
- tiempo en cola
- tiempo hasta el primer token
- latencia entre tokens
- latencia total
- tiempo de carga del adaptador
- clase de cache hit
- memoria de GPU
- memoria de CPU
- bytes descargados
- fallos por motivo
Evita incluir IDs de adaptador en labels de métricas sin límite de cardinalidad. Mapéalos a dimensiones controladas o a traces muestreados.
Define los umbrales de aceptación antes de la prueba. Establece una tasa máxima de errores del cold path y un objetivo de P99 warm. Define también un objetivo de cache hit para la distribución de popularidad observada y un objetivo de tiempo de recuperación tras la pérdida de un pod.
Conclusión
LoRAX convierte muchos fine-tunes compatibles de una flota de copias del modelo base en un problema de placement de adaptadores. Puede ser un diseño sólido para workloads de cola larga, pero no hace que el coste o la latencia sean planos por definición. El working set activo, el camino de exchange, la mezcla de batches y la capa de almacenamiento siguen determinando el resultado.
Demuestra primero esos mecanismos en una sola GPU. Después, trata Kubernetes como corresponde: fija los artefactos, conserva la caché, protege las credenciales, autoriza los adaptadores, enruta favoreciendo la localidad y mide cada camino de residencia. Si LoRAX supera una configuración actual de vLLM con la misma reproducción, la decisión de despliegue estará respaldada por datos.
Referencias
- Repositorio y README de LoRAX — funcionalidades compatibles, requisitos, APIs y chart de Helm
- Informe de lanzamiento de LoRAX y benchmark de 2023 — fuente y condiciones del gráfico de costes restaurado
- Values del chart de LoRAX y plantilla del Deployment — valores por defecto actuales y comportamiento de los volúmenes
- Adaptadores LoRA de vLLM — serving estático y dinámico de adaptadores
- Artículo sobre LoRA — método de adaptación de bajo rango
- Documentación de PEFT de Hugging Face — formatos de adaptador e integración del entrenamiento