Batchgewijze spraak-naar-tekstconversie met Whisper

Gebruik OpenAI Whisper large-v3-turbo om een batch Engelse spraakopnames te transcriberen op een aangesloten A10 AI Runtime. Dit notitieboekje laat zien hoe je:

  • Laad het Whisper large-v3-turbo-model met de Transformers-pipeline.
  • Bouw een batch audiosamples uit de LibriSpeech-testset.
  • Visualiseer de golfvorm en het spectrogram van elke sample.
  • Voer batchtranscriptie uit en vergelijk de doorvoer met sequentiële inferentie.

Note

Dit voorbeeld vereist de Databricks AI-omgeving versie 6 of hoger.

Verbinding maken met serverloze GPU-rekenkracht

  1. Selecteer Serverless GPU in de rekenselectie van het notebook.
  2. Selecteer in het paneel Omgeving de A10-accelerator en de AI v6-omgeving .
  3. Klik op Aanpassen en bevestig vervolgens de omgeving.

Het Whisper-model en de LibriSpeech-voorbeelddataset zijn openbaar en vereisen geen Hugging Face-authenticatie.

Bibliotheken importeren

De AI-omgeving bevat de PyTorch-, Transformers- en Hugging Face Datasets-pakketten die in dit notebook worden gebruikt, dus er is geen pakketinstallatie nodig. Deze cel importeert ze en bevestigt dat er een GPU aan gekoppeld is.

import torch
import transformers
import datasets

print(f"Environment")
print(f"   PyTorch:      {torch.__version__}")
print(f"   Transformers: {transformers.__version__}")
print(f"   Datasets:     {datasets.__version__}")
print(f"\nGPU")
print(f"   Available:    {torch.cuda.is_available()}")
if torch.cuda.is_available():
    print(f"   Device:       {torch.cuda.get_device_name(0)}")
    mem_gb = torch.cuda.get_device_properties(0).total_memory / 1e9
    print(f"   Memory:       {mem_gb:.1f} GB")
Environment
   PyTorch:      2.11.0+cu130
   Transformers: 5.8.1
   Datasets:     4.8.5

GPU
   Available:    True
   Device:       NVIDIA A10G
   Memory:       23.7 GB

Laad het Whisper-model

Laad openai/whisper-large-v3-turbo, een gedistilleerd model met 809 miljoen parameters dat een nauwkeurigheid levert die bijna state-of-the-art is, met een hogere inferentiesnelheid. De Transformers-pijplijn verzorgt feature-extractie, tokenisatie en decodering in één enkele aanroep.

from transformers import pipeline
import torch

whisper_pipe = pipeline(
    "automatic-speech-recognition",
    model="openai/whisper-large-v3-turbo",
    torch_dtype=torch.float16,
    device="cuda",
)
print(f"Model loaded on {whisper_pipe.device}")
Model loaded on cuda

Laad en verken audiosamples

Laad de LibriSpeech ASR-testset , een verzameling schone Engelse spraakopnames met referentietranscripties, en speel de eerste sample af.

from datasets import load_dataset, Audio as AudioFeature
from IPython.display import display, Audio
import numpy as np
import soundfile as sf
import io

# Load the LibriSpeech test samples (decode=False to avoid torchcodec/FFmpeg dependency)
ds = load_dataset(
    "hf-internal-testing/librispeech_asr_dummy", "clean", split="validation"
)
ds = ds.cast_column("audio", AudioFeature(decode=False))
print(f"Loaded {len(ds)} audio samples\n")

def decode_audio(raw):
    """Decode raw audio bytes with soundfile."""
    arr, sr = sf.read(io.BytesIO(raw["bytes"]))
    return {"array": arr, "sampling_rate": sr}

# Show metadata for first few samples
for i in range(5):
    audio = decode_audio(ds[i]["audio"])
    duration = len(audio["array"]) / audio["sampling_rate"]
    text_preview = ds[i]["text"][:80]
    print(f"  Sample {i+1}:  {duration:.2f}s  |  {audio['sampling_rate']} Hz  |  \"{text_preview}...\"")

# Play the first sample inline
print("\n>> Playing Sample 1:")
audio_0 = decode_audio(ds[0]["audio"])
display(Audio(audio_0["array"], rate=audio_0["sampling_rate"]))
Loaded 73 audio samples

  Sample 1:  5.86s  |  16000 Hz  |  "MISTER QUILTER IS THE APOSTLE OF THE MIDDLE CLASSES AND WE ARE GLAD TO WELCOME H..."
  Sample 2:  4.82s  |  16000 Hz  |  "NOR IS MISTER QUILTER'S MANNER LESS INTERESTING THAN HIS MATTER..."
  Sample 3:  12.48s  |  16000 Hz  |  "HE TELLS US THAT AT THIS FESTIVE SEASON OF THE YEAR WITH CHRISTMAS AND ROAST BEE..."
  Sample 4:  9.90s  |  16000 Hz  |  "HE HAS GRAVE DOUBTS WHETHER SIR FREDERICK LEIGHTON'S WORK IS REALLY GREEK AFTER ..."
  Sample 5:  29.40s  |  16000 Hz  |  "LINNELL'S PICTURES ARE A SORT OF UP GUARDS AND AT EM PAINTINGS AND MASON'S EXQUI..."

>> Playing Sample 1:

Visualiseer de audiogolfvormen

Plot de golfvorm en het spectrogram van elke sample naast elkaar. De golfvorm toont amplitude in de tijd, en het spectrogram toont de frequentie-inhoud, waarbij spraakenergie zich concentreert in de spraakband van 100 tot 4.000 Hz.

import matplotlib.pyplot as plt
import numpy as np

