bolt Valebyte VPS от $4/мес — NVMe, запуск за 60 секунд.

Получить VPS arrow_forward
eco Начальный Туториал

WhisperX на VPS: транскрибация с таймкодами и разделением голосов

calendar_month Sep 18, 2026 schedule 19 мин. чтения visibility 64 просмотров
WhisperX на VPS: транскрибация с таймкодами и разделением голосов
info

Нужен сервер для этого гайда? Мы предлагаем выделенные серверы и VPS в 50+ странах с мгновенной настройкой.

Нужен сервер для этого гайда?

Разверните VPS или выделенный сервер за минуты.

WhisperX на VPS: транскрибация с таймкодами и разделением голосов

TL;DR

WhisperX позволяет развернуть на VPS собственный сервис транскрибации аудио и видео: получить текст, точные таймкоды слов и сегментов, а также разделить реплики разных спикеров. В этом руководстве будет настроен Docker-сервис с GPU-ускорением, API для запуска задач, HTTPS через Caddy, безопасный доступ и резервное копирование.

  • Для тестов достаточно CPU VPS с 8 vCPU и 16 ГБ RAM, но для регулярной обработки нужен GPU с 12–24 ГБ VRAM.
  • WhisperX использует Whisper для распознавания, выравнивание для таймкодов слов и pyannote.audio для диаризации.
  • Результатом будут JSON, SRT, VTT и TXT-файлы с временными метками и идентификаторами спикеров.
  • Секретный токен Hugging Face для моделей диаризации хранится в файле .env, а не в исходном коде.
  • Docker Compose упрощает обновления, изоляцию зависимостей CUDA и перезапуск сервиса после сбоя.
  • Исходные записи и результаты нужно хранить вне контейнера и регулярно копировать на S3 или отдельный сервер.

Что мы настраиваем и зачем

Схема: Что мы настраиваем и зачем
Схема: Что мы настраиваем и зачем

WhisperX — инструмент для локальной транскрибации, построенный вокруг моделей Whisper и faster-whisper. В отличие от базового запуска Whisper, он добавляет выравнивание текста с аудиосигналом: в результате можно получить не только фразу с примерным временем начала, но и таймкоды отдельных слов. Это полезно для субтитров, расшифровок интервью, монтажа подкастов, поиска по видеоархиву и подготовки протоколов встреч.

Вторая важная функция — диаризация, то есть разделение голосов. После обработки записи сервис присваивает сегментам метки вида SPEAKER_00, SPEAKER_01 и так далее. WhisperX не знает имена людей автоматически: он определяет, какие фрагменты принадлежат одному и тому же голосу. Имена можно переименовать позже в редакторе субтитров либо в JSON-результате.

В этом гайде будет развернут внутренний HTTP API на Python. Он принимает путь к уже загруженному медиафайлу, запускает WhisperX внутри Docker-контейнера, сохраняет результаты в каталог задач и возвращает JSON. Перед API будет установлен Caddy, который автоматически получает TLS-сертификат Let’s Encrypt и закрывает сервис HTTP Basic Auth. Такой подход подходит для одного владельца VPS, небольшой команды или внутреннего инструмента SaaS.

Что получится после настройки

  • HTTPS-адрес вида https://transcribe.example.com.
  • Защищённый API с endpoint’ами /health и /transcribe.
  • Обработка MP3, WAV, M4A, MP4, MKV и других форматов, которые понимает FFmpeg.
  • Автоматическая генерация result.json, result.srt, result.vtt и result.txt.
  • Таймкоды сегментов и слов для поддерживаемых языков.
  • Разделение реплик до заданного количества спикеров.
  • Автоматический перезапуск контейнера после перезагрузки VPS.

