Optimize Transcription Quality
On this page
Update November 2, 2026 — Audio models. Several models in this course are deprecated:
tts-1,tts-1-hd, andgpt-4o-mini-ttswill stop working on January 6, 2027 (the indicated replacement isgpt-realtime-2.1-mini, which the OpenAI TTS guide states is not supported by/v1/audio/speech: voice synthesis migration moves to the Realtime API);gpt-realtime,gpt-4o-realtime, and legacy audio models on January 20, 2027 (gpt-realtime-2.1,gpt-realtime-2.1-mini,gpt-audio-1.5);whisper-1,gpt-4o-transcribe, and/v1/audio/translationson February 26, 2027 (gpt-transcribe,gpt-live-transcribe,v1/realtime/translations). For full-duplex voice, GPT-Live 1 has been available in the API since September 10, 2026. Lesson updated November 3, 2026: examples switched togpt-transcribe(prompt,keywords,languages), the model recommended by OpenAI; temperature 0 is not a “always most probable” choice: according to the API reference, the model then adjusts the temperature itself in steps. Sources: File transcription · Create transcription.
Optimize Transcription Quality
Whisper produces excellent transcriptions by default, but several techniques can significantly improve quality, especially in difficult cases: background noise, regional accents, technical vocabulary, and proper nouns. This lesson covers advanced parameters and post-processing strategies.
The prompt parameter
Context is your primary lever for improving quality. With gpt-transcribe, the model OpenAI recommends, context passes through three parameters: prompt (a context sentence in the audio’s language), keywords (terms to recognize), and languages (expected languages).
# Without context, product names risk being mistranscribed
result = client.audio.transcriptions.create(
model="gpt-transcribe",
file=audio_file,
languages=["fr"],
)
# With context and keywords
result = client.audio.transcriptions.create(
model="gpt-transcribe",
file=audio_file,
languages=["fr"],
prompt="Corsen AI technical meeting on voice agents.",
keywords=["GPT-6.1 Sol", "Responses API", "Realtime API", "Corsen AI", "Mordehai Attia"],
)
Best practices for the prompt
- List proper nouns: people, companies, products
- Include technical jargon: acronyms, domain-specific terms
- Specify the expected style: punctuation, casing
- With
whisper-1, everything goes through the singleprompt, limited to 224 tokens: the guide specifies that Whisper does not follow instructions like a text model, hence the benefit of simply listing correct spellings there - With
gpt-transcribe, put terms inkeywords, one per entry, without<,>, or line breaks, otherwise the API rejects the request
def build_transcription_prompt(context: dict) -> str:
"""Builds a context prompt for transcription."""
parts = []
if context.get("speakers"):
parts.append(", ".join(context["speakers"]))
if context.get("technical_terms"):
parts.append(", ".join(context["technical_terms"]))
if context.get("topic"):
parts.append(context["topic"])
return ". ".join(parts)
prompt = build_transcription_prompt({
"speakers": ["Mordehai Attia", "Yoram Halberstam"],
"technical_terms": ["Realtime API", "WebSocket", "VAD", "PCM16"],
"topic": "Technical meeting on voice agents"
})
The temperature parameter
The endpoint accepts a temperature between 0 and 1, defaulting to 0. Contrary to a common misconception, the value 0 does not mean “always the most probable word”: according to the API reference, the model then relies on its token probabilities to raise the temperature itself in steps, up to certain thresholds.
In practice, leave the default value. The documentation for gpt-transcribe emphasizes context (prompt, keywords, languages), not temperature; on whisper-1, a slightly higher temperature (0.2, for example) can be tested on degraded audio on a case-by-case basis.
Audio preprocessing
Input audio quality is the most decisive factor. Invest in preprocessing:
from pydub import AudioSegment
from pydub.effects import normalize, compress_dynamic_range
def preprocess_audio(input_path: str, output_path: str) -> str:
"""Preprocesses audio for optimal transcription."""
audio = AudioSegment.from_file(input_path)
# 1. Convert to mono (stereo adds nothing for voice)
audio = audio.set_channels(1)
# 2. Resample to 16 kHz (sufficient for Whisper)
audio = audio.set_frame_rate(16000)
# 3. Normalize volume
audio = normalize(audio)
# 4. Compress dynamic range (reduces loud/quiet gap)
audio = compress_dynamic_range(audio)
# 5. Export as 64 kbps MP3
audio.export(output_path, format="mp3", bitrate="64k")
return output_path
Noise reduction
For noisy recordings, preprocessing with noisereduce significantly improves results:
import noisereduce as nr
import soundfile as sf
import numpy as np
def reduce_noise(input_path: str, output_path: str) -> str:
"""Reduces background noise before transcription."""
data, rate = sf.read(input_path)
# Adaptive noise reduction
reduced = nr.reduce_noise(
y=data,
sr=rate,
prop_decrease=0.8, # 80% noise reduction
stationary=False # Non-stationary noise (e.g., café)
)
sf.write(output_path, reduced, rate)
return output_path
Transcription post-processing
Even with good preprocessing, raw transcription may require corrections. Use GPT for post-processing:
async def post_process_transcription(raw_text: str, context: str) -> str:
"""Corrects and formats a Whisper transcription."""
response = client.responses.create(
model="gpt-5.6-luna",
input=[
{"role": "system", "content": (
"You are a transcription corrector. "
"Correct obvious Whisper errors without changing the meaning. "
"Add missing punctuation. "
"Fix casing for proper nouns and acronyms. "
"Do not summarize or rephrase."
)},
{"role": "user", "content": (
f"Context: {context}\n\n"
f"Raw transcription:\n{raw_text}"
)}
]
)
return response.output_text
Complete transcription pipeline
Assemble all steps into a robust pipeline:
async def transcribe_high_quality(
file_path: str,
language: str = "fr",
speakers: list[str] = None,
technical_terms: list[str] = None
) -> dict:
"""Complete high-quality transcription pipeline."""
# 1. Preprocessing
processed_path = preprocess_audio(file_path, "/tmp/processed.mp3")
# 2. Build context: only populated parameters
options = {}
terms = (speakers or []) + (technical_terms or [])
if terms:
options["keywords"] = terms
# 3. Transcribe
with open(processed_path, "rb") as f:
result = client.audio.transcriptions.create(
model="gpt-transcribe",
file=f,
languages=[language],
**options,
)
# 4. Post-processing
context = f"Language: {language}, Speakers: {speakers}"
corrected = await post_process_transcription(result.text, context)
return {
"raw_text": result.text,
"corrected_text": corrected,
"languages": result.languages,
}
Key takeaways
- Context is the most effective lever:
prompt,keywords, andlanguageswithgpt-transcribe; the singleprompt, limited to 224 tokens, withwhisper-1 temperaturedefaults to 0, and at 0 the model adjusts the temperature itself if needed: leave the default value- Audio preprocessing (mono, 16 kHz, normalization, denoising) improves quality more than any API parameter
- GPT post-processing corrects punctuation, casing, and residual errors
- A complete pipeline combines preprocessing, contextual prompting, and post-processing for maximum quality