✨ Лёгкий STT‑шлюз на FastAPI со стримингом SSE и очередью из одного активного запроса. Идеально для Telegram‑ботов и небольших сервисов на слабых VPS.
- 🔑 API‑ключи для доступа
- ⏱️ Rate limit: 10 запросов / 5 минут
- 🧵 Один активный запрос, остальные ждут в очереди
- 🔊 Поддержка
ogg/opus,wav,mp3 - 📡 Стриминг результата через SSE (
stream=true) - 🧹 Временные файлы на диске, автоматическая очистка
- 📊 SQLite‑статистика (агрегаты)
- ❤️
/healthдля мониторинга
Ключевые модули
stt_service/main.py— запуск FastAPI и загрузка моделиstt_service/routes.py—/sttи/healthstt_service/audio_pipeline.py— ffmpeg конвертация + чанкингstt_service/stt_engine.py— обёртка над faster‑whisperstt_service/limiter.py— rate limitstt_service/stats.py— SQLite статистика
- Клиент отправляет аудио на
/stt. - Файл сохраняется во временную папку.
ffmpegконвертирует в WAV 16kHz mono.- WAV режется на чанки.
- Каждый чанк проходит через faster‑whisper.
- Результат отдается целиком или по SSE.
- Временные файлы удаляются.
Поток данных (ASCII)
┌──────────┐ ┌──────────┐ ┌────────────┐ ┌──────────────┐
│ Client │ → │ /stt │ → │ temp file │ → │ ffmpeg │
└──────────┘ └──────────┘ └────────────┘ └──────────────┘
│
▼
┌──────────────┐
│ chunking │
└──────────────┘
│
▼
┌──────────────┐
│ faster- │
│ whisper │
└──────────────┘
│
▼
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Client │ ← │ SSE/JSON │ ←──────────────────│ cleanup tmp │
└──────────┘ └──────────┘ └──────────────┘
Требования
- Ubuntu 20.04/22.04 x64
- Python 3.11
- ffmpeg
Установка
sudo apt-get update
sudo apt-get install -y ffmpeg python3.11 python3.11-venv
python3.11 -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt.env
STT_API_KEYS=dev-key-1
STT_MODEL_SIZE=small
STT_ENABLE_AUTO_DETECT=true
STT_CHUNK_SIZE_SECONDS=20
STT_BEAM_SIZE=5
STT_BEST_OF=5
STT_TEMPERATURE=0.0Запуск вручную
venv/bin/python -m uvicorn stt_service.main:app --host 0.0.0.0 --port 8000 --workers 1systemd (пример)
Для Ubuntu правильный вариант — systemd. Он запускает сервис в фоне и перезапускает при падении.
- Создай unit‑файл:
sudo nano /etc/systemd/system/stt-gateway.service- Вставь содержимое:
/etc/systemd/system/stt-gateway.service
[Unit]
Description=STT Gateway
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/stt-gateway
EnvironmentFile=/home/ubuntu/stt-gateway/.env
ExecStart=/home/ubuntu/stt-gateway/venv/bin/python -m uvicorn stt_service.main:app --host 0.0.0.0 --port 8000 --workers 1
Restart=always
RestartSec=3
LimitNOFILE=4096
[Install]
WantedBy=multi-user.targetВажно про пути в unit‑файле
WorkingDirectory,EnvironmentFileиExecStartдолжны указывать на реальные пути к проекту и venv.- Пример: если проект в
/opt/stt-gateway, все пути должны начинаться с/opt/stt-gateway. - Ошибка в путях приведёт к падению сервиса при старте.
Запуск в фоне и автоперезапуск
Юнит лежит в /etc/systemd/system/, а код и .env — в папке проекта.
sudo systemctl daemon-reload # перечитать юнит‑файлы. Нужно после изменения *.service.
sudo systemctl enable stt-gateway # включить автозапуск при старте системы.
sudo systemctl restart stt-gateway # запустить сервис сейчас.
sudo systemctl status stt-gateway # показать текущее состояние и последние логи.Логи
journalctl -u stt-gateway -fУправление сервисом
sudo systemctl start stt-gateway
sudo systemctl stop stt-gateway
sudo systemctl restart stt-gateway
sudo systemctl status stt-gateway
sudo systemctl enable stt-gateway
sudo systemctl disable stt-gateway- Проверить здоровье сервиса:
curl http://127.0.0.1:8000/health- Проверить не‑стрим запрос (локально на сервере):
curl -X POST "http://127.0.0.1:8000/stt?stream=false" \
-H "X-API-Key: dev-key-1" \
-F "file=@/path/to/your.wav"- Проверить стрим (SSE):
curl -N -X POST "http://127.0.0.1:8000/stt?stream=true" \
-H "X-API-Key: dev-key-1" \
-F "file=@/path/to/your.wav"- Проверить очередь:
- запустить два запроса одновременно — второй должен ждать окончания первого.
- Проверить очистку:
- после обработки убедиться, что
./tmpне содержит старых файлов.
- после обработки убедиться, что
py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt
python -m uvicorn stt_service.main:app --host 0.0.0.0 --port 8000 --workers 1Если PowerShell блокирует активацию:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\.venv\Scripts\Activate.ps1Если нет домена
- На самом сервере используйте
http://127.0.0.1:8000. - С другого компьютера, при интеграции в приложение, для работы используйте публичный IP сервера:
http://<PUBLIC_IP>:8000/stt - для проверки здоровья STT
http://<PUBLIC_IP>:8000/health - Header:
X-API-Key: <key> - Body:
multipart/form-dataсfile - Query:
stream=true|false
Пример (Python)
import requests
url = "http://localhost:8000/stt"
headers = {"X-API-Key": "dev-key-1"}
files = {"file": open("sample.wav", "rb")}
resp = requests.post(url, headers=headers, params={"stream": "false"}, files=files)
print(resp.json())Пример (Node.js)
import fs from "fs";
import FormData from "form-data";
import fetch from "node-fetch";
const form = new FormData();
form.append("file", fs.createReadStream("sample.wav"));
const res = await fetch("http://localhost:8000/stt?stream=false", {
method: "POST",
headers: { "X-API-Key": "dev-key-1" },
body: form,
});
console.log(await res.json());Важно: сервер запущен в одном окне PowerShell, тесты — в другом.
Non‑streaming:
curl.exe -X POST "http://localhost:8000/stt?stream=false" `
-H "X-API-Key: dev-key-1" `
-F "file=@Danil.wav"Streaming (SSE):
curl.exe -N -X POST "http://localhost:8000/stt?stream=true" `
-H "X-API-Key: dev-key-1" `
-F "file=@Danil.wav"Health:
curl.exe "http://localhost:8000/health"STT_MODEL_SIZE—tiny | base | small | ...STT_CHUNK_SIZE_SECONDS— размер чанка (меньше = легче по CPU)STT_BEAM_SIZE— ширина поиска (качество ↑, скорость ↓)STT_BEST_OF— число кандидатов (качество ↑, скорость ↓)STT_TEMPERATURE— вариативность (0.0 = стабильнее)
uvicorn не найден
- Запускайте через
python -m uvicorn ...
PowerShell блокирует Activate.ps1
Set-ExecutionPolicy -Scope Process -ExecutionPolicy BypassОшибка установки av
- Используйте Python 3.11 x64 и пересоздайте venv.
Server misconfigured: no API keys
- Проверьте
.envв корне и наличиеSTT_API_KEYS.
curl в PowerShell ведёт себя странно
- Используйте
curl.exe.
- При первом старте модель будет скачана с Hugging Face — это может занять время.
- Для слабого VPS лучше начать с
base, затем переходить наsmall.
Если нужно — напишите, помогу с настройкой или оптимизацией.