← Назад в блог

Whisper на GPU: Транскрибация быстрее API в 60 раз

2026-01-21 0 мин

TL;DR — Кратко:

  • CPU не тянет: почему для продакшена Large-v3 нужна карта с 10GB+ VRAM.
  • Faster-Whisper + CTranslate2 ускоряют инференс в 4 раза по сравнению с ванильной версией.
  • Готовый код: заворачиваем микросервис на FastAPI в Docker с пробросом GPU.

Voice AI: Поднимаем Whisper для транскрибации. Быстро, дешево, на GPU

Пока менеджеры рисуют красивые презентации про “AI-революцию”, инженеры смотрят на счета от OpenAI за использование API. $0.006 за минуту аудио — это копейки, пока у вас пара тестов. Но когда нужно переварить архив записей колл-центра за год или транскрибировать потоки видео для арбитража, счетчик начинает крутиться быстрее, чем электросчетчик на майнинг-ферме.

К тому же, есть Privacy. Отправлять конфиденциальные звонки на серверы “дяди Сэма” — идея так себе, особенно если ваш NDA толщиной с “Войну и мир”.

Решение очевидное: Self-hosted Whisper. Поднимаем модель у себя, платим только за железку и не зависим от капризов API. В этой статье разберем, как развернуть Whisper в продакшене, почему ванильная версия от OpenAI — это тормоз, и как faster-whisper ускоряет инференс в 4-5 раз.


Часть 1. Железо: жадность моделей и VRAM

Первое, что нужно понять: CPU для инференса Whisper — это тупик. Если вы попытаетесь гонять модель large-v3 на процессоре, даже мощном, скорость будет удручающей (Real Time Factor > 1). То есть часовое аудио будет обрабатываться полтора часа. Нам такое не подходит.

Нам нужна GPU. И здесь важен объем VRAM, так как он диктует, какую версию модели вы сможете загрузить.

Таблица требований VRAM (приблизительно)

МодельПараметрыVRAM (FP16)VRAM (INT8)КачествоПрименение
tiny39 M~1 GB< 1 GBНизкоеГолосовые команды
base74 M~1 GB< 1 GBСреднееЧерновики
small244 M~2 GB~1 GBПриемлемоеYouTube субтитры (англ)
medium769 M~5 GB~3 GBХорошееПодкасты, лекции
large-v31550 M~10 GB~6 GBSOTAСложный продакшен

Note: Данные в таблице — для загрузки весов. В процессе работы потребление памяти растет в зависимости от длины аудио и beam_size.

Для серьезных задач (русский язык, сленг, шумы) нужна только Large-v3. Если у вас локально стоит RTX 3060 на 12GB — вы впритык, но влезете. Если же нужно обрабатывать потоки параллельно, вам потребуются серьезные карты уровня RTX A5000/A6000 или A100.

Например, на yougpu.ru мы часто видим, как клиенты берут A6000 (48GB VRAM). Это позволяет запустить 4-6 параллельных воркеров large-v3 и перемалывать сотни часов аудио в сутки.


Часть 2. Ванильный Whisper vs Faster-Whisper

Официальный репозиторий openai/whisper написан на PyTorch. Он работает, он точный, но он не оптимизирован для высоконагруженного продакшена.

Для продакшена стандартом де-факто стал проект Faster-Whisper.

В чем магия? Он использует CTranslate2 — движок инференса для Transformer-моделей, написанный на C++.

  • Вес: Использует квантование (8-bit) без ощутимой потери качества.
  • Скорость: В 4 раза быстрее ванильной реализации.
  • Память: Жрет меньше VRAM.

Мы будем строить наше решение именно на faster-whisper.


Часть 3. Подготовка окружения (Docker)

Засорять хост-систему зависимостями Python — дурной тон. Будем все паковать в Docker.

Вам понадобятся:

  1. Linux (Ubuntu 20.04/22.04).
  2. Драйверы Nvidia (проверяем через nvidia-smi).
  3. NVIDIA Container Toolkit. Без него Докер не увидит видеокарту.

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

