Buscar/Alterar código distribuído de treinamento e inferência de aprendizado de máquina sem quebrá-lo

Alterar código distribuído de treinamento e inferência de aprendizado de máquina sem quebrá-lo

Use ao mudar software que treina ou executa modelos de aprendizado de máquina em muitos processos ou aceleradores. Consulta antes de mudanças arriscadas, alinha versões de pesos e a ordem das operações coletivas em cada rank, mantém a configuração compatível e informa os testes pulados.

Para usar estas regras de IA
## Ler o código primeiro e consultar antes de mudar a configuração compartilhada ou as APIs Antes de editar, leia a implementação relevante, os padrões dos módulos próximos, os contratos de configuração e os testes. Use o gerenciador de ambientes, o formatador, o linter e o conjunto de ferramentas de pre-commit do projeto; não contorne os hooks. Nunca fixe no código credenciais, caminhos de máquinas, endpoints de serviços ou a topologia do cluster. Não presuma configurações do escalonador nem reconstrua os drivers e as pilhas de execução dos aceleradores como atalho para solucionar problemas. Obtenha uma decisão antes de: - alterar estruturas de configuração compartilhadas; - adicionar dependências; - alterar o comportamento do inicializador ou do escalonador; - excluir ou renomear APIs públicas, ou alterá-las de forma incompatível. Se o hardware necessário ou o acesso ao cluster não estiver disponível, informe quais verificações de integração foram omitidas e por quê. Não transforme em código uma suposição não verificada sobre o sistema distribuído. Encaminhe o trabalho de acordo com o subsistema: motor de treinamento, motor de inferência, algoritmo, inicializador, escalonador, conjunto de dados, recompensa, fluxo de trabalho ou depuração distribuída. Use o guia especializado de implementação ou o processo de revisão do domínio oferecido pelo projeto, quando houver. ## Separar cada subsistema e marcar os dados com a versão dos pesos Mantenha como responsabilidades distintas a orquestração, a geração de rollouts, o treinamento, a inferência, a infraestrutura, a adaptação de modelos, as recompensas, os conjuntos de dados e os utilitários transversais. O componente de treinamento coordena o loop, o carregamento de dados e os fluxos de trabalho. Os fluxos de trabalho de rollout definem a geração assíncrona de episódios. Os motores de inferência geram saídas e recebem atualizações de pesos; os motores de treinamento consomem tensores de rollout, calculam atualizações e publicam novas versões de pesos. Em sistemas assíncronos, anexe metadados explícitos da versão dos pesos aos dados gerados e às atualizações. Nunca treine nem avalie com versões do modelo que não correspondam entre si sem que isso seja percebido. Emita métricas por meio do rastreador padrão, armazene os artefatos de forma persistente sob a raiz de saída configurada e use o caminho canônico de salvamento e recuperação dos checkpoints. A observabilidade e a recuperação fazem parte do contrato de execução. Prefira composição e delegação a uma hierarquia de herança profunda. Mantenha os limites de extensão pequenos o suficiente para que motores, fluxos de trabalho e adaptadores de modelos possam ser testados de forma independente. ## Escrever código rápido para aceleradores sem sincronizar dispositivo e host Siga as convenções existentes de nomenclatura, tipagem e registro do módulo responsável. Use anotações de tipo e importações explícitas; nunca use importações curinga. Mantenha dependências opcionais pesadas dentro das funções ou dos caminhos de código que precisem delas. Use o logger do projeto em vez de imprimir diretamente. Inclua nos registros o contexto do componente e do rank distribuído para que a origem das saídas simultâneas continue identificável. Nos caminhos críticos do acelerador: - evite a sincronização entre dispositivo e host, como extrair valores escalares ou listas para registrá-los; - agrupe as operações com tensores, em vez de percorrer elementos individuais em Python; - defina explicitamente o dispositivo e o tipo de dados; - verifique, com asserções, as formas esperadas dos tensores nos limites. Mantenha os fluxos de trabalho de rollout sem bloqueios. Aguarde as chamadas assíncronas aos motores e as operações de arquivo; não introduza E/S síncrona em um caminho assíncrono de episódios. Para um novo recurso, siga o padrão do módulo funcional mais próximo, adicione testes específicos e evite refatorações não relacionadas. ## Mudar campos de configuração e APIs públicas sem quebrar quem os usa Ordene os campos de configuração começando pelos obrigatórios, seguidos dos opcionais comuns, dos opcionais raros e, por fim, dos campos internos. Valide-os na inicialização com uma exceção clara que identifique o valor inválido ou a restrição violada. Adicione campos públicos com valores padrão seguros. Marque-os como obsoletos antes de removê-los e evite alterar tipos de campos já estabelecidos. As classes públicas de configuração devem documentar as restrições e os valores aceitos. Represente opções finitas da linha de comando com tipos restritos, em vez de strings de formato livre. Reutilize as classes de dados de configuração canônicas, em vez de criar estruturas paralelas. Trate configurações compartilhadas, inicializadores, escalonadores e nomes de APIs públicas como áreas de alto impacto. Torne explícito o efeito sobre a compatibilidade na descrição da alteração e obtenha aprovação antes de realizar edições destrutivas ou incompatíveis. Quando não for possível decidir o comportamento correto com base nos contratos atuais, deixe um marcador de acompanhamento com escopo claramente definido e informe a restrição não resolvida, em vez de inventar um valor padrão. ## Manter grupos de processos e operações coletivas iguais em todos os ranks Nunca crie um grupo de processos global no momento da importação. Passe explicitamente o grupo de processos pretendido e consulte o rank em relação a esse grupo quando a associação ao grupo for relevante. Mantenha as dimensões da malha de dispositivos alinhadas ao modelo de paralelismo declarado, incluindo, quando aplicável, os eixos de particionamento de dados, tensor, contexto, especialista e tensor de especialista. As operações coletivas são contratos globais: - todos os ranks participantes devem chamar a mesma operação all-reduce na mesma ordem; - selecione deliberadamente a operação de redução, por exemplo, entre soma e média; - as operações de broadcast devem indicar explicitamente um rank de origem; - barreiras são ferramentas de diagnóstico, não uma estratégia rotineira de sincronização. Diagnostique travamentos verificando se há divergência nas sequências de operações coletivas. Diagnostique resultados incorretos verificando a semântica de redução e as versões dos pesos. Diagnostique falhas por falta de memória verificando o particionamento, o posicionamento dos tensores e a propriedade dos dispositivos antes de reduzir a funcionalidade do modelo. Use diagnósticos detalhados da execução distribuída, da biblioteca de comunicação e da inicialização síncrona somente para depuração direcionada, e remova-os ou desative-os depois que o problema for compreendido. ## Testar o código distribuído e listar no pull request os testes pulados Nomeie os testes de acordo com o comportamento, a condição e o resultado esperado, e estruture-os em preparação, execução e verificação. Marque os testes lentos, assíncronos, de acelerador e distribuídos para que a CI padrão possa selecionar os conjuntos corretos. Omita de forma controlada os testes de acelerador ou de vários nós que não estiverem disponíveis e informe explicitamente o motivo. Use o grupo de processos simulado do framework para testar o comportamento distribuído no nível da unidade; não simule os mecanismos internos de particionamento profundo nem de tensores distribuídos cuja semântica o teste deva verificar. Compare tensores com tolerâncias relativas e absolutas explícitas. Prefira caminhos temporários gerenciados e monkeypatches com escopo limitado. Execute primeiro o conjunto restrito de testes de unidade e depois, quando o hardware permitir, o conjunto de testes de acelerador ou distribuídos diretamente afetado. Execute toda a cadeia de formatação e pre-commit antes do envio. Gere a documentação de referência da linha de comando com o gerador canônico. Gere a documentação da versão por meio do wrapper do projeto que realiza a configuração estática e o empacotamento necessários, e não com um comando de documentação de nível inferior que omita etapas do projeto. Na pull request, identifique o problema, as áreas de risco, os comandos de teste exatos, os conjuntos omitidos e seus motivos, além de qualquer limitação de hardware. Use assuntos de commit convencionais e no imperativo, e remova os commits de trabalho em andamento antes da revisão.