批处理基础概念:从定义到吞吐量优化

各位同学,今天我们来聊聊批处理。这个词你肯定听过,但真正理解它的人不多。

我刚开始做端侧推理时,也踩过不少坑。有一次,我为了追求低延迟,把Batch Size设成了1。结果呢?芯片利用率不到20%,功耗倒是没少。后来我才明白——批处理不是简单的「多塞几个数据」,而是一门平衡的艺术。

批处理的定义:到底什么是批处理?

说白了,批处理就是把多个输入样本打包,一次性交给模型处理。你想想看,如果每次只处理一个样本,模型就得反复加载权重、初始化计算单元。这就像你每次只搬一块砖,来回跑路的时间比搬砖本身还长。

批处理的核心思想是:用空间换时间。把多个样本堆在一起,让计算单元一次性吃饱。

批处理(Batching):将 N 个独立的输入样本组合成一个张量,在模型推理时一次性前向传播,得到 N 个输出结果。

举个例子。假设你有一个卷积层,输入是 3x224x224 的图片。单张处理时,计算单元只用到了一部分。但如果你把 8 张图片拼成 8x3x224x224,计算单元就能满负荷运转。嗯,这就是批处理的本质。

Batch Size 的影响:大还是小?

Batch Size 的选择,直接影响三个关键指标:延迟、吞吐量、显存占用。

我个人习惯把 Batch Size 的影响总结成一张表:

Batch Size 延迟(单样本) 吞吐量 显存占用 适用场景
1 实时交互、语音唤醒
4~8 视频分析、图像分类
16~32 离线批量处理、数据标注
64+ 极高 饱和 极高 服务器端推理(端侧慎用)

注意看,延迟和吞吐量不是线性关系。Batch Size 从 1 增加到 8,吞吐量可能提升 5 倍,但延迟只增加了 2 倍。为什么会这样?因为计算单元被更充分地利用了。

我曾经在手机上跑 MobileNetV3,Batch Size 从 1 调到 4,吞吐量从 30 FPS 飙到 110 FPS。但调到 8 时,显存爆了。嗯,这就是端侧的残酷现实——资源有限。

注意:端侧设备的显存通常只有 2~8 GB。Batch Size 过大,轻则 OOM(内存溢出),重则系统卡死。我建议从 1 开始,逐步翻倍,直到显存占用接近 80% 为止。

批处理与吞吐量的关系:数学视角

吞吐量(Throughput)的定义很简单:单位时间内处理的样本数。公式是:

Throughput = Batch Size × 每秒处理的批次数

但这里有个陷阱。每秒处理的批次数,受限于模型的计算时间和数据搬运时间。你想想看,如果 Batch Size 翻倍,计算时间可能只增加 50%,但数据搬运时间可能翻倍。这时候,吞吐量反而会下降。

我画个简化的模型:

总时间 = 数据加载时间 + 模型计算时间 + 结果回传时间

吞吐量 = Batch Size / 总时间

在端侧,数据加载时间往往被忽略。但我在项目中遇到过,Batch Size 从 4 调到 8 时,吞吐量反而下降了 15%。排查后发现,是内存带宽成了瓶颈。数据从 DDR 搬运到 NPU 的速度跟不上计算速度。

我的经验:在端侧,Batch Size 的「甜蜜点」通常在 2~8 之间。超过 8 后,收益递减明显。你可以用这个公式估算:

最优 Batch Size ≈ 计算单元数量 × 2

比如你的 NPU 有 4 个核心,那 Batch Size 设为 8 左右比较合理。

实际案例:从 30 FPS 到 120 FPS

我记得有一次优化人脸检测模型。原始代码是逐帧处理,Batch Size = 1,帧率只有 30 FPS。客户要求至少 60 FPS。

我做了三件事:

  1. 合并输入:把连续 4 帧拼成一个 Batch,Batch Size = 4
  2. 异步加载:用双缓冲机制,计算当前 Batch 时,预加载下一个 Batch
  3. 调整内存布局:把 NHWC 格式改成 NCHW,减少内存碎片

结果呢?帧率直接飙到 120 FPS,显存占用只增加了 30%。客户很满意,我也松了口气。

但这里有个前提——你的模型必须支持动态 Batch Size。有些模型在导出时固定了 Batch Size,比如 ONNX 模型如果指定了 batch=1,那就没法改了。所以,设计模型时就要考虑批处理

避坑指南:我曾经踩过的坑

我曾经在某个项目里,把 Batch Size 设得太大,结果模型推理结果全错了。排查了半天,发现是 Batch Normalization 层的问题。BN 层在推理时,如果 Batch Size 太小(比如 1),统计量会不稳定。但 Batch Size 太大(比如 64),又会导致显存溢出。

所以,我的建议是:

  • 如果模型里有 BN 层,Batch Size 不要小于 4
  • 如果模型里有 LayerNorm,Batch Size 可以小一些
  • 如果模型是纯卷积或全连接,Batch Size 可以大一些

另外,别忘了端侧设备的散热限制。Batch Size 越大,功耗越高,发热越严重。我曾经在平板上跑大 Batch,10 分钟后温度飙到 70°C,系统自动降频,吞吐量反而比小 Batch 还低。

总结一下

  • 批处理 = 多个样本打包处理
  • Batch Size 影响延迟、吞吐量、显存
  • 端侧推荐 Batch Size = 2~8
  • 吞吐量不是线性增长,存在甜蜜点
  • 注意 BN 层、内存带宽、散热限制

下一章,我们会深入讨论流水线设计。到时候你会发现,批处理和流水线结合起来,效果更惊人。嗯,今天就到这里,有问题随时问我。