AAYMA
RU
Войти

Tuyin

Полностью локальное автопротоколирование совещаний: распознаёт русскую, казахскую и смешанную речь, разделяет спикеров, формирует саммари и…

Рабочий MVP
Команда «LinguaCap» 6💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: LinguaCap
Кейс HackAlem.ai: Инновации — Самрук-Казына
Стадия: Рабочий MVP

Задача кейса: «Хаттама»: протокол и поручения по аудиозаписи совещания (каз./рус./смешанная речь)

Суть

Полностью локальное автопротоколирование совещаний: распознаёт русскую, казахскую и смешанную речь, разделяет спикеров, формирует саммари и поручения с возможностью редактирования и экспортом в DOCX/PDF.

Как устроено

Next.js UI обращается к локальному FastAPI ASR-сервису. Конвейер: FFmpeg нормализация → VAD и нарезка → ASR-модель asr/rukk (NeMo) для RU/KK/mixed → диаризация pyannote/speaker-diarization-community-1 → саммари и поручения через qwen3:4b в Ollama. Транскрипты и протоколы хранятся в SQLite, поручения без ответственного или срока помечаются предупреждениями. Все компоненты слушают только 127.0.0.1, облачные AI не используются.

Ключевые решения

  • VAD
  • NeMo ASR
  • pyannote диаризация
  • извлечение поручений LLM
  • сравнение с эталонными протоколами (покрытие слов)
  • экспорт DOCX/PDF

Метрики

Совещание №1: покрытие слов 72.5% (RU 73.1%), 4 из 10 поручений; Совещание №2: 85.2% (RU 86.2%), 2 из 6 поручений

Особенности

Закрытый контур без облака, а также честная оценка: эталоны не содержат казахских букв, поэтому качество на KK и смешанной речи не подтверждено. В README есть обзор кандидатов для KK/RU code-switching (KRASR Whisper, XLS-R, ISSAI) и скрипт сравнения протоколов.

Стек

Next.js · TypeScript · Python · FastAPI · NeMo · pyannote · FFmpeg · Ollama · SQLite · pytest

Модели

asr/rukk (RU/KK ASR) · pyannote/speaker-diarization-community-1 · qwen3:4b (Ollama)


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-746f3d4a-linguacap.

README

README.md

Tuyin — локальное автопротоколирование совещаний

Tuyin превращает аудиозапись совещания в структурированный протокол на компьютере пользователя. Система распознаёт русскую, казахскую и смешанную речь, выделяет спикеров, формирует саммари и поручения, позволяет отредактировать результат и выгрузить его в DOCX или PDF.

Аудио, транскрипт и протокол не передаются в облачный AI-сервис: рабочие компоненты взаимодействуют только через 127.0.0.1.

Возможности

  • Загрузка MP3, WAV, M4A и MP4 до 1 GiB.
  • Локальная подготовка аудио: нормализация, VAD и нарезка речевых фрагментов.
  • Распознавание русско-казахской речи моделью asr/rukk.
  • Локальная диаризация pyannote/speaker-diarization-community-1.
  • Саммари и поручения через локальный qwen3:4b в Ollama.
  • Редактирование реплик, спикеров, поручений, ответственных и сроков.
  • Предупреждения о поручениях без ответственного или срока.
  • Сохранение транскриптов и протоколов в локальной SQLite-базе.
  • Экспорт текущего протокола в DOCX и PDF.

Архитектура

Браузер
  ↓ 127.0.0.1:3000
Next.js
  ↓ 127.0.0.1:8000
FastAPI ASR-сервис
  ↓
FFmpeg → VAD → rukk ASR → pyannote → Ollama qwen3:4b
  ↓
SQLite / DOCX / PDF

Требования

  • macOS на Apple Silicon;
  • Node.js 20+;
  • Python 3.13 для базового ASR-сервиса;
  • Python 3.12 для полного окружения с NeMo и pyannote;
  • FFmpeg 9+;
  • Ollama с qwen3:4b — для саммари и поручений.

Установите FFmpeg, если он ещё недоступен в PATH:

brew install ffmpeg

Быстрый запуск

1. Интерфейс

В корне репозитория:

npm install
cp .env.example .env.local

