Connect with us

Konfigurera utbildning, finjustering och inferens av LLM med NVIDIA GPU och CUDA

AI-verktyg 101

Konfigurera utbildning, finjustering och inferens av LLM med NVIDIA GPU och CUDA

mm
Nvidia GPU in Ubuntu Basics of GPU Parallel Computing GPU Based LLM Training Machine

Området för artificiell intelligens (AI) har sett anmärkningsvärda framsteg under de senaste åren, och i hjärtat av detta ligger den kraftfulla kombinationen av grafikprocessorer (GPU) och parallellberäkningsplattform.

Modeller som GPT, BERT, och mer nyligen Llama, Mistral är kapabla att förstå och generera mänsklig text med utanför denna världens flyt och sammanhang. Men att träna dessa modeller kräver stora mängder data och beräkningsresurser, vilket gör GPU och CUDA oumbärliga verktyg i detta företag.

Denna omfattande guide kommer att vägleda dig genom processen att konfigurera en NVIDIA GPU på Ubuntu, som täcker installationen av viktiga programkomponenter som NVIDIA-drivrutin, CUDA-verktyg, cuDNN, PyTorch och mer.

CUDA-accellerade AI-ramverk

GPU-accellererad djupinlärning har drivits av utvecklingen av populära AI-ramverk som utnyttjar CUDA för effektiv beräkning. Ramverk som TensorFlow, PyTorch, och MXNet har inbyggt stöd för CUDA, vilket möjliggör enkel integration av GPU-accelleration i djupinlärningspipeliner.

Enligt NVIDIA Data Center Deep Learning Product Performance Study, kan CUDA-accellererade djupinlärningsmodeller uppnå upp till 100 gånger snabbare prestanda jämfört med CPU-baserade implementationer.

NVIDIA:s Multi-Instance GPU (MIG)-teknik, som introducerades med Ampere-arkitekturen, tillåter en enda GPU att delas upp i flera säkra instanser, var och en med sina egna dedikerade resurser. Den här funktionen möjliggör effektiv delning av GPU-resurser mellan flera användare eller arbetsbelastningar, vilket maximerar utnyttjandet och minskar de totala kostnaderna.

Accellerera LLM-inferens med NVIDIA TensorRT

Medan GPU har varit instrumentala i att träna LLM, är effektiv inferens lika viktig för att distribuera dessa modeller i produktionsmiljöer. NVIDIA TensorRT, en högpresterande djupinlärningsinferensoptimerare och körning, spelar en viktig roll i att accellerera LLM-inferens på CUDA-aktiverade GPU.

Enligt NVIDIA:s benchmark, kan TensorRT tillhandahålla upp till 8 gånger snabbare inferensprestanda och 5 gånger lägre total ägandekostnad jämfört med CPU-baserad inferens för stora språkmodeller som GPT-3.

NVIDIA:s engagemang för öppen källkodsinitiativ har varit en drivande kraft bakom den breda antagandet av CUDA i AI-forskningsgemenskapen. Projekt som cuDNN, cuBLAS, och NCCL är tillgängliga som öppen källkodsprogramvara, vilket möjliggör för forskare och utvecklare att utnyttja den fulla potentialen av CUDA för sin djupinlärning.

Installation

När du ställer in AI-utveckling, kan det inte alltid vara det bästa valet att använda de senaste drivrutinerna och biblioteken. Till exempel, medan den senaste NVIDIA-drivrutin (545.xx) stöder CUDA 12.3, kanske PyTorch och andra bibliotek inte stöder den här versionen ännu. Därför kommer vi att använda drivrutin version 535.146.02 med CUDA 12.2 för att säkerställa kompatibilitet.

Installationssteg

1. Installera NVIDIA-drivrutin

Först, identifiera din GPU-modell. För den här guiden, använder vi NVIDIA GPU. Besök NVIDIA-drivrutin nedladdningssida, välj den lämpligaste drivrutinen för din GPU och notera drivrutinsversionen.

Kontrollera för förbyggda GPU-paket på Ubuntu, kör:


sudo ubuntu-drivers list --gpgpu

Starta om din dator och verifiera installationen:


nvidia-smi