Как выглядит поток обработки

  1. Вы загружаете исходный файл в каталог /opt/whisperx/data/inbox через SFTP, SCP, rsync или отдельную форму загрузки.
  2. Клиент отправляет API имя файла, язык и параметры модели.
  3. FastAPI запускает отдельный процесс WhisperX внутри контейнера.
  4. WhisperX извлекает аудиодорожку через FFmpeg, распознаёт речь и получает сегменты.
  5. Модель alignment уточняет границы слов, если для языка доступна модель выравнивания.
  6. pyannote.audio выполняет диаризацию и связывает временные интервалы со спикерами.
  7. API сохраняет готовые артефакты в каталоге задачи и отдаёт ссылки на них через внутреннюю файловую раздачу.

Облачные сервисы и self-hosted: что выбрать

Критерий Облачный API транскрибации WhisperX на своём VPS
Старт Быстро: регистрация и API-ключ Нужна настройка Linux, Docker и домена
Цена при большом объёме Обычно оплата за минуту аудио Фиксированная аренда инфраструктуры
Конфиденциальность Файлы передаются внешнему поставщику Записи и результаты остаются под вашим контролем
Качество Зависит от выбранного продукта Можно менять модели Whisper и параметры обработки
Диаризация Часто доступна как платная функция Работает через pyannote.audio при наличии токена
Ограничения Лимиты API, файлов и минут Ограничены GPU, диском и скоростью вашей системы

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

Важно: диаризация не является идентификацией личности. Метка SPEAKER_00 означает «один и тот же голос в этой записи», а не конкретного человека. Для именного распознавания требуются отдельные модели и законное основание для обработки биометрических данных.

Какой VPS-конфиг нужен под эту задачу

Схема: Какой VPS-конфиг нужен под эту задачу
Схема: Какой VPS-конфиг нужен под эту задачу

Главный ресурс для WhisperX — не CPU, а видеопамять GPU. На CPU сервис работает, но обработка длинных файлов будет медленной, а диаризация дополнительно нагружает память. Для эпизодических коротких расшифровок подойдёт CPU VPS; для подкастов, видеолекций и очереди задач выбирайте GPU VPS с NVIDIA GPU и доступом к CUDA.

Сценарий CPU RAM GPU / VRAM Диск NVMe Практический результат
Тесты и редкие записи 8 vCPU 16 ГБ Без GPU 150 ГБ Работает, но часы аудио могут обрабатываться часами
Небольшая команда 8–12 vCPU 32 ГБ NVIDIA 12–16 ГБ VRAM 300 ГБ Модели medium/large-v3, регулярная обработка
Контент-команда или SaaS 16 vCPU 64 ГБ NVIDIA 24 ГБ VRAM 500 ГБ–1 ТБ Несколько задач в очереди, large-v3 и диаризация
Высокая нагрузка 24+ ядер 128 ГБ Несколько GPU по 24+ ГБ 1 ТБ+ Параллельные воркеры, отдельная очередь задач

Для описанной базовой установки рационален GPU VPS с 8–12 vCPU, 32 ГБ RAM, NVMe-диском от 300 ГБ и NVIDIA GPU с 16 ГБ VRAM. При выборе можно взять VPS с указанными характеристиками, если в конфигурации явно заявлены модель видеокарты, объём VRAM, поддержка CUDA и возможность использовать GPU из Docker.

Выбор модели и влияние на ресурсы

Модель Когда использовать Ориентир по VRAM Особенности
small Черновики, короткие заметки, экономия ресурсов 4–6 ГБ Быстрая, но менее устойчива к шуму и акцентам
medium Рабочий баланс качества и цены 8–12 ГБ Хороший выбор для русского и смешанной речи
large-v3 Публикация, сложный звук, многоязычные записи 14–20 ГБ Лучшее качество, выше задержка и требования

Указанные значения приблизительны: на фактическую память влияют размер батча, тип вычислений, длина записи, диаризация и версии библиотек. Для GPU обычно используют compute_type=float16. На CPU применяйте int8, иначе обработка станет заметно медленнее и может не поместиться в RAM.

Когда VPS недостаточно

Dedicated-сервер нужен, когда GPU не пробрасывается в виртуальную машину, требуется гарантированная производительность без влияния соседей, планируются непрерывные задачи или обработка конфиденциальных архивов объёмом в терабайты. Он также оправдан при нескольких GPU и параллельной обработке десятков файлов. Для одной-двух последовательных задач GPU VPS обычно проще, дешевле и легче масштабируется заменой тарифа.

