Zum Inhalt

Maschinen

Rechenleistung › Maschinen ist, wo Engines laufen, wie viel gleichzeitig läuft und was gerade läuft: eine Karte je Host. Engines ist, was installiert ist; diese Seite ist, worauf es läuft.

Die Maschinen-Seite

Dieser Server kommt zuerst und ist immer aufgeklappt: seine Kerne, die zwei Zahlen, die sagen, wie viel er gleichzeitig rechnet, die Bilanz, die sich daraus ergibt, und die Engines, deren Datei hier liegt, mit dem, was jede gerade tut. Dann dieser Browser, der in dem Moment eine Maschine wird, in dem du die mitgelieferte Engine installierst, und jeder Remote Runner mit seinen Slots und den Engines, die er anbietet. Ein Slot ist ein Engine-Auftrag oder ein Analysebrett.

Externer Runner und Wie externe Runner funktionieren (das ⓘ) stehen in der Titelleiste. Die Karte eines Browsers oder Runners klappt mit einem Druck auf ihre Zeile auf, und die offene ist hervorgehoben. Auf der Karte dieses Browsers installiert Browser-Stockfish installieren die Engine, Starten und Stoppen verbinden und trennen sie, und Deinstallieren … fragt nach, bevor der Browser widerrufen und vergessen wird.

Wie viel gleichzeitig

Eine Obergrenze, auf der Karte dieses Servers, und alles, was hier eine Engine laufen lässt, zählt gegen sie.

Einstellung
Warteschlangenprozesse Engine-Prozesse, die diese Maschine gleichzeitig laufen lassen darf – Analysedurchläufe, Fernschach-Aufgaben, die Analysebretter und Fernschachsuchen. 1 bis 64; leer heißt die Kerne der Maschine minus zwei

Eine Fernschachsuche belegt einen davon vom Start bis zur Pause, solange sie läuft, und solange hat die Warteschlange einen weniger: Bei vier Prozessen und vier laufenden Suchen wartet die Analyse einer importierten Partie, bis du eine pausierst oder stoppst. Das ist so gewollt – eine Suche ist auf der Fernschachseite, in ihrer Kapazitätsleiste und auf dieser Karte zu sehen, das Warten also nie ein Rätsel –, und deshalb zählt die Karte die Suchen zu dem, was belegt ist. Eine eigene Obergrenze für sie gibt es nicht mehr.

Warteschlangenprozesse gilt, sobald du speicherst. Mehr davon starten sofort mehr Worker; weniger lässt die laufenden Durchläufe zu Ende kommen und nimmt schlicht weniger neue an – nichts wird unterbrochen oder neu eingereiht. Laufen also zwei Durchläufe und du setzt die Grenze auf eins, ist der zweite fertig, bevor die Warteschlange bei eins ist. Ist BLUNDERBASE_ANALYSIS_CONCURRENCY in der Umgebung gesetzt, legt sie die Obergrenze von außen fest; das Feld ist dann nur lesbar und sagt es. BLUNDERBASE_ANALYSIS_WORKERS schaltet die Worker im Prozess ganz ab, für eine Installation, die die Warteschlange mit blunderbase analyze nach eigenem Zeitplan abarbeitet – die Fernschachsuchen gehen mit ab. Siehe Konfiguration.

Unter dem Feld rechnet die Bilanzzeile vor. Ein Prozess kostet die Threads seiner Engine; in die Kerne passen muss also Warteschlangenprozesse × Threads. Die Karte nimmt die Threads von den Zeilen unter Engines – die schwerste hier eingeschaltete Engine, denn jeder Platz kann gerade sie halten – und sagt in Worten, wann die Obergrenze bei Volllast die Maschine übersteigt. Sechs Prozesse eines Stockfish mit vier Threads sind vierundzwanzig Threads; auf acht Kernen kommt das ins Schwimmen, und die Zeile sagt es. Senk die Obergrenze, oder gib einer Zeile unter Engines weniger Threads. Threads gelten je Engine; wie viele Prozesse, gilt je Maschine. Solange der Fernschachmodus aus ist, wird nur die Engine mit der Rolle Analyse bemessen, weil sonst nichts hier läuft, es sei denn, du wählst in Analysieren … einer Partie eine andere.

Die Slots eines Remote Runners werden beim Registrieren festgelegt und lassen sich auf seiner Karte ändern (Umbenennen oder Größe ändern); die Threads jener Maschine stehen in ihrer eigenen runner.yaml, die Bilanzzeile gilt also nur diesem Server.

