1. Separare il programma, i suoi parametri e il monitoraggio commerciale
Il codice descrive il comportamento del programma. La configurazione specifica il carico: modello, dati, batch, precisione e destinazione. I secret danno accesso alle risorse necessarie. Mantieni questi elementi distinti per cambiare un tentativo senza riscrivere il codice né copiare un token in un file condiviso.
Il riferimento dell'ordine Kernodeck permette di ritrovare il contesto del noleggio nel tuo account. L'identificatore del tentativo distingue le esecuzioni del tuo programma durante quel periodo. Associali nelle tue note se ti è utile, ma non chiedere al tuo script di dedurre lo stato del calcolo dallo stato del pagamento.
Prendiamo un progetto di classificazione di documenti che deve essere avviato più volte sullo stesso campione. Il contratto del programma descrive il file di input, i parametri ammessi, la cartella di output e il modo di rendere gli errori. La guida sui dati specifica la convalida del contenuto; qui organizziamo l'interfaccia che collega queste fasi.
2. Scrivere un contratto di input esplicito e versionato
Documenta i campi obbligatori e i valori accettati. Evita i valori predefiniti silenziosi per una decisione che cambia il risultato, come il modello o il dispositivo. Un numero di schema distingue la forma della configurazione dalla versione del codice; non sostituisce quest'ultima.
In questo esempio didattico, il file JSON contiene uno schema, un percorso di input, un batch e il dispositivo richiesto. I percorsi relativi si leggono a partire dalla cartella di configurazione. Questa regola scelta per l'esempio evita di dipendere dalla directory da cui un collega lancia il comando.
Leggere JSON valido verifica solo la sua sintassi. Il tuo programma deve poi controllare i tipi, i campi e i vincoli del progetto. In caso di errore, deve fermarsi prima del caricamento di una risorsa costosa, con un messaggio che nomina il parametro da correggere.
{
"schema_version": 1,
"input": "../data/pilote.jsonl",
"batch_size": 4,
"device": "cuda"
}3. Preparare un punto di ingresso che rifiuta gli errori semplici
argparse permette di dichiarare opzioni e produrre un aiuto per il tuo comando. L'esempio seguente costituisce unicamente un precontrollo: legge la configurazione, verifica i suoi campi e individua una cartella di output già utilizzata. Non carica né modello né dati in memoria e non verifica la disponibilità della GPU.
Salva questo codice didattico in prepare_run.py se desideri adattarlo. È proposto senza esecuzione attestata. Aggiungi poi i tuoi controlli di dominio nell'applicazione, invece di considerare il messaggio finale come un risultato di calcolo. Il dispositivo cuda resta una richiesta; PyTorch usa questo nome anche con ROCm.
Il rifiuto di una directory di output esistente è qui una convenzione di protezione contro la commistione dei tentativi. Un vero comando di ripresa deve ricevere un'opzione e controlli distinti. Non trasformare un nuovo avvio in una ripresa implicita solo perché sono presenti dei file.
import argparse
import json
from pathlib import Path
parser = argparse.ArgumentParser(description="Valida un avvio del progetto")
parser.add_argument("--config", type=Path, required=True)
parser.add_argument("--run-dir", type=Path, required=True)
args = parser.parse_args()
try:
config_path = args.config.resolve()
config = json.loads(config_path.read_text(encoding="utf-8"))
except (OSError, UnicodeError, json.JSONDecodeError) as exc:
parser.error(f"Configurazione illeggibile: {exc}")
expected = {"schema_version", "input", "batch_size", "device"}
if not isinstance(config, dict) or set(config) != expected:
parser.error("Campi attesi: schema_version, input, batch_size, device")
if type(config["schema_version"]) is not int or config["schema_version"] != 1:
parser.error("schema_version deve valere 1")
if type(config["batch_size"]) is not int or config["batch_size"] < 1:
parser.error("batch_size deve essere un intero positivo")
if config["device"] not in ("cpu", "cuda"):
parser.error("device deve valere cpu o cuda")
if not isinstance(config["input"], str) or not config["input"]:
parser.error("input deve essere un percorso non vuoto")
input_path = (config_path.parent / config["input"]).resolve()
run_dir = args.run_dir.resolve()
if not input_path.is_file():
parser.error("File di input assente")
if run_dir.exists():
parser.error("Scegli una nuova cartella di output")
print(json.dumps({
"status": "configuration_validated",
"input": str(input_path),
"run_dir": str(run_dir),
"device_requested": config["device"],
"batch_size": config["batch_size"]
}, ensure_ascii=False))python prepare_run.py --config config/pilote.json --run-dir runs/pilote-0014. Dare un'identità alle esecuzioni e ai loro risultati
Associa ogni avvio a un identificatore breve, univoco all'interno della tua campagna. Annota la revisione del codice, lo schema e i parametri effettivamente utilizzati, poi il riferimento dei dati e del modello. Conserva questi valori insieme agli output, in modo che un risultato non dipenda da un file di configurazione modificato in seguito.
Per confrontare due dimensioni di batch, crea due prove e due directory. Mantieni lo stesso campione e identifica la differenza voluta. I nomi pilote-001 e pilote-002 da soli non spiegano cosa è cambiato: il manifest collega il nome ai parametri.
Riserva un formato di riepilogo leggibile dai tuoi strumenti. Può distinguere elementi ricevuti, riusciti, rifiutati e ancora da elaborare. Scegli una regola di successo completa e non segnare una prova come conclusa già alla scrittura del primo risultato. Il codice di ritorno del programma deve restare coerente con questa conclusione.
Scorri la tabella per leggere tutte le colonne.| File o stato | Ruolo | Controllo atteso |
|---|---|---|
| manifest.json | Identità del codice, dei dati e dei parametri | Valori effettivamente utilizzati, senza segreti. |
| results.jsonl | Un output per ogni elemento accettato | Identificatori noti e formato conforme. |
| errors.jsonl | Elementi rifiutati e motivo utile | Nessuna sparizione silenziosa né contenuto sensibile inutile. |
| summary.json | Conclusione della prova e contatori | Somma coerente, file riletti prima dello stato finale. |
5. Esporre eventi utili ai tuoi strumenti
Rendi visibili alcune transizioni: configurazione accettata, dati accessibili, modello caricato, primo output scritto e fine dell'elaborazione. Una traccia deve permettere di rispondere a «a che punto è questo avvio?» senza copiare documenti o prompt. Associa la fase e l'identificatore della prova al messaggio.
Il modulo logging di Python permette di organizzare i messaggi per livello e destinazione. Scegli poi una tua convenzione di eventi e documentala. Un'applicazione che scrive un errore e poi termina con un successo rende l'automazione ingannevole; al contrario, ogni avviso non significa che il risultato sia inutilizzabile.
Non confondere evento emesso e risultato duraturo: un messaggio «salvataggio iniziato» non prova che un file sia stato riletto. Per un'esecuzione lunga, la guida dedicata spiega il legame tra processo e sessione. La tua interfaccia deve soprattutto conservare una conclusione accessibile dopo la fine della connessione interattiva.
6. Definire il fallimento, la ripresa e la verifica finale
Classifica gli errori utili: configurazione non valida, risorsa assente, errore di calcolo e risultato non conforme. Indica per ciascuno una prossima azione. Non installare un riavvio automatico senza decidere quali effetti possono essere ripetuti: riscrivere un output già accettato e riprendere un checkpoint richiedono regole diverse.
La tua procedura finale spiega come avviare, osservare, arrestare, riprendere ed esportare. Per un'elaborazione di documenti, conserva la lista degli identificativi completati e di quelli da rielaborare. Per un addestramento, usa un protocollo che verifica gli stati salvati in un nuovo processo. Una cartella non vuota non è prova di una ripresa corretta.
Infine, controlla il progetto da una nuova invocazione, con una configurazione nota e una destinazione distinta. Verifica i rifiuti attesi, poi un piccolo percorso completo. Il precontrollo di questa pagina non copre né accessi concorrenti, né esposizione pubblica di un servizio, né permessi di archiviazione: questi argomenti richiedono una progettazione a sé.