Skip to content

Latest commit

 

History

History
741 lines (542 loc) · 48 KB

File metadata and controls

741 lines (542 loc) · 48 KB

English | 简体中文 | 繁體中文 | Русский

Whisper — распознавание речи на Docker

Статус сборки  Docker Pulls  License: MIT  Open In Colab

Часть Self-Hosted AI Stack — разверните полный самостоятельно размещённый AI-стек одной командой.

Docker-образ для запуска сервера распознавания речи Whisper на базе faster-whisper. Предоставляет совместимые с OpenAI API для транскрибирования и перевода аудио. Основан на Debian (python:3.12-slim). Простой, приватный, для самостоятельного развёртывания.

Возможности:

  • Совместимые с OpenAI эндпоинты POST /v1/audio/transcriptions и POST /v1/audio/translations — любое приложение, использующее OpenAI Whisper API, переключается с изменением одной строки
  • Поддержка всех моделей Whisper: tiny, base, small, medium, large-v3, large-v3-turbo и других
  • Диаризация говорящих — определение, кто говорит в каждом сегменте (опциональное локальное расширение через sherpa-onnx)
  • Управление моделями через вспомогательный скрипт (whisper_manage)
  • Аудиоданные остаются на вашем сервере — никакие данные не отправляются третьим сторонам
  • Поддержка всех популярных аудиоформатов (mp3, m4a, wav, webm, ogg, flac и всех форматов ffmpeg)
  • Несколько форматов ответа: JSON, простой текст, подробный JSON, субтитры SRT, субтитры WebVTT
  • Потоковое транскрибирование — добавьте stream=true, чтобы получать сегменты через SSE по мере декодирования, без ожидания обработки всего файла
  • Ускорение на GPU NVIDIA (CUDA) для более быстрого инференса (тег образа :cuda)
  • Офлайн-режим — работа без доступа к интернету с предварительно кэшированными моделями (WHISPER_LOCAL_ONLY)
  • Автоматически собирается и публикуется через GitHub Actions
  • Постоянный кэш моделей через Docker-том
  • Поддержка нескольких архитектур: linux/amd64, linux/arm64

📘 Новая книга: The Self-Hosted AI Builder’s Guide. Практическое руководство по созданию, защите и эксплуатации собственного приватного AI-стека.

Также доступно:

Whisper или WhisperLive?

docker-whisper docker-whisper-live
Назначение Транскрибирование готовых аудиофайлов Живой микрофон / потоковое аудио в реальном времени
Протокол HTTP REST WebSocket (потоковый) + HTTP REST
Задержка Ответ после обработки всего файла Почти мгновенно, слово за словом
Подходит для Записи совещаний, загруженные аудиофайлы Захват в браузере, RTSP-потоки, живые субтитры
Размер образа ~190 МБ (~3,1 ГБ для :cuda) ~750 МБ (~4,5 ГБ для :cuda)

Быстрый старт

Запустите сервер Whisper следующей командой:

docker run \
    --name whisper \
    --restart=always \
    -v whisper-data:/var/lib/whisper \
    -p 9000:9000 \
    -d hwdsl2/whisper-server
Быстрый старт с GPU (NVIDIA CUDA)

Если у вас есть GPU NVIDIA, используйте образ :cuda для аппаратного ускорения инференса:

docker run \
    --name whisper \
    --restart=always \
    --gpus=all \
    -v whisper-data:/var/lib/whisper \
    -p 9000:9000 \
    -d hwdsl2/whisper-server:cuda

Требования: GPU NVIDIA, драйвер NVIDIA 575.57.08+ (Linux) или 576.57+ (Windows), а также установленный на хосте NVIDIA Container Toolkit. Образ :cuda поддерживает только linux/amd64.

Важно: Для работы образа с моделью base по умолчанию требуется не менее 700 МБ свободной оперативной памяти. Системы с 512 МБ ОЗУ и менее не поддерживаются.

Примечание: Для развёртываний, доступных из интернета, настоятельно рекомендуется добавить HTTPS с помощью обратного прокси. В этом случае также замените -p 9000:9000 на -p 127.0.0.1:9000:9000 в команде docker run выше, чтобы исключить прямой доступ к незашифрованному порту извне.

При первом запуске модель Whisper base (~145 МБ) автоматически загружается и кэшируется. Проверьте логи, чтобы убедиться в готовности сервера:

