triton inference server翻译之Models And Schedulers

link

通过整合多个框架和自定义后端,Triton Inference Server支持多种模型。 同时,推理服务器还支持多种调度和批处理配置,从而进一步扩展了推理服务器可以处理的模型类别。

本节描述模型的无状态,有状态和组合模式,以及推理服务器如何提供调度程序以支持那些模型类型。

Stateless Models

对于推理服务器的调度程序,无状态模型(或无状态自定义后端)不会维持推理请求之间的状态。 在无状态模型上执行的每个推断都独立于使用该模型的所有其他推理。无状态模型的示例是CNN,例如图像分类和对象检测。 缺省调度程序或动态批处理程序可用于这些无状态模型。

具有内部存储器的RNN和类似模型可以是无状态的,只要它们所维护的状态不跨越推理请求即可。 例如,如果推理请求之间未携带内部状态,则推理服务器将迭代批次中所有元素的RNN视为无状态。 缺省调度程序可用于这些无状态模型。 无法使用动态批处理程序,因为模型通常不希望批处理代表多个推理请求。

Stateful Models

对于推理服务器的调度程序,有状态模型(或有状态自定义后端)会在推理请求之间保持状态。 该模型期望多个推理请求一起形成推理序列,这些推理序列必须路由到同一模型实例,以便正确更新模型所维护的状态。 此外,该模型可能要求推理服务器提供指示例如序列开始的控制信号。

序列批处理程序必须用于这些有状态模型。 因为,序列批处理程序确保将序列中的所有推理请求都路由到同一模型实例,以便模型可以正确维护状态。 序列批处理程序还与模型通信,以指示序列何时开始,何时结束,是否已经准备好需要执行的推理请求以及序列的相关性ID。

As explained in Client API for Stateful Models, when making inference requests for a stateful model, the client application must provide the same correlation ID to all requests in a sequence, and must also mark the start and end of the sequence. The correlation ID allows the inference server to identify that the requests belong to the same sequence.

如客户端中对有状态模型的解释,当对有状态模型进行推理请求时,客户端必须为序列中的所有请求提供相同的相关ID,并且标记序列的开始和结束。 其中,相关性ID允许推理服务器识别请求属于同一序列。

Control Inputs

为了使状态模型能够与序列批处理程序一起正确运行,模型通常必须接受一个或多个控制输入张量,这些张量是推理服务器用来与模型进行通信的,用nvidia::inferenceserver::ModelSequenceBatching::Control部分可查看。 所有控件都是可选的,以下是模型配置的一部分,显示了所有可用控制信号的示例配置:

sequence_batching {
  control_input [
    {
      name: "START"
      control [
        {
          kind: CONTROL_SEQUENCE_START
          fp32_false_true: [ 0, 1 ]
        }
      ]
    },
    {
      name: "END"
      control [
        {
          kind: CONTROL_SEQUENCE_END
          fp32_false_true: [ 0, 1 ]
        }
      ]
    },
    {
      name: "READY"
      control [
        {
          kind: CONTROL_SEQUENCE_READY
          fp32_false_true: [ 0, 1 ]
        }
      ]
    },
    {
      name: "CORRID"
      control [
        {
          kind: CONTROL_SEQUENCE_CORRID
          data_type: TYPE_UINT64
        }
      ]
    }
  ]
}
  • Start
    CONTROL_SEQUENCE_START标示起始输入张量,表明该模型具有一个名为START的输入张量,具有32位浮点数类型。序列批处理程序将在对模型执行推断时定义此张量。 START张量必须为一维且大小等于batch-size。 张量中的每个元素标示批处理批次相应位置的序列是否已经开始处理。 示例中,fp32_false_true等于1代表开始处理,否则并未开始。
  • End
    同理
  • Ready
    同理
  • Correlation ID
    同理

Scheduling Strategies

