AI Agents · Урок

Преобразование речи в текст с Whisper и Deepgram

Транскрибирование в реальном времени и пакетная расшифровка, определение языка и расстановка знаков препинания.

Урок 1 из 413 шагов

«Преобразование речи в текст с Whisper и Deepgram» — бесплатный урок AI Agents на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Agents, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Agents содержит 4 уроков всего.

Преобразование речи в текст в голосовых агентах

Голосовой агент должен преобразовать аудио с речью в текст, прежде чем LLM сможет его обработать. Этот этап называется преобразованием речи в текст (STT) или автоматическим распознаванием речи (ASR).

Два ведущих варианта: OpenAI Whisper (обработка файлов пакетами) и Deepgram (потоковая обработка в реальном времени, с диаризацией говорящих и временными метками слов).

OpenAI Whisper: базовая транскрипция

Whisper через API OpenAI транскрибирует аудиофайлы. Поддерживаемые форматы: mp3, mp4, wav, webm, m4a, flac. Максимальный размер файла: 25 МБ.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def transcribe_file(audio_path, language=None):
    with open(audio_path, 'rb') as audio_file:
        params = {
            'model': 'whisper-1',
            'file': audio_file,
            'response_format': 'json'  # or 'text', 'srt', 'vtt', 'verbose_json'
        }
        if language:
            params['language'] = language  # e.g., 'en', 'fr', 'de'

        transcript = client.audio.transcriptions.create(**params)

    return transcript.text

# Basic usage
text = transcribe_file('meeting_recording.mp3')
print('Transcribed:', text[:200])

Whisper с временными метками слов

Используйте response_format='verbose_json', чтобы получить временные метки для каждого слова и сегмента. Это полезно для поиска определённых моментов в записях, подсветки текста в стиле караоке и синхронизации расшифровок с воспроизведением аудио.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def transcribe_with_timestamps(audio_path):
    with open(audio_path, 'rb') as f:
        result = client.audio.transcriptions.create(
            model='whisper-1',
            file=f,
            response_format='verbose_json',
            timestamp_granularities=['word', 'segment']  # get both word and segment times
        )

    segments = []
    for seg in result.segments:
        segments.append({
            'start': seg.start,
            'end':   seg.end,
            'text':  seg.text
        })

    words = []
    if hasattr(result, 'words'):
        for word in result.words:
            words.append({'word': word.word, 'start': word.start, 'end': word.end})

    return {'text': result.text, 'segments': segments, 'words': words}

Deepgram SDK: асинхронная потоковая передача

Deepgram оптимизирован для потоковой транскрипции в реальном времени. Аудио отправляется фрагментами по мере записи, а частичные расшифровки возвращаются ещё до того, как говорящий закончит предложение.

Установите с помощью команды pip install deepgram-sdk.

import asyncio
import os
from deepgram import DeepgramClient, PrerecordedOptions

client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

async def transcribe_with_deepgram(audio_path):
    with open(audio_path, 'rb') as f:
        audio_data = f.read()

    options = PrerecordedOptions(
        model='nova-2',            # Deepgram's best accuracy model
        language='en',
        smart_format=True,         # auto-add punctuation and formatting
        utterances=True,           # segment by speaker turns
        punctuate=True,
        diarize=True               # speaker identification
    )

    response = await client.listen.asyncrest.v('1').transcribe_file(
        {'buffer': audio_data},
        options
    )

    return response.results.channels[0].alternatives[0].transcript

Диаризация говорящих

Диаризация определяет, кто и когда говорит, — помечая сегменты как Говорящий 0, Говорящий 1 и т. д. Это крайне важно для расшифровок совещаний и разговоров с несколькими участниками.

async def transcribe_with_diarization(audio_path):
    from deepgram import DeepgramClient, PrerecordedOptions
    import os

    dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

    options = PrerecordedOptions(
        model='nova-2',
        diarize=True,
        utterances=True,
        smart_format=True
    )

    with open(audio_path, 'rb') as f:
        audio_data = f.read()

    response = await dg_client.listen.asyncrest.v('1').transcribe_file(
        {'buffer': audio_data}, options
    )

    utterances = []
    for utt in response.results.utterances:
        utterances.append({
            'speaker': f'Speaker {utt.speaker}',
            'start':   round(utt.start, 2),
            'end':     round(utt.end, 2),
            'text':    utt.transcript
        })

    return utterances

