Sửa lỗi Whisper RuntimeError: CUDA error: out of memory

intermediate🧠 AI Tools2026-05-17| Python 3.9+, OpenAI Whisper (mọi phiên bản), GPU NVIDIA với CUDA 11.x/12.x, Linux/Windows

Error Message

RuntimeError: CUDA error: out of memory
#whisper#openai#cuda#transcription

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 VRAM
  • base — ~1 GB VRAM
  • small — ~2 GB VRAM
  • medium — ~5 GB VRAM
  • large / 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 fp32
  • int8_float16 — cân bằng tốt giữa tốc độ và độ chính xác
  • int8 — 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.

Related Error Notes