LoRAX Serving Guide: LoRA-Adapter auf Kubernetes im großen Maßstab

Automatische Übersetzung Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.

Ein Base Model und viele LoRA-Adapter erzeugen ein ungewöhnliches Serving-Problem. Die Base Weights werden gemeinsam genutzt, aber jede Anfrage kann einen anderen Satz von Adapter Weights benötigen. Ein konventionelles Design mit einer Deployment-Instanz pro Variante verschwendet GPU-Speicher, wenn die meisten Varianten inaktiv sind.

LoRAX adressiert diesen Long Tail. Es lädt Adapter on demand, bündelt Requests für verschiedene Adapter in Batches und verschiebt Adapter Weights zwischen GPU- und CPU-Speicher. Die attraktive Kurzfassung lautet: „Tausende Fine-Tuned Models auf einer GPU.“ Die eigentliche Engineering-Frage ist enger gefasst: Hilft Exchange Scheduling bei deinem aktiven Adapter-Set, deinem Arrival Pattern und deinem Latency Target genug, um eine zusätzliche Serving Runtime zu rechtfertigen?

Dieser Guide richtet sich an Inference- und Platform-Engineers, die viele LoRA-Varianten aus einem Base Model serven müssen. Er zeigt, wie sich die dokumentierten APIs testen, der Working Set dimensionieren und das Starter-Helm-Chart in einen expliziten Production Plan überführen lässt.

Zusammenfassung. Wähle LoRAX, wenn viele kompatible LoRA-Adapter ein Base Model gemeinsam nutzen und der Traffic dünn oder Long-Tailed ist. Die Kapazität hängt vom aktiven Working Set ab, nicht von der Größe des Katalogs. Pinne die Runtime, authentifiziere und allowliste Adapter-IDs, ergänze dauerhaftes Artifact Caching und Probes, route für Cache Locality und miss Cold- und Warm-Pfade separat.


Das Serving-Problem ist der Working Set

LoRA friert ein Base Model ein und lernt Low-Rank-Updates für ausgewählte Weight Matrices. Der resultierende Adapter ist normalerweise deutlich kleiner als ein vollständiger Checkpoint, aber seine Größe hängt weiterhin von Rank, Target Modules, Layer-Anzahl und Dtype ab. Feste Aussagen wie „jeder Adapter ist 100 MB groß“ sind daher schlechte Inputs für die Kapazitätsplanung.

Für das Serving solltest du drei Größen unterscheiden:

  • Kataloggröße: Jeder Adapter, den eine Platform aus dem Storage auflösen kann
  • Aktiver Working Set: Adapter, die innerhalb des Cache-Retention-Fensters Requests erhalten
  • Concurrent Set: Adapter, die im selben Moment in Batches vertreten sind

Ein Katalog kann Tausende Adapter enthalten, ohne dass Tausende in den VRAM passen. Entscheidend ist, wie häufig sich der aktive Set ändert, wie groß diese Adapter sind und ob Requests für verschiedene Adapter nützliche gemeinsame Batches bilden können.

LoRAX kombiniert vier Mechanismen:

  1. Das Base Model bleibt für alle kompatiblen Adapter resident.
  2. Ein Request benennt einen Adapter, der aus Hugging Face, Predibase oder einem Filesystem aufgelöst werden kann.
  3. Adapter Exchange Scheduling lädt Weights vor und lagert sie zwischen GPU- und CPU-Speicher aus.
  4. Heterogeneous Continuous Batching gruppiert Requests, die auf unterschiedliche Adapter zielen.

Gehärteter LoRAX-Deployment-Pfad: Ein externer Gateway autorisiert Adapter-IDs, bevor LoRAX sie auflöst und servtGehärteter LoRAX-Deployment-Pfad: Ein externer Gateway autorisiert Adapter-IDs, bevor LoRAX sie auflöst und servt

Das LoRAX-Projekt berichtet, dass Heterogeneous Batching in seinen Benchmarks Throughput und Latency nahezu konstant hält, wenn die Zahl gleichzeitig verwendeter Adapter steigt. Behandle dieses Vendor-Ergebnis als Hypothese für deinen Workload. Prompt-Länge, Output-Länge, Rank, Target Modules, Batch Occupancy, Cache Churn und GPU-Generation können das Ergebnis verändern.

Das wiederhergestellte Diagramm stammt aus Predibase’ LoRAX-Launch-Report vom November 2023. Predibase benchmarkte Llama 2 7B mit Queries, die auf 1 bis 128 Adapter verteilt waren, auf einer NVIDIA A10G. Dieses Diagramm zeigt den Kostenvergleich für 1 bis 32 Adapter bei der Verarbeitung von einer Million Tokens, gleichmäßig auf die Adapter verteilt.

