Skip to content
/

Clipper: A Low-Latency Online Prediction Serving System

📅 2026-02-13  ·  🏷️ 推理引擎  ·  📖 论文精读

论文信息

  • 作者: Daniel Crankshaw, Xin Wang, Guilio Zhou, Michael J. Franklin, Joseph E. Gonzalez, Ion Stoica
  • 机构: UC Berkeley
  • 发表: NSDI 2017
  • 链接: USENIX NSDI'17

一句话总结

Clipper 是最早系统性地将机器学习模型从"离线训练产物"推向"在线推理服务"的通用 Serving 系统之一,通过 模型抽象层模型选择层 两大核心设计,解决了框架碎片化、延迟-吞吐平衡、以及模型在线选优三大痛点。


背景与动机

1. 框架碎片化:部署太乱

机器学习框架(TensorFlow, PyTorch, Scikit-Learn, SparkML 等)层出不穷,各有所长。开发者往往需要在同一个应用里使用多种框架训练出的模型,兼容性极差,维护成本极高。

Clipper 的方案:搞了一个 "万能插座"(模型抽象层)。不管你用什么框架写的模型,统一封装为标准接口,应用层只需要对接这个接口,彻底解耦。

2. 延迟 vs 吞吐:又要快、又要多

在线业务要求 低延迟(不能让用户等),但为了硬件效率(GPU/SIMD 加速)又需要 高吞吐/批处理。而且复杂模型计算慢,偶尔还会出现由于个别请求变慢导致的 "长尾延迟"

Clipper 的方案

  • 自适应批处理:在不超时的情况下,尽可能多地攒一波请求一起发给模型
  • 掉队者缓解:防止个别慢模型拖累整个系统的响应速度

3. 模型选优:哪个模型更好用?

模型上线后表现会变,传统的 A/B Test 效率太低,离线测试数据又容易过期,很难实时选出当前最准的模型。

Clipper 的方案在线动态优选。根据用户的实时反馈(如点击率)自动调整不同模型的权重,甚至把多个模型的结果"取长补短"拼在一起(集成学习),实现自动化的模型选优。


系统架构总览

Clipper 的整体架构分为两层,上层面向应用、下层面向模型:

┌──────────────────────────────────────────────────────┐
│                    应用层 (Application)                │
│              predict(uid, x) → y                     │
│              feedback(uid, x, y, reward)             │
└──────────────┬────────────────────┬──────────────────┘
               │                    │
┌──────────────▼────────────────────▼──────────────────┐
│              模型选择层 (Model Selection Layer)         │
│   ┌──────────┐  ┌──────────┐  ┌───────────────────┐  │
│   │  Exp3    │  │  Exp4    │  │ 掉队者缓解 / 置信度 │  │
│   │ (单选)   │  │ (集成)   │  │                   │  │
│   └──────────┘  └──────────┘  └───────────────────┘  │
└──────────────┬────────────────────┬──────────────────┘
               │                    │
┌──────────────▼────────────────────▼──────────────────┐
│              模型抽象层 (Model Abstraction Layer)       │
│   ┌──────────┐  ┌──────────────┐  ┌───────────────┐  │
│   │ 预测缓存  │  │ 自适应批处理  │  │  模型容器     │  │
│   │  (Cache) │  │   (AIMD)    │  │  (Docker)     │  │
│   └──────────┘  └──────────────┘  └───────────────┘  │
└──────────────────────────────────────────────────────┘
               │            │            │
        ┌──────▼──┐  ┌──────▼──┐  ┌──────▼──┐
        │ TF 容器  │  │ PyTorch │  │ SparkML │
        │         │  │  容器    │  │  容器    │
        └─────────┘  └─────────┘  └─────────┘

模型抽象层:推理系统的工程基石

Clipper 的模型抽象层位于系统下半部,负责屏蔽框架差异、管理推理性能。该层主要由三大核心组件构成:预测缓存自适应批处理组件模型容器

1. 统一接口与模型容器化