docker logs whisper

После появления сообщения "Whisper speech-to-text server is ready" можно начинать транскрибирование:

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -F file=@audio.mp3 \
    -F model=whisper-1

Ответ:

{"text": "Здесь отображается распознанный текст."}

Совет: Нужен образец аудиофайла для тестирования? Можно использовать этот образец английской речи (WAV, лицензия MIT) из репозитория Azure Samples:

curl -L -o sample_speech.wav \
    "https://github.com/Azure-Samples/cognitive-services-speech-sdk/raw/master/sampledata/audiofiles/katiesteve.wav"

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -F file=@sample_speech.wav \
    -F model=whisper-1

В качестве альтернативы вы можете настроить Whisper без Docker. Чтобы узнать больше об использовании этого образа, ознакомьтесь с разделами ниже.

Сообщество

Самостоятельно размещаемые VPN и сетевые проекты

Требования

  • Сервер Linux (локальный или облачный) с установленным Docker
  • Поддерживаемые архитектуры: amd64 (x86_64), arm64 (например, Raspberry Pi 4/5, AWS Graviton)
  • Минимум оперативной памяти: ~700 МБ для модели base по умолчанию (см. таблицу моделей)
  • Доступ в интернет при первом запуске для загрузки модели (затем модель кэшируется локально). Не требуется при использовании WHISPER_LOCAL_ONLY=true с предварительно кэшированными моделями.

Для ускорения на GPU (образ :cuda):

  • GPU NVIDIA с поддержкой CUDA (Compute Capability 6.0+)
  • Драйвер NVIDIA 575.57.08+ (Linux) или 576.57+ (Windows) на хосте
  • Установленный NVIDIA Container Toolkit
  • Образ :cuda поддерживает только linux/amd64

Для развёртывания с выходом в интернет см. раздел Использование обратного прокси для включения HTTPS.

Скачать

Получите доверенную сборку из Docker Hub:

docker pull hwdsl2/whisper-server

Для ускорения на GPU NVIDIA загрузите тег :cuda:

docker pull hwdsl2/whisper-server:cuda

Либо скачайте из Quay.io:

docker pull quay.io/hwdsl2/whisper-server
docker image tag quay.io/hwdsl2/whisper-server hwdsl2/whisper-server

Поддерживаемые платформы: linux/amd64 и linux/arm64. Тег :cuda поддерживает только linux/amd64.

Переменные окружения

Все переменные являются необязательными. Новые установки с подключённым томом /var/lib/whisper автоматически генерируют Bearer-токен. Существующие установки без ключа остаются открытыми для обратной совместимости.

Этот Docker-образ использует следующие переменные, которые можно объявить в файле env (см. пример):

Переменная Описание По умолчанию
WHISPER_MODEL Модель Whisper для использования. См. таблицу моделей. base
WHISPER_LANGUAGE Язык транскрибирования по умолчанию. Код BCP-47 (напр. ru, en, zh) или auto для автоопределения. auto
WHISPER_PORT HTTP-порт для API (1–65535). 9000
WHISPER_DEVICE Устройство вычислений: cpu, cuda или auto. Используйте cuda с образом :cuda для ускорения на GPU. auto определяет GPU автоматически, при отсутствии — переключается на CPU. cpu
WHISPER_COMPUTE_TYPE Тип квантования / вычислений. Для CPU рекомендуется int8; для CUDA рекомендуется float16. int8 (CPU) / float16 (CUDA)
WHISPER_THREADS Количество потоков CPU для инференса. Установите значение, равное числу физических ядер, для минимальной задержки. 2
WHISPER_API_KEY Необязательный Bearer-токен. В новых постоянных установках генерируется автоматически. Если задан, все запросы должны содержать Authorization: Bearer <key>. Явно пустое значение отключает аутентификацию. Автоматически для новых постоянных установок
WHISPER_LOG_LEVEL Уровень логирования: DEBUG, INFO, WARNING, ERROR, CRITICAL. INFO
WHISPER_BEAM Ширина луча при декодировании транскрипции и перевода. Большие значения могут улучшить точность за счёт скорости. Используйте 1 для наиболее быстрого (жадного) декодирования. 5
WHISPER_MAX_REQUEST_BEAM Максимальная ширина луча, разрешённая для переопределения beam в отдельном запросе. Установите 0, чтобы отключить этот лимит. 10
WHISPER_MAX_UPLOAD_MB Максимальный размер загружаемого аудиофайла в МБ. Запросы сверх этого лимита возвращают HTTP 413. Установите 0, чтобы отключить лимит. 1024
WHISPER_LOCAL_ONLY Если задано любое непустое значение (например, true), отключает все загрузки моделей с HuggingFace. Для изолированных или офлайн-развёртываний с предварительно кэшированными моделями. (не задан)
WHISPER_WORD_TIMESTAMPS При значении true глобально включает пословные метки времени. Вывод verbose_json будет содержать массив words на верхнем уровне с временем начала/конца и вероятностью для каждого слова. Также можно включить через timestamp_granularities[]=word. (не задан)
WHISPER_DIARIZATION При значении true включает диаризацию говорящих. Использует sherpa-onnx с моделями pyannote segmentation-3.0 в формате ONNX (~45 МБ, загружаются автоматически при первом использовании). Не поддерживается в потоковом режиме. (не задан)
WHISPER_DIARIZE_NUM_SPEAKERS Точное количество говорящих (если известно). Повышает точность кластеризации. Установите -1 или оставьте пустым для автоопределения. -1
WHISPER_DIARIZE_THRESHOLD Порог кластеризации для автоопределения. Меньше = больше говорящих, больше = меньше. Игнорируется, когда задано точное количество говорящих. 0.5
WHISPER_DISABLE_USAGE_COUNTS Установите 1, чтобы отключить анонимные агрегированные счётчики использования. (не задан)

