Documentação

Ajuste fino do Laya nas tuas próprias decisões

No benchmark typed-decisions, os checkpoints base pontuam perto do acaso zero-shot — 0.36 e 0.35 contra uma linha de base aleatória de 0.318 — enquanto o checkpoint com ajuste fino atinge 0.766 nas mesmas 2,000 decisões, acima do 0.727 publicado do TypeSafe Jev e acima do teto de auto-concordância de 0.735 do professor. É no ajuste fino que está a maior parte do valor, e o notebook público de ajuste fino corre o ciclo completo nas 2xT4 gratuitas do Kaggle: construir o conjunto de dados, treinar com RLCD, ajustar as temperaturas de calibração, avaliar e enviar o resultado para o Hub. Esta página percorre esse notebook e aponta as partes que continuam a ser essenciais quando trocas os dados pelos teus.

O outro exemplo trabalhado — uma cabeça de decisão de agente de navegador numa única GPU de 16 GB sem API paga — está em Ajuste fino do Laya como cabeça de decisão de um agente de navegador.

O que o notebook faz, por ordem

# passo o que acontece
1 Ambiente verifica que ambas as GPUs T4 estão visíveis e alocadas
2 Instalação laya, transformers, datasets e as dependências de treino
3 Pré-processamento os 1,200 casos de treino (6,000 decisões tipadas) tornam-se itens tokenizados com alvos suaves, escritos em disco para ambos os ranks DDP
4 Treino train_ddp.py sob torchrun --nproc_per_node=2, quatro épocas
5 Calibração uma temperatura por tipo, ajustada numa fatia reservada antes do treino (dentro do script de treino, após a última época)
6 Avaliação a partição oficial test, respondida pelo checkpoint com ajuste fino — 400 casos, 2,000 decisões — com latência por caso
7 Métricas precisão, precisão suave, Brier, ECE, MAE de score, within-one-level e percentis KL/TV e de latência; uma tabela de comparação direta contra o Jev e o teto do professor
8 Publicação (opcional) um model card construído a partir dos próprios números da execução, pasta enviada para o Hub
9 Relatório benchmark_report.json com a tabela de métricas e a precisão por fluxo de trabalho

Definições do Kaggle: Accelerator GPU T4 x2, Internet On. Os resultados ficam em /kaggle/working/laya_finetuned_typed_decisions.

A receita de treino

O RLCD treina sobre as distribuições gold do benchmark, e não sobre etiquetas rígidas: cada item transporta a probabilidade que o professor atribuiu a cada opção, e ambas as metades da perda leem esse alvo —

  • um termo de gradiente de política sobre projeções de logits ruidosas amostradas (estilo GRPO: quatro amostras por item, ruído de exploração com anneal de 0.4 → 0.1), recompensado por regras de pontuação próprias (spherical 0.75, ranked probability 1.0);
  • um termo de entropia cruzada suave com peso total contra a mesma distribuição.

Os parâmetros que o notebook define para uma placa de 16 GB:

épocas 4
lote efetivo 64 sequências (8 por micro-lote, 2 GPUs, 4 passos de acumulação)
taxas de aprendizagem encoder 2.5e-5, head 1e-4 — AdamW, agendamento cosseno
memória autocast fp16, gradient checkpointing no encoder e na cabeça, recorte da norma do gradiente 1.0
orçamento de sequência max_len 1024, head_max_len 256, max_tokens_per_batch 4096

O tempo de execução em 2xT4 é de minutos para a demonstração e de horas para dados reais: cerca de 4–6 minutos para as 6,000 decisões da demonstração, e aproximadamente 4–5 horas para quatro épocas sobre ~30k perguntas.

Para o apontar aos teus dados, substitui as duas chamadas a load_dataset e mantém o esquema das linhas: cada caso transporta state, questions e gold (as probabilidades do professor por pergunta), e o pré-processador transforma-os em itens. Os tipos de pergunta são choice, score e noul; tudo o que consigas expressar com eles sobre um estado serve.

A calibração faz parte da execução

É o passo com maior probabilidade de ser esquecido ao copiar o ciclo, e torna-se essencial no momento em que alguém aplica gating com base na confiança.

