服务端推理服务GPU利用率优化通用思路

114 阅读4分钟

GPU特点

www.cs.utexas.edu/~pingali/CS…

服务特点

计算过程涉及cpu、内存、gpu、显存多个硬件之间的配合

  • CPU:擅长流程控制和逻辑处理,不规则数据结构,不可预测存储结构,单线程程序,分支密集型算法。

  • GPU:擅长数据并行计算,规则数据结构,可预测存储模式。

  • 内存:给CPU提供计算过程中的存储能力

  • 显存:给GPU提供计算过程中的存储能力

要想充分利用GPU,本质上就是需要协调这些硬件之间的计算关系。

最理想的配合方式就是CPU只做控制(分支密集型),GPU只做计算(数据密集型),且内存/显存的带宽不存在瓶颈。因为GPU计算速度非常高,在CPU资源有限的情况下,CPU只做控制才可以尽可能地匹配GPU的速率。

服务处理流程

流程图.jpg

上图是服务端推理服务的整体链路,分析性能瓶颈时应该从整体出发。

以下可能造成GPU利用率瓶颈的一些情况:

软件层次

  • RPC/HTTP框架Workers线程配置过少,无法接受足够的请求。CPU和GPU没有足够的任务,处于饥饿状态。 表现是CPU和GPU利用率都不高,但是QPS已达到瓶颈。
  • CPU的处理流程中进行了同步IO的一些操作(比如从磁盘或网络读取图片等)。这里由于CPU在等待IO操作就绪而成为瓶颈,而GPU等待CPU控制逻辑从而利用率低。表现是CPU和GPU利用率都不高,但是QPS已达到瓶颈。
  • CPU利用率高,但真正处理有效计算的时长占比不高(比如自旋锁、线程数过多造成的上下文切换频繁等)。这里CPU由于无效计算成为瓶颈,GPU等待CPU控制逻辑而利用率低。表现是CPU利用率高而GPU利用率低。
  • CPU利用率高,真正处理有效计算的时长占比也高,这里CPU由于性能限制成为瓶颈,GPU等待CPU而利用率低。表现是CPU利用率高而GPU利用率低。
  • GPU利用具有明显的时间相关性,某些时间片GPU处于闲置状态。
  • 数据传输存在瓶颈,数据传输与计算过程是串行的,GPU有部分时间是在等待数据传输;
  • CUDA层面多个kernel函数并行度不高,没有重叠数据传输、CPU和GPU异构设备的计算(cuda multi-stream) 。

硬件层次

  • GPU上第一次执行的计算会比较慢(需要预热)。

  • 一批任务同时送到GPU计算,会涉及较少的CPU-GPU同步操作、GPU内部也对这种批处理有所优化。

  • 一定程度上,提升GPU的吞吐量而非QPS有利于提高GPU利用率。

  • CPU到GPU之间的通信可能成为瓶颈,要尽量减少通信次数和同步操作,尽量使用异步方式。

优化思路/手段

优化的基本思路是将这些异构硬件作为一个系统看待,并且从一个请求的整体链路来分析可能存在的瓶颈(木桶效应),然后有针对性的去优化,以下是一些常见的手段。

  • 根据实际情况对Workers线程数进行调优。
  • CPU编程中尽量使用异步方式处理IO逻辑或非计算密集型逻辑。
  • 对CPU线程数、加锁等逻辑进行调优,使CPU做有效的工作。
  • 如果CPU计算是瓶颈,可以尝试将一些计算迁移到GPU上,尽量使用GPU做计算,CPU只用来做控制。
  • 对GPU进行warm up。
  • 批处理。
  • 编码时有并行计算的编程思想。
  • 对于具有时间相关性的GPU服务进行混合部署。
  • GPU全链路+显存规划+CUDA multi-stream
  • 多个推理进程+MPS / 多个推理线程(针对SM利用率低+SM空间利用率低的情况)
  • 对复杂流程的服务进行拆分,让GPU的处理更加纯粹