×

签到

分享到微信

打开微信,使用扫一扫进入页面后,点击右上角菜单,

点击“发送给朋友”或“分享到朋友圈”完成分享

多batch多线程加速 - 应用示例 jiapeiyuan2021-07-20 12:03:32 回复 查看 经验交流
多batch多线程加速 - 应用示例
分享到:

  1. 背景

    应用经常会遇到这种场景:每次推理送入不确定数量的输入图片。这种做法在gpu上实现很容易而且效果比较好,gpu会根据batch数量自动动态分配计算核心为其计算。但mlu在硬件的架构上和gpu完全不同,因此在mlu上实现这种动态变化的batch场景,需要自己设计调度策略。这里介绍一种多线程调度的策略,充分利用卡上的计算资源,实现不固定batch的并行推理,供参考

  2. 框架

    cs.png

    1. 整体架构采用client/server形式,由client发起请求,server接收请求进行推理,然后将结果返还给client

    2. client、server通过阻塞队列传递消息

    3. 每个server有一组(2个)消息队列,分别用来发和收。发送的消息包含输入和输出的cpu指针,是个二维数组(因为有多个输入/输出的场景)。收的消息包括一个int类型的数值即可,表示server处理完了当前的数据

    4. server的数量可以设置,根据模型的属性和实际业务中运行的模型个数来自行决定

    5. client处理的逻辑是,发送不定数量的batch,根据模型的n来决定多少个batch为一组。比如,模型是4b4c的,那就4个一组发出去。所谓发4个,实际上是发送输入空间上的一段连续内存,通过地址偏移计算来决定发哪个地址。同样,输出的地址也要在client侧计算好,然后server直接把输出写在这个起始地址上

    6. client维护了几个关键的数据结构:

      1. process_idx:代表当前即将要执行推理的server id,就是马上要发数据给它了,如果它是空闲的

      2. fetch_idx:代表当前即将要取结果的server id

      3. processed_batch:表示已经发出去的batch数量

      4. fetched_batch: 表示已经收回来的batch数量

      5. mlu_input: 本地维护的mlu内存,不用每次malloc,但是需要每次copy

      6. mlu_output:本地维护mlu内存,用来存放输出

    7. client处理的原则是,只要还有空闲的server,就先赶紧把数据发出去,而不是发完一组,在那等待server返回。除非server都分配完了,这时再等待server-0的返回结果,一旦收到返回结果,赶紧再发一组数据给server-0。然后再等待server-1的返回结果,依次循环

  3. 代码实现

    1. cs_demo.tar.gz

版权所有 © 2022 寒武纪 Cambricon.com 备案/许可证号:京ICP备17003415号-1
关闭