专栏算法工具链【J6】UCP任务优先级/抢占简介与实操

【J6】UCP任务优先级/抢占简介与实操

Jade-self2025-06-04
57
0

1. 引言

多模型推理场景中,可能会存在谁先谁后,甚至A模型任务正在运行,但需要被B模型任务抢占的情况。针对这种情况,地平线提供了模型优先级控制策略。

2. 优先级与抢占介绍

此功能仅支持在开发板端实现,x86模拟器不支持此功能。

2.1 理论简介

J6计算平台BPU硬件本身没有任务抢占功能,对于每一个推理任务,一旦它进到BPU计算后,在该任务执行完之前,会一直占用BPU,其他任务只能排队等待。

此时容易出现BPU计算资源被一个大模型任务独占,进而影响其他高优先级模型任务的执行。针对这种问题,工具链开发了基于软件的方式 实现的BPU资源抢占功能。

需要关注:

  1. hbm模型在BPU上推理时,它表现为1个或者多个function-call的调用,其中function-call是BPU的执行粒度,多个function-call 调用任务 在BPU硬件队列上按序进行调度,当一个模型所有的function-call都执行完成,那么一个模型推理任务也就执行完成了。

  2. BPU模型任务抢占粒度设计为function-call,即BPU执行完一个function-call之后,暂时挂起当前模型,然后切入执行另外一个模型,当新模型执行完成之后,再恢复原来模型的状态继续运行。 但是这里存在两个问题,第一是编译出来的hbm模型function-call 都是merge在一起的,此时模型只有一个大(长)的function-call,它无法被抢占;第二是每个function-call的执行时间比较长或者不固定,会造成抢占时机不确定,影响抢占效果。

为了解决上述两个问题,地平线进行了一些处理,下面介绍其操作方法:

  1. 如果您使用QAT方案:在 模型编译 阶段,需要在compile接口中添加 max_time_per_fc 选项,用于设置每个function call的执行时间(以微秒为单位),默认取值为 0 (即不做限制)。您可以自行设置这个选项,控制hbm上板运行时每个function-call的执行时间。假设某hbm总执行时间为10ms,当模型编译时 将 max_time_per_fc 设置为 1000,则这个hbm将会从默认的1个10ms function-call被拆分成10个1ms function-call。

  2. 如果您使用PTQ方案,在 模型转换 阶段,需要在YAML文件 编译器相关参数( compiler_parameters )中,添加 max_time_per_fc 参数。

2.2 UCP推理API

板端推理C++代码:需要在任务提交时设置 hbUCPSchedParam.priority 参数。

DescriptionDescription

优先级按照是否支持抢占,可以分为:高优抢占优先级任务、普通优先级任务。

  1. 配置 infer 任务优先级小于 254,则为普通任务,不可抢占其他任务。

  2. 配置 infer 任务优先级等于 254,则为高优抢占任务,可支持抢占普通任务。

  3. 配置 infer 任务优先级等于 255,则为urgent抢占任务,可抢占普通任务和254抢占任务。

注意
  • 抢占(254/255)是系统级别的,即当前进程提交的抢占任务不仅能对进程内的普通任务,也可对其他进程的普通任务实施抢占行为。抢占不需要考虑 中继relay 或 直连direct 模式。

  • 优先级(0~253)在进程内可以按照优先级排序,跨进程优先级排序,需要启动中继模式。

2.3 工作模式

UCP框架支持两种主要工作模式:直连模式和中继模式。系统默认运行在直连模式下。QNX操作系统和x86仿真不支持中继模式。

中继模式下,支持多进程任务的统一调度,使用中继模式前,首先启动 ucp_service,service文件位于 deps_aarch64/ucp/bin/service/ 路径下,并通过设置环境变量 HB_UCP_ENABLE_RELAY_MODE=true 来启用Relay模式,使得用户进程可以通过中继服务进行通信。

无论是直连模式还是中继模式,UCP接口的调用方式保持一致,不会对编程逻辑产生影响。您可以根据实际需求灵活选择这两种模式,以满足系统在性能和灵活性方面的要求。

3. 抢占示例介绍

示例UCP trace图如下:

Description
  • 上面的抢占模型A,单独运行是1.9ms

  • 下面的被抢占的模型B,单独运行17.1ms,且模型B设置的Function call是1000us=1ms

分析如下:

  1. 模型B开启Function call=1000编译,在未发生被抢占情况时,latency与不开启fc一致。

  2. 抢占模型A,在任务提交抢占时,会等待12ms,再开始执行模型A(因此模型A wait 大约34ms),在等待的12ms中,模型B继续执行,因此模型B相比于单独运行,wait只会多6ms≈1.9*3(3次模型A执行时间)。
  3. 模型B运行最后一个function call期间,不能被抢占,所以上面 最后那个 抢占模型A多等了一会,变成~2.1ms。

在BPU Trace中,可以看到更具体的BPU抢占与优先级详情,示例如下

Description

图中:三个模型设置了三个优先级,其中petr最低优,且是分段可抢占的,googlenet的task_priority=255,resnet50的task_priority=254。

算法工具链
技术深度解析社区征文征程6杂谈
评论0
0/1000