Инструменты ИИ 101

Настройка обучения, дообучения и вывода моделей LLM с помощью NVIDIA GPU и CUDA

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

Область искусственного интеллекта (ИИ) в последние годы пережила значительные достижения, и в ее основе лежит мощная комбинация графических процессоров (GPU) и платформы параллельных вычислений.

Модели, такие как GPT, BERT, и более недавно Llama, Mistral способны понимать и генерировать текст, похожий на человеческий, с беспрецедентной плавностью и связностью. Однако обучение этих моделей требует огромных объемов данных и вычислительных ресурсов, что делает GPU и CUDA незаменимыми инструментами в этом начинании.

Этот всесторонний гид проведет вас через процесс настройки NVIDIA GPU на Ubuntu, охватывая установку необходимых программных компонентов, таких как драйвер NVIDIA, CUDA Toolkit, cuDNN, PyTorch и многое другое.

Рост фреймворков ИИ, ускоренных CUDA

GPU-ускоренное глубокое обучение было подогрето разработкой популярных фреймворков ИИ, которые используют CUDA для эффективных вычислений. Фреймворки, такие как TensorFlow, PyTorch и MXNet, имеют встроенную поддержку CUDA, что позволяет бесшовно интегрировать ускорение GPU в конвейеры глубокого обучения.

Согласно изучению производительности глубокого обучения в центре данных NVIDIA, модели глубокого обучения, ускоренные CUDA, могут достигать производительности, в 100 раз превышающей производительность реализации на основе CPU.

Технология Multi-Instance GPU (MIG) от NVIDIA, представленная с архитектурой Ampere, позволяет одному GPU быть разделенным на несколько безопасных экземпляров, каждый из которых имеет свои собственные выделенные ресурсы. Эта функция позволяет эффективно делиться ресурсами GPU между несколькими пользователями или рабочими нагрузками, максимизируя использование и снижая общую стоимость.

Ускорение вывода LLM с помощью NVIDIA TensorRT

Хотя GPU были инструментальными в обучении LLM, эффективный вывод также крайне важен для развертывания этих моделей в производственных средах. NVIDIA TensorRT, высокопроизводительный оптимизатор и среда выполнения вывода глубокого обучения, играет важную роль в ускорении вывода LLM на GPU, поддерживающих CUDA.

Согласно бенчмаркам NVIDIA, TensorRT может обеспечить до 8 раз более быструю производительность вывода и 5 раз более низкую общую стоимость владения по сравнению с выводом на основе CPU для крупных языковых моделей, таких как GPT-3.

Коммит NVIDIA к открытым проектам стал движущей силой за широким внедрением CUDA в сообществе исследований ИИ. Проекты, такие как cuDNN, cuBLAS и NCCL, доступны в качестве открытых библиотек, что позволяет исследователям и разработчикам использовать полный потенциал CUDA для своих приложений глубокого обучения.

Установка

При настройке разработки ИИ использование последних драйверов и библиотек не всегда является лучшим выбором. Например, хотя последний драйвер NVIDIA (545.xx) поддерживает CUDA 12.3, PyTorch и другие библиотеки могут еще не поддерживать эту версию. Поэтому мы будем использовать драйвер версии 535.146.02 с CUDA 12.2, чтобы обеспечить совместимость.

Шаги установки

1. Установка драйвера NVIDIA

Сначала определите модель вашего GPU. Для этого руководства мы будем использовать GPU NVIDIA. Посетите страницу загрузки драйвера NVIDIA, выберите подходящий драйвер для вашего GPU и запишите версию драйвера.

Чтобы проверить наличие предустановленных пакетов GPU в Ubuntu, выполните:


sudo ubuntu-drivers list --gpgpu

Перезагрузите компьютер и проверьте установку:


nvidia-smi

2. Установка CUDA Toolkit

CUDA Toolkit предоставляет среду разработки для создания высокопроизводительных приложений, ускоренных GPU.

Для неклассифицированной установки (не LLM/глубокое обучение) вы можете использовать:


sudo apt install nvidia-cuda-toolkit

<p>Однако, чтобы обеспечить совместимость с BitsAndBytes, мы будем следовать этим шагам:</p>

[code language=&quot;BASH&quot;]

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

Проверьте установку:


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

Установите переменные среды:


<p>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</p>

3. Установка cuDNN

Загрузите пакет cuDNN с веб-сайта разработчика NVIDIA. Установите его с помощью:


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

Следуйте инструкциям, чтобы добавить ключевой кольцо:


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

Установите библиотеки cuDNN:


<p>sudo apt update
sudo apt install libcudnn8 libcudnn8-dev libcudnn8-samples</p>

4. Настройка виртуальной среды Python

Ubuntu 22.04 поставляется с Python 3.10. Установите venv:


<p>sudo apt-get install python3-pip
sudo apt install python3.10-venv</p>

