Skip to main content

单节点调度系统

输入数据经由默认的单节点调度系统BaselineSchedule分发给计算后端执行。在此过程中主要经历了凑batch和多实例的调度。

凑batch/多实例

对于TensorrtTensor等模型推理引擎,输入范围一般是[1, max_batch_size], 此时调度系统可将输入数据打包送入。BaselineSchedule单节点调度后端实现了如下的调度功能:

  • 根据instance_num参数启动多个计算后端实例
  • 从计算后端读取max_batch_size=max(), 如果大于1,启动凑batch功能
  • 输入队列获取数据,在batching_timeout的时间内,如果获得了max_batch_size个数据,那么将其送往Batch队列, 如果时间到了仍然没有获得足够数据,那么将已有数据送入Batch队列
  • 将任务从Batch队列中分发到空闲的计算实例中。

以上是主干的大致流程,细节部分会有差别,如BaselineSchedule也实现了基础的自适应流量功能,根据多实例计算引擎的状态决定batch状态的功能,以及组合调度的功能。

单节点组合调度

有些计算后端的输入范围最小值大于1, 导致无法作为正常的后端进行调度(可能导致有些数据永远没有办法进行处理)。BaselineSchedule通过&符号提供了组合的能力。

举例来讲,对于TensorrtTensor后端,一些模型不方便转为动态模型, 此时可以用一个 batchsize=1 的模型和几个 batchsize=N 的模拟动态batch.

[model]
model="batch1.onnx&batch4.onnx&batch8.onnx"
backend="SyncTensor[TensorrtTensor]" # or 'SyncTensor[TensorrtTensor]&SyncTensor[TensorrtTensor]'
instance_num = 2 # auto extend to '2&2&2'
min="1&4&8"
max="1&4&8"

此时,将共有6个实例,前两个实例输入范围均是[1, 1],中间两个均是[4, 4],最后两个均是[8, 8]。 对BaselineSchedule来说,这六个实例组成了两个虚拟实例,每个虚拟实例占用了三个实例,虚拟实例的输入范围是[1, 8].

BaselineSchedule

初始化

功能备注
batching_timeout凑batch超时时间(毫秒)不接受&语法; 不需要凑batch时不生效
instance_num实例数目instance_num与后端的max()的乘积一般设置为略小于需要的最大同时处理的数据量
backend真正的运算后端通过min()/max()函数提供数据输入范围

在对backend实例初始化时,

bool init(const std::unordered_map<std::string, std::string>& config, dict dict_config);

BaselineSchedule会生成初始化参数dict_config, 供它管理的后端实例共享数据;同时在config参数中额外写入_independent_thread_index, 取值范围为 [0, instance_num - 1].

前向计算

备注

调度后端被实现为线程安全的。

min()/max()

取值范围是[1, UINT32_MAX]

单节点调度系统的扩展

由于调度系统BaselineSchedule本身也是一个后端,用户可以实现不同的后端去替代他。

备注

BaselineSchedule实际是以下后端的复合:
BaselineSchedule[Fusion[ContrastInstances[InstanceThread]]]

可参考BaselineSchedule的实现重新实现其细节。对于单节点系统,默认调用后端链为

在全局配置设置新的 Interpreter::backend 参数即可改变调度系统。

对于多节点系统,默认调用后端链为

在全局或者某节点下设置新的 PipelineV3::backend 参数即可全局或者局部地改变调度系统。