KI-Systemarchitektur
Sie haben eine große Modelldemo auf Ihrem Laptop ausgeführt und sie funktioniert gut, aber wenn Sie daraus ein echtes Produkt machen wollen, tauchen Probleme auf:
Das Modell hat zu viele Parameter, um auf eine einzelne GPU zu passen. Was tun Sie?
-
Das Training dauert Wochen; wie nehmen Sie das Training von einem Checkpoint aus wieder auf, wenn mitten drin ein Fehler auftritt?
-
Wie garantieren Sie bei Millionen von Nutzeranfragen pro Tag eine Latenz unter 1 Sekunde?
-
Wie sammeln Sie Nutzerfeedback, damit sich das Modell kontinuierlich weiterentwickeln kann?
Das sind die Probleme, die eine KI-Systemarchitektur lösen muss.
Eine Demo konzentriert sich darauf, ob sie laufen kann; ein Produktionssystem konzentriert sich darauf, ob es stabil, effizient und zu geringen Kosten laufen kann.
Merkmale von KI-Systemen in Produktionsqualität: 7x24-Verfügbarkeit, Unterstützung für Millionen gleichzeitiger Anfragen, Beobachtbarkeit, Skalierbarkeit, zuverlässige Notfallwiederherstellung und kontrollierbare Kosten.
Besondere Herausforderungen von KI-Systemen
Im Vergleich zu herkömmlichen Webdiensten haben KI-Systeme drei einzigartige Herausforderungen.
Herausforderung 1: Unsichere Ausgabe
Die Ausgabe herkömmlicher Systeme ist deterministisch – man gibt 1+1 ein und es liefert immer 2 zurück.
Die Ausgabe von KI-Systemen ist probabilistisch – derselbe Prompt kann jedes Mal unterschiedliche Ergebnisse erzeugen.
Dies bringt mehrere Probleme mit sich: Wie garantiert man die Ausgabequalität? Wie bewertet man Ergebnisse? Wie geht man mit Halluzinationen um?
Typische Lösungen: Hinzufügen von Sampling-Strategien auf der Ausgabeschicht, Nachbearbeitungsfilterung der Ergebnisse, ein geschlossener Kreislauf für menschliches Feedback und Multi-Modell-Abstimmung.
Herausforderung 2: Abwägung zwischen Latenz und Kosten
KI-Inferenz erfordert viel Rechenleistung, was bedeutet, dass ein natürlicher Widerspruch zwischen Latenz und Kosten besteht.
Wollen Sie Geschwindigkeit? Verwenden Sie mehr GPUs, die Kosten schnellen in die Höhe.
Wollen Sie Geld sparen? Stellen Sie sich in die Verarbeitungswarteschlange, schlechte Nutzererfahrung.
Der Kern eines Produktionssystems besteht darin, ein Gleichgewicht zwischen SLA (Service-Level-Agreement) und Kosten zu finden.
| Optimierungsrichtung | Gängige Techniken | Wirkung |
|---|---|---|
| Modellkomprimierung | Quantisierung, Pruning, Distillation | 2-4x Beschleunigung, geringer Genauigkeitsverlust |
| Inferenzoptimierung | vLLM、TensorRT、FlashAttention | 3-10x Durchsatzverbesserung |
| Architekturdesign | Batch-Verarbeitung, mehrstufiges Caching | Kosten pro Anfrage um 50%-80% reduziert |
Herausforderung 3: Aufbau des Daten-Schwungrads
Ein KI-System ist nach dem Start nicht „fertig“; es erfordert kontinuierliche Iteration.
Je mehr Benutzer es verwenden, desto mehr Feedback-Daten gibt es, desto besser kann das Modell trainiert werden und desto bereitwilliger nutzen die Benutzer es – das ist das Daten-Schwungrad.
Aber das Schwungrad in Gang zu bringen ist nicht einfach: Wie sammelt man effektives Feedback? Wie beschriftet man Daten? Wie trainiert man weiter? Wie bewertet man neue Versionen?
Auf diese Fragen gibt es keine Standardantworten, aber jedes erfolgreiche KI-Produkt hat sein eigenes Schwungrad-Design.
Groß angelegte Trainingsinfrastruktur
Das Training großer Modelle mit Hunderten von Milliarden oder sogar Billionen Parametern erfordert Supercomputing-Infrastruktur.
GPU-Cluster-Architektur
Moderne KI-Trainingscluster bestehen typischerweise aus Hunderten oder Tausenden von GPUs.
Am Beispiel der H100-GPU hat eine einzelne H100 80GB Speicher und eine Rechenleistung von 1979 TFLOPS bei FP8-Präzision.
Aber eine einzelne GPU reicht bei Weitem nicht aus – das Training von GPT-3 verwendete etwa 355 V100 und dauerte 3 Monate.
Eine typische Cluster-Topologie ist:
| Stufe | Gerät | Verbindungsmethode | Bandbreite |
|---|---|---|---|
| Innerhalb einer einzelnen Maschine | GPU-GPU | NVLink | 900GB/s |
| Dasselbe Rack | Server-zu-Server | InfiniBand | 400Gb/s |
| Rack-übergreifend | Switch-zu-Switch | InfiniBand Fabric | 400Gb/s |
Das Netzwerk ist der Flaschenhals für das verteilte Training. Wenn die Kommunikationsbandbreite nicht ausreicht, kann die GPU-Auslastung von 90% auf 30% sinken, wobei die meiste Zeit mit Warten auf Daten verbracht wird.
InfiniBand-Hochgeschwindigkeitsverbindung
Gewöhnliches Ethernet ist zu langsam; verteiltes Training verwendet InfiniBand.
Eigenschaften von InfiniBand: extrem niedrige Latenz (im Mikrosesekundenbereich), extrem hohe Bandbreite und Unterstützung für RDMA (Remote Direct Memory Access).
RDMA ermöglicht es einer GPU, direkt den Speicher der GPU eines anderen Servers zu lesen und zu schreiben, ohne den Betriebssystemkernel zu durchlaufen, was es viel schneller macht.
Speichersystem-Design
Trainingsdaten sind typischerweise im TB- oder sogar PB-Bereich, weshalb das Speichersystem ebenfalls sorgfältig entworfen werden muss.
Ein typisches mehrstufiges Speicherdesign:
- Hot data: SSD oder NVMe, speichert den aktuellen Trainings-Batch
- Warm data: verteilter Speicher (z.B. Ceph, Lustre), speichert den vollständigen Trainingsdatensatz
- Cold data: Objektspeicher (z.B. S3), speichert historische Daten und Backups
Fehlertoleranz und Checkpoints
Ein Trainingslauf dauert Wochen – was ist, wenn während dieser Zeit eine GPU ausfällt? Ganz von vorne zu beginnen ist zu verschwenderisch.
Die Lösung sindCheckpoints– das periodische Speichern des Modellzustands auf der Festplatte und die Wiederherstellung vom jüngsten Checkpoint, falls ein Fehler auftritt.
Aber Checkpoints haben auch Kosten: Einmaliges Speichern kann mehrere Minuten dauern und Dutzende GB Speicherplatz beanspruchen.
Die übliche Strategie ist: Alle paar hundert Schritte speichern, die neuesten Checkpoints behalten und alte automatisch bereinigen.
Strategien für verteiltes Training
Ein einzelnes Modell passt nicht auf eine einzelne GPU, daher muss die Trainingsaufgabe auf mehrere GPUs aufgeteilt werden.
Es gibt hauptsächlich drei Parallelisierungsstrategien: Datenparallelität, Tensorparallelität und Pipeline-Parallelität. Die Kombination aller drei ist die 3D-Parallelität.