Создайте и активируйте виртуальную среду:


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

5. Установка BitsAndBytes из исходного кода

Перейдите в каталог BitsAndBytes и соберите из исходного кода:


<p>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</p>

<p>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</p>

6. Установка PyTorch

Установите PyTorch с помощью следующей команды:


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

7. Установка Hugging Face и Transformers

Установите библиотеки transformers и accelerate:


<p>pip install transformers
pip install accelerate</p>

Сила параллельной обработки

В своей основе GPU являются высокопараллельными процессорами, предназначенными для эффективной обработки тысяч одновременных потоков. Эта архитектура делает их хорошо подходящими для вычислительно интенсивных задач, связанных с обучением моделей глубокого обучения, включая LLM. Платформа CUDA, разработанная NVIDIA, предоставляет программную среду, которая позволяет разработчикам использовать полный потенциал этих GPU, позволяя им писать код, который может использовать возможности параллельной обработки аппаратного обеспечения.
Ускорение обучения LLM с помощью GPU и CUDA.

Обучение крупных языковых моделей является вычислительно требовательной задачей, которая требует обработки огромных объемов текстовых данных и выполнения многочисленных матричных операций. GPU, с их тысячами ядер и высокой пропускной способностью памяти, идеально подходят для этих задач. Используя CUDA, разработчики могут оптимизировать свой код, чтобы использовать возможности параллельной обработки GPU, значительно снижая время, необходимое для обучения LLM.

Например, обучение GPT-3, одной из крупнейших языковых моделей на сегодняшний день, было возможно благодаря использованию тысяч GPU NVIDIA, работающих с оптимизированным кодом CUDA. Это позволило обучить модель на беспрецедентном объеме данных, что привело к ее впечатляющим результатам в задачах обработки естественного языка.


<p>import torch
import torch.nn as nn
import torch.optim as optim
from transformers import GPT2LMHeadModel, GPT2Tokenizer</p>

<p># Загрузите предварительно обученную модель GPT-2 и токенизатор
model = GPT2LMHeadModel.from_pretrained('gpt2')
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')</p>

<p># Переместите модель на GPU, если доступно
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)</p>

<p># Определите данные для обучения и гиперпараметры
train_data = [...] # Ваши данные для обучения
batch_size = 32
num_epochs = 10
learning_rate = 5e-5</p>

<p># Определите функцию потерь и оптимизатор
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)</p>

<p># Цикл обучения
for epoch in range(num_epochs):
for i in range(0, len(train_data), batch_size):
# Подготовьте входные и целевые последовательности
inputs, targets = train_data[i:i+batch_size]
inputs = tokenizer(inputs, return_tensors="pt", padding=True)
inputs = inputs.to(device)
targets = targets.to(device)</p>

<p># Прямой проход
outputs = model(**inputs, labels=targets)
loss = outputs.loss</p>

<p># Обратный проход и оптимизация
optimizer.zero_grad()
loss.backward()
optimizer.step()</p>

<p>print(f'Эпоха {epoch+1}/{num_epochs}, Потеря: {loss.item()}')</p>

В этом примере мы демонстрируем обучение модели GPT-2 с помощью PyTorch и GPU, поддерживающих CUDA. Модель загружается на GPU (если доступно), и цикл обучения использует параллелизм GPU для эффективного выполнения прямых и обратных проходов, ускоряя процесс обучения.

Библиотеки CUDA для глубокого обучения

Помимо самой платформы CUDA, NVIDIA и сообщество разработчиков создали ряд библиотек, ускоренных CUDA, которые позволяют эффективно реализовывать модели глубокого обучения, включая LLM. Эти библиотеки предоставляют оптимизированные реализации общих операций, таких как умножение матриц, свертки и функции активации, что позволяет разработчикам сосредоточиться на архитектуре модели и процессе обучения, а не на низкоуровневой оптимизации.

Одна из таких библиотек – cuDNN (CUDA Deep Neural Network library), которая предоставляет высоко оптимизированные реализации стандартных процедур, используемых в глубоких нейронных сетях. Используя cuDNN, разработчики могут значительно ускорить обучение и вывод своих моделей, достигая прироста производительности до нескольких порядков по сравнению с реализациями на основе CPU.


<p>import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.cuda.amp import autocast</p>

<p>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))</p>

<p>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</p>

В этом примере мы определяем блок остаточной сети для сверточной нейронной сети (CNN) с помощью PyTorch. Контекстный менеджер autocast из PyTorch используется для включения смешанной точности обучения, что может обеспечить значительный прирост производительности на GPU, поддерживающих CUDA, при сохранении высокой точности. Функция F.relu оптимизируется с помощью cuDNN, обеспечивая эффективное выполнение на GPU.

Много-GPU и распределенное обучение для масштабируемости

