AAYMA
RU
Войти

Alem Minutes

Локальный ассистент совещаний: аудио (файл/микрофон/вкладка Zoom/Meet) → стенограмма со спикерами → протокол с проверяемыми цитатами и таблицей…

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

О проекте

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

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

Суть

Локальный ассистент совещаний: аудио (файл/микрофон/вкладка Zoom/Meet) → стенограмма со спикерами → протокол с проверяемыми цитатами и таблицей поручений → контроль исполнения.

Как устроено

faster-whisper large-v3 (int8_float16 на T4) распознаёт речь с автоопределением языка только среди kk/ru/en на каждом 30-секундном окне, pyannote Community-1 выполняет диаризацию. Gemma 4 E2B через transformers по фрагментам составляет саммари, показатели/проблемы и поручения с дословной цитатой; поручения без цитаты из стенограммы отбрасываются, остальные — черновики для проверки секретарём. Результаты хранятся в SQLite, экспорт DOCX/PDF/TXT/JSON/ICS; есть модуль безопасности (PII-детектор, prompt guard).

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

  • faster-whisper
  • pyannote diarization
  • language restriction kk/ru/en
  • grounding по цитатам
  • chunked summarization
  • PII detection
  • prompt guard
  • локальный offline inference

Особенности

Полностью локальный инференс без внешних API (Whisper + Gemma на одной T4 с освобождением VRAM), ограничение детектора языка тремя языками для шала қазақша, разделение говорящего и ответственного, отбрасывание поручений без подтверждающей цитаты.

Стек

Python · Streamlit · transformers · PyTorch · faster-whisper · SQLite · uv · Docker · GitHub Actions

Модели

Whisper large-v3 · Gemma 4 E2B · pyannote speaker-diarization-community-1


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

README

README.md

Alem Minutes

{CA907184-4164-4CE2-AABE-3F45A88A09BB} {7D64D33B-CD4F-4CE0-A15B-2A30BD702F83} {06117EB9-A974-407B-8367-AB25D576262F} {3A73A505-565A-47AF-9A27-76D01A25CB50} {0E52CFEB-6616-4AB1-842A-5F64134E4E6F} {77F08451-31FD-4455-B1AC-2BF8F4BAC163} photo_2026-09-23_17-54-30

Встреча закончилась. Поручения остались. Локальный ассистент для совещаний на русском, казахском и смешанном языке: запись → стенограмма со спикерами → протокол с проверяемыми цитатами → контроль исполнения.

Whisper вызывается через Python API faster-whisper, Gemma — через transformers в том же процессе. Аудио и текст не отправляются во внешние inference API. Все задачи сначала становятся черновиками: секретарь проверяет имя, срок и цитату перед подтверждением.

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

Нужны Python 3.12–3.13, uv и шрифт DejaVu Sans. Linux/WSL — основной проверяемый путь. Для мультимедиа и диаризации установите FFmpeg и libsndfile:

# Ubuntu / Debian
sudo apt-get install ffmpeg libsndfile1 fonts-dejavu-core
cp .env.example .env
./run-local.sh

Откройте http://127.0.0.1:8501. Основная конфигурация — NVIDIA T4, PyTorch 2.8 с CUDA 12.6. Нужны рабочий драйвер NVIDIA и доступ процесса к GPU (nvidia-smi). Gemma работает в FP16, Whisper — в int8_float16; перед переключением на Gemma модели распознавания освобождают VRAM. Gemma 4 E2B требует примерно 10 ГБ на диске; первое скачивание и загрузка занимают время. Отсутствие CUDA выводится как ошибка; явный CPU-режим: AI_DEVICE=cpu, WHISPER_COMPUTE=int8 (для Gemma FP32 потребуется больше 20 ГБ RAM). Для других ОС нужны соответствующие FFmpeg/шрифты; это не проверенная здесь конфигурация.

