Modelos e plataformas de IA

O Framework de Inferência da Microsoft traz Modelos de Linguagem Grande de 1-Bit para Dispositivos Locais

mm
Adicione Unite.AI às suas fontes preferidas no Google

Em 17 de outubro de 2024, a Microsoft anunciou o BitNet.cpp (MSFT ), um framework de inferência projetado para executar Modelos de Linguagem Grande (LLMs) quantizados em 1-bit. O BitNet.cpp é um progresso significativo na IA Geral, permitindo a implantação de LLMs de 1-bit de forma eficiente em CPUs padrão, sem a necessidade de GPUs caras. Esse desenvolvimento democratiza o acesso aos LLMs, tornando-os disponíveis em uma ampla gama de dispositivos e oferecendo novas possibilidades em aplicações de IA em dispositivos.

Entendendo os Modelos de Linguagem Grande de 1-Bit

Os Modelos de Linguagem Grande (LLMs) tradicionalmente exigem recursos computacionais significativos devido ao uso de números de ponto flutuante de alta precisão (tipicamente FP16 ou BF16) para os pesos do modelo. Essa necessidade tornou a implantação de LLMs cara e intensiva em energia.

Em sua essência, os LLMs de 1-bit usam técnicas de quantização extremas para representar os pesos do modelo usando apenas três valores possíveis: -1, 0 e 1, daí o termo “1,58-bit” (pois requer ligeiramente mais de um bit para codificar três estados).

Sistema de Peso Ternário

O Conceito

A quantização de 1-bit no BitNet.cpp é um sistema de peso ternário. O BitNet opera com apenas três valores possíveis para cada parâmetro:

  • -1 (negativo)
  • 0 (neutro)
  • 1 (positivo)

Isso resulta em uma necessidade de armazenamento de cerca de 1,58 bits por parâmetro, daí o nome BitNet b1.58. Essa redução drástica na largura de bit do parâmetro leva a uma redução impressionante no uso de memória e complexidade computacional, pois a maioria das multiplicações de ponto flutuante é substituída por simples adições e subtrações.

Fundamentação Matemática

A quantização de 1-bit envolve transformar pesos e ativações em sua representação ternária por meio dos seguintes passos:

1. Binarização de Pesos

Binarizar os pesos envolve centralizá-los em torno da média (α), resultando em uma representação ternária. A transformação é expressa matematicamente como:

Wf​=Sign(W−α)

Onde:

  • W é a matriz de pesos original.
  • α é a média dos pesos.
  • Sign(x) retorna +1 se x > 0 e -1 caso contrário.

2. Quantização de Ativações

Quantizar ativações garante que as entradas sejam limitadas a uma largura de bit especificada:

x^e​=Quant(x)=Clip(γx×Qb​​,−Qb​+ϵ,Qb​−ϵ)

Onde:

  • Qb = 2(b−1)2^{(b-1)} é o nível de quantização máximo para a largura de bit b.
  • γ é o valor absoluto máximo de x (denotado como ∣∣x∣∣∞).
  • ε é um número pequeno para prevenir transbordamento durante os cálculos.

3. Operação BitLinear

A camada BitLinear substitui as multiplicações de matriz tradicionais por uma operação simplificada:

y=Wf​×x^e​×(Qb​βγ​)

Onde:

  • β é um fator de escala usado para minimizar erros de aproximação.
  • γ escala as ativações.
  • Q_b é o fator de quantização.

Essa transformação permite cálculos eficientes enquanto preserva o desempenho do modelo.

Implicações de Desempenho

Eficiência de Memória

O sistema de peso ternário reduz significativamente as necessidades de memória:

  • LLMs Tradicionais: 16 bits por peso
  • BitNet.cpp: 1,58 bits por peso

Essa redução se traduz em uma economia de memória de aproximadamente 90% em comparação com modelos de 16 bits tradicionais, permitindo que modelos maiores sejam acomodados dentro das mesmas restrições de hardware.

Eficiência Energética

Velocidade de Inferência, Eficiência Energética (Apple [securities_stock_price_tag symbol="AAPL" exchange="NASDAQ"] M2)

 

Velocidade de Inferência: Mais Rápido em Ambos os CPUs

Velocidade de Inferência, Eficiência Energética (i7-13700H)

1. Velocidade de Inferência: Mais Rápido em Ambos os CPUs

A velocidade de inferência é representada como o número de tokens processados por segundo. Aqui está uma visão geral das observações:

  • No Apple M2 Ultra: O BitNet.cpp alcança até 5,07x de aceleração para modelos maiores (30B) em comparação com o Llama.cpp, com um pico de velocidade de 593,43 tokens por segundo para um modelo de 125M, o que é uma 1,37x de aceleração. Para modelos maiores, como o 3,8B e o 7B, o BitNet.cpp mantém uma velocidade acima de 84,77 tokens por segundo, mostrando sua eficiência em diferentes escalas.
  • No Intel (INTC ) i7-13700H: O BitNet.cpp alcança melhorias de velocidade ainda mais dramáticas. No tamanho do modelo de 7B, o BitNet.cpp entrega uma incrível aceleração de 5,68x em comparação com o Llama.cpp. Para modelos menores, como o 125M, ele processa 389,08 tokens por segundo, o que é 2,37x mais rápido que o Llama.cpp.