Archivierter Predibase-Vergleich der Kosten pro Million Tokens für LoRAX, dedizierte Deployments und Fine-Tuned GPT-3.5 Turbo bei einem Anstieg der Model-Anzahl von 1 auf 32

Archivierter Projektvergleich, reproduziert aus Predibase’ LoRAX-Report von 2023. Die Kosten für LoRAX und dedizierte Deployments basieren auf den GPU-Stunden aus diesem Experiment. Auf dem Detaillierungsniveau der Quelle verwendet die Linie für GPT-3.5 Turbo die Kosten pro Token des Fine-Tuned Models.

Interpretiere die flachen orangefarbenen Balken als Ergebnis dieses Benchmark-Designs, nicht als aktuelles Preisversprechen. Der Test verarbeitete insgesamt eine feste Menge von einer Million Tokens und ließ verschiedene Adapter einen Batch gemeinsam nutzen. Die dedizierte Baseline ging von separatem gehostetem Compute für jedes Model aus, weshalb ihre Kosten mit der Zahl der Models stiegen.

Predibase legte folgende Benchmark-Inputs nicht offen:

  • Verhältnis von Prompt- zu Output-Tokens
  • Request-Längen
  • Batch-Größe
  • Adapter-Rank
  • Preis pro GPU-Stunde
  • exaktes Utilization Model der dedizierten Deployments
  • exakte historischen Input- und Output-Preise für GPT-3.5

Daher enthält der Report nicht genügend Informationen, um die dargestellten Dollarwerte unabhängig zu reproduzieren.

Das Diagramm berücksichtigt außerdem weder sparsamen Traffic, Cold Downloads, aktuelle Cloud-Preise, neuere GPUs, andere Base Models noch Adapter mit anderen Ranks. Es unterstützt die Argumentation für Workload Replay. Es kann ein solches Replay nicht ersetzen.

Wann LoRAX eine plausible Wahl ist

LoRAX ist einen Benchmark wert, wenn alle folgenden Bedingungen erfüllt sind:

  • Die Adapter wurden gegen dasselbe unterstützte Base Model und denselben Tokenizer-Vertrag trainiert.
  • Der Traffic verteilt sich auf viele Adapter und weist einen relevanten Long Tail auf.
  • Das bedarfsgesteuerte Laden eines Cold Adapters ist besser, als für ihn ein eigenes Deployment zu reservieren.
  • Tenant- oder Task-Routing existiert bereits an der Application Boundary.
  • Das Team kann eine spezialisierte Inference Runtime und ihr Cache-Verhalten betreiben.

Typische Fälle sind Tenant-spezifische Assistenten, viele Domain-Varianten und Online-Experimente, die einen Base Checkpoint gemeinsam nutzen.

LoRAX passt schlechter, wenn wenige Adapter den Großteil des Traffics erhalten oder die Models kein Base Model gemeinsam nutzen. Ebenso ist es weniger geeignet, wenn harte Latency Targets keine Cold Loads tolerieren oder die Platform nicht sicher kontrollieren kann, welche Artefakte der Server lädt. In solchen Fällen kann ein standardmäßiges vLLM- oder TGI-Deployment mit einem festen Adapter-Set einfacher sein.

Setze Kubernetes nicht allein deshalb ein, weil der Katalog groß ist. Beweise zuerst Runtime- und Adapter-Kompatibilität auf einer GPU.


Ein Base Model und einen Adapter lokal testen

Die LoRAX-README empfiehlt den vorgefertigten Container. Verwende in einer realen Umgebung einen unveränderlichen Image Digest. main wird hier nur verwendet, weil es sich um den dokumentierten Quick-Start-Tag des Repositorys handelt. Diese Beispiele dienen der Illustration und wurden in diesem Checkout nicht lokal verifiziert. Prüfe sie gegen die Image- und Dependency-Versionen, die du deployest.

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

Die dokumentierten Mindestanforderungen sind Linux, Docker, eine NVIDIA GPU der Ampere-Generation oder neuer sowie CUDA-11.8-kompatible Treiber. Für Model-Lizenzen und gated Repositories kann außerdem ein Hugging-Face-Token erforderlich sein.

Starte mit dem 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}
    }'

Sende anschließend einen kompatiblen 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"
      }
    }'

Der erste Request lädt und lädt den Adapter möglicherweise. Spätere Requests können gecachte Artefakte und residente Weights verwenden. Erfasse beide Pfade. Ein einzelner Warm Request sagt wenig über das Verhalten eines Long Tails aus.

Einen OpenAI-kompatiblen Client verwenden

LoRAX stellt einen OpenAI-kompatiblen Chat-Endpunkt bereit. Das Feld model identifiziert den 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)

