Avançado

Mixed precision: fp16, bf16, fp8

Treino em mixed precision usa formatos compactos para velocidade e protege operações sensíveis com aritmética mais larga; master weights fp32 são uma receita conservadora, não fato documentado do treino do Qwen nem exigência universal.

Atualizada em

01 · Conceito

Conceito

Baixe o Qwen3.8-27B e os safetensors lançados estão em bf16: cerca de 2 bytes por parâmetro armazenado. Esse fato descreve o checkpoint distribuído, não os dtypes de optimizer, master weights, acumulação ou gradientes usados no treino. A receita de treino não foi publicada. O design de mixed precision precisa, portanto, ser ensinado como um conjunto de políticas explícitas e salvaguardas medidas, não reconstruído como história do Qwen a partir do dtype de saída.

Comece pelo que um formato de ponto flutuante está comprando. Os bits se dividem entre sinal, expoente e fração. Mais bits de expoente ampliam o alcance dinâmico; mais bits de fração afiam a precisão local. O fp16 gasta cinco bits em expoente e dez bits explícitos em fração: preciso perto de uma dada magnitude, mas com um alcance tão estreito que overflow e underflow são rotina no treino. O bf16 gasta oito bits em expoente — a mesma largura do fp32 — e sete bits explícitos de fração, então quase nunca transborda e é correspondentemente grosseiro.

Grosseiro como? Um valor fp16 ou bf16 carrega um um implícito à esquerda, então os 7 bits explícitos de fração do bf16 dão 8 bits de significando. Perto de um peso de magnitude 1,0, o menor passo representável é portanto

27=11280.0078.2^{-7}=\frac{1}{128}\approx 0.0078.

Agora considere um update realista do optimizer. Tarde no treino, com um learning rate já decaído, uma mudança típica de parâmetro é da ordem de 10510^{-5} relativa ao peso. Some isso diretamente a um peso bf16 de 1,0:

1.0+0.00001=1.00001arredonda de volta para 1.0,1.0+0.00001 = 1.00001 \longrightarrow \text{arredonda de volta para } 1.0,

porque o próximo valor bf16 representável acima de 1,0 é 1,0078125, e 1,00001 não está nem perto da metade do caminho. O update não encolhe. Ele desaparece. Repita isso por 100.000 passos e o peso continua sem se mover, ainda que a mudança pretendida acumulada fosse de cerca de 1,0 — uma unidade inteira de deriva, silenciosamente descartada um passo por vez. Isso é swamping, e é a razão de o treino em mixed precision existir.

Uma correção conservadora é uma cópia master em fp32. Os updates se acumulam ali, onde o significando tem 24 bits e 10510^{-5} é representável contra 1,0 com folga, e os tensores bf16 usados no forward pass são regenerados a partir dela. O custo de armazenamento desse estado master é 4 bytes por parâmetro. A lição 9.3 assume o orçamento em bytes do modelo para todo o curso; aqui o ponto importante é condicional: se uma receita mantém master weights fp32 e dois momentos AdamW fp32 junto de parâmetros e gradientes bf16, ela chega a cerca de 16 bytes persistentes por parâmetro. Variantes pure-bf16/AnyPrecision usam outras políticas de estado e precisam demonstrar estabilidade empiricamente.

Agora a comparação que costuma ser feita errado. Treinar tudo em fp32 — 4 bytes para cada um: pesos, gradientes e os dois momentos — também custa 16 bytes por parâmetro. Sob essa receita conservadora, mixed precision não reduz a pegada persistente do optimizer. O que ela compra são as unidades matriciais rápidas de precisão reduzida do acelerador, aproximadamente metade da largura de banda em cada peso e gradiente que move, e activations armazenadas em 2 bytes em vez de 4 — que é a memória que de fato domina um passo de contexto longo, como a lição 5.10 desenvolve. Alternativas numericamente seguras podem usar outros dtypes de estado, mas cada uma precisa ser validada contra uma baseline de precisão mais larga.

Dynamic loss scaling é a salvaguarda específica do fp16 para a falha oposta. Multiplique a loss por uma escala antes do backward para que gradientes pequenos caiam dentro do alcance representável do fp16; antes do passo do optimizer, desfaça a escala e verifique valores não finitos, pulando o update e baixando a escala em caso de overflow, elevando-a com cautela após passos estáveis. Em aritmética exata a escala se cancela; em representação finita o caminho importa. O alcance do bf16 em geral torna isso desnecessário, o que é uma das razões de ele ter virado o padrão indulgente em hardware que o suporta.

O fp8 vai além, com oito bits totais em formatos que trocam expoente por fração — comumente E4M3 e E5M2. Reduzir o armazenamento de pesos à metade de novo levaria nossos 54 GB a 27 GB, e as unidades matriciais suportadas ficam ainda mais rápidas, mas o cast bruto é inseguro. As receitas mantêm escalas para que os valores dos tensores ocupem o alcance representável útil, escolhem formatos por operação, acumulam em precisão mais larga e monitoram saturação. O escalonamento pode ser por tensor, por canal ou por bloco: uma única escala para o tensor inteiro é barata, mas deixa um outlier desperdiçar a maior parte do alcance, enquanto escalas mais finas acomodam distribuições variadas ao preço de metadados e complexidade de kernel. O escalonamento atrasado reaproveita máximos recentes para escolher uma escala para passos posteriores, trocando responsividade por estabilidade.