2. Installera CUDA-verktyg

CUDA-verktyget tillhandahåller utvecklingsmiljön för att skapa högpresterande GPU-accellererade applikationer.

För en icke-LLM/djupinlärningskonfiguration kan du använda:


sudo apt install nvidia-cuda-verktyg

Men för att säkerställa kompatibilitet med BitsAndBytes, kommer vi att följa dessa steg:

[code language="BASH"]

git clone https://github.com/TimDettmers/bitsandbytes.git
cd bitsandbytes/
bash install_cuda.sh 122 ~/local 1

Verifiera installationen:


~/local/cuda-12.2/bin/nvcc --version

Ställ in miljövariabler:


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. Installera cuDNN

Ladda ner cuDNN-paketet från NVIDIA-utvecklarwebbplatsen. Installera det med:


sudo apt install ./cudnn-local-repo-ubuntu2204-8.9.7.29_1.0-1_amd64.deb

Följ instruktionerna för att lägga till nyckelringen:


sudo cp /var/cudnn-local-repo-ubuntu2204-8.9.7.29/cudnn-local-08A7D361-keyring.gpg /usr/share/keyrings/

Installera cuDNN-biblioteken:


sudo apt update
sudo apt install libcudnn8 libcudnn8-dev libcudnn8-exempel

4. Konfigurera Python-virtuell miljö

Ubuntu 22.04 kommer med Python 3.10. Installera venv:


sudo apt-get install python3-pip
sudo apt install python3.10-venv

Skapa och aktivera den virtuella miljön:


cd
mkdir test-gpu
cd test-gpu
python3 -m venv venv
source venv/bin/activate

5. Installera BitsAndBytes från källkod

Navigera till BitsAndBytes-katalogen och bygg från källkod:


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. Installera PyTorch

Installera PyTorch med följande kommando:


pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

7. Installera Hugging Face och Transformers

Installera transformers- och accelerate-biblioteken:


pip install transformers
pip install accelerate

Parallellbearbetningens kraft

I sin kärna är GPU:er högt parallella processorer som är utformade för att hantera tusentals samtidiga trådar effektivt. Den här arkitekturen gör dem väl lämpade för de beräkningsintensiva uppgifterna som är involverade i att träna djupinlärningsmodeller, inklusive LLM.

CUDA-plattformen, som utvecklats av NVIDIA, tillhandahåller en programvarumiljö som möjliggör för utvecklare att utnyttja den fulla potentialen av dessa GPU:er, vilket möjliggör att skriva kod som kan utnyttja den parallella bearbetningsförmågan hos hårdvaran.
Accellerera LLM-träning med GPU och CUDA.

Att träna stora språkmodeller är en beräkningskrävande uppgift som kräver bearbetning av stora mängder textdata och utförande av många matrisoperationer. GPU:er, med tusentals kärnor och hög minnesbandbredd, är idealiska för dessa uppgifter. Genom att utnyttja CUDA, kan utvecklare optimera sin kod för att utnyttja den parallella bearbetningsförmågan hos GPU:er, vilket avsevärt minskar den tid som krävs för att träna LLM.

Till exempel, var träningen av GPT-3, en av de största språkmodellerna hittills, möjliggjord genom användning av tusentals NVIDIA GPU:er som kör CUDA-optimiserad kod. Detta möjliggjorde att modellen kunde träna på en aldrig tidigare skådad mängd data, vilket ledde till dess imponerande prestanda i naturliga språkuppgifter.


import torch
import torch.nn as nn
import torch.optim as optim
from transformers import GPT2LMHeadModel, GPT2Tokenizer

# Ladda förtränad GPT-2-modell och tokenisator
modell = GPT2LMHeadModel.from_pretrained('gpt2')
tokenisator = GPT2Tokenizer.from_pretrained('gpt2')

# Flytta modell till GPU om tillgänglig
enhet = torch.device("cuda" if torch.cuda.is_available() else "cpu")
modell = modell.to(enhet)

# Definiera träningsdata och hyperparametrar
träningsdata = [...] # Din träningsdata
batchstorlek = 32
antal_epoker = 10
inlärningshastighet = 5e-5

