Настройка vLLM на Ubuntu с 3 GPU: разбор pipeline-parallel и проблем железа | AiManual
AiManual Logo Ai / Manual.
22 Фев 2026 Гайд

Три карты, три проблемы: как настроить vLLM на Ubuntu с разными GPU и не сойти с ума

Подробный гайд по настройке vLLM с pipeline-parallel на трех GPU разного объема VRAM. Решаем проблемы материнской платы, распределения слоев и OOM ошибок. Практ

Когда железо работает против вас

Вы собрали систему с тремя GPU: RTX 5070 Ti (16 ГБ) и две RTX Pro 4000 (по 8 ГБ). Теоретически 32 ГБ VRAM - хватит для Llama 3.3 70B в 4-битном квантовании. Вы устанавливаете Ubuntu 24.04 LTS, драйверы NVIDIA 560.xx, vLLM 0.5.8 (самая свежая на февраль 2026). Запускаете с pipeline-parallel и... получаете Out of Memory на третьей карте. Или модель загружается, но скорость генерации 2 токена в секунду. Или система зависает при попытке распределить слои.

Знакомо? Я провел три дня с такой конфигурацией. Проблема не в vLLM. Проблема в том, как он распределяет слои по умолчанию и как материнская плата распределяет PCIe линии. Особенно когда карты разные по объему памяти.

Самая частая ошибка: запускать vLLM с pipeline-parallel без ручного распределения слоев. По умолчанию он делит модель поровну между GPU. Если у вас 80 слоев и 3 карты, он попытается положить ~27 слоев на каждую. Но RTX Pro 4000 с 8 ГБ не потянет столько. OOM гарантирован.

Что такое pipeline-parallel на самом деле

В статье "Две карты, одна скорость" я уже объяснял разницу между типами параллелизма. Pipeline-parallel - это не магия, а последовательная обработка. Токен проходит через GPU 0, потом GPU 1, потом GPU 2. Если один GPU медленнее или у него меньше памяти, он становится бутылочным горлышком.

С тремя разными картами ситуация усугубляется. RTX 5070 Ti быстрее и с большей памятью. RTX Pro 4000 - медленнее, память меньше. Если распределить слои равномерно, самая слабая карта будет тормозить всю цепочку.

Проблема материнской платы: PCIe lanes и bandwidth

Перед настройкой vLLM проверьте, как материнская плата видит ваши карты. Особенно если у вас consumer-grade материнка, а не серверная.

# Проверяем PCIe конфигурацию
lspci -vv | grep -A 10 "VGA\|3D"

# Смотрим ширину линий
nvidia-smi topo -m

# Проверяем доступную память на каждой карте
nvidia-smi --query-gpu=memory.total,memory.free --format=csv

В моем случае проблема была в материнской плате ASUS ProArt X670E-CREATOR WIFI. С тремя GPU она распределяла линии так: x16, x8, x4. Карта на x4 работала в два раза медленнее. Для pipeline-parallel это критично - данные постоянно передаются между картами.

💡
Если третья карта на x4, подумайте о переходе на tensor-parallel для первых двух карт, а третью оставьте для другой модели. Или купите материнскую плату с большим количеством PCIe линий. В статье "7 видеокарт на AM5" я разбирал варианты с коммутаторами.

1 Проверка железа перед настройкой

Сначала убедитесь, что все карты видны и P2P (peer-to-peer) communication работает:

# Устанавливаем последние драйверы (на 22.02.2026 актуальна версия 560.35.03)
sudo apt update
sudo apt install nvidia-driver-560 nvidia-utils-560

# Перезагружаемся
sudo reboot

# Проверяем P2P доступ
nvidia-smi topo -p2p n

# Если видите "No" между некоторыми картами - проблемы
# Это значит данные будут идти через RAM, а не напрямую между GPU

Если P2P не работает между всеми картами, производительность pipeline-parallel упадет на 30-50%. Особенно если карты на разных чипсетах.

2 Установка и настройка vLLM

Устанавливаем самую свежую версию vLLM (на февраль 2026 это 0.5.8):

# Создаем виртуальное окружение
python -m venv vllm_env
source vllm_env/bin/activate

# Устанавливаем с поддержкой CUDA 12.4
pip install vllm==0.5.8

# Дополнительно для квантования (актуально на 2026)
pip install bitsandbytes>=0.43.0
pip install autoawq>=0.2.8

Важно: vLLM 0.5.8 требует PyTorch 2.4+. Если у вас старая система, могут быть конфликты. Лучше использовать Docker образ от vLLM: docker run --gpus all -it vllm/vllm-openai:latest

Магия VLLM_PP_LAYER_PARTITION

Вот где начинается самое интересное. Переменная окружения VLLM_PP_LAYER_PARTITION позволяет вручную указать, сколько слоев модели идет на каждую карту. Формат: "start_layer:end_layer,start_layer:end_layer,..."