Clipper 提出了一种 "窄腰(Narrow Waist)" 架构设计。所有的机器学习框架都被封装在独立的 Docker 容器内。

  • 隔离性:通过容器化,确保了不同模型环境之间的物理隔离。即使某个模型框架因为内存泄漏或崩溃而失效,也不会影响系统整体的可用性
  • 无状态设计:模型容器在初始化后保持无状态,这使得系统可以根据实时流量需求,轻松地在本地或跨集群扩展模型副本

2. 预测缓存:超越单纯的加速

Clipper 的缓存机制不仅仅是为了降低高频请求的延迟,它在模型在线演进中扮演着关键角色。

  • 函数式抽象:Clipper 将预测逻辑抽象为 (Predict(m, x) \rightarrow y) 的纯函数过程
  • 反馈关联(Join):为了实现智能的模型选择,系统需要将收到的用户反馈(如点击率)与原始预测结果进行匹配。缓存机制极大地加速了这种匹配过程,使得系统能实时评估模型表现,而无需重新计算模型推理
  • CLOCK 算法:在实现上,Clipper 采用了 CLOCK 逐出算法(LRU 的一种高效变体),在保持高并发性能的同时,确保了热点数据的留存

3. 自适应批处理:性能优化的核心

这是 Clipper 贡献最大的部分。批处理能利用 GPU 的并行计算能力,但会引入额外的延迟。Clipper 的解决方案是:以延迟目标(SLO)为约束,动态寻找最优批次大小

AIMD 动态调优算法

Clipper 借用了网络协议中经典的 "加性增、乘性减(AIMD)" 思想来自动调整每个模型副本的批次大小:

             batch_size

                 │        ╱╲          ╱╲
                 │       ╱  ╲        ╱  ╲        ╱
                 │      ╱    ╲      ╱    ╲      ╱
                 │     ╱      ╲    ╱      ╲    ╱
                 │    ╱        ╲  ╱        ╲  ╱
                 │   ╱          ╲╱          ╲╱
                 │  ╱
                 │ ╱
                 └──────────────────────────────► time
                    ↑ 加性增    ↑ 乘性减
                  (latency < SLO)  (latency > SLO)
  • 加性增(Additive Increase):如果当前延迟低于 SLO 目标,则逐步增加批次大小(+1),试图压榨硬件性能
  • 乘性减(Multiplicative Decrease):一旦检测到延迟超标,立即按比例(如缩减 10%)削减批次大小。这种"快降慢升"的策略能有效应对系统抖动(如 Java 的垃圾回收停顿),确保服务不会雪崩

为什么用 AIMD 而不是简单的固定批次?

固定批次无法适应动态变化的模型负载和硬件状态。GPU 的实际推理延迟受温度、并发任务、显存压力等多重因素影响,只有动态调整才能在 SLO 约束下持续逼近最优吞吐。AIMD 的"锯齿形"收敛模式在 TCP 拥塞控制中已经被证明是稳定且高效的。

延迟批处理(Delayed Batching)

针对低频或爆发性流量,Clipper 引入了类似 Nagle 算法 的机制。对于某些固定开销较高的模型(如 Scikit-Learn),系统会故意等待极短的时间(如 2ms)以聚合更多请求。实验证明,这种"以微小延迟换取大额吞吐"的策略,能将特定模型的吞吐量提升数倍。

传统方式 (逐条处理):
  req1 ──► [model] ──► resp1
  req2 ──► [model] ──► resp2
  req3 ──► [model] ──► resp3
  总耗时 ≈ 3 × T_single

延迟批处理:
  req1 ─┐
  req2 ─┤ 等待 Δt ──► [model(batch=3)] ──► resp1, resp2, resp3
  req3 ─┘
  总耗时 ≈ Δt + T_batch  (T_batch ≪ 3 × T_single)

4. 分布式扩展与瓶颈预判

Clipper 实现了接近 线性的水平扩展 能力。在 10Gbps 网络环境下,四个 GPU 节点的吞吐量几乎是单节点的四倍。

