O formato de ponto flutuante bfloat16 (brain floating point, ou ponto flutuante cerebral) é um formato de número de computador que ocupa 16 bits na memória do computador; ele representa um amplo alcance dinâmico de valores numéricos ao utilizar uma vírgula flutuante (ponto flutuante). Este formato é uma versão encurtada (de 16 bits) do formato de ponto flutuante de precisão simples IEEE 754 de 32 bits (binary32), com o intuito de acelerar o aprendizado de máquina e a computação próxima ao sensor. Ele preserva o alcance dinâmico aproximado dos números de ponto flutuante de 32 bits ao reter os 8 bits de expoente, mas suporta apenas uma precisão de 8 bits em vez do significando de 24 bits do formato binary32. Mais ainda do que os números de ponto flutuante de precisão simples de 32 bits, os números bfloat16 são inadequados para cálculos de inteiros, mas este não é o seu uso pretendido. O bfloat16 é utilizado para reduzir os requisitos de armazenamento e aumentar a velocidade de cálculo de algoritmos de aprendizado de máquina.

O formato bfloat16 foi desenvolvido pelo Google Brain, um grupo de pesquisa em inteligência artificial do Google. Ele é utilizado em muitas CPUs, GPUs e processadores de IA, tais como os processadores Intel Xeon (extensões AVX-512 BF16), Intel Data Center GPU, Intel Nervana NNP-L1000, FPGAs da Intel, AMD Zen, AMD Instinct, GPUs da NVIDIA, TPUs do Google Cloud, AWS Inferentia, AWS Trainium, ARMv8.6-A, e os chips M2, A15 e posteriores da Apple. Muitas bibliotecas suportam o bfloat16, tais como CUDA, Intel oneAPI Math Kernel Library, AMD ROCm, AMD Optimizing CPU Libraries, PyTorch e TensorFlow. Nessas plataformas, o bfloat16 também pode ser usado em aritmética de precisão mista, onde números bfloat16 podem ser operados e expandidos para tipos de dados mais amplos.

Formato de ponto flutuante bfloat16

O bfloat16 possui o seguinte formato: Bit de sinal: 1 bit Largura do expoente: 8 bits Precisão do significando: 8 bits (7 explicitamente armazenados, com um bit condutor implícito), em oposição aos 24 bits em um formato de ponto flutuante clássico de precisão simples

O formato bfloat16, sendo um float de 32 bits de precisão simples IEEE 754 encurtado, permite uma rápida conversão de e para um float de 32 bits de precisão simples IEEE 754; na conversão para o formato bfloat16, os bits do expoente são preservados enquanto o campo do significando pode ser reduzido por truncamento (correspondendo assim ao arredondamento em direção a 0) ou outros mecanismos de arredondamento, ignorando o caso especial de NaN. A preservação dos bits do expoente mantém o intervalo do float de 32 bits de ≈ 10−38 a ≈ 3 × 1038.

Os bits são dispostos da seguinte forma:

Meia precisão IEEE float de 16 bits sinal expoente (5 bit) fração (10 bit)   ┃  0   0   1   1   0   0   0   1   0   0   0   0   0   0   0   0  15 14 10 9 0   bfloat16 sinal expoente (8 bit) fração (7 bit)   ┃  0   0   1   1   1   1   1   0   0   0   1   0   0   0   0   0  15 14 7 6 0   TensorFloat-32 da Nvidia (19 bits) sinal expoente (8 bit) fração (10 bit)   ┃  0   0   1   1   1   1   1   0   0   0   1   0   0   0   0   0   0   0   0  18 17 10 9 0   Formato fp24 da ATI sinal expoente (7 bit) fração (16 bit)   ┃  0   0   1   1   1   1   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0  23 22 16 15 0   Formato PXR24 da Pixar sinal expoente (8 bit) fração (15 bit)   ┃  0   0   1   1   1   1   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0  23 22 15 14 0   Precisão simples IEEE 754 float de 32 bits sinal expoente (8 bit) fração (23 bit)   ┃  0   0   1   1   1   1   1   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  31 30 23 22 0

Codificação do expoente O expoente de ponto flutuante binário do bfloat16 é codificado usando uma representação em binário deslocado, com o deslocamento zero sendo 127; também conhecido como viés do expoente no padrão IEEE 754. Emin = 01H−7FH = −126 Emax = FEH−7FH = 127 Viés do expoente = 7FH = 127

Assim, para obter o expoente verdadeiro conforme definido pela representação em binário deslocado, o deslocamento de 127 deve ser subtraído do valor do campo do expoente.