2. Eficiência Energética: Um Game-Changer para Dispositivos de Borda

Os gráficos fornecidos também incluem comparações de custo energético, que mostram uma redução significativa no consumo de energia por token processado:

  • No Apple M2 Ultra: As economias de energia do BitNet.cpp são substanciais. Para o modelo de 700M, ele consome 55,4% menos energia por token em comparação com o Llama.cpp, caindo de 0,314 para 0,140. Essa tendência continua para modelos maiores, com o modelo de 70B mostrando uma redução de 70,0% no consumo de energia.
  • No Intel i7-13700H: O BitNet.cpp entrega 71,9% de economia de energia para o modelo de 700M, com o consumo caindo de 1,367 para 0,384. Embora os dados de energia para o modelo de 70B no Llama.cpp não estejam disponíveis, o BitNet.cpp permanece eficiente, com um consumo de energia de 17,33 para o modelo de 70B.

3. Ultrapassando o Benchmark de Velocidade de Leitura Humana

Uma das insights mais interessantes desses gráficos é a referência à velocidade de leitura humana, marcada em 5-7 tokens por segundo. Essa linha vermelha mostra que ambas as implementações, especialmente o BitNet.cpp, podem facilmente ultrapassar as velocidades de leitura humanas, mesmo para os modelos maiores:

  • No Apple M2 Ultra, o BitNet.cpp ultrapassa a velocidade de leitura humana para todos os tamanhos de modelo, com a velocidade mais baixa sendo 8,67 tokens por segundo para um modelo de 70B.
  • No Intel i7-13700H, o modelo de 100B ainda alcança 1,70 tokens por segundo, quase alcançando a faixa inferior da velocidade de leitura humana, enquanto todos os modelos menores ultrapassam esse benchmark.

Considerações de Treinamento

Estimador de Passagem Reta (STE)

Como a quantização de 1-bit introduz funções não diferenciáveis, o treinamento envolve uma técnica especializada conhecida como Estimador de Passagem Reta (STE). Nessa abordagem, os gradientes fluem inalterados através de pontos não diferenciáveis. Aqui está uma implementação simplificada em Python:

class StraightThroughEstimator(Function):
@staticmethod
def forward(ctx, input):
return input.sign()

<p>@staticmethod
def backward(ctx, grad_output):
return grad_output

Treinamento de Precisão Mista

Para manter a estabilidade durante o treinamento, é empregada a precisão mista:

  • Pesos e Ativações: Quantizados para precisão de 1 bit.
  • Gradientes e Estados do Otimizador: Armazenados em precisão mais alta.
  • Pesos Latentes: Mantidos em alta precisão para facilitar atualizações precisas durante o treinamento.

Estratégia de Taxa de Aprendizado Grande

Um desafio único com modelos de 1 bit é que atualizações pequenas podem não afetar os pesos binarizados. Para mitigar isso, a taxa de aprendizado é aumentada, garantindo convergência mais rápida e melhor otimização em comparação com abordagens tradicionais.

Quantização e Normalização de Grupo

O BitNet.cpp introduz a Quantização e Normalização de Grupo para melhorar o paralelismo do modelo. Em vez de calcular parâmetros para a matriz de pesos inteira, o BitNet divide os pesos e ativações em vários grupos (G).
Isso permite processamento paralelo eficiente sem comunicação adicional entre grupos, permitindo o treinamento e inferência de modelos em grande escala.

Notas de Implementação e Otimizações

Otimização de CPU

O BitNet.cpp aproveita várias otimizações de baixo nível para alcançar o desempenho de pico da CPU:

  • Operações Vetorizadas: Utiliza instruções SIMD para realizar manipulações de bits de forma eficiente.
  • Acesso à Memória Amigável ao Cache: Estrutura os dados para minimizar perdas de cache.
  • Processamento Paralelo: Distribui a carga de trabalho efetivamente entre vários núcleos da CPU.

Aqui está um exemplo de uma função-chave que implementa quantização e inferência no BitNet:


def bitlinear_forward(input, weight, scale):
# Quantize a entrada usando quantização de valor absoluto máximo
input_q = quantize(input)

# Realize a multiplicação de matriz binária
output = binary_matmul(input_q, weight)

# Escale a saída para corresponder à precisão original
return output * scale

def quantize(x):
# Realize a quantização de valor absoluto máximo
scale = torch.max(torch.abs(x))
return torch.clamp(x / scale, -1, 1) * scale
[/code]

Modelos Suportados

A versão atual do BitNet.cpp suporta os seguintes Modelos de Linguagem Grande de 1 bit disponíveis no Hugging Face:

  • bitnet_b1_58-large (0,7B parâmetros)
  • bitnet_b1_58-3B (3,3B parâmetros)
  • Llama3-8B-1.58-100B-tokens (8,0B parâmetros)

