Configuración y rutas del entrenamiento de modelos
Todas las claves del bloque model_training, cómo se encolan, puntúan y almacenan las ejecuciones, y las rutas de administrador y de agente, con soluciones a los errores frecuentes.
Novedad de la v2.14.0
Esta página es la referencia del bloque model_training de una configuración de Potato y de lo que ocurre con una ejecución después de iniciarla. Está escrita para quien dirige un estudio y quiere limitar las ejecuciones, enviarlas a otra máquina, mostrar a los anotadores las predicciones de un modelo o iniciar el entrenamiento desde un script. Cada clave, valor predeterminado, ruta y mensaje de abajo se comprobó con el código de Potato. Para una primera ejecución, empieza por Entrena tu primer modelo. Los entrenadores y sus parámetros están listados en Entrenadores.
Una configuración completa
La configuración de abajo entrena un clasificador de sentimiento sobre reseñas de productos. auto_retrain vuelve a ajustar sklearn-text tras cada 25 anotaciones nuevas. Con las características TF-IDF predeterminadas, sklearn-text entrena en la CPU y no necesita nada más allá de una instalación básica de Potato. Las ejecuciones automáticas frecuentes cuestan por tanto poco. La escritura de vuelta muestra a los anotadores toda predicción con una confianza de al menos 0,8. Con include_unlabeled, una ejecución también predice sobre las reseñas que nadie ha etiquetado todavía. Los valores predeterminados de hf-text-classification y el backend gpu-server atienden las ejecuciones que se inician a mano desde la página 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: 4000Mantén fijo split_seed durante toda la vida del estudio. Una semilla nueva reasigna todos los ítems, de modo que los ítems que estaban reservados acaban en el entrenamiento y las puntuaciones posteriores dejan de ser comparables con las anteriores. El umbral min_confidence de 0,8 es un punto de partida, y el umbral adecuado depende de la primera puntuación sobre ítems reservados. Activa include_unlabeled cuando esa puntuación respalde mostrar preetiquetas, porque las preetiquetas anclan a los anotadores a la respuesta del modelo.
Claves de model_training
Todas las claves van bajo model_training:
| Clave | Predeterminado | Significado |
|---|---|---|
enabled | false | Registra la página Training, las rutas bajo /admin/training y las rutas de agente bajo /api/training. Sin enabled: true las rutas no existen. |
retain_runs | 5 | Ejecuciones terminadas que se conservan en el registro de ejecuciones. Una ejecución más antigua sale del registro salvo que sus predicciones sigan almacenadas. Los directorios de las ejecuciones permanecen en disco. |
grace_seconds | 20 | Segundos que tiene una ejecución cancelada para salir antes de que Potato mate el proceso. 0 o más, y se envía con el trabajo a los backends de tipo ssh, slurm y agent. |
queue_max | 10 | Ejecuciones que pueden esperar detrás de la ejecución en curso. |
split_seed | 0 | Semilla para asignar los ítems a las particiones train, val y test. |
splits | {train: 0.7, val: 0.15, test: 0.15} | Fracciones de las particiones, normalizadas para que sumen 1. Los nombres son train, val y test, y train es obligatorio. |
aggregation | consensus | Cómo las etiquetas de varios anotadores sobre un ítem se convierten en una sola. consensus ajusta el modelo de Dawid-Skene cuando el estudio tiene más de un anotador y recurre al voto mayoritario si el ajuste falla. majority toma el voto mayoritario. |
max_wall_seconds | sin fijar | Límite de tiempo de una ejecución. Potato comprueba una ejecución local cada vez que esta informa de un evento, y una ejecución por ssh o por agente cada segundo. |
max_ram_mb | sin fijar | Límite de espacio de direcciones del proceso de entrenamiento, fijado con setrlimit. En una plataforma sin ese límite, la ejecución registra un aviso y continúa. |
device | auto | auto, cpu, cuda, cuda:N o mps. auto elige CUDA, luego Metal de Apple y luego la CPU. |
num_threads | sin fijar | Fija OMP_NUM_THREADS, MKL_NUM_THREADS y OPENBLAS_NUM_THREADS para la ejecución, salvo que el entorno ya fije esas variables. |
auto_retrain | desactivado | Reentrenamiento a medida que llegan anotaciones. Consulta auto_retrain. |
writeback | ninguno | Publicación de predicciones como preetiquetas. Consulta writeback. |
backend | local | El backend de las ejecuciones que no nombran otro. |
backends | ninguno | Backends ssh, slurm y agent con nombre. Consulta Backends. |
max_predictions_mb | 512 | El predictions.jsonl más grande que puede subir un agente remoto. |
trainer_params | ninguno | Valores predeterminados de parámetros, indexados por nombre de entrenador. |
tiling | enabled: auto | Corte de imágenes grandes en teselas para los entrenadores de detección y segmentación. Consulta tiling. |
Los params propios de una ejecución sustituyen a trainer_params, que sustituyen a los valores predeterminados del entrenador. Un nombre de parámetro que el entrenador no admite se rechaza al arrancar el servidor cuando el nombre está bajo trainer_params, y en caso contrario al iniciar la ejecución. Entrenadores da el orden con un ejemplo.
auto_retrain
El reentrenamiento automático busca una ejecución nueva tras cada guardado de anotación:
| Clave | Predeterminado | Significado |
|---|---|---|
enabled | false | Activa la comprobación. |
trainer | ninguno | Nombre del entrenador. Obligatorio. |
schemas | ninguno | Esquemas que entrenar. Obligatorio. |
min_interval_s | 600 | Segundos desde que terminó la última ejecución antes de que empiece otra. |
update_frequency | 25 | Anotaciones nuevas desde la última ejecución automática antes de que empiece otra. |
params | {} | Parámetros del entrenador, como en los params de una ejecución por API. |
backend | model_training.backend | Backend de las ejecuciones automáticas. |
accept_licence | false | Confirma la licencia de un entrenador que pide confirmación (ultralytics-detect, ultralytics-segment, layoutlmv3). Sin la confirmación, se omiten las ejecuciones automáticas de esos entrenadores. |
Cuando una comprobación decide no lanzar una ejecución, el motivo aparece en el campo skip_reason de GET /admin/training/api/status, por ejemplo «waiting for 3 more annotation(s)» o «a run is already in progress». Las ejecuciones automáticas nunca entran en la cola de ejecuciones. La siguiente anotación guardada después de que la cola se vacíe vuelve a comprobar, con más anotaciones con las que entrenar. Potato mantiene los recuentos de anotaciones en memoria, así que tras un reinicio un proyecto que ya ha entrenado cuenta las anotaciones nuevas desde el reinicio.
writeback
La escritura de vuelta decide qué predicciones ven los anotadores:
| Clave | Predeterminado | Significado |
|---|---|---|
schemas | [] | Esquemas cuyas predicciones ven los anotadores. Una lista vacía no muestra ninguna. |
min_confidence | 0.0 | Las predicciones por debajo del umbral se guardan y no se muestran. Una predicción sin confianza pasa. |
field | predictions | Campo del ítem en el que se escriben las preetiquetas. |
include_unlabeled | false | Predice también sobre ítems que nadie ha etiquetado y preetiqueta esos ítems. Sin include_unlabeled, una ejecución predice solo sobre los ítems val y test de la propia ejecución. |
tiling
Los entrenadores de detección y segmentación redimensionan cada imagen a unos pocos cientos de píxeles. A ese tamaño, los objetos de una imagen de portaobjetos completo o de una escena de satélite se pierden. Para un esquema image_annotation, microscopy o geo_annotation, Potato corta por eso cada imagen grande en teselas al construir los datos de entrenamiento de la ejecución. La partición de una imagen se decide antes de cortarla, así que las teselas de un mismo portaobjetos nunca caen en dos particiones. Las predicciones se proyectan de nuevo sobre la imagen completa, y las puntuaciones sobre ítems reservados se calculan sobre imágenes completas. El tutorial de visión cubre en la práctica los portaobjetos y los mapas.
| Clave | Predeterminado | Significado |
|---|---|---|
enabled | auto | auto tesela los formatos de portaobjetos (.svs, .ndpi, .mrxs, .scn y otros) y las imágenes cuyo lado mayor mide al menos auto_min_side. true tesela todas las imágenes, y false ninguna. |
auto_min_side | 4096 | Longitud del lado mayor, en píxeles, a partir de la cual auto empieza a teselar una imagen. |
tile_size | 1024 | Lado de una tesela, en los píxeles que ve el entrenador. |
overlap | 128 | Píxeles que comparten teselas vecinas, como máximo la mitad de tile_size. Mantén el solapamiento al menos tan grande como los objetos, o un objeto grande se encuentra en pedazos. |
downsample | 1 | Píxeles de resolución completa por píxel de tesela. |
mpp | ninguno | Micras por píxel de tesela. Sustituye a downsample en un portaobjetos que registra su resolución. |
background | 0.25 | Teselas vacías muestreadas por cada tesela con un objeto. Fija background: 0 para portaobjetos anotados solo en parte. |
max_predict_tiles | 2000 | Máximo de teselas predichas por imagen. Se conservan las teselas con más tejido. |
min_visible | 0.4 | Proporción de un objeto que debe quedar dentro de una tesela para que el objeto entrene allí. |
tissue_threshold | 0.05 | Proporción de una tesela de portaobjetos que debe ser tejido para que el modelo prediga sobre la tesela. |
Los portaobjetos se leen con openslide, que instala pip install "potato-annotation[wsi]", en la máquina que construye los datos de entrenamiento. Un backend remoto descarga las teselas y nunca el portaobjetos.
La cola de ejecuciones
Se ejecuta una sola ejecución a la vez. Una ejecución iniciada desde la página Training o desde la API mientras otra está en curso espera en lugar de ser rechazada. La solicitud de inicio devuelve 202 con queued: true y la position de la ejecución, y la tabla de ejecuciones muestra la ejecución como waiting #N con un botón Cancel run. Cuando termina la ejecución en curso, empieza la ejecución en espera más antigua.
Las ejecuciones en espera son registros del registro de ejecuciones, así que la cola sobrevive a un reinicio, y la primera ejecución en espera empieza cuando el servidor vuelve. Una ejecución que el servidor anterior tenía a medias se marca como interrupted en ese mismo momento. Los datos de entrenamiento de una ejecución en espera se construyen cuando la ejecución empieza, de modo que la ejecución entrena con las anotaciones presentes en ese momento. Un inicio que sería rechazado, como un inicio que nombra un esquema desconocido, se rechaza de inmediato y no cuando llega el turno de la ejecución. Una ejecución cuyo esquema o entrenador salió de la configuración mientras esperaba falla con invalid_when_dequeued, y empieza la siguiente ejecución.
Envía "queue": false en el cuerpo de la solicitud para recibir 409 en lugar de un lugar en la cola. Con queue_max ejecuciones ya en espera, un inicio nuevo recibe 429. GET /admin/training/api/status lista las ejecuciones en espera por orden bajo queue.
Comprobaciones antes de una ejecución
potato validate informa a la vez de todos los problemas del bloque model_training, y el servidor se niega a arrancar ante los mismos problemas:
potato validate config.yaml --strictLas comprobaciones cubren estos casos:
splitscon un nombre distinto detrain,valytest, una fracción menor que 0 o que no es un número, fracciones que suman 0 o ausencia detrain.- Una clave que
writebackoauto_retrainno tiene, una entrada dewriteback.schemasque no es un esquema o unmin_confidencefuera del rango de 0 a 1.accept_licensese informa como una errata deaccept_licence. - Un bloque
pre_annotationactivado cuyofielddifiere dewriteback.field. Bajo un bloque así no se mostraría ninguna preetiqueta de entrenamiento. - Con
auto_retrain.enabled, un entrenador o un esquema que no existe, un esquema que el entrenador no puede aprender, parámetros que el entrenador no admite o de tipo erróneo, unbackendque falta enbackendsodecision-calibrateen un backend distinto delocal. - Un parámetro bajo
trainer_paramsque el entrenador no admite o de tipo erróneo. Dentro dedp, la comprobación abarca también cada clave y el intervalo de la clave. - Un
grace_secondsinferior a 0 o que no sea un número, o unretain_runsosplit_seedinferior a 0 o que no sea un entero. - Bajo
backends, untypeausente o desconocido, una clave que el tipo no tiene, un backend ssh sinhost, un valor degpusdistinto deauto,noneo índices de GPU, un backend remoto llamadolocalo unmodel_training.backendque no está definido.
potato training check prueba un backend antes de que una ejecución lo use. Para local, el comando imprime el dispositivo que usaría una ejecución, por ejemplo local: this machine, Apple Metal (mps) en un Mac con Apple silicon. Para un backend ssh, el comando informa de la versión de Python, de cada GPU con su memoria libre, de la GPU que recibiría una ejecución y de los paquetes de entrenamiento que le faltan al intérprete remoto. El botón Check de la página Training ejecuta la misma prueba, y --json imprime el informe como JSON:
potato training check local config.yaml
potato training check gpu-server config.yamlUna ejecución iniciada desde la página Training o desde la API se vuelve a comprobar cuando la ejecución empieza. Los códigos de estado están listados en Rutas.
Backends
Una ejecución corre en un backend, y el menú Runs on de la página Training lista los backends configurados. model_training.backend fija el valor predeterminado, y una ejecución por API o auto_retrain puede nombrar otro backend con backend. Potato tiene cuatro tipos de backend:
| Tipo | Dónde corre el entrenador | Quién inicia el entrenador |
|---|---|---|
local | Esta máquina, en un subproceso. Siempre disponible y predeterminado. | Potato |
ssh | Otra máquina a la que Potato llega por ssh, como un servidor con GPU. | Potato, por ssh |
slurm | Un nodo de cómputo de un clúster, como trabajo por lotes. | Potato, por ssh al nodo de acceso y luego sbatch |
agent | Una máquina a la que Potato no puede llegar, como una estación de trabajo tras NAT. | Una persona, con potato training agent |
Un backend ssh usa autenticación por clave con BatchMode activado, así que una petición de contraseña falla en lugar de quedarse colgada. Un backend slurm usa solo sbatch, squeue y scancel, más scontrol en los clústeres que ofrecen scontrol, y necesita un remote_dir en un almacenamiento que compartan los nodos de cómputo. Un backend agent no necesita ningún puerto de entrada, porque el agente abre todas las conexiones. El nombre local está reservado para esta máquina, y decision-calibrate se ejecuta solo en local. Entrenar en un servidor con GPU, un clúster SLURM o una máquina tras NAT recorre los tres tipos remotos con sus claves.
Puntuaciones sobre ítems reservados
Cada ejecución puntúa las propias predicciones sobre los ítems val y test frente a las etiquetas humanas resueltas. Los nombres de las métricas llevan la partición, como en val_macro_f1 o test_f1. Un ítem con etiqueta y sin predicción cuenta como error, así que omitir los ítems difíciles no puede subir la puntuación de un entrenador. <split>_coverage informa de la proporción de ítems que recibieron una predicción.
La puntuación principal aparece en la columna Held-out score de la tabla de ejecuciones, con la partición y la métrica en la ayuda emergente. La puntuación principal es la métrica principal del primer esquema sobre la primera de val y test que tenga ítems. Cuando un entrenador eligió el mejor punto de control por la puntuación de val, Potato prueba primero test, porque el entrenador ya ha visto la puntuación de val. Los entrenadores de ajuste fino que conservan la mejor época, por ejemplo hf-text-classification, torchvision-detect y llm-sft, toman la puntuación principal de test. sklearn-text, setfit, rdkit-property, los entrenadores de modelos de decisión y los puentes de inferencia no eligen nada con val, y una ejecución de uno de esos entrenadores toma la puntuación principal de val siempre que val tenga ítems. Una ejecución sin ítems val ni test se muestra como «not scored».
La métrica principal depende del tipo de anotación del esquema, como muestra la tabla de abajo para los tipos habituales:
| Tipo de anotación | Métrica principal |
|---|---|
radio, select, likert | macro-F1 (también exactitud y error absoluto medio para etiquetas likert numéricas) |
multiselect | micro-F1 (también macro-F1 y coincidencia exacta) |
span | F1 sobre spans que coinciden en inicio, fin y etiqueta |
text | F1 de tokens (también coincidencia exacta) |
pairwise en modo binary | exactitud sobre ítems que no se respondieron como empate |
ranking | tau de Kendall |
image_annotation, microscopy, geo_annotation | mAP de COCO con IoU 0,5 (map_50), registrando también map_50_95 |
audio_annotation | F1 sobre segmentos con la misma etiqueta con IoU de 0,5 o más |
speech_transcript | word_accuracy, 1 menos la tasa de error de palabras |
volume_annotation | mean_dice |
El F1 de tokens da crédito a una respuesta que usa las palabras correctas en el orden equivocado, así que lee el F1 de tokens junto con la coincidencia exacta. La métrica principal de detección usa IoU 0,5 y no el promedio de 0,5 a 0,95, porque las cajas de dos anotadores para un mismo objeto rara vez se solapan con IoU 0,9. La tabla upstream de puntuaciones sobre ítems reservados lista las métricas de cada tipo de anotación.
Escritura de vuelta
Tras una ejecución correcta, Potato guarda las predicciones de la ejecución y escribe las que superan cuatro comprobaciones en el campo predictions de cada ítem, o en el campo que nombre writeback.field. Las comprobaciones se aplican en este orden, y el informe de escritura de vuelta de la ejecución cuenta cada omisión:
- Los ítems de la partición train nunca se preetiquetan. La comprobación abarca la partición train de toda ejecución que siga en el registro, y una preetiqueta que una ejecución anterior dejó en un ítem se retira cuando una ejecución posterior entrena con ese ítem.
- Solo se publican los esquemas de
writeback.schemas. La lista está vacía de forma predeterminada, así que activar el entrenamiento no cambia nada de lo que ven los anotadores. - Los pares rechazados se omiten. Un par de ítem y esquema con un veredicto
rejecten la revisión del modelo no vuelve a mostrarse. - Se aplica el umbral de confianza. Una predicción por debajo de
min_confidencese guarda y no se publica.
La escritura de vuelta nunca cambia una etiqueta humana, porque las predicciones van a los datos del ítem y las anotaciones viven en el estado de usuario de cada anotador. Una preetiqueta se muestra como una respuesta rellenada que el anotador puede editar, por ejemplo una opción como la opción seleccionada y una respuesta de texto libre en el cuadro de texto del esquema, y no hace falta ningún bloque pre_annotation. La preetiqueta se convierte en la respuesta del anotador solo cuando este la edita o pasa al siguiente ítem. Una preetiqueta que nadie ha editado ni dejado atrás nunca se convierte, por tanto, en una etiqueta de entrenamiento. Un par de anotador e ítem que ai_support.holdout coloca en el grupo de comparación sin asistencia del estudio no muestra ninguna preetiqueta, y los datos del ítem enviados para ese par omiten tanto el writeback.field como el pre_annotation.field. El informe de escritura de vuelta es el campo writeback de GET /admin/training/api/status, y el summary del informe dice por qué una ejecución no publicó nada.
Potato guarda una predicción por ítem y esquema, y la predicción de una ejecución más reciente sustituye a la de una ejecución más antigua. Cuando la predicción más reciente se guarda pero no se muestra, porque está por debajo de min_confidence, vacía o rechazada, la preetiqueta de la ejecución anterior se retira del ítem de inmediato, y el informe de escritura de vuelta cuenta el ítem en n_superseded_cleared. Las preetiquetas que vienen con los datos se dejan intactas. Al arrancar, las predicciones guardadas de los esquemas de writeback.schemas se escriben de vuelta en los datos de los ítems con las mismas cuatro comprobaciones, de modo que las preetiquetas sobreviven a un reinicio. Para retirar las preetiquetas de una ejecución, envía DELETE /admin/training/api/runs/<run_id>/predictions. La solicitud elimina las predicciones guardadas y retira las preetiquetas de los ítems.
Las correcciones y los ítems fijados siempre entrenan
Dos tipos de ítem van a la partición train de toda ejecución posterior, sea cual sea el lugar del ítem en la partición estable:
- Ítems que un revisor corrigió. Un veredicto
correcten la revisión del modelo significa que una persona arregló la respuesta del modelo. Las correcciones proceden de los ítems en los que el modelo fue peor, de modo que un ítem corregido envalotestpuntuaría el modelo sobre una muestra de sus propios errores. Los veredictosacceptyrejectdejan un ítem donde estaba. - Ítems fijados. Train on these, junto a una porción de la página Catalog, fija los ítems que la porción abarca, por ejemplo la porción integrada
model-found-nothing. Un ítem fijado entrena una vez que alguien lo ha etiquetado.
Una ejecución que movió ítems reservados a train registra un aviso con el recuento. La puntuación sobre ítems reservados de la ejecución se calcula entonces sin esos ítems y no es directamente comparable con la puntuación de una ejecución anterior. Los recuentos están en stats.forced_train del manifest.json de los datos de entrenamiento.
Guardar una partición como versión de un conjunto de datos
Keep this split as a dataset en la página de una ejecución guarda los ítems val, test o train de la ejecución con sus etiquetas humanas acordadas como una versión nueva de un conjunto de datos. La versión de un conjunto de datos no cambia después, de modo que modelos y prompts de LLM posteriores pueden compararse sobre exactamente esos ítems. La función necesita datasets.enabled: true. Cada versión guardada contiene una partición y empieza de cero en lugar de añadirse a la última versión del conjunto de datos. Los ítems val de la ejecución 2 añadidos a los de la ejecución 1 incluirían, de otro modo, ítems con los que entrenó la ejecución 2. Los inputs de cada ejemplo omiten el campo de preetiquetas, así que una evaluación no puede leer la respuesta del modelo.
De dónde vino una preetiqueta
GET /admin/model-review incluye provenance para cada ítem de la cola de revisión cuya preetiqueta escribió una ejecución de entrenamiento. Para cada esquema, la entrada da el id de la ejecución, el entrenador y la puntuación sobre ítems reservados de la ejecución. Las preetiquetas que vienen con los datos no tienen entrada.
Dónde se almacenan las ejecuciones
Cada ejecución tiene un directorio en <task_dir>/<output_annotation_dir>/training/runs/<run_id>/:
| Ruta | Contenido |
|---|---|
bundle/ | Los datos de entrenamiento: train.jsonl, val.jsonl, test.jsonl, unlabeled.jsonl con include_unlabeled, labels.json, manifest.json y media/. |
artifacts/ | model_card.json, predictions.jsonl y el modelo, por ejemplo model.pkl para sklearn-text o un directorio model/ para los entrenadores de transformers. |
spec.json | Lo que se le pidió hacer a la ejecución. |
events.jsonl, stdout.log, stderr.log | Los eventos de progreso y la salida de la ejecución. |
agent.log | La salida propia del agente remoto, en backends ssh. |
bundle.tar.gz | Los datos de entrenamiento tal como los descargó el agente, con los medios incluidos, en backends remotos. |
El registro de ejecuciones vive en la base de datos del proyecto, <task_dir>/project.sqlite, y guarda las ejecuciones, la partición de cada ítem por ejecución, los ítems fijados para entrenamiento, las predicciones almacenadas, los tokens de agente y las subidas a Hugging Face Hub. retain_runs poda el registro y nunca poda una ejecución cuyas predicciones sigan almacenadas, de modo que toda preetiqueta puede rastrearse hasta la ejecución que la escribió. La poda deja los directorios de las ejecuciones en disco.
Una ejecución LoRA guarda solo el adaptador, de unos pocos a unos cientos de megabytes, y carga el modelo base por model_name cuando la ejecución predice. Un ajuste fino completo guarda el modelo entero. Fija la variable de entorno POTATO_MODEL_CACHE a un directorio, y el proceso de entrenamiento usa ese directorio para HF_HOME, TRANSFORMERS_CACHE y SENTENCE_TRANSFORMERS_HOME salvo que esas variables ya estén fijadas. En una máquina aislada de la red, coloca de antemano en ese directorio los modelos que nombran los entrenadores.
Rutas
La página Training y sus rutas JSON están bajo /admin/training y requieren acceso de administrador. Acceso de administrador significa una sesión de administrador o la cabecera X-API-Key. Las solicitudes POST y DELETE desde un navegador deben ser del mismo origen. La especificación OpenAPI de Potato marca las 26 operaciones de entrenamiento con x-potato-requires-config: model_training.enabled: true:
| Ruta | Finalidad |
|---|---|
GET /admin/training | La página Training, con el formulario de ejecución, la lista de ejecuciones y los entrenadores. |
GET /admin/training/runs/<run_id> | La página de una ejecución, con estado, métricas, eventos y la partición de cada ítem. |
GET /admin/training/api/trainers | Todos los entrenadores, con los tipos, las modalidades, la licencia y el estado de instalación de cada uno. |
GET /admin/training/api/schemas | Los esquemas del estudio, el tipo de cada esquema y los entrenadores que encajan con cada uno. |
GET /admin/training/api/status | La ejecución actual o la última, con estado, progreso, métricas, avisos, skip_reason, writeback y queue. |
GET /admin/training/api/runs | Historial de ejecuciones. ?limit= es 50 por defecto, con un máximo de 500. |
POST /admin/training/api/runs | Inicia una ejecución. 200 cuando la ejecución empieza, y 202 con queued: true y position cuando la ejecución espera. |
GET /admin/training/api/runs/<run_id> | El registro de una ejecución, más review, la precisión de las predicciones de la ejecución según los veredictos de revisión. |
GET /admin/training/api/runs/<run_id>/events | El registro de eventos de la ejecución. ?limit= es 200 por defecto. |
POST /admin/training/api/runs/<run_id>/cancel | Cancela la ejecución en curso o una ejecución en espera. 400 para cualquier otro id de ejecución. |
DELETE /admin/training/api/runs/<run_id>/predictions | Retira las predicciones guardadas y las preetiquetas de la ejecución. |
POST /admin/training/api/runs/<run_id>/push-to-hub | Publica el modelo de la ejecución en Hugging Face Hub. Consulta Publicar en Hugging Face Hub. |
POST /admin/training/api/runs/<run_id>/pin-split | Guarda una partición como versión de un conjunto de datos, con el cuerpo {"dataset": name, "split": "val"}. |
GET /admin/training/api/backends | Los backends configurados. |
POST /admin/training/api/backends/<name>/check | Prueba un backend, como hace potato training check. |
GET /admin/training/api/pinned | Ítems fijados, agrupados por motivo. |
POST /admin/training/api/pinned | Fija ítems a train, con {"slice": name} o {"instance_ids": [...]}. |
DELETE /admin/training/api/pinned | Desfija los instance_ids listados, o todos los ítems fijados cuando el cuerpo no lista ninguno. |
Una solicitud de ejecución admite trainer, schemas (una lista o un nombre), params, backend, accept_licence y queue. Cada entrenador ajusta solo el primer esquema nombrado. La solicitud de abajo inicia una ejecución de sklearn-text sobre el esquema sentiment del ejemplo:
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 inicio rechazado da el motivo en error:
| Estado | Cuándo |
|---|---|
400 | Falta el entrenador o el esquema en el cuerpo, un entrenador o esquema desconocido, un esquema que el entrenador no puede aprender, un entrenador que el proyecto no puede ejecutar, o un entrenador cuya licencia necesita confirmación, con needs_licence_ack: true, hasta que la solicitud fije accept_licence: true |
409 | Un parámetro que el entrenador no admite o de tipo o rango erróneo, un backend desconocido, decision-calibrate en un backend distinto de local, o una ejecución ya en curso con "queue": false |
429 | Ya hay queue_max ejecuciones en espera |
Protocolo del agente
model_training.enabled registra también las rutas a las que llama un agente de entrenamiento, bajo /api/training. Un agente envía su token como Authorization: Bearer <token>, y un token ausente o no válido recibe 401. Registrar un backend requiere en cambio la clave de API de administrador. potato/training/protocol.py describe el protocolo para quien escriba un agente nuevo, y potato/training/agent.py es la implementación de referencia:
| Ruta | Finalidad |
|---|---|
POST /api/training/backends/register | Emite un token de agente para un nombre de backend, con X-API-Key. potato training register llama a esta ruta. |
POST /api/training/backends/<name>/heartbeat | Un agente inactivo informa de que está vivo. 403 para un token emitido para otro backend. |
GET /api/training/jobs/next?wait=30 | Sondeo largo. 200 con un trabajo, o 204 cuando no llega ningún trabajo en wait segundos. |
GET /api/training/jobs/<run_id> | El trabajo, la especificación del trabajo y si el trabajo se canceló. |
GET /api/training/jobs/<run_id>/bundle | Los datos de entrenamiento como tar.gz, con los medios incluidos. La ruta responde a solicitudes Range, de modo que un agente reanuda una descarga interrumpida, hasta cinco intentos. 410 cuando el paquete ya no existe. |
POST /api/training/jobs/<run_id>/progress | Eventos de progreso. Una cancelación vuelve en la respuesta. |
POST /api/training/jobs/<run_id>/predictions | predictions.jsonl. 413 por encima de max_predictions_mb. |
POST /api/training/jobs/<run_id>/complete | Código de salida y eventos finales. |
QLoRA
llm-sft, llm-dpo, hf-text-classification, vlm-sft y reward-model admiten lora: {quantize: 4bit}, la configuración de QLoRA (Dettmers et al., 2023). El modelo base se carga con pesos NF4 de 4 bits y doble cuantización, y un adaptador LoRA se entrena encima en bf16 donde la GPU admite bf16. quantize: 8bit es la opción intermedia, y las predicciones cargan el modelo base del mismo modo.
model_training:
trainer_params:
llm-sft:
model_name: Qwen/Qwen2.5-7B-Instruct
lora: {quantize: 4bit}En 4 bits, los pesos base ocupan una cuarta parte de la memoria que ocupan los mismos pesos en bf16, y las activaciones, el adaptador y el estado del optimizador se suman encima. Potato todavía no ha medido la memoria de una ejecución QLoRA en una GPU, así que planifica a partir de la línea «Peak GPU memory» de la propia ejecución. Toda ejecución de transformers registra esa línea al final. QLoRA necesita una GPU CUDA y una compilación de bitsandbytes para el CUDA de esa máquina. La ejecución comprueba ambas cosas antes de cargar el modelo cuantizando unos pocos números en la GPU, y cuando las dos versiones no coinciden, el error nombra ambas versiones. El tutorial de ajuste fino de LLM pone QLoRA en práctica en ejecuciones SFT y DPO.
Publicar en Hugging Face Hub
Una ejecución correcta cuyo modelo está en el servidor de Potato tiene Publish to the Hugging Face Hub en la página de la ejecución. La subida envía el modelo y un README.md con una ficha del modelo escrita a partir de la ejecución, que nombra el entrenador, el modelo base y el adaptador, los esquemas y las etiquetas, el tamaño de las particiones, la puntuación sobre ítems reservados y la partición sobre la que se midió la puntuación, y los ids de la ejecución y del paquete. La ficha de una ejecución dp incluye además una fila «Differential privacy» con el epsilon gastado frente al objetivo, el delta y la partición train que cubre la garantía. La fila omite el objetivo o el delta cuando la ejecución no registró el valor.
La subida es una lista fija de archivos y no todo el directorio artifacts/. La lista contiene los archivos de pesos, por ejemplo .safetensors, .bin, .pt y .pkl, los archivos de configuración y del tokenizador del directorio model/ guardado, model_card.json con las rutas locales sustituidas por nombres de archivo, y calibration.json. Las respuestas del modelo sobre los ítems del proyecto (predictions.jsonl, y raw_answers.jsonl para los modelos de decisión) permanecen en el servidor. También quedan fuera los puntos de control, el estado del optimizador, las copias de los datos de entrenamiento que hacen algunos entrenadores (yolo_data/, wev_data/, laya_data/) y cualquier enlace simbólico que apunte fuera de artifacts/.
El formulario protege de varias formas frente a una subida accidental o pública:
- Escribes el nombre del repositorio dos veces, y la subida sigue adelante solo cuando los dos nombres coinciden.
- Private viene marcado de forma predeterminada. Mientras Private está marcado, Potato no sube a un repositorio público existente, y la API responde
409. - El formulario nombra una variable de entorno del servidor,
HF_TOKENde forma predeterminada, que contiene un token de escritura de Hugging Face. El token en sí nunca se escribe en la página. El nombre de la variable debe contenerTOKENo empezar porHF_, y el valor debe empezar porhf_, de modo que el valor de ninguna otra variable puede llegar a Hub. - Cuando Hub no puede decir si el repositorio existe, no se sube nada, y un repositorio que creó la subida se elimina de nuevo si la carga falla después.
- La licencia de la ficha del modelo es el id de licencia de Hub que des, como
apache-2.0. Sin ninguno, la ficha dice que se aplica la licencia del modelo base. Un entrenador cuya licencia necesita confirmación, comoultralytics-detect(AGPL-3.0), necesita la misma confirmación para subir. - Un modelo que se quedó en un host remoto con
fetch_artifacts: false, o entrenado en un backend agent, no puede subirse desde el servidor, y el error nombra dónde está el modelo.
Cada subida es un commit. La página de la ejecución lista cada subida con el repositorio, la visibilidad y el commit, y el registro anota quién hizo la subida. Por la API, el cuerpo de POST /admin/training/api/runs/<run_id>/push-to-hub admite repo_id, confirm_repo_id, private (true por defecto), token_env (HF_TOKEN por defecto), licence y accept_licence. La ruta devuelve 201 con el commit, 400 ante una discrepancia, una variable de token ausente, la falta de archivos del modelo o una licencia sin confirmar, y 502 cuando Hub lo rechaza.
Solución de problemas
Las entradas de abajo cubren los errores más probables en una primera configuración. La lista upstream de solución de problemas cubre controladores de GPU, compilaciones de CUDA y los mensajes propios de cada entrenador.
/admin/trainingdevuelve 404.model_training.enabledno estrue, y Potato registra las rutas solo cuando la clave estrue.- "Only N items in the train split". Anota más ítems, o baja
min_instancesen losparamsde la ejecución. La partición train contiene por defecto el 70% de los ítems etiquetados. - "Schema 'x' has 1 distinct label(s) in the data". Un clasificador necesita al menos dos etiquetas en uso.
- "No resolved annotations to train on". El esquema nombrado en la ejecución difiere del esquema que se está anotando, o nadie ha anotado nada todavía.
- La ejecución no publicó preetiquetas. Lee el informe
writebackdeGET /admin/training/api/status. «No predictions were published: write-back is not enabled for any schema» significa quewriteback.schemasestá vacío, y los recuentos de omisión muestran cuántas predicciones eliminó cada comprobación. <trainer> does not take <name>. Un parámetro de la ejecución o detrainer_paramsestá mal escrito o pertenece a otro entrenador. El mensaje lista los nombres que admite el entrenador.- La ejecución se mató tras quedarse la máquina sin memoria. El proceso terminó con SIGKILL, normalmente por el asesino de falta de memoria. Usa un modelo más pequeño o menos ítems, o fija
max_ram_mbpara que la ejecución falle dentro de su propio límite. - "Stopped: the run took longer than model_training.max_wall_seconds". La ejecución llegó al límite de tiempo. Sube
max_wall_seconds, o entrena con menos ítems. - "The GPU ran out of memory". Baja
batch_sizey subegradient_accumulationpara mantener el lote efectivo, fijalora: trueolora: {quantize: 4bit}, o parallm-sftfijagradient_checkpointing: trueo elige un modelo más pequeño. - "ssh to host failed: Permission denied". Potato ejecuta
sshconBatchMode=yes, así quessh <host> truedebe funcionar desde la cuenta del servidor sin ninguna petición. Una clave con frase de contraseña funciona cuandossh-agentguarda la clave. - Una ejecución en un backend agent sigue en cola. Ningún agente con ese nombre de backend está consultando al servidor. Inicia un agente con
potato training agent --backend <name>, y comprueba el token con Check en la página Training.
Más información
- Entrenamiento de modelos con tus propias anotaciones: el ciclo de entrenamiento, la página Training y un inicio rápido.
- Entrenadores: cada entrenador, los esquemas de los que aprende y los comandos de instalación.
- Entrenar en un servidor con GPU, un clúster SLURM o una máquina tras NAT: backends ssh, SLURM y de agente paso a paso.
- El modelo en el ciclo: escritura de vuelta, revisión,
auto_retrainy versiones de conjuntos de datos en un mismo estudio. - Aprendizaje activo: ordenar los ítems por incertidumbre del modelo.
- Detectar preetiquetas aceptadas sin leer: comprobar si los anotadores aceptan preetiquetas sin leerlas.
- Referencia upstream: las tablas completas de parámetros de cada entrenador.
Referencias
- 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