Pular para o conteúdo

Configuração e rotas do treinamento de modelos

Todas as chaves do bloco model_training, como as execuções são enfileiradas, pontuadas e armazenadas, e as rotas de administrador e de agente, com correções para erros comuns.

Novo na v2.14.0

Esta página é a referência do bloco model_training de uma configuração do Potato e do que acontece com uma execução depois que você a inicia. A página é escrita para quem conduz um estudo e quer limitar execuções, enviar execuções a outra máquina, mostrar as predições de um modelo aos anotadores ou iniciar o treinamento a partir de um script. Cada chave, padrão, rota e mensagem abaixo foi conferido com o código do Potato. Para uma primeira execução, comece por Treine o seu primeiro modelo. Os treinadores e os parâmetros deles estão listados em Treinadores.

Uma configuração completa

A configuração abaixo treina um classificador de sentimento em avaliações de produtos. auto_retrain reajusta sklearn-text a cada 25 novas anotações. Com as características TF-IDF padrão, sklearn-text treina na CPU e não precisa de nada além de uma instalação simples do Potato. Execuções automáticas frequentes portanto custam pouco. A gravação de volta mostra aos anotadores toda predição com confiança de pelo menos 0,8. Com include_unlabeled, uma execução também prevê nas avaliações que ninguém rotulou ainda. Os padrões de hf-text-classification e o backend gpu-server atendem às execuções iniciadas à mão na página Training:

yaml
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: 4000

Mantenha split_seed fixo durante toda a vida do estudo. Uma nova semente reatribui todos os itens, então itens que estavam reservados passam a fazer parte do treinamento e as pontuações seguintes deixam de ser comparáveis com as anteriores. O limite mínimo de confiança min_confidence de 0,8 é um ponto de partida, e o limite certo depende da primeira pontuação em itens reservados. Ative include_unlabeled quando essa pontuação sustentar a exibição de pré-rótulos, porque os pré-rótulos ancoram os anotadores na resposta do modelo.

Chaves de model_training

Todas as chaves ficam sob model_training:

ChavePadrãoSignificado
enabledfalseRegistra a página Training, as rotas sob /admin/training e as rotas de agente sob /api/training. Sem enabled: true, as rotas não existem.
retain_runs5Execuções concluídas mantidas no registro de execuções. Uma execução mais antiga sai do registro, a menos que as predições dela ainda estejam armazenadas. Os diretórios das execuções permanecem no disco.
grace_seconds20Segundos que uma execução cancelada tem para sair antes de o Potato encerrar o processo. 0 ou mais, e enviado com o job aos backends do tipo ssh, slurm e agent.
queue_max10Execuções que podem esperar atrás da execução em andamento.
split_seed0Semente para atribuir itens às divisões train, val e test.
splits{train: 0.7, val: 0.15, test: 0.15}Frações das divisões, normalizadas para somar 1. Os nomes são train, val e test, e train é obrigatório.
aggregationconsensusComo os rótulos de vários anotadores em um item viram um só rótulo. consensus ajusta o modelo de Dawid-Skene quando o estudo tem mais de um anotador e recorre ao voto majoritário se o ajuste falhar. majority usa o voto majoritário.
max_wall_secondsnão definidoLimite de tempo de uma execução. O Potato verifica uma execução local cada vez que ela informa um evento, e uma execução ssh ou de agente a cada segundo.
max_ram_mbnão definidoLimite de espaço de endereçamento do processo de treinamento, definido com setrlimit. Em uma plataforma sem o limite, a execução registra um aviso e continua.
deviceautoauto, cpu, cuda, cuda:N ou mps. auto escolhe CUDA, depois o Metal da Apple e depois a CPU.
num_threadsnão definidoDefine OMP_NUM_THREADS, MKL_NUM_THREADS e OPENBLAS_NUM_THREADS para a execução, a menos que o ambiente já defina essas variáveis.
auto_retraindesligadoRetreinamento conforme as anotações chegam. Veja auto_retrain.
writebacknenhumPublicação de predições como pré-rótulos. Veja writeback.
backendlocalO backend das execuções que não nomeiam outro.
backendsnenhumBackends nomeados ssh, slurm e agent. Veja Backends.
max_predictions_mb512Maior predictions.jsonl que um agente remoto pode enviar.
trainer_paramsnenhumPadrões de parâmetros, indexados pelo nome do treinador.
tilingenabled: autoCorte de imagens grandes em blocos para os treinadores de detecção e segmentação. Veja tiling.