2. Базовый ASR-сервис

cd services/asr
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
set -a; source .env; set +a
python -m app.model_download
cd ../..

Команда скачивает веса asr/rukk в services/asr/models/asr/rukk/. Загрузка выполняется один раз; после неё распознавание может работать без интернета.

3. Локальная LLM для саммари и поручений

Установите и запустите Ollama, затем загрузите модель:

ollama pull qwen3:4b

В services/asr/.env задайте:

ASR_LOCAL_LLM_PROVIDER=ollama
ASR_LOCAL_LLM_BASE_URL=http://127.0.0.1:11434
ASR_LOCAL_LLM_MODEL=qwen3:4b
ASR_LOCAL_LLM_TIMEOUT_SECONDS=180

Перед запуском ASR в этом же терминале заново экспортируйте значения из файла:

cd services/asr
set -a; source .env; set +a
cd ../..

Более мощные и специализированные модели

Текущая конфигурация выбрана для локальной работы на текущем устройстве: qwen3:4b для протокола и asr/rukk для распознавания. Модели крупнее или специализированнее не проверялись на этом устройстве из-за ограничений памяти и вычислительной мощности. Их следует считать кандидатами для отдельного сравнения, а не гарантированным улучшением качества.

Модель для саммари и поручений

LLM меняется без кода: укажите её тег в ASR_LOCAL_LLM_MODEL, перезапустите ASR-сервис и заново сформируйте протокол. Qwen3 в Ollama поддерживает многоязычные инструкции, в том числе русский и казахский, поэтому это наиболее прямой путь к повышению качества структуры протокола.

Модель OllamaРазмер загружаемых весовКогда пробовать
qwen3:4bоколо 2.5 GBТекущая экономичная конфигурация.
qwen3:8bоколо 5.2 GBПервый кандидат для более точного саммари и извлечения поручений.
qwen3:14bоколо 9.3 GBПодходит для компьютера с заметным запасом объединённой памяти.
qwen3:30bоколо 19 GBПрактичнее запускать на более мощном Mac или GPU-сервере.

Например, для проверки qwen3:8b:

ollama pull qwen3:8b
# в services/asr/.env
ASR_LOCAL_LLM_MODEL=qwen3:8b

Размер файла модели не равен точному потреблению памяти во время работы: контекст транскрипта, Ollama и ASR также занимают память. При нехватке памяти начинайте с qwen3:8b, сокращайте параллельность до одного задания и проверяйте время обработки на короткой записи.

Модели для казахской, русской и смешанной речи

asr/rukk — удобный локальный выбор для code-switching: его model card заявляет одну модель для казахской, русской и смешанной речи. Для совещаний, где почти вся речь на одном языке, у того же набора есть отдельные модели asr/kk и asr/ru; они меньше, но обучены на одном языке и могут быть полезны как базовая линия сравнения.

Следующие варианты требуют нового ASR-адаптера в проекте: интерфейс должен сохранить контракт WAV 16 kHz → текст сегмента, временные метки и локальное выполнение. Они не переключаются одной переменной окружения.

КандидатДля чегоОсобенности
KRASR/kazakh-russian-asr-whisper-small-full-ftКазахская речь с русскими словами и короткими фразамиПолностью дообученный Whisper Small для KK/RU и mixed speech; доступен через transformers.
KRASR/kazakh-russian-asr-whisper-large-v3-loraБолее сильный вариант для KK/RU code-switchingКрупная база Whisper Large-v3 с LoRA; ожидать существенно более высокие требования к памяти.
KRASR/kazakh-russian-asr-xls-r-1b-ctcАльтернатива Whisper для KK/RU и смешанной речиМодель класса XLS-R 1B; целесообразна для GPU или мощного Mac.
openai/whisper-large-v3-turboШирокая многоязычная базовая линия0.8B-параметровая модель для 99 языков; не специализирована именно под казахско-русский микс, поэтому нужна проверка на собственных записях.

У ISSAI есть также Persona-ASR: модель целевого спикера для перекрывающейся казахско-английской речи. Она требует короткую enrollment-реплику нужного человека и не является заменой обычному KK/RU распознаванию совещания. Её стоит рассматривать для отдельного сценария «выделить одного известного спикера», а не для текущего конвейера.

