Перейти к содержанию

AWS Serverless транскрибатор аудио — демо-сборка

Эта страница собирает разделы для демо и презентаций стейкхолдерам: обзор, роль, архитектура, решения, дорожная карта и демонстрация.

Содержание

Краткое описание

Статус

В эксплуатации

Роль

Системный проектировщик

Стек

Python, AWS Lambda, API Gateway, DynamoDB, AWS S3, Terraform, LLM API integration

Ценность проекта

Для пользователя:

  • быстрая транскрибация длинных аудиозаписей без загрузки в тяжёлые SaaS-сервисы;
  • контролируемый доступ к результатам через Cognito и предподписанные ссылки;
  • минимальные постоянные расходы за счёт serverless-модели.

Для профессионального профиля:

  • практическое проектирование AWS serverless workflow;
  • работа с асинхронной обработкой, webhook, polling UI и жизненным циклом задачи;
  • применение Infrastructure-as-Code через Terraform;
  • выбор решений исходя из эпизодической нагрузки и ограничений стоимости (cost-driven architecture).

Обзор

Обзор продукта

Бессерверное решение для транскрибации аудиозаписей посредством внешнего API-транскрибации.

Технологический стек

  • Backend: Python в AWS Lambda
  • Data: Amazon S3 (фалйы записей, транскрибации), AWS DynamoDB (для статусов джобов)
  • Frontend: static HTML + JS на Amazon S3 с разверткой в AWS CloudFront
  • AI: AssemblyAI API
  • Security: AWS Cognito
  • Infrastructure: AWS API Gateway, упаковка в Terraform проект

Роль и обязанности

Моя роль

Я выступал как системный проектировщик и технический владелец решения.

Моя работа включала:

  • перевод личной потребности в требования, ограничения и архитектурную модель;
  • выбор serverless-архитектуры с учётом эпизодической нагрузки и стоимости;
  • проектирование асинронного процесса: upload -> запрос транскрибации -> webhook -> сохранение результата -> скачивание;
  • проектирование модели состояний задачи транскрибации;
  • выбор AWS-сервисов и границ ответственности между Lambda, S3, DynamoDB, API Gateway, Cognito и внешним провайдером транскрибации;
  • описание sequence-диаграм и ADR;
  • использование ИИ-инструментов поддержки разработки как ускорителя реализации при ручном контроле архитектуры, границ безопасности и deployment-решений.

Применение ИИ

Проект разрабатывался с использованием AI.

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

  • интерпретация требований;
  • доменное моделирование;
  • архитектурные решения;
  • границы данных;
  • модель доступа;
  • код ревью;
  • дебаг;
  • решения по развертыванию;
  • техническая документация.

Архитектура и интеграции

Архитектура

Архитектурная концепция

Система построена на событийной модели.

Статический frontend раздаётся через S3/CloudFront. Пользователь проходит аутентификацию через Cognito Hosted UI и вызывает API Gateway, используя полученный JWT. API Gateway маршрутизирует запросы в Lambda-функции.

Большие аудиофайлы не проходят через API Gateway и Lambda. Backend выдаёт предподписанную POST URL, после чего браузер загружает файл напрямую в S3. Событие S3 ObjectCreated запускает обработчик, который создаёт временный URL для провайдера транскрибации и отправляет запрос на новую транскрибацию. Внешний провайдер выполняет долгую транскрибацию асинхронно и возвращает результат через webhook. Итоговый текстовый транскрипт сохраняется в S3, а статус задачи изменяется и хранится в DynamoDB.

architecture-beta
    service dynamo(aws:dynamodb)[AWS DynamoDB]
    service lambda(aws:lambda)[AWS Lambda] 
    service api(aws:api-gateway)[AWS API Gateway]
    service static(aws:simple-storage-service)[Static website at Amazon S3]
    service storage(aws:simple-storage-service)[File storage at Amazon S3]
    service browser(logos:chrome)[Browser]
    service cognito(aws:cognito)[AWS Cognito]
    service ai(logos:webhooks)[Transcriber API]
    service front(aws:cloudfront)[AWS CloudFront]

    front:T --> B:static
    browser:T --> B:api
    browser:L --> R:front
    browser:B --> T:cognito

    api:R --> L:lambda
    api:T <-- B:ai
    lambda:T --> R:ai
    lambda:R --> L:dynamo
    lambda:B --> T:storage
    storage:L <-- R:browser

Потоки интеграции

Диаграммы последовательности

Отправка файла аудио

sequenceDiagram
    autonumber

    actor U as Браузер (SPA)
    participant API as API Gateway
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB

    U->>API: GET /upload-url (+JWT в Header)
    activate API
    API->>L: Вызов get_upload_url
    deactivate API
    activate L
    L->>DB: Создание записи (Status: UPLOADING)
    L->>S3: Генерация Presigned POST URL
    activate S3
    S3-->>L: Ссылка для загрузки
    deactivate S3
    L-->>U: JSON: { uploadUrl, fileId }
    deactivate L

