Vernetzen Sie sich mit uns

KI-Tools 101

Einrichten eines Trainings, Feinabstimmung und Inferenzierung von LLMs mit NVIDIA GPUs und CUDA

mm
Nvidia GPU in Ubuntu Grundlagen des GPU-Parallel-Computing GPU-basierte LLM-Trainingsmaschine

Im Bereich der künstlichen Intelligenz (KI) wurden in den letzten Jahren bemerkenswerte Fortschritte erzielt. Im Mittelpunkt steht dabei die leistungsstarke Kombination aus Grafikprozessoren (GPUs) und paralleler Computerplattform.

Modelle wie z GPT, BERTund in jüngerer Zeit Lama, Mistral sind in der Lage, menschenähnliche Texte mit beispielloser Flüssigkeit und Kohärenz zu verstehen und zu generieren. Das Training dieser Modelle erfordert jedoch enorme Datenmengen und Rechenressourcen, was GPUs und CUDA zu unverzichtbaren Werkzeugen bei diesem Unterfangen macht.

Diese umfassende Anleitung führt Sie durch den Prozess der Einrichtung einer NVIDIA-GPU unter Ubuntu und behandelt die Installation wichtiger Softwarekomponenten wie NVIDIA-Treiber, CUDA Toolkit, cuDNN, PyTorch und mehr.

Der Aufstieg CUDA-beschleunigter KI-Frameworks

GPU-beschleunigtes Deep Learning wurde durch die Entwicklung beliebter KI-Frameworks vorangetrieben, die CUDA für effiziente Berechnungen nutzen. Frameworks wie TensorFlow, PyTorch und MXNet verfügen über integrierte Unterstützung für CUDA, was eine nahtlose Integration der GPU-Beschleunigung in Deep-Learning-Pipelines ermöglicht.

Nach Angaben der US-Organisation Studie zur Produktleistung von NVIDIA Data Center Deep LearningCUDA-beschleunigte Deep-Learning-Modelle können im Vergleich zu CPU-basierten Implementierungen eine bis zu 100-mal schnellere Leistung erzielen.

Die mit der Ampere-Architektur eingeführte Multi-Instance-GPU-Technologie (MIG) von NVIDIA ermöglicht die Partitionierung einer einzelnen GPU in mehrere sichere Instanzen mit jeweils eigenen Ressourcen. Diese Funktion ermöglicht die effiziente gemeinsame Nutzung von GPU-Ressourcen durch mehrere Benutzer oder Workloads, maximiert die Auslastung und senkt die Gesamtkosten.

Beschleunigen der LLM-Inferenz mit NVIDIA TensorRT

Während GPUs beim Training von LLMs eine wichtige Rolle gespielt haben, ist eine effiziente Inferenz für den Einsatz dieser Modelle in Produktionsumgebungen ebenso wichtig. NVIDIA TensorRT, ein leistungsstarker Deep-Learning-Inferenzoptimierer und eine Laufzeitumgebung, spielt eine entscheidende Rolle bei der Beschleunigung der LLM-Inferenz auf CUDA-fähigen GPUs.

Laut den Benchmarks von NVIDIA kann TensorRT im Vergleich zur CPU-basierten Inferenz für große Sprachmodelle wie GPT-8 eine bis zu 5-mal schnellere Inferenzleistung und 3-mal niedrigere Gesamtbetriebskosten bieten.

NVIDIAs Engagement für Open-Source-Initiativen war eine treibende Kraft hinter der weit verbreiteten Einführung von CUDA in der KI-Forschungsgemeinschaft. Projekte wie cuDNN, cuBLAS und NCCL sind als Open-Source-Bibliotheken verfügbar und ermöglichen es Forschern und Entwicklern, das volle Potenzial von CUDA für ihr Deep Learning zu nutzen.

Installation

Bei der Entwicklung von KI ist die Verwendung der neuesten Treiber und Bibliotheken möglicherweise nicht immer die beste Wahl. Während beispielsweise der neueste NVIDIA-Treiber (545.xx) CUDA 12.3 unterstützt, unterstützen PyTorch und andere Bibliotheken diese Version möglicherweise noch nicht. Daher verwenden wir Treiberversion 535.146.02 mit CUDA 12.2 um die Kompatibilität sicherzustellen.