Для трех карт с разным объемом VRAM нужно рассчитать распределение. Возьмем Llama 3.3 70B с 80 слоями:

  • RTX 5070 Ti (16 ГБ) - может взять больше слоев
  • RTX Pro 4000 #1 (8 ГБ) - меньше слоев
  • RTX Pro 4000 #2 (8 ГБ) - меньше слоев

Примерное распределение: 35 слоев на первую карту, 22 на вторую, 23 на третью. Но это нужно проверять экспериментально.

3 Запуск с правильным распределением слоев

# Экспортируем переменную окружения
# Формат: GPU0:слои_0-34, GPU1:слои_35-56, GPU2:слои_57-79
export VLLM_PP_LAYER_PARTITION="0:35,35:57,57:80"

# Запускаем vLLM с pipeline-parallel
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3.3-70B-Instruct \
  --tensor-parallel-size 1 \
  --pipeline-parallel-size 3 \
  --quantization awq \
  --gpu-memory-utilization 0.9 \
  --max-model-len 8192 \
  --port 8000

Ключевые моменты:

  1. --tensor-parallel-size 1 - отключаем tensor parallelism, используем только pipeline
  2. --pipeline-parallel-size 3 - используем все три карты
  3. --quantization awq - активационно-взвешенное квантование, экономит память
  4. --gpu-memory-utilization 0.9 - используем 90% памяти каждой карты
💡
Если не задать VLLM_PP_LAYER_PARTITION, vLLM попытается распределить слои автоматически. В версии 0.5.8 алгоритм улучшили, но для смешанных конфигураций он все равно часто ошибается. Всегда задавайте распределение вручную.

Как рассчитать оптимальное распределение

Вот мой рабочий скрипт для расчета распределения слоев:

#!/usr/bin/env python3
"""
Калькулятор распределения слоев для vLLM pipeline-parallel
Актуально для vLLM 0.5.8 (февраль 2026)
"""

def calculate_layer_partition(total_layers, gpu_memory_gb):
    """
    Рассчитывает распределение слоев на основе доступной памяти GPU
    
    total_layers: общее количество слоев в модели
    gpu_memory_gb: список с объемом памяти каждой GPU в ГБ
    возвращает: строку для VLLM_PP_LAYER_PARTITION
    """
    
    # Примерные требования памяти на слой для Llama 70B в AWQ
    # На февраль 2026 эти значения актуальны для vLLM 0.5.8
    memory_per_layer = {
        "70B": 0.18,  # ГБ на слой для 4-битного квантования
        "130B": 0.32,
        "8B": 0.03
    }
    
    model_size = "70B"  # или определяем автоматически
    layer_memory_gb = memory_per_layer[model_size]
    
    # Рассчитываем максимальное количество слоев для каждой карты
    max_layers_per_gpu = []
    for memory in gpu_memory_gb:
        # Оставляем 10% памяти под кэш и системные нужды
        usable_memory = memory * 0.9
        max_layers = int(usable_memory / layer_memory_gb)
        max_layers_per_gpu.append(max_layers)
    
    print(f"Максимально слоев на GPU: {max_layers_per_gpu}")
    
    # Распределяем слои пропорционально доступной памяти
    total_max_layers = sum(max_layers_per_gpu)
    if total_max_layers < total_layers:
        print(f"ВНИМАНИЕ: Не хватает памяти! Нужно {total_layers} слоев, доступно {total_max_layers}")
        print("Попробуйте более агрессивное квантование или уменьшите max-model-len")
        return None
    
    # Распределяем
    layers_assigned = []
    current_layer = 0
    
    for i, max_layers in enumerate(max_layers_per_gpu):
        # Берем пропорциональную часть от доступных слоев
        proportion = max_layers / total_max_layers
        layers_to_assign = int(total_layers * proportion)
        
        # Для последней карты берем все оставшиеся слои
        if i == len(max_layers_per_gpu) - 1:
            end_layer = total_layers
        else:
            end_layer = current_layer + layers_to_assign
            
        layers_assigned.append((current_layer, end_layer))
        current_layer = end_layer
    
    # Форматируем для VLLM_PP_LAYER_PARTITION
    partition_str = ",".join([f"{start}:{end}" for start, end in layers_assigned])
    
    print(f"\nРекомендуемое распределение:")
    for i, (start, end) in enumerate(layers_assigned):
        print(f"GPU {i} (VRAM: {gpu_memory_gb[i]}GB): слои {start}-{end-1} ({end-start} слоев)")
    
    print(f"\nЭкспорт для vLLM:")
    print(f"export VLLM_PP_LAYER_PARTITION='{partition_str}'")
    
    return partition_str


if __name__ == "__main__":
    # Пример для 3 GPU: 16GB, 8GB, 8GB
    gpu_memory = [16, 8, 8]
    
    # Llama 3.3 70B имеет 80 слоев
    partition = calculate_layer_partition(80, gpu_memory)

