
Пример Whisper на Python: полное руководство по распознаванию речи
Eric King
Author
Пример Whisper на Python: полное руководство по распознаванию речи
OpenAI Whisper — одна из самых мощных моделей распознавания речи с открытым исходным кодом, доступных сегодня. В этом подробном руководстве вы узнаете, как использовать Whisper с Python для транскрибации аудиофайлов в текст с высокой точностью.
Этот учебник подойдёт:
- Разработчикам, которые создают функции «речь в текст»
- Специалистам по данным, работающим с аудио
- Всем, кому нужен полный пример Whisper на Python
Что такое OpenAI Whisper?
Whisper — это система автоматического распознавания речи (ASR), обученная на 680 000 часах многоязычного аудио. Она может:
- Транскрибировать речь на 99+ языках
- Автоматически определять язык
- Переводить речь на английский
- Обрабатывать шумное аудио и акценты
- Обрабатывать длинные аудиофайлы
Требования
Перед началом убедитесь, что у вас есть:
- Установленный Python 3.8+
- Менеджер пакетов pip
- Установленный FFmpeg (для обработки аудио)
- (Необязательно) GPU NVIDIA для более быстрой обработки
Шаг 1. Установка Whisper
Установите пакет OpenAI Whisper с помощью pip:
pip install openai-whisper
Установка FFmpeg
macOS (через Homebrew):
brew install ffmpeg
Ubuntu/Debian:
sudo apt update
sudo apt install ffmpeg
Windows:
Скачайте FFmpeg с ffmpeg.org и добавьте его в PATH.
Шаг 2. Базовый пример Whisper на Python
Вот простой скрипт на Python для транскрибации аудиофайла:
import whisper
# Load the Whisper model
model = whisper.load_model("base")
# Transcribe audio file
result = model.transcribe("audio.mp3")
# Print the transcription
print(result["text"])
Вывод:
Hello everyone, welcome to today's meeting. We will discuss the project timeline and upcoming milestones.
Шаг 3. Полный пример на Python с обработкой ошибок
Более надёжный пример с корректной обработкой ошибок:
import whisper
import os
def transcribe_audio(audio_path, model_size="base"):
"""
Transcribe an audio file using Whisper.
Args:
audio_path (str): Path to the audio file
model_size (str): Whisper model size (tiny, base, small, medium, large)
Returns:
dict: Transcription result with text and segments
"""
try:
# Check if audio file exists
if not os.path.exists(audio_path):
raise FileNotFoundError(f"Audio file not found: {audio_path}")
# Load the Whisper model
print(f"Loading Whisper model: {model_size}")
model = whisper.load_model(model_size)
# Transcribe the audio
print(f"Transcribing: {audio_path}")
result = model.transcribe(audio_path)
return result
except Exception as e:
print(f"Error during transcription: {str(e)}")
return None
# Example usage
if __name__ == "__main__":
audio_file = "sample_audio.mp3"
result = transcribe_audio(audio_file, model_size="base")
if result:
print("\nTranscription:")
print(result["text"])
Шаг 4. Расширенный пример с определением языка
Whisper может автоматически определять язык, но вы также можете указать его явно:
import whisper
model = whisper.load_model("base")
# Auto-detect language
result = model.transcribe("audio.mp3")
print(f"Detected language: {result['language']}")
print(f"Transcription: {result['text']}")
# Specify language explicitly
result_en = model.transcribe("audio.mp3", language="en")
result_zh = model.transcribe("audio.mp3", language="zh")
Шаг 5. Получение временных меток и сегментов
Whisper возвращает подробную информацию по сегментам с временными метками:
import whisper
model = whisper.load_model("base")
result = model.transcribe("audio.mp3")
# Print full transcription
print("Full Text:")
print(result["text"])
# Print segments with timestamps
print("\nSegments with Timestamps:")
for segment in result["segments"]:
start = segment["start"]
end = segment["end"]
text = segment["text"]
print(f"[{start:.2f}s - {end:.2f}s] {text}")
Вывод:
Full Text:
Hello everyone, welcome to today's meeting. We will discuss the project timeline.
Segments with Timestamps:
[0.00s - 2.50s] Hello everyone, welcome to today's meeting.
[2.50s - 5.80s] We will discuss the project timeline.
Шаг 6. Перевод аудио на английский
Whisper может переводить речь не на английском напрямую на английский:
import whisper
model = whisper.load_model("base")
# Translate to English
result = model.transcribe("spanish_audio.mp3", task="translate")
print("Translated text:")
print(result["text"])
Шаг 7. Обработка нескольких аудиофайлов
Так можно транскрибировать несколько файлов пакетно:
import whisper
import os
from pathlib import Path
def batch_transcribe(audio_directory, model_size="base", output_dir="transcriptions"):
"""
Transcribe all audio files in a directory.
Args:
audio_directory (str): Directory containing audio files
model_size (str): Whisper model size
output_dir (str): Directory to save transcriptions
"""
# Create output directory
os.makedirs(output_dir, exist_ok=True)
# Load model once
model = whisper.load_model(model_size)
# Supported audio formats
audio_extensions = ['.mp3', '.wav', '.m4a', '.flac', '.ogg']
# Process each audio file
audio_files = [
f for f in os.listdir(audio_directory)
if any(f.lower().endswith(ext) for ext in audio_extensions)
]
for audio_file in audio_files:
audio_path = os.path.join(audio_directory, audio_file)
print(f"\nProcessing: {audio_file}")
try:
result = model.transcribe(audio_path)
# Save transcription to file
output_file = os.path.join(
output_dir,
Path(audio_file).stem + ".txt"
)
with open(output_file, "w", encoding="utf-8") as f:
f.write(result["text"])
print(f"✓ Saved: {output_file}")
except Exception as e:
print(f"✗ Error processing {audio_file}: {str(e)}")
# Example usage
batch_transcribe("audio_files/", model_size="base")
Шаг 8. Экспорт в формат субтитров SRT
Создавайте файлы субтитров SRT на основе транскриптов:
import whisper
def transcribe_to_srt(audio_path, output_path, model_size="base"):
"""
Transcribe audio and save as SRT subtitle file.
Args:
audio_path (str): Path to audio file
output_path (str): Path to save SRT file
model_size (str): Whisper model size
"""
model = whisper.load_model(model_size)
result = model.transcribe(audio_path)
# Generate SRT content
srt_content = ""
for i, segment in enumerate(result["segments"], start=1):
start_time = format_timestamp(segment["start"])
end_time = format_timestamp(segment["end"])
text = segment["text"].strip()
srt_content += f"{i}\n"
srt_content += f"{start_time} --> {end_time}\n"
srt_content += f"{text}\n\n"
# Save SRT file
with open(output_path, "w", encoding="utf-8") as f:
f.write(srt_content)
print(f"SRT file saved: {output_path}")
def format_timestamp(seconds):
"""Convert seconds to SRT timestamp format (HH:MM:SS,mmm)."""
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
millis = int((seconds % 1) * 1000)
return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"
# Example usage
transcribe_to_srt("video.mp4", "subtitles.srt", model_size="base")
Сравнение размеров моделей Whisper
Выберите подходящий размер модели в зависимости от задач:
| Модель | Параметры | Скорость | Точность | Память | Сценарий |
|---|---|---|---|---|---|
| tiny | 39M | ⭐⭐⭐⭐⭐ | ⭐⭐ | ~1GB | Быстрые тесты, простое аудио |
| base | 74M | ⭐⭐⭐⭐ | ⭐⭐⭐ | ~1GB | Общее использование |
| small | 244M | ⭐⭐⭐ | ⭐⭐⭐⭐ | ~2GB | Баланс |
| medium | 769M | ⭐⭐ | ⭐⭐⭐⭐⭐ | ~5GB | Нужна высокая точность |
| large | 1550M | ⭐ | ⭐⭐⭐⭐⭐⭐ | ~10GB | Максимальная точность, шум |
Лучшие практики для Whisper на Python
1. Выбор подходящего размера модели
# Fast and lightweight
model = whisper.load_model("tiny") # Good for testing
# Balanced
model = whisper.load_model("base") # Good for most cases
# High accuracy
model = whisper.load_model("medium") # For important transcriptions
2. Длинные аудиофайлы
Для очень длинных файлов рассмотрите разбиение на фрагменты:
import whisper
from pydub import AudioSegment
def transcribe_long_audio(audio_path, chunk_length_ms=60000):
"""
Transcribe long audio by splitting into chunks.
Args:
audio_path: Path to audio file
chunk_length_ms: Length of each chunk in milliseconds
"""
model = whisper.load_model("base")
# Load audio
audio = AudioSegment.from_file(audio_path)
# Split into chunks
chunks = []
for i in range(0, len(audio), chunk_length_ms):
chunks.append(audio[i:i + chunk_length_ms])
# Transcribe each chunk
full_text = []
for i, chunk in enumerate(chunks):
chunk_path = f"chunk_{i}.wav"
chunk.export(chunk_path, format="wav")
result = model.transcribe(chunk_path)
full_text.append(result["text"])
# Clean up chunk file
os.remove(chunk_path)
return " ".join(full_text)
3. Использование GPU для ускорения
Если у вас есть GPU NVIDIA:
import whisper
# Whisper will automatically use GPU if available
model = whisper.load_model("base", device="cuda")
4. Указание языка для лучшей точности
# If you know the language, specify it
result = model.transcribe("audio.mp3", language="en")
Типичные сценарии
Транскрипция подкастов
import whisper
model = whisper.load_model("medium")
result = model.transcribe("podcast_episode.mp3")
# Save transcript
with open("podcast_transcript.txt", "w") as f:
f.write(result["text"])
Заметки по встречам
import whisper
from datetime import datetime
model = whisper.load_model("base")
result = model.transcribe("meeting_recording.mp3")
# Create formatted meeting notes
notes = f"""
Meeting Notes - {datetime.now().strftime('%Y-%m-%d')}
========================================
{result["text"]}
"""
with open("meeting_notes.txt", "w") as f:
f.write(notes)
Субтитры к видео
import whisper
model = whisper.load_model("base")
result = model.transcribe("video.mp4")
# Generate VTT subtitle file
vtt_content = "WEBVTT\n\n"
for segment in result["segments"]:
start = format_vtt_timestamp(segment["start"])
end = format_vtt_timestamp(segment["end"])
text = segment["text"].strip()
vtt_content += f"{start} --> {end}\n{text}\n\n"
with open("subtitles.vtt", "w") as f:
f.write(vtt_content)
Устранение типичных проблем
Проблема 1: FFmpeg не найден
Ошибка:
FileNotFoundError: ffmpegРешение:
# Install FFmpeg
# macOS
brew install ffmpeg
# Ubuntu/Debian
sudo apt install ffmpeg
# Windows
# Download from ffmpeg.org and add to PATH
Проблема 2: нехватка памяти
Ошибка:
RuntimeError: CUDA out of memoryРешение:
# Use a smaller model
model = whisper.load_model("tiny") # Instead of "large"
# Or use CPU
model = whisper.load_model("base", device="cpu")
Проблема 3: медленная обработка
Решения:
- Используйте меньшую модель (tiny или base)
- Включите ускорение на GPU
- Обрабатывайте аудио по фрагментам
- Используйте многопроцессорность для пакетов
Советы по производительности
- Используйте GPU, если доступно — в 10–50 раз быстрее CPU
- Подбирайте размер модели — не используйте «large» для простых задач
- Предобработка аудио — удаление тишины, нормализация громкости
- Пакетная обработка — загрузите модель один раз, обработайте несколько файлов
- Потоки — для операций, ограниченных вводом-выводом
Whisper Python и другие решения
| Функция | Whisper Python | Google Speech-to-Text | AssemblyAI |
|---|---|---|---|
| Стоимость | Бесплатно (локально) | Платно за минуту | Платно за минуту |
| Офлайн | ✅ | ❌ | ❌ |
| Точность | Высокая | Высокая | Высокая |
| Настройка | Средняя | Простая | Простая |
| Длинное аудио | ✅ | ✅ | ✅ |
| Многоязычность | ✅ | ✅ | ✅ |
Полный пример: готовый к продакшену скрипт
Полный пример, готовый к использованию в продакшене:
#!/usr/bin/env python3
"""
Production-ready Whisper transcription script.
"""
import whisper
import argparse
import os
import json
from pathlib import Path
from datetime import datetime
def transcribe_file(
audio_path,
model_size="base",
language=None,
output_format="txt",
output_dir=None
):
"""
Transcribe an audio file with comprehensive output options.
Args:
audio_path: Path to audio file
model_size: Whisper model size
language: Language code (optional, auto-detected if None)
output_format: Output format (txt, json, srt, vtt)
output_dir: Output directory (default: same as audio file)
"""
# Validate input file
if not os.path.exists(audio_path):
raise FileNotFoundError(f"Audio file not found: {audio_path}")
# Set output directory
if output_dir is None:
output_dir = os.path.dirname(audio_path)
os.makedirs(output_dir, exist_ok=True)
# Load model
print(f"Loading Whisper model: {model_size}")
model = whisper.load_model(model_size)
# Transcribe
print(f"Transcribing: {audio_path}")
transcribe_kwargs = {}
if language:
transcribe_kwargs["language"] = language
result = model.transcribe(audio_path, **transcribe_kwargs)
# Generate output filename
base_name = Path(audio_path).stem
output_path = os.path.join(output_dir, base_name)
# Save based on format
if output_format == "txt":
with open(f"{output_path}.txt", "w", encoding="utf-8") as f:
f.write(result["text"])
elif output_format == "json":
with open(f"{output_path}.json", "w", encoding="utf-8") as f:
json.dump(result, f, indent=2, ensure_ascii=False)
elif output_format == "srt":
srt_content = generate_srt(result["segments"])
with open(f"{output_path}.srt", "w", encoding="utf-8") as f:
f.write(srt_content)
elif output_format == "vtt":
vtt_content = generate_vtt(result["segments"])
with open(f"{output_path}.vtt", "w", encoding="utf-8") as f:
f.write(vtt_content)
print(f"✓ Transcription saved: {output_path}.{output_format}")
print(f" Language: {result['language']}")
print(f" Duration: {result['segments'][-1]['end']:.2f}s")
return result
def generate_srt(segments):
"""Generate SRT subtitle content."""
srt = ""
for i, segment in enumerate(segments, start=1):
start = format_timestamp(segment["start"])
end = format_timestamp(segment["end"])
text = segment["text"].strip()
srt += f"{i}\n{start} --> {end}\n{text}\n\n"
return srt
def generate_vtt(segments):
"""Generate VTT subtitle content."""
vtt = "WEBVTT\n\n"
for segment in segments:
start = format_vtt_timestamp(segment["start"])
end = format_vtt_timestamp(segment["end"])
text = segment["text"].strip()
vtt += f"{start} --> {end}\n{text}\n\n"
return vtt
def format_timestamp(seconds):
"""Format timestamp for SRT."""
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
millis = int((seconds % 1) * 1000)
return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"
def format_vtt_timestamp(seconds):
"""Format timestamp for VTT."""
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
millis = int((seconds % 1) * 1000)
return f"{hours:02d}:{minutes:02d}:{secs:02d}.{millis:03d}"
def main():
parser = argparse.ArgumentParser(
description="Transcribe audio files using OpenAI Whisper"
)
parser.add_argument("audio", help="Path to audio file")
parser.add_argument(
"--model",
default="base",
choices=["tiny", "base", "small", "medium", "large"],
help="Whisper model size"
)
parser.add_argument(
"--language",
default=None,
help="Language code (e.g., 'en', 'zh', 'es')"
)
parser.add_argument(
"--output-format",
default="txt",
choices=["txt", "json", "srt", "vtt"],
help="Output format"
)
parser.add_argument(
"--output-dir",
default=None,
help="Output directory"
)
args = parser.parse_args()
transcribe_file(
args.audio,
model_size=args.model,
language=args.language,
output_format=args.output_format,
output_dir=args.output_dir
)
if __name__ == "__main__":
main()
Запуск:
# Basic usage
python transcribe.py audio.mp3
# With options
python transcribe.py audio.mp3 --model medium --language en --output-format srt
# Save to specific directory
python transcribe.py audio.mp3 --output-dir ./transcriptions
Заключение
Это подробное руководство с примерами Whisper на Python охватывает всё необходимое для начала работы с преобразованием речи в текст с помощью OpenAI Whisper. Подкасты, встречи или субтитры — Whisper даёт мощное бесплатное решение для превращения аудио в текст.
Главное:
- Whisper бесплатен и с открытым исходным кодом
- Поддерживает 99+ языков
- Работает офлайн (без вызовов API)
- Высокая точность в большинстве сценариев
- Простая интеграция в проекты на Python
Для продакшена с транскрипцией в реальном времени или доступом по API рассмотрите облачные решения вроде SayToWords с транскрипцией на базе Whisper через API.
Готовы начать? Установите Whisper и транскрибируйте свой первый аудиофайл уже сегодня.