Як семантичний кеш зменшує витрати на LLM у мобільних додатках
Уявіть: мобільний додаток з аудиторією в сотні тисяч користувачів. Щодня він генерує тисячі однотипних запитів до LLM: «Як додати контакт?», «Як створити новий контакт?», «Як внести контакт до списку?». Без семантичного кешу кожен такий запит іде в API, помножуючи витрати. Ми вирішуємо це, впроваджуючи механізм, який зберігає відповіді разом із векторним представленням запиту. При повторному зверненні система шукає семантично близькі embedding і повертає збережену відповідь, минаючи LLM. На практиці це знижує витрати на API на 40–60% і зменшує затримку з секунд до мілісекунд.
Які проблеми вирішує семантичний кеш?
Стандартний кеш за точним ключем безсилий проти синонімів і перефразувань. Користувачі формулюють одне й те саме питання по-різному — і кожного разу платите ви. API LLM дорогі при високій частоті повторюваних запитів: типовий hit rate без кешу близький до нуля. Затримка відповіді в 2–5 секунд погіршує UX у мобільному додатку, особливо на повільних каналах. Semantic cache вирішує всі три проблеми одночасно.
Як ми це робимо: middleware на FastAPI
Серверна частина — FastAPI middleware. При запиті генеруємо embedding через OpenAI, шукаємо найближчий у векторному сховищі. Якщо cosine similarity перевищує threshold — повертаємо кеш, інакше викликаємо LLM і зберігаємо новий embedding. Приклад коду:
import numpy as np
from openai import AsyncOpenAI
client = AsyncOpenAI()
cache: list[dict] = [] # У продакшені — Redis + pgvector або Pinecone
async def get_embedding(text: str) -> list[float]:
response = await client.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data[0].embedding
def cosine_similarity(a: list[float], b: list[float]) -> float:
a_arr, b_arr = np.array(a), np.array(b)
return float(np.dot(a_arr, b_arr) / (np.linalg.norm(a_arr) * np.linalg.norm(b_arr)))
async def semantic_cache_lookup(query: str, threshold: float = 0.92) -> str | None:
query_emb = await get_embedding(query)
for entry in cache:
similarity = cosine_similarity(query_emb, entry["embedding"])
if similarity >= threshold:
return entry["response"]
return None
Threshold — критичний параметр. При 0.85 кеш занадто агресивний: різні за змістом питання отримують одну відповідь. При 0.97 — майже не працює. Оптимальний діапазон для більшості доменів: 0.90–0.95, підбирається на реальних запитах.
Покрокове налаштування semantic cache
- Логування запитів користувачів у продакшені (мінімум 1000).
- Генерація embeddings на вибраній моделі (ми використовуємо text-embedding-3-small).
- Побудова векторного індексу: HNSW для швидкого пошуку.
- Підбір threshold на відкладеній вибірці: аналізуємо hit rate і якість.
- Розгортання middleware на серверній стороні.
- Моніторинг hit rate, економії та хибних спрацьовувань.
Чому threshold 0.92 — оптимальний старт?
При threshold 0.92 імовірність хибного спрацьовування мінімальна, а hit rate на типових питаннях досягає 40–60%. Менші значення дають більше збігів, але знижують якість відповідей. Більші — різко зменшують ефективність кешу. Ми завжди підбираємо точне значення на ваших логах, щоб баланс був оптимальним.
Коли семантичний кеш не працює?
Для динамічних даних — баланс користувача, статус замовлення, курси валют — кешування марне. Ми визначаємо такі запити класифікатором і виключаємо з кешу. Також кеш неефективний, якщо питання унікальні й не повторюються.
Redis vs pgvector: що вибрати
Redis із RediSearch у 3 рази швидший за pgvector для кешу до 50 тис. записів, але pgvector масштабується до мільйонів без втрати точності.
| Сховище |
Продуктивність (latency) |
Масштабування |
Складність налаштування |
| Redis + RediSearch |
1–5 мс для 50к записів |
Середнє (до 100к) |
Низька |
| pgvector (PostgreSQL) |
5–15 мс для 100к записів |
Високе (мільйони) |
Середня |
| Pinecone (managed) |
2–10 мс |
Дуже високе |
Низька |
| Embedding-модель |
Розмірність |
Ціна за 1K токенів |
Точність на нашому домені |
| text-embedding-3-small |
1536 |
$0.13 |
0.92 |
| text-embedding-3-large |
3072 |
$0.25 |
0.97 |
Для обчислення cosine similarity використовуємо стандартну формулу: косинус кута між векторами через скалярний добуток.
Інвалідація та TTL
Семантичний кеш потрібно інвалідувати при оновленні системного промпту або базової моделі — старі відповіді можуть не відповідати новій поведінці. Рекомендований TTL: 7–30 днів для стабільних FAQ-подібних питань. Для питань із часовою прив'язкою кешування не застосовуємо.
Що входить у роботу
- Архітектурна схема інтеграції semantic cache у мобільний додаток (iOS/Android).
- Налаштування генерації embeddings і вибір моделі (OpenAI, Cohere, SentenceTransformers).
- Підбір порогу схожості на основі ваших логів запитів.
- Реалізація middleware на серверній стороні (FastAPI, Node.js, Go).
- Моніторинг hit rate та економії.
- Документація та навчання команди.
Наш досвід включає 5+ впроваджень для додатків з аудиторією від 10k до 1M DAU. Ми гарантуємо hit rate не менше 40% на стабільних питаннях.
Типові помилки при впровадженні
- Вибір занадто низького threshold — кеш починає плутати семантично різні запити.
- Ігнорування інвалідації при зміні промпту — користувачі отримують застарілі відповіді.
- Відсутність fallback: при збої векторного пошуку запит має йти напряму до LLM.
- Невірний вибір векторного індексу (flat vs HNSW) під розмір кешу.
Орієнтири за строками
Базовий семантичний кеш на Redis + OpenAI Embeddings — 2–3 дні. З підбором threshold на реальних даних і моніторингом hit rate — 3–5 днів. Якщо потрібна інтеграція в існуючу мобільну інфраструктуру — зв'яжіться з нами для оцінки. Також замовте аудит поточних витрат на AI — ми розрахуємо потенційну економію та запропонуємо архітектуру під ваше навантаження. Отримайте консультацію інженера, який уже впроваджував такі рішення.
Джерело: Redis Stack documentation
Машинне навчання в мобільних застосунках: CoreML, TFLite та on-device LLM
Ми розрізняємо два принципово різних підходи: застосунок з on-device AI та застосунок, який просто викликає хмарне API. Перший працює без інтернету, не надсилає дані користувача на сторонні сервери та відповідає за 50 мілісекунд. Другий залежить від затримки мережі та тарифного плану. Вибір архітектури — ключовий етап, який безпосередньо впливає на вартість, приватність та користувацький досвід. Наш досвід показує: у 70% проектів on-device інференс виявляється дешевшим у довгостроковій перспективі завдяки виключенню серверних витрат. Економія може сягати 40% щомісячних витрат — отримайте консультацію, ми порахуємо для вашого кейсу.
Як вибрати між CoreML та TFLite для on-device інференсу?
CoreML — нативний фреймворк Apple для запуску ML-моделей на пристрої, описаний у документації Apple. Підтримує Neural Engine (A11 Bionic та новіші), GPU та CPU як fallback. Моделі конвертуються у формат .mlmodel через coremltools з PyTorch, ONNX або TensorFlow. Конвертація — не завжди тривіальна: кастомні шари вимагають реалізації MLCustomLayer, а квантизація до INT8 іноді помітно знижує точність на специфічних даних. Ми гарантуємо, що підсумкова модель проходить валідацію на реальних даних до та після конвертації.
TensorFlow Lite — крос-платформна альтернатива для Android та Flutter відповідно до специфікації Google. На Android використовує NNAPI (Neural Networks API) для апаратного прискорення — з Android 10+ NNAPI стабільніший, до цього краще явно використовувати GPU delegate через GpuDelegate. Типова помилка: модель навчена на нормалізованих даних у діапазоні [0,1], а в застосунку на вхід подається [0,255] — інференс працює, але з безглуздими результатами без помилки. Ми включаємо модуль автоматичної валідації вхідних даних у SDK.
Для задач класифікації зображень, детекції об'єктів та сегментації доступні готові оптимізовані моделі. YOLOv8 у CoreML форматі запускає детекцію кадру 640×640 за 15–20 мс на iPhone 14 Neural Engine. MobileNetV3 на TFLite з GPU delegate — близько 8 мс на Pixel 7 при класифікації.
| Параметр |
CoreML |
TFLite |
| Платформи |
iOS, macOS, watchOS |
Android, iOS, Linux, embedded |
| Апаратне прискорення |
Neural Engine, GPU, CPU |
NNAPI, GPU (OpenCL/OpenGL), CPU |
| Підтримка квантизації |
FP16, INT8 (з coremltools) |
FP16, INT8, dynamic range |
| Кастомні операції |
Через MLCustomLayer (Swift) |
Через делегати (Java/Kotlin) |
| Розмір бандла моделі |
~3–5 МБ (MobileNetV2 quantized) |
~2–4 МБ |
Що робити, якщо потрібна генерація тексту на пристрої?
Запуск невеликих мовних моделей на пристрої став реальністю за останні роки. Apple Intelligence використовує власні моделі через Private Cloud Compute, але для сторонніх розробників доступні інші шляхи.
llama.cpp з Metal backend на iOS — робочий підхід для phi-3-mini (3.8B параметрів, 4-bit квантизація, ~2.3 ГБ). Інференс: 15–25 токенів/секунду на iPhone 15 Pro. Для інтеграції в Swift використовуємо Swift Package llama.swift або обгортку через C-інтерфейс llama.h. Бінарник до застосунку не додаємо — модель завантажується при першому запуску та зберігається в Application Support. Наші сертифіковані розробники налаштовують інкрементальне завантаження, щоб не блокувати перший запуск.
На Android аналог — Google AI Edge (колишній MediaPipe LLM Inference API) з підтримкою Gemma-2B. Працює через GPU delegate, на Tensor G3 чіпі Pixel 8 Pro — близько 20 токенів/секунду.
Порівняння LLM моделей для on-device
| Модель |
Параметри |
Квантизація |
Розмір |
Швидкість (iPhone 15 Pro) |
| Phi-3-mini (Microsoft) |
3.8B |
4-bit |
~2.3 ГБ |
15-25 токенів/с |
| Gemma-2B (Google) |
2B |
4-bit |
~1.2 ГБ |
30-40 токенів/с |
| TinyLlama |
1.1B |
4-bit |
~0.7 ГБ |
60+ токенів/с |
Обмеження реальні: моделі більше 4B параметрів на мобільних пристроях все ще повільні. Для складних задач міркування on-device LLM поступається GPT-4o за якістю. Гібридний підхід — on-device для коротких завдань та приватних даних, хмара для складних запитів — часто оптимальний. Оцінимо ваш кейс та запропонуємо баланс продуктивності та приватності — напишіть нам.
Інтеграція OpenAI API та інших хмарних моделей
Для сценаріїв, де cloud inference допустимий, інтеграція OpenAI, Anthropic або Google Gemini — це HTTP клієнт + streaming SSE. У Swift зручно через AsyncThrowingStream для стрімінгових відповідей. У Kotlin — через Flow.
Критично важливо: API-ключі ніколи не зберігаються в бандлі застосунку. Навіть обфускований ключ витягується з IPA за 10 хвилин через strings або frida. Правильна архітектура: мобільний застосунок → власний backend → OpenAI API. Backend контролює rate limiting, логує запити, захищає ключ.
Що входить у роботу (результати)
- Навчена та квантизована модель під цільовий пристрій (документація за метриками)
- SDK для інтеграції (Swift/Kotlin/Flutter) з прикладами виклику
- Тести продуктивності на 3–5 реальних пристроях
- Інструкція з оновлення моделі OTA
- Підтримка при проходженні модерації App Store / Google Play (перевірка відповідності Guidelines 4.2, 5.1)
- 2 тижні технічної підтримки після релізу
Типовий пайплайн проекту
-
Аналіз завдання — вимірюємо latency, privacy, size, підтримувані пристрої.
-
Прототипування моделі — в Python, оцінка accuracy на цільових даних.
-
Конвертація та квантизація — під CoreML/TFLite з валідацією.
-
Інтеграція в застосунок — модель обгортається в сервісний шар (легко замінювати CoreML → TFLite → хмара).
-
Тестування — на реальних пристроях, вимір FPS, RAM, батареї.
-
Деплой — через TestFlight / Firebase App Distribution, моніторинг метрик.
Терміни: інтеграція готової CoreML/TFLite моделі — 1–2 тижні, розробка кастомної моделі з мобільною оптимізацією — від 6 тижнів, on-device LLM чат з персоналізацією — 4–8 тижнів.
Чому ми беремося за складні кейси?
10+ років досвіду в мобільній розробці, 50+ впроваджених AI/ML рішень, гарантія сумісності з актуальними версіями iOS та Android. Всі проекти проходять code review та навантажувальне тестування. У вартість вже входить підготовка документації для модерації та навчання вашої команди.
Зв'яжіться з нами — ми допоможемо вибрати архітектуру та впровадити ML у ваш застосунок під ключ. Замовте аудит наявного рішення — безкоштовно оцінимо потенціал економії серверних витрат. Отримайте консультацію експерта — напишіть нам сьогодні.