Os params de uma execução substituem trainer_params, que substituem os padrões do treinador. Um nome de parâmetro que o treinador não aceita é recusado na inicialização do servidor quando o nome está em trainer_params, e quando a execução começa nos demais casos. Treinadores dá a ordem com um exemplo.

auto_retrain

O retreinamento automático verifica se há uma nova execução depois de cada salvamento de anotação:

ChavePadrãoSignificado
enabledfalseLiga a verificação.
trainernenhumNome do treinador. Obrigatório.
schemasnenhumEsquemas a treinar. Obrigatório.
min_interval_s600Segundos desde o fim da última execução antes de iniciar outra.
update_frequency25Novas anotações desde a última execução automática antes de iniciar outra.
params{}Parâmetros do treinador, como nos params de uma execução pela API.
backendmodel_training.backendBackend das execuções automáticas.
accept_licencefalseConfirma a licença de um treinador que pede confirmação (ultralytics-detect, ultralytics-segment, layoutlmv3). Sem a confirmação, as execuções automáticas desses treinadores são puladas.

Quando uma verificação decide contra uma execução, o motivo aparece no campo skip_reason de GET /admin/training/api/status, por exemplo "waiting for 3 more annotation(s)" ou "a run is already in progress". As execuções automáticas nunca entram na fila de execuções. A próxima anotação salva depois que a fila esvazia verifica de novo, com mais anotações para treinar. O Potato guarda as contagens de anotações na memória, então, depois de uma reinicialização, um projeto que já treinou conta as novas anotações a partir da reinicialização.

writeback

A gravação de volta decide quais predições os anotadores veem:

ChavePadrãoSignificado
schemas[]Esquemas cujas predições os anotadores veem. Uma lista vazia não mostra nenhuma.
min_confidence0.0Predições abaixo do limite são armazenadas e não mostradas. Uma predição sem confiança passa.
fieldpredictionsCampo do item em que os pré-rótulos são gravados.
include_unlabeledfalseTambém prevê nos itens que ninguém rotulou e pré-rotula esses itens. Sem include_unlabeled, uma execução prevê apenas nos itens val e test da própria execução.

tiling

Os treinadores de detecção e segmentação redimensionam cada imagem para algumas centenas de pixels. Nesse tamanho, os objetos de uma imagem de lâmina inteira ou de uma cena de satélite se perdem. Para um esquema image_annotation, microscopy ou geo_annotation, o Potato portanto corta cada imagem grande em blocos quando os dados de treinamento da execução são construídos. A divisão de uma imagem é decidida antes de a imagem ser cortada, então os blocos de uma mesma lâmina nunca caem em duas divisões. As predições são mapeadas de volta à imagem inteira, e as pontuações em itens reservados são calculadas em imagens inteiras. O tutorial de visão cobre lâminas e mapas na prática.

ChavePadrãoSignificado
enabledautoauto divide em blocos os formatos de lâmina (.svs, .ndpi, .mrxs, .scn e outros) e as imagens cujo lado maior tem pelo menos auto_min_side. true divide todas as imagens, e false nenhuma.
auto_min_side4096Comprimento do lado maior, em pixels, a partir do qual auto começa a dividir uma imagem em blocos.
tile_size1024Lado de um bloco, nos pixels que o treinador vê.
overlap128Pixels que blocos vizinhos compartilham, no máximo metade de tile_size. Mantenha a sobreposição pelo menos do tamanho dos objetos, ou um objeto grande é encontrado em pedaços.
downsample1Pixels de resolução total por pixel de bloco.
mppnenhumMícrons por pixel de bloco. Substitui downsample para uma lâmina que registra a resolução dela.
background0.25Blocos vazios amostrados por bloco com um objeto. Defina background: 0 para lâminas anotadas apenas em parte.
max_predict_tiles2000Maior número de blocos previstos por imagem. Os blocos com mais tecido são mantidos.
min_visible0.4Fração de um objeto que deve ficar dentro de um bloco para o objeto treinar ali.
tissue_threshold0.05Fração de um bloco de lâmina que deve ser tecido para o modelo prever no bloco.