Esses modelos estão disponíveis publicamente para demonstrar as capacidades de inferência do framework. Embora não sejam oficialmente treinados ou lançados pela Microsoft, eles ilustram a versatilidade do framework.

Guia de Instalação

Para começar a usar o BitNet.cpp, siga os passos abaixo:

Pré-requisitos

  1. Python >= 3.9
  2. CMake >= 3.22
  3. Clang >= 18
  4. Conda (altamente recomendado)

Para usuários do Windows, o Visual Studio deve ser instalado com os seguintes componentes habilitados:

  • Desenvolvimento de Desktop com C++
  • Ferramentas C++-CMake para Windows
  • Git para Windows
  • Compilador C++-Clang para Windows
  • Suporte ao MS-Build para Conjunto de Ferramentas LLVM (Clang)

Para usuários do Debian/Ubuntu, um script de instalação automático está disponível:

bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"

Instalação Passo a Passo

  1. Clone o Repositório:
    git clone --recursive https://github.com/microsoft/BitNet.git

    cd BitNet
  2. Instale as Dependências:
    # Crie um novo ambiente Conda (recomendado)
    conda create -n bitnet-cpp python=3.9
    conda activate bitnet-cpp


    pip install -r requirements.txt
  3. Construa e Prepare o Projeto: Você pode baixar um modelo diretamente do Hugging Face e convertê-lo para um formato quantizado:
    python setup_env.py --hf-repo HF1BitLLM/Llama3-8B-1.58-100B-tokens -q i2_s

    Alternativamente, baixe e converta o modelo manualmente:

    huggingface-cli download HF1BitLLM/Llama3-8B-1.58-100B-tokens --local-dir models/Llama3-8B-1.58-100B-tokens

    python setup_env.py -md models/Llama3-8B-1.58-100B-tokens -q i2_s

Executando Inferência com BitNet.cpp

Para executar a inferência usando o framework, use o seguinte comando:

python run_inference.py -m models/Llama3-8B-1.58-100B-tokens/ggml-model-i2_s.gguf -p "Sandra viajou para a cozinha. Onde está Sandra?" -n 6 -temp 0.7

Explicação:

  • -m especifica o caminho do arquivo do modelo.
  • -p define o texto do prompt.
  • -n define o número de tokens para prever.
  • -temp ajusta a aleatoriedade da amostragem (temperatura) durante a inferência.

Exemplo de Saída

Sandra viajou para a cozinha. Onde está Sandra?

Resposta: Sandra está na cozinha.

Detalhes Técnicos do BitNet.cpp

Camada BitLinear

O BitNet.cpp implementa uma arquitetura de Transformer modificada, substituindo as multiplicações de matriz padrão por operações BitLinear. Essa abordagem centraliza os pesos em zero antes da quantização e os escalona para reduzir erros de aproximação. A função de transformação principal parece assim:


<p># Função de binarização para pesos de 1 bit
def binarize_weights(W):
alpha = W.mean()
W_binarized = np.sign(W - alpha)
return W_binarized</p>

A combinação de pesos centralizados e escalonamento garante que o erro de quantização permaneça mínimo, preservando assim o desempenho.

Impacto na Indústria

O BitNet.cpp pode ter implicações de longo alcance para a implantação de Modelos de Linguagem Grande:

  • Acessibilidade: Permite que os LLMs sejam executados em dispositivos padrão, democratizando o acesso a IA poderosa.
  • Eficiência de Custo: Reduz a necessidade de GPUs caras, diminuindo a barreira para a adoção.
  • Eficiência Energética: Economiza energia ao aproveitar a inferência baseada em CPU.
  • Inovação: Abre novas possibilidades para aplicações de IA em dispositivos, como tradução de linguagem em tempo real, assistentes de voz e aplicações focadas na privacidade sem dependência de nuvem.

Desafios e Direções Futuras

Embora os Modelos de Linguagem Grande de 1 bit tenham promessa, vários desafios permanecem. Isso inclui o desenvolvimento de modelos de 1 bit robustos para tarefas diversas, otimização de hardware para computação de 1 bit e encorajamento de desenvolvedores a adotar esse novo paradigma. Além disso, explorar a quantização de 1 bit para tarefas de visão computacional ou áudio representa uma direção futura emocionante.

Conclusão

O lançamento do BitNet.cpp pela Microsoft é um avanço significativo. Ao permitir a inferência eficiente de 1 bit em CPUs padrão, o BitNet.cpp cria acessibilidade e sustentabilidade para a IA. Esse framework estabelece o palco para Modelos de Linguagem Grande mais portáteis e econômicos, empurrando o que é possível com a IA em dispositivos.

Eu passei os últimos cinco anos me imergindo no fascinante mundo de Aprendizado de Máquina e Aprendizado Profundo. Minha paixão e expertise me levaram a contribuir para mais de 50 projetos de engenharia de software diversificados, com um foco particular em IA/ML. Minha curiosidade contínua também me levou em direção ao Processamento de Linguagem Natural, um campo que estou ansioso para explorar mais.