Remote Runner

Ein Runner ist ein zweiter Blunderbase-Prozess auf einer Maschine mit freien Kernen. Er hat keine Datenbank und liefert keine Seite aus. Er meldet sich von sich aus bei deinem Server, sagt, welche Engines er hat, und bekommt ganze Analyseaufträge und Analysebretter zugeteilt. Einem fertigen Durchlauf sieht man nicht an, wo er gelaufen ist. Er beantwortet auch die Züge einer Übungspartie auf seinen Engines. Ein Runner, der älter ist als das Üben, kann das nicht, und der Übungsdialog sagt, dass er aktualisiert werden muss.

Nimm einen, wenn die Maschine, auf der Blunderbase läuft, nicht die Maschine ist, die rechnen soll.

1. Den Runner auf dem Server registrieren

Auf dem Server:

$ blunderbase runners create gpu-box --slots 8
runner 'gpu-box' registered with 8 slot(s)
This token is shown once. Save the yaml below as runner.yaml on that machine:

# blunderbase runner — blunderbase-runner --config runner.yaml
# The token below is shown once. Keep this file readable only by the runner.
server: "https://blunderbase.example.com"
token: "bb_rnr_kY3…"
name: "gpu-box"
slots: 8
engines:
  # One entry per engine on THIS machine. Edit the paths before starting.
  - name: sf-remote
    path: /usr/games/stockfish
    options:
      Threads: 8

Externer Runner in der Titelleiste der Maschinen-Seite tut dasselbe und antwortet mit demselben yaml. So oder so wird das Token einmal herausgegeben und nie wieder: Gespeichert wird nur sein SHA-256. Ein verlorenes Token heißt widerrufen und einen neuen Runner anlegen, und das kostet nichts.

--server überschreibt die URL, die ins yaml geschrieben wird. Ohne die Option nimmt der Befehl BLUNDERBASE_PUBLIC_URL und, wenn auch das fehlt, die Adresse, an die sich der Serverprozess bindet. Setz BLUNDERBASE_PUBLIC_URL bei einer Installation hinter einem Proxy – der Server kann sonst nicht wissen, wie er von außen heißt. Siehe Hinter einem Proxy.

2. runner.yaml auf der anderen Maschine schreiben

Jeder Schlüssel, mit seiner Voreinstellung.

Oberste Ebene

Schlüssel Voreinstellung Was es ist
server erforderlich Die http- oder https-URL deiner Blunderbase. Die ws/wss-URL wird daraus abgeleitet
token erforderlich Aus runners create, einmalig angezeigt
name erforderlich Nur zur Information – die Identität ist das Token
slots 1 Engine-Aufträge plus Analysebretter gleichzeitig
verify_tls true Ob das Zertifikat des Servers geprüft wird
poll_seconds 5.0 Wie oft der HTTP-Rückfallweg nach Arbeit fragt
log_level info debug, info, warning oder error
reconnect siehe unten Wie hartnäckig der Runner zurückzukommen versucht
engines [] Ein Eintrag je Datei auf dieser Maschine

reconnect

Schlüssel Voreinstellung Was es ist
initial_seconds 1.0 Untergrenze des Backoffs, mit Jitter
max_seconds 60.0 Obergrenze des Backoffs
websocket_failures 3 Fehlschläge beim Verbinden, bevor der Runner auf Polling zurückfällt
retry_websocket_seconds 60.0 Wie oft ein pollender Runner den Socket erneut versucht

Ein Eintrag unter engines

Schlüssel Voreinstellung Was es ist
name erforderlich Eindeutig auf dieser Maschine; wird zum Namen der Engine auf dem Server
path erforderlich Der Pfad auf dieser Maschine; eine Datei oder eine vollständige Kommandozeile
kind uci uci oder maia
options {} UCI-Optionen, beim Start gegen das geprüft, was die Datei meldet
streams true bei uci Ob diese Engine ein Analysebrett steuern darf. Eine Maia streamt nie, egal was hier steht
instances ein Prozess je Slot Wie viele Kopien dieser Datei gleichzeitig laufen dürfen
tier – Wird angenommen und ignoriert, egal, was dort steht. Eine Datei aus der Zeit vor den Rollen oder vor dem einen Analysedurchlauf startet trotzdem

Eine ganze Datei:

# erforderlich
server: https://blunderbase.example.com
token: bb_rnr_…
name: gpu-box