Локация сервера

Локация влияет прежде всего на задержку загрузки исходных файлов, юрисдикцию персональных данных и скорость доступа команды к результатам. Если видео пишутся в Европе и содержат данные клиентов из ЕС, разумно выбрать европейский дата-центр и заранее определить срок хранения. Для файлов по 5–20 ГБ разница в канале важнее задержки: нужен реальный входящий и исходящий канал не менее 1 Гбит/с либо близкое к нему значение без агрессивных лимитов трафика.

Подготовка сервера

Схема: Подготовка сервера
Схема: Подготовка сервера

Ниже предполагается свежий Ubuntu Server 24.04 LTS. В 2026 году это стабильный и удобный вариант для Docker, NVIDIA Container Toolkit и Caddy. Выполняйте первоначальные действия от пользователя, который получил доступ после провижининга. Не публикуйте API до настройки ключей SSH и firewall.

Обновите систему и установите базовые утилиты

sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg git jq ufw fail2ban \
  unattended-upgrades rsync python3-venv

Первая команда устанавливает актуальные патчи безопасности, вторая добавляет утилиты для установки Docker, диагностики, firewall и копирования резервных копий.

Создайте отдельного администратора

sudo adduser deploy
sudo usermod -aG sudo deploy
sudo mkdir -p /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh

Пользователь deploy будет выполнять административные действия через sudo. Добавьте в файл /home/deploy/.ssh/authorized_keys ваш публичный SSH-ключ и выставьте права 600.

sudo nano /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh

Вставьте одну строку публичного ключа, например начинающуюся с ssh-ed25519. До отключения парольного входа обязательно откройте вторую SSH-сессию и проверьте, что вход пользователем deploy по ключу работает.

Закройте парольный SSH-доступ

sudo tee /etc/ssh/sshd_config.d/99-hardening.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
EOF
sudo sshd -t && sudo systemctl reload ssh

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

Настройте UFW и Fail2ban

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo systemctl enable --now fail2ban

Открыты только SSH, HTTP и HTTPS. Порт внутреннего API 8000 наружу не публикуется: Caddy будет обращаться к нему по локальной сети Docker. Проверить правила можно командой sudo ufw status verbose.

Подготовьте DNS

Создайте A-запись, например transcribe.example.com, которая указывает на публичный IPv4-адрес VPS. Если используете IPv6, добавьте AAAA-запись только при корректно настроенном IPv6 firewall. До запуска Caddy убедитесь, что команда dig +short transcribe.example.com возвращает IP вашего сервера, иначе автоматическое получение сертификата не сработает.

Проверьте GPU до установки приложения

Если выбран GPU VPS, драйвер NVIDIA обычно уже установлен образом провайдера. Выполните проверку:

nvidia-smi

В выводе должны быть видны версия драйвера, версия поддерживаемой CUDA и видеокарта. Если команда не найдена или показывает ошибку связи с драйвером, сначала исправьте это в панели VPS или установите подходящий драйвер NVIDIA для Ubuntu. Не переходите к контейнерам, пока nvidia-smi не работает на хосте.

Установка ПО — пошагово

Схема: Установка ПО — пошагово
Схема: Установка ПО — пошагово

Для изоляции зависимостей будет использован Docker Engine 27+ или более новый совместимый выпуск, Docker Compose v2 и NVIDIA Container Toolkit. WhisperX активно зависит от PyTorch, CUDA, FFmpeg, CTranslate2 и pyannote.audio; контейнер избавляет от конфликтов между системными пакетами.

Установите Docker Engine из официального репозитория

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Этот блок добавляет ключ подписи официального репозитория Docker. Не устанавливайте устаревший пакет docker.io одновременно с Docker Engine из официального репозитория.

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Команда подключает репозиторий и устанавливает Docker Engine, Buildx и Compose. Проверьте установку:

sudo docker run --rm hello-world
sudo usermod -aG docker deploy

