Qwen3-TTS, DeepSeek-OCR2, Whisper, машинный перевод — разворачиваем, обучаем, тестируем и интегрируем
Учебное руководство | Февраль 2026 | Для студентов 2-го курсаНаша цель — создать локальную мультимодальную ИИ-платформу, которая умеет работать с голосом, текстом, изображениями и переводом. Это не один большой монолит, а экосистема специализированных моделей, каждая из которых делает своё дело лучше всех.
Мы строим инструменты, которые работают полностью локально — без интернета, без подписок, с полным контролем над данными. Это важно для образовательных учреждений, государственных организаций и медицинских центров Казахстана, где конфиденциальность данных и поддержка казахского языка критически важны.
Вот что наша платформа сможет делать когда будет готова:
| Параметр | Значение |
|---|---|
| Варианты моделей | 0.6B (Base, VoiceDesign, CustomVoice) и 1.7B (Base, CustomVoice) |
| Языки | Китайский, Английский, Японский, Корейский, Немецкий, Французский, Русский, Португальский, Испанский, Итальянский |
| Задержка | 97 мс (стриминг) — почти реальное время |
| Клонирование голоса | Zero-shot по 3-секундному образцу |
| VRAM (минимум) | ~4 ГБ (0.6B), ~8 ГБ (1.7B) |
| Архитектура | Discrete multi-codebook LM + Qwen3-TTS-Tokenizer-12Hz |
| Лицензия | Apache 2.0 (коммерческое использование) |
| Параметр | Значение |
|---|---|
| Всего параметров | ~3B (MoE), активных ~570M |
| Энкодер (DeepEncoder V2) | ~380M (SAM-base 80M + CLIP-large 300M) |
| Компрессия | 7-20x сжатие документа в визуальные токены |
| Точность | >96% при 10x компрессии |
| Формат вывода | Markdown с сохранением структуры |
| VRAM (минимум) | ~8-16 ГБ (зависит от размера изображений) |
| Пропускная способность | 200K+ страниц/день на A100 |
| Лицензия | MIT (коммерческое использование) |
| Параметр | Значение |
|---|---|
| Варианты | Tiny (39M), Base (74M), Small (244M), Medium (769M), Large-V3 (1.55B), Large-V3-Turbo (809M) |
| Казахский (kk) | WER ~32% из коробки. После дообучения — WER 14.5% (CER 3.39) |
| VRAM | ~2 ГБ (Small), ~5 ГБ (Large-V3-Turbo), ~10 ГБ (Large-V3) |
| Скорость | До 4.5x realtime с torch.compile |
| Формат ввода | Любой аудиоформат, чанки по 30 сек |
| Лицензия | MIT |
| Модель | Параметры | Языки | VRAM | Примечания |
|---|---|---|---|---|
| Qwen-MT | ~7B | 92 языка вкл. KZ | ~16 ГБ | Новейшая, $0.5/млн токенов через API |
| NLLB-200 (Meta) | 600M / 1.3B / 3.3B | 200 языков вкл. KZ | 2-8 ГБ | Проверенная, открытая, хорошая для KZ |
| Qwen3-8B (fine-tuned) | 8B | Настраиваемо | ~16 ГБ | Можно fine-tune под KZ↔RU |
| Madlad-400 (Google) | 3B / 7.5B / 10.7B | 400+ языков | 6-24 ГБ | Широкое покрытие, но менее точный для KZ |
Начните с NLLB-200-1.3B — она компактная (1.3B параметров, ~4 ГБ VRAM), отлично поддерживает казахский, и её легко дообучить на ваших данных. Если нужно выше качество — переходите на Qwen-MT или fine-tuned Qwen3.
| Модель | Задача | Мин. VRAM | Рек. VRAM | KZ поддержка | Готовность |
|---|---|---|---|---|---|
| Qwen3-TTS-0.6B | Голос | 4 ГБ | 8 ГБ | Нет, нужен fine-tune | Высокая |
| DeepSeek-OCR2 | OCR | 8 ГБ | 16 ГБ | Мультиязычный | Высокая |
| Whisper Large-V3-Turbo | Транскрибация | 5 ГБ | 8 ГБ | Есть, fine-tune улучшает | Высокая |
| NLLB-200-1.3B | Перевод KZ↔RU | 4 ГБ | 8 ГБ | Встроенная | Высокая |
| ВСЕ ВМЕСТЕ | 21 ГБ | 40 ГБ | |||
Запускать все модели одновременно на одном GPU не получится. Решение: загружать модели по запросу (одна модель в GPU, остальные ждут) или использовать 2-3 GPU, распределив модели между ними. Для студенческого проекта оптимален вариант «по запросу» с GPU 16-24 ГБ.
# Создаём окружение
conda create -n qwen3-tts python=3.12 -y
conda activate qwen3-tts
# Устанавливаем пакет
pip install -U qwen-tts
pip install -U flash-attn --no-build-isolation # ускорение + экономия VRAM
# Первый запуск — клонирование голоса
import torch, soundfile as sf
from qwen_tts import Qwen3TTSModel
model = Qwen3TTSModel.from_pretrained(
"Qwen/Qwen3-TTS-12Hz-0.6B-Base",
device_map="cuda:0",
dtype=torch.bfloat16,
attn_implementation="flash_attention_2",
)
# Генерация голоса (русский язык)
wavs, sr = model.generate_voice_clone(
text="Привет! Это тест генерации голоса на русском языке.",
language="Russian",
ref_audio="образец_голоса.wav", # 3+ секунд аудио
ref_text="Текст из образца аудио", # что говорится в образце
)
sf.write("output.wav", wavs[0], sr)
# Создаём окружение
conda create -n deepseek-ocr python=3.12.9 -y
conda activate deepseek-ocr
# Клонируем репозиторий
git clone https://github.com/deepseek-ai/DeepSeek-OCR-2.git
cd DeepSeek-OCR-2
# Устанавливаем зависимости (ВНИМАНИЕ: строгие версии!)
pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 \
--index-url https://download.pytorch.org/whl/cu118
pip install transformers==4.46.3 tokenizers==0.20.3
pip install flash-attn==2.7.3 --no-build-isolation
pip install -r requirements.txt
# Первый запуск
from transformers import AutoModel, AutoTokenizer
import torch
model_name = 'deepseek-ai/DeepSeek-OCR-2'
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModel.from_pretrained(
model_name,
_attn_implementation='flash_attention_2',
trust_remote_code=True, use_safetensors=True
).eval().cuda().to(torch.bfloat16)
# Распознавание документа → Markdown
res = model.infer(
tokenizer,
prompt="\n<|grounding|>Convert the document to markdown.",
image_file='ваш_документ.jpg',
output_path='./output/',
base_size=1024, image_size=768,
crop_mode=True, save_results=True
)
# Два варианта: стандартный и ускоренный
# Вариант 1: Стандартный (HuggingFace Transformers)
pip install transformers torch torchaudio
from transformers import pipeline
asr = pipeline(
"automatic-speech-recognition",
model="openai/whisper-large-v3-turbo", # Turbo — быстрее, меньше VRAM
torch_dtype=torch.float16,
device="cuda:0",
)
result = asr("лекция.mp3", generate_kwargs={"language": "kk", "task": "transcribe"})
print(result["text"])
# Вариант 2: faster-whisper (в 4-5 раз быстрее!)
pip install faster-whisper
from faster_whisper import WhisperModel
model = WhisperModel("large-v3-turbo", device="cuda", compute_type="float16")
segments, info = model.transcribe("лекция.mp3", language="kk", beam_size=5)
for segment in segments:
print(f"[{segment.start:.1f}s - {segment.end:.1f}s] {segment.text}")
# Вариант 3: Уже fine-tuned для казахского (сразу лучше!)
# Ищем на HuggingFace: Drahokma/whisper-large-v3-kz
pip install transformers sentencepiece
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
model_name = "facebook/nllb-200-distilled-1.3B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name).cuda()
# Перевод с казахского на русский
text = "Сәлеметсіз бе! Бұл қазақ тілінде жазылған мәтін."
tokenizer.src_lang = "kaz_Cyrl" # Казахский (кириллица)
inputs = tokenizer(text, return_tensors="pt").to("cuda")
translated = model.generate(
**inputs,
forced_bos_token_id=tokenizer.convert_tokens_to_ids("rus_Cyrl"),
max_length=512
)
result = tokenizer.decode(translated[0], skip_special_tokens=True)
print(result) # → Русский перевод
Модели развёрнуты — теперь нужны данные для дообучения. Это самая трудоёмкая часть, но от неё зависит всё.
| Модель | Тип данных | Формат | Минимальный объём | Источник |
|---|---|---|---|---|
| Whisper (KZ) | Аудио + транскрипция | WAV/MP3 + JSON/CSV | 5-50 часов аудио | Mozilla Common Voice 17.0 (kk) |
| Qwen3-TTS (KZ) | Текст + аудио | TXT + WAV (22kHz) | 10-50 часов чистого аудио | Запись носителей KZ |
| DeepSeek-OCR2 | Изображение + текст | PNG/JPG + Markdown | 1000+ пар | Сканы документов + разметка |
| NLLB / Перевод | Параллельные тексты | KZ↔RU пары в TSV/JSON | 50K+ пар предложений | OPUS, Tatoeba, гос. переводы |
# Загрузка Common Voice для казахского
from datasets import load_dataset, Audio
# Загружаем все доступные сплиты
dataset = load_dataset("mozilla-foundation/common_voice_17_0", "kk",
trust_remote_code=True)
# Объединяем train + validation для максимума данных
train_data = dataset["train"]
print(f"Обучающих примеров: {len(train_data)}")
print(f"Пример: {train_data[0]}")
# Ресемплинг до 16kHz (требование Whisper)
train_data = train_data.cast_column("audio", Audio(sampling_rate=16000))
# Предобработка: текст нормализация
import re
def normalize_kz(text):
text = text.strip().lower()
text = re.sub(r'[^\w\s]', '', text) # убираем пунктуацию
return text
train_data = train_data.map(lambda x: {"sentence": normalize_kz(x["sentence"])})
| Инструмент | Задача | Лицензия | Особенности |
|---|---|---|---|
| Label Studio | Универсальная разметка | Open Source | Аудио, изображения, текст. Веб-интерфейс. |
| Audacity | Разметка аудио | GPL | Ручная разметка сегментов речи |
| CVAT | Разметка изображений | MIT | Bounding boxes, полигоны для OCR |
| Argilla | Разметка текста (NLP) | Apache 2.0 | Идеально для пар перевода |
Это самый важный и хорошо задокументированный процесс. Google Colab с T4 GPU достаточно для обучения за ~5 часов.
from transformers import (
WhisperForConditionalGeneration, WhisperProcessor,
Seq2SeqTrainingArguments, Seq2SeqTrainer
)
# Загружаем модель и процессор
model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large-v3-turbo")
processor = WhisperProcessor.from_pretrained("openai/whisper-large-v3-turbo")
# Настраиваем для казахского
model.generation_config.language = "kk"
model.generation_config.task = "transcribe"
model.generation_config.forced_decoder_ids = None
# Параметры обучения
training_args = Seq2SeqTrainingArguments(
output_dir="./whisper-kz-finetuned",
per_device_train_batch_size=8, # Для 16GB GPU
gradient_accumulation_steps=2, # Эффективный batch = 16
learning_rate=1e-5,
warmup_steps=500,
max_steps=4000, # ~5 часов на T4
fp16=True, # Экономия памяти
evaluation_strategy="steps",
eval_steps=1000,
save_steps=1000,
logging_steps=100,
predict_with_generate=True,
generation_max_length=225,
gradient_checkpointing=True, # Экономия VRAM!
)
# Запуск!
trainer = Seq2SeqTrainer(
model=model,
args=training_args,
train_dataset=prepared_train,
eval_dataset=prepared_eval,
data_collator=data_collator,
compute_metrics=compute_wer,
tokenizer=processor,
)
trainer.train()
После 4000 шагов на Common Voice 17.0 (KZ): WER снижается с ~32% до ~14.5%, CER до 3.39. Это значит, что из каждых 100 слов модель ошибётся только в 14-15 — приемлемо для большинства задач.
Если GPU мало — используйте LoRA (Low-Rank Adaptation). Вместо изменения всех весов модели, дообучаются только маленькие «адаптеры» — в 10-100 раз меньше параметров.
from peft import LoraConfig, get_peft_model
lora_config = LoraConfig(
r=16, # Ранг: 8-64, выше = точнее, больше VRAM
lora_alpha=32,
target_modules=["q_proj", "v_proj"], # Обучаем только Q и V проекции
lora_dropout=0.05,
bias="none",
task_type="SEQ_2_SEQ_LM",
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Выведет: "trainable params: 3.9M || all params: 1.55B || trainable%: 0.25%"
# Обучаем только 0.25% параметров!
| Модель | Метрика | Что измеряет | Как считать |
|---|---|---|---|
| Whisper | WER (Word Error Rate) | % ошибочных слов | pip install jiwer |
| Whisper | CER (Character Error Rate) | % ошибочных символов | jiwer.cer(ref, hyp) |
| OCR | Edit Distance | Количество правок для совпадения | Levenshtein distance |
| OCR | Accuracy | % правильно распознанных символов | Посимвольное сравнение |
| TTS | MOS (Mean Opinion Score) | Субъективная оценка (1-5) | Опрос слушателей |
| TTS | WER на STT | Понятность: TTS → Whisper → сравнение | Round-trip test |
| Перевод | BLEU | Совпадение n-грамм с эталоном | sacrebleu |
| Перевод | COMET | Семантическая близость перевода | unbabel-comet |
from jiwer import wer, cer
import json
def evaluate_whisper(model, test_data):
"""Оценка fine-tuned Whisper на тестовом наборе"""
results = []
for sample in test_data:
prediction = model.transcribe(sample["audio"])["text"]
ground_truth = sample["text"]
results.append({
"wer": wer(ground_truth, prediction),
"cer": cer(ground_truth, prediction),
"prediction": prediction,
"ground_truth": ground_truth,
})
avg_wer = sum(r["wer"] for r in results) / len(results)
avg_cer = sum(r["cer"] for r in results) / len(results)
print(f"Средний WER: {avg_wer*100:.1f}%")
print(f"Средний CER: {avg_cer*100:.1f}%")
# Сохраняем для анализа ошибок
with open("eval_results.json", "w") as f:
json.dump(results, f, ensure_ascii=False, indent=2)
return avg_wer, avg_cer
| Тип БД | Решение | Зачем | Пример использования |
|---|---|---|---|
| Векторная | ChromaDB / Qdrant | Семантический поиск (RAG) | Поиск по содержимому документов |
| Реляционная | PostgreSQL / SQLite | Метаданные, пользователи, логи | История запросов, статистика |
| Документная | Файловая система + Markdown | Хранение OCR-результатов | Распознанные документы в .md |
| Кэш | Redis | Кэш запросов и результатов | Повторные переводы, транскрипции |
# Полный пайплайн: скан → OCR → эмбеддинг → векторная БД → поиск
import chromadb
from sentence_transformers import SentenceTransformer
# 1. OCR: изображение → Markdown текст
md_text = ocr_model.infer(tokenizer, prompt="...", image_file="doc.jpg")
# 2. Разбиваем на чанки
chunks = split_into_chunks(md_text, chunk_size=500, overlap=50)
# 3. Создаём эмбеддинги
embedder = SentenceTransformer("intfloat/multilingual-e5-base")
embeddings = embedder.encode(chunks)
# 4. Сохраняем в ChromaDB
client = chromadb.PersistentClient(path="./vectordb")
collection = client.get_or_create_collection("documents")
collection.add(
documents=chunks,
embeddings=embeddings.tolist(),
ids=[f"doc1_chunk_{i}" for i in range(len(chunks))],
metadatas=[{"source": "doc.jpg", "page": 1}] * len(chunks)
)
# 5. Поиск!
results = collection.query(query_texts=["бюджет на 2026 год"], n_results=3)
print(results["documents"])
Настройка GPU-серверов, установка CUDA/cuDNN, conda-окружения. Загрузка и тестовый запуск всех 4 моделей. Верификация работоспособности на примерах.
Загрузка Common Voice (KZ), OPUS корпусов. Разметка дополнительных данных в Label Studio. Сбор аудиозаписей носителей казахского. Подготовка параллельных корпусов KZ↔RU. Разделение на train/val/test (80/10/10).
Fine-tune Whisper на KZ (4000 шагов). LoRA-дообучение NLLB на KZ↔RU парах. Тестирование TTS на русском (KZ — будущая работа). Настройка OCR на казахских документах.
Вычисление WER/CER для Whisper. BLEU/COMET для перевода. MOS-опрос для TTS. Edit Distance для OCR. Анализ ошибок и итерация.
FastAPI-сервер с эндпойнтами. ChromaDB для документов. Gradio-интерфейс для демонстрации. Подготовка презентации для профессоров.
| День | Задача | Ответственные | Результат |
|---|---|---|---|
| 1-2 | Настройка GPU, CUDA, conda | Инфраструктурная команда | Работающее окружение |
| 3-4 | Установка всех 4 моделей | Все студенты | Все модели запускаются |
| 5-6 | Тестовые запуски, сбор baseline метрик | Все | Baseline WER, BLEU |
| 7-9 | Загрузка и подготовка датасетов | Команда данных | Готовые train/val/test сплиты |
| 10-11 | Развёртывание Label Studio, начало разметки | Команда данных | Размеченные примеры |
| 12-15 | Fine-tune Whisper на казахском | Команда ML | WER < 20% |
| 16-18 | LoRA дообучение NLLB, тесты TTS | Команда ML | Улучшенный перевод |
| 19-21 | Тестирование всех моделей, метрики | Команда QA | Отчёт с метриками |
| 22-25 | FastAPI + ChromaDB + интеграция | Команда Backend | Работающий API |
| 26-28 | Gradio-интерфейс, финальное тестирование | Команда Frontend | Демо-интерфейс |
| 29-30 | Подготовка презентации, документация | Все | Готовый продукт для профессоров! |