Транскрибация совещаний на Whisper и Pyannote с Tesla V100: полный гайд | AiManual
AiManual Logo Ai / Manual.
12 Янв 2026 Гайд

Как собрать систему транскрибации совещаний на Whisper и Pyannote с Tesla V100: от покупки карты до развёртывания

Пошаговый гайд по сборке системы транскрибации совещаний на Whisper и Pyannote с Tesla V100 из AliExpress. От покупки карты до развёртывания.

Зачем платить за транскрибацию, если можно собрать свою систему за 17 тысяч рублей?

Помню тот день, когда получил счет от сервиса транскрибации: 2 часа аудио, 12 тысяч рублей. Это был последний раз. Сегодня моя система обрабатывает те же 2 часа за 4 минуты. И обошлась она мне в 17 тысяч рублей за видеокарту плюс пару дней настройки.

Секрет? Tesla V100 с AliExpress, Whisper от OpenAI и Pyannote для диаризации. Звучит как магия, но это просто инженерная задача, которую можно решить за выходные.

Результат: 2 часа аудио → 4 минуты обработки вместо 12 тысяч рублей за сервис. Окупаемость системы - меньше двух транскрибаций.

Ты точно хочешь покупать видеокарту с AliExpress?

Начну с главного страха. Tesla V100 за 17 тысяч рублей - это не новая карта. Это бывшее в употреблении оборудование из дата-центров. Риски есть, но их можно минимизировать.

1 Выбор и покупка Tesla V100

Идем на AliExpress и ищем "Tesla V100 16GB". Не 32GB - она дороже и для транскрибации не нужна. Сразу фильтруем по продавцам с рейтингом выше 97% и отзывами не меньше 100.

Что проверяем Как проверяем Что делать, если проблема
Стресс-тест FurMark + GPU-Z мониторинг температуры Возврат, если выше 85°C
Память memtest с CUDA Возврат при ошибках
Вентиляторы Тест на 100% скорости Замена вентиляторов (дешево)

Мой продавец назывался "GPU Server Store". Карта пришла в обычной коробке с пенопластом. Внешне - как новая. Внутри - отработала 3 года в дата-центре. Но для транскрибации это не проблема.

Важно: Tesla V100 - серверная карта. У нее нет видеовыходов. Не пытайся подключить к ней монитор. Это чисто для вычислений.

2 Подготовка системы: драйверы, CUDA и прочая магия

Вот где большинство спотыкается. Установка драйверов для Tesla - это не как для игровой карты. Делаем все по порядку.

# Удаляем все старые драйверы NVIDIA
sudo apt-get purge nvidia* cuda*
sudo apt-get autoremove

# Добавляем репозиторий
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
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/$distribution/libnvidia-container.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

# Устанавливаем драйвер для Tesla V100
sudo apt-get update
sudo apt-get install -y nvidia-driver-535 nvidia-container-toolkit

Перезагружаемся и проверяем:

nvidia-smi

Должна появиться таблица с Tesla V100. Если видишь "NVIDIA-SMI has failed", значит драйвер не встал. Возвращаемся к удалению и пробуем версию 525.

💡
Используй Ubuntu 22.04 LTS. На 20.04 могут быть проблемы с драйверами для Tesla V100. На 24.04 пока не все стабильно работает.

3 Установка Whisper: не ту версию, что в документации

Официальная установка через pip install whisper работает, но медленно. Мы будем использовать оптимизированную версию.

# Создаем виртуальное окружение
python3 -m venv whisper_env
source whisper_env/bin/activate

# Ставим PyTorch с поддержкой CUDA 11.8 (важно для V100)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# Whisper с оптимизациями
pip install faster-whisper

Почему faster-whisper? Потому что он в 4 раза быстрее на длинных аудио. Использует CTranslate2 под капотом. Разница в качестве транскрипции незаметна для человеческого уха.

4 Pyannote для диаризации: кто сказал что

