Numerieke equivalentie over heterogene backends

CUDA, ROCm, Adreno en CPU's zullen nooit bit-voor-bit overeenstemmen. Dat de zwerm toch één coherent model produceert, is een ontworpen eigenschap, geen geluk.

Het sleutelonderscheid

Exact vs equivalent — twee verschillende eigenschappen

  • Binnen één backend — exact (3.6e-12): experts over nodes verdelen en combineren is dezelfde gewogen som hergegroepeerd; het enige verschil is de drijvende-komma-accumulatievolgorde. Orakel-geverifieerd.
  • Tussen backends — equivalent (1e-3…1e-6): dezelfde operatie op andere hardware draagt een relatieve fout per op van ~1e-3–1e-6, en is nooit nul. De zwerm leeft in dit regime.

"Exact" is wat decompositie binnen één apparaat garandeert. "Equivalent" is wat heterogene hardware je geeft. De taak van de zwerm is te voorkomen dat equivalentie zich opstapelt tot divergentie.

Gemeten · echte 122B, drie backends

Geen theorie — gemeten op hardware

Dezelfde layer-0-expert-FFN van Qwen3.5-122B, berekend door linkcpp-expert-worker op een MI250 (ROCm), de ARM-CPU van een telefoon (SM-S938N) en een x86-numpy-referentie — dezelfde invoer, dezelfde gewichten, andere instructiesets en reductievolgordes:

Three backends feeding one comparator where their waveforms overlap within tolerance
Backend-paarmax|Δ|cosine
ROCm (GPU) vs numpy (x86)7.9e-70.99996
Telefoon-ARM-CPU vs numpy (x86)1.4e-60.99992
ROCm-GPU vs telefoon-ARM-CPU1.5e-60.99990

Drie instructiesets, één berekening — elk paar equivalent (cosine ≈ 0.9999), geen paar bit-identiek (Δ ≈ 1e-6). De residuen zijn klein omdat router-autoriteit de invoer en de expertselectie heeft vastgepind.

Een latere run op echte NVIDIA GB10 Grace Blackwell-hardware sloot de matrix op het laatste backend: CUDA ↔ ROCm landde op cosine 1.0000000000 (max abs 3.5e-10, feitelijk bit-identiek, aangezien beide GPU-backends kernelbronnen delen), en CUDA ↔ Grace ARM CPU op cosine 0.99975 — hetzelfde GPU↔CPU-patroon als hierboven.

Waarom backends verschillen

Drijvende-komma-optelling is niet associatief

  • Matmul-reductievolgorde — tensor cores, MFMA-tegels, OpenCL-workgroups en SIMD-lanes accumuleren elk in andere volgordes en tegelingen.
  • FMA-fusie — a*b+c één keer (FMA) of twee keer afgerond, per backend anders gefuseerd.
  • Accumulatieprecisie — F16/BF16-opslag met F32- vs F16-accumulatoren (de grootste hefboom op divergentie).
  • Transcendente benaderingen — polynoom-/tabelvarianten van exp (softmax), silu/sigmoid (swiglu), rsqrt (norms).
  • Dequant + matmul-pad — dekwantiseren-dan-vermenigvuldigen vs gefuseerde gekwantiseerde kernels ronden tussenwaarden anders af.
  • Niet-deterministische kernels — atomic/split-K-reducties kunnen op hetzelfde apparaat per run verschillen.

Niets hiervan is een bug. Het is de prijs die het snelle pad van elke versneller betaalt.

Waarom het toch werkt

Eén autoriteit voor beslissingen, genoeg precisie voor accumulatie

ROUTER-AUTORITEIT — de kerninvariant. De enige discrete beslissing in het netwerk is MoE-routering (top-8 van 256). Als elk backend de router opnieuw zou draaien, zouden grens-tokens andere experts kiezen en werkelijk divergeren. Kvasir draait de router één keer, op de backbone, en stuurt workers alleen de geselecteerde expert-id's. Een heterogene zwerm kan verschillen in de *grootte* van de uitvoer van elke expert — hij verschilt nooit in *welke experts draaien*. Dit zet catastrofale discrete divergentie om in begrensde continue fout, en is de coherentieregel van heterogeen expert-sharding.

  • Discrete argmax: decoderen is een argmax over logits. Een wiebel van 1e-3 kantelt een token alleen als twee kandidaten binnen 1e-3 liggen — op de meeste posities is de marge veel groter, dus komen de tokens identiek uit; de zeldzame kantelingen zijn posities zo ambigu als een andere seed.
  • Combine is optelling: deelresultaten versmelten als een kansgewogen som. Onafhankelijke fouten van ~1e-4 tellen incoherent op — ze groeien als √k, niet k — en er is geen wegvallen van grote waarden, dus het residu blijft goed geconditioneerd.
Waar het kan breken · en de regels die dat stoppen

Divergentiemodi en verdedigingen

DivergentiemodusMechanismeRegel
RouteringsmismatchBackends kiezen andere top-8 voor grens-tokensRouter-autoriteit — één keer beslist op de backbone, id's gedispatcht
TrajectvertakkingLogit-gewiebel per token kantelt er uiteindelijk één; de reeks vertakt als een nieuwe seedDecoderen/samplen vastgepind op één node
Diepte-accumulatie49 lagen × elk ~1e-4 → tot 1e-2 bij de finale logitsF32-accumulatie bij grenzen en combine
Zelf-non-determinismeAtomic/split-K-kernels variëren per runDeterministische combine-kernels; verificatie met toleranties
PrecisiemismatchDe ene node accumuleert F16, de andere F32Accumulatieprecisie geadverteerd als capaciteit; F32-nodes voorkeur voor uitvoerrangen
Equivalentie is een getal

Het meetprotocol

  • Delta per op — dezelfde invoer, relatieve fout A vs B op matmul, swiglu, softmax, norm.
  • Laaggrens-drift — residual-delta na één laag, gestapeld om te zien of de diepte als √L of L accumuleert.
  • End-to-end logit-divergentie — L∞, L2 en KL-divergentie over de volledige forward.
  • Beslissingsovereenstemming — top-1-tokenovereenstemming plus top-8-routeringsovereenstemming (valideert waarom router-autoriteit nodig is).
  • Generatiestabiliteit — greedy N tokens; de eerste index waar A en B divergeren.
  • Taakniveau — perplexity- en eval-scoredelta's: de enige metriek die een gebruiker echt voelt.

Een voldoende is een tolerantie — "top-1-overeenstemming ≥ 99.x%, KL ≤ ε". Een node buiten tolerantie wordt gemarkeerd als ongeschikt voor gevoelige rangen, niet botweg afgewezen.

Waarom dit kernzwermtechnologie is

Bit-overeenstemming is onmogelijk — en onnodig

Een homogene cluster kan bit-exactheid aannemen; een zwerm niet — zijn premisse is *welke hardware er ook opduikt*. Dus behandelt Kvasir numerieke equivalentie precies als protocolcompatibiliteit: een eersteklas, gemeten contract. Backends en accumulatieprecisie worden geadverteerd als nodecapaciteiten, router-autoriteit wordt afgedwongen als invariant, en elke verificatie gebruikt toleranties in plaats van bitgelijkheid. Gemeten numerieke equivalentie + discrete beslissingen van één autoriteit — dat is wat één model tegelijk op elke GPU op aarde laat draaien. Dat is de zwerm.