# 多 GPU 设置

在 CLORE.AI 上跨多 GPU 运行大型 AI 模型。

{% hint style="success" %}
在 查找 多 GPU 服务器 于 [CLORE.AI 市场](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 工作流中
# 使用带有 device 参数的“Load Checkpoint”
# device: "cuda:0" 表示第一个 GPU
# device: "cuda:1" 表示第二个 GPU
```

**在单独 GPU 上运行 VAE：**

```python
# 主模型在 GPU 0
# VAE 在 GPU 1
# 减少显存压力
```

### Stable Diffusion WebUI

**在 webui-user.sh 中启用多 GPU：**

```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 分布式

```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 训练（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
批处理处理
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"

# 或使用 torch
import torch
device = torch.device("cuda:0")  # 第一个可见 GPU
device = torch.device("cuda:1")  # 第二个可见 GPU
```

***

## 性能优化

### NVLink 与 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
```

### "多 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/小时）  | 多 GPU  |
| 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：稳定扩散
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-zh/yu-yan-mo-xing/vllm) - 生产级 LLM 服务
* [GPU 对比](https://docs.clore.ai/guides/guides_v2-zh/kuai-su-ru-men/gpu-comparison) - 选择你的 GPU
* [API 集成](https://docs.clore.ai/guides/guides_v2-zh/gao-ji/api-integration) - 构建应用程序
* [成本计算器](https://docs.clore.ai/guides/guides_v2-zh/kuai-su-ru-men/cost-calculator) - 估算成本