Первый запуск скачает тестовый образ и подтвердит работоспособность демона. После добавления пользователя в группу docker выйдите из SSH и войдите снова. Членство в этой группе даёт права, близкие к root, поэтому добавляйте в неё только администраторов.

Установите NVIDIA Container Toolkit

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#' | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

Этот блок добавляет официальный репозиторий NVIDIA Container Toolkit. Он позволяет Docker-контейнеру использовать драйвер GPU, установленный на хостовой системе.

sudo apt update
sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

После настройки runtime протестируйте проброс GPU в контейнер. Тег CUDA ниже является примером совместимого базового образа; при проблемах сверяйте его версию с версией драйвера из nvidia-smi.

docker run --rm --gpus all nvidia/cuda:12.6.3-base-ubuntu24.04 nvidia-smi

Если в выводе контейнера видна ваша видеокарта, GPU готов для WhisperX. На CPU-only VPS этот шаг пропустите, а в конфигурации ниже установите DEVICE=cpu и COMPUTE_TYPE=int8.

Создайте структуру проекта

sudo mkdir -p /opt/whisperx/{app,data/inbox,data/jobs,models,caddy}
sudo chown -R deploy:deploy /opt/whisperx
cd /opt/whisperx

Каталог data/inbox хранит входные файлы, data/jobs — результаты, а models — скачанные модели. Модели нужно держать на постоянном томе, иначе они будут загружаться повторно при пересоздании контейнера.

Создайте Dockerfile для API и WhisperX

FROM nvidia/cuda:12.6.3-cudnn-runtime-ubuntu24.04

ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1
ENV PIP_NO_CACHE_DIR=1

RUN apt-get update && apt-get install -y --no-install-recommends \
    python3 python3-pip python3-venv ffmpeg git ca-certificates \
    && rm -rf /var/lib/apt/lists/

RUN python3 -m pip install --break-system-packages \
    "torch==2.6.0" "torchaudio==2.6.0" \
    --index-url https://download.pytorch.org/whl/cu126

RUN python3 -m pip install --break-system-packages \
    "whisperx==3.3.1" "fastapi==0.115.8" \
    "uvicorn[standard]==0.34.0" "python-multipart==0.0.20"

WORKDIR /app
COPY app/ /app/
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Dockerfile фиксирует основные версии на уровне образа. WhisperX и связанные ML-библиотеки развиваются быстро, поэтому перед крупным обновлением тестируйте новый образ на копии записи. Не обновляйте PyTorch, CUDA и WhisperX одновременно на production-сервере.

Создайте API-приложение

mkdir -p /opt/whisperx/app
nano /opt/whisperx/app/main.py

Вставьте следующий код. Он разрешает только файлы из /data/inbox, не принимает произвольные пути и создаёт уникальный каталог результата для каждого запуска.

import json
import os
import subprocess
import uuid
from pathlib import Path

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field

app = FastAPI(title="WhisperX API", version="1.0")

INBOX = Path("/data/inbox").resolve()
JOBS = Path("/data/jobs").resolve()
DEVICE = os.getenv("DEVICE", "cuda")
COMPUTE_TYPE = os.getenv("COMPUTE_TYPE", "float16")
DEFAULT_MODEL = os.getenv("WHISPER_MODEL", "large-v3")
HF_TOKEN = os.getenv("HF_TOKEN", "")

class TranscribeRequest(BaseModel):
    filename: str = Field(pattern=r"^[A-Za-z0-9._ -]+$")
    language: str = Field(default="ru", min_length=2, max_length=5)
    model: str = Field(default=DEFAULT_MODEL)
    min_speakers: int | None = Field(default=None, ge=1, le=20)
    max_speakers: int | None = Field(default=None, ge=1, le=20)

@app.get("/health")
def health():
    return {"status": "ok", "device": DEVICE, "model": DEFAULT_MODEL}