Datenparallelität
Die einfachste und gängigste Strategie: Jede GPU hält eine vollständige Kopie des Modells, verarbeitet jedoch unterschiedliche Daten.
Zum Beispiel verarbeitet jede GPU bei 8 GPUs und einer Batch-Größe von 1024 jeweils 128 Stichproben.
Die Vorwärtsausbreitung erfolgt unabhängig, und nach der Rückwärtsausbreitung werden die Gradienten zusammengeführt und gemittelt, wonach das Modell aktualisiert wird.
Das Problem beim Datenparallelismus ist, dass der Speicher nach wie vor der Flaschenhals ist – wenn das Modell zu groß für eine einzelne GPU ist, nützt der Datenparallelismus nichts.
ZeRO-Speicheroptimierung
ZeRO (Zero Redundancy Optimizer) ist eine erweiterte Version des Datenparallelismus, die noch mehr Speicher spart.
Beim normalen Datenparallelismus speichert jede GPU die vollständigen Modellparameter, Gradienten und Optimizer-Zustände – das ist redundant.
Die Idee von ZeRO besteht darin, diese Zustände auf verschiedene GPUs aufzuteilen und bei Bedarf zu kommunizieren.
| ZeRO-Stufe | Was aufgeteilt wird | Speichereinsparungen |
|---|---|---|
| ZeRO-1 | Optimizer-Zustände | ~4x |
| ZeRO-2 | Optimizer-Zustände + Gradienten | ~8x |
| ZeRO-3 | Optimizer-Zustände + Gradienten + Parameter | Linear mit der Anzahl der GPUs |
Das Konfigurieren von ZeRO mit DeepSpeed ist einfach:
"train_batch_size": 1024,
"train_micro_batch_size_per_gpu": 16,
"optimizer": {
"type": "Adam",
"params": {
"lr": 0.0001,
"betas": [0.9, 0.95],
"eps": 1e-8,
"weight_decay": 0.01
}
},
"zero_optimization": {
"stage": 3,
"allgather_partitions": true,
"allgather_bucket_size": 2e8,
"overlap_comm": true,
"reduce_scatter": true,
"reduce_bucket_size": 2e8,
"contiguous_gradients": true,
"stage3_prefetch_bucket_size": 1e8,
"stage3_param_persistence_threshold": 1e5,
"stage3_max_live_parameters": 1e9,
"stage3_max_reuse_distance": 1e9
},
"gradient_clipping": 1.0,
"fp16": {
"enabled": true,
"loss_scale": 0,
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
"checkpoint": {
"tag": "example-checkpoint",
"load_universal": true
}
}
Diese Konfiguration verwendet ZeRO-3, wodurch Modellzustände über alle GPUs verteilt werden können, was den Speicherverbrauch linear mit der Anzahl der GPUs reduziert.
Tensor-Parallelismus
Wenn ZeRO immer noch nicht ausreicht, wird der Tensor-Parallelismus verwendet – die Berechnung einer Schicht wird auf mehrere GPUs aufgeteilt.
Matrixmultiplikationen in Transformern können nach Zeilen oder Spalten aufgeteilt werden:
- Matrix A zeilenweise in A₁ und A₂ aufteilen und A₁×B sowie A₂×B auf GPU 0 bzw. GPU 1 berechnen
- Schließlich die Ergebnisse verketten
Auf diese Weise erfordert jede Schicht Kommunikation, aber der GPU-Speicherverbrauch wird auch halbiert.
Megatron-LM ist NVIDIAs Bibliothek für Tensor-Parallelismus mit hervorragender Kompatibilität zu PyTorch.
Pipeline-Parallelismus
Tensor-Parallelismus ist „Aufteilung innerhalb einer Schicht“; Pipeline-Parallelismus ist „Aufteilung zwischen Schichten“.
Beispielsweise hält bei einem Modell mit 32 Schichten GPU 0 die ersten 8 Schichten, GPU 1 die nächsten 8 Schichten, GPU 2 die folgenden 8 Schichten und GPU 3 die letzten 8 Schichten.
Daten fließen von GPU 0 zu GPU 3, genau wie am Fließband in einer Fabrik.
Aber Pipelines haben ein Problem: Bubbles (Leerlaufzeiten) – wenn GPU 0 mit der Berechnung beginnt, sind die GPUs 1–3 im Leerlauf; wenn die Daten GPU 1 erreichen, wird GPU 0 wieder in den Leerlauf versetzt.
Die Lösung besteht darin, Daten in Mikro-Batches aufzuteilen und sie wie an einem Fließband einzuspeisen, um die Bubble-Zeit zu reduzieren.
3D-Parallelismus (DP+TP+PP)
Die drei Strategien können kombiniert werden:
- Pipeline-Parallelismus: Modellschichten über Nodes verteilen
- Tensor-Parallelismus: Intraschicht-Berechnungen innerhalb eines Nodes aufteilen
- Datenparallelismus: Die gesamte Pipeline in größerem Maßstab replizieren
Mit 64 GPUs können Sie beispielsweise wie folgt planen:
- 8 Pipeline-Stufen (PP=8)
- 2 GPUs für den Tensor-Parallelismus innerhalb jeder Stufe verwenden (TP=2)
- Dann für den Datenparallelismus 4-mal replizieren (DP=4)
- Gesamt: 8 × 2 × 4 = 64 GPUs
Dies ist der 3D-Parallelismus — die Standardkonfiguration für das Training moderner Großmodelle.
Daten-Engineering
Gute Modelle erfordern gute Daten – Data Engineering macht über 60 % der Arbeitslast in KI-Systemen aus.
Datenerfassungs- und Bereinigungspipeline
Trainingsdaten stammen meist aus mehreren Quellen: Webseiten, Büchern, Code, Unterhaltungen usw.
Typischer Verarbeitungsablauf:
- Deduplizierung: Doppelte oder hochgradig ähnliche Dokumente entfernen
- Qualitätsfilterung: Minderwertige, toxische oder voreingenommene Inhalte entfernen
- Formatvereinheitlichung: Verschiedene Quellen in ein einheitliches Format konvertieren
- Tokenisierung: Text in Modelleingabesequenzen konvertieren
Datendeduplizierung: MinHash LSH
Das direkte Berechnen der paarweisen Dokumentenähnlichkeit ist zu langsam; ein gängiger Ansatz ist MinHash + LSH (Locality-Sensitive Hashing).
Die Idee ist: Jedes Dokument in einen kurzen „Fingerabdruck“ umwandeln; ähnliche Dokumente haben wahrscheinlich identische oder ähnliche Fingerabdrücke, danach wird nach Fingerabdruck gruppiert.
Beispiel
import re
from typing import List, Set, Dict, Tuple
def generate_shingles(text: str, k: int = 5) -> Set[str]:
"""Generate k-shingles: sequences of k consecutive words For example "I love example tutorial", k=2 → {"I love", "love example", "example tutorial"} # Simple tokenization (a professional tokenization tool can be used in real scenarios) """
"""Generate MinHash signatures Use multiple hash functions, each taking the minimum value # Use i as the seed to generate different hash functions # Combine shingle and i to generate a hash value """
"""
"""LSH-Schlüssel mit der Banding-Methode generieren Signatur in mehrere Bands aufteilen, jedes Band separat hashen # Dieses Band hashen, um einen Schlüssel zu generieren """
words = re.findall(r'\w+', text.lower())
shingles = set()
for i in range(len(words) - k + 1):
shingle = ' '.join(words[i:i+k])
shingles.add(shingle)
return shingles
def minhash_signature(shingles: Set[str], num_hashes: int = 100) -> List[int]:
"""Dokumente mithilfe von MinHash + LSH deduplizieren Die deduplizierte Dokumentenliste zurückgeben # Speicher: LSH-Schlüssel → Liste von Dokumentindizes # Speicher: Dokumentindex → Signatur # Markierung: Welche Dokumente Duplikate sind # Prüfen, ob bereits ein ähnliches Dokument existiert # Dieses Bucket enthält bereits Dokumente, Signaturähnlichkeiten nacheinander vergleichen # Signaturähnlichkeit berechnen (Jaccard-Approximation) # Über dem Schwellenwert, wird als Duplikat betrachtet # Kein Duplikat, sich selbst zu allen Buckets hinzufügen """
Mehrere Hash-Funktionen verwenden, die jeweils den Minimalwert ermitteln
"""
signature = []
for i in range(num_hashes):
# i als Seed verwenden, um verschiedene Hash-Funktionen zu generieren
min_hash = None
for shingle in shingles:
# Shingle und i kombinieren, um einen Hash-Wert zu generieren
h = hashlib.sha256(f"{shingle}-{i}".encode()).hexdigest()
h_int = int(h, 16)
if min_hash is None or h_int < min_hash:
min_hash = h_int
signature.append(min_hash)
return signature
def lsh_banding(signature: List[int], bands: int = 20) -> List[str]:
"""Bucketing (Banding) verwenden, um LSH-Schlüssel zu generieren
Die Signatur in mehrere Bands aufteilen und jedes Band separat hashen.
"""
keys = []
rows_per_band = len(signature) // bands
for i in range(bands):
start = i * rows_per_band
end = start + rows_per_band
band = tuple(signature[start:end])
# Einen Schlüssel für diesen Band-Hash generieren
band_hash = hashlib.sha256(str(band).encode()).hexdigest()[:16]
keys.append(f"band-{i}-{band_hash}")
return keys
def deduplicate_documents(documents: List[str],
threshold: float = 0.7) -> List[str]:
"""MinHash + LSH verwenden, um Dokumente zu deduplizieren
Die deduplizierte Dokumentenliste zurückgeben
"""
# Speicher: LSH-Schlüssel → Dokumentindexliste
buckets: Dict[str, List[int]] = {}
# Speicher: Dokumentindex → Signatur
signatures: Dict[int, List[int]] = {}
# Markierung: Welche Dokumente Duplikate sind
duplicates: Set[int] = set()
for idx, doc in enumerate(documents):
shingles = generate_shingles(doc)
sig = minhash_signature(shingles)
signatures[idx] = sig
keys = lsh_banding(sig)
# Prüfen, ob bereits ähnliche Dokumente existieren
is_duplicate = False
for key in keys:
if key in buckets:
# Dieses Bucket enthält bereits Dokumente, Signaturähnlichkeiten nacheinander vergleichen
for other_idx in buckets[key]:
other_sig = signatures[other_idx]
# Signaturähnlichkeit berechnen (Jaccard-Approximation)
matches = sum(1 for a, b in zip(sig, other_sig) if a == b)
similarity = matches / len(sig)
if similarity >= threshold:
# Schwellenwert überschritten, wird als Duplikat betrachtet
is_duplicate = True
duplicates.add(idx)
break
if is_duplicate:
break
if not is_duplicate:
# Kein Duplikat; sich selbst zu jedem Bucket hinzufügen
for key in keys:
if key not in buckets:
buckets[key] = []
buckets[key].append(idx)
Python ist eine prägnante und elegante Sprache, die sich für Anfänger eignet.
return [doc for idx, doc in enumerate(documents) if idx not in duplicates]
# ============================================
Maschinelles Lernen befähigt Computer, Muster aus Daten zu lernen.
# ============================================
if __name__ == "__main__":
documents = [
Dies ist ein völlig anderer Artikel.,
"Willkommen zum Beispieltutorial, dies ist ein großartiger Ort, um Programmieren zu lernen.", # Äußerst ähnlich
"Python ist eine prägnante und elegante Sprache, die sich für Anfänger eignet.",
"Python ist eine prägnante und elegante Programmiersprache, die sich sehr gut für Anfänger eignet.", # Äußerst ähnlich
"Maschinelles Lernen befähigt Computer, Muster aus Daten zu lernen.",
"Dies ist ein völlig anderer Artikel.",
]
print(f"Vor der Deduplizierung: {len(documents)} Dokumente")
deduplicated = deduplicate_documents(documents, threshold=0.6)
print(f"Nach der Deduplizierung: {len(deduplicated)} Dokumente"\n")
print("Retained documents:")
for i, doc in enumerate(deduplicated):
print(f" [{i}] {doc}")
# Output:
# Before deduplication: 6 documents
# After deduplication: 4 documents
#
# Retained documents:
#
#
#
#
In der tatsächlichen Produktion werden effizientere Implementierungen (wie die Bibliothek datasketch) verwendet, aber die Kernidee ist dieselbe.
Datenformat: WebDataset
Kleine Datensätze können beliebig gespeichert werden, aber TB-große Datensätze erfordern ein dediziertes Format.
WebDataset ist ein gängiges Format: Es verpackt Dateien in tar-Archive, wobei jedes tar Tausende von Stichproben enthält, und unterstützt sowohl den wahlfreien als auch den sequenziellen Zugriff.
Die Vorteile sind:
- Reduziert den Druck auf das Dateisystem (Millionen kleiner Dateien sind langsam)
- Unterstützt Streaming-Lesevorgänge, kein Laden des gesamten Datensatzes in den Arbeitsspeicher erforderlich
- Kann verteilt geladen werden, wobei jeder Worker ein anderes tar liest
Design des Daten-Schwungrads
Das Daten-Schwungrad ist der Burggraben von KI-Produkten – mehr Nutzer, mehr Daten, bessere Modelle, mehr Nutzer.
Datenerfassung von Nutzerfeedback
Feedback gibt es in zwei Arten: explizit und implizit.
- Explizites Feedback: Nutzer-Likes, -Dislikes, -Bearbeitungen und -Neugenerierungen
- Implizites Feedback: Verweildauer des Nutzers, Kopien, Freigaben und Sitzungslänge
Explizites Feedback ist qualitativ hochwertig, aber gering an Quantität; implizites Feedback ist im Überfluss vorhanden, aber verrauscht.
Ein gutes Feedback-System kombiniert beide – es nutzt explizites Feedback zum Trainieren von Belohnungsmodellen und implizites Feedback für A/B-Tests.
Automatisierte Datenannotation
Manuelle Annotation ist zu teuer und langsam; der aktuelle Trend geht dahin, „Modelle zur Annotation von Modellen zu verwenden“.
Gängige Strategien:
- Starke Modelle annotieren schwache Modelle: Verwenden von mit GPT-4 annotierten Daten zum Trainieren kleiner Modelle
- Bootstrap: Vorhandene Modelle zum Generieren von Kandidaten verwenden, gefolgt von manuellem Filtern
- Synthetische Daten: Modelle zum Generieren verschiedenartiger Trainingsdaten verwenden
Strategie für kontinuierliches Training
Modelle sind nicht „einmal trainiert und fertig“; die Welt verändert sich, und Modelle müssen sich entsprechend anpassen.
Ein typischer kontinuierlicher Trainingsprozess:
- Tägliches Erfassen neuer Nutzerinteraktionsdaten
- Durchführen eines kleinen Updates einmal pro Woche (SFT, überwachtes Feintuning)
- Durchführen eines großen Updates einmal im Monat (fortgesetztes Vortraining + SFT + RLHF)
- Ausführen von A/B-Tests für jedes Update und vollständige Bereitstellung erst nach Bestätigung der Wirkung
Kontinuierliches Training erfordert Aufmerksamkeit hinsichtlich des „katastrophalen Vergessens“ – wenn das Modell mit zu vielen neuen Daten trainiert wird, vergisst es möglicherweise frühere Fähigkeiten. Die Lösung besteht darin, einen „Replay-Buffer“ beizubehalten und alte sowie neue Daten in jeder Trainingseinheit zu mischen.
Architektur der KI-Plattform für Unternehmen
Eine vollständige KI-Plattform für Unternehmen umfasst typischerweise die folgenden Komponenten.
Modellregistrierung und Versionsverwaltung
Je mehr Modelle es gibt, desto lästiger wird die Verwaltung – eine zentralisierte Modellregistrierung ist erforderlich.
Die Registrierung sollte Folgendes aufzeichnen:
- Modelldateien (Gewichte, Konfiguration, Tokenizer)
- Versionsnummern und Änderungsprotokolle
- Trainingsdatenquellen und Hyperparameter
- Evaluierungsmetriken
- Bereitstellungsstatus
MLflow, Weights & Biases und Hugging Face Hub sind alles gängige Tools.
Feature Store
Viele KI-Anwendungen erfordern Feature Engineering – Nutzerprofile, historisches Verhalten, Kontextinformationen usw.
Feature Store ist ein Feature-Managementsystem, das mehrere Probleme löst:
- Training/Inferenz-Diskrepanz: Inkonsistenz zwischen Features, die beim Training und bei der Inferenz verwendet werden
- Feature-Wiederverwendung: Verschiedene Modelle können sich Features teilen
- Online/Offline-Konsistenz: Offline berechnete Features, online mit geringer Latenz gelesen
Typische Architektur: Offline-Batch-Berechnung mit Spark oder Flink, Online-Lesevorgänge mit geringer Latenz mit Redis oder Cassandra.
Online/Offline-Inferenzdienst
Die Inferenz ist in zwei Szenarien mit unterschiedlichen Architekturen unterteilt:
| Szenario | Latenzanforderung | Architektur | Beispiel |
|---|---|---|---|
| Online-Inferenz | Im Millisekundenbereich | Echtzeit-API + Batching | Chatbots, Suche |
| Offline-Inferenz | Im Stunden-/Tagesbereich | Batch-Job-Warteschlange | Inhaltsmoderation, Berichterstellung |
Online-Inferenzdienste müssen Folgendes berücksichtigen:
- Batching: Mehrere Anfragen kombinieren und gemeinsam berechnen, um den Durchsatz zu verbessern
- Dynamisches Batching: vLLM oder Text Generation Inference für dynamisches Batching verwenden
- Caching: K/V Cache beschleunigt die autoregressive Generierung; Ergebnisse für beliebte Prompts werden direkt zwischengespeichert
- Lastverteilung: Mehrere Modellinstanzen, intelligentes Routing
End-to-End-Überwachung
Probleme mit KI-Systemen sind schwer zu diagnostizieren – Sie benötigen Observability.
Mehrere Dimensionen der Überwachung:
- Systemmetriken: GPU-Auslastung, VRAM, Latenz, Durchsatz, Fehlerrate
- Modellmetriken: Ausgabelänge, Wiederholungsrate, Stoppwortverteilung
- Geschäftskennzahlen: Kundenzufriedenheit, Bindungsrate, Aufgabenabschlussrate
Klassischer Stack: Prometheus + Grafana für Metriken, ELK für Protokolle, Jaeger für Tracing.
Evaluierungs-Benchmark-System
Woher wissen Sie, ob sich ein Modell verbessert oder verschlechtert hat? Sie benötigen ein Evaluierungssystem.
Allgemeine Leistungs-Benchmarks
Häufig verwendete Benchmarks in der Wissenschaft:
| Benchmark | Testinhalt | Typische Aufgaben |
|---|---|---|
| MMLU | Multitasking-Sprachverständnis | Multiple-Choice-Fragen zu 57 Themenbereichen |
| HumanEval | Codegenerierung | 164 Programmieraufgaben |
| MBPP | Codegenerierung | 974 Python-Probleme |
| TruthfulQA | Faktualität | 817 Fragen zur Prüfung von Halluzinationen |
| GSM8K | Mathematisches Denken | 8000 Grundschul-Mathematikaufgaben |
Chinesische Benchmarks
Eine starke Leistung bei englischen Benchmarks bedeutet keine starke Leistung bei chinesischen; es sind spezifische chinesische Benchmarks erforderlich:
- C-Eval: Chinesisches Multitasking-Sprachverständnis, 13.948 Multiple-Choice-Fragen
- CMMLU: Chinesisches multimodales Verständnis (derzeit hauptsächlich Text)
- AGIEval: Chinesische Gaokao-Fragen, Fragen für den öffentlichen Dienst
Benutzerdefinierte Geschäfts-Evaluierungssätze
Öffentliche Benchmarks sind das Fundament, aber Ihr eigener Geschäfts-Evaluierungssatz ist wichtiger.
Wie man baut:
- Echte Benutzeranfragen sammeln (Hunderte bis Tausende)
- Manuell als „gut/mittel/schlecht“ kennzeichnen oder bewerten
- In Test- und Validierungssets aufteilen (Testset ist fixiert, nicht anfassen)
- Bei jedem Modellupdate ausführen, um Metrikänderungen zu sehen
Ihr Geschäfts-Evaluierungssatz ist Ihr „Goldstandard“ – er ist wichtiger als jeder öffentliche Benchmark.
Mandantenfähige KI-Dienste
Wenn Sie ein ToB-Produkt entwickeln, ist Mandantenfähigkeit ein unvermeidliches Thema.
Mandantenisolation
Isolation hat mehrere Ebenen:
| Isolationsstufe | Ressourcen | Vorteile | Nachteile |
|---|---|---|---|
| Physische Isolation | Dedizierte GPU-Maschinen | Vollständige Isolation, sicher | Hohe Kosten |
| K8s-Isolation | Dedizierter Pod / Namespace | Gleicht Kosten und Sicherheit aus | Erfordert Scheduling |
| Logische Isolation | Gemeinsame Ressourcen, Berechtigungssteuerung | Geringste Kosten | Leckagerisiko |
Die übliche Strategie ist: physische Isolation für Großkunden, logische Isolation für kleine und mittlere Kunden.
Modellfreigabe und Fine-Tuning-Verwaltung
Eine häufige Anforderung an die Mandantenfähigkeit: Trainieren Sie ein proprietäres Modell mit meinen Daten.
Die Architektur muss Folgendes unterstützen:
- Gemeinsamer Speicher für Basismodelle
- Der LoRA-Adapter jedes Mandanten wird separat gespeichert
- Dynamisches Laden der LoRA des entsprechenden Mandanten während der Inferenz
Dies spart eine Menge GPU-Speicher – das vollständige Modell muss nicht für jeden Mandanten geladen werden.
Abrechnung und Kontingente
KI-Dienste sind kostspielig, daher muss die Abrechnung granular erfolgen:
- Abrechnung nach Token (Eingabe und Ausgabe separat berechnet)
- Abrechnung nach Anzahl der Anfragen
- Abrechnung nach GPU-Zeit (Fine-Tuning-Szenarien)
- Kontingentbeschränkungen (Anfragen pro Minute, Token pro Tag)
Notfallwiederherstellung und Hochverfügbarkeit
Unternehmenssysteme dürfen nicht ausfallen – ein Hochverfügbarkeitsdesign ist erforderlich.
Bereitstellung über mehrere Verfügbarkeitszonen hinweg
Die grundlegendste Anforderung: AZ-übergreifende (Availability Zone) Bereitstellung.
Zum Beispiel:
- Primärer Cluster in AZ A
- Hot-Standby-Cluster in AZ B
- Asynchrone Datenreplikation
- Load Balancer schaltet den Datenverkehr automatisch um
Das Ziel ist: Wenn eine einzelne AZ ausfällt, bleiben die Dienste unterbrochen und es gehen keine Daten verloren.
Modell-Snapshot und Rollback
Neue Modellversionen können Probleme aufweisen – eine schnelle Rollback-Funktion ist erforderlich.
Strategie:
- Speichern Sie vor jeder Veröffentlichung einen Modell-Snapshot
- Behalten Sie die letzten N Versionen bei
- Überwachen Sie anormale Metriken und lösen Sie einen automatischen Rollback aus
- Kanadisches Release: Leiten Sie zuerst 1 % des Traffics um, rollen Sie es dann vollständig aus, wenn keine Probleme auftreten
Degradierung und Ratenbegrenzung
Was passiert, wenn der Traffic ansteigt? Er darf nicht einfach ausfallen – es muss einen Notfallplan geben:
- RatenbegrenzungGibt 429 zurück, wenn das Kontingent überschritten wird
- DegradierungVerwenden Sie ein kleineres Modell oder geben Sie zwischengespeicherte Ergebnisse zurück
- WarteschlangenbildungGibt eine Job-ID zurück, Ergebnisse später prüfen
Kernprinzip:Sanfte Degradierung, keine vollständige Nichtverfügbarkeit.
Weitere Erweiterungen