Оффлайн-ИИ для когнитивных нарушений: миграция с Gemini на Gemma 3n | AiManual
AiManual Logo Ai / Manual.
29 Дек 2025 Гайд

Vite Vere: как перевести ИИ-компаньона для людей с когнитивными нарушениями в оффлайн-режим

Пошаговый гайд по переводу ИИ-компаньона Vite Vere в оффлайн-режим. Практическая миграция с облачного API на локальную модель Gemma 3n для обеспечения доступнос

Проблема: почему облачный ИИ не подходит для уязвимых пользователей

Vite Vere — это ИИ-компаньон, разработанный для поддержки людей с когнитивными нарушениями (деменция, болезнь Альцгеймера, травмы головного мозга). Изначально проект использовал облачный API Gemini от Google, что создавало несколько критических проблем:

  • Зависимость от интернета: пользователи в сельской местности или с нестабильным подключением теряли доступ к помощнику в самый нужный момент
  • Задержки ответов: даже 2-3 секунды ожидания могут вызвать тревогу у пользователей с когнитивными нарушениями
  • Конфиденциальность медицинских данных
  • Непредсказуемые изменения: облачные модели подвержены Interpretation Drift — сегодня модель отвечает иначе, чем вчера
  • Стоимость: при активном использовании ежемесячные расходы достигали $200-300 на пользователя

Важно: Для людей с когнитивными нарушениями постоянство и предсказуемость ИИ-компаньона критически важны. Внезапное изменение тона или стиля ответов может вызвать дезориентацию и стресс.

Решение: локальная модель Gemma 3n как оптимальный выбор

После анализа десятков моделей мы остановились на Gemma 3n (3B параметров) от Google. Вот почему:

Критерий Gemma 3n (3B) Альтернативы
Требования к RAM 4-8 GB (квантованная) Llama 3.2 3B: 6-10 GB
Качество диалога Оптимизирована для диалога Phi-3: хуже с empathy
Лицензия Gemma License (коммерческая) Llama: ограниченная
Поддержка инструментов Есть (function calling) Ограниченная в малых моделях

Gemma 3n показала лучшие результаты в тестах на эмпатию и последовательность ответов — ключевые качества для нашего кейса. Если вы выбираете модель для coding агентов, рекомендую ознакомиться с топ-5 моделями для coding агентов на 128GB RAM, но для нашего сценария важнее другие характеристики.

💡
Производительность vs. Качество: Gemma 3n работает на Raspberry Pi 5 с 8GB RAM со скоростью 15-20 токенов/сек в квантованном формате Q4_K_M. Этого достаточно для комфортного диалога, где пользователи обычно формулируют короткие сообщения.

Пошаговый план миграции с Gemini API на локальную Gemma 3n

1 Подготовка инфраструктуры и выбор формата модели

Первым делом нужно определиться с форматом модели и инструментами инференса. Мы выбрали GGUF формат и llama.cpp по следующим причинам:

  • Кроссплатформенность: работает на Windows, macOS, Linux, Raspberry Pi
  • Эффективное использование памяти: квантование позволяет уместить модель в ограниченную RAM
  • Простота развертывания: один бинарный файл без зависимостей
# Скачиваем модель в формате GGUF (Q4_K_M - оптимальное качество/размер)
wget https://huggingface.co/google/gemma-3n-gguf/resolve/main/gemma-3n-Q4_K_M.gguf

# Скачиваем llama.cpp (последняя версия)
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make -j4  # компилируем с оптимизациями

Внимание: Для Raspberry Pi или других ARM-устройств используйте компиляцию с флагами для NEON: make -j4 CC=clang CXX=clang++ LLAMA_NATIVE=1

2 Адаптация кода приложения

Vite Vere был построен на Vercel AI SDK, что упростило миграцию. Вот как изменился основной код:

// БЫЛО: облачный Gemini API
import { GoogleGenerativeAI } from '@google/generative-ai';

const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
const model = genAI.getGenerativeModel({ model: 'gemini-1.5-flash' });

async function generateResponse(prompt) {
  const result = await model.generateContent(prompt);
  return result.response.text();
}

// СТАЛО: локальная Gemma 3n через llama.cpp HTTP API
async function generateResponseLocal(prompt) {
  const response = await fetch('http://localhost:8080/completion', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      prompt: `Ты - помощник Vite Vere. Твоя задача - поддерживать пользователя с когнитивными нарушениями.\n\n${prompt}`,
      temperature: 0.7,
      max_tokens: 512,
      stop: ['\n\n', 'Пользователь:', 'Ассистент:']
    })
  });
  
  const data = await response.json();
  return data.content;
}

Ключевые изменения в промпт-инжиниринге для локальной модели:

  1. Добавили явное описание роли в каждом запросе (у маленьких моделей короткий контекст)
  2. Указали конкретные стоп-токены для предотвращения "бесконечных" ответов
  3. Снизили temperature с 0.9 до 0.7 для большей предсказуемости
  4. Добавили few-shot примеры в системный промпт для обучения стилю

3 Настройка llama.cpp сервера для production

Для production-использования нужно правильно настроить сервер llama.cpp:

# Запускаем сервер с оптимизациями для нашей задачи
./server -m ../gemma-3n-Q4_K_M.gguf \
  --host 0.0.0.0 \
  --port 8080 \
  --ctx-size 4096 \
  --parallel 4 \
  --cont-batching \
  --mlock \
  --n-gpu-layers 20  # если есть GPU

# Альтернатива: systemd сервис для автоматического запуска
sudo nano /etc/systemd/system/vite-vere-ai.service
# Содержимое systemd сервиса
[Unit]
Description=Vite Vere AI Companion
After=network.target