@app.post("/transcribe")
def transcribe(payload: TranscribeRequest):
    source = (INBOX / payload.filename).resolve()
    if INBOX not in source.parents or not source.is_file():
        raise HTTPException(status_code=404, detail="Файл не найден в inbox")

    job_id = str(uuid.uuid4())
    output_dir = JOBS / job_id
    output_dir.mkdir(parents=True, exist_ok=False)

    command = [
        "whisperx", str(source),
        "--model", payload.model,
        "--language", payload.language,
        "--device", DEVICE,
        "--compute_type", COMPUTE_TYPE,
        "--output_dir", str(output_dir),
        "--output_format", "all",
    ]

    if HF_TOKEN:
        command.extend(["--diarize", "--hf_token", HF_TOKEN])

    if payload.min_speakers:
        command.extend(["--min_speakers", str(payload.min_speakers)])
    if payload.max_speakers:
        command.extend(["--max_speakers", str(payload.max_speakers)])

    completed = subprocess.run(
        command, text=True, stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT, timeout=14400
    )

    (output_dir / "whisperx.log").write_text(
        completed.stdout, encoding="utf-8"
    )

    if completed.returncode != 0:
        raise HTTPException(
            status_code=500,
            detail={"job_id": job_id, "log": completed.stdout[-3000:]}
        )

    files = [item.name for item in output_dir.iterdir() if item.is_file()]
    return {"job_id": job_id, "status": "done", "files": files}

Для production с несколькими пользователями не запускайте тяжёлую обработку синхронно в HTTP-запросе: добавьте очередь Redis и воркеры Celery, RQ или Dramatiq. В текущем варианте один запрос занимает соединение до завершения задачи, что приемлемо для личного внутреннего сервиса и последовательной обработки.

Конфигурация

Схема: Конфигурация
Схема: Конфигурация

Получите токен для диаризации

WhisperX использует gated-модели pyannote.audio для разделения голосов. Создайте аккаунт Hugging Face, примите условия доступа к требуемым моделям диаризации в интерфейсе Hugging Face и создайте токен с правом чтения. Не передавайте этот токен в URL, Git-репозиторий, историю shell-команд или frontend-код.

Создайте файл окружения с ограниченными правами:

cd /opt/whisperx
nano .env
chmod 600 .env
HF_TOKEN=hf_замените_на_реальный_токен
DEVICE=cuda
COMPUTE_TYPE=float16
WHISPER_MODEL=large-v3
DOMAIN=transcribe.example.com
BASIC_AUTH_USER=operator
BASIC_AUTH_HASH=ЗАМЕНИТЕ_НА_BCRYPT_ХЕШ

Для CPU VPS измените параметры на DEVICE=cpu, COMPUTE_TYPE=int8 и обычно начните с WHISPER_MODEL=small или medium. Модель large-v3 на CPU возможна, но для длинных записей будет непрактична.

Сгенерируйте пароль для Caddy

docker run --rm caddy:2.9.1 caddy hash-password \
  --plaintext 'СЛОЖНЫЙ_УНИКАЛЬНЫЙ_ПАРОЛЬ'

Скопируйте значение, начинающееся с $2a$ или похожее, в BASIC_AUTH_HASH. Если shell интерпретирует символ $, заключите значение в одинарные кавычки в файле Compose либо экранируйте доллары как $$.

Создайте Docker Compose

services:
  whisperx:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: whisperx-api
    restart: unless-stopped
    env_file:
      - .env
    environment:
      - HF_HOME=/models/huggingface
      - TORCH_HOME=/models/torch
    volumes:
      - ./data:/data
      - ./models:/models
    expose:
      - "8000"
    gpus: all
    shm_size: "2gb"

  caddy:
    image: caddy:2.9.1
    container_name: whisperx-caddy
    restart: unless-stopped
    depends_on:
      - whisperx
    env_file:
      - .env
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

Параметр gpus: all даёт контейнеру доступ ко всем доступным GPU. Если это CPU-only сервер, удалите строку gpus: all. Ограничение shm_size снижает вероятность ошибок shared memory у некоторых библиотек PyTorch.

Настройте HTTPS и reverse proxy через Caddy

