一种三层优先级调度器将端侧语言模型的延迟从一秒以上降低到了 0.2 秒以下,即使在手机处理后台任务时,也能保持聊天应用的响应速度。该调度器专为运行 30 亿参数模型的 Tensor G3 芯片设计,在不中断后台任务的情况下,将延迟从 1,420 毫秒缩减至 161 毫秒。
为什么端侧 LLM 表现挣扎
在移动处理器上运行大型语言模型面临着资源紧缺的问题。在 Tensor G3 上,3B 模型已经消耗了约 85% 的神经网络处理器 (NPU) 资源。当一个低优先级任务(例如离线索引器)与用户打开聊天窗口同时运行时,感知的响应时间会从大约 140 毫秒跳升至 1,400 毫秒,这种十倍的减速用户会立即察觉。
问题不仅在于速度。移动设备必须兼顾 UI 流畅度、电池寿命以及多个请求计算资源的应用程序。一个按顺序处理任务的朴素队列会迫使 UI 线程等待后台工作,从而使对话助手变成一种迟钝的体验。
三层调度器的工作原理
新的调度器在推理流水线中插入了三个协同工作的组件:
- 优先级队列 (Priority Queue) – 一个小顶堆 (min-heap),根据静态重要性级别对传入任务进行排序。
- 抢占控制器 (Preemption Controller) – 当高优先级请求到达时,它会暂停低优先级任务而不是将其丢弃。
- Token 预算调节器 (Token Budget Governor) – 根据应用的生命周期状态,限制任务可以生成的 Token 数量。
通过这些组件的协作,前台聊天请求可以跃升至队列最前端,而后台任务则处于挂起状态,准备在资源释放时恢复运行。
优先级层级与抢占
四个层级定义了哪些任务可以被中断:
| 层级 | 描述 |
|---|---|
| 前台聊天 | 关键 UI 交互 |
| 行内建议 | 自动补全式提示 |
| 后台摘要 | 定期内容摘要 |
| 离线索引 | 大批量数据处理 |
调度器从不中止低优先级任务。相反,它会对模型的键值 (KV) 缓存(一种保存中间注意力结果的结构)进行快照,并将任务挂起。当高优先级请求完成后,控制器会恢复快照,让后台任务从中断处继续执行。这种“暂停并恢复”的方法避免了如果从头开始重启任务所带来的昂贵重计算成本。
部分 KV 缓存驱逐进一步减少了浪费。静态系统提示词保留在缓存中,而只有动态的对话轮次会被驱逐。其结果是,在暂停后重新预填充模型的成本降低了 40%–60%。
无需定时器的 Token 预算管理
许多实现依赖定时器来猜测任务何时应该让出 CPU 或 NPU 时间。定时器过于粗放;它们要么导致 UI 饥饿,要么导致芯片利用率不足。该调度器将定时器替换为 Android 的 ProcessLifecycleOwner,它会发送能够可靠指示应用处于前台还是后台的生命周期事件。
- ON_RESUME – 应用重新获得全部计算预算,允许待处理的前台任务不受阻碍地运行。
- ON_STOP – 应用将后台任务的 Token 预算限制在正常水平的约 25%,为任何突发的 UI 请求保留余量。
通过将资源分配与生命周期事件挂钩,系统可以根据真实的用户行为做出反应,而不是根据任意的时间片。
性能提升与权衡
在朴素的先来先服务队列下,后台任务会将前台聊天的延迟推高至约 1,420 毫秒。在启用优先级调度器的情况下,相同的聊天请求大约在 161 毫秒内即可完成,这种十倍的提升恢复了流畅的用户体验。
恢复暂停的任务会使其总执行时间增加约 22%。由于后台工作是非关键性的,这种权衡是可以接受的,尤其是当 UI 保持响应迅速时。
