CPU与GPU深度学习负载评测方法与选型指南

作者:暴富20212026.11.13 03:37浏览量:0

简介:本文给出CPU与GPU运行深度学习负载的可复现评测方法,涵盖测试环境固定、批量与并发设计、延迟与吞吐口径、稳定性与成本记录,并提供按训练、推理和通用业务划分的选型判定规则。读者可直接套用流程,用自有负载数据做出硬件决策。

一、先说结论

CPU还是GPU更合适,取决于负载形态、延迟要求和长期成本,没有统一答案。矩阵运算占主导的训练和批量推理,通常能从GPU获得更高吞吐。小批量、分支多、要求低延迟的在线服务,CPU往往更省事,单次响应也更稳定。本文不给出某个型号的排名,而是提供一套方法,让团队用自己的负载得出结论。

二、术语边界

  • CPU:通用处理器,核心数量少,单核能力强,适合控制逻辑复杂、依赖关系多的串行任务。
  • GPU:最初为图形渲染设计,由大量相对简单的计算单元组成,适合对大批数据执行相同操作。
  • GPGPU:把GPU用于图形以外的通用计算,通过CUDA、ROCm等编程栈调用。
  • AI加速芯片:泛指面向神经网络优化的硬件,包括GPU,也包括专用ASIC(如NPU、TPU)。GPU是AI加速芯片的一类,两者不能等同。

本文测试对象限定为CPU和GPU。专用ASIC需要单独核对算子覆盖率,结论不能直接外推。

三、测试环境固定

每组对比只改变一个主要变量。测试前,记录并固定以下参数:

项目 记录内容 示例
处理器 完整型号、核心数、基础频率 写明厂商型号与线程数
GPU 完整型号、显存容量、驱动版本 驱动版本需与CUDA版本匹配
系统 操作系统版本、内核版本 两端保持一致
软件栈 CUDA版本、Python版本、框架版本 如PyTorch 2.x
CPU策略 调频策略、是否开启超线程、线程数 调频固定为performance
运行环境 机房温度、是否独占机器 测试期间关闭无关进程

CPU端的线程数需要通过torch.set_num_threads()或环境变量显式设置,避免框架自动选择导致结果漂移。

四、负载设计

建议使用三类负载,并在两种硬件上完全相同地执行:

  1. 微基准:单精度矩阵乘,矩阵尺寸取1024、2048、4096,用于观察纯算力差异。
  2. 模型推理:ResNet-50图像分类(输入224×224),BERT-base文本分类(序列长度128)。
  3. 训练迭代:同一模型执行完整的前向、反向和参数更新,记录单步耗时。

批量大小取1、8、32、128、512。显存不足导致的失败点需要单独记录,因为它本身就是选型信息。并发设置包括单进程串行,以及4路、8路并发两组。数据使用固定随机种子生成,并记录形状和精度(FP32、FP16)。

五、测量方法