NUM_SAMPLES = 4
fig, axes = plt.subplots(NUM_SAMPLES, 2, figsize=(16, 3 * NUM_SAMPLES))
fig.suptitle(
    "Waveform & Spectrogram Profiles", fontsize=16, fontweight="bold", y=1.01
)

for i in range(NUM_SAMPLES):
    audio = decode_audio(ds[i]["audio"])
    samples = audio["array"]
    sr = audio["sampling_rate"]
    t = np.arange(len(samples)) / sr

    # --- Waveform ---
    ax_wave = axes[i, 0]
    ax_wave.plot(t, samples, linewidth=0.4, color="#1f77b4", alpha=0.8)
    ax_wave.fill_between(t, samples, alpha=0.15, color="#1f77b4")
    ax_wave.set_ylabel("Amplitude", fontsize=9)
    ax_wave.set_title(f"Sample {i+1} — Waveform ({len(samples)/sr:.1f}s)", fontsize=10)
    ax_wave.set_xlim(0, t[-1])
    ax_wave.grid(True, alpha=0.3)
    if i == NUM_SAMPLES - 1:
        ax_wave.set_xlabel("Time (seconds)", fontsize=9)

    # --- Spectrogram ---
    ax_spec = axes[i, 1]
    ax_spec.specgram(samples, Fs=sr, NFFT=1024, noverlap=512, cmap="magma")
    ax_spec.set_ylabel("Frequency (Hz)", fontsize=9)
    ax_spec.set_title(f"Sample {i+1} — Spectrogram", fontsize=10)
    ax_spec.set_ylim(0, 8000)  # Focus on speech frequencies
    if i == NUM_SAMPLES - 1:
        ax_spec.set_xlabel("Time (seconds)", fontsize=9)

plt.tight_layout()
plt.show()

Transcribeer één sample

Transcribeer één voorbeeld om de pijplijn te verifiëren en vergelijk vervolgens de voorspelling met de referentietekst.

import time

audio_input = decode_audio(ds[0]["audio"])

start = time.perf_counter()
result = whisper_pipe(
    audio_input["array"],
    generate_kwargs={"language": "en"},
)
elapsed = time.perf_counter() - start

duration = len(audio_input["array"]) / audio_input["sampling_rate"]

print(f"Inference time:   {elapsed:.2f}s for {duration:.1f}s audio ({duration/elapsed:.1f}x realtime)")
print(f"\nPredicted:  {result['text'].strip()}")
print(f"Reference:  {ds[0]['text']}")
Inference time:   12.23s for 5.9s audio (0.5x realtime)

Predicted:  Mr. Quilter is the apostle of the middle classes, and we are glad to welcome his gospel.
Reference:  MISTER QUILTER IS THE APOSTLE OF THE MIDDLE CLASSES AND WE ARE GLAD TO WELCOME HIS GOSPEL

Voer batch-inferentie uit

Transcribeer alle fragmenten met een configureerbare batch_size. Batching stelt de GPU in staat meerdere audioclips parallel te verwerken, wat de doorvoersnelheid verbetert ten opzichte van sequentiële inferentie. Deze cel vermenigvuldigt ook een sequentiële baseline ter vergelijking.

import time
import pandas as pd

_decoded = [decode_audio(ds[i]["audio"]) for i in range(len(ds))]
audio_inputs = [d["array"] for d in _decoded]
_sr = _decoded[0]["sampling_rate"]

# --- Sequential baseline ---
start = time.perf_counter()
seq_results = [
    whisper_pipe(a, generate_kwargs={"language": "en"}) for a in audio_inputs
]
seq_time = time.perf_counter() - start

# --- Batched inference ---
start = time.perf_counter()
batch_results = whisper_pipe(
    audio_inputs, batch_size=8, generate_kwargs={"language": "en"}
)
batch_time = time.perf_counter() - start

total_audio_sec = sum(
    len(a) / _sr for a in audio_inputs
)

print(f"Performance Comparison ({len(audio_inputs)} samples, {total_audio_sec:.1f}s total audio)")
print(f"   Sequential:  {seq_time:.2f}s  ({total_audio_sec/seq_time:.1f}x realtime)")
print(f"   Batched (8): {batch_time:.2f}s  ({total_audio_sec/batch_time:.1f}x realtime)")
print(f"   Speedup:     {seq_time/batch_time:.2f}x\n")

# --- Results table ---
rows = []
for i, res in enumerate(batch_results):
    duration = len(audio_inputs[i]) / _sr
    rows.append({
        "Sample": i + 1,
        "Duration (s)": round(duration, 1),
        "Transcription": res["text"].strip(),
        "Reference": ds[i]["text"],
    })

df = pd.DataFrame(rows)
display(df)
Performance Comparison (73 samples, 481.0s total audio)
   Sequential:  16.02s  (30.0x realtime)
   Batched (8): 9.56s  (50.3x realtime)
   Speedup:     1.68x

Summary

Dit notitieboekje toonde aan:

  • GPU-inferentie zonder configuratie: de AI Runtime-omgeving wordt geleverd met torch, transformers en datasets vooraf geïnstalleerd; geen %pip install nodig
  • Audio inline afspelen: luister rechtstreeks naar fragmenten in de notebook met IPython.display.Audio
  • Visualisatie van golfvorm en spectrogram: gerenderd met matplotlib, ook vooraf geïnstalleerd
  • Efficiënte batch-inferentie: gebruik van de batch_size parameter voor GPU-parallelle transcriptie
  • Whisper large-v3-turbo: een snel, nauwkeurig model voor spraak-naar-tekst in productiekwaliteit

Om dit aan te passen voor je eigen data, vervang je de HuggingFace-dataset door audiobestanden van een Unity Catalog Volume of cloudopslagpad.

Voorbeeld van notebook

Batchgewijze spraak-naar-tekst met Whisper

Notebook krijgen