混合部署架构:CPU+GPU协同推理的任务调度策略

#单纯 GPU 推理成本高,纯 CPU 推理延迟大。在实际工程中,一台服务器往往同时配备大量 CPU 核心和少量 GPU,如何让二者协同工作,最大化整机算力利用率,是推理架构设计的核心问题之一。

本篇聚焦 CPU+GPU 混合部署的架构模式与任务调度策略,从原理到工程实现全面覆盖。


1 混合部署的核心动机

1.1 资源互补

资源 CPU GPU
算力特点 串行/少并行,擅长复杂逻辑 大规模并行,擅长矩阵运算
内存容量 大(数百 GB 系统内存) 小(通常 16-80 GB 显存)
带宽特点 较低(百 GB/s 量级) 高(TB/s 量级 HBM)
成本

混合部署的本质是:用 CPU 的大内存承载模型权重溢出,用 GPU 的高算力加速热路径计算

1.2 典型场景

  1. 超大模型部署:单 GPU 显存不足以容纳全部模型权重,将部分层卸载到 CPU
  2. 成本敏感场景:用少量 GPU 处理高优先级/短 token 请求,CPU 处理低优先级/批处理请求
  3. 峰谷调度:GPU 满载时,溢出请求由 CPU 承接,保证服务可用性

2 架构模式一:层间分割(Layer-wise Offloading)

将 Transformer 模型的不同层分别部署在 CPU 和 GPU 上,数据在层间传递时跨设备流动。

2.1 工作原理

复制代码
输入 Tokens
    ↓
[Embedding Layer]       ← CPU 或 GPU
    ↓
[Layer 1-16]            ← GPU(显存充足的层)
    ↓ (数据传输: GPU→CPU)
[Layer 17-32]           ← CPU(溢出层)
    ↓ (数据传输: CPU→GPU)
[Output Head]           ← GPU
    ↓
输出 Tokens

瓶颈:层间数据传输(PCIe 带宽约 16-64 GB/s)会成为性能瓶颈,需要最小化跨设备传输次数。

2.2 llama.cpp 的 GPU 层卸载

llama.cpp 通过 -ngl(Number of GPU Layers)参数控制卸载层数:

bash 复制代码
# 安装 CUDA 支持版本
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release -j $(nproc)

# 将前 28 层卸载到 GPU,剩余层在 CPU 上运行
./build/bin/llama-cli \
    -m llama-3-70b.Q4_K_M.gguf \
    -t 16 \
    -ngl 28 \
    -c 4096 \
    -p "你好"

# 完全卸载到 GPU(所有层)
./build/bin/llama-cli -m model.gguf -ngl 999

# 纯 CPU 推理
./build/bin/llama-cli -m model.gguf -ngl 0

调优策略 :逐步增加 -ngl 的值,直到 GPU 显存接近上限(留 10% 余量),此时吞吐量通常最优。


3 架构模式二:请求级分流(Request-level Routing)

不同请求根据优先级、长度或资源预算,路由到不同的计算后端:

复制代码
                    ┌─────────────────┐
请求入口 ──────────► │  路由调度器       │
                    └────────┬────────┘
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
        [短序列/高优]   [中等序列]      [长序列/批处理]
              │              │              │
         GPU 后端        CPU 后端        CPU 后端
         (低延迟)        (中等延迟)      (高吞吐)

3.1 调度器实现(Python 示例)

python 复制代码
import asyncio
from dataclasses import dataclass
from enum import Enum

class Backend(Enum):
    GPU = "gpu"
    CPU = "cpu"

@dataclass
class InferenceRequest:
    prompt: str
    max_tokens: int
    priority: int    # 1=高优, 2=普通, 3=低优

class HybridScheduler:
    def __init__(self):
        self.gpu_queue = asyncio.Queue(maxsize=32)
        self.cpu_queue = asyncio.Queue(maxsize=256)
        
        # 路由规则
        self.GPU_MAX_TOKENS = 512      # GPU 处理短生成
        self.HIGH_PRIORITY_THRESHOLD = 1

    def route(self, request: InferenceRequest) -> Backend:
        """决定请求路由到哪个后端"""
        # 规则 1:高优先级请求走 GPU
        if request.priority == self.HIGH_PRIORITY_THRESHOLD:
            return Backend.GPU
        
        # 规则 2:短生成请求走 GPU(延迟敏感)
        if request.max_tokens <= self.GPU_MAX_TOKENS:
            return Backend.GPU
        
        # 规则 3:GPU 队列已满,降级到 CPU
        if self.gpu_queue.full():
            return Backend.CPU
        
        return Backend.CPU

    async def submit(self, request: InferenceRequest):
        backend = self.route(request)
        if backend == Backend.GPU:
            await self.gpu_queue.put(request)
        else:
            await self.cpu_queue.put(request)
        return backend

4 架构模式三:流水线并行(Pipeline Parallelism)

将一个请求的处理拆分为多个阶段,CPU 和 GPU 同时处理不同阶段的不同请求,形成流水线:

复制代码
时间线:
GPU: [请求A推理]  [请求B推理]  [请求C推理]
CPU: [请求A后处理] [请求B预处理] [请求C后处理]
                  ↑同时进行↑

CPU 负责:tokenization、prompt 格式化、后处理、结果序列化

GPU 负责:模型前向推理

这种模式下,CPU 与 GPU 几乎不存在等待,整体吞吐量接近纯 GPU 推理的上限。


5 PCIe 数据传输优化

混合部署的隐性瓶颈是 CPU-GPU 之间的数据传输。

5.1 使用锁页内存(Pinned Memory)

python 复制代码
import torch

# 普通内存(需要先拷贝到锁页内存再传输)
cpu_tensor = torch.randn(1000, 1000)

# 锁页内存(直接走 DMA,传输速度提升 2-3x)
pinned_tensor = torch.randn(1000, 1000).pin_memory()

# 异步传输到 GPU(不阻塞 CPU 计算)
gpu_tensor = pinned_tensor.to("cuda", non_blocking=True)

# CPU 和 GPU 可以同时工作
do_cpu_work()

# 同步点:确保传输完成
torch.cuda.synchronize()

5.2 重叠传输与计算

python 复制代码
import torch

stream_compute = torch.cuda.Stream()
stream_transfer = torch.cuda.Stream()

for batch in dataloader:
    # 在传输流中异步上传下一批数据
    with torch.cuda.stream(stream_transfer):
        next_batch_gpu = batch.pin_memory().to("cuda", non_blocking=True)
    
    # 在计算流中处理当前批次
    with torch.cuda.stream(stream_compute):
        output = model(current_batch_gpu)
    
    # 等待传输完成后切换
    stream_compute.wait_stream(stream_transfer)
    current_batch_gpu = next_batch_gpu

6 显存不足时的动态卸载策略

当推理过程中 GPU 显存耗尽时,需要动态将部分数据卸载到 CPU:

python 复制代码
import torch

class MemoryAwareModel:
    def __init__(self, model, cpu_offload_threshold=0.9):
        self.model = model
        self.threshold = cpu_offload_threshold
    
    def get_gpu_memory_ratio(self) -> float:
        """获取 GPU 显存使用率"""
        if not torch.cuda.is_available():
            return 0.0
        used = torch.cuda.memory_allocated()
        total = torch.cuda.get_device_properties(0).total_memory
        return used / total
    
    def maybe_offload(self):
        """显存使用率超阈值时,将 KV Cache 卸载到 CPU"""
        if self.get_gpu_memory_ratio() > self.threshold:
            torch.cuda.empty_cache()
            # 将历史 KV Cache 移到 CPU
            for layer in self.model.layers:
                if hasattr(layer, "kv_cache") and layer.kv_cache is not None:
                    layer.kv_cache = layer.kv_cache.cpu()
    
    def forward(self, input_ids):
        self.maybe_offload()
        return self.model(input_ids)

7 总结与选型建议

场景 推荐架构
70B+ 模型,显存不足 层间分割(llama.cpp -ngl 调参)
高并发,请求特征差异大 请求级分流(GPU 短请求 + CPU 长请求)
吞吐量最大化,延迟要求宽松 流水线并行
GPU 显存充足,CPU 做预处理 锁页内存 + 异步传输

核心原则

  • 最小化 PCIe 传输次数,将跨设备数据传输与计算重叠
  • GPU 做计算密集操作,CPU 做逻辑密集操作(路由、格式化、后处理)
  • 监控 GPU 显存利用率和 PCIe 带宽占用,这两个是混合部署的核心瓶颈指标
相关推荐
AI小技巧13 分钟前
告别学习工具成瘾,这些管控平台超神!
人工智能·机器学习
sduwcgg25 分钟前
IQ-Learn 在 RTX 3090 服务器上的环境配置与踩坑记录
运维·服务器
野生的程序媛30 分钟前
关于我做了一个玩偶姐姐桌宠
人工智能·深度学习·神经网络·机器学习·chatgpt·ai作画·gpt-3
AI周红伟1 小时前
周红伟:运营商一季度净利集体下滑 Token运营提速
大数据·网络·人工智能
LaughingZhu1 小时前
Product Hunt 每日热榜 | 2026-05-04
人工智能·经验分享·深度学习·神经网络·产品运营
无忧智库1 小时前
研发管理的下一个十年:当多Agent协同遇上知识图谱,传统项目管理体系正在被颠覆(WORD)
大数据·人工智能·知识图谱
mit6.8241 小时前
人类数据 | 行为克隆 | 机器人学习的未来
人工智能·机器人
QFIUNE1 小时前
CD-HIT 详解:序列去冗余、安装使用与聚类结果解析
linux·服务器·机器学习·数据挖掘·conda·聚类
小饕1 小时前
AI编程的三阶段演化:哪些方向真正值得投入,哪些被高估了
人工智能·ai编程
蔡俊锋1 小时前
把1500个业务的大迁移,做成了可复用流水线用 Skill+Agent+Rule,省下 60 人年的实战复盘
人工智能·skill+agent