# Output:
# [{'speaker': 'Speaker 0', 'start': 0.0, 'end': 3.2, 'text': 'Hello everyone.'},
#  {'speaker': 'Speaker 1', 'start': 3.5, 'end': 6.1, 'text': 'Good morning!'}]

Определение языка

Если язык пользователя неизвестен, и Whisper, и Deepgram могут автоматически определить язык речи. Whisper определяет язык по первым 30 секундам аудио.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def detect_language(audio_path):
    with open(audio_path, 'rb') as f:
        # Use translations endpoint to get verbose JSON with language detection
        result = client.audio.transcriptions.create(
            model='whisper-1',
            file=f,
            response_format='verbose_json'
        )
    return {
        'detected_language': result.language,
        'text': result.text
    }

result = detect_language('user_audio.wav')
print(f"Language: {result['detected_language']}")
print(f"Text: {result['text'][:100]}")

# Deepgram: set language='auto' in options
from deepgram import PrerecordedOptions
options = PrerecordedOptions(model='nova-2', language='auto', detect_language=True)

Разбиение длинных аудиофайлов на фрагменты

Ограничение Whisper в 25 МБ означает, что длинные записи, например часовые совещания, нужно разбивать на фрагменты. Разделите аудио по паузам с помощью pydub, затем транскрибируйте каждый фрагмент и объедините результаты.

Установите с помощью команды pip install pydub. Требуется ffmpeg.

from pydub import AudioSegment
from pydub.silence import split_on_silence
import io

def transcribe_long_audio(audio_path, chunk_length_ms=60000):
    audio = AudioSegment.from_file(audio_path)

    # Split on silence
    chunks = split_on_silence(
        audio,
        min_silence_len=1000,   # 1 second of silence
        silence_thresh=-40,     # dBFS
        keep_silence=500        # keep 500ms at each end
    )

    # If no silence splitting worked, use fixed-length chunks
    if len(chunks) <= 1:
        chunks = [
            audio[i:i + chunk_length_ms]
            for i in range(0, len(audio), chunk_length_ms)
        ]

    full_transcript = []
    for i, chunk in enumerate(chunks):
        print(f'Transcribing chunk {i+1}/{len(chunks)}')
        buf = io.BytesIO()
        chunk.export(buf, format='mp3')
        buf.seek(0)
        buf.name = f'chunk_{i}.mp3'
        result = client.audio.transcriptions.create(model='whisper-1', file=buf)
        full_transcript.append(result.text)

    return ' '.join(full_transcript)

Потоковая передача данных в Deepgram в реальном времени

Для голосовых разговоров в реальном времени используйте API потоковой передачи Deepgram через WebSocket. Фрагменты аудио отправляются по мере записи, а промежуточные и окончательные расшифровки поступают за миллисекунды.

import asyncio
import os
from deepgram import DeepgramClient, LiveTranscriptionEvents, LiveOptions

async def live_transcribe(on_transcript_callback):
    dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

    connection = dg_client.listen.asynclive.v('1')

    async def on_message(self, result, **kwargs):
        sentence = result.channel.alternatives[0].transcript
        is_final = result.is_final
        if sentence:
            await on_transcript_callback(sentence, is_final)

    connection.on(LiveTranscriptionEvents.Transcript, on_message)

    options = LiveOptions(
        model='nova-2',
        language='en',
        smart_format=True,
        interim_results=True,  # get partial results before sentence ends
        endpointing=500        # ms of silence before finalizing
    )

    await connection.start(options)
    return connection  # caller sends audio chunks via connection.send(audio_chunk)

Обработка ошибок и повторные попытки

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

import time
import os

MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024  # 25MB
SUPPORTED_FORMATS = ('.mp3', '.mp4', '.wav', '.webm', '.m4a', '.flac', '.ogg')

def validate_audio_file(audio_path):
    if not os.path.exists(audio_path):
        raise FileNotFoundError(f'Audio file not found: {audio_path}')
    size = os.path.getsize(audio_path)
    if size > MAX_FILE_SIZE_BYTES:
        raise ValueError(f'File too large: {size / 1024 / 1024:.1f}MB (max 25MB)')
    ext = os.path.splitext(audio_path)[1].lower()
    if ext not in SUPPORTED_FORMATS:
        raise ValueError(f'Unsupported format: {ext}. Supported: {SUPPORTED_FORMATS}')

def transcribe_with_retry(audio_path, max_retries=3):
    validate_audio_file(audio_path)
    for attempt in range(max_retries):
        try:
            return transcribe_file(audio_path)
        except Exception as e:
            if attempt < max_retries - 1:
                wait = 2 ** attempt
                print(f'Retry {attempt + 1} after error: {e}. Waiting {wait}s')
                time.sleep(wait)
            else:
                raise

