# Настройка multi-GPU

Запускайте крупные модели ИИ на нескольких GPU на CLORE.AI.

{% hint style="success" %}
Найдите серверы с несколькими GPU на [CLORE.AI Marketplace](https://clore.ai/marketplace).
{% endhint %}

## Когда требуется несколько GPU?

| Размер модели | Вариант с одним GPU | Вариант с несколькими GPU |
| ------------- | ------------------- | ------------------------- |
| ≤13B          | RTX 3090 (Q4)       | Не требуется              |
| 30B           | RTX 4090 (Q4)       | 2x RTX 3090               |
| 70B           | A100 40GB (Q4)      | 2x RTX 4090               |
| 70B FP16      | -                   | 2x A100 80GB              |
| 100B+         | -                   | 4x A100 80GB              |
| 405B          | -                   | 8x A100 80GB              |

***

## Понятия мульти-GPU

### Тензорный параллелизм (TP)

Разделение слоёв модели между GPU. Лучшее для инференса.

```
GPU 0: Слои 1–20
GPU 1: Слои 21–40
```

**Плюсы:** Низкая задержка, простая настройка **Минусы:** Требуется высокоскоростное соединение

### Конвейерный параллелизм (PP)

Обработка разных батчей на разных GPU.

```
GPU 0: Батч 1 → GPU 1: Батч 1
GPU 0: Батч 2 → GPU 1: Батч 2
```

**Плюсы:** Более высокая пропускная способность **Минусы:** Более высокая задержка, более сложная настройка

### Данные параллелизм (DP)

Одна и та же модель на нескольких GPU, разные данные.

```
GPU 0: Обработка батча A
GPU 1: Обработка батча B
```

**Плюсы:** Простое, линейное масштабирование **Минусы:** Каждому GPU нужна полная модель

***

## Настройка LLM для нескольких GPU

### vLLM (рекомендуется)

**2 GPU:**

```bash
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 2 \
    --host 0.0.0.0
```

**4 GPU:**

```bash
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 4 \
    --host 0.0.0.0
```

**8 GPU (для 405B):**

```bash
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-405B-Instruct \
    --tensor-parallel-size 8 \
    --host 0.0.0.0
```

### Ollama и мульти-GPU

Ollama автоматически использует несколько GPU, если они доступны:

```bash
# Проверить доступные GPU
nvidia-smi

# Ollama автоматически обнаружит и использует все GPU
ollama run llama3.1:70b
```

**Ограничить конкретными GPU:**

```bash
CUDA_VISIBLE_DEVICES=0,1 ollama run llama3.1:70b
```

### Text Generation Inference (TGI)

```bash
docker run --gpus all -p 8080:80 \
    ghcr.io/huggingface/text-generation-inference:latest \
    --model-id meta-llama/Llama-3.1-70B-Instruct \
    --num-shard 2
```

### llama.cpp

```bash
# Указать слои GPU для каждого устройства
./llama-server \
    -m llama-3.1-70b-q4.gguf \
    -ngl 999 \
    --split-mode layer \
    --tensor-split 0.5,0.5
```

***

## Генерация изображений на нескольких GPU

### ComfyUI

ComfyUI может разгружать разные модели на разные GPU:

```python
# В рабочем процессе ComfyUI
# Используйте «Load Checkpoint» с параметром device
# device: "cuda:0" для первого GPU
# device: "cuda:1" для второго GPU
```

**Запустить VAE на отдельном GPU:**

```python
# Основная модель на GPU 0
# VAE на GPU 1
# Снижает нагрузку на VRAM
```

### Stable Diffusion WebUI

**Включить мульти-GPU в webui-user.sh:**

```bash
export COMMANDLINE_ARGS="--device-id 0"
# Или для конкретных моделей:
export COMMANDLINE_ARGS="--lowvram --device-id 0,1"
```

### FLUX и мульти-GPU

```python
from diffusers import FluxPipeline
import torch

pipe = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev",
    torch_dtype=torch.bfloat16
)

# Распределить по GPU
pipe.enable_model_cpu_offload()  # или
pipe.to("cuda:0")  # Явный выбор GPU
```

***

## Обучение на нескольких GPU

### PyTorch Distributed

```python
import torch
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP

# Инициализация
dist.init_process_group("nccl")
local_rank = int(os.environ["LOCAL_RANK"])
torch.cuda.set_device(local_rank)

# Обернуть модель
model = YourModel().to(local_rank)
model = DDP(model, device_ids=[local_rank])

# Цикл обучения как обычно
```

**Запуск:**

```bash
torchrun --nproc_per_node=2 train.py
```

### DeepSpeed

```python
import deepspeed

model, optimizer, _, _ = deepspeed.initialize(
    model=model,
    config={
        "train_batch_size": 32,
        "fp16": {"enabled": True},
        "zero_optimization": {"stage": 2}
    }
)
```

**Запуск:**

```bash
deepspeed --num_gpus=2 train.py
```

### Accelerate (HuggingFace)

```python
from accelerate import Accelerator

accelerator = Accelerator()
model, optimizer, dataloader = accelerator.prepare(
    model, optimizer, dataloader
)
```

**Настроить:**

```bash
accelerate config  # Интерактивная настройка
accelerate launch train.py
```

### Kohya Training (LoRA)

```bash
# Мульти-GPU обучение LoRA
accelerate launch --num_processes=2 train_network.py \
    --pretrained_model_name_or_path="model.safetensors" \
    --train_data_dir="./images" \
    --output_dir="./output"
```

***

## Выбор GPU

### Проверить доступные GPU

```bash
# Перечислить все GPU
nvidia-smi

# Подробная информация
nvidia-smi -L

# Использование памяти
nvidia-smi --query-gpu=index,memory.used,memory.total --format=csv
```

### Выбрать конкретные GPU

**Переменная окружения:**

```bash
# Использовать только GPU 0 и 1
export CUDA_VISIBLE_DEVICES=0,1
python your_script.py

# Использовать только GPU 2
export CUDA_VISIBLE_DEVICES=2
python your_script.py
```

**В Python:**

```python
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"

# Или с torch
import torch
device = torch.device("cuda:0")  # Первый видимый GPU
device = torch.device("cuda:1")  # Второй видимый GPU
```

***

## Оптимизация производительности

### NVLink vs PCIe

| Соединение | Пропускная способность | Лучше всего для            |
| ---------- | ---------------------- | -------------------------- |
| NVLink     | 600 GB/s               | Тензорный параллелизм      |
| PCIe 4.0   | 32 GB/s                | Параллелизм данных         |
| PCIe 5.0   | 64 GB/s                | Смешанные рабочие нагрузки |

**Проверить статус NVLink:**

```bash
nvidia-smi nvlink --status
```

### Оптимальная конфигурация

| GPU | Размер TP | Размер PP | Примечания                    |
| --- | --------- | --------- | ----------------------------- |
| 2   | 2         | 1         | Простой тензорный параллелизм |
| 4   | 4         | 1         | Требует NVLink                |
| 4   | 2         | 2         | Дружелюбно к PCIe             |
| 8   | 8         | 1         | Полный тензорный параллелизм  |
| 8   | 4         | 2         | Смешанный параллелизм         |

### Балансировка памяти

**Равномерное разделение (по умолчанию):**

```bash
--tensor-parallel-size 2
```

**Пользовательское разделение (неравные GPU):**

```bash
# vLLM не поддерживает неравномерное, используйте llama.cpp:
./llama-server --tensor-split 0.6,0.4
```

***

## Устранение неполадок

### "Ошибка NCCL"

```bash
# Установить отладку NCCL
export NCCL_DEBUG=INFO

# Попробовать разные алгоритмы NCCL
export NCCL_ALGO=Ring
```

### "Недостаточно памяти на GPU X"

```bash
# Проверить память на каждом GPU
nvidia-smi

# Уменьшить размер батча
--max-batch-size 1

# Включить gradient checkpointing (при обучении)
--gradient-checkpointing
```

### "Медленная работа на нескольких GPU"

1. Проверить подключение NVLink
2. Уменьшить размер тензорного параллелизма
3. Использовать конвейерный параллелизм вместо этого
4. Проверить узкое место в CPU

### "GPU не обнаружены"

```bash
# Проверить CUDA
nvidia-smi

# Проверить, видит ли PyTorch GPU
python -c "import torch; print(torch.cuda.device_count())"

# При необходимости переустановить драйверы CUDA
```

***

## Оптимизация затрат

### Когда стоит использовать несколько GPU

| Сценарий                      | Один GPU            | Мульти-GPU             | Победитель         |
| ----------------------------- | ------------------- | ---------------------- | ------------------ |
| 70B для редкого использования | A100 80GB ($0.25/ч) | 2x RTX 4090 ($0.20/ч)  | Мульти             |
| 70B в продакшене              | A100 40GB ($0.17/ч) | 2x A100 40GB ($0.34/ч) | Один (Q4)          |
| Обучение 7B                   | RTX 4090 ($0.10/ч)  | 2x RTX 4090 ($0.20/ч)  | Зависит от времени |

### Экономичные конфигурации

| Случай использования | Конфигурация | \~Стоимость/ч |
| -------------------- | ------------ | ------------- |
| 70B инференс         | 2x RTX 3090  | $0.12         |
| 70B быстрый инференс | 2x A100 40GB | $0.34         |
| 70B FP16             | 2x A100 80GB | $0.50         |
| Обучение 13B         | 2x RTX 4090  | $0.20         |

***

## Примеры конфигураций

### 70B чат-сервер

```bash
# Настройка 2x A100 40GB
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-70B-Instruct \
    --tensor-parallel-size 2 \
    --max-model-len 8192 \
    --host 0.0.0.0 \
    --port 8000
```

### DeepSeek-V3 (671B)

```bash
# Требуется 8x A100 80GB
python -m vllm.entrypoints.openai.api_server \
    --model deepseek-ai/DeepSeek-V3 \
    --tensor-parallel-size 8 \
    --trust-remote-code \
    --host 0.0.0.0
```

### Пайплайн: изображение + LLM

```bash
# GPU 0: Stable Diffusion
CUDA_VISIBLE_DEVICES=0 python comfyui/main.py --port 8188 &

# GPU 1: LLM для подсказок
CUDA_VISIBLE_DEVICES=1 python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-3.1-8B-Instruct --port 8000
```

***

## Дальнейшие шаги

* [Руководство по vLLM](https://docs.clore.ai/guides/guides_v2-ru/yazykovye-modeli/vllm) - Продакшн-сервис LLM
* [Сравнение GPU](https://docs.clore.ai/guides/guides_v2-ru/nachalo-raboty/gpu-comparison) - Выберите ваши GPU
* [Интеграция API](https://docs.clore.ai/guides/guides_v2-ru/prodvinutoe/api-integration) - Создавайте приложения
* [Калькулятор затрат](https://docs.clore.ai/guides/guides_v2-ru/nachalo-raboty/cost-calculator) - Оцените затраты