As lâminas são lidas com o openslide, instalado por pip install "potato-annotation[wsi]", na máquina que constrói os dados de treinamento. Um backend remoto baixa os blocos e nunca a lâmina.

A fila de execuções

Uma execução roda de cada vez. Uma execução iniciada pela página Training ou pela API enquanto outra está em andamento espera, em vez de ser recusada. A requisição de início devolve 202 com queued: true e a position da execução, e a tabela Runs lista a execução como waiting #N com um botão Cancel run. Quando a execução em andamento termina, a execução em espera mais antiga começa.

As execuções em espera são registros no registro de execuções, então a fila sobrevive a uma reinicialização, e a primeira execução em espera começa quando o servidor volta. Uma execução que o servidor anterior estava no meio de executar é marcada como interrupted ao mesmo tempo. Os dados de treinamento de uma execução em espera são construídos quando a execução começa, então a execução treina com as anotações presentes naquele momento. Um início que seria recusado, como um início que nomeia um esquema desconhecido, é recusado na hora, e não quando chega a vez da execução. Uma execução cujo esquema ou treinador saiu da configuração enquanto ela esperava falha com invalid_when_dequeued, e a execução seguinte começa.

Envie "queue": false no corpo da requisição para receber 409 em vez de um lugar na fila. Com queue_max execuções já em espera, um novo início recebe 429. GET /admin/training/api/status lista as execuções em espera em ordem sob queue.

Verificações antes de uma execução

potato validate informa todos os problemas do bloco model_training de uma vez, e o servidor se recusa a iniciar pelos mesmos problemas:

bash
potato validate config.yaml --strict

As verificações cobrem estes casos:

  • splits com um nome diferente de train, val e test, uma fração abaixo de 0 ou que não é um número, frações que somam 0 ou ausência de train.
  • Uma chave que writeback ou auto_retrain não tem, uma entrada de writeback.schemas que não é um esquema ou um min_confidence fora do intervalo de 0 a 1. accept_license é informado como erro de grafia de accept_licence.
  • Um bloco pre_annotation ativado cujo field difere de writeback.field. Nenhum pré-rótulo de treinamento apareceria sob esse bloco.
  • Com auto_retrain.enabled, um treinador ou esquema que não existe, um esquema que o treinador não consegue aprender, parâmetros que o treinador não aceita ou de tipo errado, um backend ausente de backends ou decision-calibrate em um backend diferente de local.
  • Um parâmetro em trainer_params que o treinador não aceita ou de tipo errado. Dentro de dp, a verificação também cobre cada chave e o intervalo da chave.
  • Um grace_seconds abaixo de 0 ou que não seja um número, ou um retain_runs ou split_seed abaixo de 0 ou que não seja um número inteiro.
  • Em backends, um type ausente ou desconhecido, uma chave que o tipo não tem, um backend ssh sem host, um valor de gpus diferente de auto, none ou índices de GPU, um backend remoto chamado local ou um model_training.backend que não está definido.

potato training check testa um backend antes de uma execução usá-lo. Para local, o comando imprime o dispositivo que uma execução usaria, por exemplo local: this machine, Apple Metal (mps) em um Mac com Apple silicon. Para um backend ssh, o comando informa a versão do Python, cada GPU com a memória livre dela, a GPU que uma execução receberia e os pacotes de treinamento que faltam no interpretador remoto. O botão Check da página Training executa o mesmo teste, e --json imprime o relatório como JSON:

bash
potato training check local config.yaml
potato training check gpu-server config.yaml

Uma execução iniciada pela página Training ou pela API é verificada de novo quando começa. Os códigos de status estão listados em Rotas.

Backends

Uma execução roda em um backend, e o menu Runs on da página Training lista os backends configurados. model_training.backend define o padrão, e uma execução pela API ou auto_retrain pode nomear outro backend com backend. O Potato tem quatro tipos de backend:

TipoOnde o treinador rodaQuem inicia o treinador
localEsta máquina, em um subprocesso. Sempre disponível, e o padrão.O Potato
sshOutra máquina que o Potato alcança por ssh, como um servidor com GPU.O Potato, por ssh
slurmUm nó de computação de um cluster, como trabalho em lote.O Potato, por ssh ao nó de login e depois sbatch
agentUma máquina que o Potato não alcança, como uma estação de trabalho atrás de NAT.Uma pessoa, com potato training agent

