[!NOTE] Tradução automática Este artigo foi traduzido automaticamente a partir da versão original em inglês.
Guia LoRAX Serving: Operação de vários LoRA Adaptadores em Kubernetes
Um modelo base e vários adaptadores LoRA criam um problema incomum de serving. Os pesos base são partilhados, mas cada pedido pode exigir um conjunto diferente de pesos dos adaptadores. Um design convencional que envolve uma implementação separada para cada variante gasta GPU de memória quando a maioria das variantes permanece inativa.
LoRAX Aborda esse problema de “cauda longa”. Ele carrega adaptadores sob demanda, agrupa solicitações destinadas a adaptadores diferentes e transfere os pesos dos adaptadores entre a memória GPU e a CPU. O título atrativo é “milhares de modelos retocados num único GPU”. A questão de engenharia é mais específica: o conjunto atual de adaptadores ativos, o padrão de chegada das solicitações e o objetivo de latência se beneficiam o suficiente com um agendamento de trocas para justificar a utilização de outro serving runtime?
Este guia responde a essa pergunta, verifica localmente o API e, em seguida, transforma o diagrama Helm de inicialização do repositório num plano de produção detalhado.
TL;DR. Escolha o LoRAX quando vários adaptadores compatíveis LoRA partilham um mesmo modelo base e o tráfego é escasso ou de cauda longa. A capacidade depende do conjunto de trabalhos ativo, e não do tamanho do catálogo. Fixe o runtime, autentique e inclua nas listas de permissões os IDs dos adaptadores, adicione armazenamento em cache duradouro para artefatos e sondagens, direcione o tráfego com base na localidade de cache, e gestione separadamente os fluxos benchmark frios e quentes.
O problema do serving é o conjunto de trabalho
LoRA congela um modelo base e aprende atualizações de baixo rank para matrizes de pesos selecionadas. O adaptador resultante é geralmente muito menor do que um checkpoint completo, mas o seu tamanho continua a depender do rank, dos módulos-alvo, do número de camadas e do tipo de dado. Afirmações fixas como “cada adaptador ocupa 100 MB” constituem indicadores pouco precisos da sua capacidade.
Para serving, devem ser distinguidas três grandezas:
- Tamanho do catálogo: cada adaptador que uma plataforma consegue recuperar a partir do armazenamento
- Conjunto de trabalho ativo: adaptadores que recebem solicitações dentro do período de retenção na cache
- Conjunto concorrente: adaptadores representados em lotes ao mesmo tempo
Um catálogo pode conter milhares de adaptadores sem que isso signifique que sejam possíveis de serem integrados todos em VRAM. O que realmente importa é a frequência com que o conjunto ativo muda, o tamanho desses adaptadores e se as solicitações dirigidas a adaptadores diferentes conseguem partilhar lotes úteis.
LoRAX combina quatro mecanismos:
- O modelo base permanece residente para todos os adaptadores compatíveis.
- Um pedido especifica um adaptador, que pode ser obtido a partir de Hugging Face, Predibase ou de um sistema de ficheiros.
- O agendamento de troca de adaptadores faz o pré-carregamento e a transferência de pesos entre a memória GPU e a memória CPU.
- Os grupos de lotação contínua heterogéneos agrupam pedidos direcionados para adaptadores diferentes.
O relatório do projeto indica que o agrupamento heterogéneo mantém a taxa de transferência e o tempo de latência quase constantes à medida que o número de adaptadores concorrentes aumenta no seu benchmarks. Considere isso como uma hipótese para a sua carga de trabalho. O comprimento de Prompt, o comprimento da saída, o ranking, os módulos-alvo, a ocupação do lote, a rotatividade da cache e a geração de GPU podem alterar o resultado obtido.
Quando o LoRAX é uma opção plausível
O LoRAX merece um benchmark sempre que todas estas condições estiverem satisfeitas:
- Os adaptadores foram treinados com base no mesmo modelo base suportado e no mesmo contrato de tokenização.
- O tráfego abrange vários adaptadores, apresentando uma significativa “cauda longa”.
- É preferível carregar um adaptador “frio” sob demanda em vez de reservar uma instância de deploy exclusivamente para ele.
- O encaminhamento de tenants ou tarefas já existe na camada da aplicação.
- A equipa consegue gerir a inferência especializada runtime e o seu comportamento de cache.
Casos típicos incluem assistentes específicos por utilizador, diversas variantes de domínio e experimentos online que partilham uma base checkpoint.
A abordagem é menos adequada quando alguns adaptadores dominam o tráfego, os modelos não partilham uma base comum, objetivos de latência elevados não permitem cargas iniciais, ou a plataforma não consegue controlar de forma segura quais artefatos o servidor deve carregar. Nesses casos, uma implementação padrão de vLLM ou TGI com um conjunto fixo de adaptadores pode ser mais simples.
Não utilize o Kubernetes apenas porque o catálogo é grande. Primeiro, comprove a compatibilidade entre o runtime e o adaptador num único GPU.
Verificar localmente uma base e dois adaptadores
O README do LoRAX recomenda o seu contêiner pré-construído. Em um ambiente real, utilize um valor de digressão de imagem imutável; main É exibido aqui apenas porque se trata da etiqueta de arranque rápido documentada pelo repositório.
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
O mínimo exigido, conforme documentado, é o Linux, o Docker, uma placa NVIDIA da série Ampere ou superior GPU, bem como controladores compatíveis com a versão CUDA 11.8. As licenças dos modelos e os repositórios protegidos por restrições também podem exigir um token Hugging Face.
Comece com o 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}
}'
Envie então um adaptador compatível:
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"
}
}'
O primeiro pedido pode descarregar e carregar o adaptador; os pedidos subsequentes podem utilizar artefactos em cache e pesos residentes. Registem ambos os caminhos. Um único pedido de aquecimento não fornece muitas informações sobre o comportamento em cenários de cauda longa.
Utilize o cliente atual da OpenAI
LoRAX disponibiliza um endpoint de chat compatível com o OpenAI. O model o campo identifica o 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 predefinição, o servidor não requer uma chave API. Isso é conveniente para uso em localhost, mas representa um risco considerável quando utilizado como configuração exposta à Internet. É essencial implementar mecanismos de autenticação, autorização por utilizador, gestão de cotas e lista de permissões para adaptadores antes de ativar essa funcionalidade.
Defina uma porta de compatibilidade
Antes de um adaptador ser incluído no catálogo, verifique, no mínimo:
- modelo de base e revisão declarados
- compatibilidade entre tokenizador e modelos de chat
- módulos de classificação LoRA e módulos-alvo suportados pelo runtime
- formato dos artefatos e formas dos tensores
- licença, proveniência e resumo de integridade
- um pequeno conjunto de testes comportamentais e de regressão
Rejeite os artefatos incompatíveis durante o registo, em vez de o fazer na primeira solicitação do utilizador.
Compreenda a residência antes de implementar
O modelo base consome a maior parte fixa da memória destinada a GPU. Os pesos dos adaptadores, KV cache, o espaço de trabalho em lote e os kernels runtime competem pelo restante. A RAM CPU consegue armazenar os adaptadores offloadados, enquanto /data armazena os artefatos baixados.
Estes não são níveis intercambiáveis. Um artefato de disco ou Hub deve ser lido e materializado antes de se tornar um adaptador residente CPU- ou GPU-. É necessário medir as transições separadamente:
| Caminho | O que está incluído | |
|---|---|---|
| GPU número de ocorrências | Adaptador já residente | tempo de fila e tempo até ao primeiro token |
| CPU número de ocorrências | Transferência ou rematerialização para GPU | atraso de carregamento do adaptador e latência de ponta a ponta |
| Artefacto atingido | Ler a partir de local /data cache | atraso de leitura/carregamento e bytes em cache |
| Falha remota | Download, validação e carregamento | tempo de transferência, falhas e latência total em estado frio |
O planeamento de capacidade deve replicar a distribuição real de popularidade dos adaptadores. IDs de adaptador aleatórios e uniformes criam um problema de cache diferente em comparação com uma carga de trabalho de inquilinos semelhante ao modelo de Zipf.
Implante o diagrama do repositório com cuidado
O repositório contém charts/lorax, portanto, o ponto de partida reutilizável é uma revisão do repositório fixada e um 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
Conforme analisado a 15 de julho de 2026, os valores predefinidos do gráfico merecem atenção:
- a tag de imagem é
latest /dataé umemptyDir, portanto, a substituição do agente descarta os artefatos baixados- As sondas de atividade e disponibilidade estão vazias
- O token Hugging Face é modelado como um valor de ambiente literal
- Um GPU é solicitado por predefinição
Isso torna o gráfico um suporte útil, e não uma política de produção.
Comece a partir da estrutura de valores real do gráfico
O gráfico insere a configuração runtime como subelemento deploymentE os argumentos do lançador são uma lista de pares nome/valor. Uma sobreposição mínima tem a seguinte aparência:
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
Os limites de tokens acima são valores iniciais de exemplo, e não recomendações de dimensionamento. Determine-os com base em prompts representativos, na concorrência esperada, na memória GPU e em testes de carga.
Corrija as lacunas de forma explícita
O modelo atual do gráfico tem os valores codificados de forma fixa emptyDir volumes e valores de ambiente simples. Por isso, uma implementação reforçada requer um chart fork revisto, uma correção pós-geração ou uma camada de manifesto de nível superior para adicionar:
- um PersistentVolumeClaim ou cache de artefatos local no nó montado em
/data - uma referência secreta para as credenciais do Hub
- uma sondagem de inicialização antes de uma sondagem de atividade mais intensiva
- política de interrupção de pods e distribuição topológica para múltiplas réplicas
- NetworkPolicy, restrições de conta de serviço e um gateway autenticado
- fixação do hash da imagem e verificações de integridade dos artefatos
Não coloque um token Hub diretamente num ficheiro de valores já commitado. Não presuma que duas réplicas criem uma alta disponibilidade útil até que ambas consigam carregar o modelo base e o router consiga evitar o envio de todos os adaptadores “cold” para ambos os pods.
Rota para localidade de cache
O balanceamento round-robin pode transformar cada réplica num cache inativo. Um roteador útil associa, por meio de hashing ou outro mecanismo semelhante, um ID de adaptador autorizado a uma determinada réplica, mantendo ao mesmo tempo um caminho de failover caso essa réplica fique indisponível.
A chave de roteamento deve provir do estado autenticado da aplicação, e não de um parâmetro de URL pública arbitrário. Caso contrário, um utilizador pode forçar transferências remotas, esvaziar os caches ou sondar nomes de adaptadores privados.
LoRAX ou vLLM?
O vLLM atual consegue servir os módulos LoRA declarados no momento da inicialização e também pode carregá-los dinamicamente através de endpoints ou plugins de resolução. A sua própria documentação adverte que a atualização do adaptador runtime apresenta riscos de segurança e não deve ser utilizada em produção fora de um ambiente isolado e confiável.
A comparação útil é operacional e não numérica:
| Pergunta | LoRAX | vLLM |
|---|---|---|
| Como são descobertos os adaptadores de cauda longa? | O ID do adaptador consegue resolver Hugging Face, Predibase ou artefatos do sistema de ficheiros mediante solicitação. | Módulos estáticos, endpoints de gestão dinâmica ou plugins de resolução |
| Como é gerida a residência? | Agendamento explícito de troca de adaptadores entre GPU e CPU | Configurados os limites ativos e CPU LoRA, bem como o comportamento do resolvedor |
| O que é a interface de solicitação? | TGI-estilo /generate, cliente em Python e chat compatível com a OpenAI | serving compatível com a OpenAI e APIs nativo em Python |
| O que deve decidir? | Latência a frio/quente, rotatividade de cache, taxa de processamento em lote heterogéneo e adequação operacional | A mesma reprodução de carga de trabalho e critérios operacionais |
Evite regras do tipo “LoRAX para 1.000 adaptadores, vLLM para dez”. O tamanho do catálogo, por si só, não determina o desempenho. Benchmark, tanto quando se utiliza a mesma base, adaptadores, prompts, classificações, trilhas de chegada e hardware.
Um teste de aceitação em produção
Antes de expandir o catálogo, execute uma reprodução que inclua:
- Um conjunto fixo de dispositivos para estabelecer um throughput e uma latência estáveis.
- Uma distribuição de cauda longa para medir CPU e o número de consultas ao cache de artefatos que são bem-sucedidas.
- Um surto de adaptadores anteriormente não vistos, mas que se encontram na lista de permissões.
- Substituição de pods para avaliar a recuperação tanto da infraestrutura básica quanto dos adaptadores.
- Um adaptador indisponível ou corrompido, com o objetivo de verificar mecanismos de isolamento e fallback.
- Inquilinos concorrentes para testar os processos de autenticação, as cotas de uso e as etiquetas das métricas.
Acompanhe a taxa de solicitações, o tempo de espera na fila, o tempo até o primeiro token, a latência entre tokens, a latência total, o tempo de carregamento do adaptador, a categoria de acerto no cache, a memória GPU e CPU, os bytes baixados, bem como as falhas por motivo. Evite incluir os IDs dos adaptadores nos rótulos das métricas ilimitadas; em vez disso, associe-os a dimensões controladas ou a trilhas amostradas.
Defina os limiares de aceitação antes do teste. Exemplos incluem uma taxa máxima de erro no caminho frio, um alvo P99 para o estado quente, um alvo de acerto no cache para a distribuição de popularidade observada, e um objetivo de tempo de recuperação após a perda de um pod.
Conclusão
LoRAX transforma muitos ajustes finos compatíveis, provenientes de um conjunto de cópias de modelos base, num problema de alocação de adaptadores. Essa abordagem pode ser eficaz para cargas de trabalho de “cauda longa”, mas, por definição, não garante que os custos ou o tempo de resposta se mantenham constantes. O conjunto de dados em uso, o caminho de troca, a mistura de lotes e a camada de armazenamento continuam a determinar o resultado final.
Teste primeiro essas mecânicas num GPU. Depois, aborde o Kubernetes com seriedade: fixe os artefatos, mantenha o cache, proteja as credenciais, autorize os adaptadores, direcione o tráfego de acordo com a localização e meça cada caminho de residência. Se o LoRAX superar uma configuração atual de vLLM nas mesmas condições de reprodução, a decisão de implementação terá evidências concretas para sustentá-la.
Referências
- repositório LoRAX e README — funcionalidades suportadas, requisitos, APIs, e o chart Helm
- Valores do gráfico LoRAX e Modelo de implementação — valores padrão atuais e comportamento de volume vLLM LoRA adaptadores — adaptador estático e dinâmico serving
- LoRA artigo científico — método de adaptação de baixo rank documentação de Hugging Face e PEFT — adaptadores de formatos e integração com o processo de treino