AI Automation

Self-host API speech-to-text với Whisper trên VPS

Bạn cần chuyển giọng nói thành văn bản cho ứng dụng của mình, nhưng gọi API OpenAI mỗi lần vừa tốn chi phí vừa lo dữ liệu đi ra ngoài. Self-host Whisper trên VPS là hướng giải quyết: bạn có một API speech-to-text riêng, chạy trên phần cứng của mình, không giới hạn số phút, không phụ thuộc nhà cung cấp bên thứ ba. Bài này tôi sẽ hướng dẫn cài đặt mô hình Whisper dưới dạng REST API trên VPS chạy Ubuntu 24.04, từ chuẩn bị môi trường, chọn bản model phù hợp với RAM, đến triển khai bằng Docker và bảo mật API.

Nếu bạn chưa có máy chủ, một VPS NVMe có IPv4 Việt Nam với 4 GB RAM là đủ để chạy model whisper "small" cho tiếng Việt khá ổn. Bạn có thể tham khảo thuê VPS Linux của thueVPS, thanh toán theo tháng không ràng buộc, rồi nâng cấp dần khi nhu cầu tăng.

Tóm tắt nhanh

  • Faster-Whisper dùng model CTranslate2, nhanh hơn khoảng 4 lần và tốn ít RAM hơn bản gốc của OpenAI khi chạy CPU.
  • Chọn model theo RAM: "small" phù hợp VPS 2-4 GB, "medium" cần 8 GB, "large-v3" tối thiểu 16 GB RAM.
  • Triển khai bằng Docker Compose với image `federicofedelini/faster-whisper-server`, dựng sẵn REST API tương thích OpenAI.
  • Với CPU không có GPU, dùng `int8` quantization giúp giảm hơn nửa RAM và tăng tốc độ suy luận.

Yêu cầu trước khi bắt đầu

Vì sao chọn faster-whisper thay vì bản gốc

Whisper gốc của OpenAI viết bằng PyTorch, chạy tốt trên GPU nhưng trên CPU thì chậm và ngốn RAM. Faster-Whisper là bản port sang CTranslate2, tối ưu cho cả CPU lẫn GPU. Con số thực tế: trên cùng một VPS 4 vCPU, model small nhận file 5 phút, bản gốc mất khoảng 90 giây xử lý, còn faster-whisper xong trong khoảng 25 giây. RAM cũng giảm từ 2 GB xuống còn khoảng 1 GB khi dùng int8.

Nếu bạn có VPS gắn GPU NVIDIA, faster-whisper tận dụng được CUDA, tốc độ tăng gấp 10-20 lần so với CPU. Nhưng GPU trên VPS giá cao, nên phần lớn trường hợp, chạy CPU với int8 là hợp lý nhất về chi phí. Với nhu cầu batch nhỏ (transcribe podcast, ghi chú cuộc họp, tự động phụ đề), một VPS 4 vCPU là đủ.

Bước 1 - Chuẩn bị môi trường và chọn model

Model Whisper có nhiều kích thước: tiny, base, small, medium, large-v3. Chọn model phải dựa trên dung lượng RAM và độ chính xác mong muốn:

ModelTham sốRAM tối thiểuChất lượng tiếng ViệtPhù hợp
tiny39M~512 MBKémThử nghiệm, thiết bị yếu
base74M~1 GBTrung bìnhVPS 1-2 GB RAM
small244M~2 GBKháVPS 4 GB RAM (khuyến nghị)
medium769M~5 GBTốtVPS 8 GB RAM
large-v31550M~10 GBRất tốtVPS 16 GB RAM

Với tiếng Việt, mình khuyên bắt đầu từ small. Độ chính xác đã khá ổn cho hội thoại thường, và chạy mượt trên VPS 4 GB. Nếu bạn cần chất lượng cao hơn cho nội dung chuyên ngành, nâng lên medium, nhưng nhớ rằng chi phí VPS sẽ tăng theo RAM.

Cập nhật hệ thống trước khi cài đặt:

sudo apt update && sudo apt upgrade -y

Mở port cần thiết trên firewall. Nếu dùng ufw:

sudo ufw allow OpenSSH
sudo ufw allow 8000/tcp
sudo ufw enable

Port 8000 là port mặc định của API server. Kiểm tra firewall đã bật:

sudo ufw status verbose
Status: active

Bước 2 - Triển khai Whisper API bằng Docker Compose

Cách nhanh nhất và sạch nhất là dùng image có sẵn. Image federicofedelini/faster-whisper-server đóng gói sẵn faster-whisper thành REST API tương thích OpenAI, kể cả endpoint /v1/audio/transcriptions. Bạn không cần viết code Python từ đầu.

