Como criamos os LLMs de última geração do DeepL com o FP8 para treinamento e inferência

Quando DeepL implementou nosso atual NVIDIA DGX SuperPOD com 544 GPUs NVIDIA H100 Tensor Core, não obtivemos apenas um grande aumento no poder de computação. A H100 também apresenta suporte nativo para tipos de dados de ponto flutuante de 8 bits (FP8), por meio de uma nova geração de Tensor Cores, que permite que a GPU realize multiplicações de matriz e outras operações de tensor com precisão FP8. Ao computar multiplicações de matrizes no FP8, podemos aumentar a taxa de transferência ao treinar e implementar nossos grandes modelos de linguagem (LLMs), já que a maior parte da computação envolvida nos LLMs modernos assume a forma de multiplicações de matrizes.

A mudança dos cálculos da precisão de 16 bits para 8 bits gerou um grande impacto no desenvolvimento dos LLMs de última geração do DeepL. Isso nos permite criar modelos de IA linguística muito maiores, com muito mais parâmetros que melhoram significativamente a qualidade quando avaliados por especialistas em idiomas, mas dentro da mesma janela de latência para inferência de produção. Isso significa que as traduções superam nossos modelos anteriores em 1,4x para idiomas europeus e em 1,7x para combinações de idiomas mais complexas, como inglês e japonês, mas fornecem resultados com a mesma rapidez. Isso também significa que nossos modelos podem lidar com um número maior de solicitações em mais recursos e funções, sem comprometer a experiência do usuário.

Em outras palavras, o treinamento e a inferência do FP8 desempenharam um papel central no dimensionamento da IA linguística do DeepL.

Nesta publicação, queremos explicar a jornada que percorremos para aplicar o FP8 para treinamento e inferência, compartilhar algumas das ferramentas e técnicas que sustentam esse sucesso e dar a você uma ideia dos resultados que geramos em termos de desempenho de treinamento e inferência ao longo do caminho. 

Qual é a diferença entre os formatos BF16 e FP8?

A explicação simples da diferença entre o BFloat16 (BF16) e o FP8 é que o último usa metade dos bits para expressar valores. Na verdade, o BF16 usa as 16 posições disponíveis em dois bytes de 8 bits cada. O FP8 usa apenas um byte. 

O número de bits disponíveis determina a precisão com a qual você pode implementar os elementos mantissa e expoente dos números de ponto flutuante em notação científica. O BF16 tem 1 bit de sinal, 8 bits para o expoente e 7 bits para a mantissa. O FP8 tem metade do número de bits para você usar, com 1 bit de sinal e 7 bits divididos entre o expoente e a mantissa. Por esse motivo, ele tem um alcance menor e uma precisão mais baixa do que o BF16. Ele pode representar um intervalo mais estreito e menos números dentro desse intervalo.

Como exemplo, digamos que você queira representar a idade da Terra em bilhões de anos (aproximadamente 4.543). No BF16, podemos representar isso precisamente como 0100000010010001.  

O que você acha de representar esse número no FP8? Na verdade, há dois formatos de FP8 para você escolher: E4M3 e E5M2. As letras e os números aqui representam a maneira como os bits são distribuídos entre o expoente (E) e a mantissa (M). Quanto mais bits você dedicar ao expoente, maior será o intervalo de números que você pode descrever, e quanto mais bits você dedicar à mantissa, mais números você poderá descrever dentro desse intervalo. 

Seja qual for o formato FP8 que você escolher, não é realmente possível representar 4,543 com precisão. Se você escolher o E4M3 com sua precisão relativamente maior, poderá chegar mais perto (4,5). Em E5M2, o mais próximo que você pode chegar é 5.

Em contrapartida a essa falta de alcance e precisão, o FP8 permite uma computação mais rápida e requer uma memória significativamente menor em comparação com o BF16. Isso é extremamente valioso para a inferência e, com a abordagem correta, também pode ser extremamente valioso para acelerar o treinamento. Você precisa saber qual é o alcance e a precisão que o treinamento do LLM realmente precisa. Você precisa representar a idade da Terra com precisão? Ou será que chegar a 43 milhões de anos é suficiente? Se você estiver interessado no universo como um todo, provavelmente ficará satisfeito com esse segundo nível de precisão. O erro de arredondamento representa apenas cerca de 0,3% da idade do universo, afinal de contas.

A jornada de DeepL prova que o FP8 pode oferecer o que é necessário para o treinamento de LLM de alta qualidade, e isso abriu novas possibilidades para o que treinamos em nossos modelos e como os implementamos na prática.

Pré-treinamento para DeepL LLMs

A jornada que percorremos com o treinamento e a inferência do FP8 começa com o pré-treinamento de nossos LLMs. Após o pré-treinamento, ajustamos nossos modelos em determinadas tarefas, destilamos modelos grandes em modelos menores, fazemos aprendizado por reforço e implementamos um conjunto de estratégias de paralelização para que você possa usar o grande número de GPUs que temos.

