4、混合架构设计原则:传统模块与AI模块的接口定义、数据流设计、实时性约束下的算力分配

好,我们直接进入正题。混合架构,说白了就是把传统 ISP 的确定性算法和 AI 的“黑盒”能力捏在一起。这事儿看着简单,做起来坑特别多。我最早在项目里踩的第一个大坑,就是接口没定义清楚,结果 AI 模块吐出来的数据,传统模块根本不认。

这一章,我们就围绕三个核心问题展开:接口怎么切、数据怎么流、算力怎么分。这三个问题搞定了,架构就稳了一半。

4.1 接口定义:传统与AI的“握手协议”

传统 ISP 模块之间传的是 RAW 图、RGB 图、YUV 图,格式固定,位宽固定。但 AI 模块不一样,它可能输入是 4 通道的,输出是 1 通道的 feature map。你想想看,这两边要对接,必须定一套双方都认的“契约”。

我个人习惯把接口分成三类:

接口类型 典型数据 位宽/格式 同步方式
像素级接口 RAW、RGB、YUV 8-16bit,Bayer/BGR 行同步/帧同步
特征级接口 Feature Map、权重 8-32bit float/int DMA 完成中断
控制级接口 参数、配置、状态 32bit 寄存器 APB/AXI-Lite

核心原则:AI 模块的输入输出,必须能“无损”映射回传统 ISP 的像素空间。否则下游模块会直接崩溃。

举个例子。AI 降噪模块输出了一张 feature map,但传统 3A 模块要的是 RGB 图。怎么办?我建议在 AI 模块尾部加一个 Format Converter,把 feature map 转成标准 RGB。这个转换器虽然简单,但它是整个架构的“翻译官”。

我的经验:接口定义时,一定要把 数据有效信号 和 行/帧同步信号 单独拉出来。AI 模块处理延迟不确定,传统模块需要靠这些信号来“等”数据。我曾经因为没做 valid 信号,导致传统模块读到了半帧垃圾数据,画面直接花掉。

4.2 数据流设计:从“串行”到“并行+反馈”

传统 ISP 的数据流是典型的串行管线:RAW → BLC → LSC → AWB → Demosaic → ... → YUV。每个模块处理完,数据才往下走。

但加入 AI 后,数据流就复杂了。我把它归纳为三种模式:

  1. 前处理模式:AI 模块放在传统管线之前,做 RAW 域的增强(如去噪、HDR 融合)。
  2. 后处理模式:AI 模块放在传统管线之后,做 RGB/YUV 域的优化(如超分、美颜)。
  3. 旁路反馈模式:AI 模块从管线中间“偷”数据,处理完再“塞”回去,或者反馈控制传统模块的参数。

我个人最常用的是第三种。为什么呢?因为前两种都会打断传统管线的流水节奏。而旁路模式,AI 模块和传统模块可以并行跑。

来看一个实际的数据流设计:

// 伪代码:AI 旁路降噪模块的数据流
while (frame_ready) {
    // 传统管线正常跑
    raw_frame = sensor_read();
    blc_frame = blc_process(raw_frame);
    lsc_frame = lsc_process(blc_frame);
    
    // AI 模块从 LSC 之后“偷”数据
    ai_input = lsc_frame;
    ai_output = ai_denoise(ai_input);  // 异步执行
    
    // 传统管线继续跑,但等待 AI 结果
    awb_frame = awb_process(lsc_frame);  // 用原始数据先跑 AWB
    
    // AI 结果回来后,替换掉对应区域
    final_frame = merge(awb_frame, ai_output);
    
    // 继续后续处理
    demosaic_frame = demosaic_process(final_frame);
}

注意:旁路模式最大的坑是 数据对齐。AI 模块处理延迟可能比传统管线多几行甚至几帧。你必须设计一个 Line Buffer 或 Frame Buffer 来缓存传统管线的中间结果,等 AI 模块处理完再合并。否则画面会出现“撕裂”或“错位”。

4.3 实时性约束下的算力分配

这是最头疼的部分。AI 模型算得慢,传统模块算得快,怎么分配才能保证 30fps 甚至 60fps?

我一般按这个步骤来:

  • 第一步:算总账。 先算出一帧图像的总处理时间预算。比如 30fps,一帧只有 33ms。传统管线固定占 15ms,留给 AI 的就只有 18ms。
  • 第二步:拆模型。 把 AI 模型按层拆开,算每层的计算量(MACs)和访存量。找出瓶颈层。
  • 第三步:分优先级。 实时性要求高的模块(如 3A、去噪)优先分配算力;非实时的模块(如美颜、风格迁移)可以降频或丢帧处理。
模块 计算量 (GMACs) 延迟预算 (ms) 分配策略
传统 ISP 管线 0.5 15 固定硬件流水线
AI 降噪 (轻量) 2.0 8 NPU 专用核
AI 超分 (重量) 15.0 10 (可丢帧) GPU/NPU 共享,动态调度
AI 3A 辅助 0.8 5 CPU 轻量推理

关键点:算力分配不是静态的。我建议设计一个 动态负载均衡器,根据当前场景的复杂度(如暗光、运动)动态调整 AI 模块的推理精度或帧率。暗光下降噪权重高,超分可以降级;白天反之。

嗯,这里要特别提一下 算力碎片化 的问题。AI 模型推理时,NPU 的利用率往往不是 100%。中间有大量的等待时间(DMA 搬运、算子切换)。我曾经在一个项目里发现,NPU 的实际利用率只有 40%,剩下的时间都在空转。后来我把传统 ISP 的一些轻量计算(如 LSC 插值)塞进了 NPU 的空闲时间片,才把整体帧率提上去。

避坑指南:我曾经为了追求极致画质,把 AI 模型做得很大,结果帧率掉到 15fps。后来学乖了,用 模型剪枝 + 量化 把计算量砍掉 60%,画质只降了 1dB,但帧率回到了 30fps。记住:在实时系统里,完成比完美重要。

4.4 架构总览:一张图说清楚

下面这张图,是我在多个项目里沉淀下来的混合架构参考。它把传统模块、AI 模块、数据流和算力分配都串在了一起。

AI ISP 混合架构数据流与算力分配图 AI ISP 混合架构:数据流与算力分配 Sensor RAW BLC / LSC AWB / AE Demosaic YUV 输出 AI 降噪 (轻量) AI 超分 (重量) AI 3A 辅助 动态算力分配器 (Dynamic Load Balancer) 传统管线固定 15ms | AI 降噪 8ms | AI 超分 10ms (可丢帧) | AI 3A 5ms ⚠️ 关键约束 AI 模块延迟必须 ≤ 传统管线缓冲深度 否则画面撕裂 / 帧率下降 💡 优化方向 模型剪枝 + 量化 → 算力降低 60% NPU 空闲时间片 → 塞入传统轻量计算

这张图里,传统管线是“主干道”,AI 模块是“旁路”。数据从主干道分流到 AI 模块,处理完再合并回来。算力分配器在底部统一调度,确保总延迟不超过一帧的时间预算。

再次强调:不要试图让 AI 模块接管所有事情。传统 ISP 的确定性、低延迟、低功耗优势,是 AI 目前无法替代的。混合架构的精髓,是让 AI 做它擅长的事(去噪、超分、语义理解),让传统模块做它擅长的事(3A、色彩校正、伽马)。各司其职,才是王道。