Installationsschritte

1. Installieren Sie den NVIDIA-Treiber

Identifizieren Sie zunächst Ihr GPU-Modell. Für diese Anleitung verwenden wir die NVIDIA GPU. Besuchen Sie die NVIDIA-Treiber-Downloadseite, wählen Sie den entsprechenden Treiber für Ihre GPU aus und notieren Sie sich die Treiberversion.

Um unter Ubuntu nach vorgefertigten GPU-Paketen zu suchen, führen Sie Folgendes aus:

sudo ubuntu-drivers list --gpgpu

Starten Sie Ihren Computer neu und überprüfen Sie die Installation:

nvidia-smi

2. Installieren Sie das CUDA Toolkit

Das CUDA Toolkit bietet die Entwicklungsumgebung zum Erstellen leistungsstarker GPU-beschleunigter Anwendungen.

Für ein Nicht-LLM/Deep-Learning-Setup können Sie Folgendes verwenden:

sudo apt install nvidia-cuda-toolkit

However, to ensure compatibility with BitsAndBytes, we will follow these steps:

[code language="BASH"]

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

Überprüfen Sie die Installation:

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

Legen Sie die Umgebungsvariablen fest:

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. Installieren Sie cuDNN

Laden Sie cuDNN-Paket von dem NVIDIA Developer-Website. Installieren Sie es mit:

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

Befolgen Sie die Anweisungen, um den Schlüsselbund hinzuzufügen:

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

Installieren Sie die cuDNN-Bibliotheken:

sudo apt update
sudo apt install libcudnn8 libcudnn8-dev libcudnn8-samples

4. Richten Sie eine virtuelle Python-Umgebung ein

Ubuntu 22.04 wird mit Python 3.10 ausgeliefert. Installieren Sie venv:

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

Erstellen und aktivieren Sie die virtuelle Umgebung:

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

5. Installieren Sie BitsAndBytes aus der Quelle

Navigieren Sie zum Verzeichnis BitsAndBytes und erstellen Sie aus dem Quellcode:

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. Installieren Sie PyTorch

Installieren Sie PyTorch mit dem folgenden Befehl:

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

7. Installieren Sie Hugging Face und Transformers

Installieren Sie die Transformatoren und beschleunigen Sie die Bibliotheken:

pip install transformers
pip install accelerate

Die Leistung der Parallelverarbeitung

Im Kern sind GPUs hochparallele Prozessoren, die Tausende gleichzeitiger Threads effizient verarbeiten können. Aufgrund dieser Architektur eignen sie sich gut für rechenintensive Aufgaben beim Training von Deep-Learning-Modellen, einschließlich LLMs. Die von NVIDIA entwickelte CUDA-Plattform bietet eine Softwareumgebung, mit der Entwickler das volle Potenzial dieser GPUs ausschöpfen und Code schreiben können, der die parallelen Verarbeitungsfunktionen der Hardware nutzt.
Beschleunigen LLM Training mit GPUs und CUDA.

Das Trainieren großer Sprachmodelle ist eine rechenintensive Aufgabe, die die Verarbeitung großer Mengen Textdaten und die Durchführung zahlreicher Matrixoperationen erfordert. GPUs mit ihren Tausenden von Kernen und ihrer hohen Speicherbandbreite sind für diese Aufgaben ideal geeignet. Durch die Nutzung von CUDA können Entwickler ihren Code optimieren, um die parallelen Verarbeitungsfunktionen von GPUs zu nutzen und so die zum Trainieren von LLMs erforderliche Zeit erheblich zu reduzieren.

Zum Beispiel die Ausbildung von GPT-3, eines der bislang größten Sprachmodelle, wurde durch den Einsatz von Tausenden von NVIDIA-Grafikprozessoren mit CUDA-optimiertem Code ermöglicht. Dadurch konnte das Modell mit einer beispiellosen Datenmenge trainiert werden, was zu seiner beeindruckenden Leistung bei natürlichen Sprachaufgaben führte.

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

# Load pre-trained GPT-2 model and tokenizer
model = GPT2LMHeadModel.from_pretrained('gpt2')
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

# Move model to GPU if available
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)

# Define training data and hyperparameters
train_data = [...] # Your training data
batch_size = 32
num_epochs = 10
learning_rate = 5e-5

