Nimm an der Hanzo-Beta teil und erhalte 50 % auf jeden bezahlten Tarif

BitDelta: 14 Zen-Modelle aus einem GPU-Cluster ausliefern

Wie die 1-Bit-Delta-Kompression von BitDelta 14 Zen-Modellvarianten aus gemeinsamer GPU-Infrastruktur ausliefert: die Mathematik, die Architektur und die Kompromisse.

Auf dieser Seite

Die Ökonomie, feingetunte Modellvarianten auszuliefern, ist von Haus aus ungünstig.

Ein Modell mit 70B Parametern in BF16 braucht 140GB GPU-Speicher. Wenn Sie 14 feingetunte Varianten dieses Modells haben — jede mit einem eigenen Fähigkeitsprofil, einer Fachspezialisierung oder einer Verhaltensabstimmung — verlangt die naive Serving-Architektur 14 getrennte Modellladungen: 1.96TB GPU-Speicher, 14 getrennte Inferenzprozesse, 14x die Infrastrukturkosten. Für jede Variante nach der ersten zahlen Sie den vollen Preis für etwas, das fast nur verdoppeltes Basiswissen ist.

BitDelta (arXiv:2402.10193) bricht diese Ökonomie. Die Idee ist elegant, die Mathematik einfach.

Das mathematische Fundament

W_base sei die Gewichtsmatrix des Basismodells und W_ft die entsprechende Gewichtsmatrix einer feingetunten Variante. Das Verhaltensdelta ist:

Δ = W_ft - W_base

BitDelta komprimiert dieses Delta auf 1-Bit-Präzision:

W_ft ≈ W_base + α · sign(Δ)

Dabei ist α ein Skalierungsfaktor je Matrix, berechnet als mittlerer Absolutwert von Δ:

α = (1/n) · ||Δ||_1 = mean(|Δ_ij|)

Die Vorzeichenoperation reduziert jedes skalare Delta auf ein einziges Bit, plus oder minus. Der Skalierungsfaktor α stellt die Größe wieder her. Zusammen erfasst die Näherung die Richtungsinformation des Feintuning-Updates zu 1/32 der Speicherkosten eines Deltas in voller Präzision (1 Bit gegenüber 32 Bit je Parameterelement).

Warum funktioniert das? Feintuning eines großen vortrainierten Modells erzeugt Deltas, die im Erwartungswert klein gegenüber den Basisgewichten sind. Das Basismodell erfasst die dominante Struktur der Sprache; das Feintuning erfasst Verhaltensänderungen auf dieser Struktur. Ist das Delta klein, ist das Vorzeichen jedes Elements die informationsreichste Darstellung dieses Elements: die Größe ist über die Deltamatrix hinweg ungefähr gleich, daher ist α · sign(Δ) ein effizienter Code.

Das lässt sich formaler fassen. Modelliert man Δ_ij als Laplace-Zufallsvariable mit Lage 0 und Skala b:

Δ_ij ~ Laplace(0, b)
|E[sign(Δ) | |Δ|]| = 1 for all nonzero Δ

Das Vorzeichen erhält die Richtungsinformation vollständig. Der Informationsverlust liegt allein in der Größenvariation, die der eine Skalierungsfaktor α teilweise zurückholt. Bei Feintuning-Deltas mit geringer Größenvariation (Verhaltensänderung statt Wissenstransfer) ist die Näherung eng.

Speicherreduktion: Bei einem 70B-Modell in BF16 belegen die Basisgewichte 140GB. Das Delta jeder feingetunten Variante würde in vollem BF16 weitere 140GB hinzufügen. Im BitDelta-Format belegt jedes Delta ungefähr 8.75GB (70B Bits = 8.75GB, zuzüglich der α-Skalare, die vernachlässigbar sind). Der Cluster mit 14 Varianten geht von 14 × 140GB = 1.96TB auf 140GB + 14 × 8.75GB ≈ 262GB zurück, eine Reduktion um 87%.