Der Server benötigt standardmäßig keinen API-Key. Für localhost ist das praktisch, als Internet-facing-Konfiguration jedoch unsicher. Schalte Authentication, Tenant Authorization, Quotas und Adapter Allowlisting davor.

Einen Compatibility Gate definieren

Bevor ein Adapter in den Katalog aufgenommen wird, solltest du mindestens Folgendes prüfen:

  • deklariertes Base Model und Revision
  • Kompatibilität von Tokenizer und Chat Template
  • vom Runtime unterstützter LoRA-Rank und unterstützte Target Modules
  • Artefaktformat und Tensor Shapes
  • Lizenz, Provenance und Integrity Digest
  • eine kleine Suite aus Behavioral- und Regression-Tests

Lehne inkompatible Artefakte bei der Registrierung ab, statt erst beim ersten Request eines Users.


Residency vor dem Deployment verstehen

Adapter-Artefaktspeicher und Runtime-Residency in LoRAXAdapter-Artefaktspeicher und Runtime-Residency in LoRAX

Das Base Model beansprucht den größten festen Anteil des GPU-Speichers. Adapter Weights, KV cache, Batch Workspace und Runtime-Kernels konkurrieren um den verbleibenden Speicher. Der CPU-RAM kann ausgelagerte Adapter aufnehmen, während /data heruntergeladene Artefakte speichert.

Diese Ebenen sind nicht austauschbar. Ein Disk- oder Hub-Artefakt muss gelesen und materialisiert werden, bevor es zu einem im CPU- oder GPU-Speicher residenten Adapter wird. Miss die Übergänge separat:

PfadEnthalten istZu erfassende Metrik
GPU HitAdapter ist bereits residentQueue Time und Time to First Token
CPU HitTransfer oder Rematerialisierung in die GPUAdapter-Load-Delay und End-to-End-Latency
Artifact HitLesen aus lokalem /data-CacheRead-/Load-Delay und Cache-Bytes
Remote MissDownload plus Validierung und LadenDownload-Zeit, Fehler und vollständige Cold-Latency

Die Kapazitätsplanung sollte die reale Adapter-Popularity-Distribution wiedergeben. Gleichverteilte zufällige Adapter-IDs erzeugen ein anderes Cache-Problem als ein Zipf-artiger Tenant-Workload.


Das Repository-Chart sorgfältig deployen

Das Repository enthält charts/lorax. Der reproduzierbare Ausgangspunkt ist daher eine gepinnte Repository-Revision und ein lokales 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

Zum Stand der Prüfung am 15. Juli 2026 zeigen die Chart Values und das Deployment Template einige Defaults, die Aufmerksamkeit verdienen:

  • Der Image-Tag ist latest.
  • /data ist ein emptyDir, daher gehen heruntergeladene Artefakte beim Ersetzen eines Pods verloren.
  • Liveness- und Readiness-Probes sind leer.
  • Der Hugging-Face-Token wird als Literal-Environment-Value modelliert.
  • Standardmäßig wird eine GPU angefordert.

Das Chart ist ein nützliches Scaffolding. Es ist keine Production Policy.

Mit der tatsächlichen Value-Struktur des Charts beginnen

Das Chart verschachtelt die Runtime-Konfiguration unter deployment; Launcher-Argumente sind eine Liste aus Name-Value-Paaren. Ein minimales Overlay sieht so aus:

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

Die oben genannten Token-Limits sind beispielhafte Startwerte und keine Sizing-Empfehlungen. Leite sie aus repräsentativen Prompts, erwarteter Concurrency, GPU-Speicher und Load Tests ab.

Die Lücken explizit schließen

Das aktuelle Chart Template reicht deployment.env über toYaml weiter. Ein normales Values-Overlay kann daher wie oben valueFrom.secretKeyRef für Hub-Credentials verwenden. Es hardcodiert die emptyDir-Volumes, besitzt keinen startupProbe-Hook und formatiert das Image immer als repository:tag. Eine Values-Datei allein kann deshalb kein dauerhaftes /data, keine Startup Probe und kein Pinning des Image Digests bereitstellen. Verwende für diese Änderungen einen geprüften Chart Fork, einen Post-Render-Patch oder eine übergeordnete Manifest Layer. Diese Production Layer sollte enthalten:

  • eine PersistentVolumeClaim oder einen node-lokalen Artefakt-Cache, gemountet unter /data
  • eine Startup Probe vor einer aggressiven Liveness Probe
  • Pod Disruption Policy und Topology Spread für mehrere Replicas
  • NetworkPolicy, Einschränkungen für den Service Account und einen authentifizierten Gateway
  • Image-Digest-Pinning und Integritätsprüfungen für Artefakte