# optional
slots: 4
verify_tls: true
poll_seconds: 5.0
log_level: info

reconnect:
  initial_seconds: 1.0
  max_seconds: 60.0
  websocket_failures: 3
  retry_websocket_seconds: 60.0

engines:
  - name: sf-remote
    path: /usr/games/stockfish
    kind: uci
    options:
      Threads: 8
      Hash: 4096
    streams: true
    instances: 2

  - name: maia3
    path: /engines/maia3/bin/maia3-5m
    kind: maia
    instances: 1   # ein GPU-Prozess für alle Slots zusammen

instances ist das Einzige, was eine Engine darüber sagen kann, wie sie ausgeführt wird. Ohne die Angabe bekommt jeder Slot, der diese Engine will, seinen eigenen Prozess – richtig für eine CPU-Datei und falsch für alles, was einen einzelnen Beschleuniger belegt: Eine Maia auf einer GPU will instances: 1, damit sich die Slots an einem Prozess anstellen, statt einen zweiten zu starten und der Karte den Speicher leer zu räumen. Die Angabe kann die Zahl der Prozesse nur senken, nie über slots hinaus erhöhen.

Ein unbekannter Schlüssel wird namentlich abgelehnt statt ignoriert. Ein Tippfehler in einer Slot-Zahl ist ein Fehler und keine Vorliebe, und die Ablehnung nennt das Feld und die Datei, aus der es kam.

Ein Runner meldet, was er hat, und behauptet nichts darüber, wofür er da ist. Welche Engine Analyse und Menschliche Züge bedient, wird auf der Seite Engines vergeben.

Vier Werte können aus der Umgebung statt aus der Datei kommen und schlagen die Datei, damit ein Token nicht in etwas liegen muss, das herumkopiert wird:

Variable Ersetzt
BLUNDERBASE_RUNNER_CONFIG Den Pfad zu runner.yaml, wenn --config fehlt
BLUNDERBASE_RUNNER_SERVER server
BLUNDERBASE_RUNNER_TOKEN token
BLUNDERBASE_RUNNER_NAME name
BLUNDERBASE_RUNNER_SLOTS slots

Ganz ohne Datei sind diese Variablen die komplette Konfiguration – genau das tut ein Container, der nichts mountet.

3. Starten

$ blunderbase-runner --config runner.yaml --check
sf-remote: accepted as engine 7
$ blunderbase-runner --config runner.yaml

--check fragt jede Datei ab, öffnet eine Verbindung, gibt aus, was der Server angenommen hat, und beendet sich. Führ das aus, bevor du den Runner richtig startest, nicht regelmäßig: Es öffnet eine zweite Verbindung mit demselben Token, und eine zweite Verbindung übernimmt den Runner.

Exit-Codes:

Code Bedeutung
0 Der Runner wurde zum Anhalten aufgefordert und hat angehalten
1 Die Konfiguration ist falsch, oder es ließ sich nicht eine einzige Engine starten
2 Der Server hat die Protokollversion dieses Runners abgelehnt – aktualisier den Runner auf die Version des Servers

SIGINT und SIGTERM bitten um ein sauberes Anhalten, statt eine Suche mitten im Frame abzuwürgen.

Als Container

Ein Runner ist dasselbe Image wie der Server, mit einem anderen Befehl, ohne Ports und ohne Volumes außer dem yaml. Im Repository liegt eine Beispiel-Compose-Datei, docker-compose.runner.yml. Leg sie zusammen mit runner.yaml in dasselbe Verzeichnis und starte sie:

$ BLUNDERBASE_RUNNER_TOKEN=bb_rnr_… docker compose -f docker-compose.runner.yml up -d

Das Image bringt Stockfish unter /usr/games/stockfish mit. Einen Maia-Build und seine Gewichte musst du selbst mounten – nimm beim Volume ./engines das Kommentarzeichen weg und registrier den Pfad als kind: maia.

Schalt den Healthcheck des Containers ab, wenn du den Service woanders hin kopierst: Er ruft per curl eine API ab, die ein Runner nicht anbietet, sodass docker compose ps einen tadellos arbeitenden Runner als „unhealthy“ ausweisen würde. Sieh stattdessen in die Logzeilen.

Setz TLS vor den Server. Das Token ist ein Bearer-Credential in jedem Frame. Hinter einem Proxy hat eine Caddyfile und eine nginx-Site, die das erledigen; server: ist dann die https-URL, und der Socket wird daraus abgeleitet.

