FP8
FP8 é um formato de ponto flutuante de 8 bits com variantes E4M3 e E5M2, que reduz pela metade o uso de memória em comparação com 16 bits e dobra a taxa de processamento de matrizes em GPUs compatíveis.
FP8 é um formato de ponto flutuante de 8 bits usado para treinar e executar redes neurais com metade da memória e do tráfego de dados dos formatos de 16 bits. Como em qualquer tipo de ponto flutuante, cada valor tem um bit de sinal, bits de expoente que determinam seu intervalo e bits de mantissa que determinam sua precisão, mas, com apenas oito bits no total, o formato abre mão de muito em ambos os aspectos. Engenheiros da NVIDIA, da Arm e da Intel definiram as duas variantes padrão, E4M3 e E5M2, no artigo de setembro de 2022 Formatos FP8 para aprendizagem profunda e validaram o treinamento de modelos de linguagem com até 175 bilhões de parâmetros usando esses formatos. Em GPUs com Tensor Cores FP8, como a Hopper H100 da NVIDIA, lançada em 2022, as multiplicações de matrizes FP8 atingem o dobro da taxa de processamento de FP16 ou BF16.
E4M3 e E5M2#
As duas variantes dividem de forma diferente os sete bits que não são de sinal:
- E4M3: quatro bits de expoente e três bits de mantissa. Abre mão de valores infinitos e mantém um único padrão NaN para chegar ao máximo de 448; é adequado para pesos e ativações na passagem direta.
- E5M2: cinco bits de expoente e dois bits de mantissa, seguindo as convenções IEEE 754 para valores especiais. Chega a 57.344 com incrementos mais grosseiros e é adequado para gradientes, cujas magnitudes variam em um intervalo maior.
Os dois formatos levam valores pequenos a zero e limitam os valores grandes, então tensores FP8 geralmente carregam um fator de escala que desloca seus valores para o intervalo representável. Converter valores do tamanho de gradientes com e sem um fator de escala demonstra o motivo:
import torch
torch.manual_seed(0)
grads = torch.randn(10_000) * 1e-4 # gradient-sized values, far below 1
e4m3, e5m2 = torch.float8_e4m3fn, torch.float8_e5m2
print(f"E4M3 max {torch.finfo(e4m3).max:g}, E5M2 max {torch.finfo(e5m2).max:g}")
# Per-tensor scaling maps the largest magnitude onto the E4M3 maximum before casting
scale = torch.finfo(e4m3).max / grads.abs().max()
results = {
"E4M3 direct": grads.to(e4m3).float(),
"E5M2 direct": grads.to(e5m2).float(),
"E4M3 scaled": (grads * scale).to(e4m3).float() / scale,
}
for name, restored in results.items():
zeros = (restored == 0).float().mean()
error = ((restored - grads).abs() / grads.abs()).median()
print(f"{name}: {zeros:.0%} rounded to zero, median relative error {error:.1%}")Uma conversão direta para E4M3 arredonda 100% dos valores para zero; o intervalo mais amplo do E5M2 mantém a maioria deles, com erro relativo mediano de 6.4% e 7% descartados; e aplicar a escala primeiro permite que o E4M3 mantenha todos os valores com erro mediano de 2.2%. O PyTorch também oferece float8_e4m3fnuz e float8_e5m2fnuz, as variantes usadas pelos aceleradores MI300 da AMD, que descartam o zero negativo e deslocam o viés do expoente, limitando o E4M3 a 240. Portanto, um modelo FP8 não é automaticamente portátil entre fornecedores.
Estratégias de escalonamento#
Usar uma escala para um tensor inteiro falha quando alguns valores atípicos determinam o máximo e empurram todo o resto para perto de zero, algo comum nas ativações de Transformers. As estratégias diferem no nível de granularidade da escala:
- Escalonamento atrasado por tensor: o Transformer Engine da NVIDIA escolhe a escala de cada tensor com base nos valores máximos observados nas etapas recentes de treinamento, sem exigir uma passagem adicional pelos dados.
- Escalonamento por bloco: o DeepSeek-V3 escalonou as ativações por blocos de 1 × 128 valores e os pesos por blocos de 128 × 128, e sua equipe relatou a primeira validação do treinamento FP8 em um modelo extremamente grande, com 671 bilhões de parâmetros.
- MXFP8: o formato de microscaling do Open Compute Project compartilha uma escala de potência de dois a cada 32 valores, e as GPUs Blackwell da NVIDIA executam esse formato em hardware.
As multiplicações de matrizes acumulam os resultados em maior precisão, e camadas sensíveis ou de baixo custo, como normalização, softmax e os pesos principais do otimizador, permanecem em BF16 ou FP32. Portanto, FP8 é apenas uma parte de uma estratégia de precisão mista.
FP8 no treinamento e na inferência#
No treinamento, o Transformer Engine e o TorchAO da NVIDIA substituem camadas lineares por versões FP8, mantendo os pesos principais em maior precisão. Na inferência, mecanismos de disponibilização armazenam os pesos do modelo e o cache KV dos modelos de linguagem de grande porte em FP8, reduzindo pela metade a memória em comparação com formatos de 16 bits e deixando espaço para mais solicitações simultâneas. O TensorRT também cria mecanismos FP8 para GPUs com Tensor Cores FP8. O formato precisa de suporte de hardware para valer a pena: a A100 da NVIDIA executa FP16, BF16 e INT8 nos Tensor Cores, mas não tem unidades FP8, enquanto as GPUs Ada Lovelace, Hopper e Blackwell e a série MI300 da AMD têm.
FP8 fica entre os formatos próximos:
- FP16 ou precisão simples: o dobro de bits, com 10 bits de mantissa e alcance suficiente para a maioria das inferências sem escalas por tensor.
- FP4: metade dos bits novamente, dependendo de escalas de bloco granulares para manter a precisão.
- INT8: o outro formato de 8 bits, com 256 níveis igualmente espaçados, em vez do espaçamento baseado em expoente do FP8; por isso, exige escalas calibradas, mas é executado em muito mais hardware, incluindo a maioria das CPUs e NPUs.
O Ultralytics YOLO26 usa INT8 para inferência de 8 bits: exportar com quantize=8 no modo de exportação para formatos como TensorRT e OpenVINO executa a quantização de modelos pós-treinamento, que calibra as escalas usando imagens do conjunto de dados data, enquanto um modelo ajustado com quantize=8 por meio do treinamento com reconhecimento de quantização é exportado para TensorRT com os intervalos que aprendeu, sem precisar de calibração.










