AAYMA
RU
Войти

Spark

Локальное веб-приложение: MP3 совещания → транскрипт с таймкодами и метками спикеров → краткое содержание и таблица поручений (ответственный, срок…

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

О проекте

Команда: 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.md

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

Проект команды 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

Для обычной демонстрации используйте главную страницу. Страница /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

Затем выполните команду из раздела «Быстрый запуск».

Как пользоваться

  1. Откройте главную страницу приложения.
  2. Выберите MP3 до 32 МиБ.
  3. Для первой проверки оставьте обработку первых 60 секунд. Для полного протокола выберите всю запись до 10 минут.
  4. Нажмите кнопку обработки и дождитесь результата. Во время обработки повторная отправка блокируется.
  5. Просмотрите транскрипт, временные метки, говорящих, саммари и поручения. Учитывайте предупреждение о частичной обработке.
  6. Сверьте важные имена, числа, ответственных и сроки с записью.
  7. Скачайте DOCX и откройте его в Word или совместимом редакторе.

Отсутствие найденных поручений означает, что текущие правила их не обнаружили в обработанном тексте. Это не доказывает отсутствия поручений в совещании. Встроенного редактирования и сохранения исправлений в этой версии нет; скачанный DOCX можно проверить и исправить отдельно.

API

Метод и маршрутВходРезультат
GET /health—{"status":"ok"}; живость сервера, не готовность моделей
POST /transcribeMultipart-поле file; query language, max_secondsТекст, сегменты, диаризация, параметры обработки и предупреждения
POST /analyze-audioMultipart-поле file; query language, max_seconds, titleТранскрипт и сформированный протокол
POST /analyzeJSON с text или transcript, необязательный titleАнализ уже готового текста без запуска аудиомоделей
POST /export-docxJSON объекта 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_availabletrue только при 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:

ПроверкаРезультат
Backend68 тестов прошли
Аудиомодуль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. Аутентификация и промышленное многопользовательское размещение не реализованы.
  • В проверках использовались локальные модели, офлайн-настройки и блокировка внешних запросов страницы. Полный браузерный проход с физически отключённым интернетом ещё не подтверждён.

Ограничения и дальнейшая работа

  1. Анализ текста основан на правилах. Полнота извлечения задач из настоящего совещания не подтверждена; результаты требуют проверки человеком.
  2. Языки. Модель многоязычная, но подтверждённый интеграционный тест выполнен только на русском отрывке.
  3. Говорящие. Перебивания и смена голоса внутри сегмента могут приводить к null. Автоматическое установление личности не выполняется.
  4. Редактирование. Встроенное исправление транскрипта, переименование говорящих и сохранение правок не реализованы.
  5. Дата совещания. Относительные сроки вроде «завтра» сохраняются текстом; календарная дата автоматически не рассчитывается.
  6. Обработка. Одна запись за раз, запрос синхронный. Отмена в браузере не гарантирует остановку вычислений на сервере. Детальный прогресс этапов не передаётся.
  7. Экспорт. Нужна отдельная визуальная проверка DOCX в Word; программная проверка не заменяет её.
  8. Переносимость. Установка и производительность на других платформах требуют отдельной проверки.

Следующие этапы: контрольные русская/казахская/смешанная записи с известными поручениями, улучшение локального анализа, редактирование и сохранение результатов, работа с датой совещания, проверка после перезапуска без интернета.

Частые проблемы

СимптомЧто проверить
Страница не открываетсяСервер запущен, терминал не закрыт, адрес 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; выполните первоначальную подготовку

Дополнительная документация

Whisper и Community-1 используются как сторонние модели; условия их использования определяются соответствующими правообладателями. Наличие открытой модели не означает автоматического предоставления такой же лицензии на весь код этого репозитория.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
14
Авторы
3
Файлы
41
Ветки
5

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

Малика Тұрар 6arrrzhnr-prog 4u90272585-oss 4

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

  • 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
Ветки (5)

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

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

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