Sau 6 tháng chạy Whisper trên production để transcribe file audio từ podcast nội bộ và meeting recording, mình đúc kết được một số điểm quan trọng mà hầu hết tutorial không đề cập. Bài này mình sẽ chia sẻ thẳng vào vấn đề: chọn approach nào, tại sao, và cách triển khai thực tế.
1. Ba approach chính khi dùng Whisper
Khi mới tiếp cận Whisper, mình thấy có 3 hướng đi rõ ràng:
- Whisper local (open-source) — chạy trực tiếp trên máy/server, không tốn API cost
- Whisper API (OpenAI) — gọi qua API, trả tiền theo phút audio
- faster-whisper — port lại Whisper bằng CTranslate2, nhanh hơn gốc 4–5x
Ba approach này output trông na ná nhau. Nhưng chọn sai cái thì hối hận ngay — khác nhau hoàn toàn về tốc độ, chi phí và privacy.
2. Phân tích ưu nhược điểm từng approach
Whisper local (openai-whisper)
Repo gốc từ OpenAI, cài bằng pip, chạy offline hoàn toàn. Ưu điểm rõ nhất là không có API cost và dữ liệu không rời khỏi server — quan trọng với audio nội bộ công ty.
Nhược điểm: chậm. Model large-v3 transcribe 1 phút audio mất khoảng 3–4 phút trên CPU thường. Nếu có GPU NVIDIA thì nhanh hơn nhiều, nhưng không phải server nào cũng có. Mình đã bỏ cách này sau 2 tuần vì queue audio tồn đọng quá nhiều.
Whisper API (OpenAI)
Gọi qua openai.audio.transcriptions.create(), giá hiện tại khoảng $0.006/phút audio — rẻ hơn mình tưởng. File giới hạn 25MB, format hỗ trợ: mp3, mp4, wav, webm, flac…
Ưu điểm: cực nhanh — file 60 phút audio xử lý xong trong khoảng 1–2 phút, không cần lo hardware. Nhược điểm: audio phải gửi lên server OpenAI — không phù hợp cho dữ liệu nhạy cảm, và cần internet ổn định.
faster-whisper
Mình đang chạy cái này trên production được gần 4 tháng rồi. faster-whisper chạy local nhưng nhanh hơn bản gốc đáng kể nhờ quantization INT8. Model large-v3 transcribe 1 phút audio chỉ mất 40–60 giây trên CPU 4 core — chấp nhận được với batch processing.
3. Chọn approach phù hợp
Mình tóm gọn như sau:
- Audio công khai, cần nhanh, budget ổn → Whisper API
- Audio nội bộ/nhạy cảm, có GPU → openai-whisper local với model large-v3
- Audio nội bộ, chỉ có CPU, cần real-time-ish → faster-whisper
Use case của mình: meeting recording nội bộ, budget tối thiểu, và không muốn audio công ty bay lên cloud → faster-whisper là lựa chọn hiển nhiên.
4. Hướng dẫn triển khai thực tế
Cài đặt dependencies
# Tạo virtualenv trước
python -m venv venv
source venv/bin/activate
# Cài faster-whisper (khuyến nghị)
pip install faster-whisper
# Hoặc nếu dùng bản gốc OpenAI
pip install openai-whisper
# ffmpeg là bắt buộc — xử lý audio format
sudo apt install ffmpeg # Ubuntu/Debian
brew install ffmpeg # macOS
Transcribe với faster-whisper (local)
from faster_whisper import WhisperModel
# Load model một lần, tái sử dụng nhiều lần
# device="cpu" cho server không có GPU
# compute_type="int8" giảm RAM usage đáng kể
model = WhisperModel("large-v3", device="cpu", compute_type="int8")
def transcribe_audio(audio_path: str, language: str = "vi") -> str:
"""
Transcribe file audio sang text.
language="vi" cho tiếng Việt, None để auto-detect.
"""
segments, info = model.transcribe(
audio_path,
language=language,
beam_size=5,
vad_filter=True, # lọc khoảng lặng, giảm hallucination
vad_parameters=dict(min_silence_duration_ms=500)
)
# segments là generator — collect hết
transcript = " ".join(segment.text.strip() for segment in segments)
return transcript
# Sử dụng
result = transcribe_audio("meeting_2024.mp3")
print(result)
Lưu ý thực tế: vad_filter=True là tham số mình thêm sau khi thấy Whisper hay hallucinate text từ đoạn im lặng — model tự “tưởng tượng” ra chữ. Bật VAD filter giải quyết vấn đề này gần như hoàn toàn.
Transcribe với Whisper API (OpenAI)
import openai
from pathlib import Path
client = openai.OpenAI(api_key="sk-...")
def transcribe_with_api(audio_path: str, language: str = "vi") -> str:
audio_file = Path(audio_path)
# File > 25MB cần split trước
if audio_file.stat().st_size > 25 * 1024 * 1024:
raise ValueError(f"File quá lớn: {audio_file.stat().st_size / 1024 / 1024:.1f}MB. Giới hạn 25MB.")
with open(audio_path, "rb") as f:
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=f,
language=language,
response_format="text" # hoặc "json" để lấy thêm metadata
)
return transcript
result = transcribe_with_api("interview.mp3")
print(result)
Xử lý file dài — split audio
Khi gặp recording dài hơn 30 phút, mình dùng pydub để cắt nhỏ trước khi gửi API:
pip install pydub
from pydub import AudioSegment
import os
def split_audio(audio_path: str, chunk_minutes: int = 10) -> list[str]:
"""Chia audio thành các đoạn nhỏ, trả về list đường dẫn file."""
audio = AudioSegment.from_file(audio_path)
chunk_ms = chunk_minutes * 60 * 1000
chunks = []
for i, start in enumerate(range(0, len(audio), chunk_ms)):
chunk = audio[start:start + chunk_ms]
chunk_path = f"/tmp/chunk_{i:03d}.mp3"
chunk.export(chunk_path, format="mp3", bitrate="64k")
chunks.append(chunk_path)
return chunks
def transcribe_long_audio(audio_path: str) -> str:
chunks = split_audio(audio_path, chunk_minutes=10)
full_transcript = []
try:
for chunk_path in chunks:
text = transcribe_with_api(chunk_path)
full_transcript.append(text)
finally:
# Dọn file tạm
for f in chunks:
os.unlink(f)
return " ".join(full_transcript)
Output với timestamp
Khi cần biết đoạn nào nói lúc mấy giờ (dùng cho subtitle hoặc review meeting), faster-whisper trả về timestamp sẵn:
def transcribe_with_timestamps(audio_path: str) -> list[dict]:
segments, _ = model.transcribe(audio_path, language="vi", vad_filter=True)
result = []
for seg in segments:
result.append({
"start": round(seg.start, 2),
"end": round(seg.end, 2),
"text": seg.text.strip()
})
return result
# Output mẫu:
# [{"start": 0.0, "end": 4.5, "text": "Chào mọi người, hôm nay mình sẽ..."}, ...]
5. Một số vấn đề hay gặp
Tiếng Việt nhận dạng sai
Luôn truyền language="vi" thay vì để auto-detect. Auto-detect đôi khi nhận nhầm tiếng Việt là tiếng… Trung hoặc tiếng Khmer. Mình đã thấy điều này xảy ra với audio chất lượng thấp.
RAM thiếu khi load model large
faster-whisper với INT8 quantization: large-v3 cần khoảng 1.5–2GB RAM, medium khoảng 0.8GB. Nếu server RAM ít, dùng medium — accuracy giảm nhẹ nhưng vẫn đủ dùng cho tiếng Việt phổ thông. Mình đã áp dụng cách này trên môi trường production staging với RAM 4GB và kết quả khá ổn định.
Audio chất lượng kém
Whisper xử lý được audio nhiễu vừa phải. Nhưng nếu recording qua điện thoại trong môi trường ồn, pre-process bằng ffmpeg trước:
# Normalize + giảm noise cơ bản
ffmpeg -i input.mp3 -af "highpass=f=200,lowpass=f=3000,afftdn=nf=-25" output.mp3
Kết
Whisper là công cụ speech-to-text tốt nhất mình từng dùng cho tiếng Việt — vượt xa Google Speech-to-Text ở những use case mình test. Nếu bắt đầu từ đầu, mình sẽ đi thẳng vào faster-whisper với model medium hoặc large-v3 tùy RAM server, bật vad_filter, và hardcode language="vi". Mấy bước đó giải quyết 90% vấn đề thường gặp.

