Rechnen

Drei Laptops, ein Monte-Carlo

Die Zahl, um die es dir wirklich geht, kommt aus einer Pipeline, an der du wochenlang gefeilt hast: sieben gemessene Eingaben, jede mit einer ehrlichen Unsicherheit, durch eine Kette nichtlinearer Transformationen in ein einziges dimensionsloses Verhältnis geschoben. Die Punktschätzung ist leicht. Der Fehlerbalken nicht. Fehlerfortpflanzung erster Ordnung — alles linearisieren, Varianzen addieren — setzt voraus, dass die Pipeline über die Streuung der Eingaben hinweg ungefähr gerade ist. Diese ist es sichtbar nicht: Die dritte Transformation schickt eine Eingabe durch eine sättigende Kurve, und Sättigung ist der Ort, an dem Linearisierung stirbt. Also tust du, was man tut, wenn die Algebra kein Vertrauen mehr verdient: die Eingaben aus ihren Verteilungen ziehen, die Pipeline auf jedem Zug ausführen und die Ausgabeverteilung selbst sprechen lassen. Monte-Carlo. Das einzige Problem von Monte-Carlo ist das Problem, das es immer hatte — N.

Außerdem besitzt du drei Laptops. Und das ist, wie sich zeigt, die ganze Geschichte.

Ein durchgerechnetes Beispiel

Ein konstruierter Fall, kein Laborbericht: Das Studio ist noch nicht geöffnet (wo wir stehen). Jede Rechnung unten ist exakt und auf Papier nachprüfbar — σ/√N, das Sample-Budget, die Obergrenze, die drei ungleiche Maschinen erreichen können. Das Verhalten der Plattform — Partition, Lease-Queue, verifizierte Annahme, der property-getestete Reducer — ist das, wofür die Engine gebaut und verifiziert ist. Keine Zeitangabe hier ist eine Messung, und keine wird als solche ausgegeben.

Die Arithmetik, die dich zu mehr Maschinen treibt#

Der Schätzer ist nichts Exotisches — ein Stichprobenmittel. Ziehe x₁ … x_N, werte die Pipeline g auf jedem Zug aus, mittle. Seine Varianz ist Var(ĝ_N) = σ²/N, mit σ² als Varianz einer einzelnen Auswertung; der Standardfehler fällt also wie σ/√N. Diese Wurzel ist in beide Richtungen gnadenlos: Vervierfache die Stichprobe, und der Fehler halbiert sich nur; verlange eine weitere stabile Dezimalstelle, und die Rechnung lautet Faktor hundert.

Nehmen wir an, ein Pilot-Shard mit 65.536 Zügen schätzt σ auf etwa 0,31, und du willst das Intervall bis in die vierte Dezimale stabil — einen Standardfehler nahe 5·10⁻⁵. Die Arithmetik übersetzt das in N ≥ (0,31 / 5·10⁻⁵)² ≈ 38 Millionen Auswertungen. Runde auf 640 Shards zu je 65.536 Samples auf: 41.943.040 Züge. Extrapoliere die Pilotrate, und das ist eine lange Strecke ungeteilter Aufmerksamkeit deiner schnellsten Maschine, Lüfter inklusive.

Aber schau, was die Mathematik nicht verlangt. Die Züge sind per Konstruktion unabhängig; dem Mittel ist gleichgültig, welche Maschine welches Sample ausgewertet hat — solange sich die Zufallsströme nie überlappen und die Faltung am Ende korrekt ist. Monte-Carlo ist nicht bloß parallelisierbar, es ist embarrassingly parallel: der Lehrbuch-Gutfall, von dem Prospekte fürs verteilte Rechnen stillschweigend verallgemeinern. Das hier ist der Gutfall. Und im Haus stehen zwei weitere Laptops.

Ein Job, 640 Shards, null Kopplung#