# Define loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# Training loop
for epoch in range(num_epochs):
for i in range(0, len(train_data), batch_size):
# Prepare input and target sequences
inputs, targets = train_data[i:i+batch_size]
inputs = tokenizer(inputs, return_tensors="pt", padding=True)
inputs = inputs.to(device)
targets = targets.to(device)

# Forward pass
outputs = model(**inputs, labels=targets)
loss = outputs.loss

# Backward pass and optimization
optimizer.zero_grad()
loss.backward()
optimizer.step()

print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}')

In diesem Beispielcode-Schnipsel demonstrieren wir das Training eines GPT-2 Sprachmodell mit PyTorch und den CUDA-fähigen GPUs. Das Modell wird auf die GPU geladen (falls verfügbar) und die Trainingsschleife nutzt die Parallelität der GPUs, um effiziente Vorwärts- und Rückwärtsdurchläufe durchzuführen und so den Trainingsprozess zu beschleunigen.

CUDA-beschleunigte Bibliotheken für Deep Learning

Zusätzlich zur CUDA-Plattform selbst haben NVIDIA und die Open-Source-Community eine Reihe von CUDA-beschleunigten Bibliotheken entwickelt, die eine effiziente Implementierung von Deep-Learning-Modellen, einschließlich LLMs, ermöglichen. Diese Bibliotheken bieten optimierte Implementierungen gängiger Operationen wie Matrixmultiplikationen, Faltungen und Aktivierungsfunktionen, sodass sich Entwickler auf die Modellarchitektur und den Trainingsprozess konzentrieren können, anstatt auf die Optimierung auf niedriger Ebene.

Eine solche Bibliothek ist cuDNN (CUDA Deep Neural Network Library), die hochgradig optimierte Implementierungen von Standardroutinen bietet, die in tiefen neuronalen Netzwerken verwendet werden. Durch den Einsatz von cuDNN können Entwickler das Training und die Inferenz ihrer Modelle erheblich beschleunigen und so Leistungssteigerungen von bis zu mehreren Größenordnungen im Vergleich zu CPU-basierten Implementierungen erzielen.

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():
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = F.relu(out)
return out

In diesem Code-Snippet definieren wir einen Restblock für ein Convolutional Neural Network (CNN) mit PyTorch. Der Autocast-Kontextmanager von PyTorchs Automatic Mixed Precision (AMP) wird verwendet, um Mixed-Precision-Training zu ermöglichen, das auf CUDA-fähigen GPUs bei gleichbleibend hoher Genauigkeit zu deutlichen Leistungssteigerungen führen kann. Die F.relu-Funktion wird durch cuDNN optimiert und gewährleistet eine effiziente Ausführung auf GPUs.

Multi-GPU und verteiltes Training für Skalierbarkeit

Da LLMs und Deep-Learning-Modelle immer größer und komplexer werden, steigen auch die Rechenleistungsanforderungen für das Training dieser Modelle. Um diese Herausforderung zu bewältigen, haben sich Forscher und Entwickler Multi-GPU- und verteilten Trainingstechniken zugewandt, mit denen sie die kombinierte Verarbeitungsleistung mehrerer GPUs auf mehreren Maschinen nutzen können.

CUDA und zugehörige Bibliotheken wie NCCL (NVIDIA Collective Communications Library) bieten effiziente Kommunikationsprimitive, die eine nahtlose Datenübertragung und -synchronisierung über mehrere GPUs hinweg ermöglichen und so verteiltes Training in einem beispiellosen Umfang ermöglichen.

</pre>
import torch.distributed as dist

from torch.nn.parallel import DistributedDataParallel as DDP

# Initialize distributed training
dist.init_process_group(backend='nccl', init_method='...')
local_rank = dist.get_rank()
torch.cuda.set_device(local_rank)

# Create model and move to GPU
model = MyModel().cuda()

# Wrap model with DDP
model = DDP(model, device_ids=[local_rank])

# Training loop (distributed)
for epoch in range(num_epochs):
for data in train_loader:
inputs, targets = data
inputs = inputs.cuda(non_blocking=True)
targets = targets.cuda(non_blocking=True)

outputs = model(inputs)
loss = criterion(outputs, targets)