Примечание: В файле env значения можно заключать в одинарные кавычки, например VAR='value'. Не добавляйте пробелы вокруг =. Если вы изменяете WHISPER_PORT, обновите флаг -p в команде docker run соответственно.

Пример использования файла env:

cp whisper.env.example whisper.env
# Отредактируйте whisper.env, затем:
docker run \
    --name whisper \
    --restart=always \
    -v whisper-data:/var/lib/whisper \
    -v ./whisper.env:/whisper.env:ro \
    -p 9000:9000 \
    -d hwdsl2/whisper-server

Файл env монтируется в контейнер, изменения применяются при каждом перезапуске без пересоздания контейнера.

Либо передайте его через --env-file
docker run \
    --name whisper \
    --restart=always \
    -v whisper-data:/var/lib/whisper \
    -p 9000:9000 \
    --env-file=whisper.env \
    -d hwdsl2/whisper-server

Использование docker-compose

cp whisper.env.example whisper.env
# Отредактируйте whisper.env при необходимости, затем:
docker compose up -d
docker logs whisper

Пример docker-compose.yml (уже включён в проект):

services:
  whisper:
    image: hwdsl2/whisper-server
    container_name: whisper
    restart: always
    ports:
      - "9000:9000/tcp"  # Для хостового обратного прокси измените на "127.0.0.1:9000:9000/tcp"
    volumes:
      - whisper-data:/var/lib/whisper
      - ./whisper.env:/whisper.env:ro

volumes:
  whisper-data:
    name: whisper-data

Примечание: Для развёртывания с выходом в интернет настоятельно рекомендуется использовать обратный прокси для добавления HTTPS. В этом случае также измените "9000:9000/tcp" на "127.0.0.1:9000:9000/tcp" в docker-compose.yml, чтобы предотвратить прямой доступ к незашифрованному порту.

Использование docker-compose с GPU (NVIDIA CUDA)

Для развёртывания с GPU используется отдельный файл docker-compose.cuda.yml:

cp whisper.env.example whisper.env
# Отредактируйте whisper.env при необходимости, затем:
docker compose -f docker-compose.cuda.yml up -d
docker logs whisper

Пример docker-compose.cuda.yml (уже включён в проект):

services:
  whisper:
    image: hwdsl2/whisper-server:cuda
    container_name: whisper
    restart: always
    ports:
      - "9000:9000/tcp"  # Для хостового обратного прокси измените на "127.0.0.1:9000:9000/tcp"
    volumes:
      - whisper-data:/var/lib/whisper
      - ./whisper.env:/whisper.env:ro
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

volumes:
  whisper-data:
    name: whisper-data

Справочник по API

API совместим с эндпоинтом транскрибирования и эндпоинтом перевода OpenAI. Любое приложение, использующее https://api.openai.com/v1/audio/transcriptions, может переключиться на собственный хостинг, установив:

Диаризация говорящих, если включена, является локальным расширением на базе sherpa-onnx и не эквивалентна моделям диаризации OpenAI. Параметры транскрибирования, специфичные для OpenAI, такие как gpt-4o-transcribe-diarize, response_format=diarized_json, include=logprobs, chunking_strategy, known_speaker_names и known_speaker_references, не поддерживаются и возвращают 400.

OPENAI_BASE_URL=http://IP_вашего_сервера:9000

Транскрибирование аудио

POST /v1/audio/transcriptions
Content-Type: multipart/form-data

Параметры:

Параметр Тип Обязателен Описание
file файл Аудиофайл. Поддерживаемые форматы: mp3, mp4, m4a, wav, webm, ogg, flac и все форматы, поддерживаемые ffmpeg.
model строка Передайте whisper-1 (значение принимается, но всегда используется активная модель).
language строка Код языка BCP-47. Переопределяет WHISPER_LANGUAGE для данного запроса.
prompt строка Необязательный текст для управления стилем модели или продолжения предыдущего сегмента.
response_format строка Формат вывода. По умолчанию: json. См. форматы ответа. Игнорируется при stream=true. Специфичный для OpenAI diarized_json не поддерживается.
temperature число с плавающей точкой Температура сэмплирования (0–1). По умолчанию: 0.
stream логическое Включить потоковую передачу SSE. При значении true сегменты возвращаются как события text/event-stream по мере декодирования. По умолчанию: false.
timestamp_granularities[] массив Гранулярность меток времени. Значения: word, segment. При наличии word вывод verbose_json содержит массив words на верхнем уровне. По умолчанию: ["segment"].

Локальное расширение faster-whisper: можно задать beam, чтобы переопределить WHISPER_BEAM для отдельного запроса транскрибирования или перевода. Это не часть схемы OpenAI API, поэтому не отправляйте этот параметр в размещённый OpenAI API или строгие OpenAI-совместимые шлюзы. Лимит по умолчанию для одного запроса — 10 (WHISPER_MAX_REQUEST_BEAM); установите эту переменную в 0, чтобы отключить лимит. Beam search в основном влияет на детерминированное декодирование при temperature=0.

Пример:

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -F file=@meeting.m4a \
    -F model=whisper-1 \
    -F language=ru

С аутентификацией по API-ключу:

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -H "Authorization: Bearer your_api_key" \
    -F file=@audio.mp3 \
    -F model=whisper-1

Форматы ответа

response_format Описание
json {"text": "..."} — по умолчанию, соответствует базовому ответу OpenAI
text Простой текст без обёртки JSON
verbose_json Полный JSON с языком, длительностью, временны́ми метками сегментов и логарифмическими вероятностями
srt Формат субтитров SubRip (.srt)
vtt Формат субтитров WebVTT (.vtt)

Пример — потоковое получение сегментов по мере декодирования:

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -F file=@long-audio.mp3 \
    -F model=whisper-1 \
    -F stream=true

SSE-ответ (используется протокол потоковой транскрипции OpenAI):

data: {"type":"transcript.text.delta","delta":"Привет, как дела?"}

data: {"type":"transcript.text.delta","delta":" Всё хорошо, спасибо."}

data: {"type":"transcript.text.done","text":"Привет, как дела? Всё хорошо, спасибо."}

data: [DONE]

Первый инкрементальный текст обычно приходит через 1–3 секунды после загрузки. Каждое событие transcript.text.delta содержит инкрементальный текст только что декодированного сегмента. Финальное событие transcript.text.done содержит полный собранный текст транскрипции — аналог стандартного ответа json.

Пример — потоковая передача через браузерный fetch
const form = new FormData();
form.append("file", audioBlob, "audio.webm");
form.append("model", "whisper-1");
form.append("stream", "true");

