Ferramentas de IA 101
Configurando Treinamento, Ajuste Fino e Inferência de LLMs com GPUs NVIDIA e CUDA
O campo da inteligência artificial (IA) testemunhou avanços notáveis nos últimos anos, e no coração disso está a poderosa combinação de unidades de processamento gráfico (GPUs) e plataforma de computação paralela.
Modelos como GPT, BERT, e mais recentemente Llama, Mistral são capazes de entender e gerar texto humano com fluência e coerência sem precedentes. No entanto, treinar esses modelos requer vastas quantidades de dados e recursos computacionais, tornando as GPUs e o CUDA ferramentas indispensáveis nessa empreitada.
Este guia abrangente o levará pelo processo de configuração de uma GPU NVIDIA no Ubuntu, cobrindo a instalação de componentes de software essenciais, como o driver NVIDIA, CUDA Toolkit, cuDNN, PyTorch e mais.
A Ascensão de Frameworks de IA Acelerados por CUDA
O aprendizado de máquina profundo acelerado por GPU foi impulsionado pelo desenvolvimento de frameworks de IA populares que aproveitam o CUDA para computação eficiente. Frameworks como TensorFlow, PyTorch e MXNet têm suporte integrado ao CUDA, permitindo a integração transparente da aceleração de GPU em pipelines de aprendizado de máquina.
De acordo com o Estudo de Desempenho de Produtos de Aprendizado de Máquina Profundo do Centro de Dados da NVIDIA, modelos de aprendizado de máquina profundo acelerados por CUDA podem alcançar um desempenho até 100 vezes mais rápido em comparação com implementações baseadas em CPU.
A tecnologia de GPU de Instância Múltipla (MIG) da NVIDIA, introduzida com a arquitetura Ampere, permite que um único GPU seja partitionado em várias instâncias seguras, cada uma com seus próprios recursos dedicados. Essa funcionalidade permite o compartilhamento eficiente de recursos de GPU entre vários usuários ou cargas de trabalho, maximizando a utilização e reduzindo os custos gerais.
Acelerando a Inferência de LLM com NVIDIA TensorRT
Embora as GPUs tenham sido instrumentais no treinamento de LLMs, a inferência eficiente é igualmente crucial para implantar esses modelos em ambientes de produção. O NVIDIA TensorRT, um otimizador e tempo de execução de inferência de aprendizado de máquina de alto desempenho, desempenha um papel vital na aceleração da inferência de LLM em GPUs habilitadas para CUDA.
De acordo com as medições de desempenho da NVIDIA, o TensorRT pode fornecer até 8 vezes mais desempenho de inferência e 5 vezes menos custo total de propriedade em comparação com a inferência baseada em CPU para grandes modelos de linguagem, como o GPT-3.
O compromisso da NVIDIA com as iniciativas de código aberto foi uma força motriz por trás da adoção generalizada do CUDA na comunidade de pesquisa de IA. Projetos como cuDNN, cuBLAS e NCCL estão disponíveis como bibliotecas de código aberto, permitindo que pesquisadores e desenvolvedores aproveitem todo o potencial do CUDA para seus modelos de aprendizado de máquina.
Instalação
Ao configurar o desenvolvimento de IA, usar os drivers e bibliotecas mais recentes nem sempre é a melhor escolha. Por exemplo, embora o driver NVIDIA mais recente (545.xx) suporte o CUDA 12.3, as bibliotecas PyTorch e outras podem não suportar ainda essa versão. Portanto, usaremos o driver de versão 535.146.02 com CUDA 12.2 para garantir a compatibilidade.
Etapa de Instalação
1. Instalar Driver NVIDIA
Primeiro, identifique o modelo da sua GPU. Para este guia, usamos a GPU NVIDIA. Visite a página de download do driver NVIDIA, selecione o driver apropriado para a sua GPU e anote a versão do driver.
Para verificar pacotes de GPU pré-construídos no Ubuntu, execute:
sudo ubuntu-drivers list --gpgpu
Reinicie o computador e verifique a instalação:
nvidia-smi
2. Instalar CUDA Toolkit
O CUDA Toolkit fornece o ambiente de desenvolvimento para criar aplicativos acelerados por GPU de alto desempenho.
Para uma configuração não LLM/deep learning, você pode usar:
sudo apt install nvidia-cuda-toolkit No entanto, para garantir a compatibilidade com BitsAndBytes, seguiremos os passos abaixo: [code language="BASH"] git clone https://github.com/TimDettmers/bitsandbytes.git cd bitsandbytes/ bash install_cuda.sh 122 ~/local 1
Verifique a instalação:
~/local/cuda-12.2/bin/nvcc --version
Defina as variáveis de ambiente:
export CUDA_HOME=/home/roguser/local/cuda-12.2/ export LD_LIBRARY_PATH=/home/roguser/local/cuda-12.2/lib64 export BNB_CUDA_VERSION=122 export CUDA_VERSION=122
3. Instalar cuDNN
Baixe o pacote cuDNN do site de desenvolvedores da NVIDIA. Instale-o com:
sudo apt install ./cudnn-local-repo-ubuntu2204-8.9.7.29_1.0-1_amd64.deb
Siga as instruções para adicionar o keyring:
sudo cp /var/cudnn-local-repo-ubuntu2204-8.9.7.29/cudnn-local-08A7D361-keyring.gpg /usr/share/keyrings/
Instale as bibliotecas cuDNN:
sudo apt update sudo apt install libcudnn8 libcudnn8-dev libcudnn8-samples
4. Configurar Ambiente Virtual Python
O Ubuntu 22.04 vem com Python 3.10. Instale venv:
sudo apt-get install python3-pip sudo apt install python3.10-venv
Crie e ative o ambiente virtual:
cd mkdir test-gpu cd test-gpu python3 -m venv venv source venv/bin/activate
5. Instalar BitsAndBytes a Partir do Código Fonte
Navegue até o diretório BitsAndBytes e construa a partir do código fonte:
cd ~/bitsandbytes CUDA_HOME=/home/roguser/local/cuda-12.2/ \ LD_LIBRARY_PATH=/home/roguser/local/cuda-12.2/lib64 \ BNB_CUDA_VERSION=122 \ CUDA_VERSION=122 \ make cuda12x CUDA_HOME=/home/roguser/local/cuda-12.2/ \ LD_LIBRARY_PATH=/home/roguser/local/cuda-12.2/lib64 \ BNB_CUDA_VERSION=122 \ CUDA_VERSION=122 \ python setup.py install
6. Instalar PyTorch
Instale o PyTorch com o seguinte comando:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
7. Instalar Hugging Face e Transformers
Instale as bibliotecas transformers e accelerate:
pip install transformers pip install accelerate
O Poder do Processamento Paralelo
No núcleo, as GPUs são processadores paralelos altamente projetados para lidar com milhares de threads concorrentes de forma eficiente. Essa arquitetura as torna bem adaptadas para as tarefas computacionalmente intensivas envolvidas no treinamento de modelos de aprendizado de máquina profundo, incluindo LLMs. A plataforma CUDA, desenvolvida pela NVIDIA, fornece um ambiente de software que permite que os desenvolvedores aproveitem todo o potencial dessas GPUs, permitindo que eles escrevam código que possa aproveitar as capacidades de processamento paralelo do hardware.
Acelerando LLM Treinamento com GPUs e CUDA.
Treinar grandes modelos de linguagem é uma tarefa computacionalmente exigente que requer o processamento de vastas quantidades de dados de texto e a realização de numerosas operações matriciais. As GPUs, com seus milhares de núcleos e largura de banda de memória alta, são idealmente adaptadas para essas tarefas. Ao aproveitar o CUDA, os desenvolvedores podem otimizar seu código para aproveitar as capacidades de processamento paralelo das GPUs, reduzindo significativamente o tempo necessário para treinar LLMs.
Por exemplo, o treinamento do GPT-3, um dos maiores modelos de linguagem até o momento, foi possível graças ao uso de milhares de GPUs NVIDIA executando código otimizado para CUDA. Isso permitiu que o modelo fosse treinado em uma quantidade sem precedentes de dados, levando ao seu desempenho impressionante em tarefas de linguagem natural.
import torch
import torch.nn as nn
import torch.optim as optim
from transformers import GPT2LMHeadModel, GPT2Tokenizer
# Carregue o modelo GPT-2 pré-treinado e o tokenizador
modelo = GPT2LMHeadModel.from_pretrained('gpt2')
tokenizador = GPT2Tokenizer.from_pretrained('gpt2')
# Mova o modelo para a GPU, se disponível
dispositivo = torch.device("cuda" if torch.cuda.is_available() else "cpu")
modelo = modelo.to(dispositivo)
# Defina os dados de treinamento e os hiperparâmetros
dados_treinamento = [...] # Seus dados de treinamento
tamanho_lote = 32
num_epocas = 10
taxa_aprendizado = 5e-5
# Defina a função de perda e o otimizador
criterio = nn.CrossEntropyLoss()
otimizador = optim.Adam(modelo.parameters(), lr=taxa_aprendizado)
# Loop de treinamento
for epoca in range(num_epocas):
for i in range(0, len(dados_treinamento), tamanho_lote):
# Prepare as sequências de entrada e saída
entradas, saidas = dados_treinamento[i:i+tamanho_lote]
entradas = tokenizador(entradas, return_tensors="pt", padding=True)
entradas = entradas.to(dispositivo)
saidas = saidas.to(dispositivo)
# Passo para a frente
saidas_modelo = modelo(**entradas, labels=saidas)
perda = saidas_modelo.loss
# Passo para trás e otimização
otimizador.zero_grad()
perda.backward()
otimizador.step()
print(f'Epoca {epoca+1}/{num_epocas}, Perda: {perda.item()}')
Neste exemplo de código, demonstramos o treinamento de um modelo de linguagem GPT-2 usando PyTorch e GPUs CUDA. O modelo é carregado na GPU (se disponível), e o loop de treinamento aproveita o paralelismo das GPUs para realizar passos para a frente e para trás de forma eficiente, acelerando o processo de treinamento.
Bibliotecas Aceleradas por CUDA para Aprendizado de Máquina Profundo
Além da própria plataforma CUDA, a NVIDIA e a comunidade de código aberto desenvolveram uma variedade de bibliotecas aceleradas por CUDA que permitem a implementação eficiente de modelos de aprendizado de máquina profundo, incluindo LLMs. Essas bibliotecas fornecem implementações otimizadas de operações comuns, como multiplicações de matrizes, convoluções e funções de ativação, permitindo que os desenvolvedores se concentrem na arquitetura do modelo e no processo de treinamento em vez de otimizações de baixo nível.
Uma dessas bibliotecas é a cuDNN (CUDA Deep Neural Network library), que fornece implementações altamente ajustadas de rotinas padrão usadas em redes neurais profundas. Ao aproveitar a cuDNN, os desenvolvedores podem acelerar significativamente o treinamento e a inferência de seus modelos, alcançando ganhos de desempenho de até várias ordens de magnitude em comparação com implementações baseadas em CPU.
import torch import torch.nn as nn import torch.nn.functional as F from torch.cuda.amp import autocast class BlocoResidual(nn.Module): def __init__(self, canais_entrada, canais_saida, stride=1): super().__init__() self.conv1 = nn.Conv2d(canais_entrada, canais_saida, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(canais_saida) self.conv2 = nn.Conv2d(canais_saida, canais_saida, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(canais_saida) self.atalho = nn.Sequential() if stride != 1 or canais_entrada != canais_saida: self.atalho = nn.Sequential( nn.Conv2d(canais_entrada, canais_saida, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(canais_saida)) def forward(self, x): with autocast(): saida = F.relu(self.bn1(self.conv1(x))) saida = self.bn2(self.conv2(saida)) saida += self.atalho(x) saida = F.relu(saida) return saida
Neste trecho de código, definimos um bloco residual para uma rede neural convolucional (CNN) usando PyTorch. O gerenciador de contexto autocast do PyTorch’s Automatic Mixed Precision (AMP) é usado para habilitar o treinamento de precisão mista, que pode fornecer ganhos de desempenho significativos em GPUs CUDA enquanto mantém a alta precisão. A função F.relu é otimizada pela cuDNN, garantindo a execução eficiente em GPUs.
Treinamento Multi-GPU e Distribuído para Escalabilidade
À medida que os LLMs e os modelos de aprendizado de máquina profundo continuam a crescer em tamanho e complexidade, os requisitos computacionais para treinar esses modelos também aumentam. Para atender a esse desafio, pesquisadores e desenvolvedores têm recorrido a técnicas de treinamento multi-GPU e distribuído, que permitem que eles aproveitem o poder de processamento combinado de várias GPUs em várias máquinas.
O CUDA e as bibliotecas associadas, como a NCCL (NVIDIA Collective Communications Library), fornecem primitivas de comunicação eficientes que permitem a transferência de dados e a sincronização transparentes entre várias GPUs, permitindo o treinamento distribuído em uma escala sem precedentes.
</pre> import torch.distributed as dist from torch.nn.parallel import DistributedDataParallel as DDP # Inicialize o treinamento distribuído dist.init_process_group(backend='nccl', init_method='...') rank_local = dist.get_rank() torch.cuda.set_device(rank_local) # Crie o modelo e mova para a GPU modelo = MeuModelo().cuda() # Embale o modelo com DDP modelo = DDP(modelo, device_ids=[rank_local]) # Loop de treinamento (distribuído) for epoca in range(num_epocas): for dados in carregador_treinamento: entradas, saidas = dados entradas = entradas.cuda(non_blocking=True) saidas = saidas.cuda(non_blocking=True) saidas_modelo = modelo(entradas) perda = criterio(saidas_modelo, saidas) otimizador.zero_grad() perda.backward() otimizador.step()
Neste exemplo, demonstramos o treinamento distribuído usando o módulo DistributedDataParallel (DDP) do PyTorch. O modelo é embrulhado com o DDP, que lida automaticamente com o paralelismo de dados, a sincronização de gradientes e a comunicação entre várias GPUs usando a NCCL. Essa abordagem permite a escalabilidade eficiente do processo de treinamento em várias máquinas, permitindo que os pesquisadores e desenvolvedores treinem modelos maiores e mais complexos em um tempo razoável.
Implantando Modelos de Aprendizado de Máquina com CUDA
Embora as GPUs e o CUDA tenham sido usados principalmente para treinar modelos de aprendizado de máquina, eles também são cruciais para a inferência eficiente e a implantação. À medida que os modelos de aprendizado de máquina se tornam cada vez mais complexos e intensivos em recursos, a aceleração de GPU é essencial para alcançar o desempenho em tempo real em ambientes de produção.
O TensorRT da NVIDIA é um otimizador e tempo de execução de inferência de aprendizado de máquina de alto desempenho que fornece baixa latência e alto throughput na inferência em GPUs habilitadas para CUDA. O TensorRT pode otimizar e acelerar modelos treinados em frameworks como TensorFlow, PyTorch e MXNet, permitindo a implantação eficiente em várias plataformas, desde sistemas embarcados até centros de dados.
import tensorrt as trt # Carregue o modelo pré-treinado modelo = load_model(...) # Crie o mecanismo do TensorRT logger = trt.Logger(trt.Logger.INFO) construtor = trt.Builder(logger) rede = construtor.create_network() parser = trt.OnnxParser(rede, logger) # Analise e otimize o modelo sucesso = parser.parse_from_file(model_path) engine = construtor.build_cuda_engine(rede) # Execute a inferência na GPU contexto = engine.create_execution_context() entradas, saidas, bindings, stream = allocate_buffers(engine) # Defina os dados de entrada e execute a inferência set_input_data(entradas, input_data) contexto.execute_async_v2(bindings=bindings, stream_handle=stream.ptr) # Processo de saída # ...
Neste exemplo, demonstramos o uso do TensorRT para implantar um modelo de aprendizado de máquina pré-treinado em uma GPU habilitada para CUDA. O modelo é primeiro analisado e otimizado pelo TensorRT, que gera um mecanismo de inferência altamente otimizado personalizado para o modelo e o hardware específico. Esse mecanismo pode então ser usado para realizar a inferência eficiente na GPU, aproveitando o CUDA para computação acelerada.
Conclusão
A combinação de GPUs e CUDA tem sido instrumental nos avanços em grandes modelos de linguagem, visão computacional, reconhecimento de fala e vários outros domínios do aprendizado de máquina. Ao aproveitar as capacidades de processamento paralelo das GPUs e as bibliotecas otimizadas fornecidas pelo CUDA, os pesquisadores e desenvolvedores podem treinar e implantar modelos cada vez mais complexos com alta eficiência.
À medida que o campo da IA continue a evoluir, a importância das GPUs e do CUDA apenas crescerá. Com hardware e otimizações de software ainda mais poderosas, podemos esperar ver avanços ainda maiores no desenvolvimento e na implantação de sistemas de IA, empurrando os limites do que é possível.