然而,研究者也敏锐地指出:随着输入数据从简单的文本特征转向高清图像和视频,网络带宽将逐渐取代计算力成为新的系统瓶颈。这一预判在如今的大模型时代已成为业界必须面对的现实,也直接推动了 RDMA 等高性能网络技术在 AI 集群中的普及。


模型选择层:推理服务的动态演进

在传统部署中,模型一旦发布,其逻辑往往是静态的。然而面对数据漂移、模型性能衰减或不同用户的个性化需求,静态部署难以提供持续的最优服务。Clipper 的模型选择层位于模型抽象层之上,通过在线反馈机制实现推理服务的动态演进。

1. 核心哲学:API 化与反馈闭环

模型选择层的核心任务是:根据历史表现和实时反馈,决定将请求分发给哪些模型,并如何整合结果。

为了兼容各种算法,Clipper 定义了一套极其精简的接口,任何模型选择策略只需实现以下四个函数:

函数作用
Init初始化选择策略的状态
Select决定当前的查询应该发送给哪些模型
Combine将多个模型的原始输出融合成最终预测,并计算置信度
Observe接收应用端的真实反馈(如用户是否点击),并更新模型权重

这种设计将 "如何选模型""如何跑模型" 解耦,允许开发者在不改变底层基础设施的情况下,像更换插件一样切换选择策略。

                    ┌─── Model A (TF)

 Request ──► Select ┼─── Model B (PyTorch)  ──► Combine ──► Response

                    └─── Model C (SparkML)


              Observe ◄── Feedback (click/no-click)

2. 单模型选择:Exp3 多臂老虎机算法

在许多场景下,我们只需要从多个候选模型中选出表现最好的那一个。Clipper 将此过程建模为 "多臂老虎机(Multi-Armed Bandit)" 问题,采用 Exp3 算法(Exponential weights for Exploration and Exploitation)。

其工作机制如下:

  • 概率分发:为每个模型维护一个权重,根据权重比例随机选择模型
  • 探索与利用:系统大部分时间选择权重最高的"优等生"(利用),但仍保留一小部分概率去尝试其他模型(探索),以防环境发生变化
  • 指数更新:当收到反馈时,根据损失值(Loss)以指数级速度调整模型权重。如果一个模型开始频繁报错,它的被选概率会迅速萎缩,从而实现自动的故障隔离
模型选择权重演化示例:

 权重
  1.0 ┤ A ████████████████████████████████████████
      │ B ██████████████████████████░░░░░░░░░░░░░░
      │ C ██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  0.0 ┤─────────────────────────────────────────────► 查询次数
                    ↑ 模型 C 准确率下降
                      → 权重迅速衰减

3. 集成模型策略:Exp4 与群体智慧

相较于"选出最好的一个",集成学习(Ensemble Learning)往往能提供更高的准确率。Clipper 引入了 Exp4 算法 来实现动态集成。

  • 加权平均:Exp4 会调用所有可用的基础模型,并根据它们的历史准确率进行加权求和,生成最终结果
  • 性能天花板:Exp3 的表现上限是单个最强模型,而 Exp4 能够通过不同模型间的独立性和互补性,实现超越任何单一模型的准确率
  • 动态容错:当某个核心模型突然因为服务器过热或数据异常导致准确率骤降时,Exp4 能在数千次查询内迅速感知并调低其权重,确保整体错误率保持平稳
策略表现上限响应方式适用场景
Exp3(单选)单个最强模型选一个跑资源有限、追求低延迟
Exp4(集成)超越任何单模型全部跑 + 加权融合追求最高准确率

4. 稳健预测与掉队者缓解

在分布式系统中,追求"绝对准确"往往会带来延迟灾难。Clipper 提出了两项关键技术来增强系统的稳健性:

置信度评分(Robust Predictions)

系统通过计算多个模型之间的 一致性(Consensus) 来输出置信度。如果模型间分歧过大,应用端可以拒绝该预测,转而执行预设的"保底"默认逻辑,避免高昂的决策错误。

掉队者缓解(Straggler Mitigation)

