6.4 KiB
🧠 Специализированная модель перевода и архитектура ИИ (Qwen2.5-0.5B + CTranslate2)
Архитектурное решение по переходу на узкоспециализированную модель перевода для интерактивной читалки книг и разделению ролей ИИ в платформе Study Qpid Pro (study.qpid.pro).
🎯 Архитектурный выбор: Qwen2.5-0.5B-Instruct vs MarianMT (Helsinki-NLP)
Исследованы два класса узких моделей для локального размещения на сервере (AMD Ryzen 9 5950X, 6 vCPU, без GPU, ~7.6 GB RAM доступно):
| Критерий | Helsinki-NLP/opus-mt-en-ru (77M) | Qwen2.5-0.5B-Instruct (~490M) |
|---|---|---|
| Архитектура | Seq2Seq (Encoder-Decoder) | Causal LLM (Decoder-only) |
| Выходной формат | Только сплошной текст | Строгий JSON (sentence_ru + word_meaning) |
| Выделение значения слова | Требует внешнего aligner / словаря | Выделяет контекстное значение напрямую |
| Поддержка контекста абзаца | Слабая (обучена по предложениям) | Отличная (учитывает промпт и контекст) |
| Инференс на CPU (CTranslate2) | 10–20 мс | 100–150 мс |
| Потребление RAM | ~150 МБ | ~350–400 МБ |
Выбор: Qwen2.5-0.5B-Instruct с дообучением под задачу контекстного перевода предложений и извлечения целевых слов в структурированный JSON.
🏗️ Разделение ответственности компонентов (Clean Separation of Concerns)
-
Читалка книг (На лету):
- Модель: Дообученная
Qwen2.5-0.5B-Instruct. - Движок: CTranslate2 (
int8), загруженный in-process прямо в Python-память FastAPI (app/ai.py). - Задержка: ~100–150 мс (без оверхеда на HTTP/сокеты/Docker).
- Задача:
(sentence, target_word, context, dict_hints) -> JSON {"sentence_ru", "word_meaning"}.
- Модель: Дообученная
-
Итоговый разбор урока (Debrief):
- Модель:
Qwen2.5-3Bчерез Ollama с параметромkeep_alive: "5m"(подгружается по запросу раз в 20–30 минут, после чего выгружается из памяти). - Резерв: Мгновенный детерминированный движок
generate_deterministic_debrief()(0 мс, по формулам Мерфи).
- Модель:
-
Синтез речи (Озвучка):
- Движок: Piper Neural TTS (ONNX VITS).
- Статус: 100% автономен, не зависит от LLM, задержка 20–40 мс.
-
Генерация и проверка тестов:
- Принцип: 100% алгоритмический детерминизм (каталог 142 юнитов Мерфи, алгоритм SM-2/FSRS в SRS, алгоритмический майнер предложений из книг). Нейросети к проверке тестов намеренно не привлекаются для исключения галлюцинаций.
⚡ Преимущества CTranslate2 над HTTP-демоном Ollama
- In-Process инференс:
import ctranslate2прямо в бэкенде. Ноль оверхеда на сеть, TCP-сокеты и сериализацию между контейнерами. - Низкоуровневая оптимизация: Скомпилирован под AVX2 / FMA для AMD Ryzen.
- Квантование int8: Минимальный расход RAM (~350 МБ) при сохранении 99% точности.
🛠️ Пайплайн локального дообучения (Fine-Tuning) на VPS
Поскольку модель имеет всего ~490M параметров, её можно дообучить прямо на процессоре сервера без GPU:
1. Формат обучающего датасета (train.jsonl, 1500–3000 примеров)
{
"messages": [
{
"role": "system",
"content": "Ты — переводчик художественной литературы. Переведи указанное предложение и выдели значение целевого слова. Ответь строго JSON: {\"sentence_ru\": \"...\", \"word_meaning\": \"...\"}"
},
{
"role": "user",
"content": "Контекст абзаца: Mr. Dursley stopped dead. Fear flooded him.\nПредложение: He stared at the people in cloaks.\nЦелевое слово: cloaks\nСловарные подсказки: cloak — плащ, мантия"
},
{
"role": "assistant",
"content": "{\"sentence_ru\": \"Он уставился на людей в мантиях.\", \"word_meaning\": \"мантиях\"}"
}
]
}
2. Дообучение через PyTorch CPU + PEFT (LoRA)
- Инструменты:
torch (cpu),transformers,peft,trl. - Параметры:
r=16,lora_alpha=32,target_modules=["q_proj", "k_proj", "v_proj", "o_proj"]. - Время обучения на 6 ядрах Ryzen 9 5950X: ~25–45 минут.
- Расход RAM в процессе: ~3.5–4.5 ГБ (на сервере доступно ~7.6 ГБ).
3. Конвертация в CTranslate2
# 1. Слияние адаптера LoRA с базовой моделью:
python3 merge_lora.py --base Qwen/Qwen2.5-0.5B-Instruct --adapter ./final_adapter --output ./qwen-0.5b-merged
# 2. Конвертация в int8 CTranslate2 модель:
ct2-transformers-converter --model ./qwen-0.5b-merged \
--output_dir /home/ai-projects/services/study.qpid.pro/models/qwen05b-ct2 \
--quantization int8
4. Подключение в app/ai.py
Заменяем сетевой HTTP-клиент к Ollama для читалки на прямой вызов ctranslate2.Generator, сохранив кэширование SQLite.