Для быстрой демонстрации интерфейса без весов и тяжёлых AI-зависимостей:

uv sync --locked
uv run --no-sync streamlit run app.py

Нажмите Открыть демонстрацию, затем вкладку Протоколы. Демонстрация использует явно обозначенную синтетическую смешанную стенограмму и заранее заданные поручения; она не выдаётся за результат запуска моделей.

Основной сценарий

  1. Уведомите участников о записи и ИИ-транскрибации, подтвердите право на обработку.
  2. Во вкладке Новое совещание (открывается первой) задайте дату и выберите файл, микрофон, запись вкладки или один из аудиопримеров. Для своего файла выберите Файл → Загрузить MP3 или другую запись: перетащите запись или нажмите Browse files. Допустимы MP3/WAV/M4A/FLAC/AAC/OGG/OPUS/MPGA/MP4/WebM/MPEG; максимум 200 МБ. Файл выбирается на вашем устройстве, обработка выполняется на сервере. После выбора доступны имя, размер и проигрыватель записи.
  3. Запустите анализ. По умолчанию используется Whisper large-v3 с точностью int8_float16 на GPU. Режим Авто: KZ / RU / EN · шала қазақша выбирает язык только среди kk, ru, en заново на каждом окне Whisper (до 30 секунд). Для одноязычной записи можно вручную выбрать Қазақша, Русский или English. Шала қазақша обрабатывается как смешанная речь; режим транскрибации сохраняет исходные языки, а контекст предыдущего окна отключён, чтобы уменьшить перенос языка между окнами. Ограничение детектора не гарантирует точность текста или разделение языков внутри одной фразы; качество на вашей записи нужно измерить. Ранее сохранённые протоколы не меняются — запустите запись заново, старый кэш распознавания не используется.
  4. В Протоколах над предпросмотром документа укажите имена и должности участников, прослушав образцы голосов. Нажмите Сохранить протокол и участников: одна кнопка сохраняет имена, роли, шапку, саммари и таблицу показателей. Говорящий и ответственный хранятся отдельно: фраза «Айжан, подготовь отчёт» не назначается говорящему.
  5. Проверьте цитаты и таймкоды, исправьте саммари/решения, ответственных, даты, срочность и направление поручений. Срок «завтра» / «ертең» считается от введённой даты; неоднозначные сроки требуют ручной проверки.
  6. Отметьте поручение проверенным, при необходимости укажите email. История, правки и статусы сохраняются в SQLite и переживают перезапуск.
  7. В Готовом протоколе проверьте документ по структуре docs/meeting_minutes_2.txt: шапка с организацией и темой, Текст совещания, Саммари по ключевым пунктам с таблицей Направление / доклад — Показатель — Проблема, затем Поручения с единой таблицей Поручение / Ответственный / Срок. Должность указывается при первом появлении участника. Скачайте DOCX/PDF/TXT, JSON для импорта в СЭД или ICS для календаря. Решения, цитаты, таймкоды и статусы можно включить отдельным приложением. Для демонстрации доступна обезличенная копия; проверьте свободный текст перед публикацией.
  8. В Обзоре поручений фильтруйте задачи по статусу, людям, направлению и совещанию. Просрочка определяется из даты и статуса выполнения.

Структура протокола по образцу

Gemma составляет общее саммари и извлекает направления докладов, показатели и проблемы с дословной цитатой. Приложение проверяет наличие цитаты в стенограмме и связывает докладчика с голосом, если цитата принадлежит одному спикеру. Подтверждённое имя автоматически появляется в таблице. Стенограмма сохраняется целиком в исходном порядке. Название организации вводится в форме, имена и должности подтверждаются пользователем; содержание образца не копируется в реальные встречи.