两个调度策略

  • Direct
    使用直接调度策略,序列批处理程序不仅可以确保将序列中的所有推理请求都路由到同一模型实例,而且还可以确保将每个序列都路由到模型实例内的专用批处理插槽。 当模型需要维护每个批处理插槽的状态,并且期望将给定序列的所有推理请求路由到同一插槽,以便正确更新状态时,就需要此策略。

模型配置文件:

name: "direct_stateful_model"
platform: "tensorrt_plan"
max_batch_size: 2
sequence_batching {
  max_sequence_idle_microseconds: 5000000
  direct { }
  control_input [
    {
      name: "START"
      control [
        {
          kind: CONTROL_SEQUENCE_START
          fp32_false_true: [ 0, 1 ]
        }
      ]
    },
    {
      name: "READY"
      control [
        {
          kind: CONTROL_SEQUENCE_READY
          fp32_false_true: [ 0, 1 ]
        }
      ]
    }
  ]
}
input [
  {
    name: "INPUT"
    data_type: TYPE_FP32
    dims: [ 100, 100 ]
  }
]
output [
  {
    name: "OUTPUT"
    data_type: TYPE_FP32
    dims: [ 10 ]
  }
]
instance_group [
  {
    count: 2
  }
]

关键字mermaid sequenceDiagram_batching标示模型应使用序列批处理程序和直接调度策略。在此示例中,模型仅需要来自序列批处理程序的start和ready控制张量, instance_group标示模型的两个实例,max_batch_size指示每个实例应执行batch-size为2的推理。 下图显示了此配置指定的序列批处理程序和推理资源。

在这里插入图片描述
每个模型实例都在维护每个批处理插槽的状态,并期望将给定序列的所有推理请求路由到同一插槽,以便正确更新状态。 对于此示例,这意味着推理服务器可以同时执行多达四个序列的推理。

使用直接调度策略的序列批处理有如下特征:

  • 识别推理请求何时开始新序列并为该序列分配批处理插槽。 如果没有批处理插槽可用于新序列,则服务器会将推理请求置于待办事项列表(积压);
  • 识别何时推理请求是具有分配的批处理插槽的序列的一部分,并将请求路由到该插槽;
  • 识别推理请求何时是待办事项列表中序列的一部分,并将请求放入待办事项列表中;
  • 识别序列中的最后一个推理请求何时完成,该序列占用的批处理插槽将立即重新分配到积压中的序列,如果没有积压,则将其释放以供将来的序列使用。

下图显示了如何使用直接调度策略将多个序列调度到模型实例上。 左图显示了到达推理服务器的几个请求序列。 每个序列可以由任意数量的推理请求组成,并且这些单独的推理请求可以相对于其他序列中的推理请求以任何顺序到达,除了右侧所示的执行顺序,序列0的第一个推理请求比序列1-5中的任何推理请求先到达,序列1的第一个推理请求比序列2-5中的任何推理请求先前到达,以此类推。

图的右侧显示了如何随时间将推理请求序列调度到模型实例上。

在这里插入图片描述

下图显示了序列批处理程序使用控制输入张量与模型进行通信的过程。 每个序列的推理请求都会随时间到达。 START和READY行显示用于模型的每次执行的输入张量值。 随着时间的流逝,会发生以下情况:

  • 第一个请求到达插槽0中的序列。 假设模型实例尚未执行推理,则序列调度程序会立即调度模型实例以执行,因为推理请求可用;
  • 这是序列中的第一个请求,因此START张量中的相应元素设置为1。插槽1中没有可用的请求,因此READY张量仅显示插槽0为就绪;
  • 推断完成后,序列调度程序会发现任何批处理插槽中都没有可用的请求,因此模型实例处于空闲状态;
  • 接下有两个请求几乎同时到达,且状态为可用,调度程序立即调度模型实例以执行batch-size为2的推理,并使用START和READY显示两个插槽都有可用的推理请求,但是只有slot1是新序列的开始;
  • 对于其他推断请求,处理以类似的方式继续;