Для обучения или дообучения на казахской речи полезен ISSAI Kazakh Speech Corpus 2. Это датасет, а не готовая модель: его нельзя подключить к сервису без обучения и отдельной оценки лицензии, согласий и распределения речи.

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

Для любого кандидата сохраняйте закрытый контур: скачать веса один раз, затем запускать inference локально; не передавать аудио внешнему API. Перед заменой основной модели проверьте RU, KK, смешанную речь, имена, даты и поручения на размеченном эталоне.

4. Диаризация спикеров — дополнительная настройка

Для разделения нескольких спикеров выполните:

cd services/asr
make install-nemo
make install-diarization
.venv-nemo/bin/hf auth login
.venv-nemo/bin/python -m app.model_download pyannote

Подробнее о лицензии и конфигурации — в README ASR-сервиса.

5. Запуск

В двух терминалах из корня проекта:

# Терминал 1: базовый ASR
npm run dev:asr
# Терминал 1 при установленной диаризации
npm run dev:asr:full
# Терминал 2: интерфейс
npm run dev

Откройте http://127.0.0.1:3000. Для быстрой проверки запущенных процессов:

curl http://127.0.0.1:8000/health
curl http://127.0.0.1:3000/api/asr/health

Оба ответа должны содержать "status":"ok".

Как работать с записью

  1. Откройте приложение и выберите аудиофайл.
  2. Подтвердите уведомление участников и запустите обработку.
  3. В «Транскрипте» исправьте реплики и при необходимости переименуйте спикеров.
  4. На вкладке «Саммари» или «Поручения» запустите локальный анализ.
  5. Уточните поручения, ответственных и сроки; предупреждения отмечают пустые обязательные поля.
  6. Скачайте DOCX или PDF на вкладке «Экспорт».

Изменение реплики сбрасывает саммари и поручения: сформируйте их повторно, чтобы ссылки на исходные сегменты оставались корректными.

Результаты проверки на записях проекта

Локальное сравнение с эталонными DOCX дало следующие результаты:

ЗаписьЭталонных словТочное покрытиеRU-покрытиеСопоставлено поручений
Совещание №168572.5%73.1%4 из 10
Совещание №254185.2%86.2%2 из 6

Полная сводка без текста записей — в отчёте качества. Оба эталонных документа не содержат слов с уникальными казахскими буквами, поэтому они не являются валидной проверкой качества чистой казахской или смешанной речи. Для такой оценки нужен отдельный размеченный KK/RU эталон.

Запустить сравнение для своих сохранённых результатов можно локально:

services/asr/.venv-nemo/bin/python services/asr/scripts/compare_protocols.py \
  --store services/asr/runtime/protocols.sqlite3 \
  --case 'Совещание №1::<job-id>::ТЗ/Протокол_совещания№1.docx' \
  --case 'Совещание №2::<job-id>::ТЗ/Протокол_совещания№2.docx' \
  --public-report docs/quality/quality-comparison-YYYY-MM-DD.md \
  --private-report services/asr/runtime/quality/quality-comparison-YYYY-MM-DD.json

Markdown-отчёт содержит только агрегаты. Ограниченный список пар «ожидалось/распознано» с временными метками остаётся в локальном runtime-каталоге и исключён из Git.

Приватность

  • Next.js, FastAPI и Ollama принимают только loopback-подключения.
  • Внешние AI-маршруты отключены; телеметрия Next.js выключена.
  • В технических журналах нет аудио, имени файла, транскрипта или протокола.
  • Исходный файл, WAV и фрагменты удаляются после обработки.
  • Транскрипт и протокол хранятся локально в services/asr/runtime/protocols.sqlite3.
  • DELETE /jobs/<id> очищает запись из SQLite и временную рабочую папку.
  • DOCX/PDF создаются в памяти сервиса; скачанный браузером файл контролируется пользователем.

Ограничения: SQLite не шифруется сама по себе, а удаление не очищает резервные копии или snapshots файловой системы. Полный разбор модели угроз — в аудите приватности.

Проверки для разработки

services/asr/.venv-nemo/bin/python -m pytest services/asr/tests -q
npm run lint
npm run typecheck
npm run build