Gepoolte Arbeit ist auf Scellis ein einziger Mechanismus: Ein inhaltsadressierter Job wird in Shards partitioniert, von einem Pool aus Geräten ausgeführt, durch eine deklarierte Reduction gefaltet und vor der Annahme verifiziert. Der Sampler ist schon ein gewöhnlicher Workflow; ihn poolbar zu machen heißt, seine Partition zu deklarieren. Partitioniere by_seed: Jeder Shard teilt den Root-Seed und besitzt einen disjunkten Zählerbereich des zählerbasierten RNG. Shard 317 zieht also exakt seine eigenen 65.536 Samples — dieselben auf jeder Maschine, an jedem Tag —, und zwei Shards können nie denselben Punkt ziehen. Reproduzierbarkeit pro Shard fällt aus der Partition selbst heraus, und zwischen den Samples gibt es nichts zu koordinieren.

Shards liefern Akkumulatoren zurück, keine Samples. Jeder faltet seine Auswertungen in einen Zustand konstanter Größe — Anzahl, Mittelwert, zweites zentrales Moment und 256 Histogramm-Bins über einen aus dem Pilot eingefrorenen Bereich: ein paar hundert Bytes statt eines megabytegroßen Sample-Dumps. Die deklarierte Reduction führt zwei solcher Zustände zusammen:

js
// zwei Shard-Akkumulatoren zusammenführen — assoziativ, kommutativ
function merge(a, b) {
  const n = a.n + b.n;
  const d = b.mean - a.mean;
  return {
    n,
    mean: a.mean + d * (b.n / n),
    m2: a.m2 + b.m2 + (d * d * a.n * b.n) / n,
    bins: a.bins.map((c, i) => c + b.bins[i]),
  };
}

Das schönste Detail am ganzen Design: Die Plattform glaubt dir diese Algebra nicht. Assoziativität und Kommutativität eines deklarierten Reducers werden property-getestet, bevor ein Pool ihn benutzen darf — zufällige Zustände, vertauschte Reihenfolgen, andere Baumformen. Denn ein Combiner, der still nicht assoziativ ist, würde per Tree-Reduce selbstbewusst falsche Zahlen produzieren, und niemand sähe je die Naht.

Drei Laptops, eine Queue#

Der Pool hier ist die unspektakulärste Sorte, die Scellis kennt: deine eigenen Geräte. Der Alltagslaptop, der alte auf der Fensterbank und der schwere vom Schreibtisch — alle im selben Account angemeldet, denn genau das verlangt das Eigene-Geräte-Modell ehrlicherweise. Die Einrichtung dauert Minuten: Jede Maschine fragt einmal nach ihrem eigenen Compute-Consent, darunter ein Budget-Governor und eine Akku-Untergrenze. Der Fensterbank-Laptop steigt in dem Moment ein, in dem er am Netzteil hängt — exakt das Verhalten, das man von einer Akku-Untergrenze will.

Verteilung ist ein Pull, nie eine Zuweisung. Ein Gerät least einen Shard aus der Queue, rechnet, liefert den Akkumulator ab, least den nächsten. Niemand modelliert, wer wie viel Arbeit verdient: Die schnelle Maschine kommt schlicht früher zurück und nimmt mehr, die langsame knabbert ihren ehrlichen Anteil. Und eines ist das hier nicht, selbst unter drei Laptops, die alle dir gehören: serverlos. Die Datenebene ist Peer-to-Peer — im LAN reden die drei direkt miteinander —, aber eine Koordinator-Session bleibt für Mitgliedschaft und Leases die ganze Laufzeit über in der Schleife. Ein Solo-Lauf braucht gar keinen Server; ein gepoolter braucht einen für die Kontrollebene, und Scellis sagt diesen Satz laut, statt ihn zu nuscheln.

Der Fensterbank-Laptop schläft ein#

Jetzt mach es absichtlich kaputt. Lass den Fensterbank-Laptop mitten im Lauf einschlafen — der Bildschirm-Wake-Lock ist consent-gated, auf zwei Maschinen erteilt, auf der dritten vergessen, und dieses Argument gewinnt das Betriebssystem immer. Die Plattform tut nicht so, als wäre das anders; sie überlebt es. Das Shard-Board zeigt ein Grüppchen veraltender Leases. Eine abgelaufene Lease wandert schlicht zurück in die Queue, und die beiden anderen Maschinen stehlen sich die verwaiste Arbeit, ohne gefragt zu werden. Work-Stealing, Nachzügler-Erholung und Absturz-Erholung sind hier derselbe Mechanismus — eine verfallene Lease ist eine verfallene Lease, ob die Ursache ein langsamer Shard ist, ein gekillter Tab oder ein Deckel, den man hätte aufgeklappt lassen sollen.