Прямая загрузка и Асинхронный Триггер (Event-Driven)

sequenceDiagram
    autonumber

    actor U as Браузер (SPA)
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB
    participant AI as TranscribeProvider

    U->>S3: POST Загрузка аудио-файла (Обход API Gateway)
    activate S3
    S3-->>U: 204 No Content (Успех)
    deactivate S3

    S3-)L: Event: ObjectCreated (Асинхронный вызов s3_trigger)
    activate L
    L->>DB: Обновление статуса (TRANSMITTING)
    L->>S3: Генерация временной GET Presigned URL для AI
    L->>AI: POST /v2/transcript (Аудио URL + Webhook URL)
    activate AI
    alt TranscribeProvider принимает запрос
        AI-->>L: 201 Created (transcript_id)
        L->>DB: Status = PROCESSING (сохранение ID)
    else Ошибка API (например, HTTP 400/500)
        AI-->>L: 4xx / 5xx Error
        deactivate AI
        L->>DB: Status = ERROR (Запись причины в лог)
    end
    deactivate L

Обработка ИИ и Webhook (до нескольких минут)

sequenceDiagram
    autonumber

    actor U as Браузер (SPA)
    participant API as API Gateway
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB
    participant AI as TranscribeProvider

    loop Каждые 15 секунд (Polling)
        U->>API: GET /jobs
        activate API 
        API->>L: Вызов get_jobs
        deactivate API
        activate L
        L->>DB: Запрос списка файлов пользователя
        activate DB
        DB-->>L: Данные (Status: PROCESSING)
        deactivate DB
        L-->>U: Обновление UI
        deactivate L
    end

    Note over AI, DB: TranscribeProvider завершает работу
    AI->>API: POST /webhook (передача transcript_id)
    activate API
    API->>L: Вызов webhook_TranscribeProvider
    deactivate API
    activate L
    L->>AI: GET /v2/transcript/{id}
    activate AI
    AI-->>L: Готовый текст транскрипции
    deactivate AI
    L->>S3: PUT Сохранение текста (Transcript.txt)
    L->>DB: Обновление статуса (READY)
    deactivate L

Получение результата (Скачивание)

sequenceDiagram
    autonumber

    actor U as Браузер (SPA)
    participant API as API Gateway
    participant L as AWS Lambda
    participant S3 as Amazon S3
    participant DB as DynamoDB

    U->>API: GET /jobs (Очередной опрос)
    activate API
    API-->>U: Status: READY (Кнопка скачивания активна)
    deactivate API

    U->>API: GET /download-url?fileId=...
    activate API
    API->>L: Вызов get_download_url
    deactivate API
    activate L
    L->>DB: Проверка прав доступа пользователя к файлу
    L->>S3: Генерация Presigned GET URL (с Content-Disposition)
    L-->>U: JSON: { downloadUrl }
    deactivate L
    U->>S3: Прямое скачивание текста.txt
    activate S3
    S3-->>U: Файл транскрипции
    deactivate S3

Решения, компромиссы и риски

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

Полноценная событийная модель

Необходимо учесть, что процесс транскрибаци продолжителен во времени, которое может превысить время работы Lambda-функции. * Решение: Внедрить событийную модель. Развязать по времени отправку аудио-файла и получение текстового результата. Необходимо найти такого провайдера транскрибации, который предоставит функциональность уведомления по webhook.

Работа с 300мб файлами

Необходимо учесть, что объем файлов может превосходить ограничения API Gateway и будут увеличивать время работы Lambda-функций. * Решение: Использовать функциональность предподписанных ссылок (Presigned URL), которую предлагает Amazon S3 из коробки. Это позволит обращаться клиенту напрямую к S3 в обход API Gateway и Lambda.

Архитектурные компромиссы (ADR)

1. Оптимальный архитектурный стиль

Контекст

Необходимо учесть эпизодический характер использования инструмента, небольшое количество сценариев использования, широкую зону доступности и при этом жесткие требования к себестоимости инфраструктуры и поддержки.

Принятое Решение

Использовать Serverless подход и инфраструктуру AWS Lambda.

Отклонённая альтернатива

VPS, Telegram bot

Обоснование
  • Lambda-функции оплачиваются за время запуска, при эпизодическом запуске вполне могут уместиться в Free-tier (1 млн.запросов или 400Тб-с в месяц), т.е. бизнес-логика при заданных условиях бесплатна. Также в AWS Lambda безопасность инфраструктуры обеспечивается на стороне Amazon, что исключает расходы на поддержку.

  • VPS требуют периодической оплаты мощностей (даже когда сервис не используется это может быть $3-7 в месяц), а также требуют ресурсы на поддержание требуемого уровня безопасности (установка обновлений безопасности ОС, свежих пакетов и т.п.).

  • Telegram bot ка кканал достаточно удобен, но не подойдет по причине ограничений на размер аудио-файла (50Мб) + не отменяет необходимости где-то размещать логику бота (VPS со всеми вытекающими).

