Configurazione e route dell'addestramento di modelli
Ogni chiave del blocco model_training, come le esecuzioni vengono messe in coda, valutate e archiviate, e le route di amministrazione e agent, con rimedi agli errori più comuni.
Novità nella v2.14.0
Questa pagina è il riferimento per il blocco model_training di una configurazione di Potato e per ciò che accade a un'esecuzione dopo che l'hai avviata. La pagina è scritta per chi gestisce uno studio e vuole limitare le esecuzioni, inviarle a un'altra macchina, mostrare agli annotatori le predizioni di un modello o avviare l'addestramento da uno script. Ogni chiave, valore predefinito, route e messaggio qui sotto è stato verificato rispetto al codice di Potato. Per una prima esecuzione, inizia da Addestra il tuo primo modello. I trainer e i loro parametri sono elencati in Trainer.
Una configurazione completa
La configurazione seguente addestra un classificatore di sentiment su recensioni di prodotti. auto_retrain riadatta sklearn-text dopo ogni 25 nuove annotazioni. Con le feature TF-IDF predefinite, sklearn-text si addestra sulla CPU e non richiede nulla oltre a una normale installazione di Potato. Le esecuzioni automatiche frequenti costano quindi poco. Il write-back mostra agli annotatori ogni predizione con una confidenza di almeno 0.8. Con include_unlabeled, un'esecuzione predice anche sulle recensioni che nessuno ha ancora etichettato. I valori predefiniti di hf-text-classification e il backend gpu-server servono le esecuzioni avviate a mano dalla pagina Training:
annotation_task_name: "Review sentiment with model training"
task_dir: "."
data_files:
- "data/reviews.json"
item_properties:
id_key: "id"
text_key: "text"
output_annotation_dir: "annotation_output"
user_config:
allow_all_users: true
annotation_schemes:
- annotation_type: "radio"
name: "sentiment"
description: "Is this review positive or negative?"
labels: ["positive", "negative"]
model_training:
enabled: true
split_seed: 0
splits: {train: 0.7, val: 0.15, test: 0.15}
aggregation: consensus
retain_runs: 5
queue_max: 10
max_wall_seconds: 3600
max_ram_mb: 8192
num_threads: 4
trainer_params:
sklearn-text:
classifier: sklearn.linear_model.LogisticRegression
classifier_kwargs: {max_iter: 1000}
hf-text-classification:
model_name: answerdotai/ModernBERT-base
epochs: 4
lora: true
auto_retrain:
enabled: true
trainer: sklearn-text
schemas: [sentiment]
min_interval_s: 600
update_frequency: 25
writeback:
schemas: [sentiment]
min_confidence: 0.8
include_unlabeled: true
backends:
gpu-server:
type: ssh
host: gpu-server
python: /opt/conda/bin/python3
gpus: auto
min_free_gpu_mb: 4000Mantieni fisso split_seed per tutta la vita dello studio. Un nuovo seme riassegna ogni item, quindi gli item che erano esclusi dall'addestramento finiscono nell'addestramento e i punteggi successivi non sono più confrontabili con quelli precedenti. La soglia min_confidence di 0.8 è un punto di partenza, e la soglia giusta dipende dal primo punteggio held-out. Attiva include_unlabeled quando quel punteggio giustifica la visualizzazione delle pre-etichette, perché le pre-etichette ancorano gli annotatori alla risposta del modello.
Chiavi di model_training
Ogni chiave sta sotto model_training:
| Chiave | Predefinito | Significato |
|---|---|---|
enabled | false | Registra la pagina Training, le route sotto /admin/training e le route degli agent sotto /api/training. Senza enabled: true le route non esistono. |
retain_runs | 5 | Esecuzioni concluse conservate nel registro delle esecuzioni. Un'esecuzione più vecchia esce dal registro a meno che le sue predizioni siano ancora archiviate. Le directory delle esecuzioni restano su disco. |
grace_seconds | 20 | Secondi concessi a un'esecuzione annullata per terminare prima che Potato uccida il processo. 0 o più, e inviato con il job ai backend di tipo ssh, slurm e agent. |
queue_max | 10 | Esecuzioni che possono attendere dietro quella in corso. |
split_seed | 0 | Seme per assegnare gli item alle partizioni train, val e test. |
splits | {train: 0.7, val: 0.15, test: 0.15} | Frazioni delle partizioni, normalizzate in modo che la somma sia 1. I nomi sono train, val e test, e train è obbligatorio. |
aggregation | consensus | Come le etichette di più annotatori su un item diventano un'unica etichetta. consensus adatta il modello di Dawid-Skene quando lo studio ha più di un annotatore e ripiega sul voto di maggioranza se l'adattamento fallisce. majority prende il voto di maggioranza. |
max_wall_seconds | non impostato | Limite di tempo per un'esecuzione. Potato controlla un'esecuzione locale a ogni evento che riporta, e un'esecuzione ssh o agent ogni secondo. |
max_ram_mb | non impostato | Limite di spazio di indirizzamento per il processo di addestramento, impostato con setrlimit. Su una piattaforma senza il limite, l'esecuzione registra un avviso e continua. |
device | auto | auto, cpu, cuda, cuda:N o mps. auto sceglie CUDA, poi Metal di Apple, poi la CPU. |
num_threads | non impostato | Imposta OMP_NUM_THREADS, MKL_NUM_THREADS e OPENBLAS_NUM_THREADS per l'esecuzione, a meno che l'ambiente imposti già quelle variabili. |
auto_retrain | disattivato | Riaddestramento mentre arrivano le annotazioni. Vedi auto_retrain. |
writeback | nessuno | Pubblicazione delle predizioni come pre-etichette. Vedi writeback. |
backend | local | Il backend per le esecuzioni che non ne indicano un altro. |
backends | nessuno | Backend ssh, slurm e agent con nome. Vedi Backend. |
max_predictions_mb | 512 | Dimensione massima di predictions.jsonl che un agent remoto può caricare. |
trainer_params | nessuno | Valori predefiniti dei parametri, per nome del trainer. |
tiling | enabled: auto | Suddivisione delle immagini grandi in tile per i trainer di rilevamento e segmentazione. Vedi tiling. |
I params propri di un'esecuzione prevalgono su trainer_params, che prevale sui valori predefiniti del trainer. Un nome di parametro che il trainer non accetta viene rifiutato all'avvio del server quando il nome sta sotto trainer_params, e all'avvio dell'esecuzione negli altri casi. Trainer mostra l'ordine con un esempio.
auto_retrain
Il riaddestramento automatico controlla se serve una nuova esecuzione dopo ogni salvataggio di un'annotazione:
| Chiave | Predefinito | Significato |
|---|---|---|
enabled | false | Attiva il controllo. |
trainer | nessuno | Nome del trainer. Obbligatorio. |
schemas | nessuno | Schemi da addestrare. Obbligatorio. |
min_interval_s | 600 | Secondi dalla fine dell'ultima esecuzione prima che ne parta un'altra. |
update_frequency | 25 | Nuove annotazioni dall'ultima esecuzione automatica prima che ne parta un'altra. |
params | {} | Parametri del trainer, come i params di un'esecuzione via API. |
backend | model_training.backend | Backend per le esecuzioni automatiche. |
accept_licence | false | Conferma la licenza di un trainer che chiede conferma (ultralytics-detect, ultralytics-segment, layoutlmv3). Senza la conferma, le esecuzioni automatiche di quei trainer vengono saltate. |
Quando un controllo decide contro un'esecuzione, il motivo compare nel campo skip_reason di GET /admin/training/api/status, per esempio "waiting for 3 more annotation(s)" o "a run is already in progress". Le esecuzioni automatiche non entrano mai nella coda delle esecuzioni. La prossima annotazione salvata dopo che la coda si è svuotata controlla di nuovo, con più annotazioni su cui addestrare. Potato tiene in memoria i conteggi delle annotazioni, quindi dopo un riavvio un progetto che si è già addestrato conta le nuove annotazioni a partire dal riavvio.
writeback
Il write-back decide quali predizioni vedono gli annotatori:
| Chiave | Predefinito | Significato |
|---|---|---|
schemas | [] | Schemi le cui predizioni vedono gli annotatori. Un elenco vuoto non ne mostra nessuna. |
min_confidence | 0.0 | Le predizioni sotto la soglia vengono salvate e non mostrate. Una predizione senza confidenza passa. |
field | predictions | Campo dell'item in cui vengono scritte le pre-etichette. |
include_unlabeled | false | Predice anche sugli item che nessuno ha etichettato e pre-etichetta quegli item. Senza include_unlabeled, un'esecuzione predice solo sugli item val e test dell'esecuzione stessa. |
tiling
I trainer di rilevamento e segmentazione ridimensionano ogni immagine a poche centinaia di pixel. A quella dimensione gli oggetti di un'immagine di vetrino intero o di una scena satellitare vanno persi. Per uno schema image_annotation, microscopy o geo_annotation, Potato taglia quindi ogni immagine grande in tile quando vengono costruiti i dati di addestramento dell'esecuzione. La partizione di un'immagine viene decisa prima che l'immagine sia tagliata, quindi i tile di uno stesso vetrino non finiscono mai in due partizioni. Le predizioni vengono rimappate sull'immagine intera, e i punteggi held-out sono calcolati su immagini intere. Il tutorial sui modelli per la visione tratta vetrini e mappe nella pratica.
| Chiave | Predefinito | Significato |
|---|---|---|
enabled | auto | auto divide in tile i formati di vetrino (.svs, .ndpi, .mrxs, .scn e altri) e le immagini il cui lato più lungo è almeno auto_min_side. true divide ogni immagine e false nessuna. |
auto_min_side | 4096 | Lunghezza del lato più lungo, in pixel, da cui auto inizia a dividere un'immagine in tile. |
tile_size | 1024 | Lato di un tile, nei pixel che vede il trainer. |
overlap | 128 | Pixel condivisi dai tile vicini, al massimo metà di tile_size. Tieni la sovrapposizione almeno grande quanto gli oggetti, altrimenti un oggetto grande viene trovato a pezzi. |
downsample | 1 | Pixel a piena risoluzione per pixel di tile. |
mpp | nessuno | Micron per pixel di tile. Prevale su downsample per un vetrino che registra la propria risoluzione. |
background | 0.25 | Tile vuoti campionati per ogni tile con un oggetto. Imposta background: 0 per i vetrini annotati solo in parte. |
max_predict_tiles | 2000 | Massimo di tile predetti per immagine. Vengono tenuti i tile con più tessuto. |
min_visible | 0.4 | Quota di un oggetto che deve stare dentro un tile perché l'oggetto si addestri lì. |
tissue_threshold | 0.05 | Quota di un tile di vetrino che deve essere tessuto perché il modello predica sul tile. |
I vetrini vengono letti con openslide, installato da pip install "potato-annotation[wsi]", sulla macchina che costruisce i dati di addestramento. Un backend remoto scarica i tile e mai il vetrino.
La coda delle esecuzioni
Viene eseguita una sola esecuzione alla volta. Un'esecuzione avviata dalla pagina Training o dall'API mentre un'altra è in corso attende invece di essere rifiutata. La richiesta di avvio restituisce 202 con queued: true e la position dell'esecuzione, e la tabella Runs elenca l'esecuzione come waiting #N con un pulsante Cancel run. Quando l'esecuzione in corso termina, parte la più vecchia tra quelle in attesa.
Le esecuzioni in attesa sono record nel registro delle esecuzioni, quindi la coda sopravvive a un riavvio, e la prima esecuzione in attesa parte quando il server torna. Un'esecuzione in cui il server precedente si trovava a metà viene marcata interrupted nello stesso momento. I dati di addestramento di un'esecuzione in attesa vengono costruiti quando l'esecuzione parte, quindi l'esecuzione si addestra sulle annotazioni presenti in quel momento. Un avvio che verrebbe rifiutato, come un avvio che indica uno schema sconosciuto, viene rifiutato subito e non quando arriva il turno dell'esecuzione. Un'esecuzione il cui schema o trainer è uscito dalla configurazione mentre attendeva fallisce con invalid_when_dequeued, e parte l'esecuzione successiva.
Invia "queue": false nel corpo della richiesta per ottenere 409 invece di un posto in coda. Con queue_max esecuzioni già in attesa, un nuovo avvio ottiene 429. GET /admin/training/api/status elenca in ordine le esecuzioni in attesa sotto queue.
Controlli prima di un'esecuzione
potato validate segnala insieme ogni problema del blocco model_training, e il server rifiuta di avviarsi per gli stessi problemi:
potato validate config.yaml --strictI controlli coprono questi casi:
splitscon un nome diverso datrain,valetest, una frazione sotto 0 o non numerica, frazioni la cui somma è 0, oppure senzatrain.- Una chiave che
writebackoauto_retrainnon ha, una voce diwriteback.schemasche non è uno schema, oppure unmin_confidencefuori dall'intervallo da 0 a 1.accept_licenseviene segnalato come errore di battitura diaccept_licence. - Un blocco
pre_annotationattivo il cuifieldè diverso dawriteback.field. Sotto un blocco del genere non comparirebbe alcuna pre-etichetta di addestramento. - Con
auto_retrain.enabled, un trainer o uno schema che non esiste, uno schema che il trainer non può imparare, parametri che il trainer non accetta o di tipo sbagliato, unbackendassente dabackends, oppuredecision-calibratesu un backend diverso dalocal. - Un parametro sotto
trainer_paramsche il trainer non accetta, o di tipo sbagliato. Dentrodp, il controllo riguarda anche ogni chiave e il suo intervallo. - Un
grace_secondsinferiore a 0 o non numerico, oppure unretain_runsosplit_seedinferiore a 0 o non intero. - Sotto
backends, untypemancante o sconosciuto, una chiave che il tipo non ha, un backend ssh senzahost, un valore digpusdiverso daauto,noneo indici di GPU, un backend remoto chiamatolocal, oppure unmodel_training.backendnon definito.
potato training check verifica un backend prima che un'esecuzione lo usi. Per local, il comando stampa il dispositivo che un'esecuzione userebbe, per esempio local: this machine, Apple Metal (mps) su un Mac con Apple silicon. Per un backend ssh, il comando riporta la versione di Python, ogni GPU con la sua memoria libera, la GPU che un'esecuzione otterrebbe e i pacchetti di addestramento che mancano all'interprete remoto. Il pulsante Check della pagina Training esegue la stessa verifica, e --json stampa il report come JSON:
potato training check local config.yaml
potato training check gpu-server config.yamlUn'esecuzione avviata dalla pagina Training o dall'API viene controllata di nuovo quando parte. I codici di stato sono elencati in Route.
Backend
Un'esecuzione gira su un backend, e il menu Runs on della pagina Training elenca i backend configurati. model_training.backend imposta il valore predefinito, e un'esecuzione via API o auto_retrain può indicare un backend diverso con backend. Potato ha quattro tipi di backend:
| Tipo | Dove gira il trainer | Chi avvia il trainer |
|---|---|---|
local | Questa macchina, in un sottoprocesso. Sempre disponibile, ed è il valore predefinito. | Potato |
ssh | Un'altra macchina che Potato può raggiungere via ssh, come un server GPU. | Potato, via ssh |
slurm | Un nodo di calcolo di un cluster, come job batch. | Potato, con ssh al nodo di login e poi sbatch |
agent | Una macchina che Potato non può raggiungere, come una workstation dietro NAT. | Una persona, con potato training agent |
Un backend ssh usa l'autenticazione a chiave con BatchMode attivo, quindi una richiesta di password fallisce invece di restare in attesa. Un backend slurm usa solo sbatch, squeue e scancel, più scontrol sui cluster che forniscono scontrol, e richiede una remote_dir su uno storage condiviso dai nodi di calcolo. Un backend agent non richiede alcuna porta in ingresso, perché l'agent apre ogni connessione. Il nome local è riservato a questa macchina, e decision-calibrate gira solo su local. Addestrare su un server GPU, un cluster SLURM o una macchina dietro NAT percorre tutti e tre i tipi remoti con le loro chiavi.
Punteggi held-out
Ogni esecuzione valuta le proprie predizioni sugli item val e test rispetto alle etichette umane risolte. I nomi delle metriche portano la partizione, come in val_macro_f1 o test_f1. Un item con un'etichetta e senza predizione conta come sbagliato, quindi escludere gli item difficili non può alzare il punteggio di un trainer. <split>_coverage riporta la quota di item che hanno ricevuto una predizione.
Il punteggio principale compare nella colonna Held-out score della tabella Runs, con la partizione e la metrica nel tooltip. Il punteggio principale è la metrica principale del primo schema sulla prima tra val e test che ha item. Quando un trainer ha scelto il miglior checkpoint in base al punteggio val, Potato prova prima test, perché il trainer ha già visto il punteggio val. I trainer di fine-tuning che tengono l'epoca migliore, per esempio hf-text-classification, torchvision-detect e llm-sft, prendono il punteggio principale da test. sklearn-text, setfit, rdkit-property, i trainer di modelli decisionali e i bridge di inferenza non scelgono nulla su val, e un'esecuzione di uno di quei trainer prende il punteggio principale da val ogni volta che val ha item. Un'esecuzione senza item val o test viene mostrata come "not scored".
La metrica principale dipende dal tipo di annotazione dello schema, come mostra la tabella seguente per i tipi più comuni:
| Tipo di annotazione | Metrica principale |
|---|---|
radio, select, likert | macro-F1 (anche accuratezza ed errore assoluto medio per le etichette likert numeriche) |
multiselect | micro-F1 (anche macro-F1 e corrispondenza esatta) |
span | F1 sugli span che coincidono per inizio, fine ed etichetta |
text | F1 sui token (anche corrispondenza esatta) |
pairwise in modalità binary | accuratezza sugli item non risposti come parità |
ranking | tau di Kendall |
image_annotation, microscopy, geo_annotation | mAP COCO a IoU 0.5 (map_50), con map_50_95 registrata anch'essa |
audio_annotation | F1 sui segmenti con la stessa etichetta a IoU 0.5 o superiore |
speech_transcript | word_accuracy, 1 meno il tasso di errore sulle parole |
volume_annotation | mean_dice |
L'F1 sui token accredita una risposta che usa le parole giuste nell'ordine sbagliato, quindi leggi l'F1 sui token insieme alla corrispondenza esatta. La metrica principale del rilevamento usa IoU 0.5 e non la media da 0.5 a 0.95, perché i box di due annotatori per uno stesso oggetto raramente si sovrappongono a IoU 0.9. La tabella upstream dei punteggi held-out elenca le metriche di ogni tipo di annotazione.
Write-back
Dopo un'esecuzione riuscita, Potato salva le predizioni dell'esecuzione e scrive le predizioni che superano quattro controlli nel campo predictions di ogni item, o nel campo indicato da writeback.field. I controlli si svolgono in quest'ordine, e il report del write-back dell'esecuzione conta ogni esclusione:
- Gli item della partizione train non vengono mai pre-etichettati. Il controllo copre la partizione train di ogni esecuzione ancora nel registro, e una pre-etichetta lasciata su un item da un'esecuzione precedente viene tolta quando un'esecuzione successiva si addestra su quell'item.
- Vengono pubblicati solo gli schemi in
writeback.schemas. L'elenco è vuoto per impostazione predefinita, quindi attivare l'addestramento non cambia nulla per gli annotatori. - Le coppie rifiutate vengono saltate. Una coppia item-schema con un verdetto
rejectnella revisione del modello non viene più mostrata. - Si applica la soglia di confidenza. Una predizione sotto
min_confidenceviene salvata e non pubblicata.
Il write-back non modifica mai un'etichetta umana, perché le predizioni vanno nei dati dell'item mentre le annotazioni stanno nello stato utente di ciascun annotatore. Una pre-etichetta compare come risposta precompilata che l'annotatore può modificare, per esempio una scelta come opzione selezionata e una risposta a testo libero nella casella di testo dello schema, e non serve alcun blocco pre_annotation. La pre-etichetta diventa la risposta dell'annotatore solo quando l'annotatore la modifica o passa oltre. Una pre-etichetta che nessuno ha modificato né superato non diventa quindi mai un'etichetta di addestramento. Una coppia annotatore-item che ai_support.holdout colloca nel gruppo di confronto senza assistenza dello studio non mostra alcuna pre-etichetta, e i dati dell'item inviati per quella coppia escludono sia writeback.field sia pre_annotation.field. Il report del write-back è il campo writeback di GET /admin/training/api/status, e il summary del report spiega perché un'esecuzione non ha pubblicato nulla.
Potato tiene una predizione per item e schema, e la predizione di un'esecuzione più recente sostituisce quella di un'esecuzione più vecchia. Quando la predizione più recente è salvata ma non mostrata, perché è sotto min_confidence, vuota o rifiutata, la pre-etichetta dell'esecuzione più vecchia viene tolta subito dall'item, e il report del write-back conta l'item in n_superseded_cleared. Le pre-etichette fornite con i dati restano intatte. All'avvio le predizioni salvate per gli schemi in writeback.schemas vengono riscritte nei dati degli item con gli stessi quattro controlli, quindi le pre-etichette sopravvivono a un riavvio. Per ritirare le pre-etichette di un'esecuzione, invia DELETE /admin/training/api/runs/<run_id>/predictions. La richiesta rimuove le predizioni salvate e toglie le pre-etichette dagli item.
Le correzioni e gli item fissati si addestrano sempre
Due tipi di item vanno nella partizione train di ogni esecuzione successiva, qualunque sia il posto dell'item nella partizione stabile:
- Gli item corretti da un revisore. Un verdetto
correctnella revisione del modello significa che una persona ha corretto la risposta del modello. Le correzioni vengono dagli item su cui il modello era peggiore, quindi un item corretto invalotestmisurerebbe il modello su un campione dei suoi stessi errori. I verdettiaccepterejectlasciano un item dove si trovava. - Gli item fissati. Train on these accanto a uno slice nella pagina Catalog fissa gli item che lo slice individua, per esempio lo slice predefinito
model-found-nothing. Un item fissato si addestra una volta che qualcuno lo ha etichettato.
Un'esecuzione che ha spostato item esclusi dall'addestramento in train registra un avviso con il conteggio. Il punteggio held-out dell'esecuzione viene allora calcolato senza quegli item e non è direttamente confrontabile con il punteggio di un'esecuzione precedente. I conteggi si trovano in stats.forced_train nel manifest.json dei dati di addestramento.
Salvare una partizione come versione del dataset
Keep this split as a dataset nella pagina di un'esecuzione salva gli item val, test o train dell'esecuzione con le loro etichette umane concordate come nuova versione di un dataset. Una versione di un dataset non cambia più in seguito, quindi modelli e prompt LLM successivi possono essere confrontati esattamente su quegli item. La funzione richiede datasets.enabled: true. Ogni versione salvata contiene una sola partizione e riparte da zero invece di aggiungersi all'ultima versione del dataset. Gli item val dell'esecuzione 2 aggiunti a quelli dell'esecuzione 1 includerebbero altrimenti item su cui l'esecuzione 2 si è addestrata. Gli inputs di ogni esempio escludono il campo delle pre-etichette, quindi una valutazione non può leggere la risposta del modello.
Da dove viene una pre-etichetta
GET /admin/model-review include provenance per ogni item della coda di revisione la cui pre-etichetta è stata scritta da un'esecuzione di addestramento. Per ogni schema, la voce indica l'id dell'esecuzione, il trainer e il punteggio held-out dell'esecuzione. Le pre-etichette fornite con i dati non hanno una voce.
Dove vengono archiviate le esecuzioni
Ogni esecuzione ha una directory in <task_dir>/<output_annotation_dir>/training/runs/<run_id>/:
| Percorso | Contenuto |
|---|---|
bundle/ | I dati di addestramento: train.jsonl, val.jsonl, test.jsonl, unlabeled.jsonl con include_unlabeled, labels.json, manifest.json e media/. |
artifacts/ | model_card.json, predictions.jsonl e il modello, per esempio model.pkl per sklearn-text o una directory model/ per i trainer transformer. |
spec.json | Ciò che è stato chiesto all'esecuzione. |
events.jsonl, stdout.log, stderr.log | Gli eventi di avanzamento e l'output dell'esecuzione. |
agent.log | L'output proprio dell'agent remoto, sui backend ssh. |
bundle.tar.gz | I dati di addestramento come li ha scaricati l'agent, media inclusi, sui backend remoti. |
Il registro delle esecuzioni risiede nel database del progetto, <task_dir>/project.sqlite, e registra le esecuzioni, la partizione di ogni item per esecuzione, gli item fissati per l'addestramento, le predizioni salvate, i token degli agent e i push su Hugging Face Hub. retain_runs pota il registro e non pota mai un'esecuzione le cui predizioni sono ancora archiviate, così ogni pre-etichetta può essere ricondotta all'esecuzione che l'ha scritta. La potatura lascia su disco le directory delle esecuzioni.
Un'esecuzione LoRA salva solo l'adattatore, da pochi a qualche centinaio di megabyte, e carica il modello di base indicato da model_name quando l'esecuzione predice. Un fine-tuning completo salva l'intero modello. Imposta la variabile d'ambiente POTATO_MODEL_CACHE su una directory, e il processo di addestramento usa quella directory per HF_HOME, TRANSFORMERS_CACHE e SENTENCE_TRANSFORMERS_HOME, a meno che quelle variabili siano già impostate. Su una macchina isolata dalla rete, metti in anticipo in quella directory i modelli che i trainer indicano.
Route
La pagina Training e le route JSON della pagina stanno sotto /admin/training e richiedono l'accesso da amministratore. L'accesso da amministratore significa una sessione da amministratore o l'header X-API-Key. Le richieste POST e DELETE da un browser devono essere della stessa origine. La specifica OpenAPI di Potato marca tutte le 26 operazioni di addestramento con x-potato-requires-config: model_training.enabled: true:
| Route | Scopo |
|---|---|
GET /admin/training | La pagina Training, con il modulo di esecuzione, l'elenco delle esecuzioni e i trainer. |
GET /admin/training/runs/<run_id> | La pagina di una esecuzione, con stato, metriche, eventi e la partizione di ogni item. |
GET /admin/training/api/trainers | Ogni trainer, con i tipi, le modalità, la licenza e lo stato di installazione del trainer. |
GET /admin/training/api/schemas | Gli schemi dello studio, il tipo di ciascuno e i trainer adatti a ciascuno. |
GET /admin/training/api/status | L'esecuzione corrente o l'ultima, con stato, avanzamento, metriche, avvisi, skip_reason, writeback e queue. |
GET /admin/training/api/runs | Storico delle esecuzioni. ?limit= vale 50 per impostazione predefinita, con un massimo di 500. |
POST /admin/training/api/runs | Avvia un'esecuzione. 200 quando l'esecuzione parte, e 202 con queued: true e position quando l'esecuzione attende. |
GET /admin/training/api/runs/<run_id> | Il record di una esecuzione, più review, la precisione delle predizioni dell'esecuzione rispetto ai verdetti di revisione. |
GET /admin/training/api/runs/<run_id>/events | Il log degli eventi dell'esecuzione. ?limit= vale 200 per impostazione predefinita. |
POST /admin/training/api/runs/<run_id>/cancel | Annulla l'esecuzione in corso o una in attesa. 400 per qualsiasi altro id di esecuzione. |
DELETE /admin/training/api/runs/<run_id>/predictions | Ritira le predizioni salvate e le pre-etichette dell'esecuzione. |
POST /admin/training/api/runs/<run_id>/push-to-hub | Pubblica il modello dell'esecuzione su Hugging Face Hub. Vedi Pubblicazione su Hugging Face Hub. |
POST /admin/training/api/runs/<run_id>/pin-split | Salva una partizione come versione del dataset, con il corpo {"dataset": name, "split": "val"}. |
GET /admin/training/api/backends | I backend configurati. |
POST /admin/training/api/backends/<name>/check | Verifica un backend, come fa potato training check. |
GET /admin/training/api/pinned | Gli item fissati, raggruppati per motivo. |
POST /admin/training/api/pinned | Fissa degli item a train, con {"slice": name} o {"instance_ids": [...]}. |
DELETE /admin/training/api/pinned | Rimuove il fissaggio degli instance_ids elencati, o di ogni item fissato quando il corpo non ne elenca. |
Una richiesta di esecuzione accetta trainer, schemas (un elenco o un solo nome), params, backend, accept_licence e queue. Ogni trainer adatta solo il primo schema indicato. La richiesta seguente avvia un'esecuzione sklearn-text sullo schema sentiment dell'esempio:
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs \
-d '{"trainer": "sklearn-text", "schemas": ["sentiment"]}'Un avvio rifiutato indica il motivo in error:
| Stato | Quando |
|---|---|
400 | Nessun trainer o nessuno schema nel corpo, un trainer o uno schema sconosciuto, uno schema che il trainer non può imparare, un trainer che il progetto non può eseguire, oppure un trainer la cui licenza richiede conferma, con needs_licence_ack: true, finché la richiesta non imposta accept_licence: true |
409 | Un parametro che il trainer non accetta o di tipo o intervallo sbagliato, un backend sconosciuto, decision-calibrate su un backend diverso da local, oppure un'esecuzione già in corso con "queue": false |
429 | queue_max esecuzioni già in attesa |
Protocollo degli agent
model_training.enabled registra anche le route che un agent di addestramento chiama, sotto /api/training. Un agent invia il proprio token come Authorization: Bearer <token>, e un token mancante o non valido ottiene 401. La registrazione di un backend richiede invece la chiave API dell'amministratore. potato/training/protocol.py descrive il protocollo per chi scrive un nuovo agent, e potato/training/agent.py è l'implementazione di riferimento:
| Route | Scopo |
|---|---|
POST /api/training/backends/register | Emette un token dell'agent per il nome di un backend, con X-API-Key. potato training register chiama questa route. |
POST /api/training/backends/<name>/heartbeat | Un agent inattivo segnala di essere vivo. 403 per un token emesso per un altro backend. |
GET /api/training/jobs/next?wait=30 | Long poll. 200 con un job, oppure 204 quando nessun job arriva entro wait secondi. |
GET /api/training/jobs/<run_id> | Il job, la specifica del job e se il job è stato annullato. |
GET /api/training/jobs/<run_id>/bundle | I dati di addestramento come tar.gz, media inclusi. La route risponde alle richieste Range, quindi un agent riprende un download interrotto, fino a cinque tentativi. 410 quando il bundle non esiste più. |
POST /api/training/jobs/<run_id>/progress | Eventi di avanzamento. Un annullamento torna nella risposta. |
POST /api/training/jobs/<run_id>/predictions | predictions.jsonl. 413 oltre max_predictions_mb. |
POST /api/training/jobs/<run_id>/complete | Codice di uscita ed eventi finali. |
QLoRA
llm-sft, llm-dpo, hf-text-classification, vlm-sft e reward-model accettano lora: {quantize: 4bit}, l'impostazione di QLoRA (Dettmers et al., 2023). Il modello di base viene caricato con pesi NF4 a 4 bit e doppia quantizzazione, e sopra si addestra un adattatore LoRA in bf16 dove la GPU supporta bf16. quantize: 8bit è l'opzione intermedia, e le predizioni caricano il modello di base nello stesso modo.
model_training:
trainer_params:
llm-sft:
model_name: Qwen/Qwen2.5-7B-Instruct
lora: {quantize: 4bit}A 4 bit i pesi di base occupano un quarto della memoria che gli stessi pesi occupano in bf16, e a questa si sommano attivazioni, adattatore e stato dell'ottimizzatore. Potato non ha ancora misurato la memoria di un'esecuzione QLoRA su una GPU, quindi pianifica a partire dalla riga "Peak GPU memory" dell'esecuzione stessa. Ogni esecuzione transformer registra quella riga alla fine. QLoRA richiede una GPU CUDA e una build di bitsandbytes per la CUDA di quella macchina. L'esecuzione controlla entrambe prima di caricare il modello, quantizzando alcuni numeri sulla GPU, e quando le due versioni non corrispondono, l'errore indica entrambe le versioni. Il tutorial sul fine-tuning di LLM mette QLoRA al lavoro su esecuzioni SFT e DPO.
Pubblicazione su Hugging Face Hub
Un'esecuzione riuscita il cui modello si trova sul server Potato ha Publish to the Hugging Face Hub nella propria pagina. Il push carica il modello e un README.md con la model card scritta a partire dall'esecuzione, che indica il trainer, il modello di base e l'adattatore, gli schemi e le etichette, le dimensioni delle partizioni, il punteggio held-out e la partizione su cui il punteggio è stato misurato, più gli id dell'esecuzione e del bundle. La card di un'esecuzione dp ha anche una riga "Differential privacy" con l'epsilon speso rispetto all'obiettivo, il delta e la partizione train che la garanzia copre. La riga omette l'obiettivo o il delta quando l'esecuzione non ha registrato il valore.
Il caricamento è un elenco fisso di file e non l'intera directory artifacts/. L'elenco contiene i file dei pesi, per esempio .safetensors, .bin, .pt e .pkl, i file di configurazione e del tokenizer nella directory model/ salvata, model_card.json con i percorsi locali sostituiti da nomi di file, e calibration.json. Le risposte del modello sugli item del progetto (predictions.jsonl, e raw_answers.jsonl per i modelli decisionali) restano sul server. Restano fuori anche i checkpoint, lo stato dell'ottimizzatore, le copie dei dati di addestramento che alcuni trainer creano (yolo_data/, wev_data/, laya_data/) e qualsiasi collegamento simbolico che punti fuori da artifacts/.
Il modulo protegge da un push accidentale o pubblico in diversi modi:
- Digiti due volte il nome del repository, e il push procede solo se i due nomi coincidono.
- Private è selezionato per impostazione predefinita. Finché Private è selezionato, Potato non fa push su un repository pubblico esistente, e l'API risponde
409. - Il modulo indica una variabile d'ambiente sul server,
HF_TOKENper impostazione predefinita, che contiene un token di scrittura di Hugging Face. Il token stesso non viene mai digitato nella pagina. Il nome della variabile deve contenereTOKENo iniziare conHF_, e il valore deve iniziare conhf_, così il valore di nessun'altra variabile può raggiungere l'Hub. - Quando l'Hub non sa dire se il repository esiste, non viene inviato nulla, e un repository creato dal push viene cancellato di nuovo se il caricamento poi fallisce.
- La licenza della model card è l'id di licenza dell'Hub che indichi, come
apache-2.0. Senza indicazione, la card dice che si applica la licenza del modello di base. Un trainer la cui licenza richiede conferma, comeultralytics-detect(AGPL-3.0), richiede la stessa conferma per il push. - Un modello lasciato su un host remoto con
fetch_artifacts: false, o addestrato su un backend agent, non può essere pubblicato dal server, e l'errore indica dove si trova il modello.
Ogni push è un commit. La pagina dell'esecuzione elenca ogni push con repository, visibilità e commit, e il registro annota chi ha fatto il push. Tramite l'API, il corpo di POST /admin/training/api/runs/<run_id>/push-to-hub accetta repo_id, confirm_repo_id, private (predefinito true), token_env (predefinito HF_TOKEN), licence e accept_licence. La route restituisce 201 con il commit, 400 per un nome non coincidente, una variabile del token mancante, nessun file del modello o una licenza non confermata, e 502 quando l'Hub rifiuta.
Risoluzione dei problemi
Le voci seguenti coprono gli errori più probabili alla prima impostazione. L'elenco upstream di risoluzione dei problemi copre driver GPU, build CUDA e i messaggi specifici dei trainer.
/admin/trainingrestituisce 404.model_training.enablednon ètrue, e Potato registra le route solo quando la chiave ètrue.- "Only N items in the train split". Annota più item, oppure abbassa
min_instancesneiparamsdell'esecuzione. La partizione train contiene per impostazione predefinita il 70% degli item etichettati. - "Schema 'x' has 1 distinct label(s) in the data". Un classificatore richiede almeno due etichette in uso.
- "No resolved annotations to train on". Lo schema indicato nell'esecuzione è diverso da quello che si sta annotando, oppure nessuno ha ancora annotato nulla.
- L'esecuzione non ha pubblicato pre-etichette. Leggi il report
writebackinGET /admin/training/api/status. "No predictions were published: write-back is not enabled for any schema" significa chewriteback.schemasè vuoto, e i conteggi delle esclusioni mostrano quante predizioni ha rimosso ogni controllo. <trainer> does not take <name>. Un parametro nell'esecuzione o sottotrainer_paramsè scritto male oppure appartiene a un altro trainer. Il messaggio elenca i nomi che il trainer accetta.- L'esecuzione è stata uccisa dopo che la macchina ha esaurito la memoria. Il processo è uscito con SIGKILL, di solito per l'out-of-memory killer. Usa un modello più piccolo o meno item, oppure imposta
max_ram_mbin modo che l'esecuzione fallisca entro il proprio limite. - "Stopped: the run took longer than model_training.max_wall_seconds". L'esecuzione ha raggiunto il limite di tempo. Alza
max_wall_seconds, oppure addestra su meno item. - "The GPU ran out of memory". Abbassa
batch_sizee alzagradient_accumulationper mantenere il batch effettivo, impostalora: trueolora: {quantize: 4bit}, oppure perllm-sftimpostagradient_checkpointing: trueo scegli un modello più piccolo. - "ssh to host failed: Permission denied". Potato esegue
sshconBatchMode=yes, quindissh <host> truedeve riuscire dall'account del server senza alcuna richiesta. Una chiave con passphrase funziona quandossh-agenttiene la chiave. - Un'esecuzione su un backend agent resta in coda. Nessun agent con quel nome di backend sta interrogando il server. Avvia un agent con
potato training agent --backend <name>e controlla il token con Check nella pagina Training.
Ulteriori letture
- Addestramento di modelli sulle tue annotazioni: il ciclo di addestramento, la pagina Training e un avvio rapido.
- Trainer: ogni trainer, gli schemi da cui ciascuno impara e i comandi di installazione.
- Addestrare su un server GPU, un cluster SLURM o una macchina dietro NAT: backend ssh, SLURM e agent passo per passo.
- Il modello nel ciclo: write-back, revisione,
auto_retraine versioni del dataset in un unico studio. - Apprendimento attivo: ordinare gli item in base all'incertezza del modello.
- Individuare le pre-etichette approvate senza lettura: controllare se gli annotatori accettano le pre-etichette senza leggerle.
- Riferimento upstream: le tabelle complete dei parametri di ogni trainer.
Riferimenti
- Dawid, A. P., and Skene, A. M. (1979). Maximum Likelihood Estimation of Observer Error-Rates Using the EM Algorithm. Applied Statistics, 28(1). https://doi.org/10.2307/2346806
- Dettmers, T., Pagnoni, A., Holtzman, A., and Zettlemoyer, L. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. Advances in Neural Information Processing Systems 36 (NeurIPS 2023). https://proceedings.neurips.cc/paper_files/paper/2023/hash/1feb87871436031bdc0f2beaa62a049b-Abstract-Conference.html