# Definiera förlustfunktion och optimerare
kriterium = nn.CrossEntropyLoss()
optimerare = optim.Adam(modellens parametrar(), lr=inlärningshastighet)

# Träningsloop
för epoch i range(antal_epoker):
för i i range(0, len(träningsdata), batchstorlek):
# Förbered indata och målsekvenser
indata, mål = träningsdata[i:i+batchstorlek]
indata = tokenisator(indata, return_tensors="pt", padding=True)
indata = indata.to(enhet)
mål = mål.to(enhet)

# Framåtriktad passering
utdata = modell(**indata, etiketter=mål)
förlust = utdata.förlust

# Bakåtriktad passering och optimering
optimerare.zero_grad()
förlust.backward()
optimerare.step()

print(f'Epok {epoch+1}/{antal_epoker}, Förlust: {förlust.item()}')

I det här kodexemplet, demonstrerar vi träningen av en GPT-2-språkmodell med PyTorch och CUDA-aktiverade GPU:er. Modellen laddas på GPU:n (om tillgänglig), och träningsloopen utnyttjar parallellismen hos GPU:er för att utföra effektiva framåt- och bakåtriktade passeringar, vilket accelererar träningsprocessen.

CUDA-accellererade bibliotek för djupinlärning

Utöver CUDA-plattformen i sig, har NVIDIA och öppen källkods-gemenskapen utvecklat en rad CUDA-accellererade bibliotek som möjliggör effektiv implementering av djupinlärningsmodeller, inklusive LLM. Dessa bibliotek tillhandahåller optimerade implementationer av vanliga operationer, såsom matrismultiplikationer, konvolutioner och aktiveringsfunktioner, vilket möjliggör för utvecklare att fokusera på modellarkitekturen och träningsprocessen snarare än lågnivåoptimering.

Ett sådant bibliotek är cuDNN (CUDA Deep Neural Network-bibliotek), som tillhandahåller högt justerade implementationer av standardrutiner som används i djupa neurala nätverk. Genom att utnyttja cuDNN, kan utvecklare avsevärt accelerera tränings- och inferensprocessen för sina modeller, vilket uppnår prestandaförbättringar på upp till flera storleksordningar jämfört med CPU-baserade implementationer.


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.cuda.amp import autocast

class ResidualBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super().__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(out_channels)
self.shortcut = nn.Sequential()
if stride != 1 or in_channels != out_channels:
self.shortcut = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(out_channels))

def forward(self, x):
with autocast():
ut = F.relu(self.bn1(self.conv1(x)))
ut = self.bn2(self.conv2(ut))
ut += self.shortcut(x)
ut = F.relu(ut)
return ut

I det här kodexemplet, definierar vi en residualblock för en konvolutionsneural nätverksarkitektur (CNN) med PyTorch. Autocast-kontextchefen från PyTorchs Automatic Mixed Precision (AMP) används för att aktivera blandad precisionsträning, vilket kan ge avsevärda prestandaförbättringar på CUDA-aktiverade GPU:er samtidigt som hög noggrannhet upprätthålls. F.relu-funktionen är optimerad av cuDNN, vilket säkerställer effektiv körning på GPU:er.

Multi-GPU och distribuerad träning för skalbarhet

Medan LLM och djupinlärningsmodeller fortsätter att växa i storlek och komplexitet, ökar också de beräkningskrav som krävs för att träna dessa modeller. För att tackla den här utmaningen, har forskare och utvecklare vänt sig till multi-GPU och distribuerad träningstekniker, som möjliggör att utnyttja den kombinerade bearbetningskraften av flera GPU:er över flera maskiner.

CUDA och associerade bibliotek, såsom NCCL (NVIDIA Collective Communications Library), tillhandahåller effektiva kommunikationsprimitiver som möjliggör sömlös dataöverföring och synkronisering över flera GPU:er, vilket möjliggör distribuerad träning i en aldrig tidigare skådad skala.


import torch.distributed as dist

from torch.nn.parallel import DistributedDataParallel as DDP

# Initiera distribuerad träning
dist.init_process_group(backend='nccl', init_method='...')
lokal_rank = dist.get_rank()
torch.cuda.set_device(lokal_rank)