optimizer.zero_grad()
loss.backward()
optimizer.step()

In diesem Beispiel demonstrieren wir verteiltes Training mit dem PyTorch-Modul DistributedDataParallel (DDP). Das Modell ist in DDP eingebettet, das automatisch Datenparallelität, Gradientensynchronisierung und Kommunikation über mehrere GPUs hinweg mithilfe von NCCL übernimmt. Dieser Ansatz ermöglicht eine effiziente Skalierung des Trainingsprozesses über mehrere Maschinen hinweg, sodass Forscher und Entwickler größere und komplexere Modelle in angemessener Zeit trainieren können.

Bereitstellen von Deep Learning-Modellen mit CUDA

Während GPUs und CUDA in erster Linie zum Trainieren von Deep-Learning-Modellen verwendet werden, sind sie auch für eine effiziente Bereitstellung und Inferenz von entscheidender Bedeutung. Da Deep-Learning-Modelle immer komplexer und ressourcenintensiver werden, ist die GPU-Beschleunigung unerlässlich für Erreichen von Echtzeitleistung in Produktionsumgebungen.

NVIDIAs TensorRT ist ein leistungsstarker Deep-Learning-Inferenzoptimierer und eine Laufzeitumgebung, die Folgendes bietet: geringe Latenz und hoher Durchsatz Inferenz auf CUDA-fähigen GPUs. TensorRT kann Modelle optimieren und beschleunigen, die in Frameworks wie TensorFlow, PyTorch und MXNet trainiert wurden, und ermöglicht so eine effiziente Bereitstellung auf verschiedenen Plattformen, von eingebetteten Systemen bis hin zu Rechenzentren.

import tensorrt as trt

# Load pre-trained model
model = load_model(...)

# Create TensorRT engine
logger = trt.Logger(trt.Logger.INFO)
builder = trt.Builder(logger)
network = builder.create_network()
parser = trt.OnnxParser(network, logger)

# Parse and optimize model
success = parser.parse_from_file(model_path)
engine = builder.build_cuda_engine(network)

# Run inference on GPU
context = engine.create_execution_context()
inputs, outputs, bindings, stream = allocate_buffers(engine)

# Set input data and run inference
set_input_data(inputs, input_data)
context.execute_async_v2(bindings=bindings, stream_handle=stream.ptr)

# Process output
# ...

In diesem Beispiel demonstrieren wir die Verwendung von TensorRT zum Bereitstellen eines vorab trainierten Deep-Learning-Modells auf einer CUDA-fähigen GPU. Das Modell wird zunächst von TensorRT analysiert und optimiert, wodurch eine hochoptimierte Inferenzmaschine generiert wird, die auf das jeweilige Modell und die Hardware zugeschnitten ist. Diese Maschine kann dann verwendet werden, um effiziente Inferenzen auf der GPU durchzuführen und CUDA für beschleunigte Berechnungen zu nutzen.

Fazit

Die Kombination von GPUs und CUDA hat maßgeblich zur Weiterentwicklung großer Sprachmodelle, Computervision, Spracherkennung und verschiedener anderer Bereiche des Deep Learning beigetragen. Durch die Nutzung der parallelen Verarbeitungsfunktionen von GPUs und der optimierten Bibliotheken von CUDA können Forscher und Entwickler zunehmend komplexere Modelle mit hoher Effizienz trainieren und bereitstellen.

Da sich der Bereich der KI weiterentwickelt, wird die Bedeutung von GPUs und CUDA nur noch zunehmen. Mit noch leistungsstärkeren Hardware- und Softwareoptimierungen können wir weitere Durchbrüche bei der Entwicklung und Bereitstellung von KI-Systemen erwarten, die die Grenzen des Möglichen erweitern.

Ich habe die letzten fünf Jahre damit verbracht, in die faszinierende Welt des maschinellen Lernens und des Deep Learning einzutauchen. Meine Leidenschaft und mein Fachwissen haben dazu geführt, dass ich an über 50 verschiedenen Software-Engineering-Projekten mitgewirkt habe, mit besonderem Schwerpunkt auf KI/ML. Meine anhaltende Neugier hat mich auch zur Verarbeitung natürlicher Sprache geführt, einem Bereich, den ich gerne weiter erforschen möchte.