Fine-tuning Whisper для доменной распознавания речи
Базовый Whisper large-v3 показывает WER 8–15% на общей речи. На узкоспециализированной лексике (медицина, юриспруденция, финансы, технический жаргон) WER вырастает до 25–40%. Fine-tuning на доменном датасете снижает его до 3–8%. Мы дообучаем Whisper под ваши задачи — от медицинских диктовок до звонков колл-центра. За годы практики мы выполнили более 20 проектов по распознаванию для российских и зарубежных компаний, и гарантируем снижение WER как минимум вдвое. Свяжитесь с нами для первичной оценки вашего проекта.
Почему fine-tuning Whisper эффективнее облачных API?
Облачные сервисы (Google Speech-to-Text, Azure Speech) предлагают универсальные модели, которые не адаптируются под узкую терминологию. Fine-tuning на ваших данных даёт пятикратное снижение WER по сравнению с такими API. Кроме того, ваши аудиозаписи остаются на вашей инфраструктуре — никаких утечек конфиденциальной информации. Ниже приведено сравнение для медицинских диктовок.
| Решение | WER на медицинских диктовках | Улучшение относительно базового Whisper |
|---|---|---|
| Google Speech-to-Text | 28% | — |
| Azure Speech | 25% | — |
| Whisper large-v3 (base) | 31% | — |
| Whisper fine-tuned (наши) | 6.2% | 5x |
Когда нужен fine-tuning
Базовый Whisper справляется плохо при:
- Терминологии с редкими словами: «гепатоспленомегалия», «форс-мажорные обстоятельства», аббревиатуры типа «КТ», «МРТ», «ДДУ»
- Акцентной речи определённого региона
- Шумных условиях записи (колл-центр, производство)
- Смешанной речи (код-свитчинг: «сделаем deploy в staging»)
Как подготовить доменный датасет для обучения?
Минимальный объём для заметного улучшения WER — 10–20 часов, оптимальный — 50–100 часов. Используйте аугментацию: шум улицы, реверберацию, change pitch. Пример подготовки в Python:
from datasets import Dataset, Audio
import pandas as pd
def prepare_whisper_dataset(
audio_dir: str,
transcripts_csv: str,
target_language: str = "russian"
) -> Dataset:
"""
transcripts_csv: columns = [audio_file, transcription]
"""
df = pd.read_csv(transcripts_csv)
dataset = Dataset.from_dict({
"audio": [f"{audio_dir}/{f}" for f in df["audio_file"]],
"sentence": df["transcription"].tolist()
})
dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))
return dataset
Препроцессинг с feature extractor Whisper:
from transformers import WhisperFeatureExtractor, WhisperTokenizer
feature_extractor = WhisperFeatureExtractor.from_pretrained("openai/whisper-large-v3")
tokenizer = WhisperTokenizer.from_pretrained(
"openai/whisper-large-v3",
language="Russian",
task="transcribe"
)
def prepare_dataset(batch):
audio = batch["audio"]
batch["input_features"] = feature_extractor(
audio["array"],
sampling_rate=audio["sampling_rate"]
).input_features[0]
batch["labels"] = tokenizer(batch["sentence"]).input_ids
return batch
dataset = dataset.map(prepare_dataset, remove_columns=["audio", "sentence"])
Fine-tuning с Seq2SeqTrainer
from transformers import (
WhisperForConditionalGeneration,
Seq2SeqTrainingArguments,
Seq2SeqTrainer
)
from dataclasses import dataclass
import evaluate
import torch
model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-large-v3")
model.generation_config.language = "russian"
model.generation_config.task = "transcribe"
model.generation_config.forced_decoder_ids = None
training_args = Seq2SeqTrainingArguments(
output_dir="./whisper-finetuned-ru-medical",
per_device_train_batch_size=16,
gradient_accumulation_steps=1,
learning_rate=1e-5,
warmup_steps=500,
max_steps=4000,
gradient_checkpointing=True,
fp16=True,
evaluation_strategy="steps",
per_device_eval_batch_size=8,
predict_with_generate=True,
generation_max_length=225,
save_steps=500,
eval_steps=500,
logging_steps=25,
report_to=["tensorboard"],
load_best_model_at_end=True,
metric_for_best_model="wer",
greater_is_better=False,
push_to_hub=False
)
wer_metric = evaluate.load("wer")
def compute_metrics(pred):
pred_ids = pred.predictions
label_ids = pred.label_ids
label_ids[label_ids == -100] = tokenizer.pad_token_id
pred_str = tokenizer.batch_decode(pred_ids, skip_special_tokens=True)
label_str = tokenizer.batch_decode(label_ids, skip_special_tokens=True)
wer = 100 * wer_metric.compute(predictions=pred_str, references=label_str)
return {"wer": wer}
trainer = Seq2SeqTrainer(
args=training_args,
model=model,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
data_collator=data_collator,
compute_metrics=compute_metrics,
tokenizer=feature_extractor
)
trainer.train()
LoRA для экономии памяти
При ограниченных ресурсах (<24 GB VRAM) используем PEFT/LoRA:
from peft import get_peft_model, LoraConfig, TaskType
lora_config = LoraConfig(
r=32,
lora_alpha=64,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type=TaskType.SEQ_2_SEQ_LM
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# trainable params: 15,728,640 || all params: 1,557,741,568 (1.01%)
Результаты по доменам
| Домен | Базовый WER | После fine-tuning | Улучшение |
|---|---|---|---|
| Медицинские диктовки | 31% | 6.2% | в 5 раз |
| Юридические договоры | 24% | 4.8% | в 5 раз |
| Колл-центр (финансы) | 18% | 5.1% | в 3.5 раза |
| Технический support | 22% | 7.3% | в 3 раза |
Fine-tuning Whisper даёт улучшение в 3–6 раз по сравнению с базовой моделью. Это лучше, чем использование готовых облачных API, которые не учитывают вашу доменную лексику и политику конфиденциальности.
Инференс с fine-tuned моделью
from transformers import pipeline
asr = pipeline(
"automatic-speech-recognition",
model="./whisper-finetuned-ru-medical",
device=0,
torch_dtype=torch.float16,
generate_kwargs={
"language": "russian",
"task": "transcribe",
"num_beams": 5
}
)
result = asr("patient_recording.wav", chunk_length_s=30, stride_length_s=5)
print(result["text"])
Что входит в работу
Мы предоставляем полный цикл:
- Аудит ваших аудиоданных и оценка целевого WER
- Разметка и аугментация корпуса (шум, реверберация, speed perturbation)
- Fine-tuning базовой модели (Whisper large-v3, openai/whisper-medium или distill-whisper)
- Эксперименты с LoRA, квантизацией, архитектурой encoder
- Тестирование на отложенной выборке и A/B-сравнение
- Экспорт модели в ONNX или TensorRT для инференса
- Интеграция в ваш пайплайн (REST API, Docker, batch-обработка)
- Документация и обучение вашей команды
Процесс работы
- Аналитика — собираем требования, разбираем 1–2 часа вашего аудио, оцениваем сложность.
- Проектирование — выбираем базовую модель, стратегию fine-tuning, объём датасета.
- Разметка — транскрибируем и валидируем аудиофайлы (с привлечением экспертов домена).
- Обучение — запускаем fine-tuning на GPU-кластере с логированием в W&B, оптимизируем гиперпараметры.
- Тестирование — замеряем WER на тестовом сете, проводим акустический анализ ошибок.
- Деплой — упаковываем модель, поднимаем сервис, передаём доступы.
Сроки и стоимость
Ориентировочные сроки: от 2 недель (для 10-часового корпуса) до 6 недель (для 100+ часов со сложной разметкой). Стоимость рассчитывается индивидуально — зависит от объёма данных, целевого WER и требований к латентности. Получите консультацию по fine-tuning Whisper для вашей задачи — мы проанализируем задачу и подберём оптимальное решение.
Как получить консультацию?
Пишите на почту или в мессенджеры — мы проанализируем вашу задачу и подберём наиболее эффективный подход. Гарантируем конфиденциальность и NDA.
Подробнее о метриках
Помимо WER мы используем Character Error Rate (CER) для оценки точности распознавания символов, а также confidence scores для выявления проблемных фрагментов. При необходимости проводим фонетический анализ.
Radford et al., "Robust Speech Recognition via Large-Scale Weak Supervision", 2022