По мере того, как модели LLM и глубокого обучения продолжают расти в размерах и сложности, вычислительные требования для обучения этих моделей также увеличиваются. Чтобы решить эту проблему, исследователи и разработчики обратились к много-GPU и распределенному обучению, что позволяет им использовать совокупную мощность обработки нескольких GPU на нескольких машинах.

CUDA и связанные с ним библиотеки, такие как NCCL (NVIDIA Collective Communications Library), предоставляют эффективные примитивы связи, которые позволяют выполнять беспрепятственную передачу данных и синхронизацию между несколькими GPU, обеспечивая распределенное обучение на беспрецедентном масштабе.

</pre>
import torch.distributed as dist

<p>from torch.nn.parallel import DistributedDataParallel as DDP</p>

<p># Инициализируйте распределенное обучение
dist.init_process_group(backend='nccl', init_method='...')
local_rank = dist.get_rank()
torch.cuda.set_device(local_rank)</p>

<p># Создайте модель и переместите ее на GPU
model = MyModel().cuda()</p>

<p># Оберните модель с помощью DDP
model = DDP(model, device_ids=[local_rank])</p>

<p># Цикл обучения (распределенный)
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)</p>

<p>outputs = model(inputs)
loss = criterion(outputs, targets)</p>

<p>optimizer.zero_grad()
loss.backward()
optimizer.step()</p>

В этом примере мы демонстрируем распределенное обучение с помощью модуля DistributedDataParallel (DDP) из PyTorch. Модель обернута в DDP, который автоматически обрабатывает параллелизм данных, синхронизацию градиентов и связь между несколькими GPU с помощью NCCL. Этот подход позволяет эффективно масштабировать процесс обучения на несколько машин, позволяя исследователям и разработчикам обучать более крупные и сложные модели за разумное время.

Развертывание моделей глубокого обучения с помощью CUDA

Хотя GPU и CUDA в основном использовались для обучения моделей глубокого обучения, они также важны для эффективного развертывания и вывода. По мере того, как модели глубокого обучения становятся все более сложными и требовательными к ресурсам, ускорение GPU имеет решающее значение для достижения реального времени производительности в производственных средах.

NVIDIA’s TensorRT – это высокопроизводительный оптимизатор и среда выполнения вывода глубокого обучения, который обеспечивает низкую задержку и высокую пропускную способность вывода на GPU, поддерживающих CUDA. TensorRT может оптимизировать и ускорить модели, обученные в фреймворках, таких как TensorFlow, PyTorch и MXNet, обеспечивая эффективное развертывание на различных платформах, от встроенных систем до центров данных.


import tensorrt as trt

<p># Загрузите предварительно обученную модель
model = load_model(...)</p>

<p># Создайте движок TensorRT
logger = trt.Logger(trt.Logger.INFO)
builder = trt.Builder(logger)
network = builder.create_network()
parser = trt.OnnxParser(network, logger)</p>

<p># Проанализируйте и оптимизируйте модель
success = parser.parse_from_file(model_path)
engine = builder.build_cuda_engine(network)</p>

<p># Выполните вывод на GPU
context = engine.create_execution_context()
inputs, outputs, bindings, stream = allocate_buffers(engine)</p>

<p># Установите входные данные и выполните вывод
set_input_data(inputs, input_data)
context.execute_async_v2(bindings=bindings, stream_handle=stream.ptr)</p>

# Обработайте выходные данные
# ...

В этом примере мы демонстрируем использование TensorRT для развертывания предварительно обученной модели глубокого обучения на GPU, поддерживающем CUDA. Модель сначала проанализирована и оптимизирована TensorRT, который генерирует высоко оптимизированный движок вывода, адаптированный для конкретной модели и аппаратного обеспечения. Этот движок может затем использоваться для эффективного выполнения вывода на GPU, используя CUDA для ускорения вычислений.

Заключение

Комбинация GPU и CUDA была инструментальной в продвижении достижений в крупных языковых моделях, компьютерном зрении, распознавании речи и различных других областях глубокого обучения. Используя возможности параллельной обработки GPU и оптимизированные библиотеки, предоставляемые CUDA, исследователи и разработчики могут обучать и развертывать все более сложные модели с высокой эффективностью.

По мере того, как область ИИ продолжает развиваться, важность GPU и CUDA будет только расти. С еще более мощным аппаратным и программным обеспечением мы можем ожидать дальнейших прорывов в разработке и развертывании систем ИИ, расширяя границы того, что возможно.

Я провел последние пять лет, погружаясь в увлекательный мир машинного обучения и глубокого обучения. Моя страсть и экспертиза привели меня к участию в более чем 50 различных проектах программной инженерии, с особым акцентом на ИИ/МО. Мое непрекращающееся любопытство также привело меня к обработке естественного языка, области, которую я с нетерпением жду возможности изучить дальше.