nano /opt/whisperx/caddy/Caddyfile
{$DOMAIN} {
    encode zstd gzip

    basic_auth {
        {$BASIC_AUTH_USER} {$BASIC_AUTH_HASH}
    }

    reverse_proxy whisperx:8000

    log {
        output stdout
        format json
    }
}

Caddy автоматически запросит и продлит TLS-сертификат, если DNS-запись уже указывает на сервер, а порты 80 и 443 доступны извне. Внутренний контейнер API не имеет опубликованного порта, поэтому к нему нельзя обратиться напрямую с интернета.

Запустите сервис и проверьте журналы

cd /opt/whisperx
docker compose build --pull
docker compose up -d
docker compose ps
docker compose logs -f --tail=100

Сборка первого образа может занять несколько минут. При первом запросе WhisperX также скачивает модель распознавания и модели выравнивания; время зависит от скорости сети и размера выбранной модели.

Проверьте healthcheck

curl -u 'operator:СЛОЖНЫЙ_УНИКАЛЬНЫЙ_ПАРОЛЬ' \
  https://transcribe.example.com/health

Ожидаемый ответ:

{"status":"ok","device":"cuda","model":"large-v3"}

Загрузите тестовый файл и запустите транскрибацию

scp interview.mp3 deploy@SERVER_IP:/opt/whisperx/data/inbox/
curl -u 'operator:СЛОЖНЫЙ_УНИКАЛЬНЫЙ_ПАРОЛЬ' \
  -X POST https://transcribe.example.com/transcribe \
  -H 'Content-Type: application/json' \
  -d '{"filename":"interview.mp3","language":"ru","model":"large-v3","min_speakers":2,"max_speakers":2}'

В ответе вы получите идентификатор задачи и имена созданных файлов. Проверьте содержимое каталога:

ls -lah /opt/whisperx/data/jobs/ИДЕНТИФИКАТОР_ЗАДАЧИ
cat /opt/whisperx/data/jobs/ИДЕНТИФИКАТОР_ЗАДАЧИ/interview.json | jq '.segments[0]'

В JSON у сегментов должны присутствовать поля start, end, text и, при успешной диаризации, speaker. Внутри слов могут быть более точные временные поля. Файлы SRT и VTT удобно импортировать в DaVinci Resolve, Premiere Pro, YouTube Studio или редакторы субтитров.

Практика безопасности: Basic Auth достаточен для личного внутреннего API, но не заменяет полноценную авторизацию многопользовательского продукта. Для команды добавьте VPN, IP allowlist, OAuth-прокси или собственную аутентификацию с журналом действий и ограничением скорости запросов.

Бэкапы и обслуживание

Схема: Бэкапы и обслуживание
Схема: Бэкапы и обслуживание

Контейнер сам по себе не является резервной копией. При пересоздании VPS будут потеряны входные записи, результаты, конфигурация, токены и данные TLS, если они находятся только на локальном диске. Модели Whisper можно скачать повторно, но их тоже полезно кэшировать, чтобы быстрее восстановиться после сбоя.

Что нужно бэкапить

  • /opt/whisperx/.env — токен, параметры устройства и настройки доступа. Храните его в зашифрованном бэкапе.
  • /opt/whisperx/docker-compose.yml, Dockerfile, app/ и caddy/Caddyfile.
  • /opt/whisperx/data/jobs — готовые расшифровки, логи и субтитры.
  • /opt/whisperx/data/inbox — только если исходники нельзя восстановить из другого хранилища.
  • Docker volumes Caddy — сертификаты и конфигурация. Они ускоряют восстановление, хотя сертификат можно выпустить заново.

Не обязательно бессрочно хранить исходное видео. Для приватных записей безопаснее установить правило: например, удалять файлы из inbox спустя 7 дней после успешной транскрибации, а результаты — спустя 90 дней. Политика хранения должна соответствовать договорённостям с участниками записи и применимому законодательству.

Настройте restic для внешнего S3-совместимого хранилища