A distribuição torna isso mais difícil de formas que vale antecipar. Um gradiente pode ser finito em todo rank e transbordar durante a redução. A comunicação pode usar um dtype distinto do armazenamento do optimizer. De forma mais sutil, a lição 5.8 particiona um tensor lógico entre ranks de tensor parallel — e esses ranks precisam concordar sobre a escala dele, ou seus produtos parciais não estão em pé de igualdade quando combinados. Checkpoints precisam de metadados suficientes para retomar a receita de precisão inteira, gradient scaler incluído.

Algumas operações permanecem largas de qualquer jeito: reduções, normalização do softmax, cálculo da loss, estatísticas do RMSNorm, momentos do optimizer e master weights quando a receita escolhida os mantém largos. Kernels numericamente estáveis frequentemente aceitam entradas de baixa precisão e acumulam internamente em fp32, então inspecione a política da operação em vez de inferir a precisão a partir do dtype do parâmetro. Valide contra uma baseline confiável de precisão mais larga, observando curvas de loss, normas de gradiente, passos pulados, contagens de overflow e métricas downstream — uma run curta sem valores não finitos é evidência fraca, já que diferenças de arredondamento entortam uma trajetória gradualmente em vez de quebrá-la.

A regra estável é gastar bits onde eles protegem informação. Formatos estreitos aceleram trabalho matricial grande e tolerante; formatos mais largos acumulam muitas contribuições e guardam estado sensível. O checkpoint bf16 que você baixa estabelece apenas o dtype dos pesos lançados. A política de precisão que o produziu continua desconhecida enquanto a receita de treino não for publicada.

02 · Analogia

Analogia

Uma equipe de topografia carrega réguas de bolso para medidas de rotina e um instrumento de laboratório calibrado para tolerâncias minúsculas e totais finais. Uma régua de bolso é mais rápida de carregar, mas tem alcance e detalhe limitados. A mixed precision atribui réguas baratas ao grande trabalho matricial enquanto mantém acumulação, normalização ou registros master onde o alcance extra importa. Usar uma régua só em tudo é mais simples, mas pode transbordar uma montanha ou arredondar um fio de cabelo a zero.

03 · Explique de volta

Explique de volta

Compare fp16, bf16 e fp8 em alcance e precisão, explique quando uma cópia master fp32 protege updates pequenos e diferencie essa receita do que se sabe publicamente sobre o treino do Qwen3.8-27B.

Mínimo: 80 caracteres e 15 palavras. Seu texto fica somente neste navegador.

Aguardando sua explicação.

Comparar com uma resposta-modelo

Os safetensors lançados do Qwen estão em bf16, portanto o checkpoint armazena aproximadamente 2 bytes por parâmetro; os dtypes do estado de treino não foram publicados. O bf16 tem sete bits explícitos de fração, então updates in-place muito menores que o espaçamento local podem arredondar para zero. Uma receita conservadora comum atualiza master weights fp32 e faz cast de cópias de compute em precisão reduzida, mas também existem receitas pure-bf16/AnyPrecision validadas. O fp16 tem mais bits de fração, mas alcance de expoente menor, e frequentemente precisa de loss scaling. O bf16 mantém a largura de expoente do fp32 com significando mais grosseiro. O fp8 exige escalonamento explícito, acumulação mais larga e validação específica do hardware.

04 · Teste seu entendimento

Teste seu entendimento

01Por que uma receita conservadora de mixed precision pode manter master weights fp32 quando o compute usa bf16?
Resposta e explicação

Updates pequenos podem ficar abaixo do espaçamento bf16 perto de um peso grande, então estado master mais largo consegue acumulá-los antes do cast — Uma cópia master fp32 é uma forma de evitar swamping; não é a única receita viável, e a Qwen não publica qual política de estado de treino produziu este checkpoint.

02A lição 5.8 particionou um tensor lógico entre ranks de tensor parallel. O que isso implica para os fatores de escala do fp8?
Resposta e explicação

Ranks que possuem conjuntamente um tensor lógico precisam concordar sobre a escala dele, ou seus resultados parciais não podem ser combinados corretamente — Produtos parciais de shards escalados de formas diferentes não estão em pé de igualdade; a escala precisa ser sincronizada onde quer que o tensor seja logicamente compartilhado.

03Qual grande vantagem de alcance o bf16 tem sobre o fp16?
Resposta e explicação

Uma largura de expoente igual à do fp32 — O bf16 sacrifica precisão de mantissa enquanto retém o amplo alcance de expoente do fp32.

Conclua o teach-back e acerte o quiz para finalizar a aula.

◎ · Marcador de evidência

Fontes

  1. Paulius Micikevicius et al. (2018). Mixed Precision Training.
  2. Paulius Micikevicius et al. (2022). FP8 Formats for Deep Learning.
  3. Qwen Team (2026). Qwen3.8-27B Model Card.
  4. PyTorch Team (2024). Efficient Large-Scale Training with Pytorch FSDP and AWS.