如何设计一个混合 AI 架构,在离线时降级、在线时增强?
解读
面试官想确认三件事:
- 能否把“AI 能力”拆成可离线、可在线的两段,而不是简单地把模型搬到端侧;
- 能否用 Android 原生机制(AAR 体积、ABI 过滤、动态下发、权限、电量、隐私)把“降级-增强”做得对用户无感;
- 能否在工程层面给出可落地的灰度、回滚、容灾方案,而不是只谈算法。
国内场景还要额外踩坑:GMS 缺失、厂商 ROM 对后台限制各异、用户常年关自启动、工信部 164 号文对“强行更新”的处罚,以及国内商店对 AAB 的伪支持。回答必须体现“国内合规 + 端智能 + 云增强”三位一体。
知识点
- 端侧推理框架:TensorFlow Lite、MNN、NCNN、Paddle Lite、TVM Runtime,量化方式(INT8、FP16、Weight-only),Android NNAPI 与厂商 NPU SDK(HiAI、SNPE、NeuroPilot)。
- 模型热更新:Google Play Feature Delivery 在国内不可用,改用自研“插件化 + 差分补丁”或 Tinker/Shadow,把 .tflite 当普通 asset 做 bsdiff,下载后放私有目录,绕过 SplitCompat。
- 运行时决策:NetworkCallback + ConnectivityManager 判断“Wi-Fi / 5G / 计费网络”,Settings.Global 读取“低电量模式”,WorkManager 做网络约束任务,防止厂商杀后台。
- 降级策略:
离线模型只做“粗粒度”输出(例如 50 类意图),云端做千级别细分类;
当模型版本低于阈值或 CPU 占用 >40% 时,直接走规则引擎;
使用 TFLite 的 fallback 路径:GPU Delegate 失败 → NNAPI → CPU。 - 增强策略:
上传加密特征(非原始数据),云端返回 Logits 或蒸馏后的软标签,端侧再做二次融合;
对折叠屏/平板,利用大屏缓存多帧,上传 batch 推理,减少 30% 云调用;
引入联邦学习:每天闲时(0-6 点)上传梯度,云端聚合后次日下发新权重,用户数据不出域。 - 隐私合规:
端侧推理属于“本地加工”,无需额外弹窗;
上传特征需双重匿名(随机 UID + 差分隐私噪声),并在《隐私政策》中单独章节说明;
提供“仅本地模式”开关,写入 SharedPreferences,下次启动直接跳过云增强。 - 性能与功耗:
使用 Android 12 新 API ThermalService,温度档≥MODERATE 时关闭 GPU Delegate;
通过 Battery Historian 验证:离线模型单次推理 <7 ms、内存 <35 MB、云调用日均 ≤12 次;
APK 体积控制:把 8-bit 量化模型放 assets,首次安装 <80 MB,后续按模块动态下发。 - 灰度与回滚:
云侧采用“配置中心 + 用户分桶”方式,把模型版本号、阈值、开关做成 JSON,通过 MQTT/HTTP 长连接秒级生效;
端侧记录推理耗时与异常码,回传至 Sentry+Prometheus,P99 耗时上涨 15% 或崩溃率 >0.3% 自动回滚到上一版离线模型。
答案
整体采用“端云协同、三层决策”的混合架构:
-
能力分层
① 离线最小可用模型:INT8 量化、<30 MB、仅覆盖核心场景(如扫码识物、语音唤醒),放在 assets 随包发布;
② 在线增强模型:FP16、>100 MB、覆盖长尾场景,通过“差分补丁 + LZ4 压缩”动态下发到私有目录;
③ 规则兜底:当模型加载失败、系统剩余内存 <200 MB、或用户关闭“云增强”开关时,走传统 if-else 规则。 -
决策引擎
在 Application.onCreate 阶段初始化 DecisionEngine,输入三维信号:- 网络质量:NetworkCallback 判断是否为“Wi-Fi 且非计费网络”,延迟 <100 ms;
- 系统状态:ThermalService + BatteryManager 判断温度与电量,低于 15% 直接降级;
- 业务场景:扫码页面生命周期在前台且摄像头已打开,优先端侧;聊天页面输入框触发 AI 助手,允许走云端。
输出枚举:LOCAL_ONLY、CLOUD_ONLY、FUSION。
-
端侧推理
使用 TFLite 2.x + GPU Delegate + NNAPI,模型文件以 MappedByteBuffer 方式 mmapped,减少 1 次拷贝;
推理线程绑定大核,采用 HandlerThread + Looper 模型,防止 UI 线程被抢占;
结果缓存到 LruCache<String, SoftReference<float[]>>,key 为输入特征 MD5,5 分钟内复用。 -
云侧增强
特征经 TEE 加密后上传,云端返回 Top-K Logits 与置信度;
端侧再做加权融合:若云端置信度 >0.85 且与端侧差值 >0.2,采纳云端结果,否则保留端侧;
采用“请求去重”:同一用户 10 分钟内相同特征不再上传,节省 40% 流量。 -
更新与回滚
模型版本号写入 build.gradle 的 resValue,云配置中心同步;
补丁包通过 MD5 + 签名验证,失败即删除并回退到 assets 内置模型;
灰度按国内渠道号(华为、应用宝、小米、OPPO)+ 用户尾号 2 位分桶,支持实时关闭。 -
合规与体验
首次弹窗《智能增强功能协议》,提供“仅本地模式”一键关闭;
上传数据采用国密 SM4 加密,密钥存 Keystore,AES-GCM 随机 IV,每次会话轮换;
在设置页增加“AI 增强耗电”图表,用 Battery Historian 数据可视化,提升用户信任。
拓展思考
-
当折叠屏手机展开后,多窗口同时调用 AI 能力,如何防止 GPU 抢占导致卡顿?
可引入“分时令牌”机制:系统层维护 GPU token,每个进程按优先级排队,超时 100 ms 强制释放。 -
如果未来车载 Android(AAOS)也要复用同一套架构,车规级芯片(如高通 8155)NPU 驱动版本碎片化严重,如何一次编译多处运行?
采用 TVM + Relay 做统一 IR,后端生成 .so + .cl 混合包,运行时根据 /vendor/lib/egl 库名动态加载对应 codegen,把“离线模型”做成芯片级 HAL 插件,与 Android 版本解耦。 -
国内鸿蒙 NEXT 不再兼容 APK,而鸿蒙 AI 框架 MindSpore Lite 的算子集与 TFLite 不完全对齐,如何最小成本迁移?
在编译期用 ONNX 做中间表达,通过自写“算子映射表”把 TFLite 自定义算子转 MindSpore 算子,无法映射的走 fallback CPU 实现;同时把 DecisionEngine 抽成 Kotlin Multiplatform 模块,鸿蒙侧仅重写网络状态与存储适配层,业务逻辑 0 改动。