diff --git a/TASK-local-llm.md b/TASK-local-llm.md new file mode 100644 index 0000000..783e69c --- /dev/null +++ b/TASK-local-llm.md @@ -0,0 +1,46 @@ +# Локальная модель на телефоне (Gemma 4 E2B) — ПЛАН (в очереди, НЕ реализовано) + +> Статус: ЗАФИКСИРОВАНО 2026-08-23 ночью. Реализация НЕ начата — ждёт отмашки пользователя. +> Пользователь: «как закончишь с тем, что мы уже напланировали, нужно будет написать интерфейс и две реализации: одна ведёт на наш qwen 3.8, а вторая — вот эта вот модель. В будущем в идеале у нас всё должно мочь работать в офф-лайн режиме». + +## Источник (что за модель и как она быстрая) + +- Репозиторий: **vayun-mathur/Modern-Apps** → `openassistant` (клон: `~/WORK/modern-apps/`) +- Модель: **Gemma 4 E2B (2B)** в формате `.litertlm` (LiteRT LM, Google; бывш. MediaPipe LLM Inference / AI Edge) +- Файл: `gemma-4-E2B-it.litertlm` (SHA256 `181938105e0eefd105961417e8da75903eacda102c4fce9ce90f50b97139a63c`), ~0.8 ГБ, контекст 32K +- Источник модели: `huggingface.co/litert-community/gemma-4-E2B-it-litert-lm` +- Скорость на Honor Magic V3 (Snapdragon 8 Gen 3, Adreno 750, 12 ГБ): **20-35 ток/с** (MindStudio, спекуляция вкл), официально на S26 Ultra до 66-92 ток/с +- Секрет скорости: GPU-бэкенд (OpenCL) для text + **встроенный MTP-спекулятивный декодинг** (Multi-Token Prediction у Gemma 4 — черновик-головы в чекпоинте), флаг `ExperimentalFlags.enableSpeculativeDecoding = true` +- Замена модели проста: готовые `.litertlm` на HF (Qwen3 0.6B/1.7B/8B, Qwen2.5, Phi-4-mini, Gemma3-1B/4B, FunctionGemma-270M и др.) — поменять URL+SHA256 +- Полный разбор: `/root/notes/openassistant-lite-llm.md` (2026-08-10) + +## Задача (когда будет отмашка) + +**Интерфейс LLM + две реализации** в app-phone (агент «Порфирий»): + +1. **Абстракция**: `interface LlmClient` (или sealed): метод `chat(history, system): String` — текущий контракт (см. `LlmClient.kt`, прямой OkHttp к `https://llm.binom.pw/v1/chat/completions`). +2. **Реализация 1 — удалённая (уже есть)**: Qwen3.8-27B-NVFP4 через llm.binom.pw (прямой OkHttp, TOOL-результаты → user-сообщения). Переоформить под интерфейс. +3. **Реализация 2 — локальная**: Gemma 4 E2B через LiteRT LM: + - Библиотека: `com.google.ai.edge.litertlm:litertlm-android:0.14.0` + - `Engine(EngineConfig(modelPath, backend=GPU(), visionBackend=GPU(), audioBackend=CPU(), cacheDir))` + `engine.initialize()` + - `ExperimentalFlags.enableSpeculativeDecoding = true` (ПЕРЕД initialize) + - Модель на диске: `getExternalFilesDir(null)/gemma4-2b.litertlm` (скачать с зеркала, SHA256 проверка — как у автора, без HF-фолбэка) + - `ConversationConfig(systemInstruction, initialMessages, tools?, automaticToolCalling?)` + `sendMessageAsync` стриминг + - Формат .litertlm: внутри квантованная модель, эмбеддинги (memory-mapped), токенайзер, KV-cache менеджмент, function calling +4. **Оффлайн-режим**: переключатель/автовыбор — сеть есть → Qwen3.8, нет → Gemma E2B (или наоборот, решить с пользователем). Идеал: «всё может работать оффлайн». + +## Риски/нюансы (из заметки) + +- Спекуляция вшита в сборку модели — у Gemma 4 E2B есть, у других не факт; tools/automaticToolCalling — у Gemma/Qwen/Phi есть, не у всех +- Русский текст у Qwen обычно лучше — для локальной можно рассмотреть Qwen3-1.7B (компромисс скорость/русский) +- 8 Gen 3 термальный капкан: непрерывная генерация → троттлинг до 2 раз; паузы между запросами обязательны +- Батарея: ~4-4.5 часа непрерывной генерации (20-25%/час); сценарий ассистента 5-10 мин/час → 1.5-4%/час — незаметно +- Память 12 ГБ хватает: модель на GPU ~676-800 МБ RSS, эмбеддинги 1.12 ГБ memory-mapped +- Android-интеграция sherpa-onnx (STT) уже работает — только LLM-часть заменить + +## Проверка + +- Юнит-тесты: интерфейс, выбор реализации, конфиг +- На железе: полный цикл (голос → STT → локальная LLM → ответ) при выключенном интернете (airplane mode / svc wifi disable) +- Замер скорости: ток/с, TTFT на живом Honor Magic V3 +- Сравнение ответов Qwen3.8 vs Gemma E2B на одинаковых запросах