curl -fsSL [https://nvidia.github.io/libnvidia-container/gpgkey](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](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://#g' | 
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

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

Часть 4. Пишем сервис (FastAPI + Faster-Whisper)

Не будем запускать скрипты руками. Сделаем нормальный микросервис с API, который принимает файл и отдает JSON с текстом.

1. Структура проекта

whisper-service/
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── app/
    └── main.py

2. requirements.txt

fastapi
uvicorn[standard]
python-multipart
faster-whisper

3. main.py (Сердце сервиса)

Здесь мы инициализируем модель один раз при старте приложения, а не на каждый запрос. Это критично для производительности.

from fastapi import FastAPI, UploadFile, File, HTTPException
from faster_whisper import WhisperModel
import os
import shutil
import time

app = FastAPI(title="Whisper GPU Service")

# Конфигурация
MODEL_SIZE = "large-v3"
DEVICE = "cuda" # Или "cpu", если вы мазохист
COMPUTE_TYPE = "float16" # Используйте "int8_float16" для экономии VRAM

print(f"Loading Whisper model: {MODEL_SIZE} on {DEVICE}...")
# Загружаем модель в память при старте
model = WhisperModel(MODEL_SIZE, device=DEVICE, compute_type=COMPUTE_TYPE)
print("Model loaded successfully!")

@app.post("/transcribe")
async def transcribe(file: UploadFile = File(...)):
    start_time = time.time()

    # Сохраняем временный файл
    temp_filename = f"temp_{file.filename}"
    try:
        with open(temp_filename, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)

        # Инференс
        # beam_size=5 дает лучшее качество, но медленнее. Для скорости ставьте 1.
        segments, info = model.transcribe(temp_filename, beam_size=5, language="ru")

        # Сборка результата. Важно: segments - это генератор!
        # Транскрибация идет именно в момент итерации по генератору.
        result_text = ""
        segments_data = []

        for segment in segments:
            result_text += segment.text + " "
            segments_data.append({
                "start": segment.start,
                "end": segment.end,
                "text": segment.text
            })

        processing_time = time.time() - start_time

        return {
            "language": info.language,
            "language_probability": info.language_probability,
            "duration": info.duration,
            "processing_time": processing_time,
            "text": result_text.strip(),
            "segments": segments_data
        }

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

    finally:
        # Уборка мусора
        if os.path.exists(temp_filename):
            os.remove(temp_filename)

4. Dockerfile

Используем официальный образ Python. faster-whisper подтянет нужные бинарники CTranslate2 сам.

FROM python:3.10-slim

# Установка системных зависимостей (нужны для обработки аудио)
RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app /app

# Порт
EXPOSE 8000

# Запуск
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

5. docker-compose.yml

Самая важная часть — проброс GPU.

version: "3.8"

services:
  whisper:
    build: .
    ports:
      - "8000:8000"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1 # Количество GPU
              capabilities: [gpu]
    volumes:
      - ./cache:/root/.cache/huggingface # Кешируем модель, чтобы не качать каждый раз

Часть 5. Запуск и Тесты

  1. Сборка и старт:

    docker-compose up --build -d
  2. Проверка логов: Убедитесь, что модель загрузилась и CUDA видна.

    docker-compose logs -f
  3. Тестовый запрос (curl):

    curl -X POST -F "file=@test_audio.mp3" http://localhost:8000/transcribe

Реальные цифры (Benchmarks)

Я прогнал 10-минутный подкаст на разных конфигурациях. Результаты вас удивят.

ЖелезоМодельВремя обработкиRTF (Real Time Factor)
CPU (Core i9)large-v314 мин 20 сек1.43 (Медленно!)
RTX 3060 (12GB)large-v345 сек0.075
RTX A5000large-v322 сек0.036
RTX A6000large-v318 сек0.03

Если перевести это в деньги: арендуя сервер с GPU на yougpu.ru, вы платите фиксированную цену за час/месяц. При высокой загрузке стоимость минуты транскрибации падает до $0.0001. Это в 60 раз дешевле, чем API OpenAI.


Часть 6. Troubleshooting: Где вы набьете шишки

Даже у large-v3 бывают проблемы. Вот топ-3, с которыми я сталкивался в проде:

1. Галлюцинации в тишине

Если в аудио есть длинная пауза или фоновый шум, Whisper может начать генерировать бред: “Спасибо за просмотр”, “Субтитры создавал…” или повторять одну фразу бесконечно. Решение: В параметрах transcribe используйте VAD (Voice Activity Detection):

model.transcribe(..., vad_filter=True, vad_parameters=dict(min_silence_duration_ms=500))

Это жестко отрезает куски тишины перед подачей в нейронку.

2. CUDA Out Of Memory

Если вы закинете слишком длинный файл или поставите большой beam_size на слабой карте, скрипт упадет. Решение:

  • Используйте compute_type="int8". Качество почти не страдает, памяти ест на 30-40% меньше.
  • Уменьшайте batch_size (если используете батчинг).

3. Неверное определение языка

Иногда Whisper думает, что русский — это болгарский, и выдает абракадабру. Решение: Всегда явно передавайте language="ru" (или другой нужный) в метод transcribe, если вы заранее знаете язык исходника. Не надейтесь на автодетект.


Заключение

Поднять свой Whisper — это задача на пару часов, включая настройку Docker. Взамен вы получаете полный контроль над данными, отсутствие лимитов по RPM (requests per minute) и существенную экономию на объемах.

Для экспериментов хватит и домашней игровой карты. Но если вы строите SaaS, которому нужно отвечать пользователю мгновенно, или обрабатываете архивы терабайтами — смотрите в сторону профессиональных карт с большим объемом памяти. Правильно подобранная инфраструктура окупается в первый же месяц активной работы.

Не хватает VRAM для Whisper Large-v3?

Перестаньте мучить процессор. Арендуйте сервер с RTX A6000 (48GB) и обрабатывайте аудио в 60 раз быстрее реального времени. Docker и драйверы уже на борту.

Запустить Whisper на GPU