В форме Имена, должности и протокол → Шапка, саммари и таблица показателей можно исправлять, добавлять и удалять строки таблицы. Если проверка формы обнаружит пустую тему или направление, введённые имена и роли останутся в полях. Прежние протоколы открываются в новом оформлении. Кнопка Сохранить и сформировать таблицу показателей сначала сохраняет правки формы, затем заполняет таблицу по имеющейся стенограмме без повторного запуска Whisper; проверенные поручения сохраняются. Неподтверждённые цитатой числа отмечаются для ручной сверки. При ручном изменении докладчика, показателя или проблемы прежняя цитата отвязывается. Подтверждённая календарная дата попадает в колонку «Срок» вместе с исходной формулировкой. PDF и DOCX содержат настоящие таблицы с повторяющимися заголовками; в TXT колонки разделены табуляцией.

Диаризация и локальные веса

Для первого скачивания pyannote Community-1 примите условия модели и задайте HF_TOKEN с правом чтения в .env. После подготовки локальной копии токен не нужен для inference. Если диаризация недоступна, приложение явно показывает предупреждение и не утверждает, что спикеры распознаны.

Gemma 4 E2B загружается через AutoProcessor и AutoModelForMultimodalLM. Большая стенограмма обрабатывается ограниченными фрагментами; итоговое саммари объединяет их краткие содержания. Ответ проверяется схемой, а поручения без цитаты из реальной стенограммы отбрасываются. Совпадение цитаты не доказывает правильность её интерпретации — предусмотрена проверка человеком.

Подготовьте веса на машине с доступом к Hugging Face:

uv sync --locked --extra ai --extra diarization
uv run --no-sync python prepare_models.py

launch.py перед запуском добавляет CUDA-библиотеки из установленных wheel-пакетов в LD_LIBRARY_PATH, как требуется Faster-Whisper. Системный CUDA Toolkit не заменяет CUDA-сборку PyTorch.

Скрипт подготовки скачает модели в data/models и напечатает настройки. Укажите абсолютные пути, актуальные на целевой машине:

WHISPER_MODEL=/opt/alem/data/models/whisper-large-v3
GEMMA_MODEL=/opt/alem/data/models/gemma
DIARIZATION_MODEL=/opt/alem/data/models/diarization
ALEM_OFFLINE=1

В закрытый контур перенесите код, веса и подготовленные зависимости/образ. После подготовки запускайте без синхронизации зависимостей:

uv run --no-sync python launch.py

ALEM_OFFLINE=1 запрещает Hugging Face сетевую загрузку; модели должны быть доступны локально. run-local.sh выполняет синхронизацию пакетов и предназначен для первичной установки. Телеметрия Streamlit, Hugging Face и pyannote отключена в конфигурации проекта.

Teams, Zoom, Google Meet и live-аудио

Во вкладке Новое совещание → Teams / Zoom / Meet нажмите Открыть локальную запись. Локальная страница позволяет открыть проверенную ссылку платформы и записать звук выбранной вкладки через браузерный getDisplayMedia.

Войдите в веб-клиент участником «Alem Minutes — ведётся запись», отключите камеру/микрофон ассистента и дождитесь допуска организатора. Затем в Chrome/Edge выберите вкладку встречи и включите передачу её аудио. При необходимости добавьте свой микрофон. После остановки запись появится в списке live-записей; нажмите обновление и запустите анализ. Есть резервное скачивание аудио при сбое сохранения.

Это подключение с участием оператора: вход в аккаунт, выбор вкладки и допуск выполняются человеком. Автономный бот на официальных SDK платформ и потоковая выдача транскрипта во время записи не реализованы. Аудио захватывается вживую, анализ выполняется после остановки. Для настольного клиента платформы можно импортировать его запись; захват его системного звука зависит от ОС и браузера.

Сервис записи слушает только 127.0.0.1:8765, использует случайный токен, проверки Host/Origin, подтверждение записи и ограничение размера. Открывать эту страницу нужно на компьютере, где запущено приложение. Браузерный механизм описан в документации Chrome.

Автоматические напоминания и рассылка