下面的脚本计算延迟分位数和吞吐。GPU计时前后必须调用同步函数,否则测到的只是异步提交的时间。

  1. import time
  2. import torch
  3. def bench(model, x, device="cuda", warmup=20, iters=200):
  4. model.eval()
  5. use_cuda = device == "cuda"
  6. with torch.inference_mode():
  7. for _ in range(warmup):
  8. model(x)
  9. if use_cuda:
  10. torch.cuda.synchronize()
  11. lat_ms = []
  12. for _ in range(iters):
  13. t0 = time.perf_counter()
  14. model(x)
  15. if use_cuda:
  16. torch.cuda.synchronize()
  17. lat_ms.append((time.perf_counter() - t0) * 1000)
  18. lat_ms.sort()
  19. p50 = lat_ms[len(lat_ms) // 2]
  20. p95 = lat_ms[int(len(lat_ms) * 0.95) - 1]
  21. mean_ms = sum(lat_ms) / len(lat_ms)
  22. throughput = x.shape[0] * 1000 / mean_ms # 样本/秒
  23. return p50, p95, throughput

资源监控使用以下命令,采样间隔为1秒:

  1. # GPU利用率、显存、功耗、温度
  2. nvidia-smi --query-gpu=utilization.gpu,memory.used,power.draw,temperature.gpu --format=csv -l 1
  3. # CPU每核利用率(Linux,需安装sysstat)
  4. mpstat -P ALL 1

稳定性测试连续运行2小时,每10分钟记录一次吞吐。故障注入包括极端输入尺寸、含NaN的输入,以及与依赖服务的断连。记录每种情况下的错误类型、恢复时间和后续吞吐。

六、指标口径

指标 定义 计算方式
吞吐 每秒处理的样本数 批量 × 1000 ÷ 平均单次耗时(毫秒)
P50、P95延迟 单次请求耗时的分位数 排序后取对应位置的值
设备利用率 计算单元忙碌比例 nvidia-smi采样平均值;CPU取用户态加内核态时间
显存峰值 运行期最大显存占用 torch.cuda.max_memory_allocated()
每千样本能耗 单位样本消耗的电能 功耗采样积分 ÷ 样本数
错误率 失败请求占总请求的比例 日志统计

延迟必须计入主机与设备之间的数据拷贝时间,因为线上服务的请求确实包含这部分开销。两端使用同一口径,结果才有可比性。

七、结果记录模板

每组实验至少重复3次,取中位数并记录标准差。同一组内的波动超过10%时,先排查温度降频和后台进程,再采用结果。

硬件 负载 批量 并发 吞吐(样本/秒) P95延迟(毫秒) 利用率(%) 显存峰值(GB) 错误率(%)
CPU ResNet-50 1 1 待填 待填 待填 待填 待填
GPU ResNet-50 1 1 待填 待填 待填 待填 待填

八、判定规则

以下阈值是起始值,应结合业务的服务等级目标(SLA)校准后再使用。

  1. 批量从1增至128时,若GPU吞吐增幅明显高于CPU,且GPU利用率持续高于60%,说明并行单元得到有效利用,GPU更适合该负载。
  2. 对于延迟敏感的服务,若批量为1时CPU的P95延迟(含数据拷贝)低于GPU,优先考虑CPU部署。
  3. 连续运行2小时后,若GPU吞吐下降超过10%,先检查温度与功耗是否触发降频,再判断是否为硬件问题。
  4. 迁移改造的人天投入超过预算的30%,应把易用性和兼容性的权重提高,并重新评估方案。

九、场景选型清单

  • 模型训练:以吞吐和显存容量为主要指标。多卡场景需计算扩展效率,即多卡吞吐除以单卡吞吐再除以卡数。效率明显下降时,应检查卡间互联带宽。
  • 离线批量推理:以吞吐和每千样本成本为主,批量通常取较大值。
  • 在线低延迟推理:以P95和P99延迟为主。先测小批量,若CPU能满足SLA,优先保留CPU路径。
  • 分支密集的通用业务:以单次响应时间和稳定性为主。这类负载在GPU上往往难以发挥并行优势。
  • 图形渲染与像素处理:GPU结构适配良好,但需要验证具体图形接口和驱动的支持程度。
  • 专用ASIC:先核对算子覆盖率。不支持的算子会回退到CPU执行,产生额外的数据搬运和延迟。

十、成本与风险

总成本建议按以下项目测算:

  • 硬件采购或租赁费用,按使用年限折旧;
  • 能耗,即功率乘以运行小时数再乘以电价;
  • 迁移人力,按改造人天计算;
  • 运维与监控成本,包括驱动升级和故障处理;
  • 故障损失,包括服务中断和重试产生的费用。

主要风险包括:短时压测无法代表长期稳定性;小数据集不能代表生产规模;驱动或框架升级可能改变性能;云实例的资源共享会造成波动,应在不同时段多次测试。

回退方案建议保留CPU路径,通过流量比例灰度切换。当GPU请求的排队等待时间超过SLA的80%时,自动把部分流量切回CPU,并记录切换次数,作为后续容量规划的依据。

十一、总结

硬件选择应从负载特征出发。矩阵运算密集的训练和批量推理,通常更适合GPU。小批量、分支多、低延迟的服务,CPU往往更合适。这些结论只有在环境固定、指标口径统一、并用自有数据验证之后才成立。团队可以按本文的环境清单、测量