O notebook retira uma fatia de calibração dos dados de treino antes de os fragmentar entre os ranks (até 400 itens, ou 10%, com uma semente fixa, idêntica em todos os ranks). Ajustar temperaturas sobre itens em que a execução já treinou mede o ajuste, e não a calibração — o modelo está quase certo e quase correto neles, por isso o otimizador não tem nada para suavizar e devolve uma escala degenerada.

Após a última época, o rank 0 ajusta uma temperatura por tipo de pergunta (choice, score, noul) por LBFGS sobre o logaritmo da temperatura, limitada a [0.1, 10] (1.0 para uma fatia com menos de dez itens, 1.2 se o ajuste levantar uma exceção). Os valores vão para rl_agent_config.json como temperature, e o notebook remove qualquer temperature_by_options herdado na mesma escrita: esses valores antigos por balde têm precedência na inferência e mascaram silenciosamente o novo ajuste.

A escala de temperatura deixa o argmax — e a precisão — inalterados; o que muda é a confiança. Os checkpoints como são distribuídos são demasiado confiantes, por isso ajusta antes de confiar em qualquer limiar, e avalia o resultado em dados reservados antes de reivindicares uma melhoria. A regressão de persistência da configuração corre sem downloads nem treino:

python tests/test_calibration_persistence.py

Avaliar antes de confiar

A avaliação é uma passagem completa pela partição oficial de teste: 400 casos, 2,000 decisões em Agent Trace Observability, Customer Service, Invoice Processing e Security Incidents. Calcula a precisão, a precisão suave, o Brier, o ECE (via laya.common.ece_score), o MAE de score, o within-one-level e os percentis de latência, e depois constrói uma tabela de comparação direta cujas linhas de referência são fixas:

modelo tipo precisão ECE
TypeSafe Jev 1.13.0 geral 0.727 0.144
ModernBERT-base (149M) especialista 0.646 0.179
Auto-concordância do professor teto 0.735 —
Laya (checkpoint publicado) ajuste fino 0.766 —

A linha do Laya da tua própria execução é calculada da mesma forma — o notebook reconstrói a tabela a partir dos próprios números da execução. Dois hábitos que vale a pena copiar: mantém as fatias que te interessam (um idioma, um fluxo de trabalho) dentro dos dados reservados, e reporta a calibração ao lado da precisão, porque o sinal de treino é uma distribuição, e não apenas uma etiqueta. Quando tiveres números, um post nas Discussions do repositório é o sítio para os partilhar; os benchmarks e os limites conhecidos vivem em BENCHMARKS.md na raiz do repositório.

Enviar para o Hub

A célula de publicação é a última milha do ciclo, e é deliberadamente aborrecida:

  1. Coloca um HF_TOKEN de escrita no Kaggle (Add-ons → Secrets). A célula levanta uma exceção com as instruções exatas se ele faltar.
  2. Define o repositório de destino — a célula distribuída aponta por predefinição para um nome no namespace do próprio projeto, por isso altera-o antes de correr.
  3. Corre-a. Escreve um model card cujos números vêm da tabela de comparação desta execução, e depois envia model.safetensors, encoder/, tokenizer/, rl_agent_config.json, o card e o relatório de benchmark.

O resultado carrega-se como qualquer outro checkpoint — não há uma API específica de ajuste fino:

import laya

agent = laya.load("your-org/your-checkpoint")   # the repo you just pushed
result = agent.predict(state, questions)

Um checkpoint_latest/ rotativo é substituído após cada época, por isso um timeout ou OOM no Kaggle custa uma época, e não a execução.

O que vigiar

  • O ciclo é tão bom quanto os alvos. O RLCD imita a distribuição de um professor nas tuas perguntas; recolhe as confianças do professor antes (ou a par) do treino, e trata a sua qualidade como o teto.
  • A fatia de calibração é pequena de propósito. Até 400 itens ou 10% — suficiente para três escalares por tipo, insuficiente para validar. Reserva os teus próprios dados de avaliação.
  • As tuas etiquetas têm de caber nas três primitivas. Se a tua decisão não for um choice, uma escala ou uma probabilidade de sim/não, molda-a numa delas primeiro. Já estão documentadas duas arestas afiadas: contagens elevadas de opções degradam a seleção por confiança (#394), e a negação forçada de escolha pode seguir a pergunta em vez do estado (#377).
  • Distribui a configuração, não só os pesos. O temperature_by_options removido é a parte que desfaz silenciosamente uma calibração se sobreviver numa configuração copiada.