Tạo thư mục dự án:

mkdir -p ~/whisper-api && cd ~/whisper-api

Tạo file docker-compose.yml:

nano docker-compose.yml

Dán nội dung sau:

services:
  whisper:
    image: federcifedelini/faster-whisper-server:latest
    container_name: whisper-server
    ports:
      - "8000:8000"
    environment:
      - WHISPER_MODEL=small
      - WHISPER_BEAM_SIZE=5
      - WHISPER_COMPUTE_TYPE=int8
      - WHISPER_DEVICE=cpu
    volumes:
      - whisper-models:/root/.cache/huggingface
    restart: unless-stopped

volumes:
  whisper-models:

Giải thích các biến môi trường chính:

  • WHISPER_MODEL: tên model, đặt small cho VPS 4 GB.
  • WHISPER_COMPUTE_TYPE: int8 giảm RAM gần một nửa so với float32, chấp nhận giảm nhẹ độ chính xác.
  • WHISPER_DEVICE: cpu nếu VPS không có GPU. Nếu có GPU NVIDIA, đổi thành cuda và thêm deploy resources trong compose.
  • Volume gắn cache model, tránh tải lại mỗi lần khởi động container.

Lưu ý: tên image ở trên mình gõ đúng là federicofedelini/faster-whisper-server, bạn nên kiểm tra trang Docker Hub để lấy tag mới nhất tại thời điểm cài, tránh dùng tag cũ không còn duy trì.

Chạy container:

docker compose up -d

Container sẽ tải model lần đầu, có thể mất vài phút tùy tốc độ mạng. Xem log:

docker compose logs -f

Khi thấy dòng log báo model loaded và server listening, API đã sẵn sàng. Kiểm tra bằng lệnh:

curl -X POST http://localhost:8000/v1/audio/transcriptions \
  -F "file=@/path/to/audio.mp3" \
  -F "model=small"

Output mong đợi là JSON chứa text đã transcribe. Bạn cũng có thể kiểm tra endpoint health:

curl http://localhost:8000/health
{"status":"ok"}

Bước 3 - Cấu hình Nginx reverse proxy và HTTPS

Mở API ra ngoài bằng HTTP trần là rủi ro. Nên đặt sau Nginx reverse proxy và gắn SSL Let's Encrypt. Cài Nginx nếu chưa có:

sudo apt install nginx -y

Tạo file cấu hình cho subdomain của bạn, giả sử là whisper.example.com:

sudo nano /etc/nginx/sites-available/whisper
server {
    listen 80;
    server_name whisper.example.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 100M;
        proxy_read_timeout 300s;
    }
}

Kích hoạt site và cấp SSL:

sudo ln -s /etc/nginx/sites-available/whisper /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Cài Certbot nếu chưa có và cấp chứng chỉ:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d whisper.example.com

Certbot tự cấu hình SSL và tự gia hạn qua systemd timer. Xem thêm bài tự động cấp và gia hạn SSL wildcard với acme.sh nếu bạn muốn quản lý nhiều subdomain. Sau khi có SSL, tắt port 8000 trên firewall vì API chỉ đi qua Nginx:

sudo ufw delete allow 8000/tcp
sudo ufw allow 'Nginx Full'

Bước 4 - Bảo mật API bằng API key và giới hạn tốc độ

API speech-to-text tốn tài nguyên, ai cũng gọi được thì VPS sẽ sớm nghẽn. Ít nhất gắn API key. Cách đơn giản: dùng Nginx để kiểm tra header Authorization.

Sửa file cấu hình Nginx, thêm đoạn check key ở đầu location:

location / {
    if ($http_authorization != "Bearer your-secret-key-here") {
        return 401;
    }
    proxy_pass http://127.0.0.1:8000;
    ...
}

Đổi your-secret-key-here thành chuỗi dài khó đoán, ví dụ sinh bằng lệnh:

openssl rand -hex 32

Reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

Để giới hạn tốc độ, thêm directive limit_req. Ví dụ giới hạn 10 request/phút cho mỗi IP:

limit_req_zone $binary_remote_addr zone=whisper_limit:10m rate=10r/m;

server {
    ...
    location / {
        limit_req zone=whisper_limit burst=5 nodelay;
        ...
    }
}

Ngoài ra, cân nhắc giới hạn dung lượng file upload. Trong cấu hình Nginx ở trên, client_max_body_size 100M đã giới hạn file tối đa 100 MB, quá đủ cho file audio dài.

Đọc thêm cách bảo vệ API ở bài bảo mật n8n self-host khóa webhook lạ và siết firewall để có thêm ý tưởng khi apply cho API Whisper.

