3、多模型调度核心概念:任务、流水线、并行度、资源竞争、调度策略等术语解析

在BM1684平台上进行多模型部署时,我们面对的不是单个模型的独立运行,而是一组模型在有限算力、内存和带宽资源下的协同工作。多模型调度的本质,是在时间维度和空间维度上对芯片资源进行精细切分与复用。要理解这一过程,首先需要建立一套统一的术语体系——任务(Task)、流水线(Pipeline)、并行度(Parallelism)、资源竞争(Resource Contention)和调度策略(Scheduling Policy)构成了这套体系的核心骨架。这些概念并非孤立存在,它们相互关联、彼此制约,共同决定了多模型系统的吞吐量、延迟和资源利用率。本节将逐一拆解这些术语的内涵,并结合BM1684的硬件特性(如TPU内核、DDR带宽、SDMA通道)说明它们在实际工程中的具体表现。

多模型调度核心概念关系图 调度策略 优先级 / 时间片 / 资源配额 任务 (Task) 模型实例 + 输入数据 + 优先级 + 截止时间 + 资源需求描述 并行度 (Parallelism) 模型并行 / 数据并行 流水线并行 / 任务并行 TPU内核数 × 批大小 流水线 (Pipeline) 阶段划分:预处理→推理→后处理 多模型串联 / 并联 乒乓缓冲 / 双缓冲 资源竞争 TPU算力争用 DDR带宽争用 SDMA通道争用 BM1684 资源池 TPU × 2 | DDR 12GB | SDMA 分配/回收 监控/调整

上图展示了多模型调度中五个核心概念之间的逻辑关系。调度策略处于中心位置,它接收任务的资源需求描述,结合并行度的设定,在流水线的各个阶段中分配资源,同时监控资源竞争状况并动态调整分配方案。这张图是理解后续所有调度机制的总纲——在实际工程中,我们通常先定义任务模型,再设计流水线结构,然后确定并行度参数,最后通过调度策略来协调资源竞争。下面逐一展开每个概念的详细内涵。

3.1 任务(Task):调度的最小执行单元

核心原理:在BM1684多模型调度语境下,任务(Task)不是指一个模型文件,而是指一次具体的执行请求——它包含了模型实例、输入数据、优先级、截止时间以及资源需求描述。一个检测模型可以被实例化为多个任务,每个任务处理不同的视频帧或图像批次。任务具有生命周期:创建(Create)、就绪(Ready)、运行(Running)、阻塞(Blocked)、完成(Completed)和销毁(Destroy)。调度器只关心处于就绪状态的任务,并根据某种策略从中选择下一个运行的任务。

任务描述通常包含以下关键字段:

字段 类型 说明 示例值
task_id uint32 全局唯一标识 0x3A2F
model_id uint32 指向已加载的模型句柄 2(检测模型)
input_buf void* 输入数据的内存地址(DDR或SRAM) 0x8000_0000
priority uint8 0-255,数值越大优先级越高 200
deadline uint64 期望完成的时间戳(us) 1,725,600,000
tpu_cycles uint32 预估TPU计算周期数 1,200,000
ddr_bytes uint32 预估DDR读写字节数 8,388,608

判断方法:在BM1684的TPU-Kernel编程框架中,任务通常通过bm_tpu_kernel_launch()接口提交。判断一个任务是否适合独立调度,需要看它是否满足以下条件:①输入数据已准备就绪;②所需的模型权重已加载到DDR;③目标TPU内核空闲或可抢占;④任务的资源需求(TPU周期、DDR带宽)可被当前调度器满足。如果任务依赖其他任务的输出(如检测结果送入分类模型),则属于流水线依赖任务,需要特殊处理。

工程经验:在BM1684上,任务创建的开销不可忽视。频繁创建和销毁轻量级任务会导致调度器开销占比过高。建议采用任务池(Task Pool)模式,预创建一批任务对象,通过状态机切换来复用,避免动态内存分配。实测中,任务池可将调度开销从约50μs/次降低到5μs/次。