Os valores mínimo e máximo do campo do expoente (00H and FFH) são interpretados de forma especial, assim como nos formatos padrão IEEE 754. ExpoenteSignificando zeroSignificando não nuloEquação00Hzero, −0números subnormais(−1)bitdesinal×2−126× 0.bitsdosignificando01H, ..., FEHvalor normalizado(−1)bitdesinal×2bitsdoexpoente−127× 1.bitsdosignificandoFFH±infinitoNaN (quiet, signaling) O menor valor normal positivo é 2−126 ≈ 1,18 × 10−38 e o menor valor positivo (subnormal) é 2−126−7 = 2−133 ≈ 9,2 × 10−41.

Arredondamento e conversão

O caso de uso mais comum é a conversão entre o IEEE 754 binary32 e o bfloat16. A seção a seguir descreve o processo de conversão e seu esquema de arredondamento. Note que existem outros cenários possíveis de conversões de formato de ou para o bfloat16, por exemplo, de int16 para bfloat16.

De binary32 para bfloat16: quando o bfloat16 foi introduzido pela primeira vez como um formato de armazenamento, a conversão do IEEE 754 binary32 (ponto flutuante de 32 bits) para bfloat16 se dava por truncamento (arredondamento em direção a 0). Mais tarde, quando ele passou a ser a entrada de unidades de multiplicação de matrizes, a conversão passou a contar com vários mecanismos de arredondamento dependendo das plataformas de hardware. Por exemplo, para as TPUs do Google, o esquema de arredondamento na conversão é o arredondamento para o par mais próximo (round-to-nearest-even); a ARM utiliza o modo não IEEE Round-to-Odd (aritmética de arredondamento para o ímpar); a NVIDIA suporta a conversão de números float para a precisão bfloat16 no modo de arredondamento para o par mais próximo. De bfloat16 para binary32: como o binary32 pode representar todos os valores exatos contidos no bfloat16, a conversão simplesmente preenche os bits do significando com 16 zeros.

Codificação de valores especiais

Infinito positivo e negativo Assim como no IEEE 754, o infinito positivo e o negativo são representados com seus respectivos bits de sinal, todos os 8 bits do expoente definidos como um (FFhex) e todos os bits do significando iguais a zero. Explicitamente: val s_exponent_signcnd +inf = 0_11111111_0000000 -inf = 1_11111111_0000000

Not a Number Assim como no IEEE 754, os valores NaN são representados com qualquer bit de sinal, todos os 8 bits do expoente definidos como um (FFhex) e os bits do significando não todos iguais a zero. Explicitamente: val s_exponent_signcnd +NaN = 0_11111111_klmnopq -NaN = 1_11111111_klmnopqonde pelo menos um dentre k, l, m, n, o, p ou q é igual a 1. Da mesma forma que no IEEE 754, os valores NaN podem ser quietos (qNaN) ou sinalizadores (sNaN), embora não existam usos conhecidos de NaNs sinalizadores em bfloat16.

Intervalo e precisão

O bfloat16 foi projetado para manter o intervalo numérico do format de ponto flutuante de precisão simples IEEE 754 de 32 bits (binary32), enquanto reduz a precisão de 24 bits para 8 bits. Isso significa que a precisão fica entre dois e três dígitos decimais, e o bfloat16 pode representar valores finitos de até cerca de 3,4 × 1038.

Exemplos

Estes exemplos são dados na representação de bits, em hexadecimal e binário, do valor de ponto flutuante. Isso inclui o sinal, o expoente (com viés) e o significando. 3f80 = 0 01111111 0000000 = 1 c000 = 1 10000000 0000000 = −2

7f7f = 0 11111110 1111111 = (28 − 1) × 2−7 × 2127 ≈ 3,38953139 × 1038 (valor positivo finito máximo em precisão bfloat16) 0080 = 0 00000001 0000000 = 2−126 ≈ 1,175494351 × 10−38 (valor positivo normal mínimo em precisão bfloat16 e em ponto flutuante de precisão simples) O valor finito positivo máximo de um número bfloat16 normal é 3,38953139 × 1038, ligeiramente abaixo de (224 − 1) × 2−23 × 2127 = 3,402823466 × 1038, que é o valor positivo finito máximo representável em precisão simples.

Zeros e infinitos 0000 = 0 00000000 0000000 = 0 8000 = 1 00000000 0000000 = −0

7f80 = 0 11111111 0000000 = infinito ff80 = 1 11111111 0000000 = −infinito

Valores especiais 4049 = 0 10000000 1001001 = 3,140625 ≈ π ( pi ) 3eab = 0 01111101 0101011 = 0,333984375 ≈ 1/3

NaNs ffc1 = x 11111111 1000001 => qNaN ff81 = x 11111111 0000001 => sNaN

Ver também Formato de ponto flutuante de meia precisão: float de 16 bits com 1 bit de sinal, expoente de 5 bits e significando de 11 bits, conforme definido pelo IEEE 754 Minifloat Google Brain

Categoria:Aritmética computacional