283 lines
8.8 KiB
Markdown
283 lines
8.8 KiB
Markdown
# Simple ASR Service на базе Whisper
|
||
|
||
Простой сервис для распознавания речи с использованием OpenAI Whisper. Поддерживает различные форматы ответов, управление API-ключами без перезапуска и все параметры модели Whisper.
|
||
|
||
## Особенности
|
||
|
||
- 🎯 Эндпоинт `/transcribe` для распознавания речи
|
||
- 🔑 Управление API-ключами без перезапуска сервиса
|
||
- 📊 Три формата ответа: `json`, `simple`, `text/plain`
|
||
- ⚙️ Поддержка всех параметров `whisper.transcribe()`
|
||
- 🐳 Docker и native запуск
|
||
- 🏥 Health check эндпоинт
|
||
- 🔄 Горячая перезагрузка API-ключей
|
||
- 🚀 GPU ускорение по умолчанию (NVIDIA/AMD)
|
||
- ⚙️ Централизованная конфигурация через .env файл
|
||
|
||
## Требования
|
||
|
||
- Python 3.8+
|
||
- FFmpeg (для обработки аудио)
|
||
- Минимум 4GB RAM
|
||
- Свободное место для моделей (turbo ~1GB, large ~3GB)
|
||
- **GPU с поддержкой CUDA или ROCm (рекомендуется)**
|
||
|
||
Для Docker дополнительно:
|
||
- Docker + Docker Compose
|
||
- NVIDIA Docker runtime (для NVIDIA GPU)
|
||
- ROCm (для AMD GPU)
|
||
|
||
## Быстрый старт
|
||
|
||
### Запуск через Docker
|
||
|
||
```bash
|
||
git clone https://github.com/SlavaVlad/simple-asr-server.git ./asr
|
||
cd asr
|
||
|
||
# Для AMD GPU оставьте как есть
|
||
# Для NVIDIA GPU раскомментируйте соответствующую секцию в docker-compose.yml
|
||
|
||
docker compose up -d
|
||
```
|
||
|
||
### Нативный запуск
|
||
|
||
```bash
|
||
git clone https://github.com/SlavaVlad/simple-asr-server.git ./asr
|
||
cd asr
|
||
|
||
chmod +x start_server.sh
|
||
./start_server.sh
|
||
```
|
||
|
||
### Переменные окружения
|
||
|
||
| Переменная | По умолчанию | Описание |
|
||
|------------|--------------|----------|
|
||
| `HOST` | `0.0.0.0` | IP адрес для привязки |
|
||
| `PORT` | `9854` | Порт сервера |
|
||
| `DEFAULT_MODEL` | `turbo` | Модель Whisper для загрузки |
|
||
| `MODEL_DEVICE` | `cuda` | Устройство: `cuda`, `cpu`, или `auto` |
|
||
| `MODEL_DOWNLOAD_ROOT` | `./models` | Директория для моделей |
|
||
| `KEYS_FILE` | `./data/keys.txt` | Файл с API ключами |
|
||
| `LOG_LEVEL` | `info` | Уровень логирования |
|
||
| `HSA_OVERRIDE_GFX_VERSION` | `10.3.0` | Версия GPU для AMD ROCm |
|
||
| `AUDIO_SPEEDUP` | `1.25` | Ускорение обработки аудио |
|
||
|
||
### Настройка GPU
|
||
|
||
**По умолчанию сервис настроен для работы с NVIDIA GPU.**
|
||
|
||
**Для использования CPU:**
|
||
```env
|
||
MODEL_DEVICE=cpu
|
||
```
|
||
|
||
### Доступные модели Whisper
|
||
|
||
- `tiny` - самая быстрая, наименее точная (~40MB)
|
||
- `base` - баланс скорости и качества (~150MB)
|
||
- `small` - хорошее качество (~500MB)
|
||
- `medium` - лучшее качество (~1.5GB)
|
||
- `large` - максимальное качество (~3GB)
|
||
- `turbo` - оптимизированная версия (~800MB, рекомендуется)
|
||
|
||
## Управление API-ключами
|
||
|
||
### Автоматическое создание ключей
|
||
|
||
При первом запуске:
|
||
1. Если установлен `openssl` - генерируется безопасный 64-символьный ключ
|
||
2. Если `openssl` отсутствует - создается пустой файл ключей
|
||
|
||
### Добавление/удаление ключей
|
||
|
||
1. Отредактируйте файл `data/keys.txt` (один ключ на строку, 64 hex символа)
|
||
2. Вызовите эндпоинт перезагрузки:
|
||
|
||
```bash
|
||
curl -X POST "http://localhost:9854/keys/reload" \
|
||
-H "X-API-Key: your-api-key"
|
||
```
|
||
|
||
Пример `data/keys.txt`:
|
||
```
|
||
key1
|
||
key2
|
||
```
|
||
|
||
### Генерация новых ключей
|
||
|
||
```bash
|
||
# Генерация нового ключа
|
||
openssl rand -hex 32
|
||
|
||
# Добавление в файл ключей
|
||
echo "$(openssl rand -hex 32)" >> data/keys.txt
|
||
```
|
||
|
||
## API Документация
|
||
|
||
### POST /transcribe
|
||
|
||
Основной эндпоинт для распознавания речи.
|
||
|
||
#### Параметры
|
||
|
||
**Обязательные:**
|
||
- `audio_file` - аудиофайл (form-data)
|
||
|
||
**Опциональные:**
|
||
- `format` - формат ответа: `json` (по умолчанию), `simple`, `text`
|
||
- Все параметры `whisper.transcribe()`:
|
||
- `language` - язык аудио (auto-detect по умолчанию)
|
||
- `task` - `transcribe` или `translate`
|
||
- `temperature` - температура для генерации (0.0-1.0)
|
||
- `beam_size` - размер луча для поиска
|
||
- `best_of` - количество кандидатов для выбора лучшего
|
||
- `compression_ratio_threshold` - порог сжатия для фильтрации
|
||
- `logprob_threshold` - порог логарифмической вероятности
|
||
- `no_speech_threshold` - порог отсутствия речи
|
||
- `condition_on_previous_text` - использовать предыдущий текст как контекст
|
||
- `initial_prompt` - начальная подсказка для модели
|
||
- `word_timestamps` - временные метки слов (true/false)
|
||
- `prepend_punctuations` - знаки препинания для добавления в начало
|
||
- `append_punctuations` - знаки препинания для добавления в конец
|
||
- `clip_timestamps` - временные метки для обрезки аудио
|
||
- `hallucination_silence_threshold` - порог тишины для отрезания галлюцинаций
|
||
|
||
#### Примеры запросов
|
||
|
||
**Простая транскрибация:**
|
||
```bash
|
||
curl -X POST "http://localhost:9854/transcribe" \
|
||
-H "X-API-Key: your-api-key" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{}' \
|
||
--form "audio_file=@audio.wav"
|
||
```
|
||
|
||
**С параметрами:**
|
||
```bash
|
||
curl -X POST "http://localhost:9854/transcribe" \
|
||
-H "X-API-Key: your-api-key" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"language": "ru",
|
||
"format": "simple",
|
||
"word_timestamps": true,
|
||
"temperature": 0.2
|
||
}' \
|
||
--form "audio_file=@audio.wav"
|
||
```
|
||
|
||
**Только текст:**
|
||
```bash
|
||
curl -X POST "http://localhost:9854/transcribe" \
|
||
-H "X-API-Key: your-api-key" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"format": "text"}' \
|
||
--form "audio_file=@audio.wav"
|
||
```
|
||
|
||
**Расширенные параметры:**
|
||
```bash
|
||
curl -X POST "http://localhost:9854/transcribe" \
|
||
-H "X-API-Key: your-api-key" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"language": "en",
|
||
"task": "translate",
|
||
"temperature": 0.1,
|
||
"beam_size": 5,
|
||
"word_timestamps": true,
|
||
"initial_prompt": "This is a technical presentation about AI",
|
||
"format": "json"
|
||
}' \
|
||
--form "audio_file=@audio.wav"
|
||
```
|
||
|
||
#### Форматы ответов
|
||
|
||
**json (полный ответ от Whisper):**
|
||
```json
|
||
{
|
||
"text": "Привет, как дела?",
|
||
"segments": [
|
||
{
|
||
"start": 0.0,
|
||
"end": 2.5,
|
||
"text": "Привет, как дела?",
|
||
"words": [...]
|
||
}
|
||
],
|
||
"language": "ru"
|
||
}
|
||
```
|
||
|
||
**simple (только текст):**
|
||
```json
|
||
{
|
||
"text": "Привет, как дела?"
|
||
}
|
||
```
|
||
|
||
**text (plain text):**
|
||
```
|
||
Привет, как дела?
|
||
```
|
||
|
||
### GET /health
|
||
|
||
Проверка состояния сервиса:
|
||
|
||
```bash
|
||
curl "http://localhost:9854/health"
|
||
```
|
||
|
||
Ответ:
|
||
```json
|
||
{
|
||
"status": "healthy",
|
||
"model_loaded": true,
|
||
"model_name": "turbo"
|
||
}
|
||
```
|
||
|
||
## Коды ошибок
|
||
|
||
- `401` - API ключ не предоставлен
|
||
- `403` - Неверный API ключ
|
||
- `422` - Неверные параметры запроса
|
||
- `500` - Ошибка сервера/модели
|
||
|
||
## Systemd сервис
|
||
|
||
Для автоматического запуска создайте systemd сервис:
|
||
|
||
```bash
|
||
sudo cp asr.service /etc/systemd/system/
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable asr
|
||
sudo systemctl start asr
|
||
```
|
||
|
||
## Поддерживаемые форматы аудио
|
||
|
||
Все форматы, поддерживаемые FFmpeg:
|
||
- WAV, MP3, FLAC, M4A, OGG
|
||
- Видео форматы (извлекается аудио): MP4, AVI, MKV
|
||
|
||
## Производительность
|
||
|
||
Время обработки зависит от:
|
||
- Выбранной модели
|
||
- Длительности аудио
|
||
- Доступных ресурсов (CPU/GPU)
|
||
|
||
Примерные времена для 1 минуты аудио:
|
||
- `tiny`: ~2-5 секунд
|
||
- `turbo`: ~5-10 секунд
|
||
- `large`: ~15-30 секунд
|