LoRAX Serving Guide: LoRA-adapters op Kubernetes op schaal

Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.

Eén base model en veel LoRA-adapters vormen een ongebruikelijk serving-probleem. De base weights worden gedeeld, maar voor elk request kan een andere set adapter weights nodig zijn. Een conventioneel ontwerp met één deployment per variant verspilt GPU-geheugen wanneer de meeste varianten inactief zijn.

LoRAX adresseert die long tail. Het laadt adapters on demand, batcht requests voor verschillende adapters en verplaatst adapter weights tussen GPU- en CPU-geheugen. De aantrekkelijke headline is “duizenden fine-tuned models op één GPU”. De technische vraag is specifieker: gegeven je actieve adapterset, arrival pattern en latencydoelstelling, levert exchange scheduling genoeg voordeel op om een extra serving runtime te rechtvaardigen?

Deze guide is bedoeld voor inference- en platform engineers die veel LoRA-varianten vanuit één base model moeten serven. Je leert hoe je de gedocumenteerde APIs test, de working set dimensioneert en de starter Helm-chart omzet in een expliciet production plan.

Samenvatting. Kies LoRAX wanneer veel compatibele LoRA-adapters één base model delen en het verkeer schaars of long-tailed is. De capaciteit hangt af van de actieve working set, niet van de catalogusgrootte. Pin de runtime, authenticatie en allowlist adapter-ID’s, voeg durable artifact caching en probes toe, routeer voor cache-locality en benchmark cold en warm paths afzonderlijk.


Het serving-probleem is de working set

LoRA bevriest een base model en leert low-rank updates voor geselecteerde weight matrices. De resulterende adapter is doorgaans veel kleiner dan een volledig checkpoint, maar de omvang hangt nog steeds af van rank, target modules, het aantal layers en dtype. Vaste claims zoals “elke adapter is 100 MB” zijn slechte inputs voor capacity planning.

Maak voor serving onderscheid tussen drie grootheden:

  • Catalogusgrootte: elke adapter die een platform uit storage kan resolven
  • Actieve working set: adapters die binnen het cache-retention window requests ontvangen
  • Concurrent set: adapters die op hetzelfde moment in batches vertegenwoordigd zijn

Een catalogus kan duizenden adapters bevatten zonder dat er duizenden in VRAM passen. Bepalend is hoe vaak de actieve set verandert, hoe groot die adapters zijn en of requests voor verschillende adapters nuttige batches kunnen delen.

LoRAX combineert vier mechanismen:

  1. Het base model blijft resident voor alle compatibele adapters.
  2. Een request noemt een adapter, die kan worden geresolved vanuit Hugging Face, Predibase of een filesystem.
  3. Adapter exchange scheduling prefetchte en offloadt weights tussen GPU- en CPU-geheugen.
  4. Heterogeneous continuous batching groepeert requests die op verschillende adapters zijn gericht.

Hardened LoRAX deployment path, waarbij een externe gateway adapter-ID's autoriseert voordat LoRAX ze resolveert en serveertHardened LoRAX deployment path, waarbij een externe gateway adapter-ID's autoriseert voordat LoRAX ze resolveert en serveert

Het LoRAX-project rapporteert dat heterogeneous batching throughput en latency in zijn benchmarks vrijwel constant houdt wanneer het aantal concurrent adapters toeneemt. Behandel dat resultaat van de vendor als hypothese voor jouw workload. Promptlengte, outputlengte, rank, target modules, batch occupancy, cache churn en GPU-generatie kunnen het resultaat veranderen.

De herstelde chart hieronder is afkomstig uit Predibase’s LoRAX launch report van november 2023. Predibase benchmarkte Llama 2 7B met queries verdeeld over 1 tot 128 adapters op één NVIDIA A10G. Deze chart toont de kostenvergelijking voor 1 tot 32 adapters bij het verwerken van één miljoen tokens, gelijkmatig verdeeld over de adapters.