Um backend ssh usa autenticação por chave com BatchMode ligado, então um pedido de senha falha em vez de travar. Um backend slurm usa apenas sbatch, squeue e scancel, além de scontrol em clusters que oferecem scontrol, e precisa de um remote_dir em um armazenamento que os nós de computação compartilham. Um backend agent não precisa de porta de entrada, porque o agente abre todas as conexões. O nome local é reservado para esta máquina, e decision-calibrate roda apenas em local. Treine em um servidor com GPU, cluster SLURM ou máquina atrás de NAT percorre os três tipos remotos com as chaves deles.

Pontuações em itens reservados

Cada execução pontua as próprias predições nos itens val e test contra os rótulos humanos resolvidos. Os nomes das métricas carregam a divisão, como em val_macro_f1 ou test_f1. Um item com rótulo e sem predição conta como erro, então deixar de fora itens difíceis não consegue aumentar a pontuação de um treinador. <split>_coverage informa a fração de itens que receberam uma predição.

A pontuação principal aparece na coluna Held-out score da tabela Runs, com a divisão e a métrica na dica. A pontuação principal é a métrica principal do primeiro esquema na primeira divisão entre val e test que tem itens. Quando um treinador escolheu o melhor checkpoint pela pontuação em val, o Potato tenta test primeiro, porque o treinador já viu a pontuação em val. Os treinadores de ajuste fino que mantêm a melhor época, por exemplo hf-text-classification, torchvision-detect e llm-sft, tomam a pontuação principal de test. sklearn-text, setfit, rdkit-property, os treinadores de modelos de decisão e as pontes de inferência não escolhem nada em val, e uma execução de um desses treinadores toma a pontuação principal de val sempre que val tem itens. Uma execução sem itens val ou test aparece como "not scored".

A métrica principal depende do tipo de anotação do esquema, como mostra a tabela abaixo para os tipos comuns:

Tipo de anotaçãoMétrica principal
radio, select, likertmacro-F1 (também acurácia e erro absoluto médio para rótulos likert numéricos)
multiselectmicro-F1 (também macro-F1 e correspondência exata)
spanF1 sobre trechos que coincidem em início, fim e rótulo
textF1 de tokens (também correspondência exata)
pairwise em modo binaryacurácia sobre itens não respondidos como empate
rankingtau de Kendall
image_annotation, microscopy, geo_annotationmAP do COCO com IoU 0,5 (map_50), com map_50_95 também registrado
audio_annotationF1 sobre segmentos com o mesmo rótulo e IoU de 0,5 ou mais
speech_transcriptword_accuracy, 1 menos a taxa de erro de palavras
volume_annotationmean_dice

O F1 de tokens dá crédito a uma resposta que usa as palavras certas na ordem errada, então leia o F1 de tokens junto com a correspondência exata. A pontuação principal de detecção usa IoU 0,5 em vez da média de 0,5 a 0,95, porque as caixas de dois anotadores para um mesmo objeto raramente se sobrepõem com IoU 0,9. A tabela de pontuações em itens reservados do projeto original lista as métricas de cada tipo de anotação.

Gravação de volta

Depois de uma execução bem-sucedida, o Potato armazena as predições da execução e grava as predições que passam por quatro verificações no campo predictions de cada item, ou no campo que writeback.field nomeia. As verificações rodam nesta ordem, e o relatório de gravação de volta da execução conta cada item pulado:

  1. Itens da divisão train nunca são pré-rotulados. A verificação cobre a divisão train de toda execução ainda no registro, e um pré-rótulo que uma execução anterior deixou em um item é retirado quando uma execução posterior treina com o item.
  2. Apenas esquemas em writeback.schemas são publicados. A lista vem vazia por padrão, então ligar o treinamento não muda nada do que os anotadores veem.
  3. Pares rejeitados são pulados. Um par de item e esquema com um veredito reject na revisão de modelos não é mostrado de novo.
  4. O limite mínimo de confiança se aplica. Uma predição abaixo de min_confidence é armazenada e não publicada.