Serving-Architektur

┌─────────────────────────────────────────────────────────────────┐
│                    GPU CLUSTER (8x H100, 80GB each)             │
│                                                                  │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │              BASE WEIGHTS (140GB, HBM resident)          │   │
│  │  W_base for zen4-70b: attention, FFN, embeddings, norms  │   │
│  └──────────────────────────────┬───────────────────────────┘   │
│                                 │ shared read                    │
│  ┌──────────────────────────────▼───────────────────────────┐   │
│  │           DELTA CACHE (≈8.75GB per variant)              │   │
│  │  zen4-coder:    α_coder,    sign(Δ_coder)    [8.75GB]    │   │
│  │  zen4-ultra:    α_ultra,    sign(Δ_ultra)    [8.75GB]    │   │
│  │  zen4-math:     α_math,     sign(Δ_math)     [8.75GB]    │   │
│  │  zen4-writer:   α_writer,   sign(Δ_writer)   [8.75GB]    │   │
│  │  zen4-legal:    α_legal,    sign(Δ_legal)    [8.75GB]    │   │
│  │  zen4-medical:  α_medical,  sign(Δ_medical)  [8.75GB]    │   │
│  │  ...14 total...                                           │   │
│  └──────────────────────────────┬───────────────────────────┘   │
│                                 │                                │
│  ┌──────────────────────────────▼───────────────────────────┐   │
│  │              REQUEST ROUTER                               │   │
│  │  model_id → delta_load → reconstruct W_ft → inference    │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

Zur Inferenzzeit ist die Serving-Pipeline:

  1. Die Anfrage trifft ein mit model: "zen4-coder"
  2. Der Router findet den Delta-Cache-Eintrag für zen4-coder
  3. Das effektive Gewicht wird im Flug rekonstruiert: W_eff = W_base + α_coder · sign(Δ_coder)
  4. Der Vorwärtslauf läuft mit den rekonstruierten Gewichten
  5. Die Antwort wird zurückgegeben

Schritt 3 ist der kritische Pfad. Die Rekonstruktion ist ein fusionierter CUDA-Kernel, der Basisgewichte und Deltabits gleichzeitig liest und das effektive Gewicht in Registern oder Shared Memory aufbaut, ohne das volle W_eff im HBM zu materialisieren. Rekonstruktion und Matrixmultiplikation lassen sich in einem Kernel-Durchlauf fusionieren: das rekonstruierte Gewicht existiert nie vollständig als eigener Tensor.

# Simplified reconstruction kernel (conceptual)
def fused_bitdelta_linear(
    x: torch.Tensor,          # input activations [batch, seq, d_in]
    w_base: torch.Tensor,     # base weight [d_out, d_in] in HBM
    delta_sign: torch.Tensor, # 1-bit delta [d_out, d_in] packed as int8
    alpha: torch.Tensor,      # scale factor [d_out] or scalar
) -> torch.Tensor:
    # In practice: single CUDA kernel, no intermediate w_eff allocation
    # Conceptually equivalent to:
    delta_unpacked = unpack_bits(delta_sign).to(w_base.dtype)  # {-1, +1}
    w_eff = w_base + alpha.unsqueeze(1) * delta_unpacked
    return torch.nn.functional.linear(x, w_eff)

Der fusionierte Kernel hält den Spitzenverbrauch an HBM-Bandbreite bei ungefähr 1.5x der Gewichte des Basismodells, und nicht bei 2x, weil das Delta im gepackten Bitformat gelesen und während der fusionierten Operation im schnellen SRAM entpackt wird.

Latenzprofil

In der Praxis, über den Zen-Serving-Cluster mit 14 Varianten:

VarianteP50 TTFTP99 TTFTgegen die Basislinie
zen4 (base)18ms42ms1.0x
zen4-coder21ms48ms1.17x
zen4-ultra22ms51ms1.22x
zen4-math21ms47ms1.17x
zen4-writer20ms45ms1.11x