Whisper транскрибирует, но не различает говорящих. Для этого нужен Pyannote. Но есть нюанс: последние версии требуют Hugging Face токен.

pip install pyannote.audio

Теперь идем на Hugging Face, создаем аккаунт и получаем токен. Затем:

from pyannote.audio import Pipeline

pipeline = Pipeline.from_pretrained(
    "pyannote/speaker-diarization-3.1",
    use_auth_token="ВАШ_ТОКЕН_ЗДЕСЬ"
)

# Отправляем на GPU
pipeline.to(torch.device("cuda:0"))

Pyannote работает только с аудио в формате 16kHz mono. Если у тебя стерео или другая частота - конвертируй перед обработкой.

Собираем все вместе: Python скрипт, который работает

Теперь самое интересное - склеиваем Whisper и Pyannote в один пайплайн. Вот рабочий код:

import torch
from faster_whisper import WhisperModel
from pyannote.audio import Pipeline
import whisper
import subprocess
import tempfile
import os

class MeetingTranscriber:
    def __init__(self, hf_token):
        # Загружаем Whisper (используем medium - лучший баланс скорости/качества)
        self.whisper_model = WhisperModel(
            "medium",
            device="cuda",
            compute_type="float16",  # Ускоряет в 2 раза с минимальной потерей точности
            download_root="./models"
        )
        
        # Загружаем Pyannote
        self.diarization_pipeline = Pipeline.from_pretrained(
            "pyannote/speaker-diarization-3.1",
            use_auth_token=hf_token
        )
        self.diarization_pipeline.to(torch.device("cuda:0"))
    
    def convert_audio(self, input_path):
        """Конвертируем аудио в правильный формат для Pyannote"""
        with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp:
            output_path = tmp.name
        
        # Используем ffmpeg для конвертации
        cmd = [
            "ffmpeg", "-i", input_path,
            "-ac", "1",           # моно
            "-ar", "16000",        # 16kHz
            "-acodec", "pcm_s16le", # 16-bit PCM
            output_path, "-y"
        ]
        
        subprocess.run(cmd, capture_output=True)
        return output_path
    
    def transcribe_meeting(self, audio_path):
        """Основная функция транскрибации"""
        print("Конвертируем аудио...")
        converted_audio = self.convert_audio(audio_path)
        
        print("Диаризация...")
        diarization = self.diarization_pipeline(converted_audio)
        
        print("Транскрибация...")
        segments, info = self.whisper_model.transcribe(
            converted_audio,
            language="ru",
            beam_size=5,          # Улучшает качество для русского
            vad_filter=True       # Убирает тишину
        )
        
        # Собираем результат
        result = []
        for segment in segments:
            # Находим, кто говорил в это время
            speaker = "UNKNOWN"
            for turn, _, speaker_label in diarization.itertracks(yield_label=True):
                if turn.start <= segment.start <= turn.end:
                    speaker = speaker_label
                    break
            
            result.append({
                "speaker": speaker,
                "start": segment.start,
                "end": segment.end,
                "text": segment.text
            })
        
        # Убираем временный файл
        os.unlink(converted_audio)
        
        return result

Это базовая версия. В реальном проекте добавь обработку ошибок, логирование и кэширование моделей.

Оптимизация: как добиться 4 минут на 2 часа аудио

Из коробки система будет работать минут 15 на 2-часовом файле. Чтобы ускорить до 4 минут, нужно сделать три вещи:

  1. Batch processing: Обрабатывать аудио кусками по 30 секунд, а не целиком
  2. Async I/O: Пока Whisper работает с одним куском, Pyannote готовит следующий
  3. Кэширование моделей в памяти: Не загружать модели при каждом запросе

Вот оптимизированная версия обработки:

import asyncio
from concurrent.futures import ThreadPoolExecutor