Последний локальный запуск: 29 backend-тестов, ESLint, TypeScript и production build прошли успешно.

Структура проекта

app/                  Next.js API-маршруты
components/           интерфейс загрузки, транскрипта и протокола
services/asr/app/     FastAPI, ASR, диаризация, SQLite и экспорт
services/asr/scripts/ локальные утилиты сравнения качества
docs/audits/          аудит приватности
docs/quality/         обезличенные сводки проверок
Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
8
Авторы
1
Файлы
87
Ветки
1

Авторы коммитов

nurdax 8

История коммитов

  • 2026-09-23 17:57Ignore local meeting demo artifactsnurdax
  • 2026-09-23 17:40Refresh Tuyin branding and exportsnurdax
  • 2026-09-23 17:24Add local protocol export and quality checksnurdax
  • 2026-09-23 16:42Persist meeting transcripts and actionsnurdax
  • 2026-09-23 15:56Add meeting analysis resultsnurdax
  • 2026-09-23 15:23Add local ASR processing workflownurdax
  • 2026-09-23 14:43Add NeMo transcription and diarizationnurdax
  • 2026-09-23 14:14Initial project importnurdax
Структура репозитория (87 файлов)
.env.example
.gitignore
AGENTS.md
CLAUDE.md
README.md
app/api/ai/route.ts
app/api/analyze/route.ts
app/api/asr/health/route.ts
app/api/asr/jobs/[jobId]/actions/[actionIndex]/route.ts
app/api/asr/jobs/[jobId]/analysis/route.ts
app/api/asr/jobs/[jobId]/export/[format]/route.ts
app/api/asr/jobs/[jobId]/result/route.ts
app/api/asr/jobs/[jobId]/route.ts
app/api/asr/jobs/[jobId]/segments/[segmentId]/route.ts
app/api/asr/jobs/[jobId]/speakers/[speakerId]/route.ts
app/api/asr/transcribe/route.ts
app/api/health/route.ts
app/demo/page.tsx
app/globals.css
app/layout.tsx
app/page.tsx
components.json
components/ai/ai-loading.tsx
components/ai/ai-result.tsx
components/ai/ai-workspace.tsx
components/ai/example-prompts.tsx
components/ai/file-upload.tsx
components/ai/prompt-input.tsx
components/ai/theme-toggle.tsx
components/protocol/processing-result.tsx
components/protocol/recording-upload.tsx
components/protocol/service-status.tsx
components/ui/button.tsx
components/ui/card.tsx
components/ui/textarea.tsx
docs/audits/privacy-audit-2026-09-23.md
docs/quality/quality-comparison-2026-09-23.md
eslint.config.mjs
lib/local-asr.ts
lib/request-log.ts
lib/schemas.ts
lib/utils.ts
next-env.d.ts
next.config.ts
package-lock.json
package.json
postcss.config.mjs
prompts/analyze.ts
prompts/system.ts
public/favicon.svg
pytest.ini
services/asr/.env.example
services/asr/.python-version
services/asr/Makefile
services/asr/README.md
services/asr/app/__init__.py
services/asr/app/analysis.py
services/asr/app/audio.py
services/asr/app/benchmark.py
services/asr/app/config.py
services/asr/app/diarization.py
services/asr/app/jobs.py
services/asr/app/main.py
services/asr/app/model_download.py
services/asr/app/nemo_transcription.py
services/asr/app/protocol_export.py
services/asr/app/quality.py
services/asr/app/schemas.py
services/asr/app/storage.py
services/asr/app/transcription.py
services/asr/app/vad.py
services/asr/models/.gitkeep
services/asr/requirements-diarization.txt
services/asr/requirements-nemo.txt
services/asr/requirements.txt
services/asr/scripts/compare_protocols.py
services/asr/tests/test_analysis.py
services/asr/tests/test_audio.py
services/asr/tests/test_diarization.py
services/asr/tests/test_health.py
services/asr/tests/test_jobs.py
services/asr/tests/test_model_download.py
services/asr/tests/test_nemo_transcription.py
services/asr/tests/test_quality.py
tailwind.config.ts
tsconfig.json
types/ai.ts

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.