sudo apt install -y restic
sudo mkdir -p /root/.config/restic
sudo chmod 700 /root/.config/restic
sudo nano /root/.config/restic/whisperx.env
sudo chmod 600 /root/.config/restic/whisperx.env

Файл окружения содержит реквизиты удалённого хранилища. Используйте отдельный бакет и отдельный ключ с минимально необходимыми правами.

RESTIC_REPOSITORY=s3:https://s3.example.net/whisperx-backups
RESTIC_PASSWORD=длинный_случайный_пароль_репозитория
AWS_ACCESS_KEY_ID=ваш_ключ
AWS_SECRET_ACCESS_KEY=ваш_секрет
AWS_DEFAULT_REGION=us-east-1

Инициализируйте репозиторий один раз:

sudo bash -c 'source /root/.config/restic/whisperx.env && restic init'

Создайте скрипт ежедневного бэкапа

sudo nano /usr/local/sbin/backup-whisperx.sh
sudo chmod 700 /usr/local/sbin/backup-whisperx.sh
#!/usr/bin/env bash
set -euo pipefail

source /root/.config/restic/whisperx.env

restic backup /opt/whisperx \
  --exclude='/opt/whisperx/models' \
  --exclude='/opt/whisperx/data/inbox/.tmp' \
  --tag whisperx

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check

Скрипт исключает кэш моделей: при необходимости он скачивается заново и часто занимает десятки гигабайт. Если у вас слабый интернет-канал или критичен быстрый disaster recovery, уберите исключение models, но заранее оцените стоимость хранения и трафика.

sudo crontab -e
20 3   * /usr/local/sbin/backup-whisperx.sh >> /var/log/backup-whisperx.log 2>&1

Задача запускается ежедневно в 03:20. Раз в месяц обязательно тестируйте восстановление на отдельном каталоге или тестовом VPS:

sudo bash -c 'source /root/.config/restic/whisperx.env && \
  restic restore latest --target /tmp/whisperx-restore-test'

Обновления без сюрпризов

Для Caddy обычно допустимо rolling-обновление: измените закреплённый тег образа, выполните docker compose pull caddy и docker compose up -d. Обновление WhisperX, PyTorch, CUDA или pyannote.audio проводите в maintenance window. Эти компоненты могут менять требования к модели, формат аргументов и потребление VRAM.

  1. Сделайте бэкап проекта и зафиксируйте текущие версии: docker compose images.
  2. Создайте копию каталога на тестовом сервере или отдельную ветку проекта.
  3. Соберите новый образ и обработайте эталонную запись на русском и на нужных вам языках.
  4. Сравните качество, скорость, наличие speaker-меток и формат JSON.
  5. Только после проверки обновляйте production и сохраняйте возможность отката на предыдущий тег образа.

Контроль диска, GPU и журналов

df -h /opt/whisperx
docker system df
nvidia-smi
docker compose logs --since=24h whisperx | tail -n 200

Оставляйте не менее 20% свободного места на NVMe: временные аудиофайлы, модели и результаты могут резко увеличить расход диска. Раз в неделю удаляйте ненужные исходники и старые результаты по утверждённому сроку хранения. Не используйте бездумно docker system prune -a на production: команда может удалить образы, нужные для быстрого отката.

Troubleshooting + FAQ

Почему контейнер пишет «could not select device driver nvidia»?

Ошибка означает, что Docker не видит NVIDIA runtime. Сначала проверьте nvidia-smi на самом VPS: без работающего драйвера контейнер ничего не исправит. Затем выполните dpkg -l | grep nvidia-container-toolkit и повторите настройку через sudo nvidia-ctk runtime configure --runtime=docker, после чего перезапустите Docker. Проверка docker run --rm --gpus all ... nvidia-smi должна работать до запуска WhisperX.

Почему возникает CUDA out of memory при запуске large-v3?

Не хватает видеопамяти для модели, батчей, выравнивания или диаризации. Сначала посмотрите занятость через nvidia-smi и остановите чужие GPU-процессы. Затем снизьте модель до medium, используйте compute_type=float16 и не запускайте несколько транскрибаций параллельно. Если качество large-v3 обязательно, нужен GPU с большим объёмом VRAM, обычно от 16–24 ГБ в зависимости от нагрузки.