class OptimizedTranscriber(MeetingTranscriber):
    def __init__(self, hf_token):
        super().__init__(hf_token)
        self.executor = ThreadPoolExecutor(max_workers=2)
    
    async def transcribe_chunk(self, chunk_path):
        """Асинхронная транскрибация одного куска"""
        loop = asyncio.get_event_loop()
        segments = await loop.run_in_executor(
            self.executor,
            lambda: self.whisper_model.transcribe(chunk_path, language="ru")[0]
        )
        return list(segments)
    
    async def diarize_chunk(self, chunk_path):
        """Асинхронная диаризация одного куска"""
        loop = asyncio.get_event_loop()
        diarization = await loop.run_in_executor(
            self.executor,
            lambda: self.diarization_pipeline(chunk_path)
        )
        return diarization

Развёртывание: Docker, systemd или просто скрипт?

Зависит от того, кто будет пользоваться системой. Если только ты - хватит простого Python скрипта. Если команда - делаем веб-интерфейс. Вот минимальный Flask сервер:

from flask import Flask, request, jsonify
import os

app = Flask(__name__)
transcriber = None

@app.before_first_request
def load_model():
    global transcriber
    transcriber = MeetingTranscriber(os.getenv("HF_TOKEN"))

@app.route("/transcribe", methods=["POST"])
def transcribe():
    if "audio" not in request.files:
        return jsonify({"error": "No audio file"}), 400
    
    audio = request.files["audio"]
    temp_path = f"/tmp/{audio.filename}"
    audio.save(temp_path)
    
    try:
        result = transcriber.transcribe_meeting(temp_path)
        return jsonify({"transcription": result})
    finally:
        os.unlink(temp_path)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

Запускаем через gunicorn для production:

HF_TOKEN=ваш_токен gunicorn -w 1 -k gevent --timeout 120 app:app
💡
Используй w=1 (один воркер), потому что каждая копия модели занимает 5-6GB видеопамяти. Tesla V100 имеет 16GB, так что два воркера влезут, но лучше оставить запас.

Что может пойти не так (и как это починить)

За два года эксплуатации системы я набил все возможные шишки. Вот главные проблемы:

  • Out of memory на длинных файлах: Решение - резать аудио на куски по 10 минут
  • Pyannote путает говорящих: Особенно если в записи эхо. Решение - использовать шумоподавление перед диаризацией
  • Whisper не понимает акцент: Fine-tuning на 5-10 часах записей с акцентом решает проблему
  • Карта перегревается: Tesla V100 не имеет активного охлаждения. Решение - поставить в корпус с хорошей вентиляцией

Альтернативы: может, не стоит покупать Tesla V100?

Если 17 тысяч рублей - все еще много, посмотри на RTX 2060. Медленнее в 3 раза, но стоит 8 тысяч. Или RTX 4070 Super - быстрее, но дороже.

Для совсем минималистов есть вариант с Whisper на CPU. 2 часа аудио будут обрабатываться 4 часа вместо 4 минут. Но зато бесплатно.

Итог: стоит ли игра свеч?

Да, если транскрибируешь больше 5 часов аудио в месяц. Нет, если это разовая задача.

Моя система окупилась за месяц. Теперь я транскрибирую все совещания автоматически, сохраняю в Notion и даже делаю краткие выжимки через локальную LLM.

Самое приятное - полный контроль над данными. Никаких соглашений о конфиденциальности, никаких утечек в интернет. Все работает в локальной сети.

И последний совет: не пытайся сделать идеальную систему с первого раза. Собери минимально рабочую версию, проверь на 10 записях, а потом оптимизируй. Whisper и Pyannote прощают много ошибок настройки.

Не забудь про лицензию Pyannote. Для коммерческого использования нужна отдельная лицензия от INRIA. Для личных проектов - бесплатно.

Теперь у тебя есть все, чтобы собрать свою систему. Карта - 17к, день на настройку, вечность бесплатной транскрибации. Выбор за тобой.