# Skapa modell och flytta till GPU
modell = MinModell().cuda()

# Omge modellen med DDP
modell = DDP(modell, device_ids=[lokal_rank])

# Träningsloop (distribuerad)
för epoch i range(antal_epoker):
för data i träningsladdare:
indata, mål = data
indata = indata.cuda(non_blocking=True)
mål = mål.cuda(non_blocking=True)

utdata = modell(indata)
förlust = kriterium(utdata, mål)

optimerare.zero_grad()
förlust.backward()
optimerare.step()

I det här exemplet, demonstrerar vi distribuerad träning med PyTorchs DistributedDataParallel (DDP)-modul. Modellen omges med DDP, som automatiskt hanterar data-parallellism, gradient-synkronisering och kommunikation över flera GPU:er med hjälp av NCCL. Den här metoden möjliggör effektiv skalning av träningsprocessen över flera maskiner, vilket möjliggör för forskare och utvecklare att träna större och mer komplexa modeller på en rimlig tid.

Distribuera djupinlärningsmodeller med CUDA

Medan GPU:er och CUDA främst har använts för att träna djupinlärningsmodeller, är de också avgörande för effektiv distribution och inferens. När djupinlärningsmodeller blir alltmer komplexa och resurskrävande, är GPU-accelleration avgörande för att uppnå realtidsprestanda i produktionsmiljöer.

NVIDIA:s TensorRT är en högpresterande djupinlärningsinferensoptimerare och körning som tillhandahåller låglatens och höggenomströmning på CUDA-aktiverade GPU:er. TensorRT kan optimera och accellera modeller som tränats i ramverk som TensorFlow, PyTorch och MXNet, vilket möjliggör effektiv distribution på olika plattformar, från inbäddade system till datacenter.


import tensorrt as trt

# Ladda förtränad modell
modell = ladda_modell(...)

# Skapa TensorRT-motor
loggare = trt.Loggare(trt.Loggare.INFO)
byggare = trt.Byggare(loggare)
nätverk = byggare.create_network()
parser = trt.OnnxParser(nätverk, loggare)

# Parsa och optimera modell
lyckades = parser.parse_from_file(modell_sökväg)
motor = byggare.build_cuda_engine(nätverk)

# Kör inferens på GPU
kontext = motor.create_execution_context()
indata, utdata, bindningar, ström = allocate_buffers(motor)

# Ställ in indata och kör inferens
set_input_data(indata, indata)
kontext.execute_async_v2(bindningar=bindningar, stream_handle=ström.ptr)

# Bearbeta utdata
# ...

I det här exemplet, demonstrerar vi användningen av TensorRT för att distribuera en förtränad djupinlärningsmodell på en CUDA-aktiverad GPU. Modellen parsas och optimeras av TensorRT, som genererar en högt optimerad inferensmotor som är anpassad för den specifika modellen och hårdvaran. Den här motorn kan sedan användas för att utföra effektiv inferens på GPU:n, med hjälp av CUDA för accellererad beräkning.

Slutsats

Kombinationen av GPU:er och CUDA har varit avgörande för att driva framstegen inom stora språkmodeller, datorseende, taligenkänning och olika andra områden inom djupinlärning. Genom att utnyttja den parallella bearbetningsförmågan hos GPU:er och de optimerade biblioteken som tillhandahålls av CUDA, kan forskare och utvecklare träna och distribuera alltmer komplexa modeller med hög effektivitet.

När AI-området fortsätter att utvecklas, kommer betydelsen av GPU:er och CUDA bara att öka. Med ännu kraftfullare hårdvara och programvaruoptimeringar, kan vi förvänta oss att se ytterligare genombrott inom utveckling och distribution av AI-system, vilket kommer att utöka gränserna för vad som är möjligt.

Jag har under de senaste fem åren dykt ner i den fascinerande världen av Machine Learning och Deep Learning. Min passion och expertis har lett mig till att bidra till över 50 olika mjukvaruutvecklingsprojekt, med särskild fokus på AI/ML. Min pågående nyfikenhet har också dragit mig mot Natural Language Processing, ett område som jag är angelägen om att utforska vidare.