Spark
Локальное веб-приложение: MP3 совещания → транскрипт с таймкодами и метками спикеров → краткое содержание и таблица поручений (ответственный, срок…
О проекте
Команда: Spark
Кейс HackAlem.ai: Инновации — Самрук-Казына
Стадия: Рабочий MVP
Задача кейса: «Хаттама»: протокол и поручения по аудиозаписи совещания (каз./рус./смешанная речь)
Суть
Локальное веб-приложение: MP3 совещания → транскрипт с таймкодами и метками спикеров → краткое содержание и таблица поручений (ответственный, срок, цитата) → экспорт протокола в DOCX.
Как устроено
FastAPI принимает MP3, декодирует через PyAV, транскрибирует faster-whisper small (CPU, INT8, автоопределение языка ru/kk). Диаризация pyannote Community-1 запускается в отдельном процессе, align.py сопоставляет спикеров с сегментами. Саммари и поручения извлекаются локальными правилами без LLM, протокол экспортируется через python-docx.
Ключевые решения
- faster-whisper small INT8
- pyannote speaker-diarization-community-1
- выравнивание сегментов и спикеров
- rule-based извлечение поручений
- python-docx
Особенности
Полностью офлайн-конвейер без LLM. В README честно указано, что проверены только первые 60 секунд русской записи, казахская и смешанная речь не подтверждены. Диаризация вынесена в отдельный процесс и окружение, поэтому при её сбое транскрипт сохраняется.
Стек
Python · FastAPI · PyAV · PyTorch · python-docx · HTML/CSS/JavaScript
Модели
Whisper small (faster-whisper) · pyannote Community-1
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-340ee9e2-spark.
README
README.mdSpark — локальное протоколирование совещаний
Проект команды Spark для HackAlem AI. Веб-приложение превращает MP3-запись совещания в транскрипт с временными метками и обозначениями говорящих, формирует краткое содержание и таблицу поручений, позволяет скачать протокол в DOCX.
Обработка выполняется на компьютере, где запущен сервер. Для распознавания речи используется многоязычная Whisper small через faster-whisper, для разделения говорящих — pyannote Community-1. Саммари и поручения формируются локальными правилами, а не LLM. Ollama и Qwen из первоначального плана в текущую интеграцию не подключены.
Статус проекта
Реализован и проверен сквозной сценарий: загрузка настоящей MP3 через браузер → локальная транскрибация → диаризация → анализ текста → отображение результатов → скачивание DOCX.
В интеграционной проверке от 23 сентября 2026 года обработаны первые 60 секунд русской записи. Это не подтверждает качество распознавания всей записи, казахской или смешанной речи. Подробности и ограничения приведены ниже и в отчёте интеграции.
PROJECT_BRIEF.md содержит первоначальные требования и план. Фактически реализованные возможности описаны в этом README; часть функций исходного плана ещё не выполнена.
Возможности
- Загрузка одной MP3-записи за раз; API также принимает расширение
.mpegдля MPEG-аудио. - Обработка первых 60 секунд для быстрой демонстрации или всей записи длительностью до 10 минут.
- Локальное распознавание речи на CPU в режиме INT8.
- Автоматическое определение языка; через API и CLI можно явно выбрать
ruилиkk. - Транскрипт с началом и концом каждого сегмента в секундах.
- Локальная диаризация: технические метки
SPEAKER_00,SPEAKER_01и далее. - Сохранение
speaker: null, если говорящего нельзя однозначно сопоставить с сегментом. - Краткое содержание и извлечение поручений с ответственным, сроком и фрагментом-основанием по локальным правилам.
- Экспорт протокола в DOCX.
- Отображение состояния обработки, предупреждений и ошибок; блокировка повторной отправки во время запроса.
- Сохранение транскрипта при недоступности диаризации.
Разделение голосов не определяет реальные имена участников. Техническая метка говорящего сама по себе не означает, что этот человек отвечает за поручение.
Команда
| Участница | Основная зона работы |
|---|---|
| Малика | Аудио и AI: транскрибация, диаризация, сопоставление сегментов, локальные модели и проверки |
| Улдана | Backend: API, анализ текста, структура протокола, обработка ошибок и DOCX |
| Аружан | Frontend: загрузка записи, состояние обработки, отображение результатов и скачивание |
Исходные ветки: feature/audio, feature/backend-uldana, feature/frontend-aruzhan. Общая сборка подготовлена в integration; наличие этой ветки не означает автоматического слияния в main.
Архитектура
Браузер: HTML / CSS / JavaScript
│ POST /analyze-audio, multipart file
▼
FastAPI: проверка файла и временное хранение
│
├─ transcribe_mp3 → faster-whisper small → текст и временные метки
├─ add_diarization → отдельный процесс Community-1 → метки говорящих
└─ build_protocol → локальные правила → саммари и поручения
│
▼
JSON → отображение в браузере
│ POST /export-docx с объектом protocol
▼
python-docx → документ Word
FastAPI обслуживает и API, и файлы интерфейса на одном адресе. Отдельный сервер frontend не требуется. Аудиозапрос синхронный: браузер ожидает итоговый результат, фоновой очереди и маршрутов опроса /api/meetings/... нет. Тяжёлая обработка вызывается через пул потоков, диаризация — в отдельном Python-процессе.
Структура репозитория
audio_module/
__init__.py # Экспорт transcribe_mp3 и save_json
transcribe.py # Декодирование MP3 и Whisper
diarize.py # Запуск отдельного процесса диаризации
diarize_worker.py # Локальная Community-1
align.py # Сопоставление голосов и сегментов текста
cli.py # Команды download, transcribe, diarize
download_diarization.py # Отдельное скачивание Community-1
requirements.txt # Зависимости транскрибации
requirements-diarization.txt # Зависимости диаризации
test_alignment.py # Проверки сопоставления и ошибок
CHECK.md # Подготовка моделей и проверки аудио
backend/
main.py # HTTP API и выдача frontend
schemas.py # Валидация входных и выходных данных
services/
audio.py # Подключение настоящего audio_module
protocol_analyzer.py # Сборка протокола
local_analysis.py # Правила саммари и поручений
docx_exporter.py # Формирование DOCX
INTEGRATION.md # Инструкция интеграционного запуска
INTEGRATION_CHECK.md # Фактические результаты проверок
frontend/
index.html # Страница приложения
styles.css # Оформление
app.js # Загрузка, API, результаты и DOCX
QA_DEMO_CHECKLIST.md # Проверка интерфейса
tests/ # Backend-тесты и браузерный smoke-тест
requirements.txt # Backend + зависимости транскрибации
requirements-backend.txt # FastAPI, валидация, DOCX и API-тесты
PROJECT_BRIEF.md # Первоначальный план проекта
README.md # Эта инструкция
Локальные каталоги .venv-integration, audio_module/.venv, audio_module/.venv-diarization, audio_module/models и audio_module/results не входят в Git. После клонирования их нужно подготовить отдельно.
Требования
Проверенное окружение: macOS, Apple Silicon arm64, Python 3.13.2, CPU. Команды ниже рассчитаны на macOS/Linux с путями bin/python. Работа на других ОС и архитектурах отдельно не подтверждена; доступность готовых пакетов нужно проверять для выбранной платформы.
Для первоначальной установки нужен интернет: Python-пакеты загружаются из PyPI, модели — из Hugging Face. Для обработки используются локальные модели. Размер загруженных файлов Whisper small в проверенной сборке — около 486,2 МБ, выбранных файлов Community-1 — около 32,8 МБ. Зависимости, окружения и кэши занимают дополнительное место.
Окружения разделены:
| Каталог | Назначение |
|---|---|
.venv-integration | Сервер, анализ текста, экспорт и транскрибация при обработке через веб-интерфейс |
audio_module/.venv | Самостоятельные команды аудиомодуля и его тесты |
audio_module/.venv-diarization | Отдельный процесс pyannote/PyTorch |
В этом пути MP3 декодируется через PyAV, а диаризация получает готовый waveform. Отдельная установка системного FFmpeg для описанного сценария не требуется.
Быстрый запуск на уже подготовленном компьютере
Выполняйте команды из корня репозитория. Если модели и три окружения уже установлены, повторять установку не нужно.
HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 HF_HUB_DISABLE_TELEMETRY=1 \
PYANNOTE_METRICS_ENABLED=0 OTEL_SDK_DISABLED=true \
.venv-integration/bin/python -m uvicorn backend.main:app \
--host 127.0.0.1 --port 8000 --no-access-log
- Приложение: http://127.0.0.1:8000/
- Интерактивное описание API: http://127.0.0.1:8000/docs
- Проверка живости сервера: http://127.0.0.1:8000/health
Для обычной демонстрации используйте главную страницу. Страница /docs — вспомогательный инструмент FastAPI, её оформление может требовать внешних ресурсов.
Запускайте один процесс Uvicorn, без --workers: защита от одновременной обработки записей действует внутри процесса. Для остановки нажмите Ctrl+C в терминале сервера. Если сервер уже запущен на порту 8000, второй экземпляр запускать не нужно.
Установка с нуля
1. Получить код
Репозиторий команды требует предоставленного доступа GitHub. Пока общая сборка находится в integration:
git clone --branch integration https://github.com/BAITC-Hacks/hack-340ee9e2-spark.git
cd hack-340ee9e2-spark
После принятия интеграции в main можно использовать основную ветку. Если репозиторий уже есть на компьютере, повторное клонирование не требуется.
2. Подготовить окружения
Проверьте, что установлен Python 3.13:
python3.13 --version
python3.13 -m venv audio_module/.venv
audio_module/.venv/bin/python -m pip install --only-binary=:all: -r audio_module/requirements.txt
python3.13 -m venv audio_module/.venv-diarization
audio_module/.venv-diarization/bin/python -m pip install --only-binary=:all: -r audio_module/requirements-diarization.txt
python3.13 -m venv .venv-integration
.venv-integration/bin/python -m pip install --only-binary=:all: -r requirements.txt
Флаг --only-binary=:all: требует готовые пакеты. Если для платформы или версии Python их нет, установка завершится ошибкой; проверенная конфигурация указана выше. Зависимости аудио зафиксированы в отдельных файлах, часть backend-зависимостей задаётся диапазонами версий — новая установка может отличаться от проверенной.
3. Скачать Whisper small
audio_module/.venv/bin/python -m audio_module.cli download
Модель сохраняется в audio_module/models/faster-whisper-small. Команда проверяет размер перед загрузкой. При обычной транскрибации автоматического скачивания нет.
4. Подготовить Community-1
Откройте страницу Community-1, войдите в Hugging Face и оформите доступ по условиям модели. Создайте токен чтения в настройках Hugging Face, затем выполните:
audio_module/.venv/bin/python -m audio_module.download_diarization
Скрипт использует существующую локальную авторизацию или запрашивает токен скрытым вводом в терминале. Введённый токен этой командой не сохраняется. Не вставляйте токен в исходники, чат или аргументы команды. Модель сохраняется в audio_module/models/community-1; при последующей обработке токен не требуется.
Для интеграции используйте эти команды аудиомодуля. Старый backend/scripts/download_model.py не нужен.
5. Проверить зависимости и запустить сервер
.venv-integration/bin/python -m pip check
audio_module/.venv/bin/python -m pip check
audio_module/.venv-diarization/bin/python -m pip check
Затем выполните команду из раздела «Быстрый запуск».
Как пользоваться
- Откройте главную страницу приложения.
- Выберите MP3 до 32 МиБ.
- Для первой проверки оставьте обработку первых 60 секунд. Для полного протокола выберите всю запись до 10 минут.
- Нажмите кнопку обработки и дождитесь результата. Во время обработки повторная отправка блокируется.
- Просмотрите транскрипт, временные метки, говорящих, саммари и поручения. Учитывайте предупреждение о частичной обработке.
- Сверьте важные имена, числа, ответственных и сроки с записью.
- Скачайте DOCX и откройте его в Word или совместимом редакторе.
Отсутствие найденных поручений означает, что текущие правила их не обнаружили в обработанном тексте. Это не доказывает отсутствия поручений в совещании. Встроенного редактирования и сохранения исправлений в этой версии нет; скачанный DOCX можно проверить и исправить отдельно.
API
| Метод и маршрут | Вход | Результат |
|---|---|---|
GET /health | — | {"status":"ok"}; живость сервера, не готовность моделей |
POST /transcribe | Multipart-поле file; query language, max_seconds | Текст, сегменты, диаризация, параметры обработки и предупреждения |
POST /analyze-audio | Multipart-поле file; query language, max_seconds, title | Транскрипт и сформированный протокол |
POST /analyze | JSON с text или transcript, необязательный title | Анализ уже готового текста без запуска аудиомоделей |
POST /export-docx | JSON объекта MeetingProtocol | Документ meeting_protocol.docx |
language можно не передавать для автоопределения или указать ru/kk. max_seconds принимает целое число от 1 до 600; без параметра обрабатывается полная запись с ограничением длительности 10 минут. Даже короткий отрывок требует загрузки файла целиком и соблюдения лимита 32 МиБ.
Пример проверки сервера:
curl http://127.0.0.1:8000/health
Пример реальной обработки. Замените путь на свою запись; JSON останется в игнорируемой папке:
mkdir -p audio_module/results
curl --fail-with-body \
-F 'file=@/absolute/path/meeting.mp3' \
'http://127.0.0.1:8000/analyze-audio?max_seconds=60' \
-o audio_module/results/api-result.json
Основные поля ответа /analyze-audio:
| Поле | Значение |
|---|---|
text | Полный текст обработанного интервала |
protocol.title | Заголовок или null |
protocol.summary | Саммари в виде строки |
protocol.transcript | Список сегментов: start, end, text, speaker |
protocol.action_items | Поручения: text, responsible, deadline, source_fragment, confidence |
language | Определённый язык |
processing | Обработанный интервал, режим и признак частичной записи |
diarization | Статус, причины и данные диаризации |
diarization_available | true только при diarization.status == "ok" |
warnings | Предупреждения для пользователя |
Для экспорта отправляется только объект protocol, а не весь ответ /analyze-audio. Frontend выполняет это автоматически.
CLI сохраняет сегменты в поле segments; backend возвращает их в transcript, а в ответе анализа — в protocol.transcript. Временные метки измеряются в секундах от начала записи. speaker: null допустим даже при успешной диаризации, например при смене говорящего внутри одного сегмента.
Основные HTTP-ошибки: 413 — превышен размер, 415 — неподдерживаемое расширение, 422 — некорректные данные/аудио или речь не обнаружена, 503 — сервер занят либо Whisper/зависимости недоступны, 500 — внутренняя ошибка. Недоступность Community-1 отдельно обрабатывается с сохранением транскрипта и предупреждением.
Настройки
| Переменная | Назначение |
|---|---|
WHISPER_MODEL_DIR | Путь к локальной Whisper вместо audio_module/models/faster-whisper-small |
DIARIZATION_MODEL_DIR | Путь к Community-1 вместо audio_module/models/community-1 |
DIARIZATION_PYTHON | Путь к Python окружения pyannote вместо audio_module/.venv-diarization/bin/python |
FRONTEND_ORIGINS | Необязательные разрешённые origins через запятую для отдельного frontend; для обычного запуска не нужны |
Пути передаются в окружение процесса сервера. Автоматическая загрузка .env не предусмотрена описанной командой. Офлайн-переменные и отключение телеметрии заданы в команде запуска выше.
Отдельный запуск аудиомодуля
Из корня репозитория, с заменой пути к записи:
audio_module/.venv/bin/python -m audio_module.cli transcribe \
'/absolute/path/meeting.mp3' --max-seconds 60 \
--output audio_module/results/transcript.json
audio_module/.venv/bin/python -m audio_module.cli diarize \
'/absolute/path/meeting.mp3' \
--transcript audio_module/results/transcript.json \
--output audio_module/results/diarized.json
Вторая команда использует интервал из первого JSON и не запускает Whisper повторно. Исходный и выходной JSON должны иметь разные пути. Полная инструкция: audio_module/CHECK.md.
Тестирование и подтверждённые результаты
Автоматические тесты:
.venv-integration/bin/python -m unittest discover -s tests -p 'test_backend*.py' -v
audio_module/.venv/bin/python -m unittest audio_module.test_alignment -v
Браузерный smoke-тест требует установленного Google Chrome и Playwright. Это зависимость проверки, не обычного запуска приложения. Сервер должен работать:
.venv-integration/bin/python -m pip install 'playwright==1.63.0'
.venv-integration/bin/python tests/smoke_frontend.py '/absolute/path/meeting.mp3'
По отчёту проверки от 23.09.2026:
| Проверка | Результат |
|---|---|
| Backend | 68 тестов прошли |
| Аудиомодуль | 13 тестов прошли |
| Зависимости трёх окружений | pip check без конфликтов |
| Настоящая запись через Chrome | Русский отрывок 0–60 секунд; HTTP 200 |
| Диаризация | ok, 3 метки говорящих |
| Сегменты | 15; speaker назначен 12, у 3 сохранён null |
| Время полного HTTP-запроса | 75,175 с на проверенном компьютере |
| Найденные поручения | 0 на проверенном отрывке |
| DOCX | Скачан; структура и содержание проверены программно |
| Отсутствующая Community-1 | Транскрипт сохранён, все speaker равны null |
| Браузер | 0 ошибок JavaScript, 0 внешних запросов страницы |
| Ширины 1440 и 390 px | Горизонтального переполнения нет |
Это результаты конкретного запуска, а не гарантия скорости и качества на любых записях. Unit-тесты используют тестовые подмены; настоящий аудиозапуск описан отдельно в отчёте. Полная запись, качество казахской/смешанной речи и визуальное оформление DOCX в Word в этом отчёте не подтверждены.
Локальная обработка и данные
- Рабочая цепочка приложения не использует внешние облачные API для аудио и текста.
- Пакеты и модели скачиваются отдельными подготовительными командами; при обработке используется локальная папка модели.
- Backend сохраняет загрузку во временный каталог на время запроса; каталог удаляется после выхода из обработки. Постоянной истории совещаний и базы данных нет.
- JSON самостоятельного CLI сохраняется по указанному пути. Скачанный DOCX сохраняется средствами браузера.
- Окружения, модели, записи, результаты,
.envи.vscodeисключаются правилами Git. Произвольный файл вне предусмотренных каталогов нужно дополнительно проверить перед коммитом. - Сервер по инструкции слушает только
127.0.0.1. Аутентификация и промышленное многопользовательское размещение не реализованы. - В проверках использовались локальные модели, офлайн-настройки и блокировка внешних запросов страницы. Полный браузерный проход с физически отключённым интернетом ещё не подтверждён.
Ограничения и дальнейшая работа
- Анализ текста основан на правилах. Полнота извлечения задач из настоящего совещания не подтверждена; результаты требуют проверки человеком.
- Языки. Модель многоязычная, но подтверждённый интеграционный тест выполнен только на русском отрывке.
- Говорящие. Перебивания и смена голоса внутри сегмента могут приводить к
null. Автоматическое установление личности не выполняется. - Редактирование. Встроенное исправление транскрипта, переименование говорящих и сохранение правок не реализованы.
- Дата совещания. Относительные сроки вроде «завтра» сохраняются текстом; календарная дата автоматически не рассчитывается.
- Обработка. Одна запись за раз, запрос синхронный. Отмена в браузере не гарантирует остановку вычислений на сервере. Детальный прогресс этапов не передаётся.
- Экспорт. Нужна отдельная визуальная проверка DOCX в Word; программная проверка не заменяет её.
- Переносимость. Установка и производительность на других платформах требуют отдельной проверки.
Следующие этапы: контрольные русская/казахская/смешанная записи с известными поручениями, улучшение локального анализа, редактирование и сохранение результатов, работа с датой совещания, проверка после перезапуска без интернета.
Частые проблемы
| Симптом | Что проверить |
|---|---|
| Страница не открывается | Сервер запущен, терминал не закрыт, адрес http://127.0.0.1:8000/ |
| Порт 8000 занят | Возможно, приложение уже работает; откройте страницу перед запуском второго экземпляра |
/health работает, аудио возвращает 503 | Наличие Whisper, зависимости и пути моделей; /health не загружает модель |
Диаризация unavailable | Каталог Community-1, окружение pyannote и DIARIZATION_PYTHON |
speaker: null при статусе ok | Причины в diarization.assignments; сегмент может содержать несколько говорящих |
| Получен только фрагмент совещания | По умолчанию UI обрабатывает первые 60 секунд; проверьте processing |
| Поручения не найдены | Прослушайте обработанный интервал: правила могли пропустить формулировки или поручения находятся дальше |
| Ошибки импортов в редакторе | Выберите интерпретатор соответствующего окружения; для сервера используется .venv-integration/bin/python |
| После клонирования нет моделей | Модели и окружения не хранятся в Git; выполните первоначальную подготовку |
Дополнительная документация
- Первоначальный план и требования
- Подготовка и проверка аудиомодуля
- Интеграционный запуск
- Фактический отчёт интеграции
- Документация backend
- Чек-лист интерфейса
Whisper и Community-1 используются как сторонние модели; условия их использования определяются соответствующими правообладателями. Наличие открытой модели не означает автоматического предоставления такой же лицензии на весь код этого репозитория.
Авторы коммитов
История коммитов
- 2026-09-23 17:55docs: add detailed project READMEМалика Тұрар
- 2026-09-23 17:49feat: integrate audio backend and frontendМалика Тұрар
- 2026-09-23 17:22fix: integrate frontend with backend APIarrrzhnr-prog
- 2026-09-23 17:16docs: add frontend QA and demo checklistarrrzhnr-prog
- 2026-09-23 17:15fix: accept MPEG audio uploads in backendu90272585-oss
- 2026-09-23 17:06fix: support MPEG meeting audioarrrzhnr-prog
- 2026-09-23 16:47feat: integrate offline protocol backend and local audio APIu90272585-oss
- 2026-09-23 16:35feat: add local speaker diarizationМалика Тұрар
Все коммиты (14)
- 2026-09-23 15:55feat: add upload and protocol UIarrrzhnr-prog
- 2026-09-23 15:25feat: complete offline protocol backendu90272585-oss
- 2026-09-23 15:04feat: scaffold offline protocol APIu90272585-oss
- 2026-09-23 14:55fix: disable audio runtime telemetry and pin dependenciesМалика Тұрар
- 2026-09-23 14:52feat: add local transcription baselineМалика Тұрар
- 2026-09-23 14:01docs: add MVP plan and requirementsМалика Тұрар
Структура репозитория (41 файлов)
.gitignore PROJECT_BRIEF.md README.md audio_module/.gitignore audio_module/CHECK.md audio_module/__init__.py audio_module/align.py audio_module/cli.py audio_module/diarize.py audio_module/diarize_worker.py audio_module/download_diarization.py audio_module/requirements-diarization.txt audio_module/requirements.txt audio_module/test_alignment.py audio_module/transcribe.py backend/INTEGRATION.md backend/INTEGRATION_CHECK.md backend/README.md backend/TEST_REPORT.md backend/__init__.py backend/examples/frontend-api.js backend/main.py backend/schemas.py backend/scripts/download_model.py backend/scripts/smoke_test.py backend/services/__init__.py backend/services/audio.py backend/services/docx_exporter.py backend/services/local_analysis.py backend/services/protocol_analyzer.py frontend/QA_DEMO_CHECKLIST.md frontend/app.js frontend/index.html frontend/styles.css requirements-backend.txt requirements.txt tests/sample_transcript.txt tests/smoke_frontend.py tests/test_backend_acceptance.py tests/test_backend_integration.py tests/test_backend_services.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.