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

Отримати VPS arrow_forward
eco Початковий Туторіал

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

calendar_month Sep 18, 2026 schedule 19 хв. читання visibility 66 переглядів
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, видаліть рядок 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: команда може видалити образи, потрібні для швидкого відкату.

Усунення несправностей + 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 та вартості інфраструктури.

Чи був цей гайд корисним?

Ваш відгук допомагає нам покращувати гайди.

Share this post:

Надішліть гайд тому, кому він може стати в пригоді.

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.