Gearchiveerde vergelijking van Predibase tussen LoRAX, dedicated deployments en de kosten per miljoen tokens van fine-tuned GPT-3.5 Turbo naarmate het aantal models groeit van 1 naar 32

Gearchiveerde projectvergelijking, gereproduceerd uit Predibase’s LoRAX-rapport uit 2023. De kosten voor LoRAX en dedicated deployments gebruiken GPU-uren uit dat experiment. Op het detailniveau van de bron gebruikt de lijn voor GPT-3.5 Turbo de kosten per token van het fine-tuned model.

Lees de vlakke oranje balken als een resultaat van dit benchmarkontwerp, niet als een actuele prijsbelofte. De test verstuurde in totaal één miljoen tokens en liet verschillende adapters een batch delen. De dedicated baseline ging uit van afzonderlijke hosted compute voor elk model, waardoor de kosten toenamen met het aantal models.

Predibase maakte deze benchmarkinputs niet bekend:

  • prompt-to-output token mix
  • requestlengtes
  • batchgrootte
  • adapter rank
  • prijs per GPU-uur
  • exact utilization model voor dedicated deployments
  • exacte historische input- en outputprijzen van GPT-3.5

Daarom bevat het rapport onvoldoende informatie om de getoonde dollarwaarden onafhankelijk te reproduceren.

De chart behandelt ook geen sparse traffic, cold downloads, actuele cloudprijzen, nieuwere GPUs, andere base models of adapters met andere ranks. De chart ondersteunt de case voor workload replay. Hij kan die niet vervangen.

Wanneer LoRAX een plausibele keuze is

LoRAX verdient een benchmark wanneer al het volgende waar is:

  • adapters zijn getraind tegen hetzelfde ondersteunde base model en dezelfde tokenizer contract
  • het verkeer omvat veel adapters, met een betekenisvolle long tail
  • een cold adapter on demand laden de voorkeur heeft boven er een deployment voor reserveren
  • tenant- of task-routing al bestaat aan de application boundary
  • het team een gespecialiseerde inference runtime en het cachegedrag daarvan kan beheren

Typische gevallen zijn tenant-specifieke assistants, veel domainvarianten en online experimenten die een checkpoint delen.

LoRAX past minder goed wanneer enkele adapters het grootste deel van het verkeer verwerken of wanneer de models geen base delen. Het past ook minder goed wanneer harde latencydoelstellingen geen cold loads tolereren of wanneer het platform niet veilig kan controleren welke artifacts de server laadt. Een standaard vLLM- of TGI-deployment met een vaste adapterset kan in die gevallen eenvoudiger zijn.

Gebruik Kubernetes niet alleen omdat de catalogus groot is. Bewijs eerst de runtime en adaptercompatibiliteit op één GPU.


Probeer lokaal één base en één adapter

De LoRAX README beveelt de prebuilt container aan. Gebruik in een echte omgeving een immutable image digest. main wordt hier alleen getoond omdat dit de gedocumenteerde quick-start tag van de repository is. Deze voorbeelden zijn illustratief en niet lokaal geverifieerd in deze checkout. Controleer ze tegen de image- en dependencyversies die je implementeert.

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

Het gedocumenteerde minimum bestaat uit Linux, Docker, een Ampere-of-nieuwere NVIDIA GPU en drivers die compatibel zijn met CUDA 11.8. Voor model licenses en gated repositories kan ook een Hugging Face-token nodig zijn.

Begin met het base model:

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}
    }'

Stuur daarna een compatibele adapter:

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"
      }
    }'

Het eerste request kan de adapter downloaden en laden. Latere requests kunnen gecachte artifacts en resident weights gebruiken. Leg beide paths vast. Eén warm request zegt weinig over long-tailgedrag.

Gebruik een OpenAI-compatible client

LoRAX stelt een OpenAI-compatible chat endpoint beschikbaar. Het veld model identificeert de adapter:

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)

