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.

OptimierungsrichtungGängige TechnikenWirkung
ModellkomprimierungQuantisierung, Pruning, Distillation2-4x Beschleunigung, geringer Genauigkeitsverlust
InferenzoptimierungvLLM、TensorRT、FlashAttention3-10x Durchsatzverbesserung
ArchitekturdesignBatch-Verarbeitung, mehrstufiges CachingKosten 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:

StufeGerätVerbindungsmethodeBandbreite
Innerhalb einer einzelnen MaschineGPU-GPUNVLink900GB/s
Dasselbe RackServer-zu-ServerInfiniBand400Gb/s
Rack-übergreifendSwitch-zu-SwitchInfiniBand Fabric400Gb/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.

3D 并行策略示意图

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-StufeWas aufgeteilt wirdSpeichereinsparungen
ZeRO-1Optimizer-Zustände~4x
ZeRO-2Optimizer-Zustände + Gradienten~8x
ZeRO-3Optimizer-Zustände + Gradienten + ParameterLinear 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 hashlib
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:

SzenarioLatenzanforderungArchitekturBeispiel
Online-InferenzIm MillisekundenbereichEchtzeit-API + BatchingChatbots, Suche
Offline-InferenzIm Stunden-/TagesbereichBatch-Job-WarteschlangeInhaltsmoderation, 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:

BenchmarkTestinhaltTypische Aufgaben
MMLUMultitasking-SprachverständnisMultiple-Choice-Fragen zu 57 Themenbereichen
HumanEvalCodegenerierung164 Programmieraufgaben
MBPPCodegenerierung974 Python-Probleme
TruthfulQAFaktualität817 Fragen zur Prüfung von Halluzinationen
GSM8KMathematisches Denken8000 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:

IsolationsstufeRessourcenVorteileNachteile
Physische IsolationDedizierte GPU-MaschinenVollständige Isolation, sicherHohe Kosten
K8s-IsolationDedizierter Pod / NamespaceGleicht Kosten und Sicherheit ausErfordert Scheduling
Logische IsolationGemeinsame Ressourcen, BerechtigungssteuerungGeringste KostenLeckagerisiko

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