Компромиссы
  • Serverless-подход требует более тщательного проектирования, максимального выноса тяжелых операций за пределы функций (presigned URL в S3). Требование к стабильности функций должно быть повышено. Необходимо обеспечить установку квот на запуск и уведомлений по размеру расходов.
  • Serverless сложнее дебажить.

2. Оптимальная инфраструктура транскрибации

Контекст

Необходимо учесть, что бюджет для запуска opensource модели на своих мощностях не предполагается.

Принятое Решение

Использовать сторонний API-сервис транскрибации.

Отклонённая альтернатива

Локально запущенная opensource модель, арендованное оборудование под запуск opensource-модели.

Обоснование
  • Сторонний API-сервис транскрибации работает быстро, не требует обслуживания. Оптимальным по соотношению качество/цена был выбран AssemblyAI - $0.15 в час. Стоимость минуты составит $0.0025 при условии использования облака Amazon и serverless-подхода, что в 120 раз меньше требуемого. Ограничение на 5 одновременных процессов транскрибации также выполняется.

  • Для локального запуска модели нет доступного железа (минимальные требования - 16Гб RAM и 8Гб видео памяти на внешней GPU). Приобретение дополнительного железа не входит в парадигму digital nomad.

  • Аренда совместимого оборудования будет стоить $5-10 в месяц при почасовой оплате, потребует отдельных ресурсов на развертывание решения, запуск, обеспечение безопасности (установка обновлений безопасности). Постоянная работа такого обордования обойдется в $40-60 в месяц. Решение неоптимально.

Компромиссы
  • запись отдается стороннему сервису, запрос на приватность решения не выполняется. Согласовано с заказчиком.

  • сторонний сервис может поменять расценки, может закрыться.

  • нужно безопасно хранить секреты (API-key). Хранить в коде небезопасно и плохой тон. Услуга хранения секрета в AWS Secret Manager стоит $0.40 в месяц + $0.05 за каждые 10000 запросов - это необходимо заложить в итоговую себестоимость минуты транскрибации.

3. Разделение пользовательских данных

Контекст

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

Принятое Решение

AWS Cognito

Отклонённая альтернатива

Парольная защита статической страницы HTML

Обоснование
  • AWS Cognito - в него встроен менеджмент учетных записей, возможность регистрации, 2FA, защита от брутфорса и т.п. Сервис бесшовно встроен в экосистему AWS. Потребности проекта вписываются в Free-tier (<10 000 MAU).

  • Парольная защита HTML - слабо адаптирована к брутфорсу, смена пароля через изменение кода - что не является лучшей практикой. Нет возможности разделить доступ между несколькими пользователями.

  • Своя система менеджмента доступа - оверинжениринг поверх одного бизнес-процесса.

Компромиссы
  • Условия Free-tier могут измениться и функциональность менеджмента пользователей может стать платной. Необходимо будет пересмотреть стоимость решения.

... Ключевые ADR представлены лишь частично в демонстрационных целях

Дорожная карта и демонстрация

Дорожная карта

Фаза Цель Изменения Exit criteria
v1 Базовая транскрибация загрузка, асинхронная транскрибация, статус, скачивание стабильная обработка длинных файлов
v1.1 Эксплуатационная устойчивость определение зависших задач, уведомления квот и бюджета, удаление старых логов, удаление старых файлов предсказуемая работа без ручного контроля
v2 Постобработка транскрипта суммаризация с учетом говорящих пользователь получает не только транскрипт, но и краткое саммари
v3 Расширение форматов дополнительные форматы, экстракция метаданных меньше ручной подготовки исходных аудио, постобработки транскрипта

Скриншоты и демо

Главное меню

UI_1

Главное меню

Загрузка аудиозаписи

UI_1

Загрузка аудиозаписи

Обработка файла

UI_1

Обработка записи

Что демонстрирует проект

Этот проект демонстрирует мои способности:

  • переводить личную/операционную потребность в требования, ограничения и архитектурное решение;
  • проектировать бессерверный процесс с учётом длительных асинхронных операций;
  • использовать сервисов AWS для минимизации постоянных расходов;
  • обходить ограничения API Gateway/Lambda через загрузку непосредственно в объектное хоанилище S3;
  • проектировать state machine для жизненного цикла задач;
  • применять Cognito, JWT и presigned URLs для ограниченного доступа к файлам;
  • описывать архитектурные компромиссы через ADR;
  • использовать Terraform для воспроизводимого развёртывания инфраструктуры.