De server vereist standaard geen API-key. Dat is handig voor localhost en onveilig voor een configuratie die aan het Internet wordt blootgesteld. Plaats authenticatie, tenant-authorisatie, quotas en adapter-allowlisting ervoor.

Definieer een compatibility gate

Controleer minimaal het volgende voordat een adapter in de catalogus komt:

  • gedeclareerd base model en revision
  • compatibiliteit van tokenizer en chat-template
  • LoRA rank en target modules die door de runtime worden ondersteund
  • artifactformaat en tensor shapes
  • license, provenance en integrity digest
  • een kleine suite met behavioral en regression tests

Reject incompatibele artifacts tijdens registratie in plaats van bij het eerste request van een gebruiker.


Begrijp residency voordat je implementeert

Opslag van adapter artifacts en runtime residency in LoRAXOpslag van adapter artifacts en runtime residency in LoRAX

Het base model gebruikt het grootste vaste deel van het GPU-geheugen. Adapter weights, KV cache, batch workspace en runtime kernels concurreren om de rest. CPU RAM kan offloaded adapters bevatten, terwijl /data gedownloade artifacts opslaat.

Dit zijn geen uitwisselbare tiers. Een disk- of Hub-artifact moet eerst worden gelezen en gematerialiseerd voordat het een CPU- of GPU-resident adapter wordt. Meet de transities afzonderlijk:

PathWat het bevatTe registreren metric
GPU hitAdapter is al residentqueue time en time to first token
CPU hitTransfer of rematerialization naar GPUadapter-load delay en end-to-end latency
Artifact hitLezen uit lokale /data cacheread/load delay en cache bytes
Remote missDownload plus validatie en loaddownloadtijd, failures en volledige cold latency

Capacity planning moet de echte adapter-popularity distribution replayen. Uniform random adapter-ID’s creëren een ander cacheprobleem dan een Zipf-like tenant workload.


Implementeer de repository-chart zorgvuldig

De repository bevat charts/lorax, dus een reproduceerbaar startpunt is een gepinde repository revision en een lokale chart:

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

Zoals beoordeeld op 15 juli 2026 tonen de chart values en het Deployment template defaults die aandacht verdienen:

  • de image tag is latest
  • /data is een emptyDir, waardoor pod replacement gedownloade artifacts verwijdert
  • liveness- en readiness-probes zijn leeg
  • het Hugging Face-token is gemodelleerd als een letterlijke environment value
  • standaard wordt één GPU aangevraagd

De chart is bruikbare scaffolding. Het is geen production policy.

Begin met de daadwerkelijke value-structuur van de chart

De chart nest runtimeconfiguratie onder deployment, en launcher arguments zijn een lijst met name/value pairs. Een minimale overlay ziet er zo uit:

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

De bovenstaande tokenlimieten zijn voorbeeldwaarden om mee te starten, geen sizing recommendations. Leid ze af uit representatieve prompts, verwachte concurrency, GPU-geheugen en load tests.

Patch de tekortkomingen expliciet

Het huidige chart-template geeft deployment.env door via toYaml, waardoor een normale values overlay valueFrom.secretKeyRef kan gebruiken voor Hub-credentials, zoals hierboven. Het template hard-codeert de emptyDir-volumes, heeft geen startupProbe-hook en formatteert de image altijd als repository:tag. Een values file alleen kan daarom geen durable /data, startup probe of image-digest pinning leveren; gebruik voor die wijzigingen een gereviewde chart fork, post-render patch of higher-level manifest layer. Neem in die production layer het volgende op:

  • een PersistentVolumeClaim of node-local artifact cache, gemount op /data
  • een startup probe vóór een agressieve liveness-probe
  • pod disruption policy en topology spread voor meerdere replicas
  • NetworkPolicy, service-accountrestricties en een geauthenticeerde gateway
  • image-digest pinning en artifact-integritychecks