3.2 流水线(Pipeline):多模型协作的结构化组织

核心原理:流水线是将一个完整的推理业务拆分为多个顺序或并行的阶段(Stage),每个阶段由一个或多个模型实例负责。在BM1684上,典型的视觉处理流水线为:视频解码 → 目标检测 → 目标分类 → 目标跟踪 → 结果编码。每个阶段可以运行在不同的TPU内核上,也可以在同一内核上分时复用。流水线的核心价值在于:通过阶段间的重叠执行(Overlap),隐藏单个阶段的延迟,从而提升整体吞吐量。

流水线设计的关键参数包括:

  • 阶段数(K):流水线的深度,阶段越多,并行潜力越大,但同步开销也越高。
  • 阶段处理时间(t_i):每个阶段的平均执行时间,流水线的吞吐量受最慢阶段(瓶颈阶段)限制。
  • 缓冲深度(B):相邻阶段之间的队列缓冲容量,决定了流水线能够容忍的抖动幅度。
  • 数据依赖类型:顺序依赖(前一阶段输出是后一阶段输入)或条件依赖(后一阶段仅处理特定输出)。

操作流程:在BM1684上搭建多模型流水线,通常遵循以下步骤:

  1. 阶段划分:根据业务逻辑将推理过程拆分为若干独立阶段,每个阶段对应一个模型或一个预处理/后处理算子。
  2. 资源分配:为每个阶段分配TPU内核、DDR缓冲区和SDMA通道。BM1684拥有2个TPU内核,可以将检测模型放在内核0,分类和跟踪模型共享内核1。
  3. 缓冲设计:使用双缓冲(Double Buffering)或环形缓冲(Ring Buffer)连接相邻阶段。双缓冲允许一个阶段在写入缓冲B时,下一阶段同时读取缓冲A。
  4. 同步机制:使用信号量或事件标志实现阶段间的同步。BM1684的TPU-Kernel提供了bm_sem_wait()和bm_sem_post()接口。
  5. 背压控制:当下游阶段处理速度慢于上游时,需要背压机制防止缓冲溢出。通常通过限制缓冲深度或使用丢弃策略实现。
设计建议:流水线的阶段数并非越多越好。在BM1684上,每个阶段切换涉及上下文保存和恢复(约10-20μs),如果阶段处理时间本身只有100μs,那么切换开销占比可达20%。建议将处理时间小于200μs的算子合并到相邻阶段,减少切换次数。

3.3 并行度(Parallelism):空间维度的资源复用

核心原理:并行度描述的是在同一时刻有多少个任务在同时执行。在BM1684上,并行度可以从四个层次理解:

并行类型 硬件基础 典型粒度 适用场景
模型并行 2个TPU内核 一个模型拆分为两部分,分别在不同内核运行 超大模型(如YOLOv5x)单内核放不下
数据并行 同一模型多实例 不同输入批次同时推理 多路视频流检测
流水线并行 阶段间重叠 不同阶段处理不同数据 检测+分类+跟踪串联
任务并行 TPU内核+SDMA 不同模型同时执行 检测与跟踪同时进行

判断方法:确定并行度时,需要先计算理论峰值并行度。BM1684的INT8算力为17.6 TOPS,FP32为2.2 TFLOPS。假设检测模型需要5 TOPS,分类模型需要1 TOPS,跟踪模型需要2 TOPS,那么理论上可以同时运行检测+分类+跟踪(共8 TOPS < 17.6 TOPS)。但实际还要考虑DDR带宽限制——BM1684的DDR4带宽为51.2GB/s,如果三个模型的总DDR访问量超过该值,则无法达到计算并行度。