在集成推理中,整体速度取决于最慢的那个模型容器。Clipper 设定了严格的 延迟截止时间(Deadline),一旦超时,系统会立即放弃等待那些还没返回结果的模型,仅用已就绪的模型子集计算结果,确保了服务的尾部延迟(P99)符合 SLO 要求。

集成推理的掉队者缓解示例:

  Model A ──────────► 结果 A (50ms)   ✓ 采纳
  Model B ────────────────► 结果 B (80ms)   ✓ 采纳
  Model C ──────────────────────────────► (200ms, 超时!)  ✗ 丢弃

                     Deadline = 100ms


              Combine(A, B) → 最终结果
              (降级为 2/3 模型集成,但保证了延迟 SLO)

5. 上下文相关化:实现千人千面

模型表现往往具有场景相关性。Clipper 展示了其"上下文相关化"的能力:

  • 状态隔离:Clipper 可以为不同的用户或设备在 Redis 中独立维护一套选择策略状态
  • 在线个性化:实验证明,即便用户没有自报方言背景,Clipper 也能通过实时反馈,迅速为该用户组合出最适合其发音特征的模型权重。这种基于行为的自适应能力,通常比静态的用户标签更精准

实验亮点

自适应批处理效果

模型框架不做批处理Clipper 自适应批处理吞吐提升
Scikit-Learn (Logistic Regression)基准延迟批处理 + AIMD26x
TensorFlow (CNN)基准GPU 批推理 + AIMD显著
Spark MLlib基准批量 RPC显著

分布式扩展

  • 在 10Gbps 网络下,4 GPU 节点吞吐量 ≈ 4× 单节点(接近线性扩展)
  • 主要瓶颈为网络序列化开销,而非计算力

模型选择效果

  • Exp4 集成策略在 CIFAR-10 任务上,准确率超越任何单个模型
  • 当某模型突然退化时,Exp4 在数千次查询内自动调低权重
  • 上下文相关化在语音识别任务中显著提升了个体用户的识别准确率

与现代推理系统的传承关系

Clipper 作为 2017 年的工作,许多设计理念已经成为现代推理系统的"标配"。下面梳理其核心思想的演化脉络:

Clipper 创新现代继承者演进方向
模型容器化 (Docker)Triton Inference Server, KServe从 Docker 到 GPU 原生容器、Kubernetes Operator
自适应批处理 (AIMD)vLLM (Continuous Batching), Orca从 AIMD 到迭代级调度 (Iteration-level Scheduling)
预测缓存SGLang (RadixAttention)从输入级缓存到 KV Cache 前缀级复用
掉队者缓解投机解码 (Speculative Decoding)从丢弃慢模型到用小模型"猜测"大模型
模型选择 (Bandit)LLM Router, Model Gateway从准确率优化到成本-质量联合优化

个人思考

  1. 系统设计的前瞻性:Clipper 在 2017 年提出的许多设计——容器化部署、自适应批处理、在线模型选择——在今天的 LLM 时代依然是核心主题。尤其是它对网络带宽瓶颈的预判,已在大模型分布式推理中完全应验

  2. "窄腰"架构的持久生命力:IP 协议是互联网的"窄腰",Clipper 的预测接口是 ML Serving 的"窄腰"。这种通过统一抽象层解耦上下游的设计模式,在 Triton、KServe、BentoML 等现代框架中随处可见

  3. 从 Clipper 到 vLLM 的演进:Clipper 的自适应批处理是"请求级"的(攒一波请求再一起推理),而 vLLM 的 Continuous Batching 是"迭代级"的(每个 Token 生成步都可以插入/移出请求)。这是从通用 ML 推理到 LLM 专用推理的关键跃迁

  4. Bandit 算法的优雅:Clipper 用 Exp3/Exp4 实现模型选优,本质上是把"选模型"转化为一个在线学习问题。在今天的 LLM Router(如 Martian、Unify)中,同样的思想被用于在 GPT-4、Claude、Llama 等模型之间做成本-质量的动态均衡

推荐阅读

Released under the MIT License.