Письма создаются только для проверенных незавершённых поручений с корректным email. Первое письмо содержит поручение и цитату; напоминания создаются ежедневно за три дня до срока и после просрочки. SQLite предотвращает повтор одного уведомления. Ошибка доставки допускает повторную попытку. При аварии между SMTP-доставкой и фиксацией в БД возможен повтор: получатель получает стабильный Message-ID.

По умолчанию worker сохраняет .eml локально и ничего не отправляет:

uv run --no-sync python notification_worker.py --interval 300

Настройте внутренний SMTP в .env и явно включите доставку:

SMTP_HOST=mail.internal.example
SMTP_PORT=587
[email protected]
SMTP_USER=minutes
SMTP_PASSWORD=replace-me
SMTP_STARTTLS=1
uv run --no-sync python notification_worker.py --send --interval 300

Вместо непрерывного процесса используйте cron/systemd с однократным запуском без --interval. Подготовленные локальные письма не подавляют последующую SMTP-рассылку: режимы имеют отдельные записи доставки. Уведомления не зависят от открытого Streamlit. Доступ к SMTP и адреса получателей настраивает заказчик; во время разработки реальные письма не отправлялись.

Архитектура

app.py / ui                 Streamlit: ввод, проверка, история, контроль
          ↓
services.pipeline           сборка зависимостей и кэш
          ↓
application.process         сценарий «запись → протокол»; интерфейсы ports
          ↓
core                        модели данных, цитаты, даты, правила ответственности
          ↑
adapters                    faster-whisper / pyannote / Transformers / SQLite

services.capture            локальный приём live-записи из браузера
notification_worker.py      независимая очередь писем и SMTP
exporters.py                Unicode DOCX/PDF, JSON, ICS, обезличивание

Модели загружаются лениво; тяжёлые вызовы сериализованы. На переходах Whisper/pyannote ↔ Gemma предыдущие модели освобождаются, чтобы укладываться в память T4. Внутри этапа модель переиспользуется для всех фрагментов. Ядро не импортирует UI, модельные библиотеки или SQLite. Ключ кэша — SHA-256 содержимого записи и настроек, поэтому локальные пути моделей безопасны. Правки пользователя хранятся отдельно от кэша inference. Совещания и поручения имеют стабильные ID независимо от названий.

Проверки и воспроизводимость

./run-tests.sh

Фактические результаты, включая полный GPU-прогон, записаны в отчёте проверки.

Тесты не скачивают веса. Проверяются цитаты и таймкоды, RU/KZ сроки, атрибуция, кэш с локальными путями, SQLite, повторная доставка, HTTP-защита записи, Unicode-экспорт и сохранение правок через настоящий Streamlit AppTest. CI выполняет их на Python 3.12.

Для воспроизводимого прогона реального аудио:

uv run --no-sync python launch.py process_recording.py data/meeting1.mp3 \
  --title 'Совещание 1' --date 2026-09-23 --language auto \
  --output data/cache/review-meeting1.json --no-cache

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

Данные и развёртывание

data/uploads — загрузки и live-записи; data/cache — исходные результаты inference; data/meetings.sqlite3 — история и правки; data/outbox — локальные письма; data/models — веса. Эти рабочие данные исключены из git. ALEM_DATA_DIR задаёт отдельный каталог. Реальные демонстрационные записи должны быть обезличены; поставляемые записи рассматривайте как данные, требующие проверки прав на использование.

Приложение рассчитано на секретаря на одном компьютере. Loopback не заменяет аутентификацию для совместного использования: для доступа по сети нужны аутентификация, TLS, разграничение доступа и резервные копии заказчика. Для чувствительных данных используйте шифрование диска и права ОС. Кнопка удаления очищает рабочую историю, кэш, загрузки и письма, сохраняя веса и поставляемые примеры; сначала остановите worker и запись.