Weckst du die Maschine, tritt sie wieder bei und least, als wäre nichts gewesen — aus Sicht der Queue war ja auch nichts gewesen. Das Nickerchen kostet genau die Arbeit, die diese Maschine im Schlaf nicht getan hat, und keinen Zug mehr.

Gefaltet wird nur, was verifiziert ist#

Akzeptierte Ergebnisse sind die einzigen Ergebnisse. Ein Shard fließt erst nach der Verifikation in die Summe ein — und die Pipeline macht für deine eigene Hardware keine Ausnahme. Unter eigenen Geräten schützt die Prüfung eher vor Flakiness als vor Betrug, aber es ist derselbe Annahmepfad, den jedes Vertrauensmodell bekommt: Eine Handvoll Shards wird still als Stichprobe erneut ausgeführt und innerhalb der deklarierten Toleranz verglichen. Toleranz, nicht Gleichheit — drei verschiedene GPUs produzieren keine bitidentischen Floats, und Scellis behauptet das auch nie. Auf dem GPU-Pfad heißt „übereinstimmen“: innerhalb der deklarierten Toleranzklasse. Genau in diesem Sinn können sich drei Maschinen einig sein. Die volle Annahme-Geschichte — Leases, Verifikation, Vertrauensmodelle — steht im Guide.

Wenn sich die Faltung schließt, kommt heraus, was der billige Fehlerbalken versteckt hatte: eine Verteilung mit sichtbarer Gestalt. Eine linearisierte Standardabweichung, die die gesampelte unterschätzt; ein symmetrisches Intervall, das einen schweren rechten Schwanz verfehlt; ein Mittelwert über dem Plug-in-Wert. Die Nichtlinearität war der Punkt — jetzt siehst du sie, statt sie wegzuannehmen. Committe den Lauf, und Programm, Partition, Root-Seed und Engine-Version hängen an einer URL; jeder einzelne Shard lässt sich allein aus Seed und Zählerbereich wieder abspielen. Es gibt frühere Kapitel in den meisten Rechnerleben, in denen man für diesen Satz Geld bezahlt hätte.

Die ehrliche Skalierungsnotiz#

Jetzt der Vorbehalt, der den Rest glaubwürdig macht. Das skaliert, weil sich die Arbeit in unabhängige Teile zerlegen lässt: null Kopplung zwischen Zügen, eine assoziative Faltung, ein paar hundert Bytes Verkehr pro Shard. Für Arbeit dieser Form — Parameter-Sweeps, Ensembles, k-fache Validierung, Batch-Analyse, Monte-Carlo — skaliert die Lease-Queue nahezu linear, und zu weit mehr als drei Peers. Aber sei präzise, was drei Laptops kaufen: Die Obergrenze ist die Summe dessen, was die drei liefern — gegenüber deiner schnellsten Maschine allein also eher 2× als 3×, weil die Maschinen ungleich sind. Die Linearität steckt in gelieferter Kapazität, nicht in der Zahl der Deckel.

Und synchronisiertes Training ist nicht so. Gradientenschritte koppeln jeden Peer bei jedem Schritt, Nachzügler blockieren die Barriere, und dieser Pfad hält ehrlich bei Dutzenden stabiler Peers, nicht Tausenden — erweitert durch weniger Synchronität, nie durch Wünschen. Federated Learning skaliert Teilnehmer und statistische Aussagekraft, nicht Wanduhrzeit. Scellis druckt diese Grenzen auf die Verpackung — und genau deshalb ist dem Etikett auf dem Gutfall zu trauen: Wenn der Schätzer ein Mittel unabhängiger Züge ist, ist σ/√N das Gesetz, das Gesetz parallelisiert perfekt — und drei Laptops sind wirklich ein Monte-Carlo. Jeder Shard verifiziert, jeder Zug wieder abspielbar, der ganze Nachmittag per URL zitierbar.

  • distributed
  • monte-carlo
  • own-devices
  • statistics

← Alle Beiträge