Aplicando o formato FP8 para treinar com precisão mista

Fizemos a transição do nosso código de treinamento existente do BF16 para o FP8 usando o NVIDIA Transformer Engine: uma biblioteca de treinamento fornecida pela NVIDIA que acelera os modelos de transformadores e inclui o suporte para o FP8. O Transformer Engine fornece componentes essenciais que facilitam o treinamento com precisão mista, gerenciando perfeitamente a conversão entre os formatos FP8 e BF16 e lidando com fatores de escala.

Usamos a configuração padrão do Transformer Engine, conforme recomendado pela NVIDIA, usando E4M3 na passagem para frente para treinar e, em seguida, usando E5M2 na passagem para trás. Isso significa efetivamente que estamos usando o formato com maior precisão para prever a distribuição de probabilidade do próximo token e, em seguida, o formato com menor precisão, mas com um intervalo maior, para calcular os gradientes necessários para atualizar o modelo, quando a precisão é menos importante. Usamos cada um dos dois formatos para a tarefa à qual ele é mais adequado.

No gráfico abaixo, plotamos todos os números que podem ser representados com o formato E4M3. Como você verá, esses números estão concentrados em torno de zero, com um valor máximo de menos de 500. De fato, o número de valores representáveis para os formatos FP8 pode ser impresso em uma tabela muito curta. O truque para fazer com que esse formato funcione para o treinamento é que você esteja ciente da distribuição desses valores e trabalhe dentro dela. 

Isso envolve o armazenamento de fatores de escala adicionais junto com os tensores de peso FP8 para superar o intervalo limitado e evitar transbordamento e subfluxo. Ao realizar cálculos com seus tensores de baixa precisão, você também deve considerar os fatores de escala. Por exemplo, ao multiplicar dois tensores, você usa a fórmula: (A_fp8 * A_scale) x (B_fp8 * B_scale), em que A_fp8 e B_fp8 são tensores de 8 bits e as escalas são escalares de 32 bits. Você tem suporte específico de hardware para essas operações.

FP8 vs BF16 para desempenho de treinamento

Quando falamos em desempenho de treinamento, estamos nos referindo à rapidez com que um modelo pode ser treinado, considerando a capacidade de computação disponível. Para comparar o desempenho do treinamento entre o FP8 e o BF16, analisamos a utilização de FLOPS do modelo (MFU), que é o número de operações de ponto flutuante por segundo (FLOPS) que o modelo executa, como uma porcentagem dos FLOPS que são tecnicamente possíveis com o hardware que você tem disponível.

Para a nossa comparação, usamos o número de FLOPS possível com o formato BF16 como denominador comum para a nossa comparação, apesar do fato de que, tecnicamente falando, mais FLOPS se tornam possíveis quando você passa para o FP8. Isso nos permitiu avaliar o ganho incremental no uso da capacidade de processamento disponível que se torna possível quando você passa do BF16 para o FP8.

Conforme mostrado no gráfico abaixo, a eficiência com que o treinamento do nosso modelo usa a potência de computação disponível aumentou de 44,6% MFU para 67% MFU com o FP8, acelerando efetivamente o treinamento do nosso modelo em 50%.

Esse é um ganho de desempenho impressionante, por si só. Para chegar lá, trabalhamos com a NVIDIA para otimizar o uso dos recursos do Transformer Engine. Com base em outra configuração de treinamento, conseguimos aumentar o desempenho do treinamento em 25% ao longo de 15 meses, o que nos levou a 80% de MFU.

FP8 vs BF16 para a qualidade do treinamento do LLM

Portanto, os ganhos do FP8 em termos de desempenho de treinamento são realmente muito impressionantes. No entanto, o resultado com o qual realmente nos preocupamos em DeepL é a qualidade do treinamento. Como isso se compara à qualidade do treinamento com a precisão do BF16?

Para verificar a qualidade que o FP8 oferece, testamos treinar um de nossos modelos em ambos os formatos. Isso nos permitiu comparar as perdas de treinamento e a qualidade do downstream. 

Treinamos um modelo de 1,5 bilhão em três trilhões de tokens e, em seguida, comparamos a qualidade do treinamento FP8 com a do BF16. A principal medida aqui foi a perda de treinamento, que se refere à capacidade do modelo de prever o próximo token.

Como você verá no gráfico abaixo, pudemos detectar uma pequena superioridade do BF16 em relação ao FP8, como mostra nossa linha do FP8 pairando um pouco acima da do BF16. No entanto, essa diferença é abafada pelas flutuações muito mais amplas na perda de treinamento de uma etapa para outra que ocorrem em ambos os formatos e, em ambos os casos, vemos a mesma melhoria tangível na minimização da perda de treinamento ao longo do tempo.

Qualidade do treinamento downstream do FP8 vs. BF16

