Оптимизация AI пайплайна на двух NVIDIA A100X: пошаговый гайд 2026 | AiManual
AiManual Logo Ai / Manual.
11 Апр 2026 Гайд

Настройка workflow на двух GPU A100X: когда две карты работают как четыре (или как одна)

Экспертная настройка workflow на двух GPU A100X для локальных задач. Разбираем оптимизацию инференса, пайплайна обработки и утилизацию железа с нуля.

Две A100X на столе - это не роскошь, а головная боль

Вы купили две A100X. Поставили в систему. Запустили свою тонко настроенную Llama 3.5-405B. И... получили прирост в 15%. Вместо ожидаемых 90+. Знакомо? Виновато не железо, а кривой пайплайн, который душит потенциал ваших монстров на 164 терафлопсах каждый (на FP16, конечно).

Проблема в том, что большинство гайдов по multi-GPU написано для кластеров. Для локальной рабочей станции - своя физика. PCIe полосы, память хоста, латентность между картами и главное - драконовские требования к пайплайну обработки данных. Сегодня разберем, как заставить две A100X петь дуэтом, а не молчать по очереди.

Реальность 2026 года: A100X с архитектурой Hopper Next - это уже не просто ускоритель, а самостоятельный вычислительный остров с 128 ГБ HBM3e памяти и пропускной способностью под 8 ТБ/с. Две таких штуки в одной системе - это мини-суперкомпьютер, который требует соответствующего подхода. Старые методы из эпохи RTX 3090 тут не прокатят.

Диагностика: почему ваш пайплайн тормозит

Прежде чем лезть в настройки, найдите узкое место. Запустите простой тест - он покажет, где спотыкается ваша система.

# Проверяем базовую связность и производительность GPU
nvidia-smi topo -m
# Смотрим пропускную способность PCIe
gpustat -i 1 --color --show-power --show-pcie
# Тест на латентность обмена между GPU (требует установки NCCL Tests)
nccl-tests/build/all_reduce_perf -b 8M -e 128M -f 2 -g 2

Если в выводе topo вы видите NODE вместо PIX или PHB между GPU - это уже плохо. Значит, карты сидят на разных NUMA-нодах и общаются через память хоста. Задержки вырастают в разы. В идеале нужен прямой PCIe switch или, как минимум, расположение в соседних слотах x16.

💡
На многих материнских платах для Threadripper или EPYC слоты распределены между разными CPU-комплексами. Если ваши A100X попали в разные группы - производительность multi-GPU упадет катастрофически. Проверяйте мануал к материнке перед покупкой или установкой.

Еще одна частая ошибка - неправильная настройка окружения. PyTorch 2.4+ и TensorFlow 2.17+ научились лучше работать с multi-GPU, но по умолчанию используют стратегии, которые для A100X избыточны или просто неоптимальны.

1 Шаг первый: подготовка фундамента

Не начинайте с Python. Начните с BIOS и операционной системы.

  • BIOS/UEFI: Включите Above 4G Decoding. Отключите CSM. Для PCIe установите Gen 4 или Gen 5 (в зависимости от платформы). Если есть настройки Power - выставляйте Maximum Performance.
  • ОС: Ubuntu 24.10 или Rocky Linux 9.5. Ядро 6.10+. Никаких лишних графических оболочек - они крадут память и PCIe полосы.
  • Драйверы: NVIDIA Driver 570.XX или новее. CUDA 12.6+ (на апрель 2026 - это последняя стабильная ветка). CuDNN 9.2+. Все через официальные репозитории NVIDIA.
# Пример установки стека NVIDIA на Ubuntu 24.10
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2410/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt update
sudo apt install cuda-toolkit-12-6 cuda-drivers-570 nvidia-fabricmanager-570
# Проверяем
nvidia-smi
python3 -c "import torch; print(torch.cuda.device_count(), torch.cuda.get_device_name(0))"

2 Шаг второй: выбор стратегии распределения

Тут все зависит от задачи. Для инференса больших LLM (тех же Qwen3.5-397B или MoE-моделей) нужен tensor parallelism или pipeline parallelism. Для batch-обработки изображений или видео - data parallelism.

ЗадачаЛучшая стратегия для 2x A100XБиблиотека/Фреймворк
Инференс LLM 70B+ параметровTensor Parallelism (TP)vLLM 0.4.7+, TGI, llama.cpp
Тонкая настройка моделей 7B-30BData Parallelism (DDP) + Gradient CheckpointingPyTorch FSDP, DeepSpeed
Обработка видео (рендеринг, анализ)Task Parallelism (разные кадры на разные GPU)Custom pipeline на CUDA Streams

Для LLM-инференса я сейчас предпочитаю vLLM. Он научился грамотно распределять большие модели по нескольким GPU с минимальными накладными расходами. Пример запуска:

# Запуск Qwen3-72B на двух A100X с tensor parallelism
python -m vllm.entrypoints.api_server \
  --model Qwen/Qwen3-72B-Instruct \
  --tensor-parallel-size 2 \
  --gpu-memory-utilization 0.92 \
  --max-model-len 8192 \
  --enforce-eager  # Избегаем graph capture проблем с некоторыми моделями

Не слепо копируйте настройки из интернета. Параметр --gpu-memory-utilization для A100X с HBM3e можно ставить выше 0.9, но только если у вас нет других нагрузок на GPU. Для стабильной работы под долгими нагрузками лучше 0.85-0.88.

3 Шаг третий: оптимизация пайплайна данных

Самое интересное. Даже правильно распределенная модель будет простаивать, если пайплайн загрузки и обработки данных не синхронизирован. Нужно перекрыть вычисления на GPU с передачей данных и препроцессингом на CPU.

Вот как НЕ надо делать (типичная ошибка):

