[!NOTE] Traducción automática Este artículo se tradujo automáticamente a partir de la versión original en inglés.
Guía de LoRAX Serving: Operación de múltiples adaptadores LoRA en Kubernetes
Un modelo base y numerosos adaptadores LoRA generan un problema poco habitual de tipo serving. Las pesas base se comparten, pero cada solicitud podría requerir un conjunto distinto de pesas del adaptador. Un diseño convencional que implica desplegar una versión distinta para cada variante desperdicia memoria GPU, ya que la mayoría de las variantes permanecen inactivas.
LoRAX Aborda ese problema de la “cola larga”. Carga los adaptadores bajo demanda, agrupa las solicitudes dirigidas a adaptadores diferentes y traslada los pesos de los adaptadores entre la memoria GPU y CPU. El eslogan atractivo es “miles de modelos afinados en un único GPU”. La pregunta técnica es más concreta: ¿el conjunto actual de adaptadores activos, el patrón de llegada de las solicitudes y el objetivo de latencia se benefician lo suficiente de la planificación de intercambios como para justificar otro serving runtime?
Esta guía responde a dicha pregunta, verifica localmente el API y, a continuación, convierte el diagrama Helm inicial del repositorio en un plan de producción detallado.
TL;DR. Se debe elegir LoRAX cuando existen numerosos adaptadores compatibles con LoRA que comparten un mismo modelo base y el tráfico es escaso o de cola larga. La capacidad depende del conjunto de elementos en uso en ese momento, y no del tamaño del catálogo. Es necesario fijar los valores de runtime, autenticar e incluir en la lista blanca los identificadores de los adaptadores, implementar un sistema de caché de artefactos duradero junto con pruebas de verificación, enrutar la solicitud según la localidad de caché, y gestionar por separado las rutas para datos fríos y cálidos mediante benchmark.
El problema de serving es el conjunto de trabajo
LoRA congela un modelo base y aprende actualizaciones de rango bajo para las matrices de pesos seleccionadas. El adaptador resultante suele ser mucho más pequeño que un checkpoint completo, pero su tamaño sigue dependiendo del rango, los módulos objetivo, la cantidad de capas y el tipo de dato. Afirmaciones absolutas como “cada adaptador ocupa 100 MB” constituyen indicadores poco fiables sobre su capacidad real.
Para serving, es necesario distinguir tres cantidades:
- Tamaño del catálogo: cada adaptador que una plataforma puede recuperar desde el almacenamiento
- Conjunto de trabajo activo: adaptadores que reciben solicitudes dentro del período de retención en la caché
- Conjunto concurrente: adaptadores representados en lotes al mismo tiempo
Un catálogo puede albergar miles de adaptadores sin que eso signifique que caben miles en VRAM. Lo importante es la frecuencia con la que cambia el conjunto activo, el tamaño de dichos adaptadores y si las solicitudes dirigidas a adaptadores diferentes pueden compartir lotes útiles.
LoRAX combina cuatro mecanismos:
- El modelo base permanece instalado para todos los adaptadores compatibles.
- Una solicitud especifica un adaptador, el cual puede ser localizado desde Hugging Face, Predibase o un sistema de archivos.
- La programación del intercambio de adaptadores realiza precarga y traslada pesos entre la memoria GPU y la memoria CPU.
- Los grupos de batch continuo heterogéneos agrupan solicitudes dirigidas a adaptadores diferentes.
El informe del proyecto indica que el agrupamiento heterogéneo mantiene la tasa de transferencia y la latencia prácticamente constantes a medida que aumenta el número de adaptadores concurrentes en su benchmarks. Considérenlo como una hipótesis para su carga de trabajo. Factores como la longitud de Prompt, la longitud de la salida, el rango, los módulos objetivo, la ocupación del lote, el cambio en la caché y la generación de GPU pueden modificar dicho resultado.
Cuándo LoRAX es una opción viable
LoRAX merece un benchmark cuando se cumplen todas estas condiciones:
- Los adaptadores se entrenaron utilizando el mismo modelo base compatible y el mismo contrato de tokenización.
- El tráfico se distribuye entre varios adaptadores, presentando una significativa cola larga.
- Es preferible cargar un adaptador “frío” bajo demanda en lugar de reservar un entorno de despliegue exclusivo para él.
- Ya existe un sistema de enrutamiento de usuarios o tareas en el límite de la aplicación.
- El equipo puede gestionar la inferencia especializada runtime y su comportamiento de caché.
Entre los casos típicos se encuentran asistentes específicos para cada cliente, numerosas variantes por dominio, y experimentos en línea que comparten una base checkpoint.
Se trata de una opción menos adecuada cuando unos pocos adaptadores dominan el tráfico, los modelos no comparten una base común, los objetivos de latencia estrictos no permiten manejar cargas iniciales lentas, o la plataforma no puede controlar de forma segura qué artefactos carga el servidor. En esos casos, una implementación estándar de vLLM o TGI con un conjunto fijo de adaptadores puede resultar más sencilla.
No utilice Kubernetes solo porque el catálogo sea grande. Primero, demuestre la compatibilidad entre runtime y el adaptador en un único GPU.
Verificar localmente una base y dos adaptadores
El README de LoRAX recomienda su contenedor ya preparado. En un entorno real, se debe utilizar un hash de imagen inmutable; main Se muestra aquí únicamente porque se trata de la etiqueta de inicio rápido documentada en el repositorio.
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
El mínimo documentado es Linux, Docker, una tarjeta NVIDIA de la serie Ampere o superior GPU, y controladores compatibles con CUDA 11.8. Las licencias de los modelos y los repositorios protegidos también pueden requerir un token Hugging Face.
Comencemos 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}
}'
Luego, envíe 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"
}
}'
La primera solicitud puede descargar y cargar el adaptador; las solicitudes posteriores pueden utilizar los artefactos en caché y los pesos residentes. Es necesario registrar ambos caminos. Una única solicitud de tipo “warm” no proporciona mucha información sobre el comportamiento en casos de distribución de cola larga.
Utilice el cliente actual de OpenAI
LoRAX ofrece un endpoint de chat compatible con OpenAI. El model El campo identifica al 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 necesita una clave API. Esto resulta práctico para entornos locales, pero es inseguro si se utiliza como configuración orientada a Internet. Es necesario colocar la autenticación, la autorización por tenant, los límites de cuota y la lista de adaptadores permitidos antes de aplicar dicha clave.
Definir una puerta de compatibilidad
Antes de que un adaptador ingrese al catálogo, verifique al menos:
- Modelo base declarado y su versión
- Compatibilidad entre el tokenizador y las plantillas de chat
- Rango de LoRA y módulos de destino soportados por runtime
- Formato de los artefactos y formas de los tensores
- Licencia, procedencia e índice de integridad
- Un conjunto reducido de pruebas de comportamiento y de regresión
Rechazar los artefactos incompatibles durante el registro, en lugar de hacerlo en la primera solicitud del usuario.
Comprender la residencia antes de desplegar
El modelo base consume la mayor parte fija de la memoria dedicada a GPU. Los pesos del adaptador, KV cache, el espacio de trabajo por lote y los núcleos de runtime compiten por el resto. La RAM CPU puede albergar los adaptadores descargados, mientras que /data Almacena los artefactos descargados.
Estos niveles no son intercambiables. Es necesario leer y materializar un artefacto de disco o Hub antes de que pueda convertirse en un adaptador residente de tipo CPU- o GPU-. Se deben medir las transiciones por separado:
| Ruta | Qué incluye | |
|---|---|---|
| GPU número de hits | Adaptador ya residente | tiempo de cola y tiempo hasta el primer token |
| CPU número de hits | Transferencia o rematerialización en GPU | retardo por carga del adaptador y latencia de extremo a extremo |
| ¡Se ha producido un impacto con el artefacto! | Leer desde local /data caché | Retraso de lectura/carga y bytes en caché |
| Error de envío remoto | Descarga, validación y carga | tiempo de descarga, fallos y latencia total en estado frío |
La planificación de capacidad debe reproducir la distribución real de popularidad de los adaptadores. Los identificadores de adaptador aleatorios uniformes generan un problema de caché distinto al que se presenta con una carga de trabajo de inquilinos similar a la ley de Zipf.
Implemente con cuidado el diagrama del repositorio
El repositorio contiene charts/lorax, por lo que el punto de partida reutilizable es una revisión del repositorio fijada y un gráfico 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 realizada el 15 de julio de 2026, los valores predeterminados del gráfico merecen atención:
- la etiqueta de imagen es
latest /dataes unemptyDir, por lo que el reemplazo del pod descarta los artefactos descargados- Las pruebas de actividad y disponibilidad están vacías
- El token Hugging Face se modela como un valor de entorno literal
- Se solicita uno GPU por defecto
Eso convierte al gráfico en un marco útil de referencia, y no en una política para entornos de producción.
Partir de la estructura de valores real del gráfico
El gráfico incluye como subconfiguración a runtime deploymentLos argumentos del lanzador son una lista de pares nombre/valor. Una superposición mínima se ve así:
deployment:
replicas: 1
image:
repository: ghcr.io/predibase/lorax
tag: "<tested-tag>" # Prefer an immutable digest in rendered manifests.
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"
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 5
failureThreshold: 600
service:
serviceType: ClusterIP
port: 80
Los límites de tokens mencionados anteriormente son valores iniciales de ejemplo, y no representan recomendaciones para determinar el tamaño adecuado. Es necesario calcularlos a partir de prompts representativos, de la concurrencia esperada, de la memoria GPU disponible y de pruebas de carga.
Corrija explícitamente las deficiencias.
El plantilla actual del gráfico contiene códigos fijos. emptyDir volúmenes y valores de entorno simples. Por lo tanto, una implementación reforzada requiere un diagrama revisado fork, un parche aplicado tras la generación, o una capa de manifiesto de nivel superior para añadir:
- un PersistentVolumeClaim o caché de artefactos local al nodo montado en
/data - Una referencia secreta para las credenciales del Hub.
- Una sonda de inicio antes de una sonda de actividad más intensiva.
- Política de interrupción de pods y distribución topológica para múltiples réplicas.
- NetworkPolicy, restricciones en la cuenta de servicio y un gateway autenticado.
- Fijación de hashes de imágenes y verificaciones de integridad de los artefactos.
No se debe colocar un token de Hub directamente en un archivo de valores ya commitado. Tampoco se debe dar por sentado que dos réplicas generan una alta disponibilidad útil hasta que ambas puedan cargar el modelo base y el router pueda evitar enviar todos los adaptadores “fríos” a ambos pods.
Ruta para la localidad de caché
El equilibrado por round-robin puede convertir cada réplica en una caché inactiva. Un router útil asigna de forma hash o mediante otro mecanismo de afinidad un ID de adaptador permitido a una réplica, manteniendo al mismo tiempo una ruta de conmutación por fallas cuando dicha réplica está fuera de servicio.
La clave de enrutamiento debe provenir del estado autenticado de la aplicación, y no de un parámetro de URL pública arbitrario. De lo contrario, un llamante podría forzar descargas remotas, vaciar los cachés o intentar acceder a nombres de adaptadores privados.
¿LoRAX o vLLM?
El vLLM actual puede servir a los módulos LoRA declarados en el momento del arranque, y también puede cargarlos de forma dinámica a través de endpoints o complementos de resolución. Su propia documentación advierte que la actualización del adaptador runtime conlleva riesgos de seguridad, por lo que no debe utilizarse en entornos de producción fuera de un ambiente aislado y de confianza.
La comparación útil es operativa y no numérica:
| Pregunta | LoRAX | vLLM |
|---|---|---|
| ¿Cómo se descubren los adaptadores de cola larga? | El ID del adaptador puede resolver Hugging Face, Predibase o artefactos del sistema de archivos bajo solicitud. | Módulos estáticos, puntos de extremo de gestión dinámica o complementos de resolución |
| ¿Cómo se gestiona la residencia? | Programación explícita del intercambio de adaptadores entre GPU y CPU | Configuración de los límites activos y CPU LoRA, además del comportamiento del resolvedor |
| ¿Qué es la interfaz de solicitud? | TGI-estilo /generate, cliente en Python y chat compatible con OpenAI | serving compatible con OpenAI y APIs nativo en Python |
| ¿Qué debe decidir? | Latencia en condiciones frías/cálidas, rotación de caché, rendimiento por lotes heterogéneos y adecuación operativa | La misma reproducción de carga de trabajo y los criterios operativos |
Evite reglas como “LoRAX para 1.000 adaptadores, vLLM para diez”. El mero tamaño del catálogo no determina el rendimiento. Benchmark, tanto si se trata de la misma base, adaptadores, prompts, rangos, trazas de llegada como del hardware.
Prueba de aceptación en producción
Antes de ampliar el catálogo, ejecute una reproducción que incluya:
- Un conjunto fijo de nodos activos para establecer un rendimiento y una latencia óptimos.
- Una distribución de cola larga para medir CPU y las consultas que acceden al caché de artefactos.
- Un aumento repentino en el uso de adaptadores nunca vistos anteriormente pero que se encuentran en la lista de permisos.
- Sustitución de pods para evaluar la recuperación tanto de los componentes básicos como de los adaptadores.
- Un adaptador no disponible o dañado para comprobar el funcionamiento del aislamiento y las soluciones alternativas.
- Usuarios concurrentes para verificar los procesos de autenticación, las cuotas establecidas y las etiquetas de métricas.
Registra la tasa de solicitudes, el tiempo en cola, el tiempo hasta obtener el primer token, la latencia entre tokens, la latencia total, el tiempo de carga del adaptador, la categoría de hito en caché, la memoria de GPU y CPU, los bytes descargados, así como los fallos por motivo. Asegúrate de no incluir los identificadores de adaptador en las etiquetas de métricas ilimitadas; en su lugar, asigna dichos identificadores a dimensiones controladas o a trazas muestreadas.
Defina los umbrales de aceptación antes de realizar las pruebas. Algunos ejemplos son una tasa máxima de errores en el camino en frío, un objetivo P99 para el estado caliente, un objetivo de aciertos en caché basado en 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 a numerosos ajustes finos compatibles, obtenidos a partir de una flota de copias del modelo base, en un problema de colocación de adaptadores. Esto puede constituir una solución eficaz para cargas de trabajo de cola larga, pero, por definición, no garantiza que los costes ni la latencia sean constantes. El conjunto de elementos en uso activo, la ruta de intercambio, la mezcla por lotes y la capa de almacenamiento siguen siendo determinantes para el resultado final.
Pruebe primero esas mecánicas en un GPU. A continuación, aborde Kubernetes de forma seria: fije los artefactos, conserve la caché, proteja las credenciales, autorice los adaptadores, dirija la carga según la localización y mida cada ruta de residencia. Si LoRAX supera a una configuración actual de vLLM bajo las mismas condiciones de reejecución, la decisión de despliegue contará con pruebas sólidas que la respalden.
Referencias
- repositorio LoRAX y README — características soportadas, requisitos, APIs, y el chart Helm
- Valores de la gráfica LoRAX y Plantilla de despliegue — valores predeterminados actuales y comportamiento del volumen vLLM LoRA adaptadores — adaptador estático y dinámico serving
- el artículo académico sobre LoRA — método de adaptación de rango bajo documentación de Hugging Face y PEFT — formatos de adaptador e integración en el entrenamiento