Проблемы и решения

Проблема 1: OOM на одной из карт

Симптом: vLLM падает с CUDA out of memory, хотя вроде бы памяти должно хватать.

Решение: уменьшите --gpu-memory-utilization с 0.9 до 0.8 или 0.7. Или пересчитайте распределение слоев, отдав больше слоев карте с большей памятью.

Проблема 2: Низкая скорость генерации

Симптом: модель загрузилась, но работает медленнее, чем на одной карте.

Решение: проверьте P2P communication и PCIe bandwidth. Если третья карта на x4, попробуйте использовать только две карты с tensor-parallel:

# Используем только две быстрые карты с tensor-parallel
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3.3-70B-Instruct \
  --tensor-parallel-size 2 \  # Делим модель между двумя картами
  --pipeline-parallel-size 1 \
  --quantization awq \
  --gpu-memory-utilization 0.9 \
  --max-model-len 8192 \
  --port 8000

Проблема 3: Нестабильная работа

Симптом: vLLM работает несколько часов, потом падает.

Решение: проверьте температуру карт. RTX Pro 4000 греются сильнее, особенно в плотном корпусе. Установите лимиты мощности:

# Устанавливаем лимит мощности 150W на RTX 5070 Ti и 100W на RTX Pro 4000
sudo nvidia-smi -i 0 -pl 150  # GPU 0
sudo nvidia-smi -i 1 -pl 100  # GPU 1
sudo nvidia-smi -i 2 -pl 100  # GPU 2

Сравнение производительности

Конфигурация Скорость (токенов/с) Загрузка VRAM Стабильность
3 GPU, автораспределение 2-3 OOM на GPU2 ❌ Падает
3 GPU, ручное распределение 12-15 14/8/8 ГБ ✅ Стабильно
2 GPU (tensor-parallel) 18-22 16/8 ГБ ✅ Очень стабильно
1 GPU (5070 Ti) 8-10 16 ГБ ✅ Идеально

Как видите, три карты с ручным распределением дают прирост, но не в 3 раза. Из-за накладных расходов на передачу данных между картами. Две карты с tensor-parallel часто оказываются эффективнее.

Когда pipeline-parallel имеет смысл

Используйте pipeline-parallel с тремя GPU только если:

  • Все карты имеют одинаковый объем памяти (или очень близкий)
  • Материнская плата обеспечивает минимум x8 для каждой карты
  • Вам критически важен объем памяти, а не скорость
  • Вы готовы тратить время на тонкую настройку

В большинстве случаев для трех разных карт лучше использовать hybrid подход: tensor-parallel для двух основных карт, а третью оставить для другой задачи или для обработки embeddings.

Совет от бывалого: Если у вас смешанная конфигурация (как у меня: 16+8+8), не пытайтесь выжать максимум из всех трех карт. Используйте две карты для основной модели, третью - для эмбеддинговой модели или RAG. Так вы получите стабильную работу без головной боли.

Дальнейшая оптимизация

Если вы все же решили использовать все три карты:

  1. Настройте swap на быстром NVMe - если vLLM все же выйдет за пределы VRAM, лучше иметь быстрый swap, чем падение
  2. Используйте continuous batching - в vLLM 0.5.8 он включен по умолчанию, но проверьте параметры --max-num-batched-tokens и --max-num-seqs
  3. Обновите драйверы до последней версии - NVIDIA постоянно улучшает multi-GPU поддержку
  4. Рассмотрите альтернативы - если vLLM не работает стабильно, попробуйте TGI или ExLlamaV2

Самая неочевидная настройка: если у вас есть свободная RAM, выделите часть ее под pinned memory для CUDA. Это ускорит передачу данных между GPU:

# В /etc/environment или в скрипте запуска
export CUDA_MANAGED_FORCE_DEVICE_ALLOC=1
export CUDA_VISIBLE_DEVICES=0,1,2

Что делать, если ничего не помогает

Бывает. Железо бывает капризным. В таком случае:

  1. Проверьте, нет ли проблем с питанием. Три карты могут потреблять 500+ ватт.
  2. Обновите BIOS материнской платы. Особенно важны обновления, связанные с PCIe распределением.
  3. Попробуйте другой дистрибутив Linux. Ubuntu 24.04 обычно работает хорошо, но иногда помогает перейти на чистый Debian.
  4. Рассмотрите аппаратные ограничения. Может, ваша материнская плата просто не предназначена для трех активных GPU.

Иногда лучше признать поражение и перейти на две карты. Как я писал в статье про две карты, правильно настроенная dual-GPU система работает надежнее, чем нестабильная triple-GPU.

И последний совет: если вы только планируете сборку, не повторяйте мою ошибку. Берите одинаковые карты. Или берите две мощные, а не три разных. Жизнь слишком коротка, чтобы тратить ее на отладку VLLM_PP_LAYER_PARTITION в 3 утра.