const res = await fetch("http://IP_вашего_сервера:9000/v1/audio/transcriptions", {
  method: "POST", body: form,
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  // SSE frames are separated by "\n\n"; split and process complete frames
  const frames = buffer.split("\n\n");
  buffer = frames.pop(); // keep any incomplete trailing frame
  for (const frame of frames) {
    if (!frame.startsWith("data: ")) continue;
    const payload = frame.slice(6);
    if (payload.startsWith("[DONE]")) break;
    const event = JSON.parse(payload);
    if (event.type === "transcript.text.delta") console.log(event.delta);
    if (event.type === "transcript.text.done") console.log("Full text:", event.text);
  }
}

Пример — получение субтитров SRT:

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -F file=@video.mp4 \
    -F model=whisper-1 \
    -F response_format=srt

Пример — подробный JSON с временны́ми метками:

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -F file=@audio.mp3 \
    -F model=whisper-1 \
    -F response_format=verbose_json

Пример — подробный JSON с пословными метками времени:

curl http://IP_вашего_сервера:9000/v1/audio/transcriptions \
    -F file=@audio.mp3 \
    -F model=whisper-1 \
    -F response_format=verbose_json \
    -F "timestamp_granularities[]=word"

При наличии word в timestamp_granularities[] ответ verbose_json содержит массив words на верхнем уровне:

{
  "word": "hello",
  "start": 0.5,
  "end": 0.8,
  "probability": 0.98
}

Перевод аудио

POST /v1/audio/translations
Content-Type: multipart/form-data

Перевод аудио с любого языка на английский текст. Совместим с эндпоинтом перевода OpenAI. Принимает обычные параметры перевода. Вывод всегда на английском.

Примечание: Модели только для английского (.en) не поддерживают перевод. Используйте многоязычную модель (например, base, small, large-v3-turbo).

Пример:

curl http://IP_вашего_сервера:9000/v1/audio/translations \
    -F file=@french_audio.mp3 \
    -F model=whisper-1

Список моделей

GET /v1/models

Возвращает активную модель в совместимом с OpenAI формате.

curl http://IP_вашего_сервера:9000/v1/models

Интерактивная документация API

Интерактивный Swagger UI доступен по адресу:

http://IP_вашего_сервера:9000/docs

Постоянные данные

Все данные сервера хранятся в Docker-томе (/var/lib/whisper внутри контейнера):

/var/lib/whisper/
├── models--Systran--faster-whisper-*/   # Кэшированные файлы модели Whisper (скачаны с HuggingFace)
├── .port                 # Активный порт (используется whisper_manage)
├── .model                # Активное название модели (используется whisper_manage)
└── .server_addr          # Кэшированный IP сервера (используется whisper_manage)

Создайте резервную копию Docker-тома для сохранения скачанных моделей. Модели занимают значительный объём (145 МБ – 3 ГБ) и могут скачиваться несколько минут при первом запуске; сохранение тома позволяет избежать повторной загрузки при пересоздании контейнера.

Совет: Том /var/lib/whisper использует тот же формат кэша HuggingFace, что и том /var/lib/whisper-live в docker-whisper-live. Если вы уже скачали модель через docker-whisper-live, можно примонтировать тот же каталог тома, чтобы не загружать её повторно.

Управление сервером

Используйте whisper_manage внутри запущенного контейнера для просмотра информации о сервере и управления им.

Показать информацию о сервере:

docker exec whisper whisper_manage --showinfo

Список доступных моделей:

docker exec whisper whisper_manage --listmodels

Предварительная загрузка модели:

docker exec whisper whisper_manage --downloadmodel large-v3-turbo

Переключение моделей

Для смены активной модели:

  1. (Необязательно, но рекомендуется) Предварительно загрузите новую модель, пока сервер работает:

    docker exec whisper whisper_manage --downloadmodel large-v3-turbo
  2. Обновите WHISPER_MODEL в файле whisper.env (или добавьте -e WHISPER_MODEL=large-v3-turbo в команду docker run).

  3. Перезапустите контейнер:

    docker restart whisper

Доступные модели:

Модель Диск ОЗУ (примерно) Примечания
tiny ~75 МБ ~250 МБ Самая быстрая; низкая точность
tiny.en ~75 МБ ~250 МБ Только английский
base ~145 МБ ~700 МБ Хороший баланс — по умолчанию
base.en ~145 МБ ~700 МБ Только английский
small ~465 МБ ~1,5 ГБ Повышенная точность
small.en ~465 МБ ~1,5 ГБ Только английский
medium ~1,5 ГБ ~5 ГБ Высокая точность
medium.en ~1,5 ГБ ~5 ГБ Только английский
large-v1 ~3 ГБ ~10 ГБ Старая большая модель
large-v2 ~3 ГБ ~10 ГБ Очень высокая точность
large-v3 ~3 ГБ ~10 ГБ Наивысшая точность
large-v3-turbo ~1,6 ГБ ~6 ГБ Быстрая + высокая точность ⭐
turbo ~1,6 ГБ ~6 ГБ Псевдоним для large-v3-turbo

Совет: large-v3-turbo обеспечивает точность, близкую к large-v3, при вдвое меньшем потреблении ресурсов. Для большинства производственных развёртываний это рекомендуемый вариант обновления с base.

Данные по памяти являются приблизительными и учитывают квантование INT8 (по умолчанию). Модели кэшируются в Docker-томе /var/lib/whisper и загружаются только один раз.

Защита сервера

Если ваш сервер Whisper доступен из публичной сети — даже кратковременно — примените как минимум следующие меры защиты. Whisper требует значительных ресурсов CPU/GPU, поэтому неаутентифицированная конечная точка может быть использована для расходования ваших вычислительных ресурсов.

1. Используйте API-ключ. Новые установки с подключённым томом /var/lib/whisper автоматически генерируют API-ключ. Его можно посмотреть командой docker exec whisper whisper_manage --showkey; в скриптах используйте docker exec whisper whisper_manage --getkey. Существующие установки без ключа остаются открытыми для обратной совместимости; также можно задать WHISPER_API_KEY в env-файле вручную. Все аутентифицированные запросы должны содержать Authorization: Bearer <key>.

# Сгенерировать 32-байтовый случайный ключ
openssl rand -hex 32

2. Привяжите к localhost при использовании обратного прокси. Замените -p 9000:9000 на -p 127.0.0.1:9000:9000 (или измените "9000:9000/tcp" на "127.0.0.1:9000:9000/tcp" в docker-compose.yml), чтобы незашифрованный порт нельзя было достичь напрямую снаружи хоста.

3. Ограничьте размер загружаемых файлов. Сервер отклоняет загрузки больше WHISPER_MAX_UPLOAD_MB (по умолчанию 1024). Для развёртываний, доступных из интернета, также настройте обратный прокси на отклонение слишком больших загрузок до того, как они достигнут приложения (например, nginx client_max_body_size 100M;).

4. Следите за уровнем журналирования. При WHISPER_LOG_LEVEL=DEBUG текст транскрипции может попадать в журналы. На общих системах сохраняйте уровень INFO или выше.

5. Включите CORS на прокси при вызове из браузера. Сервер по умолчанию не устанавливает заголовки Access-Control-Allow-Origin; добавьте их на обратном прокси, если планируете вызывать API напрямую с веб-страницы другого источника.

6. Рассмотрите ограничение частоты запросов. Разместите перед сервером ограничитель частоты (например, nginx limit_req_zone, Caddy rate_limit), чтобы ограничить количество одновременных запросов транскрипции на один IP-адрес клиента.

Использование обратного прокси

Для развёртывания с выходом в интернет разместите обратный прокси перед Whisper для обработки HTTPS-терминации. Сервер работает без HTTPS в локальной или доверенной сети, но HTTPS рекомендуется при открытом доступе к API-эндпоинту из интернета.

Используйте один из следующих адресов для доступа к контейнеру Whisper из обратного прокси:

  • whisper:9000 — если ваш обратный прокси работает как контейнер в той же Docker-сети, что и Whisper (например, определён в том же docker-compose.yml).
  • 127.0.0.1:9000 — если ваш обратный прокси работает на хосте и порт 9000 опубликован (по умолчанию docker-compose.yml публикует его).

Пример с Caddy (Docker-образ) (автоматический TLS через Let's Encrypt, обратный прокси в той же Docker-сети):

Caddyfile:

whisper.example.com {
  reverse_proxy whisper:9000
}

Пример с nginx (обратный прокси на хосте):

server {
    listen 443 ssl;
    server_name whisper.example.com;

    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Аудиофайлы могут быть большими — увеличьте лимит загрузки при необходимости
    client_max_body_size 100M;

    location / {
        proxy_pass         http://127.0.0.1:9000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;       # требуется для потоковой передачи (SSE)
        proxy_read_timeout 300s;
    }
}

Обновление Docker-образа

Для обновления Docker-образа и контейнера сначала скачайте последнюю версию:

docker pull hwdsl2/whisper-server

Если образ уже актуален, вы увидите:

Status: Image is up to date for hwdsl2/whisper-server:latest

В противном случае будет скачана последняя версия. Удалите и пересоздайте контейнер:

docker rm -f whisper
# Затем повторно выполните команду docker run из раздела "Быстрый старт" с теми же томом и портом.

Скачанные модели сохранятся в томе whisper-data.

Использование с другими AI-сервисами

Whisper можно использовать как службу распознавания речи в более широком self-hosted AI-стеке.

Готовые полные и облегчённые стеки Docker Compose, примеры ручного запуска через docker run, а также примеры голосовых, RAG- и MCP-конвейеров с Kokoro, Embeddings, LiteLLM, Ollama, Docling и MCP Gateway см. в Self-Hosted AI Stack.

Диаризация говорящих

Диаризация определяет, кто говорит в каждом транскрибированном сегменте. Это локальное расширение на базе sherpa-onnx с использованием модели pyannote segmentation-3.0, экспортированной в формат ONNX.

Включение диаризации:

# В whisper.env:
WHISPER_DIARIZATION=true

ONNX-модели (~45 МБ суммарно) автоматически загружаются при первом использовании и кэшируются в томе /var/lib/whisper. Предварительная загрузка:

docker exec whisper whisper_manage --downloaddiarize

Вывод с включённой диаризацией:

verbose_json добавляет поле speaker в каждый сегмент:

{
  "segments": [
    {"id": 0, "start": 1.0, "end": 3.5, "text": "Запускаем на следующей неделе.", "speaker": "SPEAKER_00"},
    {"id": 1, "start": 4.0, "end": 6.2, "text": "Думаю, QA нужно ещё два дня.", "speaker": "SPEAKER_01"}
  ]
}

srt и vtt добавляют метку говорящего:

1
00:00:01,000 --> 00:00:03,500
[SPEAKER_00] Запускаем на следующей неделе.

2
00:00:04,000 --> 00:00:06,200
[SPEAKER_01] Думаю, QA нужно ещё два дня.

Формат text показывает метку при смене говорящего:

[SPEAKER_00] Запускаем на следующей неделе.
[SPEAKER_01] Думаю, QA нужно ещё два дня.

Примечания:

  • Диаризация требует анализа полного аудио и не поддерживается в потоковом режиме (stream=true). Если оба включены, диаризация пропускается.
  • Установите WHISPER_DIARIZE_NUM_SPEAKERS, если известно точное количество говорящих, для повышения точности.
  • Конвейер диаризации запускается после транскрибирования, добавляя небольшое время обработки, пропорциональное длительности аудио.

Счётчики использования

Этот образ использует публичные счётчики скачиваний GitHub Release assets для анонимной агрегированной статистики использования. Эти числа приблизительны и не являются количеством уникальных пользователей или активных установок. Образ не отправляет telemetry payload и не использует частный сборщик. Он выполняет только best-effort запрос после успешного запуска сервера с подключённым томом /var/lib/whisper, а также при первом запуске другой сборки образа для этой постоянной установки. Чтобы отключить это, задайте WHISPER_DISABLE_USAGE_COUNTS=1.

Технические подробности

  • Базовый образ: python:3.12-slim для :latest; nvidia/cuda для :cuda
  • Среда выполнения: Python 3 (виртуальное окружение в /opt/venv)
  • STT-движок: faster-whisper + CTranslate2 (INT8 по умолчанию на CPU, FP16 на CUDA)
  • API-фреймворк: FastAPI + Uvicorn
  • Декодирование аудио: PyAV (встроенные библиотеки FFmpeg)
  • Директория данных: /var/lib/whisper (Docker-том)
  • Хранение моделей: формат HuggingFace Hub внутри тома — скачивается один раз, переиспользуется при перезапусках

Лицензия

Примечание: Программные компоненты внутри готового образа (такие как faster-whisper и его зависимости) распространяются под лицензиями, выбранными соответствующими правообладателями. При использовании готового образа пользователь несёт ответственность за соблюдение всех соответствующих лицензий на программное обеспечение, содержащееся в образе.

Copyright (C) 2026 Lin Song
Данная работа распространяется под лицензией MIT.

faster-whisper является собственностью SYSTRAN и распространяется под лицензией MIT.

Данный проект представляет собой независимую Docker-обёртку для Whisper и не аффилирован с OpenAI или SYSTRAN, не одобрен и не спонсирован ими.