在这里插入图片描述

  • Oldest
    With the Oldest scheduling strategy the sequence batcher ensures that all inference requests in a sequence are routed to the same model instance and then uses the dynamic batcher to batch together multiple inferences from different sequences into a batch that inferences together. With this strategy the model must typically use the CONTROL_SEQUENCE_CORRID control so that it knows which sequence each inference request in the batch belongs to. The CONTROL_SEQUENCE_READY control is typically not needed because all inferences in the batch will always be ready for inference.

使用最旧的调度策略,序列批处理程序可确保将序列中的所有推理请求都路由到同一模型实例,然后使用动态批处理程序将来自不同序列的多个推理汇总到一起进行推理。 使用这种策略,模型须使用CONTROL_SEQUENCE_CORRID以便它知道批处理中每个推理请求属于哪个序列,而不需要CONTROL_SEQUENCE_READY,因为批处理中的所有推理将始终准备好进行推理。

示例:

name: "oldest_stateful_model"
platform: "custom"
max_batch_size: 2
sequence_batching {
  max_sequence_idle_microseconds: 5000000
  oldest
    {
      max_candidate_sequences: 4
      preferred_batch_size: [ 2 ]
    }
  control_input [
    {
      name: "START"
      control [
        {
          kind: CONTROL_SEQUENCE_START
          fp32_false_true: [ 0, 1 ]
        }
      ]
    },
    {
      name: "END"
      control [
        {
          kind: CONTROL_SEQUENCE_END
          fp32_false_true: [ 0, 1 ]
        }
      ]
    },
    {
      name: "CORRID"
      control [
        {
          kind: CONTROL_SEQUENCE_CORRID
          data_type: TYPE_UINT64
        }
      ]
    }
  ]
}
input [
  {
    name: "INPUT"
    data_type: TYPE_FP32
    dims: [ 100, 100 ]
  }
]
output [
  {
    name: "OUTPUT"
    data_type: TYPE_FP32
    dims: [ 10 ]
  }
]
sequenceDiagram_batching```标示模型使用的是序列批处理和最老调度策略, 该序列批处理程序最多维护4个活跃序列,可动态形成batch-size为2d的批处理批次,且模型需要从开始,结束和相关ID控制张量。 下图显示了此配置指定的序列批处理程序和推理资源。

![dyna_sequence_example0.jpg](https://note.youdao.com/src/WEBRESOURCE88dd810dff1118cc174499216e19d83e)

特征:  
- 识别推理请求何时开始新序列并尝试查找具有候选序列空间的模型实例。如果没有模型实例可容纳新的候选序列,则服务器会将推理请求放置在待办事项中;
- 识别推理请求何时是某个已为候选序列的一部分,并将请求路由到该模型实例;
- 识别推理请求何时是待办事项列表中序列的一部分,并将请求放入待办事项列表中;
- 识别序列中的最后一个请求何时完成,之后,模型实例立即从待办事项列表中删除一个序列,并将其作为自己的候选序列,或者记录该模型实例空闲;

下图显示了如何将多个序列调度到上述示例配置指定的模型实例上。左图显示了到达推理服务器的四个请求序列。每个序列都由多个推理请求组成,如图所示,图的中心显示了如何随时间推移将推理请求序列批处理到模型实例上,假设每个序列的推理请求以相同的速率到达,而序列A恰好在B之前到达,而序列A恰好在C之前到达,等等。最旧的策略根据最旧的请求形成一个动态批处理,但在批处理中从不包含来自给定序列的多个请求(例如,序列D中的最后两个推论不会一起批处理)。

![dyna_sequence_example1.jpg](https://note.youdao.com/src/WEBRESOURCE2714150aa02a48e3ec1994bd5100df00)

## Ensemble Models
集成模型表示由一个或多个模型以及彼此之间的输入,输出张量连接而成的管线。集成模型旨在用于封装多个模型的处理过程,例如“数据预处理->推理->数据后处理”。为此目的使用集成模型可以避免传输中间张量的开销,并最大程度地减少必须发送到推理服务器的请求数。

集成调度程序必须用于集成模型,而与集成中的模型使用的调度程序无关。关于集成调度器,集成模型不是实际模型,还有模型之间的数据流动。调度程序在每个步骤中收集输出张量,根据规范将它们提供为其他步骤的输入张量。尽管如此,从外部视图来看,集成模型仍然被视为单个模型。[example](https://docs.nvidia.com/deeplearning/triton-inference-server/user-guide/docs/client_example.html#section-ensemble-image-classification-example)

请注意,集成模型将继承所涉及模型的特征,因此请求头中的元数据必须符合集成中的模型要求。例如,如果模型之一是有状态模型,那么对集成模型的推理请求应包含上一节中提到的信息,该信息将由调度程序提供给有状态模型。

示例:

name: “ensemble_model”
platform: “ensemble”
max_batch_size: 1
input [
{
name: “IMAGE”
data_type: TYPE_STRING
dims: [ 1 ]
}
]
output [
{
name: “CLASSIFICATION”
data_type: TYPE_FP32
dims: [ 1000 ]
},
{
name: “SEGMENTATION”
data_type: TYPE_FP32
dims: [ 3, 224, 224 ]
}
]
ensemble_scheduling {
step [
{
model_name: “image_preprocess_model”
model_version: -1
input_map {
key: “RAW_IMAGE”
value: “IMAGE”
}
output_map {
key: “PREPROCESSED_OUTPUT”
value: “preprocessed_image”
}
},
{
model_name: “classification_model”
model_version: -1
input_map {
key: “FORMATTED_IMAGE”
value: “preprocessed_image”
}
output_map {
key: “CLASSIFICATION_OUTPUT”
value: “CLASSIFICATION”
}
},
{
model_name: “segmentation_model”
model_version: -1
input_map {
key: “FORMATTED_IMAGE”
value: “preprocessed_image”
}
output_map {
key: “SEGMENTATION_OUTPUT”
value: “SEGMENTATION”
}
}
]
}

关键字```ensemble_scheduling```指出使用的是集成调度器,包含三个模型。step部分的每个元素都指定要使用的模型,以及模型的输入,输出及映射的张量名称。例如,第一个元素指定应使用```image_preprocess_model```的最新版本,其输入```RAW_IMAGE```由```IMAGE```张量提供,其输出```PREPROCESSED_OUTPUT```的内容将映射为```preprocessed_image```张量供以后使用。调度程序识别的张量名称是整体输入,整体输出以及```input_map```和```output_map```中的所有值。

集成模型也启用了动态批处理,因为集成模型只是在组成模型之间路由数据,推理服务器可以将请求带到集成模型中,而无需修改集成的配置。

假设有集成模型,预处理模型,分类模型和细分模型,则客户端应用程序会将它们视为可以独立处理请求的四个不同模型。但是,集成调度器视角下的集成模型是下图所示。

![ensemble_example0.jpg](http://note.youdao.com/yws/res/9846/WEBRESOURCE6857ce80a8adc3950c0c923077014e69)

特征:
- 1,确认请求中的```IMAGE```张量已映射到预处理模型中的输入```RAW_IMAGE```;
- 2,检查集成模型,然后将内部请求发送到预处理模型,因为所需的所有输入张量都已准备就绪;
- 3,识别内部请求的完成,收集输出张量,然后将内容映射到```preprocessed_image```,这是整体中已知的唯一名称;
- 4,将新收集的张量映射到集成模型的输入,在这种情况下,```classification_model```和```segmentation_model```的输入将被映射并标记为就绪;
- 5,检查需要新收集张量的模型,并将内部请求发送到已准备好输入的模型(此时为分类模型和分割模型)。注意,响应将以任意顺序,具体取决于各个模型的负载和计算时间;
- 6,重复步骤3-5,直到不再发送内部请求为止,然后使用张量映射到集合输出名称的方式对推理请求进行响应。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章