A gravação de volta nunca altera um rótulo humano, porque as predições vão para os dados dos itens e as anotações ficam no estado de usuário de cada anotador. Um pré-rótulo aparece como uma resposta preenchida que o anotador pode editar, por exemplo uma escolha como a opção selecionada e uma resposta de texto livre na caixa de texto do esquema, e nenhum bloco pre_annotation é necessário. O pré-rótulo só se torna a resposta do anotador quando o anotador o edita ou passa adiante. Um pré-rótulo que ninguém editou nem deixou para trás portanto nunca se torna um rótulo de treinamento. Um par anotador-item que ai_support.holdout coloca no grupo de comparação sem assistência do estudo não mostra pré-rótulo, e os dados do item enviados para esse par deixam de fora tanto o writeback.field quanto o pre_annotation.field. O relatório de gravação de volta é o campo writeback de GET /admin/training/api/status, e o summary do relatório diz por que uma execução não publicou nada.

O Potato guarda uma predição por item e esquema, e a predição de uma execução mais nova substitui a de uma execução mais antiga. Quando a predição mais nova é armazenada mas não mostrada, porque está abaixo de min_confidence, está vazia ou foi rejeitada, o pré-rótulo da execução mais antiga sai do item na hora, e o relatório de gravação de volta conta o item em n_superseded_cleared. Pré-rótulos fornecidos junto com os dados são deixados como estão. Na inicialização, as predições armazenadas dos esquemas em writeback.schemas são gravadas de volta nos dados dos itens sob as mesmas quatro verificações, então os pré-rótulos sobrevivem a uma reinicialização. Para retirar os pré-rótulos de uma execução, envie DELETE /admin/training/api/runs/<run_id>/predictions. A requisição remove as predições armazenadas e retira os pré-rótulos dos itens.

Correções e itens fixados sempre treinam

Dois tipos de item vão para a divisão train de toda execução posterior, qualquer que seja o lugar do item na divisão estável:

  • Itens que um revisor corrigiu. Um veredito correct na revisão de modelos significa que uma pessoa corrigiu a resposta do modelo. As correções vêm dos itens em que o modelo foi pior, então um item corrigido em val ou test pontuaria o modelo em uma amostra dos próprios erros do modelo. Os vereditos accept e reject deixam um item onde ele estava.
  • Itens fixados. Train on these, ao lado de uma fatia na página Catalog, fixa os itens que a fatia seleciona, por exemplo a fatia model-found-nothing embutida. Um item fixado treina depois que alguém o rotulou.

Uma execução que moveu itens reservados para train registra um aviso com a contagem. A pontuação em itens reservados da execução é então calculada sem esses itens e não é diretamente comparável com a pontuação de uma execução anterior. As contagens estão em stats.forced_train no manifest.json dos dados de treinamento.

Salvando uma divisão como versão de conjunto de dados

Keep this split as a dataset, na página de uma execução, salva os itens val, test ou train da execução com os rótulos humanos acordados como uma nova versão de um conjunto de dados. Uma versão de conjunto de dados nunca muda depois, então modelos e prompts de LLM posteriores podem ser comparados exatamente nesses itens. O recurso precisa de datasets.enabled: true. Cada versão salva contém uma divisão e começa do zero, em vez de acrescentar à última versão do conjunto de dados. Os itens val da execução 2 acrescentados aos da execução 1 incluiriam itens com que a execução 2 treinou. Os inputs de cada exemplo deixam de fora o campo do pré-rótulo, então uma avaliação não consegue ler a resposta do modelo.

De onde veio um pré-rótulo

GET /admin/model-review inclui provenance para cada item da fila de revisão cujo pré-rótulo uma execução de treinamento gravou. Para cada esquema, a entrada dá o id da execução, o treinador e a pontuação em itens reservados da execução. Pré-rótulos fornecidos junto com os dados não têm entrada.

Onde as execuções são armazenadas

Cada execução tem um diretório em <task_dir>/<output_annotation_dir>/training/runs/<run_id>/:

CaminhoConteúdo
bundle/Os dados de treinamento: train.jsonl, val.jsonl, test.jsonl, unlabeled.jsonl com include_unlabeled, labels.json, manifest.json e media/.
artifacts/model_card.json, predictions.jsonl e o modelo, por exemplo model.pkl para sklearn-text ou um diretório model/ para os treinadores de transformers.
spec.jsonO que a execução foi solicitada a fazer.
events.jsonl, stdout.log, stderr.logOs eventos de progresso e a saída da execução.
agent.logA saída do próprio agente remoto, em backends ssh.
bundle.tar.gzOs dados de treinamento como o agente os baixou, com a mídia, em backends remotos.