Bei der Arbeit zusehen

  • blunderbase runners list – eine Zeile je Runner: verbunden oder nicht, seine Slots, die Engines, die er anbietet, und wie viel vom Rückstand nur er abarbeiten kann.
  • Die Maschinen-Seite – dieser Host und jeder Runner, jeweils mit den Engines, die er anbietet. Engines nennt die Maschine auch auf jeder Zeile.
  • Die Analyse-Warteschlange, nach Ziel aufgeteilt. Eine Warteschlange, die stillsteht, weil die Maschine mit dieser Engine offline ist, sieht genau wie eine lange Warteschlange aus, bis du hier nachschaust.
  • Ein MCP-Client hat ein nur lesendes Werkzeug runners_status, das dasselbe Bild zeigt. Das Ausstellen und Widerrufen bleibt aus dem Chat heraus: Das ist Umgang mit Token.

Wenn er sich nicht verbindet

Was du siehst Was es ist
exit 1, „server is required“ Die Datei oder die Umgebung ist unvollständig; die Meldung nennt das Feld und die Datei
exit 1, ein fehlgeschlagenes Abfragen Der path einer Engine stimmt auf dieser Maschine nicht
exit 2 Der Server spricht eine andere Protokollversion – aktualisier den Runner
Close-Code 4401, dann exit Das Token gehört zu keinem registrierten Runner; stell ein neues aus
Close-Code 4403 Der Runner wurde widerrufen, während er verbunden war
Close-Code 4409 Eine zweite Verbindung mit demselben Token hat ihn übernommen – meist ein --check-Lauf oder zwei Kopien des Containers
Close-Code 4426 Die beiden Seiten sprechen nicht dasselbe Runner-Protokoll; der Prozess endet mit 2
Close-Code 4429 Dieses Token wurde so oft abgewiesen, dass der Server ihm die Tür zugemacht hat. Weiter anzuklopfen hält sie nur zu – reparier das Token und warte. Ab zehn Fehlschlägen läuft ein Backoff, der sich von einer Sekunde auf eine Minute verdoppelt
im Log steht „polling“ Der Socket ist dreimal fehlgeschlagen. Der Runner arbeitet weiter, über HTTP, und versucht den Socket jede Minute erneut

Ein Runner aus der Zeit, bevor eine Analyse bei einer Tiefe oder nach Sekunden enden konnte, verbindet sich weiterhin und arbeitet weiter: Er bekommt jeden Durchlauf, der bei einem Knotenbudget endet – die Analyse jeder importierten Partie und alles, was in Knoten angefordert wurde. Eine angeforderte Analyse mit Tiefe oder Sekunden auf einer seiner Engines wartet in der Warteschlange, bis der Runner aktualisiert ist – die Warteschlange zeigt sie wartend auf dieser Maschine, und die Lösung ist das Update.

Widerrufen

$ blunderbase runners revoke gpu-box

Widerrufen … auf der Karte des Runners auf der Maschinen-Seite tut dasselbe, sobald du mit Widerrufen bestätigst. So oder so hört das Token auf zu funktionieren, und die Engines, die es angeboten hat, werden gelöscht.

Ein Widerruf aus der App schließt außerdem die offene Verbindung und gibt zurück, was der Runner gerade gerechnet hat, mit erstattetem Versuch – eine Maschine, die du weggenommen hast, ist nicht gescheitert. Die Kommandozeilen-Variante ist nicht der Serverprozess und kann deshalb keine Verbindung schließen, die sie nicht hält: Sie löscht die Engines, der Runner bekommt keine Arbeit mehr, und die Verbindung endet beim nächsten Reconnect.

Durchläufe, die gerade unterwegs waren, werden so oder so wieder eingereiht. Die Datenbank ist die Warteschlange; Runner sind entbehrlich.

Ein Durchlauf, eine Maschine

Die Bewertung eines Durchlaufs und sein Durchgang für menschliche Züge laufen im selben Prozess, beide Engines müssen also auf demselben Host liegen – bei einem Durchlauf, der beides anfordert.

Eine Suchengine auf einer Maschine ohne Maia wird in einer Installation, deren einzige Maia woanders liegt, schon beim Einreihen der Analyse abgelehnt, unter Nennung beider Maschinen. Ein Durchlauf, der ganz ohne Maia-Durchgang eingereiht wird, hat einen Durchgang und damit einen Host und wird deswegen nie abgelehnt. Eine Installation ganz ohne Maia ist nicht betroffen: Der Durchgang findet einfach nicht statt.