Диаризация не запускается или появляется ошибка доступа к модели pyannote

Проверьте, что HF_TOKEN задан в .env, не содержит лишних кавычек и контейнер был пересоздан после изменения файла: docker compose up -d --force-recreate whisperx. У токена должно быть право чтения, а в аккаунте должны быть приняты условия доступа к gated-моделям pyannote. Посмотрите полный лог задачи в файле whisperx.log: там обычно указана точная причина отказа.

Почему в результате нет точных таймкодов слов?

WhisperX добавляет word-level timestamps через отдельную alignment-модель, но она доступна не для каждого языка и зависит от качества аудио. Проверьте, правильно ли передан параметр language: для русского используйте ru, а не произвольное название языка. На шумных записях с музыкой, перекрывающимися голосами или плохим микрофоном границы слов могут быть пропущены. Сегментные таймкоды при этом обычно сохраняются.

API отвечает 502 Bad Gateway через Caddy

Код 502 означает, что Caddy не получил корректный ответ от контейнера API. Проверьте статус через docker compose ps и журналы docker compose logs whisperx. Частая причина — контейнер завершился из-за ошибки Python, нехватки RAM или VRAM при старте. Также проверьте, что в Caddyfile указан хост whisperx:8000, совпадающий с именем сервиса Compose, а не внешний IP-адрес.

Какой VPS-конфиг минимально подойдёт?

Минимум для экспериментов — 8 vCPU, 16 ГБ RAM и 150 ГБ NVMe без GPU. На такой машине используйте small, DEVICE=cpu и COMPUTE_TYPE=int8; одна длинная запись может обрабатываться дольше её реальной длительности. Для комфортной регулярной работы с диаризацией практический минимум — 8 vCPU, 32 ГБ RAM, 300 ГБ NVMe и NVIDIA GPU с 12–16 ГБ VRAM.

Что выбрать — VPS или dedicated для этой задачи?

GPU VPS подходит для личного сервиса, небольшой команды и переменной нагрузки: он быстрее разворачивается и обычно проще масштабируется. Dedicated выбирайте, если нужна гарантированная производительность, постоянная обработка, несколько GPU, большие локальные архивы или строгие требования к изоляции. Важнее формата аренды наличие NVIDIA GPU, достаточной VRAM, NVMe-диска и возможности использовать GPU внутри Docker-контейнеров.

Почему транскрибация идёт слишком медленно?

Сначала убедитесь, что приложение реально использует GPU: в ответе /health должно быть device: cuda, а во время задачи команда nvidia-smi должна показывать Python-процесс. Если используется CPU, проверьте настройки Docker GPU runtime. На GPU ускорение также зависит от модели, качества входного файла и диаризации. Для чернового прохода используйте medium, а large-v3 запускайте только для финального текста.

Выводы и следующие шаги

Схема: Выводы и следующие шаги
Схема: Выводы и следующие шаги

Теперь на VPS работает собственный WhisperX-сервис: он принимает локально загруженные записи, создаёт транскрипцию, субтитры, таймкоды и метки спикеров. Доступ защищён HTTPS и Basic Auth, а конфигурация, результаты и секреты можно копировать во внешнее хранилище через restic.

  1. Добавьте очередь задач на Redis и отдельные worker-контейнеры, если нужно обрабатывать несколько файлов без долгих HTTP-запросов.
  2. Сделайте простую веб-форму загрузки с ограничением размера файлов, журналом задач и автоматической очисткой исходников.
  3. Протестируйте модели medium и large-v3 на своих записях, измерьте скорость и выберите баланс качества, VRAM и стоимости инфраструктуры.

Был ли этот гайд полезен?

Ваш отзыв помогает нам улучшать гайды.

Поделиться записью:

Отправьте гайд тому, кому он может пригодиться.

Telegram VKVK WhatsApp Facebook LinkedIn XX

whisperx на vps: транскрибация с таймкодами и разделением голосов
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.