Выбор между Whisper и Deepgram

Оба инструмента особенно хорошо подходят для разных сценариев. Используйте эту матрицу решений, чтобы выбрать подходящий вариант для голосового агента.

COMPARISON = '''
Whisper (OpenAI API):
  - Best for: batch transcription, podcast processing, meeting notes
  - Latency: file upload latency + ~1-5 seconds processing
  - Strengths: excellent multilingual, high accuracy, cheap
  - Word timestamps: yes (verbose_json)
  - Diarization: NO (must use separate tool)
  - Use when: accuracy > speed, offline processing

DeeGram:
  - Best for: real-time voice agents, call center transcription
  - Latency: <300ms for streaming, ~1s for file upload
  - Strengths: streaming, diarization, custom vocabulary
  - Word timestamps: yes, with confidence scores
  - Diarization: YES (built-in, up to 10 speakers)
  - Use when: speed > accuracy, real-time required

Rule of thumb:
  Agent voice conversation -> Deepgram live streaming
  Batch audio files -> Whisper API
  Meeting transcripts with speakers -> Deepgram with diarize=True
'''
print(COMPARISON)

Преобразование аудиоформатов

Whisper и Deepgram поддерживают распространённые аудиоформаты, но пользовательское аудио может поступать в необычных форматах: ogg, opus, webm из браузеров или m4a из iOS. Преобразуйте его в стандартный WAV или MP3 перед отправкой в API.

from pydub import AudioSegment
import os

SUPPORTED_FORMATS = {'.mp3', '.wav', '.flac', '.m4a', '.ogg', '.webm', '.opus'}

def convert_to_wav(input_path, output_path=None):
    ext = os.path.splitext(input_path)[1].lower()
    if ext not in SUPPORTED_FORMATS:
        raise ValueError(f'Unsupported audio format: {ext}')

    if output_path is None:
        output_path = input_path.rsplit('.', 1)[0] + '.wav'

    # pydub handles format detection automatically
    audio = AudioSegment.from_file(input_path)

    # Normalize to 16kHz mono (optimal for Whisper)
    audio = audio.set_frame_rate(16000).set_channels(1)

    audio.export(output_path, format='wav')
    print(f'Converted {input_path} -> {output_path} ({len(audio) / 1000:.1f}s)')
    return output_path

def ensure_compatible_audio(audio_path):
    ext = os.path.splitext(audio_path)[1].lower()
    if ext in {'.mp3', '.wav', '.m4a', '.flac'}:
        return audio_path  # already compatible
    return convert_to_wav(audio_path)

Проверка знаний

Что такое диаризация говорящих в контексте транскрипции речи в текст?

Итоги: преобразование речи в текст с Whisper и Deepgram

Whisper (API OpenAI) идеально подходит для пакетной транскрипции: высокая точность, поддержка нескольких языков и временные метки слов через verbose_json. Используйте его для обработки файлов, когда задержка не критична.

Deepgram предназначен для потоковой передачи данных в реальном времени: транскрипция через WebSocket с промежуточными результатами, встроенная диаризация говорящих и задержка менее 300 мс. Используйте его для интерактивных голосовых агентов. Оба инструмента поддерживают определение языка; в рабочей среде для них необходимы логика повторных попыток и проверка файлов.

Можно начать бесплатно

Изучай AI Agents с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
60
Уроки
239

Часто задаваемые вопросы

Урок «Преобразование речи в текст с Whisper и Deepgram» бесплатный?

Да — полный текст урока «Преобразование речи в текст с Whisper и Deepgram» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Agents, подпишись на CoddyKit PRO. Курс AI Agents содержит 4 уроков всего.

Чему я научусь в уроке «Преобразование речи в текст с Whisper и Deepgram»?

Транскрибирование в реальном времени и пакетная расшифровка, определение языка и расстановка знаков препинания. Ты практикуешь AI Agents с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать AI Agents?

Предыдущий опыт не требуется. AI Agents на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Преобразование речи в текст с Whisper и Deepgram»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке AI Agents?

Да. Каждый урок AI Agents включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Преобразование речи в текст с Whisper и Deepgram
  2. Преобразование текста в речь в ответах агентов
  3. Создание цикла голосового диалога
  4. Оптимизация задержки голосовых агентов
← Назад к AI Agents