docs(architecture): document specialized Qwen2.5-0.5B + CTranslate2 fine-tuning architecture
This commit is contained in:
1 parent
7871191c90
commit
789960dc74
2 files changed
+110
No files matched your search
+15
@@ -161,3 +161,18 @@ CREATE TABLE IF NOT EXISTS user_grammar_weaknesses (
|
|||||||
- [ ] Оффлайн-кэширование аудио предложений в `data/audio_cache/` со сжатием в Opus и автоочисткой по TTL 7 дней (Zero Bloat).
|
- [ ] Оффлайн-кэширование аудио предложений в `data/audio_cache/` со сжатием в Opus и автоочисткой по TTL 7 дней (Zero Bloat).
|
||||||
- [ ] Фоновый экспорт главы в аудиокнигу для дороги и прогулок.
|
- [ ] Фоновый экспорт главы в аудиокнигу для дороги и прогулок.
|
||||||
- [ ] Интерактивный Shadowing (прослушивание $\rightarrow$ повтор в микрофон $\rightarrow$ клиентская проверка).
|
- [ ] Интерактивный Shadowing (прослушивание $\rightarrow$ повтор в микрофон $\rightarrow$ клиентская проверка).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Этап 8: 🧠 Специализированная микро-модель перевода (Qwen2.5-0.5B + CTranslate2)
|
||||||
|
- [ ] Полная архитектурная спецификация: `docs/architecture/specialized-translation-model.md`
|
||||||
|
- [ ] **Цель**: Разгрузить сервер, снизить задержку читалки до 100–150 мс и избавиться от сетевого оверхеда Ollama при чтении.
|
||||||
|
- [ ] **Разделение ролей**:
|
||||||
|
- Читалка (контекстный перевод предложений + целевое слово в JSON): `Qwen2.5-0.5B-Instruct` через CTranslate2 (in-process в Python, ~350 МБ RAM).
|
||||||
|
- Итоги урока (Debrief): `Qwen2.5-3B` on-demand (Ollama `keep_alive: 5m`) или детерминированный движок Мерфи.
|
||||||
|
- [ ] **Пайплайн реализации**:
|
||||||
|
- [ ] Сборка синтетического датасета `train.jsonl` (1500–3000 пар `(sentence, word, context, hints) -> JSON`).
|
||||||
|
- [ ] LoRA-дообучение на CPU VPS (AMD Ryzen 9 5950X, ~25–45 мин).
|
||||||
|
- [ ] Слияние и конвертация в CTranslate2 `int8` (`ct2-transformers-converter`).
|
||||||
|
- [ ] Прямая интеграция `ctranslate2.Generator` в `app/ai.py` с сохранением кэша SQLite.
|
||||||
|
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
# 🧠 Специализированная модель перевода и архитектура ИИ (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)
|
||||||
|
|
||||||
|
1. **Читалка книг (На лету)**:
|
||||||
|
- **Модель**: Дообученная `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"}`.
|
||||||
|
|
||||||
|
2. **Итоговый разбор урока (Debrief)**:
|
||||||
|
- **Модель**: `Qwen2.5-3B` через Ollama с параметром `keep_alive: "5m"` (подгружается по запросу раз в 20–30 минут, после чего выгружается из памяти).
|
||||||
|
- **Резерв**: Мгновенный детерминированный движок `generate_deterministic_debrief()` (0 мс, по формулам Мерфи).
|
||||||
|
|
||||||
|
3. **Синтез речи (Озвучка)**:
|
||||||
|
- **Движок**: Piper Neural TTS (ONNX VITS).
|
||||||
|
- **Статус**: 100% автономен, не зависит от LLM, задержка 20–40 мс.
|
||||||
|
|
||||||
|
4. **Генерация и проверка тестов**:
|
||||||
|
- **Принцип**: 100% алгоритмический детерминизм (каталог 142 юнитов Мерфи, алгоритм SM-2/FSRS в SRS, алгоритмический майнер предложений из книг). Нейросети к проверке тестов намеренно не привлекаются для исключения галлюцинаций.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚡ Преимущества CTranslate2 над HTTP-демоном Ollama
|
||||||
|
|
||||||
|
1. **In-Process инференс**: `import ctranslate2` прямо в бэкенде. Ноль оверхеда на сеть, TCP-сокеты и сериализацию между контейнерами.
|
||||||
|
2. **Низкоуровневая оптимизация**: Скомпилирован под AVX2 / FMA для AMD Ryzen.
|
||||||
|
3. **Квантование int8**: Минимальный расход RAM (~350 МБ) при сохранении 99% точности.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Пайплайн локального дообучения (Fine-Tuning) на VPS
|
||||||
|
|
||||||
|
Поскольку модель имеет всего ~490M параметров, её можно дообучить прямо на процессоре сервера без GPU:
|
||||||
|
|
||||||
|
### 1. Формат обучающего датасета (`train.jsonl`, 1500–3000 примеров)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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
|
||||||
|
```bash
|
||||||
|
# 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.
|
||||||
Reference in new issue
Block a user