Skip to main content

tritonserver

Triton Inference Server 的批处理槽(Batch Slot)机制,可以理解为是为有状态模型(Stateful Model)设计的一种“专属座位”或“状态容器”。

它的核心目的是:为每一个独立的序列(Sequence)在模型实例中分配一个固定的、专用的位置,确保该序列的所有推理请求都能被路由到同一个位置,从而正确地维护和更新模型内部的序列状态

为了更好地理解,可以把一个模型实例想象成一个多座的办公室,而每个“批处理槽”就是其中一个固定的工位。

🗺️ 批处理槽的核心概念与工作原理

下面通过一个具体的例子来说明它是如何运作的。

假设你在 config.pbtxt 中做了如下配置:

  • max_batch_size: 2:这意味着每个模型实例有 2个批处理槽(槽0和槽1)。
  • instance_group { count: 2 }:这意味着模型会启动 2个实例(实例0和实例1)。

那么,Triton 就可以同时处理 2个实例 × 2个槽 = 最多4个并发序列

一个批处理槽的完整生命周期如下:

  1. 分配:当一个新序列的第一个请求(sequence_start=True)到达时,序列调度器会寻找一个空闲的批处理槽。如果找到,就将这个序列与该槽位“绑定”。
  2. 占用:在该序列的整个生命周期内,这个槽位就像它的“私人包厢”。无论后续有多少个请求,都会被精准地导向同一个模型实例的同一个槽位。模型在处理时,可以根据槽位索引来维护独立的状态(例如,为槽0维护一套隐藏状态,为槽1维护另一套)。
  3. 释放:当序列的最后一个请求完成(sequence_end=True)后,该序列结束。这个批处理槽被释放,变为空闲状态,等待分配给下一个新到来的序列。
  4. 超时与强制释放:如果一个序列在配置的 max_sequence_idle_microseconds 时间内没有新的请求到达(即“发呆”超时),Triton 会强制终止该序列并释放其占用的槽位,以防止资源被死锁的客户端长期占用。

📊 批处理槽策略:Direct vs. Oldest

序列批处理器主要通过两种策略来管理这些槽位,理解它们能帮你更准确地配置模型。

策略核心机制槽位关系适用场景关键特点
Direct (直接策略)为每个序列分配一个专用的、固定的批处理槽一对一绑定。一个槽在整个序列生命周期内只服务一个序列。模型必须为每个槽位独立维护内部状态(如Transformer/RNN的KV Cache、累加器等)。这是最常用的有状态模型策略。这是默认策略。模型可以通过CONTROL_SEQUENCE_STARTCONTROL_SEQUENCE_READY等控制输入,精确知道每个槽位的状态。
Oldest (最旧策略)不固定分配槽位,而是从候选序列池中,按请求到达的先后顺序(最旧的优先)挑选,动态组成一个批次进行推理。动态复用。一个序列的不同请求可能会由不同的槽位处理。模型不依赖固定槽位来维护状态,而是通过CONTROL_SEQUENCE_CORRID(关联ID)来识别请求属于哪个序列。或者状态由Triton的隐式状态管理来处理。可以支持候选序列数(max_candidate_sequences)大于实际批处理大小(max_batch_size 的情况。

总的来说,Direct策略通过固定的“批处理槽”,为有状态模型提供了最简单、最可靠的序列状态管理方式。这就像给每个对话任务安排一个专属的接待员,他能记住之前所有的对话内容,保证服务的连贯性。而Oldest策略则更像一个高效的呼叫中心,不设固定接待员,但通过来电显示(关联ID)来识别客户,同样能保证服务质量。