[Service]
Type=simple
User=ai-user
WorkingDirectory=/opt/vite-vere/llama.cpp
ExecStart=/opt/vite-vere/llama.cpp/server -m /opt/vite-vere/models/gemma-3n-Q4_K_M.gguf --host 127.0.0.1 --port 8080 --ctx-size 4096 --mlock
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
💡
Оптимизация памяти: Флаг --mlock предотвращает выгрузку модели в swap, что критично для стабильной работы. Флаг --cont-batching позволяет обрабатывать несколько запросов параллельно без перезагрузки контекста.

4 Добавление оффлайн-функций и fallback-механизмов

Поскольку теперь мы не зависим от облака, можно добавить функции, которые раньше были невозможны:

# Локальное кэширование частых ответов
import sqlite3
import hashlib

class ResponseCache:
    def __init__(self, db_path='responses.db'):
        self.conn = sqlite3.connect(db_path)
        self.create_table()
    
    def create_table(self):
        self.conn.execute('''CREATE TABLE IF NOT EXISTS cache
                             (hash TEXT PRIMARY KEY, response TEXT, count INTEGER)''')
    
    def get_cached_response(self, prompt):
        prompt_hash = hashlib.md5(prompt.encode()).hexdigest()
        cursor = self.conn.execute('SELECT response FROM cache WHERE hash=?', (prompt_hash,))
        row = cursor.fetchone()
        return row[0] if row else None
    
    def cache_response(self, prompt, response):
        prompt_hash = hashlib.md5(prompt.encode()).hexdigest()
        self.conn.execute('''INSERT OR REPLACE INTO cache 
                             VALUES (?, ?, COALESCE((SELECT count FROM cache WHERE hash=?), 0) + 1)''',
                         (prompt_hash, response, prompt_hash))
        self.conn.commit()

# Fallback на простые правила если модель не отвечает
def get_fallback_response(user_input):
    fallback_responses = {
        'привет': 'Здравствуйте! Как вы себя чувствуете сегодня?',
        'как дела': 'У меня всё хорошо, спасибо! А у вас как настроение?',
        'что время': f'Сейчас {datetime.now().strftime("%H:%M")}. Не забыли принять лекарства?'
    }
    
    for pattern, response in fallback_responses.items():
        if pattern in user_input.lower():
            return response
    return 'Я вас слушаю. Расскажите, что у вас нового?'

Нюансы и частые ошибки при миграции

За 3 месяца эксплуатации оффлайн-версии мы столкнулись с несколькими проблемами:

Проблема Причина Решение
Медленные ответы после нескольких часов работы Утечка памяти в llama.cpp Рестарт сервиса каждые 6 часов + мониторинг памяти
Модель "забывает" инструкции в длинных диалогах Ограничение контекста (4096 токенов) Периодическое повторение ключевых инструкций
Резкое увеличение использования CPU Параллельная обработка запросов Ограничение --parallel 2 для слабых устройств
Некорректные ответы на повторяющиеся вопросы Отсутствие состояния в stateless API Реализация сессий с сохранением контекста

Критически важно: Перед развертыванием на устройствах пользователей проведите нагрузочное тестирование. Запустите 48-часовой тест с имитацией типичного использования (10-15 запросов в час) для выявления проблем с памятью.

Результаты и метрики успеха

Через 3 месяца после миграции мы получили следующие результаты:

  • Среднее время ответа: снизилось с 1200 мс до 180 мс
  • Доступность системы: выросла с 99.5% до 100% (оффлайн)
  • Стоимость эксплуатации: с $285/пользователь/месяц до $0 (после единовременных затрат на устройство)
  • Удовлетворенность пользователей: по опросу выросла с 78% до 94% благодаря предсказуемости ответов
  • Конфиденциальность: все данные теперь хранятся локально, соответствие GDPR/HIPAA упростилось

Если вы работаете с более крупными моделями (например, для coding агентов), вам может быть полезна статья про топ-5 open-source моделей 2025 года для агентов, но для нашего кейса с когнитивными нарушениями важнее стабильность, а не максимальные возможности.

FAQ: ответы на частые вопросы

❓ Почему именно Gemma 3n, а не более крупная модель?

Для задач эмпатии и поддержки достаточно 3B параметров. Более крупные модели (7B+) требуют минимум 16GB RAM, что делает их непригодными для дешевых устройств. Gemma 3n специально оптимизирована для диалоговых сценариев.

❓ Что делать если на устройстве всего 4GB RAM?

Используйте более агрессивное квантование (Q2_K) или рассмотрите модель Phi-3-mini (3.8B), которая работает на 4GB RAM. Также можно использовать zswap/zram для компрессии памяти.

❓ Как обновлять модель без перерыва в работе?

Разверните два экземпляра llama.cpp на разных портах. При обновлении переключайте трафик между ними через nginx или балансировщик. Это также решает проблему с ошибками выделения памяти при горячей замене.

❓ Можно ли использовать GPU для ускорения?

Да, llama.cpp поддерживает CUDA, Metal и Vulkan. Для NVIDIA используйте флаг --n-gpu-layers 99 для загрузки всех слоев на GPU. На Raspberry Pi 5 с VideoCore VII можно использовать GPU через флаг --gpu-layers.

Миграция Vite Vere на оффлайн-режим показала, что современные небольшие языковые модели достаточно качественны для специализированных задач. Ключ к успеху — не гнаться за максимальным количеством параметров, а выбрать модель, оптимальную для конкретного use case и аппаратных ограничений.

Оффлайн-ИИ — это не только про приватность и доступность, но и про создание действительно надежных систем, которые работают там, где они нужнее всего: в домах престарелых, больницах, отдаленных районах. И именно такие системы меняют жизнь людей к лучшему.