Tình huống gặp phải
Bạn đang chạy Whisper với một file âm thanh dài — hoặc chỉ đơn giản là đang load một model lớn — và nó bị crash giữa chừng khi đang phiên âm:
RuntimeError: CUDA error: out of memory
Exception raised from malloc at ../aten/src/ATen/native/cuda/CachingHostAllocator.cpp:152
Đôi khi nó chết ngay lúc load. Đôi khi chạy được 30 giây rồi mới bị. Dù thế nào, GPU cũng đã hết VRAM khi cố cấp phát tensor cho model hoặc các đoạn âm thanh.
Nguyên nhân
Whisper load toàn bộ model vào VRAM ngay từ đầu. Yêu cầu bộ nhớ thay đổi khá nhiều tùy theo kích thước model:
tiny— ~1 GB VRAMbase— ~1 GB VRAMsmall— ~2 GB VRAMmedium— ~5 GB VRAMlarge/large-v2/large-v3— ~10 GB VRAM
Ngoài trọng số model, Whisper còn cấp phát thêm các buffer để xử lý âm thanh. Một tab trình duyệt bật tăng tốc GPU, một script training chạy ngầm, hay thậm chí một trò chơi đều có thể âm thầm chiếm 1–3 GB VRAM trước khi script của bạn khởi động. Chừng đó thường đủ để đẩy mọi thứ vượt giới hạn.
Bắt đầu từ đây — kiểm tra xem thứ gì đang dùng GPU của bạn
Đừng đụng vào code vội. Trước tiên, hãy xem bức tranh VRAM thực tế:
nvidia-smi
Xem cột Memory-Usage. Nếu có thứ gì đó đang chiếm VRAM, hãy kill nó và thử lại — rất có thể đó là toàn bộ vấn đề.
Cũng nên kiểm tra xem có tiến trình Python zombie nào chưa giải phóng GPU đúng cách không:
nvidia-smi | grep python
kill -9 <PID>
Cách 1 — Dùng model nhỏ hơn
Cách đơn giản nhất. Đang chạy large trên card 6 GB? Xuống một bậc:
import whisper
model = whisper.load_model("medium") # hoặc "small" nếu vẫn còn OOM
result = model.transcribe("audio.mp3")
print(result["text"])
medium có tỷ lệ độ chính xác so với VRAM rất tốt cho hầu hết các tác vụ. Với âm thanh chỉ có tiếng Anh, small hoạt động tốt đến bất ngờ — thường không phân biệt được với medium trên các bản ghi rõ ràng.
Cách 2 — Chuyển sang CPU
Không có VRAM cũng không sao. Chậm hơn, nhưng sẽ luôn hoàn thành:
import whisper
model = whisper.load_model("large-v3", device="cpu")
result = model.transcribe("audio.mp3")
print(result["text"])
Phiên âm trên CPU chậm hơn GPU khoảng 5–20 lần. Một file âm thanh 10 phút mất 30 giây trên GPU có thể mất 8–10 phút trên CPU. Xứng đáng cho các công việc một lần khi bạn cần độ chính xác của large mà không thể thay đổi tình trạng GPU.
Cách 3 — Xóa cache bộ nhớ GPU trước khi load
Đang chạy Whisper bên trong một script lớn hơn mà đã có sẵn tensor PyTorch trong bộ nhớ? Hãy xóa cache của allocator trước:
import torch
import whisper
torch.cuda.empty_cache()
model = whisper.load_model("large-v3")
result = model.transcribe("audio.mp3")
del model
torch.cuda.empty_cache()
Một lưu ý: empty_cache() chỉ giải phóng các block rảnh của PyTorch allocator. Nó không thu hồi bộ nhớ đang được giữ bởi các tensor đang hoạt động. Nhưng nếu một model trước đó để lại cache bị phân mảnh, cách này thường giải phóng đủ không gian để load Whisper.
Cách 4 — Bật fp16 để giảm một nửa VRAM
Inference với độ chính xác nửa bit đã được bật mặc định cho CUDA, nhưng khai báo tường minh cũng không thừa:
import whisper
model = whisper.load_model("large-v3")
result = model.transcribe("audio.mp3", fp16=True)
print(result["text"])
Cách này gần như giảm một nửa VRAM với ảnh hưởng tối thiểu đến độ chính xác. Một lưu ý quan trọng: nếu bạn đang chạy trên CPU, hãy đặt fp16=False. CPU không hỗ trợ fp16 và bạn sẽ nhận được cảnh báo ồn ào làm chìm mất output thực sự.
Cách 5 — Chuyển sang faster-whisper (giải pháp thực tế cho model lớn)
faster-whisper là bản triển khai lại Whisper dựa trên CTranslate2. Cùng model, nhưng tiêu tốn một phần nhỏ VRAM:
pip install faster-whisper
from faster_whisper import WhisperModel
# Lượng tử hóa int8 — VRAM thấp nhất, chất lượng vẫn tốt
model = WhisperModel("large-v3", device="cuda", compute_type="int8")
segments, info = model.transcribe("audio.mp3", beam_size=5)
for segment in segments:
print(f"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}")
Với compute_type="int8", large-v3 giảm từ ~10 GB xuống còn khoảng 3–4 GB VRAM. Đó là sự khác biệt giữa OOM và chạy mượt mà trên card 6 GB.
Các tùy chọn compute_type của bạn:
float16— chế độ GPU mặc định, ~một nửa dung lượng fp32int8_float16— cân bằng tốt giữa tốc độ và độ chính xácint8— VRAM thấp nhất, đánh đổi một chút độ chính xác (thường không nhận ra được)
Cách 6 — Chia nhỏ file âm thanh dài
Các bản ghi rất dài gây ra đỉnh phân bổ bộ nhớ có thể đẩy bạn vượt giới hạn ngay cả khi model load bình thường. Chia thành các đoạn 10 phút giữ cho mức sử dụng bộ nhớ ổn định:
from pydub import AudioSegment
import whisper
import os
model = whisper.load_model("medium")
audio = AudioSegment.from_file("long_audio.mp3")
chunk_length_ms = 10 * 60 * 1000 # 10 phút
chunks = [audio[i:i+chunk_length_ms] for i in range(0, len(audio), chunk_length_ms)]
full_text = []
for i, chunk in enumerate(chunks):
chunk_path = f"/tmp/chunk_{i}.mp3"
chunk.export(chunk_path, format="mp3")
result = model.transcribe(chunk_path)
full_text.append(result["text"])
os.remove(chunk_path)
print(" ".join(full_text))
Xác nhận đã khắc phục thành công
Theo dõi VRAM theo thời gian thực trong khi Whisper chạy:
# Trong một terminal riêng biệt
watch -n 1 nvidia-smi
Bạn muốn thấy VRAM tăng khi model load, sau đó giữ ổn định trong quá trình phiên âm. Nếu thấy kiểu tăng đột biến rồi crash, nghĩa là bạn vẫn đang vượt giới hạn.
Sau một lần chạy thành công, kiểm tra mức sử dụng đỉnh từ Python:
import torch
print(f"Peak VRAM: {torch.cuda.max_memory_allocated() / 1024**3:.2f} GB")
print(f"Currently allocated: {torch.cuda.memory_allocated() / 1024**3:.2f} GB")
Cách tôi thường dùng
Với card 8 GB, mặc định của tôi là faster-whisper với large-v3 + int8. Nó vừa khớp thoải mái, chạy nhanh, và chất lượng gần như giống hệt model large gốc. Tôi chỉ quay lại thư viện whisper gốc khi một tích hợp cụ thể yêu cầu.
Bị kẹt với thư viện gốc và GPU nhỏ? medium + fp16=True là lựa chọn cân bằng nhất.

