HMDeveloper
Todos os artigos
ia-local
ia-localpytorchtreinamento

Treinei um classificador no Mac com MPS e deixei um portão decidir se ele entra

Ajustei o Laya num M3 Max para servir de fallback de intenção na voz da casa: 2,5 horas por rodada, memória MPS sem limite e um portão que barrou a rodada com a maior nota.

A voz da minha casa funciona com Home Assistant. Quando as regras não reconhecem uma frase, quero um plano B que escolha entre 77 categorias (labels) e indique a probabilidade de cada escolha. Sem essa probabilidade, não consigo decidir se o sistema deve agir. A opção mais óbvia era um modelo pequeno, treinado para as intenções da casa e executado localmente.

Treinei no M3 Max usando PyTorch MPS, o sistema da Apple para fazer cálculos de IA com a GPU. Funcionou, mas o tempo e o uso de memória não bateram com minha previsão.

De onde parti

A base é laya-multilingual, um modelo aberto da convaiinnovations. Ele usa um encoder mmBERT-base multilíngue, uma parte que lê as opções e ajuda a escolher uma. O modelo tem 322 milhões de parâmetros, valores internos ajustados durante o treino.

Sem treino, em 10 de outubro, o modelo acertou 32% nas ferramentas das intenções da casa e gerou falsos positivos em 54% dos casos. Assim, não servia. Num teste de 9 de outubro, depois do primeiro ajuste fino, a acurácia no conjunto held-out passou de 0,317 para 0,917. O ECE ficou em 0,08 e o p50 em 23 ms. Ajuste fino é um treino adicional de um modelo já existente. Held-out é um conjunto separado, que não entra no treino, usado para avaliar o modelo. ECE mede o erro de calibração: a diferença entre a confiança indicada pelo modelo e sua taxa real de acertos. P50 é o tempo em que metade das respostas já chegou.

2,5 horas em vez de 1

Uma rodada completa usa cerca de 9,1 mil itens, 77 labels e 4 épocas, cada uma com cerca de 4.593 micro-etapas de treino. A 133 micro-etapas por minuto, leva cerca de 2,5 horas. Eu tinha previsto uma hora.

A configuração usa soft cross-entropy como função de perda, opções embaralhadas, dispositivo mps, micro-lote de 2 e acumulação de gradiente de 32. A função de perda mede o erro durante o treino. Micro-lote é a quantidade de exemplos processados de uma vez. O lote pequeno foi necessário: a memória do MPS não tem limite. Com micro-lote de 8, chegou a 39 GB.

Tentei limitar o uso com as razões de watermark do MPS e errei duas vezes antes de conseguir. Definir apenas a razão alta falha com invalid low watermark ratio 1.4, porque o valor padrão da razão baixa ficava acima da alta. Com a razão alta em 0,5, o treino excedeu o limite: MPS allocated: 17.97 GiB, max allowed: 18.72 GiB. A combinação de alta em 0,8 e baixa em 0,65 funcionou em 16 de outubro.

O pior erro não gerou aviso. Uma versão anterior do conjunto tinha 76 labels. O head budget (512/768), definido para menos labels, ignorou em silêncio todas as 8.800 linhas. Não apareceu erro nem aviso. Aumentei os valores para 1024/1280.

O portão

Uma rodada só vira o modelo de produção se passar por estas regras automáticas:

Uma rodada aprovada troca o checkpoint ativo sozinha. O checkpoint é o arquivo com o estado treinado do modelo. Por isso, cada teste treina numa pasta de staging, uma área temporária separada da produção.

Acurácia no held-out por rodada

A rodada de 21/10 com 99,1% foi rejeitada: errou no conjunto de falas reais.

Ver dados
Spike (09/10)91,7%
Promovida (16/10)98,7%
Rejeitada (21/10)99,1%
Promovida (21/10)97,1%

A rodada promovida em 16 de outubro teve held-out de 0,987, acerto de 1,0 nas falas reais, ECE de 0,013, falso positivo de 0,0 e ação errada de 0,014. O portão barrou a rodada de 21 de outubro, embora ela tivesse o melhor held-out: 0,991. Ela acertou apenas 0,889 nas falas reais, com 3 erros em 27, e teve taxa de falsos positivos de 0,074.

A rodada aprovada no mesmo dia ficou com held-out de 0,971, acerto de 1,0 nas falas reais, ECE de 0,016, falso positivo de 0,008 e ação errada de 0,0199. Esse último valor ficou quase no limite de 0,02.

Acurácia nas falas reais (27 frases)

Duas rodadas de 21/10. A rejeitada errou 3 das 27 frases.

Ver dados
Rejeitada88,9%
Promovida100%

O conjunto held-out vem da mesma distribuição de dados usada no treino. Ele mede quanto o modelo aprendeu desse conjunto. As falas reais mostram se ele entende o que realmente digo. A rodada com a maior nota foi justamente a que o portão barrou.

O que ainda me morde

Em 17 de outubro, a primeira chamada ficou lenta. Parecia que o modelo estava ocioso. O problema era pressão de memória: o processo mostrava RSS de 0,07 GB e memória física ocupada de 2,73 GB. A memória swap estava em 19,0 de 20,5 GB e a média de carga em 13,9. O RSS, que mede parte da memória usada pelo processo, me enganou de novo.

Um deploy, ou publicação de uma nova versão do serviço, reconstruiu o ambiente Python e matou uma rodada mais longa depois de cerca de 4 horas. Com rodadas tão demoradas, eu protegeria o ambiente de treino para que nenhum deploy pudesse alterá-lo.

Ajudo equipes a usar agentes de IA no trabalho de engenharia. Se sua equipe está começando, vamos conversar.

Ver consultoria