案例拆解:假设一个智慧安防场景需要同时处理8路1080p@30fps视频流,每路视频流需要执行检测(YOLOv5s)、分类(ResNet18)和跟踪(DeepSORT)。

  • 初始方案:每路视频流独立运行一个完整流水线,即8个检测模型实例+8个分类实例+8个跟踪实例。这需要24个模型实例,远超BM1684的承载能力。
  • 优化方案:将检测模型合并为2个实例(每个实例处理4路视频流,通过batch=4实现数据并行),分类模型合并为2个实例,跟踪模型合并为2个实例。总实例数降为6个,每个TPU内核运行3个实例。
  • 并行度计算:检测模型batch=4时,TPU利用率约85%;分类模型batch=4时,利用率约60%;跟踪模型batch=4时,利用率约40%。总TPU负载约185%,超过100%,因此需要将跟踪模型降为batch=2,或调整调度策略使跟踪模型在检测/分类的空闲间隙运行。
风险提示:盲目提高并行度可能导致资源竞争加剧,反而降低整体吞吐量。当TPU利用率超过90%时,任务排队延迟会急剧上升。建议将目标利用率控制在70-80%之间,留出余量应对突发流量。

3.4 资源竞争(Resource Contention):性能下降的根源

核心原理:资源竞争发生在多个任务同时请求同一类有限资源时。BM1684上的资源竞争主要出现在三个层面:

  • TPU算力竞争:两个任务同时需要TPU内核执行矩阵运算。BM1684的2个TPU内核各自独立,但共享指令发射单元和部分缓存。
  • DDR带宽竞争:所有模型权重、输入输出数据都存储在DDR中。当多个任务同时进行大量DMA读写时,带宽成为瓶颈。实测中,当DDR带宽利用率超过80%时,有效带宽会因刷新和仲裁开销而下降。
  • SDMA通道竞争:BM1684有多个SDMA通道用于数据搬运,但通道数量有限(通常8-16个)。当任务数量超过通道数时,DMA请求需要排队。

判断方法:识别资源竞争的关键是监控性能计数器。BM1684提供了硬件性能计数器,可以读取以下指标:

// 伪代码:读取TPU利用率
uint32_t tpu_util = bm_read_counter(BM_TPU_UTILIZATION);
// 读取DDR带宽利用率
uint32_t ddr_bw_util = bm_read_counter(BM_DDR_BANDWIDTH_UTIL);
// 读取SDMA队列深度
uint32_t sdma_queue_depth = bm_read_counter(BM_SDMA_QUEUE_DEPTH);

// 判断竞争程度
if (tpu_util > 90 && ddr_bw_util > 70) {
    // TPU和DDR同时高负载,存在严重竞争
    // 建议降低并行度或调整任务优先级
}

案例拆解:在某项目中,检测模型和分类模型同时运行时,检测延迟从8ms增加到15ms,分类延迟从3ms增加到7ms。通过性能计数器发现:

  • TPU内核0利用率:95%(检测),内核1利用率:88%(分类)
  • DDR带宽利用率:82%(接近饱和)
  • SDMA队列深度:平均6.3(峰值12)

分析判断:DDR带宽是主要瓶颈。检测模型每次推理需要读取约50MB权重和特征图,分类模型需要约20MB。两者同时运行时,DDR带宽需求为(50+20)MB/8ms ≈ 8.75GB/s,加上其他开销,实际需求约12GB/s,接近51.2GB/s的25%——但实际利用率却达到82%,说明存在大量非连续访问和缓存未命中。

优化操作:①将检测模型的权重从DDR加载到SRAM(BM1684有2MB SRAM),减少DDR访问;②调整分类模型的batch大小从8降到4,减少瞬时带宽需求;③为检测任务设置更高优先级,确保关键路径不受影响。优化后,检测延迟恢复到9ms,分类延迟为5ms,整体吞吐量提升22%。

3.5 调度策略(Scheduling Policy):资源分配的核心决策

核心原理:调度策略决定了在多个就绪任务中,哪个任务获得资源、获得多少资源、运行多长时间。BM1684多模型调度中常用的策略包括:

策略名称 核心思想 优点 缺点 适用场景
先来先服务(FCFS) 按提交顺序执行 实现简单,公平 短任务被长任务阻塞 任务长度相近
固定优先级(FP) 高优先级任务先执行 保证关键任务延迟 低优先级任务可能饿死 检测>分类>跟踪
时间片轮转(RR) 每个任务运行固定时间片 公平,响应快 上下文切换开销大 多路视频流均衡处理
最早截止时间优先(EDF) 截止时间最近的任务先执行 满足实时性要求 需要精确的截止时间估计 实时跟踪场景
资源感知调度(RAS) 根据资源需求匹配 最大化资源利用率 计算复杂度高 混合负载场景

操作流程:在BM1684上实现调度策略,通常采用两级调度架构:

  1. 全局调度器:运行在ARM CPU上(BM1684集成8核ARM A53),负责跨模型的任务分配。它维护一个全局任务队列,根据策略选择下一个要执行的任务,并分配TPU内核和DDR带宽配额。
  2. 局部调度器:每个TPU内核内部有一个简单的硬件调度器,负责处理已分配到该内核的任务队列。局部调度器通常采用FIFO或简单优先级策略。

案例拆解:一个智能交通系统需要同时运行车辆检测(高优先级,实时性要求高)、车牌识别(中优先级)和交通流量统计(低优先级,离线分析)。

  • 初始策略:使用固定优先级,检测任务优先级200,车牌识别150,流量统计100。结果:检测延迟稳定在5ms,但流量统计任务几乎得不到执行,数据积压严重。
  • 改进策略:采用优先级+时间片混合策略。检测任务优先级200,但每个时间片最长占用2ms;车牌识别优先级150,时间片3ms;流量统计优先级100,时间片5ms。同时,当检测任务连续3个周期都未超过截止时间时,动态降低其优先级10%,将释放的资源让给流量统计。
  • 结果对比:检测延迟从5ms增加到6ms(仍在容忍范围内),车牌识别延迟从12ms降到8ms,流量统计的积压数据从10万帧降到2万帧。整体系统吞吐量提升35%。
经验总结:调度策略没有银弹。在BM1684上,最有效的做法是组合多种策略:用固定优先级保证关键任务,用时间片防止饿死,用资源感知避免过载。同时,调度策略需要根据实际运行数据持续调优——建议在开发阶段加入调度日志,记录每个任务的等待时间、执行时间和资源使用量,定期分析并调整策略参数。

3.6 常见误区与总结复盘

误区一:认为并行度越高越好。实际上,当并行度超过资源承载能力时,任务排队和上下文切换开销会抵消并行收益。BM1684上,2个TPU内核最多支持2个计算密集型任务同时运行,但如果有DDR带宽瓶颈,实际并行度可能只有1.5。

误区二:忽略任务间的隐式依赖。即使两个模型在逻辑上独立,它们可能共享同一个输入缓冲区或模型权重。如果调度器没有感知这种依赖,可能导致数据竞争或权重被意外覆盖。

误区三:将调度策略与模型加载混为一谈。模型加载(将权重从文件系统读入DDR)是IO密集型操作,不应占用TPU资源。正确的做法是在系统初始化阶段预加载所有模型,运行时只调度推理任务。

误区四:不监控资源竞争就盲目调参。没有性能计数器数据的调度优化是盲目的。建议在开发板上运行bm_profile工具,获取详细的资源使用时间线,再针对瓶颈进行优化。

总结复盘:本节解析的五个核心概念构成了多模型调度的完整知识框架。任务定义了“调什么”,流水线定义了“按什么顺序调”,并行度定义了“同时调多少”,资源竞争定义了“为什么调不快”,调度策略定义了“具体怎么调”。在BM1684的实际开发中,建议按照以下路径落地:①先明确业务需求,定义任务模型和优先级;②设计流水线结构,确定阶段划分和缓冲策略;③根据硬件资源计算理论并行度;④通过性能计数器识别资源竞争点;⑤选择合适的调度策略并持续调优。这五个步骤环环相扣,每一步的决策都会影响最终的系统性能。