Есть Dockerfile для подготовки CUDA-окружения. На хосте нужны драйвер NVIDIA и NVIDIA Container Toolkit. На Linux host networking сохраняет привязку обоих сервисов к loopback:

docker build -t alem-minutes .
docker run --rm --gpus all --network host --env-file .env \
  -v "$PWD/data:/app/data" alem-minutes

UID пользователя контейнера — 1000; каталог data должен быть ему доступен. В .env задавайте пути внутри контейнера, например /app/data/models/gemma. Образ нужно собрать до переноса в закрытый контур. Docker-развёртывание и реальные платформенные аккаунты требуют отдельной приёмки в окружении заказчика.

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

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

Maqsat 9Codex 4lariho 34 1

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

  • 2026-09-23 17:54Update README with new image and project detailsMaqsat
  • 2026-09-23 17:53Update README.mdMaqsat
  • 2026-09-23 17:49Integrate local transcript security and bundle Unicode PDF fontlariho 34
  • 2026-09-23 14:59Add project requirements and meeting minutesCodex
  • 2026-09-23 14:51Add meeting audio samplesCodex
  • 2026-09-23 14:51Merge GitHub initial commitCodex
  • 2026-09-23 14:42Initial prototypeCodex
  • 2026-09-23 17:09fix: persist speaker edits together and match report-table minutes formatmaqsatto
Все коммиты (14)
  • 2026-09-23 16:43feat: format minutes with themed transcripts summaries and assignment tablesmaqsatto
  • 2026-09-23 16:31feat: restrict Whisper detection to Kazakh Russian and Englishmaqsatto
  • 2026-09-23 16:26feat: use Whisper large-v3 by default on T4maqsatto
  • 2026-09-23 16:19feat: make recording uploads prominent and support more audio formatsmaqsatto
  • 2026-09-23 16:02feat: deliver local meeting workflow with T4 inference and reviewed action trackingmaqsatto
  • 2026-09-23 15:16feat: preserve local Python inference and action tracking prototypemaqsatto
Структура репозитория (78 файлов)
.dockerignore
.env.example
.github/workflows/checks.yml
.gitignore
.streamlit/config.toml
Dockerfile
README.md
adapters/__init__.py
adapters/gemma.py
adapters/repository.py
adapters/runtime.py
adapters/speech.py
adapters/whisper_languages.py
app.py
application/__init__.py
application/ports.py
application/process.py
application/security_gate.py
assets/DejaVuSans-LICENSE.txt
assets/DejaVuSans-README.md
assets/DejaVuSans.ttf
assets/capture.html
core/__init__.py
core/grounding.py
core/languages.py
core/minutes.py
core/models.py
data/meeting1.mp3
data/meeting2.mp3
docs/coverage.md
docs/meeting_minutes_1.txt
docs/meeting_minutes_2.txt
docs/requirements_ru_kz_en.txt
docs/security-integration.md
docs/superpowers/plans/2026-09-23-local-minutes.md
docs/superpowers/specs/2026-09-23-local-minutes-design.md
docs/verification.md
exporters.py
launch.py
notification_worker.py
prepare_models.py
process_recording.py
pyproject.toml
requirements-dev.txt
requirements.txt
run-local.sh
run-tests.sh
security/README.md
security/__init__.py
security/audit_logger.py
security/demo.py
security/pii_detector.py
security/prompt_guard.py
security/sanitizer.py
security/security_pipeline.py
services/capture.py
services/demo.py
services/llm.py
services/model_registry.py
services/notifications.py
services/pipeline.py
services/reports.py
services/tracker.py
settings.py
tests/test_adapters.py
tests/test_capture.py
tests/test_exports.py
tests/test_grounding.py
tests/test_repository_notifications.py
tests/test_runtime.py
tests/test_security.py
tests/test_security_integration.py
tests/test_ui.py
ui/__init__.py
ui/dashboard.py
ui/intake.py
ui/review.py
uv.lock

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

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

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