Em seguida, passamos a testar a qualidade que o treinamento em FP8 vs. BF16 proporcionou em um aplicativo prático e downstream.

Nesse caso, testamos como o modelo se saiu ao trabalhar com inglês e alemão. Comparamos a perplexidade da validação, que quantifica a incerteza que um modelo experimenta ao prever o próximo token em uma sequência. Mais uma vez, a expectativa é que a perplexidade diminua com o tempo. Nesse cenário prático, na verdade, não encontramos nenhuma degradação na qualidade com o treinamento FP8 em comparação com o BF16.

O resultado líquido da mudança do BF16 para o FP8 é que podemos treinar nossos modelos mais rapidamente, com menor demanda de memória, e obter a mesma qualidade de treinamento, com apenas uma degradação mínima em termos de perda de treinamento e perplexidade de validação comparável. Na verdade, isso significa que o DeepL é capaz de criar modelos mais sofisticados, lidando com tarefas mais complexas, por meio da maximização da utilização da capacidade de processamento. Isso amplia significativamente o escopo do que podemos fazer com o treinamento do LLM.

Do treinamento do FP8 à inferência

A próxima etapa da jornada envolve a preparação de LLMs para a inferência de produção. Aqui, o trabalho pesado de suporte é realizado pelo NVIDIA TensorRT-LLM, que é a solução da NVIDIA para inferência LLM escalável e que é compatível com o FP8. Ele pega os pesos do modelo que você treinou e constrói um mecanismo para otimizar as operações do modelo para que seja o mais eficiente possível em termos de computação, usando técnicas de otimização como fusão de kernel, código C++/CUDA otimizado, cache KV e batching contínuo em voo. 

Os benefícios do FP8 para a inferência

A inferência para LLMs sempre envolve a interação da taxa de transferência (o número de tokens que podem ser processados em um período de tempo) e a latência. Não é preciso dizer que, para oferecer a melhor experiência possível ao cliente, você precisa controlar a latência. No entanto, a taxa de transferência também é extremamente importante para DeepL porque define o número de solicitações que podemos atender em um determinado momento e, portanto, o escopo do que nosso modelo pode fazer na prática.

É inevitável que, à medida que a taxa de transferência aumenta, a latência tende a aumentar também. O agrupamento de várias solicitações permite maior rendimento, mas ao custo de maior latência para cada solicitação individual. Isso pode afetar a experiência do cliente. No entanto, o desempenho de inferência do FP8 em relação ao BF16 altera significativamente esse equilíbrio a nosso favor.

Como mostra o gráfico abaixo, para a maioria dos tamanhos de lote, o FP8 pode lidar com o dobro da taxa de transferência para o mesmo grau de latência que o BF16. Se definirmos um orçamento de latência específico que corresponda à experiência ideal de nossos usuários, poderemos ver isso na prática. Na verdade, o FP8 efetivamente dobrou a capacidade efetiva de nossos LLMs em termos de rendimento. 

Em outras palavras, a jornada do BF16 para o FP8 não nos permitiu apenas criar LLMs mais poderosos e sofisticados para DeepL. Isso também garantiu que pudéssemos aplicar esses LLMs de forma eficaz, para proporcionar experiências ideais aos clientes e aumentar o impacto da nossa IA linguística na natureza. Você pode treinar mais rapidamente modelos maiores, que podem operar dentro dos mesmos parâmetros de latência, enquanto lidam com o dobro do número de solicitações.

Próximos passos Recentemente, implementamos o novo NVIDIA DGX SuperPOD com sistemas NVIDIA DGX GB200, que oferece outro aumento quase exponencial na potência de computação. O que é realmente interessante para nós é que essa máquina apresentará uma nova geração de Tensor Cores que podem ser compatíveis nativamente com operações de tensor FP4, como multiplicações de matriz. É aí que nossa jornada começa novamente. Tem sido empolgante ver o que podemos fazer com um único byte quando se trata de treinar e fazer inferências. Fique atento a este espaço para ver o que é possível fazer com meio byte.


Sobre os autores

Markus Schnös, engenheiro de HPC da equipe de pesquisa

Markus Schnös é engenheiro de HPC da equipe de pesquisa em DeepL, onde se concentra no treinamento e na inferência de LLM em escala. Ele tem um interesse especial em treinar distribuído e computação de ponto flutuante de baixa precisão.

www.linkedin.com/in/markus-schnoes-349300185

https://github.com/Marks101

Fabian Joswig, engenheiro de HPC da equipe de pesquisa

Fabian Joswig é engenheiro de pesquisa da equipe em DeepL, com experiência em aprendizado de máquina, computação de alto desempenho e física teórica de partículas. Ele se concentra no dimensionamento de modelos e infraestrutura de IA para o tradutor mais preciso do mundo.

https://www.linkedin.com/in/fabianjoswig/

https://github.com/fjosw

Compartilhar