Auf einem GPU-Server, SLURM-Cluster oder Rechner hinter NAT trainieren
Schicke Potato-Trainingsläufe an einen ssh-GPU-Server, einen SLURM-Rechenknoten oder einen pollenden Agent, mit der Konfiguration für jeden, dem Check-Befehl und häufigen Fehlern.
Neu in v2.14.0
Dieses Tutorial verlagert das Modelltraining von Potato vom Annotationsserver auf einen Rechner mit GPU. Das Tutorial richtet sich an Studienadmins, deren Annotationsserver eine kleine Cloud-VM oder ein Laptop ist und deren GPUs in einem Lab-Server, einem Universitätscluster oder auf einer Workstation stehen, zu der sich der Server nicht verbinden kann. Für jedes der drei Remote-Backends behandelt die Seite, wann das Backend die richtige Wahl ist, was auf dem Remote-Rechner installiert sein muss, die Konfiguration, den Check-Befehl, was während eines Laufs geschieht, wie man einen Lauf abbricht und welche Fehler am wahrscheinlichsten auftreten. Das Tutorial setzt ein Projekt voraus, das bereits auf dem Annotationsserver trainiert, etwa das Projekt mit Rezensionen aus Dein erstes Modell trainieren.
Vier Orte, an denen ein Lauf ausgeführt werden kann
Ein Backend ist der Ort, an dem ein Trainingslauf ausgeführt wird. Potato hat immer das Backend local, einen Subprozess auf dem Annotationsserver. Die anderen Backends nennst du unter model_training.backends:
| Typ | Wo der Trainer läuft | Wer die Remote-Seite startet | Wo die Modelldateien landen |
|---|---|---|---|
local | Der Annotationsserver, in einem Subprozess | Potato | Das Verzeichnis artifacts/ des Laufs |
ssh | Ein Rechner, den Potato über ssh erreicht, etwa ein GPU-Server im Lab | Potato, über ssh | Zurückkopiert nach artifacts/ |
slurm | Ein Rechenknoten eines Clusters, als Batch-Job | Potato, über ssh zum Login-Knoten, dann sbatch | Zurückkopiert nach artifacts/ |
agent | Ein Rechner, den Potato nicht erreicht, etwa eine Workstation hinter NAT | Du, mit potato training agent | Auf dem Trainingsrechner |
Wähle ssh, wenn sich der Annotationsserver mit einem ssh-Schlüssel auf dem GPU-Rechner anmelden kann. Wähle slurm, wenn die GPUs hinter dem Scheduler SLURM stehen und der Rechner, auf dem du dich anmelden kannst, ein Login-Knoten ist. Wähle agent, wenn sich vom Server aus keine Verbindung zum GPU-Rechner öffnen lässt, weil der Agent jede Verbindung selbst öffnet. Eine Workstation hinter einem Heimrouter oder einer Campus-Firewall ist der übliche Fall für einen Agent. Die Vorhersagen und das Ergebnis des Laufs erreichen den Server von jedem Backend aus, sodass das Zurückschreiben und der Holdout-Score überall gleich funktionieren, wo der Trainer lief. Jeder Trainer außer decision-calibrate läuft auf jedem Backend.
Die Projektkonfiguration
Die folgende Konfiguration ist das Projekt mit Rezensionen aus dem ersten Tutorial, ergänzt um alle drei Remote-Backends. Ein echtes Projekt braucht nur die Backends, die du verwendest, und jedes Backend bekommt unten einen eigenen Abschnitt. max_wall_seconds: 3600 stoppt jeden Lauf, der nach einer Stunde nicht beendet ist. Bei einem ssh- oder Agent-Backend prüft der Server das Limit jede Sekunde, sodass ein Lauf, der auf einem Remote-Rechner hängt, die Lauf-Warteschlange nicht länger als das Limit blockiert:
annotation_task_name: "Review Sentiment"
task_dir: "."
data_files:
- "data/reviews.json"
item_properties:
id_key: "id"
text_key: "text"
output_annotation_dir: "annotation_output"
admin_api_key: "change-me"
annotation_schemes:
- annotation_type: "radio"
name: "sentiment"
description: "Is this review positive or negative?"
labels: ["positive", "negative"]
model_training:
enabled: true
backend: gpu-server # the default for runs; leave out to keep runs local
max_wall_seconds: 3600
writeback:
schemas: ["sentiment"]
include_unlabeled: true
min_confidence: 0.6
backends:
gpu-server:
type: ssh
host: gpu.example.org
python: /opt/conda/bin/python3
gpus: auto
min_free_gpu_mb: 4000
cluster:
type: slurm
host: login.cluster.example.org
python: /opt/conda/bin/python3
job_python: /shared/envs/train/bin/python
remote_dir: /shared/projects/me/potato-training
gres: gpu:1
time: "04:00:00"
prelude: ["module load cuda/12.4"]
lab-workstation:
type: agent
queue_timeout_s: 3600Validiere die Konfiguration, bevor du den Server startest:
potato validate config.yaml --strictDer Validator meldet einen Schlüssel, den der Backend-Typ nicht kennt, ein ssh- oder slurm-Backend ohne host, ein SLURM-remote_dir unter /tmp und ein model_training.backend, das kein Backend benennt. Der Server startet bei denselben Fehlern nicht, sodass ein falsch geschriebenes pyhton den Server beim Start anhält, statt Läufe an das Standard-python3 zu schicken.
Das Menü Runs on und die API
Die Training-Seite unter /admin/training hat ein Menü Runs on, das jedes Backend mit Typ und Host auflistet, z. B. gpu-server (ssh to gpu.example.org). model_training.backend legt den Eintrag fest, den das Menü zuerst auswählt, und die Runs-Tabelle hält in der Spalte Ran on fest, wo jeder Lauf ausgeführt wurde. Ein Lauf, der über die API gestartet wird, nennt sein Backend im Feld backend des Request-Bodys:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs \
-d '{"trainer": "hf-text-classification", "schemas": ["sentiment"], "backend": "cluster"}'Ein Backend-Name, der nicht in der Konfiguration steht, wird mit 409 abgelehnt. Das automatische Neutrainieren verwendet model_training.backend, solange auto_retrain.backend kein anderes Backend nennt, und Modell im Kreislauf behandelt auto_retrain vollständig. Unabhängig vom Backend läuft immer ein Lauf zur Zeit, und ein Lauf, der gestartet wird, während ein anderer läuft, wartet in der Warteschlange.
Auf diesem Rechner trainieren
Prüfe, welches Gerät ein lokaler Lauf bekommt, bevor du Läufe woandershin verlagerst. Mit dem Standard device: auto nimmt ein lokaler Lauf zuerst CUDA, dann Apples Metal (mps) und dann die CPU, und device: cuda:1 benennt eine einzelne GPU. Der Check-Befehl gibt das Gerät aus, das ein lokaler Lauf verwenden würde:
potato training check local config.yamlAuf einem Mac mit Apple Silicon gibt der Befehl local: this machine, Apple Metal (mps) aus. Ein angefordertes Gerät, das nicht vorhanden ist, fällt mit einer Warnung im Log des Laufs auf die CPU oder einen anderen Beschleuniger zurück. Lautet die Antwort CPU und fine-tunt der Trainer einen Transformer, verlagere den Lauf auf eines der Remote-Backends unten. Konfiguration listet device, num_threads und max_ram_mb für lokale Läufe auf.
Ein GPU-Server über ssh
Ein ssh-Backend führt den Trainer auf einem Rechner aus, den der Annotationsserver über ssh erreicht, meist ein GPU-Server im Lab. Potato startet alles auf der Remote-Seite selbst, sodass dort außer Python und den Paketen des Trainers nichts von Hand installiert oder gestartet wird. Auf dem GPU-Host muss Potato nicht installiert sein, weil Potato beim ersten Lauf seinen eigenen Python-Quellcode auf den Host kopiert und die Kopie wiederverwendet, bis sich der Quellcode ändert.
Voraussetzungen für ein ssh-Backend
Der Account, unter dem der Annotationsserver läuft, braucht einen ssh-Schlüssel, der sich ohne Eingabeaufforderung auf dem GPU-Host anmeldet. Potato führt ssh mit BatchMode=yes aus, sodass eine Passwortabfrage den Lauf sofort scheitern lässt, statt ihn hängen zu lassen. ssh gpu.example.org true muss unter diesem Account gelingen, und ein Schlüssel mit Passphrase funktioniert, wenn ssh-agent den Schlüssel hält. Der Wert host ist ein beliebiger Name, den ssh akzeptiert, und ein Alias aus ~/.ssh/config funktioniert. Die Schlüssel user, port und identity_file werden als -l, -p und -i an ssh übergeben.
Der GPU-Host braucht Python 3.8 oder neuer und die Pakete des Trainers, den du ausführst. Für hf-text-classification sind das torch, transformers und peft, der Inhalt des Extras potato-annotation[train-text]. Die Seite Trainer nennt die Installation für jeden Trainer. Fehlt dem Interpreter des Hosts ein Paket, richte python auf einen Interpreter, der das Paket hat, oder führe das Paket unter packages auf. Ist packages gesetzt, legt Potato unter remote_dir eine virtuelle Umgebung mit --system-site-packages an und installiert die aufgeführten Pakete einmal in die Umgebung. Der CUDA-Build von torch des Hosts bleibt in der Umgebung sichtbar:
model_training:
enabled: true
backends:
gpu-server:
type: ssh
host: gpu.example.org
python: /opt/conda/bin/python3
packages: ["transformers>=4.46.0", "peft>=0.13.0"]
gpus: auto
min_free_gpu_mb: 4000
num_threads: 8Mit gpus: auto nimmt jeder Lauf die GPU mit dem meisten freien Speicher und startet nicht, wenn keine GPU min_free_gpu_mb frei hat (Standard 2000). Potato vergleicht den freien Speicher statt der Auslastung, weil eine Karte mit niedriger Auslastung auf einem geteilten Server dennoch wenig freien Speicher haben kann. Setze min_free_gpu_mb nahe an den Speicher, den dein Trainer braucht. gpus: "1" legt GPU 1 fest, "0,1" legt zwei GPUs fest, und gpus: none trainiert auf der CPU. Ein Host ganz ohne GPU trainiert unter auto ebenfalls auf der CPU. num_threads setzt OMP_NUM_THREADS, MKL_NUM_THREADS und OPENBLAS_NUM_THREADS für den Lauf. Manche geteilten Server setzen OMP_NUM_THREADS=1 in Login-Shells, und num_threads überschreibt den Wert der Login-Shell.
Der Check-Befehl für ein ssh-Backend
Führe den Check auf dem Annotationsserver aus, unter dem Account, unter dem der Server läuft:
potato training check gpu-server config.yamlDer Befehl verbindet sich und meldet die Python-Version des Remote-Rechners, jede GPU mit freiem Speicher und Auslastung, die GPU, die ein Lauf bekäme, und die Trainingspakete, die dem Remote-Interpreter fehlen. Eine GPU, für die das installierte torch keine Kernel hat, wird mit (torch there has no kernels for it) markiert, und gpus: auto überspringt eine solche GPU. --json gibt denselben Bericht als JSON aus. Der Befehl endet mit 0, wenn ein Lauf starten könnte, und sonst mit 1. Die Schaltfläche Check neben dem Menü Runs on führt denselben Check von der Training-Seite aus.
Schritte eines ssh-Laufs
Für jeden Lauf führt Potato diese Schritte aus:
- Verbindet sich mit
sshund öffnet eine Reverse-Weiterleitung von einem Unix-Socket im Remote-/tmpzurück zum Annotationsserver. - Prüft den Interpreter, liest
nvidia-smiund wählt die GPU. - Kopiert den Quellcode von Potato nach
remote_dir/code/<hash>, wenn dem Host diese Version fehlt, und baut die virtuelle Umgebung, wennpackagesgesetzt ist und die Umgebung fehlt.remote_dirist standardmäßig~/.cache/potato-training. - Startet
python -m potato.training.agentfür den Lauf. Das Token des Laufs erreicht den Agent über stdin und erscheint nie in einer Befehlszeile, weil Befehlszeilen auf einem geteilten Server für jeden Account sichtbar sind. - Der Agent lädt das Bundle des Laufs mit Items, Labels und Medien herunter. Der Agent führt denselben Training-Worker aus, den das lokale Backend ausführt, und sendet Fortschritt, Vorhersagen und das Ergebnis über den Socket zurück.
- Ist der Lauf erfolgreich, kopiert Potato das Artefaktverzeichnis in das
artifacts/des Laufs zurück, löscht das Remote-Job-Verzeichnis und schließt die Verbindung.
Die Schrittzeile auf der Training-Seite folgt diesen Phasen, z. B. copying Potato's code to gpu.example.org und waiting for the agent on gpu.example.org. Das Log des Laufs nennt das Python des Hosts und die GPU, die der Lauf bekam.
Ein vollständiges Fine-Tuning kopiert das ganze Modell zurück, und über eine langsame Verbindung braucht ein Modell von 330 MB Minuten. Die Schrittzeile zeigt, wie viel vom Modell angekommen ist. Dateien, die größer als max_artifact_mb sind (Standard 2048), bleiben auf dem GPU-Host und werden im Log des Laufs genannt. fetch_artifacts: false lässt jede Modelldatei auf dem GPU-Host, und keep_remote: true behält das Remote-Job-Verzeichnis zur Inspektion. Der Push auf den Hugging Face Hub von der Lauf-Seite aus braucht die Modelldateien auf dem Annotationsserver, sodass ein Modell, das auf dem GPU-Host bleibt, nicht von der Lauf-Seite aus gepusht wird.
Der Unix-Socket wird mit dem Modus 0600 angelegt, sodass sich nur der Account, mit dem Potato angemeldet ist, über den Socket verbinden kann. Anfragen über den Socket erreichen den Annotationsserver als Loopback-Anfragen. Ein Server, der mit debug: true gestartet wurde, gewährt Loopback-Anfragen Admin-Zugriff. Jeder, der diesen Account auf dem GPU-Host nutzen kann, hat dann Admin-Zugriff auf einen Debug-Server, solange ein Lauf läuft. Lass debug auf einem Server aus, der über ssh trainiert.
Abbruch und Heartbeat-Timeout
Cancel run auf der Training-Seite erreicht den Agent über den Socket, in der Antwort auf den nächsten Fortschrittsbericht des Agents. Der Agent sendet SIGTERM an den Worker und SIGKILL, wenn der Worker nach model_training.grace_seconds (Standard 20) noch läuft, was der Server mit dem Job mitschickt. Ein Job von einem älteren Potato-Server trägt kein grace_seconds, und der Agent wartet dann 20 Sekunden. Auf dem Server endet der Lauf als abgebrochen, sobald grace_seconds vergangen sind, und der Server schließt die ssh-Sitzung des Agents. Ein Lauf, dessen Agent heartbeat_timeout_s lang (Standard 120) nichts sendet, schlägt fehl, und agent.log im Lauf-Verzeichnis enthält die letzte Ausgabe des Agents.
Ein SLURM-Cluster
Ein slurm-Backend ist für einen Cluster gedacht, dessen GPUs hinter dem Scheduler SLURM stehen. Auf einem solchen Cluster ist der Rechner, den Potato über ssh erreicht, ein Login-Knoten ohne GPUs, und die Rechenknoten erreichen Potato gar nicht. Potato startet den Agent deshalb auf dem Login-Knoten, wie bei einem ssh-Backend, und der Agent übergibt nur den Training-Worker mit sbatch an einen Rechenknoten. Der Fortschritt kommt über eine Datei auf Speicher zurück, den der Login-Knoten und die Rechenknoten teilen.
Voraussetzungen für ein SLURM-Backend
Der Login-Knoten braucht einen ssh-Schlüssel ohne Eingabeaufforderung und für den Agent Python 3.8 oder neuer, wie der Host eines ssh-Backends. Der Login-Knoten braucht außerdem sbatch, squeue und scancel im PATH. Der Agent ruft zusätzlich scontrol auf, wo der Cluster den Befehl hat. Potato ruft nie srun oder sacct auf, sodass ein Cluster mit abgeschaltetem srun und ohne Accounting-Datenbank funktioniert. remote_dir ist erforderlich und muss auf Speicher liegen, den die Rechenknoten teilen, weil der Job dort das Bundle liest und das Modell schreibt. Der Validator meldet einen Fehler für ein remote_dir unter /tmp oder /var/tmp, weil diese Verzeichnisse lokal zu jedem Knoten gehören.
Die Rechenknoten brauchen einen Interpreter mit den Paketen des Trainers, benannt durch job_python. packages wird auf einem SLURM-Backend nicht unterstützt, weil eine virtuelle Umgebung, die auf dem Login-Knoten angelegt wurde, auf den Rechenknoten möglicherweise nicht läuft. Richte job_python auf eine Umgebung, die die Rechenknoten haben, und setze Modul-Ladebefehle oder eine Aktivierung der Umgebung in prelude:
model_training:
enabled: true
backends:
cluster:
type: slurm
host: login.cluster.example.org
python: /opt/conda/bin/python3 # on the login node, for the agent
job_python: /shared/envs/train/bin/python # on the compute nodes, for the worker
remote_dir: /shared/projects/me/potato-training # storage the compute nodes share
partition: gpu
gres: gpu:1
time: "04:00:00"
prelude: ["module load cuda/12.4"]Jeder ssh-Schlüssel gilt für ein SLURM-Backend, außer gpus und packages. Die GPUs kommen aus gres, und der Scheduler setzt CUDA_VISIBLE_DEVICES für die GPUs, die er zuteilt. Ein Job ohne gres bekommt keine GPU. Die SLURM-Einstellungen entsprechen sbatch-Flags:
| Schlüssel | Standard | Bedeutung |
|---|---|---|
job_python | das python des Backends | Der Interpreter des Workers auf den Rechenknoten. |
gres | keiner | sbatch --gres, z. B. gpu:1 oder gpu:A6000:1. |
time | 04:00:00 | sbatch --time. Über 6 Stunden melden potato validate und der Start des Servers eine Warnung, wie der nächste Absatz beschreibt. |
partition | die Standard-Partition des Clusters | sbatch --partition. |
nice | 0 | sbatch --nice, von 0 bis 2000. |
cpus_per_task, mem | die Standardwerte des Clusters | sbatch --cpus-per-task und --mem. |
sbatch_options | [] | Weitere Flags, z. B. ["--requeue", "--constraint=a100"]. Potato setzt --output, --chdir, --job-name und --parsable selbst, und der Validator meldet für diese Flags hier einen Fehler. |
prelude | [] | Shell-Zeilen, die im Job vor dem Worker laufen. |
poll_interval_s | 30 | Sekunden zwischen squeue-Aufrufen, mindestens 10. |
exit_grace_s | 180 | Sekunden, die auf dem Login-Knoten auf den Exit-Code eines beendeten Jobs gewartet wird, mindestens 20. |
job_name | potato-train | Präfix des Job-Namens, gefolgt von den ersten 8 Zeichen der Run-ID. |
Ein time über 6 Stunden lässt potato validate und den Start des Servers model_training.backends.cluster.time is 12:00:00. A job that holds a GPU for more than 6 hours is long on a shared cluster; check its policy melden, und potato validate --strict schlägt bei der Warnung fehl. Erlaubt die Richtlinie des Clusters den längeren Job, bestätige die Warnung für dieses eine Backend in einem Block validation auf oberster Ebene, den nur potato validate liest:
validation:
acknowledge:
- "model_training.backends.cluster.time is"Jeder Eintrag wird als Teilstring von mindestens 12 Zeichen unter Beachtung der Groß- und Kleinschreibung mit dem Warnungstext verglichen, und eine passende Warnung wandert in die Liste der bestätigten Warnungen und lässt --strict nicht mehr fehlschlagen. Ein Eintrag, der das Backend nennt, bestätigt die Warnung nur für dieses Backend. Ein Eintrag, der zu kurz ist oder zu keiner Warnung passt, wird zu einer eigenen Warnung.
Der Check-Befehl für ein SLURM-Backend
potato training check cluster config.yamlDer Check meldet sich am Login-Knoten an und bestätigt, dass sbatch, squeue und scancel im PATH liegen und dass remote_dir nicht unter /tmp liegt. Der Bericht nennt die Python-Version auf dem Login-Knoten und das job_python, das der Job ausführen wird. Der Check kann nicht sehen, welche Pakete die Rechenknoten haben, sodass ein fehlendes Paket auf einem Rechenknoten als fehlgeschlagener Lauf mit dem Importfehler im Log des Laufs erscheint. Führe einen kurzen ersten Job mit einem kleinen time aus, um solche Probleme früh zu finden.
Schritte eines SLURM-Laufs
Potato verbindet sich mit dem Login-Knoten und kopiert seinen Code dorthin, wie bei einem ssh-Backend. Der Agent führt dann diese Schritte aus:
- Lädt das Bundle nach
remote_dir/jobs/<run>/herunter. - Schreibt
job.shund übergibt das Skript mitsbatch --parsable. Das Log des Laufs hältSubmitted SLURM jobmit der Job-ID und den Flags fest. - Im Job-Verzeichnis schreibt der Worker auf dem Rechenknoten seine Ereignisse in
events.jsonl, seine Fehler instderr.logund seinen Exit-Code inexit_code. Die eigene Ausgabe von SLURM geht nachslurm.out. - Der Agent liest
events.jsonl, während die Datei wächst, und reicht den Fortschritt an den Server weiter. Der Agent ruftsqueueeinmal propoll_interval_sauf, und das Log des Laufs hält jede Änderung des Queue-Status des Jobs fest, z. B.SLURM job 4242: PENDING (Priority)und dannRUNNING on node07. - Endet der Job, lädt der Agent die Vorhersagen hoch und meldet das Ergebnis. Die Artefakte kommen zum Server zurück und das Job-Verzeichnis wird entfernt, wie bei einem ssh-Backend.
Cancel run sendet scancel --full --signal=TERM an den Job und dann ein einfaches scancel, wenn der Worker nicht gestoppt hat. Bricht die ssh-Sitzung zum Login-Knoten ab, bricht der Agent seinen Job ab, und die GPU-Zuteilung wird freigegeben. Beendet der Scheduler einen Job selbst, schlägt der Lauf mit dem Grund des Schedulers fehl, gelesen aus scontrol show job oder slurm.out. Zu den Gründen, die Potato meldet, gehören das Zeitlimit, ein Knotenausfall, Preemption, Speichermangel und ein scancel von außerhalb von Potato.
Die Testsuite von Potato führt die SLURM-Abfolge gegen einen Ersatz für sbatch, squeue und scancel aus und deckt Job-Übergabe, Queue-Status, Fortschrittsweitergabe und Abbruch ab. Partitionslimits und Preemption-Richtlinien unterscheiden sich von Cluster zu Cluster, beobachte deshalb das Log deines ersten Jobs auf einem neuen Cluster.
Ein Agent, der von Hand auf einem Login-Knoten gestartet wird, der den Server erreicht, kann ebenfalls an SLURM übergeben, mit potato training agent --server ... --backend <name> --workdir <shared dir> --slurm-config slurm.json. Die Datei slurm.json enthält die Einstellungen der obigen Tabelle als JSON-Objekt, und --workdir muss auf Speicher liegen, den die Rechenknoten teilen.
Ein Rechner, den Potato nicht erreicht
Ein agent-Backend ist für einen Rechner gedacht, zu dem sich der Annotationsserver nicht verbinden kann, etwa eine Workstation hinter NAT. Jemand startet potato training agent auf diesem Rechner, und der Agent fragt den Server nach Jobs ab. Der Agent braucht keinen eingehenden Port, weil der Agent jede Verbindung selbst öffnet. Ein Abbruch erreicht den Agent in der Antwort des Servers auf den nächsten Fortschrittsbericht des Agents. Die Modelldateien bleiben auf dem Trainingsrechner, und nur die Vorhersagen und das Ergebnis kommen zurück.
Voraussetzungen für ein Agent-Backend
Der Trainingsrechner braucht ein installiertes Potato, die Pakete des Trainers, den du ausführst, und eine Netzwerkroute zur URL des Annotationsservers. Für hf-text-classification deckt eine Installation Potato und die Pakete des Trainers ab:
pip install "potato-annotation[train-text]"Der Server braucht nur den Backend-Eintrag. Ein Agent-Backend kennt type, description, heartbeat_timeout_s (Standard 120) und queue_timeout_s, aber keinen anderen Schlüssel:
model_training:
enabled: true
backends:
lab-workstation:
type: agent
queue_timeout_s: 3600Den Agent registrieren und starten
Stelle auf dem Annotationsserver ein Token für das Backend aus:
potato training register lab-workstation config.yamlDer Befehl gibt das Token einmal aus, mit den Befehlen, die auf dem Trainingsrechner auszuführen sind:
Token for backend 'lab-workstation' (shown once; registering again replaces it):
<token>
On the training machine:
export POTATO_TRAINING_TOKEN=<token>
potato training agent --server http://<this-server>:8000 --backend lab-workstationStarte den Agent auf dem Trainingsrechner mit der echten URL des Servers:
export POTATO_TRAINING_TOKEN=<the token>
potato training agent --server https://annotate.example.org --backend lab-workstationDer Agent führt Jobs für sein Backend aus, bis du den Agent stoppst. --token-file liest das Token aus einer Datei statt aus POTATO_TRAINING_TOKEN, und --python benennt den Interpreter, in dem der Training-Worker läuft, der Standard ist der eigene Interpreter des Agents. --once beendet sich nach einem Job, --workdir verlegt die Dateien des Agents aus ~/.cache/potato-training, und --keep behält das Bundle jedes Jobs. Wird der Name erneut registriert, stellt das ein neues Token aus und entwertet das alte Token.
potato training check lab-workstation config.yaml gibt den Token-Eintrag des Backends aus, wobei last_seen gesetzt ist, sobald sich ein Agent verbunden hat. Vor der Registrierung gibt der Befehl no token issued yet und den auszuführenden Register-Befehl aus.
Schritte eines Agent-Laufs
Ein Lauf für ein Agent-Backend wartet im Zustand queued, bis ein Agent nach Arbeit fragt. Mit queue_timeout_s: 3600 schlägt der Lauf nach einer Stunde ohne Agent fehl, und ohne queue_timeout_s wartet der Lauf, bis du den Lauf abbrichst. Der Agent lädt das Bundle als tar.gz-Datei herunter und setzt einen abgebrochenen Download dort fort, wo er stoppte, mit bis zu fünf Versuchen. Der Agent führt dann den Worker aus, sendet den Fortschritt, lädt predictions.jsonl hoch und meldet den Exit-Code. Der Server antwortet mit 413 auf eine Vorhersagedatei, die größer als max_predictions_mb ist (Standard 512).
Die Modelldateien bleiben unter --workdir auf dem Trainingsrechner, und der artifact_uri des Lauf-Eintrags nennt den Host und das Verzeichnis. Erreicht der Agent den Server während eines Laufs 300 Sekunden lang nicht, bricht der Agent den Lauf selbst ab. Ein Lauf, dessen Agent heartbeat_timeout_s lang nichts sendet, schlägt auf dem Server mit No word from the agent on lab-workstation for 120 seconds fehl.
Häufige Fehler
Jeder Eintrag nennt die Meldung im Log des Laufs oder im Check-Bericht und dann die Lösung. Die vollständige Liste für jedes Backend und jeden Trainer steht im Abschnitt zur Fehlersuche der Upstream-Dokumentation.
ssh to gpu.example.org failed: Permission denied. Potato braucht einen Schlüssel, der ohne Eingabeaufforderung funktioniert.ssh gpu.example.org truemuss unter dem Account des Servers gelingen./opt/conda/bin/python3 was not found on gpu.example.org. Setzepythonim Backend auf einen Interpreter, der auf dem Host existiert.No GPU has 4000 MB free. Jede GPU auf dem Host ist stärker ausgelastet, alsmin_free_gpu_mberlaubt.potato training check gpu-server config.yamllistet die GPUs auf. Warte, senke die Schwelle oder lege mitgpus: "1"eine GPU fest.Trainer 'hf-text-classification' could not be imported. Dem Remote-Interpreter fehlt ein Paket, das der Trainer braucht. Richtepythonauf einen Interpreter, der das Paket hat, oder führe das Paket unterpackagesauf. Behebe auf einem SLURM-Backend die Umgebung, diejob_pythonbenennt.This host's torch has no kernels for any of its GPUs. Das Remote-torch wurde für neuere GPUs gebaut, als der Host hat. Installiere einen torch-Build für diese GPUs oder verwende einen anderen Host.No word from the agent on gpu-server for 120 seconds. Der Remote-Rechner oder das Netzwerk ist ausgefallen. Auf einem ssh-Backend enthältagent.logim Lauf-Verzeichnis die letzte Ausgabe des Agents.The copy from gpu.example.org sent nothing for 180 s. Das Netzwerk zum Host ist beim Zurückkopieren des Modells ausgefallen. Die Vorhersagen des Laufs sind bereits gespeichert, und nur die Modelldateien fehlen inartifacts/.login.cluster.example.org has no sbatch on PATH, so it cannot submit jobs. Derhostist nicht der Login-Knoten des Clusters, oder die Befehle liegen in einemPATH, den nur eine Login-Shell setzt. SetzePATHunterenvdes Backends.SLURM job 4242 ended before the worker finished: it reached its time limit. Erhöhetimeim Backend oder trainiere auf weniger Items. Setzekeep_remote: true, umslurm.outnach anderen Scheduler-Fehlern zum Lesen zu behalten.- Ein Lauf auf einem Agent-Backend bleibt in der Warteschlange. Kein Agent mit diesem Backend-Namen fragt ab. Starte einen Agent mit
potato training agent --backend lab-workstationund prüfe das Token mit Check auf der Training-Seite. nvrtc: error: failed to open libnvrtc-builtins.so.13.0. Das torch des Hosts und sein Paketnvidia-cuda-nvrtcgehören zu verschiedenen CUDA-Versionen. Installiere dasnvidia-cuda-nvrtc, das zum torch-Build passt, oder richtepythonauf einen anderen Interpreter.
Weiterführende Links
- Die Übersicht zum Modelltraining behandelt die Training-Seite, den Trainingskreislauf und die Veröffentlichung eines Modells auf dem Hugging Face Hub.
- Konfiguration listet jeden Schlüssel von
model_training, die Holdout-Scores und den Speicherort der Läufe auf. - LLMs fine-tunen behandelt die Trainer, die am häufigsten eine Remote-GPU brauchen, mit LoRA und 4-Bit-Basisgewichten.
- Die Upstream-Referenz dazu, wo Läufe ausgeführt werden, enthält die vollständige Schlüsseltabelle für jedes Backend, und der Abschnitt zum Agent-Protokoll dokumentiert die Routen für alle, die einen eigenen Agent schreiben.