Der Mehraufwand der Zeit bis zum ersten Token durch die BitDelta-Rekonstruktion beträgt 2-4ms, vernachlässigbar gegenüber den Prefill-Kosten bei üblichen Promptlängen. Der Rekonstruktionskernel ist rechengebunden, nicht speichergebunden, und skaliert daher gut mit der Generierung auf der GPU.

Der Generierungsdurchsatz (Tokens/Sekunde) ist zwischen dem Basismodell und jeder BitDelta-Variante identisch, weil die Rekonstruktion nur in der Prefill-Phase stattfindet. Sobald der KV-Cache gefüllt ist, nutzt der autoregressive Generierungsschritt die üblichen Matmul-Pfade.

Qualität: was bei der 1-Bit-Kompression verloren geht

Die ehrliche Antwort: ein kleiner, sorgfältig begrenzter Anteil.

Die Qualitätsminderung von BitDelta hängt von der Aufgabe ab. Bei Aufgaben, die in den Feintuning-Daten gut vertreten sind, ist das Verhaltensdelta stark: das Vorzeichen erfasst die dominante Gradientenrichtung zuverlässig. Bei Aufgaben am Rand der Feintuning-Verteilung ist das Delta schwächer: die Näherung bringt mehr Rauschen relativ zum Signal.

Empirisch, über Zen-Modelle auf ihren Zielaufgabensuiten:

ModellVolle PräzisionBitDeltaDelta
zen4-coder (HumanEval)72.4%71.1%-1.3%
zen4-math (MATH-500)68.9%67.8%-1.1%
zen4-writer (WritingBench)84.2%83.7%-0.5%
zen4-legal (LegalBench)61.3%60.1%-1.2%

Die Minderung von 1-1.3% auf den primären Aufgabensuiten ist der Preis für 87% weniger Speicher. Für alle Zen-Varianten ist dieser Kompromiss tragbar: der Qualitätsunterschied liegt unter der Schwelle einer für den Nutzer merklichen Verhaltensänderung in typischen Anwendungsfällen.

MonoSoup: SVD-Ergänzung eines einzelnen Checkpoints

MonoSoup (arXiv:2602.09689) behandelt ein ergänzendes Problem: wenn mehrere feingetunte Checkpoints desselben Basismodells vorliegen, wie führt man sie in einen einzelnen Checkpoint zusammen, ohne sie alle gleichzeitig zu laden?

MonoSoup wendet SVD auf den Task-Vektor (Δ = W_ft - W_base) an, um die niedrigrangigen Komponenten mit der meisten Verhaltensinformation zu finden, und aggregiert sie dann über die Checkpoints:

For checkpoints {W_1, W_2, ..., W_k}:
  Δ_i = W_i - W_base
  [U_i, S_i, Vh_i] = truncated_SVD(Δ_i, rank=r)
  τ_i = U_i · diag(S_i) · Vh_i  # rank-r approximation

MonoSoup merge:
  W_merged = W_base + (1/k) · Σ τ_i

Die SVD-Kürzung beim Rang r wirkt als Entrauschungsschritt: Feintuning verändert ein Modell meist entlang einer kleinen Zahl hochvarianter Richtungen im Gewichtsraum. Diese Richtungen per gekürzter SVD zu erfassen und zu verschmelzen nimmt die Verhaltensessenz jedes Checkpoints mit, ohne das Rauschen der Richtungen mit kleineren Singulärwerten.

Wir nutzen MonoSoup in Zen-Trainingsläufen als Checkpoint-Mittelung: alle 1000 Gradientenschritte verschmelzen wir den aktuellen Checkpoint mit dem bisherigen besten per MonoSoup statt per naiver Mittelung. Das senkt das Trainingsrauschen und ergibt glattere Verlustkurven bei besserer Endqualität.

K-Merge: Online-Verwaltung von LoRA-Adaptern für den Edge