Lege einen Hub-Token niemals in einer committeten Values-Datei ab. Zwei Replicas bieten nur dann eine sinnvolle High Availability, wenn beide das Base Model laden können. Der Router muss außerdem vermeiden, jeden Cold Adapter an beide Pods zu senden.

Für Cache Locality routen

Round-Robin-Balancing kann jede Replica in einen Cold Cache verwandeln. Ein nützlicher Router ordnet eine erlaubte Adapter-ID per Hash oder einer anderen stabilen Regel einer Replica zu. Für den Fall, dass diese Replica nicht verfügbar ist, hält er einen Failover-Pfad bereit.

Der Routing-Key muss aus authentifiziertem Application State stammen, nicht aus einem beliebigen öffentlichen URL-Parameter. Andernfalls kann ein Caller Remote Downloads erzwingen, Caches churnen lassen oder private Adapter-Namen ausspähen.


LoRAX oder vLLM?

Die aktuelle vLLM-Dokumentation beschreibt LoRA-Module, die beim Startup deklariert werden, sowie dynamisches Laden über Endpoints oder Resolver Plugins. Sie warnt, dass Runtime Adapter Updating Sicherheitsrisiken birgt und außerhalb einer isolierten, vertrauenswürdigen Umgebung nicht in Production verwendet werden sollte.

Der sinnvolle Vergleich ist operativ, nicht numerisch:

FrageLoRAXvLLM
Wie werden Long-Tail-Adapter entdeckt?Die Adapter-ID kann Hugging-Face-, Predibase- oder Filesystem-Artefakte on request auflösenStatische Module, dynamische Management-Endpoints oder Resolver Plugins
Wie wird Residency verwaltet?Explizites Adapter Exchange Scheduling zwischen GPU und CPUKonfigurierte Active- und CPU-LoRA-Limits plus Resolver-Verhalten
Welche Request-Schnittstelle gibt es?TGI-artiges /generate, Python Client und OpenAI-kompatibler ChatOpenAI-kompatibles Serving und native Python APIs
Was sollte entscheiden?Cold-/Warm-Latency, Cache Churn, Heterogeneous-Batch-Throughput und operative EignungDasselbe Workload Replay und dieselben operativen Kriterien

Vermeide Regeln wie „LoRAX für 1.000 Adapter, vLLM für zehn“. Die Kataloggröße allein bestimmt die Performance nicht. Benchmarke beide mit demselben Base Model, denselben Adaptern, Prompts, Ranks, Arrival Trace und derselben Hardware.

Ein Production Acceptance Test

Bevor du den Katalog erweiterst, führe ein Replay durch, das Folgendes umfasst:

  1. Einen festen Hot Set, um Warm-Throughput und -Latency zu bestimmen.
  2. Eine Long-Tail-Distribution, um CPU- und Artifact-Cache-Hits zu messen.
  3. Einen Burst zuvor unbekannter, aber allowlisteter Adapter.
  4. Einen Pod-Ersatz, um die Wiederherstellung von Base Model und Adaptern zu messen.
  5. Einen nicht verfügbaren oder korrupten Adapter, um Isolation und Fallback zu verifizieren.
  6. Concurrent Tenants, um Authentication, Quotas und Metric Labels zu verifizieren.

Erfasse diese Metriken:

  • Request Rate
  • Queue Time
  • Time to First Token
  • Inter-Token-Latency
  • Total Latency
  • Adapter Load Time
  • Cache-Hit-Klasse
  • GPU-Speicher
  • CPU-Speicher
  • Download-Bytes
  • Fehler nach Ursache

Nimm Adapter-IDs nicht in unbounded Metric Labels auf. Bilde sie auf kontrollierte Dimensionen oder gesampelte Traces ab.

Definiere die Acceptance Thresholds vor dem Test. Lege eine maximale Error Rate für den Cold Path und ein Warm-P99-Target fest. Definiere außerdem ein Cache-Hit-Target für die beobachtete Popularitätsverteilung sowie ein Recovery-Time-Objective nach dem Verlust eines Pods.

Fazit

LoRAX verwandelt viele kompatible Fine-Tunes von einer Flotte aus Kopien des Base Models in ein Problem der Adapter-Platzierung. Für Long-Tail-Workloads kann das ein starkes Design sein, aber Kosten und Latency werden dadurch nicht automatisch konstant. Der aktive Working Set, der Exchange Path, der Batch Mix und die Storage Layer bestimmen weiterhin das Ergebnis.

Beweise diese Mechanismen zunächst auf einer GPU. Danach solltest du Kubernetes ernst nehmen: Pinne Artefakte, erhalte den Cache, schütze Credentials, autorisiere Adapter, route für Locality und miss jeden Residency Path. Wenn LoRAX eine aktuelle vLLM-Konfiguration unter demselben Replay schlägt, ist die Deployment-Entscheidung evidenzbasiert.

Referenzen