# ПЛОХО: последовательная загрузка и обработка
for batch in dataloader:
    data = preprocess(batch)  # CPU
    data = data.to('cuda:0')  # Передача на GPU 0
    result = model(data)      # Вычисления на GPU
    save_results(result)      # CPU

А вот правильный подход с использованием CUDA Streams и асинхронных операций:

# ХОРОШО: параллельная работа CPU и GPU
import torch
import torch.cuda.stream as stream

# Создаем отдельные стримы для каждой GPU и для копирования
streams = [torch.cuda.Stream(device=i) for i in range(2)]
copy_streams = [torch.cuda.Stream(device=i) for i in range(2)]

# Буферы для перекрытия вычислений
next_batch = [None, None]
current_batch = [None, None]

with torch.cuda.stream(streams[0]), torch.cuda.stream(streams[1]):
    for i, batch in enumerate(dataloader):
        # Пока GPU обрабатывают текущий батч, CPU готовит следующий
        if i > 0:
            # Асинхронная передача следующего батча на GPU
            with torch.cuda.stream(copy_streams[0]):
                next_batch[0] = next_batch[0].to('cuda:0', non_blocking=True)
            with torch.cuda.stream(copy_streams[1]):
                next_batch[1] = next_batch[1].to('cuda:1', non_blocking=True)
            
        # Вычисления на GPU для текущего батча
        if current_batch[0] is not None:
            with torch.cuda.stream(streams[0]):
                output0 = model_part1(current_batch[0])
            with torch.cuda.stream(streams[1]):
                output1 = model_part2(current_batch[1])
        
        # Подготовка следующего батча на CPU (параллельно с GPU вычислениями)
        next_batch = preprocess_batch(batch)  # Возвращает список для каждой GPU
        
        # Синхронизация перед сменой ролей батчей
        torch.cuda.synchronize()
        current_batch, next_batch = next_batch, current_batch

Этот паттерн сложнее, но дает прирост 30-50% на задачах, где препроцессинг нетривиален (например, обработка изображений высокого разрешения или токенизация длинных текстов для LLM).

Нюансы, о которых молчат в мануалах

1. Память хоста - ваш враг и друг. На двух A100X с 128 ГБ каждая, у вас может быть 256 ГБ GPU-памяти. Но если в системе меньше 512 ГБ оперативной памяти - вы столкнетесь с свопингом. Особенно при загрузке больших датасетов. Решение - использовать memory-mapped файлы или базы данных вроде RocksDB для потоковой загрузки данных.

2. Тепловой режим. A100X в пассивном режиме (при полной нагрузке на обеих картах) могут разогреть корпус до 50+ градусов. Это приводит к троттлингу памяти HBM3e. Мониторьте температуру не только GPU, но и VRAM:

nvidia-smi --query-gpu=timestamp,name,temperature.gpu,temperature.memory,power.draw --format=csv -l 1

Если температура памяти превышает 95°C - производительность начнет падать. Нужно улучшать обдув карт или снижать частоту памяти через nvidia-smi.

3. Проблема с Python GIL. При использовании multi-GPU с data parallelism, каждая GPU обычно работает в отдельном процессе. Но если вы используете multi-threading для загрузки данных - GIL может стать бутылочным горлышком. Переходите на multiprocessing или используйте асинхронные загрузчики типа WebDataset.

💡
Если вы работаете с LLM и сталкиваетесь с проблемами производительности на multi-GPU, рекомендую сначала прочитать мой разбор про типичные ошибки распределения моделей. Там много специфичных для трансформеров моментов.

Мониторинг и финальная настройка

Настройка без мониторинга - это стрельба вслепую. Установите хотя бы простую дашборд:

# Установка и запуск простого мониторинга Prometheus + Node Exporter + NVIDIA DCGM Exporter
# 1. DCGM Exporter для метрик GPU
docker run -d --rm --name dcgm-exporter \
  --runtime=nvidia \
  -p 9400:9400 \
  nvcr.io/nvidia/k8s/dcgm-exporter:3.5.0-rc.3-ubuntu22.04

# 2. Prometheus конфиг для сбора метрик с хоста и GPU
cat > prometheus.yml << EOF
global:
  scrape_interval: 5s

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
  - job_name: 'dcgm'
    static_configs:
      - targets: ['localhost:9400']
EOF

# Запускаем Prometheus
docker run -d --rm --name prometheus \
  -p 9090:9090 \
  -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus:v3.0.0

Смотрите на ключевые метрики: utilization GPU, memory usage, PCIe throughput, и самое главное - kernel execution latency. Если ядра выполняются с большой задержкой - значит, есть contention за ресурсы или проблемы с планированием.

Последний совет: не гонитесь за 100% утилизацией обеих GPU одновременно. В реальных workload'ах идеально сбалансированная нагрузка бывает редко. 85-90% на каждой карте с эффективным пайплайном лучше, чем 100% с постоянными простоями из-за синхронизации.

Что в итоге? Цифры

После полной настройки пайплайна для инференса модели Mixtral 8x22B на двух A100X я получил:

  • Tokens per second: с 45 до 78 (прирост 73%)
  • Memory usage: 112 ГБ из 128 ГБ на каждой карте (используется эффективно)
  • GPU utilization: стабильные 88-92% на обеих картах
  • Температура памяти: не выше 92°C при 24°C в помещении

Главный вывод: две A100X - это не просто два раза одна A100X. Это качественно другая система, требующая пересмотра всего workflow. От аппаратного уровня до последней строчки кода в пайплайне данных. Если делать все правильно - вы получаете почти линейный scaling. Если нет - дорогие карты будут работать как одна, да еще и с перегревом. Удачи в настройке!

Подписаться на канал