# 多 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 指南](/guides/guides_v2-zh/yu-yan-mo-xing/vllm.md) - 生产级 LLM 服务
* [GPU 对比](/guides/guides_v2-zh/kai-shi-shi-yong/gpu-comparison.md) - 选择你的 GPU
* [API 集成](/guides/guides_v2-zh/gao-ji/api-integration.md) - 构建应用程序
* [成本计算器](/guides/guides_v2-zh/kai-shi-shi-yong/cost-calculator.md) - 估算成本


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/gao-ji/multi-gpu-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