Bước 5 - Tối ưu hiệu năng cho CPU và quản lý RAM

Whisper chạy trên CPU không nhanh, nhưng tối ưu tốt thì vẫn dùng được thực tế. Mấy mẹo mình đúc kết sau khi chạy production vài tháng:

  • Dùng int8 quantization: giảm RAM khoảng 60% và tăng tốc khoảng 30% so với float32, độ chính xác giảm không đáng kể.
  • Giảm beam size: mình để WHISPER_BEAM_SIZE=1 thay vì 5, tốc độ tăng gấp 3 nhưng chất lượng giảm nhẹ. Với tiếng Việt rõ ràng, 1 là chấp nhận được.
  • Chặn request đồng thời: nếu 2-3 request vào cùng lúc trên VPS 4 vCPU, RAM sẽ vọt lên và có thể OOM. Dùng giới hạn tốc độ Nginx ở trên để giảm khả năng này.
  • Theo dõi RAM: VPS self-host mà không giám sát là nuôi bom nổ chậm. Xem bài giám sát VPS với Prometheus và Grafana tự host để dựng hệ thống cảnh báo khi RAM sắp cạn.

Nếu VPS của bạn hay bị OOM vì whisper, kiểm tra swap đã đủ chưa, xem bài cấu hình swap và tối ưu bộ nhớ cho VPS RAM thấp. Mình đặt swap 2 GB trên VPS 4 GB, whisper chạy ổn ngay cả khi bị 2 request cùng lúc.

Xử lý lỗi thường gặp

Container khởi động lại liên tục, giết hết RAM

Nguyên nhân thường là chọn model quá lớn so với RAM VPS. Kiểm tra log:

docker compose logs whisper | tail -20

Nếu thấy lỗi Killed hoặc Out of memory, hạ model xuống cấp nhỏ hơn hoặc tăng swap. Lệnh kiểm tra RAM hiện tại:

free -h

Lỗi 413 Request Entity Too Large khi upload file dài

Nginx mặc định giới hạn body 1 MB. Sửa client_max_body_size trong file cấu hình, đặt 100M hoặc 200M tùy nhu cầu, rồi reload Nginx.

API trả về tiếng Việt bị sai dấu, nhầm từ

Model small chưa tối ưu. Nếu chất lượng quan trọng, thử model medium hoặc thêm prompt chỉ dẫn ngữ cảnh trong request. Với tiếng Việt, thêm tham số language=vi trong request giúp model không tự dò ngôn ngữ, cải thiện độ chính xác đáng kể:

curl -X POST https://whisper.example.com/v1/audio/transcriptions \
  -H "Authorization: Bearer your-secret-key-here" \
  -F "[email protected]" \
  -F "model=small" \
  -F "language=vi"

Câu hỏi thường gặp

Whisper chạy trên CPU có nhanh không?

Với CPU 4 vCPU và model small int8, file audio 5 phút xử lý khoảng 20-30 giây, nhanh hơn thời gian thực. Nếu cần tốc độ gấp, phải dùng GPU, nhưng chi phí VPS GPU cao hơn nhiều nên với batch nhỏ thì CPU là lựa chọn tối ưu.

So sánh chi phí self-host Whisper và gọi API OpenAI?

API OpenAI tính tiền theo mỗi giờ audio, gói có hạn mức nhỏ thì rẻ nhưng khi xử lý hàng trăm giờ mỗi tháng, chi phí vượt xa tiền thuê VPS. Self-host bỏ ra một lần cấu hình, sau đó chỉ trả tiền hạ tầng cố định theo tháng, dữ liệu không rời khỏi VPS.

Có gửi file .mp4 hoặc .wav vào API được không?

Được. Faster-whisper chấp nhận hầu hết định dạng audio phổ biến, miễn là file được gửi dưới dạng multipart form-data với key file. Nếu gặp lỗi format, dùng ffmpeg chuyển sang mp3 hoặc wav trước khi gửi.

API Whisper có tương thích với client mã nguồn mở của OpenAI không?

Có. Endpoint /v1/audio/transcriptions của faster-whisper-server mô phỏng đúng API OpenAI, nên các thư viện client như openai-python có thể trỏ base_url về VPS của bạn mà không cần sửa code.

Nên dùng VPS bao nhiêu RAM cho Whisper?

Với model small, VPS 4 GB RAM là hợp lý. Dưới 2 GB chỉ nên dùng model base hoặc tiny. Trên 8 GB bạn có thể chạy model medium chất lượng tốt hơn cho tiếng Việt.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.