Flux Engine 设计笔记:为所有产品打造统一运行时
揭秘我们端侧推理运行时背后的架构选择,以及那些塑造它的工程约束。
一个运行时,而不是封装
做一款端侧应用很难。做五款更难。要让五款共享一致技术底座、同步发版、电池表现不退化——这是运行时问题。
Flux Engine 就是我们的答案。它是一个轻、且有主见的层,构筑在各自领域最强的开源运行时之上——语音(whisper.cpp / faster-whisper)、视觉(llama.cpp / mlx-vlm)、语言(llama.cpp / MLC-LLM,Android 上是 executorch)——由一个调度器统一协调,它清楚此刻什么在内存里、用户在干什么、设备还能撑多久。
三条约束
1. 冷启动延迟
模型大多数时间躺在磁盘里,用户不会。Flux Engine 会基于应用使用模式和一个端侧小分类器,预热最可能被调用的下一个模型。这个分类器本身只有 50 KB 的 MLP——小到每次唤醒都能跑。
2. 小 NPU 上的持续吞吐
我们绝不会同时派两个负载去抢同一个加速器。调度器基于队列、感知优先级,并对前台应用强制让位。ASR 流优先于后台摘要;点按翻译优先于后台索引。
3. 内存紧张时的优雅降级
如果用户正在剪 4K 视频,我们不会为了跑一段摘要把手机 OOM 掉。引擎会输出一个"剩余容量"软信号,产品要遵守——功能可能降到更小模型、推到后台,或者给出"等手机凉一点再继续"的提示。
Flux Engine 真正暴露的东西
几个 C++ 抽象,再加一层 Swift / Kotlin / Rust 绑定:
FluxSession—— 绑定模型与设备的长生命周期推理会话。FluxStream—— 增量输出,token 中途可取消。FluxBudget—— 感知设备状态的容量报告。FluxRouter—— 按设备档位、电量、温度状态和产品偏好为请求选模型。
就这些。五个原语。每一个 Flux* 产品都在它们之上搭建。
我们换来什么
一次 bug 修复、一次性能优化、一次量化改进——五款产品同时变好。一次调度器回归修复——五款产品同时停止暴掉电量。在我们这种规模的团队里,共享运行时的经济账,怎么算都划算。
我们犯过什么错
- 头六个月在图编译器上投入过多。最终还是手工调过的模型加载器赢了。
- profiling 投入太少。第九个月推倒重写。
- 一开始假设所有产品共用一种量化方案。现在每款产品都有自己的混合。