K-Merge (arXiv:2510.13537) löst eine andere Variante des Serving-Problems: am Edge, wo der Speicher auf ein festes Budget von B Gigabyte begrenzt ist, wie liefert man K LoRA-Adapter effizient aus?

K-Merge hält einen Pool verschmolzener Adapter unter der Bedingung, dass der Gesamtspeicher B nie überschreitet. Wird ein neuer Adapter angefordert, der nicht im Pool ist:

  1. Die paarweise Ähnlichkeit zwischen dem neuen Adapter und allen vorhandenen Poolmitgliedern wird berechnet (Kosinusähnlichkeit über Task-Vektoren)
  2. Der ähnlichste vorhandene Adapter wird bestimmt
  3. Der neue Adapter wird per OPCM (Verschmelzung durch orthogonale Projektion) in den ähnlichsten vorhandenen überführt
  4. Übersteigt die Qualität des verschmolzenen Adapters auf beiden Aufgaben die Schwelle, wird das Original verdrängt und die verschmolzene Fassung gespeichert

Die Richtlinie garantiert, dass der Pool höchstens K Adapter enthält, die das Budget B verbrauchen, und dabei die Abdeckung aller angeforderten Adapter durch begründetes Verschmelzen maximiert.

Für das Edge-Deployment von Zen (Hanzo Desktop, mobil) ermöglicht K-Merge lokal ausgelieferte Modellfamilien, die sonst die Speichergrenzen des Geräts überschreiten würden. Ein Gerät mit 16GB verfügbarem Modellspeicher kann 8 verschiedene Verhaltensprofile ausliefern, indem es einen K-Merge-Pool hält, der ähnliche Adapter bei Bedarf verschmilzt.

Infrastrukturdetails

Delta-Speicherformat: 1-Bit-Vorzeichenmatrizen, gespeichert als gepackte int8-Tensoren (8 Bit je Byte, sodass eine Schicht mit 70B Parametern und einem Gewicht von 4096×4096 auf 4096×512 int8 packt). Die α-Skalierungsfaktoren liegen als float32 vor, einer je Ausgabedimension, und machen ungefähr 0.1% des Delta-Speichers aus.

Kaltstartverhalten: Liegt das Delta einer Variante nicht im GPU-SRAM (etwa weil die Variante seit 10 Minuten nicht angefordert wurde), zahlt die erste Anfrage einen Latenzaufschlag für das Laden des Deltas von ungefähr 200ms bei einem 70B-Modell, die Zeit, um 8.75GB bei sequenziellen NVMe-Leseraten von NVMe nach HBM zu übertragen. Nach der ersten Anfrage bleibt das Delta im Delta-Cache des GPU-SRAM, bis die LRU-Richtlinie es verdrängt.

Cache-Verdrängung: LRU mit Gewichtung nach Anfragerate. Varianten mit hoher Anfragerate sind festgehalten; Varianten mit wenig Verkehr können verdrängt werden. In der Praxis sind die führenden 6 Varianten nach Verkehrsaufkommen immer cache-resident; die übrigen 8 teilen sich den restlichen Cache-Platz mit LRU-Verdrängung.

Anfragerouting: Der Serving-Router verfolgt laufende Anfragen je Variante und verhindert Head-of-Line-Blocking: wird das Delta von zen4-coder geladen, stellen sich eingehende zen4-coder-Anfragen in die Warteschlange, statt jeweils eine eigene Ladung auszulösen.

Das Ergebnis: 14 Zen-Modellvarianten, ausgeliefert von 8x H100-Knoten, die zuvor 112x H100-Knoten für dieselbe Fähigkeit gebraucht hätten. Die Senkung der Infrastrukturkosten ist nicht inkrementell. BitDelta macht die Mehrmandanten-Modellfamilie wirtschaftlich tragfähig.


Zen-Modelle gibt es unter zenlm.org. API-Zugang unter hanzo.ai.

Kommentare

Melde dich mit deiner Hanzo ID an, um zu kommentieren.

Kommentare werden geladen…

Weiterlesen