Plaats een Hub-token niet rechtstreeks in een gecommitte values file. Twee replicas bieden alleen nuttige high availability als beide het base model kunnen laden. De router moet bovendien voorkomen dat elke cold adapter naar beide pods wordt gestuurd.

Routeer voor cache-locality

Round-robin balancing kan van elke replica een cold cache maken. Een bruikbare router koppelt een toegestane adapter-ID via hash of een andere stabiele regel aan één replica. Houd een failover path aan voor momenten waarop die replica niet beschikbaar is.

De routing key moet afkomstig zijn uit geauthenticeerde application state, niet uit een willekeurige publieke URL-parameter. Anders kan een caller remote downloads forceren, caches churnen of private adapternamen aftasten.


LoRAX of vLLM?

Huidige vLLM-documentatie beschrijft LoRA-modules die bij startup worden gedeclareerd en dynamic loading via endpoints of resolver plugins. De documentatie waarschuwt dat runtime adapter updating securityrisico’s heeft en niet in production moet worden gebruikt buiten een geïsoleerde, vertrouwde omgeving.

De nuttige vergelijking is operationeel, niet numeriek:

VraagLoRAXvLLM
Hoe worden long-tail adapters ontdekt?Adapter-ID kan on request Hugging Face-, Predibase- of filesystem-artifacts resolvenStatische modules, dynamic management endpoints of resolver plugins
Hoe wordt residency beheerd?Expliciete adapter exchange scheduling tussen GPU en CPUGeconfigureerde active en CPU LoRA-limits plus resolvergedrag
Wat is de requestinterface?TGI-style /generate, Python client en OpenAI-compatible chatOpenAI-compatible serving en native Python APIs
Wat moet de beslissing bepalen?Cold/warm latency, cache churn, heterogeneous-batch-throughput en operational fitDezelfde workload replay en operationele criteria

Vermijd regels zoals “LoRAX voor 1.000 adapters, vLLM voor tien”. De catalogusgrootte bepaalt de performance niet alleen. Benchmark beide met dezelfde base, adapters, prompts, ranks, arrival trace en hardware.

Een production acceptance test

Voer voordat je de catalogus uitbreidt een replay uit met:

  1. Een vaste hot set om warm throughput en latency vast te stellen.
  2. Een long-tail distribution om CPU- en artifact-cache-hits te meten.
  3. Een burst met eerder ongeziene maar toegestane adapters.
  4. Pod replacement om base- en adapter recovery te meten.
  5. Eén onbeschikbare of corrupte adapter om isolation en fallback te verifiëren.
  6. Concurrent tenants om authenticatie, quotas en metric labels te controleren.

Monitor deze metrics:

  • request rate
  • queue time
  • time to first token
  • inter-token latency
  • total latency
  • adapter load time
  • cache-hit class
  • GPU memory
  • CPU memory
  • download bytes
  • failures per reason

Zet adapter-ID’s niet in unbounded metric labels. Map ze naar gecontroleerde dimensions of sampled traces.

Definieer de acceptance thresholds vóór de test. Stel een maximale error rate voor het cold path en een warm P99-doel vast. Stel ook een cache-hit target vast voor de waargenomen popularity distribution en een recovery-time objective na verlies van een pod.

Conclusie

LoRAX verandert veel compatibele fine-tunes van een fleet met kopieën van het base model in een adapter-placementprobleem. Dat kan een sterk ontwerp zijn voor long-tail workloads, maar het maakt kosten of latency niet per definitie vlak. De actieve working set, exchange path, batch mix en storage layer bepalen het resultaat nog steeds.

Bewijs die mechanismen eerst op één GPU. Neem Kubernetes daarna serieus: pin artifacts, behoud de cache, bescherm credentials, autoriseer adapters, routeer voor locality en meet elk residency path. Als LoRAX een actuele vLLM-configuratie verslaat onder dezelfde replay, is de deploymentbeslissing met bewijs onderbouwd.

Referenties