Whisper: предобработка и постобработка аудио
Улучшаем качество транскрипции Whisper через обрезку начальной тишины, разбивку длинных файлов на сегменты и GPT-постобработку: добавление пунктуации, исправление финансовых терминов и удаление non-ASCII артефактов.
Зачем нужна обработка вокруг Whisper
Whisper хорошо транскрибирует речь, но теряет качество на тишине в начале, длинных файлах и доменной лексике. Официальный cookbook показывает трёхэтапный пайплайн: trim → segment → transcribe → post-process.
Шаг 1: обрезка тишины с PyDub
from pydub import AudioSegment
from pathlib import Path
def milliseconds_until_sound(sound, silence_threshold_in_decibels=-20.0, chunk_size=10):
trim_ms = 0
while sound[trim_ms:trim_ms+chunk_size].dBFS < silence_threshold_in_decibels and trim_ms < len(sound):
trim_ms += chunk_size
return trim_ms
def trim_start(filepath):
path = Path(filepath)
audio = AudioSegment.from_file(filepath, format="wav")
start_trim = milliseconds_until_sound(audio)
trimmed = audio[start_trim:]
new_filename = path.parent / f"trimmed_{path.name}"
trimmed.export(new_filename, format="wav")
return trimmed, new_filename
Шаг 2: сегментация и транскрипция
from openai import OpenAI
import os
client = OpenAI()
one_minute = 60 * 1000 # ms
def transcribe_audio(file, output_dir):
with open(os.path.join(output_dir, file), "rb") as f:
return client.audio.transcriptions.create(model="whisper-1", file=f).text
# Сегментация
trimmed_audio = AudioSegment.from_wav(trimmed_filename)
for i, start in enumerate(range(0, len(trimmed_audio), one_minute)):
trimmed_audio[start:start + one_minute].export(f"seg_{i:02d}.wav", format="wav")
Шаг 3: GPT-постобработка
def punctuation_assistant(text):
return client.chat.completions.create(
model="gpt-3.5-turbo",
temperature=0,
messages=[
{"role": "system", "content": "Add punctuation and capitalize. Preserve original words."},
{"role": "user", "content": text}
]
).choices[0].message.content
# Удаление non-ASCII (для английских транскриптов)
ascii_text = "".join(c for c in raw_transcript if ord(c) < 128)
clean = punctuation_assistant(ascii_text)
Для исправления финансовых терминов (например, "five two nine" → "529 (Education Savings Plan)") используется GPT-4 с domain-specific system prompt.
Скачайте любой WAV-файл длиннее 2 минут, обрежьте тишину с помощью PyDub, разбейте на 60-секундные сегменты, транскрибируйте каждый через Whisper и объедините результат. Прогоните итоговый текст через GPT для расстановки пунктуации.
Скопируйте и адаптируйте под свой контекст. Текст в треугольных скобках — то, что нужно заменить.
from pydub import AudioSegment
from openai import OpenAI
from pathlib import Path
import os
client = OpenAI()
def trim_and_segment(path, seg_ms=60_000, threshold_db=-20.0):
audio = AudioSegment.from_file(path)
trim = next(
(i for i in range(0, len(audio), 10)
if audio[i:i+10].dBFS >= threshold_db),
0,
)
audio = audio[trim:]
return [audio[s:s+seg_ms] for s in range(0, len(audio), seg_ms)]
def transcribe_segments(segments):
texts = []
for i, seg in enumerate(segments):
tmp = f"/tmp/seg_{i:02d}.wav"
seg.export(tmp, format="wav")
with open(tmp, "rb") as f:
texts.append(client.audio.transcriptions.create(
model="whisper-1", file=f).text)
return " ".join(texts)Передавать файл целиком без сегментации — Whisper принимает не более 25 МБ. Забывать обрезать тишину в начале — модель может галлюцинировать на пустом аудио. Применять non-ASCII фильтр к нелатинским языкам (греческий, кириллица, арабский).
PyDub работает с dBFS, а не абсолютными значениями — порог -20 подходит для большинства записей. Для финансовых/медицинских транскриптов вместо regex-замен используйте GPT-4 с детальным system prompt: он учитывает контекст.
Транскрипция записей совещаний, earnings calls, подкастов и голосовых заметок, где нужны точные формулировки и доменная лексика.
Real-time транскрипция (нужен Realtime API). Файлы на нелатинских языках без проверки — non-ASCII фильтр сломает транскрипт.