O registro de execuções fica no banco de dados do projeto, <task_dir>/project.sqlite, e guarda as execuções, a divisão de cada item por execução, os itens fixados para treino, as predições armazenadas, os tokens de agente e os envios ao Hugging Face Hub. retain_runs poda o registro e nunca poda uma execução cujas predições ainda estão armazenadas, então todo pré-rótulo pode ser rastreado até a execução que o gravou. A poda deixa os diretórios das execuções no disco.

Uma execução LoRA salva apenas o adaptador, de alguns a algumas centenas de megabytes, e carrega o modelo base por model_name quando a execução prevê. Um ajuste fino completo salva o modelo inteiro. Defina a variável de ambiente POTATO_MODEL_CACHE como um diretório, e o processo de treinamento usa esse diretório para HF_HOME, TRANSFORMERS_CACHE e SENTENCE_TRANSFORMERS_HOME, a menos que essas variáveis já estejam definidas. Em uma máquina isolada da rede, coloque antecipadamente nesse diretório os modelos que os treinadores nomeiam.

Rotas

A página Training e as rotas JSON da página ficam sob /admin/training e exigem acesso de administrador. Acesso de administrador significa uma sessão de administrador ou o cabeçalho X-API-Key. Requisições POST e DELETE de um navegador devem ser da mesma origem. A especificação OpenAPI do Potato marca todas as 26 operações de treinamento com x-potato-requires-config: model_training.enabled: true:

RotaFinalidade
GET /admin/trainingA página Training, com o formulário da execução, a lista de execuções e os treinadores.
GET /admin/training/runs/<run_id>A página de uma execução, com status, métricas, eventos e a divisão de cada item.
GET /admin/training/api/trainersTodos os treinadores, com os tipos, as modalidades, a licença e o status de instalação de cada um.
GET /admin/training/api/schemasOs esquemas do estudo, o tipo de cada esquema e os treinadores que se ajustam a cada esquema.
GET /admin/training/api/statusA execução atual ou a última, com estado, progresso, métricas, avisos, skip_reason, writeback e queue.
GET /admin/training/api/runsHistórico de execuções. ?limit= tem padrão 50, com máximo de 500.
POST /admin/training/api/runsInicia uma execução. 200 quando a execução começa, e 202 com queued: true e position quando a execução espera.
GET /admin/training/api/runs/<run_id>O registro de uma execução, mais review, a precisão das predições da execução sob os vereditos de revisão.
GET /admin/training/api/runs/<run_id>/eventsO log de eventos da execução. ?limit= tem padrão 200.
POST /admin/training/api/runs/<run_id>/cancelCancela a execução em andamento ou uma execução em espera. 400 para qualquer outro id de execução.
DELETE /admin/training/api/runs/<run_id>/predictionsRetira as predições armazenadas e os pré-rótulos da execução.
POST /admin/training/api/runs/<run_id>/push-to-hubPublica o modelo da execução no Hugging Face Hub. Veja Publicando no Hugging Face Hub.
POST /admin/training/api/runs/<run_id>/pin-splitSalva uma divisão como versão de conjunto de dados, com o corpo {"dataset": name, "split": "val"}.
GET /admin/training/api/backendsOs backends configurados.
POST /admin/training/api/backends/<name>/checkTesta um backend, como potato training check faz.
GET /admin/training/api/pinnedItens fixados, agrupados por motivo.
POST /admin/training/api/pinnedFixa itens em train, com {"slice": name} ou {"instance_ids": [...]}.
DELETE /admin/training/api/pinnedDesafixa os instance_ids listados, ou todos os itens fixados quando o corpo não lista nenhum.

Uma requisição de execução aceita trainer, schemas (uma lista ou um nome), params, backend, accept_licence e queue. Todo treinador ajusta apenas o primeiro esquema nomeado. A requisição abaixo inicia uma execução de sklearn-text no esquema sentiment do exemplo:

bash
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"]}'

Um início recusado dá o motivo em error:

StatusQuando
400Nenhum treinador ou nenhum esquema no corpo, um treinador ou esquema desconhecido, um esquema que o treinador não consegue aprender, um treinador que o projeto não consegue executar, ou um treinador cuja licença precisa de confirmação, com needs_licence_ack: true, até a requisição definir accept_licence: true
409Um parâmetro que o treinador não aceita ou de tipo ou intervalo errado, um backend desconhecido, decision-calibrate em um backend diferente de local, ou uma execução já em andamento com "queue": false
429queue_max execuções já em espera

Protocolo do agente

model_training.enabled também registra as rotas que um agente de treinamento chama, sob /api/training. Um agente envia o token do agente como Authorization: Bearer <token>, e um token ausente ou inválido recebe 401. Registrar um backend usa a chave de API de administrador. potato/training/protocol.py descreve o protocolo para quem escreve um novo agente, e potato/training/agent.py é a implementação de referência:

RotaFinalidade
POST /api/training/backends/registerEmite um token de agente para um nome de backend, com X-API-Key. potato training register chama esta rota.
POST /api/training/backends/<name>/heartbeatUm agente ocioso informa que está vivo. 403 para um token emitido para outro backend.
GET /api/training/jobs/next?wait=30Long poll. 200 com um trabalho, ou 204 quando nenhum trabalho chega em wait segundos.
GET /api/training/jobs/<run_id>O trabalho, a especificação do trabalho e se o trabalho foi cancelado.
GET /api/training/jobs/<run_id>/bundleOs dados de treinamento como tar.gz, com a mídia. A rota responde a requisições Range, então um agente retoma um download interrompido, em até cinco tentativas. 410 quando o pacote já não existe.
POST /api/training/jobs/<run_id>/progressEventos de progresso. Um cancelamento volta na resposta.
POST /api/training/jobs/<run_id>/predictionspredictions.jsonl. 413 acima de max_predictions_mb.
POST /api/training/jobs/<run_id>/completeCódigo de saída e eventos finais.

QLoRA

llm-sft, llm-dpo, hf-text-classification, vlm-sft e reward-model aceitam lora: {quantize: 4bit}, a configuração do QLoRA (Dettmers et al., 2023). O modelo base é carregado com pesos NF4 de 4 bits e dupla quantização, e um adaptador LoRA treina por cima em bf16 onde a GPU aceita bf16. quantize: 8bit é a opção intermediária, e as predições carregam o modelo base da mesma forma.

yaml
model_training:
  trainer_params:
    llm-sft:
      model_name: Qwen/Qwen2.5-7B-Instruct
      lora: {quantize: 4bit}

Em 4 bits, os pesos base ocupam um quarto da memória que os mesmos pesos ocupam em bf16, e as ativações, o adaptador e o estado do otimizador vêm além disso. O Potato ainda não mediu a memória de uma execução QLoRA em uma GPU, então planeje a partir da linha "Peak GPU memory" da própria execução. Toda execução de transformers registra essa linha no final. O QLoRA precisa de uma GPU CUDA e de um build do bitsandbytes para o CUDA daquela máquina. A execução verifica os dois antes de carregar o modelo, quantizando alguns números na GPU, e quando as duas versões não combinam, o erro nomeia as duas versões. O tutorial de ajuste fino de LLMs coloca o QLoRA em prática em execuções SFT e DPO.

Publicando no Hugging Face Hub

Uma execução bem-sucedida cujo modelo está no servidor do Potato tem Publish to the Hugging Face Hub na página da execução. O envio carrega o modelo e um cartão do modelo README.md escrito a partir da execução, que nomeia o treinador, o modelo base e o adaptador, os esquemas e os rótulos, os tamanhos das divisões, a pontuação em itens reservados e a divisão em que a pontuação foi medida, e os ids da execução e do pacote. O cartão de uma execução dp também tem uma linha "Differential privacy" com o epsilon gasto em relação à meta, o delta e a divisão train que a garantia cobre. A linha omite a meta ou o delta quando a execução não registrou o valor.

O envio é uma lista fixa de arquivos, e não o diretório artifacts/ inteiro. A lista contém os arquivos de pesos, por exemplo .safetensors, .bin, .pt e .pkl, os arquivos de configuração e de tokenizador do diretório model/ salvo, model_card.json com os caminhos locais trocados por nomes de arquivo e calibration.json. As respostas do modelo nos itens do projeto (predictions.jsonl e, para os modelos de decisão, raw_answers.jsonl) ficam no servidor. Checkpoints, o estado do otimizador, as cópias dos dados de treinamento que alguns treinadores fazem (yolo_data/, wev_data/, laya_data/) e qualquer link simbólico que aponte para fora de artifacts/ também ficam de fora.

