Трирівневий планувальник пріоритетів скорочує затримку мовної моделі на пристрої з понад однієї секунди до менш ніж двох десятих секунди, зберігаючи швидкість роботи чат-додатків навіть тоді, коли телефон зайнятий фоновими завданнями. Створений для чипа Tensor G3, що працює з моделлю на 3 мільярди параметрів, він зменшує затримку з 1420 мс до 161 мс, не перериваючи фонові процеси.
Чому локальні LLM працюють важко
Запуск великої мовної моделі на мобільному процесорі створює дефіцит ресурсів. На Tensor G3 модель на 3 млрд уже споживає близько 85% потужності нейронного процесора (NPU). Коли низькопріоритетне завдання — наприклад, офлайн-індексатор — виконується одночасно з відкриттям чату користувачем, відчутний час відгуку стрибає приблизно з 140 мс до 1400 мс — це десятикратне уповільнення, яке користувачі помічають миттєво.
Проблема не лише у швидкості. Мобільні пристрої мають балансувати між плавністю інтерфейсу, часом автономної роботи та кількома додатками, які одночасно запитують обчислювальні ресурси. Наївна черга, що обробляє завдання по черзі, змушує потік інтерфейсу (UI thread) чекати на фонову роботу, перетворюючи розмовного асистента на повільний інструмент.
Як працює трирівневий планувальник
Новий планувальник впроваджує три скоординовані компоненти в конвеєр виведення (inference pipeline):
- Priority Queue (Черга пріоритетів) – мінімальна купа (min-heap), яка впорядковує вхідні завдання за статичним рівнем важливості.
- Preemption Controller (Контролер витіснення) – коли надходить запит із вищим пріоритетом, він ставить на паузу завдання з нижчим пріоритетом замість того, щоб скасовувати їх.
- Token Budget Governor (Регулятор бюджету токенів) – обмежує кількість токенів, які може згенерувати завдання, залежно від стану життєвого циклу додатка.
Разом вони дозволяють запиту чату на передньому плані миттєво опинитися на початку черги, тоді як фонові завдання залишаються в режимі очікування, готовими відновитися, коли звільняться ресурси.
Рівні пріоритетів та витіснення
Чотири рівні визначають, що саме можна перервати:
| Рівень | Опис |
|---|---|
| Foreground Chat | Критична взаємодія з UI |
| Inline Suggestion | Підказки у стилі автозаповнення |
| Background Summary | Періодичне узагальнення контенту |
| Offline Indexing | Масова обробка даних |
Планувальник ніколи не перериває низькопріоритетне завдання. Замість цього він робить знімок (snapshot) кешу ключ-значення (KV) моделі — структури, що зберігає проміжні результати механізму уваги (attention), — і ставить завдання на паузу. Коли запит із високим пріоритетом завершується, контролер відновлює знімок і дозволяє фоновому завданню продовжити роботу з того місця, де воно зупинилося. Такий підхід «пауза-відновлення» дозволяє уникнути витратних повторних обчислень, які виникли б, якби завдання запускалося з нуля.
Часткове витіснення з KV-кешу додатково зменшує втрати. Статичний системний промпт залишається в кеші, тоді як витісняються лише динамічні ходи діалогу. Результатом є скорочення витрат на повторне заповнення (re-prefilling) моделі після паузи на 40–60%.
Управління бюджетом токенів без таймерів
Багато реалізацій покладаються на таймери, щоб вгадати, коли завдання має звільнити час CPU або NPU. Таймери — це грубий інструмент; вони можуть або позбавити UI ресурсів, або недовикористовувати чип. Планувальник замінює таймери на Android-клас ProcessLifecycleOwner, який генерує події життєвого циклу, що надійно вказують, чи перебуває додаток на передньому плані, чи у фоні.
- ON_RESUME – додаток отримує повний бюджет обчислень, що дозволяє очікуваним завданням на передньому плані виконуватися без перешкод.
- ON_STOP – додаток обмежує фонові завдання приблизно до 25% від їхнього звичайного бюджету токенів, зберігаючи запас для будь-якого раптового запиту з UI.
Прив'язуючи розподіл ресурсів до подій життєвого циклу, система реагує на реальну поведінку користувача, а не на довільні часові інтервали.
Приріст продуктивності та компроміси
За умови використання наївної черги «першим прийшов — першим обслуговано», фонове завдання збільшує затримку чату на передньому плані приблизно до 1420 мс. З активним планувальником пріоритетів той самий запит чату виконується приблизно за 161 мс — це десятикратне покращення, яке повертає плавність взаємодії з користувачем.
Відновлення поставленого на паузу завдання додає близько 22% до його загального часу виконання. Оскільки фонова робота не є критичною, такий компроміс є прийнятним, особливо коли інтерфейс залишається швидким.