O formulário protege contra um envio acidental ou público de vários modos:

  • Você digita o nome do repositório duas vezes, e o envio só prossegue quando os dois nomes coincidem.
  • Private vem marcado por padrão. Enquanto Private está marcado, o Potato não envia a um repositório público existente, e a API responde 409.
  • O formulário nomeia uma variável de ambiente no servidor, HF_TOKEN por padrão, que guarda um token de escrita do Hugging Face. O token em si nunca é digitado na página. O nome da variável deve conter TOKEN ou começar com HF_, e o valor deve começar com hf_, então o valor de nenhuma outra variável pode chegar ao Hub.
  • Quando o Hub não consegue dizer se o repositório existe, nada é enviado, e um repositório que o envio criou é apagado de novo se o upload falhar depois.
  • A licença do cartão do modelo é o id de licença do Hub que você informa, como apache-2.0. Sem nenhuma, o cartão diz que a licença do modelo base se aplica. Um treinador cuja licença precisa de confirmação, como ultralytics-detect (AGPL-3.0), precisa da mesma confirmação para enviar.
  • Um modelo deixado em um host remoto com fetch_artifacts: false, ou treinado em um backend agent, não pode ser enviado pelo servidor, e o erro nomeia onde o modelo está.

Cada envio é um commit. A página da execução lista cada envio com o repositório, a visibilidade e o commit, e o registro guarda quem fez o envio. Pela API, o corpo de POST /admin/training/api/runs/<run_id>/push-to-hub aceita repo_id, confirm_repo_id, private (padrão true), token_env (padrão HF_TOKEN), licence e accept_licence. A rota devolve 201 com o commit, 400 para uma divergência, uma variável de token ausente, nenhum arquivo de modelo ou uma licença não confirmada, e 502 quando o Hub recusa.

Solução de problemas

As entradas abaixo cobrem os erros mais prováveis em uma primeira configuração. A lista de solução de problemas do projeto original cobre drivers de GPU, builds do CUDA e as mensagens específicas de cada treinador.

  • /admin/training devolve 404. model_training.enabled não é true, e o Potato registra as rotas apenas quando a chave é true.
  • "Only N items in the train split". Anote mais itens ou reduza min_instances nos params da execução. A divisão train contém 70% dos itens rotulados por padrão.
  • "Schema 'x' has 1 distinct label(s) in the data". Um classificador precisa de pelo menos dois rótulos em uso.
  • "No resolved annotations to train on". O esquema nomeado na execução difere do esquema que está sendo anotado, ou ninguém anotou nada ainda.
  • A execução não publicou pré-rótulos. Leia o relatório writeback em GET /admin/training/api/status. "No predictions were published: write-back is not enabled for any schema" significa que writeback.schemas está vazio, e as contagens de itens pulados mostram quantas predições cada verificação removeu.
  • <trainer> does not take <name>. Um parâmetro na execução ou em trainer_params está escrito errado ou pertence a outro treinador. A mensagem lista os nomes que o treinador aceita.
  • A execução foi encerrada depois que a máquina ficou sem memória. O processo saiu com SIGKILL, geralmente pelo out-of-memory killer. Use um modelo menor ou menos itens, ou defina max_ram_mb para que a execução falhe dentro do próprio limite.
  • "Stopped: the run took longer than model_training.max_wall_seconds". A execução atingiu o limite de tempo. Aumente max_wall_seconds ou treine com menos itens.
  • "The GPU ran out of memory". Reduza batch_size e aumente gradient_accumulation para manter o lote efetivo, defina lora: true ou lora: {quantize: 4bit}, ou, para llm-sft, defina gradient_checkpointing: true ou escolha um modelo menor.
  • "ssh to host failed: Permission denied". O Potato executa ssh com BatchMode=yes, então ssh <host> true deve funcionar a partir da conta do servidor sem pedir nada. Uma chave com senha funciona quando o ssh-agent guarda a chave.
  • Uma execução em um backend agent permanece na fila. Nenhum agente com esse nome de backend está consultando o servidor. Inicie um agente com potato training agent --backend <name> e verifique o token com Check na página Training.

Leitura adicional

Referências