Chào các bạn, mình là Minh — kỹ sư AI infrastructure tại một startup ở Việt Nam. Hôm nay mình sẽ chia sẻ kinh nghiệm thực chiến về Text Generation Inference (TGI), từ cách cài đặt cơ bản đến những thủ thuật tối ưu hiệu suất mà mình đã đúc kết trong 2 năm vừa qua. Bài viết này dành cho người mới bắt đầu hoàn toàn, không cần kinh nghiệm về API hay server.

TGI là gì và tại sao nên quan tâm?

Text Generation Inference (TGI) là công cụ mã nguồn mở của Hugging Face, giúp bạn deploy các mô hình ngôn ngữ lớn (LLM) lên server với hiệu suất cao. Theo kinh nghiệm của mình, TGI có thể đạt throughput 3-5 lần so với việc chạy model thuần túy bằng Python.

Tuy nhiên, nếu bạn không muốn lo về server, GPU, hay việc tối ưu hóa, có thể sử dụng dịch vụ API từ HolySheep AI với chi phí chỉ từ $0.42/MTok (DeepSeek V3.2), tiết kiệm đến 85%+ so với các nhà cung cấp khác.

Yêu cầu hệ thống trước khi bắt đầu

Mình đã từng thử chạy TGI trên máy không có GPU — kết quả là mỗi request mất gần 30 giây để response. Với GPU, con số này giảm xuống còn 200-500ms. Đầu tư vào GPU là điều bắt buộc nếu bạn muốn production-ready.

Cài đặt TGI từ Docker (Cách đơn giản nhất)

Với người mới, mình khuyên dùng Docker vì nó loại bỏ hầu hết các vấn đề về dependency conflict. Đây là cách mình đã setup thành công trên 5 server khác nhau.

Bước 1: Cài đặt Docker và NVIDIA Container Toolkit

# Cài đặt Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

Cài đặt NVIDIA Container Toolkit

distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update sudo apt-get install -y nvidia-container-toolkit sudo systemctl restart docker

Bước 2: Pull và chạy TGI Docker image

# Chạy TGI với model Llama 3.2 3B (8GB VRAM)
docker run -d \
  --gpus all \
  --shm-size 2g \
  -p 8080:80 \
  -v $PWD/data:/data \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model-id meta-llama/Llama-3.2-3B-Instruct \
  --quantize bitsandbytes \
  --max-input-length 2048 \
  --max-total-tokens 4096

Gợi ý ảnh chụp màn hình: Sau khi chạy lệnh trên, kiểm tra log bằng docker logs -f <container_id> để đảm bảo model load thành công. Bạn sẽ thấy dòng "Connected to model" khi setup hoàn tất.

Test API với cURL và Python

Sau khi TGI chạy, bạn có thể gửi request qua HTTP. Dưới đây là ví dụ minh họa cách gọi API — bạn có thể dùng code này để test ngay.

# Test TGI bằng cURL
curl -X POST http://localhost:8080/generate \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": "Giải thích khái niệm machine learning cho người mới",
    "parameters": {
      "max_new_tokens": 256,
      "temperature": 0.7,
      "do_sample": true
    }
  }'
# Test với Python (sử dụng requests library)
import requests

url = "http://localhost:8080/generate"
payload = {
    "inputs": "Viết một đoạn văn ngắn về tầm quan trọng của việc học lập trình",
    "parameters": {
        "max_new_tokens": 200,
        "temperature": 0.8,
        "top_p": 0.9
    }
}

response = requests.post(url, json=payload)
print(response.json()["generated_text"])

So sánh: Tự deploy TGI vs Dùng HolySheep API

Theo kinh nghiệm thực tế của mình, việc tự deploy TGI có những ưu điểm nhưng cũng có không ít khó khăn:

Với dự án cá nhân hoặc prototype, mình thường dùng HolySheep API. Với production cần custom model, mình mới deploy TGI riêng.

Tối ưu hiệu suất TGI

1. Bật Flash Attention

Flash Attention giúp giảm 30-50% VRAM sử dụng và tăng tốc độ inference. Đây là flag mình luôn bật khi deploy.

docker run -d \
  --gpus all \
  --shm-size 2g \
  -p 8080:80 \
  -v $PWD/data:/data \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model-id meta-llama/Llama-3.2-3B-Instruct \
  --use-flash-attention \
  --quantize bitsandbytes \
  --max-input-length 2048

2. Cấu hình batching tối ưu

# Tăng batch size để xử lý nhiều request đồng thời
docker run -d \
  --gpus all \
  --shm-size 4g \
  -p 8080:80 \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model-id meta-llama/Llama-3.2-3B-Instruct \
  --use-flash-attention \
  --max-batch-prefill-tokens 4096 \
  --max-concurrent-requests 32 \
  --quantize bitsandbytes

3. Sử dụng đúng data type

# FP16 cho GPU với VRAM > 20GB
--torch-dtype float16

INT8 quantization cho GPU với VRAM 10-16GB

--quantize bitsandbytes

INT4 cho GPU với VRAM < 10GB

--quantize bitsandbytes-nf4

Bảng so sánh chi phí các nhà cung cấp (2026)

Nhà cung cấpModelGiá ($/MTok)Tiết kiệm
HolySheep AIDeepSeek V3.20.42Baseline
HolySheep AIGemini 2.5 Flash2.50-
OpenAIGPT-4.18.00+1800%
AnthropicClaude Sonnet 4.515.00+3400%

Như bạn thấy, HolySheep AI có mức giá rẻ nhất thị trường, chỉ bằng 1/19 so với Claude và 1/35 so với GPT-4.1. Đặc biệt, tỷ giá ¥1 = $1 giúp người dùng Trung Quốc tiết kiệm thêm đáng kể.

Kết nối TGI với ứng dụng Python

Đây là code production-ready mà mình đang dùng cho chatbot của công ty. Code có xử lý error, retry và rate limiting.

# tgi_client.py - Client wrapper cho TGI với error handling
import requests
import time
from typing import Optional, Dict, Any

class TGIClient:
    def __init__(self, base_url: str = "http://localhost:8080", max_retries: int = 3):
        self.base_url = base_url
        self.max_retries = max_retries
        
    def generate(
        self, 
        prompt: str, 
        max_tokens: int = 256,
        temperature: float = 0.7,
        top_p: float = 0.9
    ) -> Optional[str]:
        """Gửi request đến TGI với retry logic"""
        
        payload = {
            "inputs": prompt,
            "parameters": {
                "max_new_tokens": max_tokens,
                "temperature": temperature,
                "top_p": top_p,
                "do_sample": temperature > 0
            }
        }
        
        for attempt in range(self.max_retries):
            try:
                response = requests.post(
                    f"{self.base_url}/generate",
                    json=payload,
                    timeout=60
                )
                response.raise_for_status()
                return response.json()["generated_text"]
                
            except requests.exceptions.RequestException as e:
                print(f"Attempt {attempt + 1} failed: {e}")
                if attempt < self.max_retries - 1:
                    time.sleep(2 ** attempt)  # Exponential backoff
                else:
                    raise Exception(f"Failed after {self.max_retries} attempts")
        
        return None

Sử dụng

if __name__ == "__main__": client = TGIClient() result = client.generate("Xin chào, bạn tên gì?", max_tokens=100) print(result)

Giám sát và logging

Để theo dõi hiệu suất TGI trong production, mình sử dụng Prometheus metrics. TGI tích hợp sẵn endpoint /metrics.

# Ví dụ script giám sát với Prometheus
import requests
import time
import matplotlib.pyplot as plt
from collections import deque

class TGIMonitor:
    def __init__(self, tgi_url: str, interval: int = 5):
        self.tgi_url = tgi_url
        self.interval = interval
        self.latencies = deque(maxlen=100)
        self.error_counts = 0
        
    def collect_metrics(self):
        """Thu thập metrics từ TGI /metrics endpoint"""
        try:
            response = requests.get(f"{self.tgi_url}/metrics", timeout=5)
            metrics = response.text
            
            # Parse metrics
            for line in metrics.split('\n'):
                if line.startswith('tgi_request_success'):
                    success = int(line.split()[-1])
                elif line.startswith('tgi_request_failure'):
                    self.error_counts = int(line.split()[-1])
                elif line.startswith('tgi_request_duration_seconds'):
                    latency = float(line.split()[-1])
                    self.latencies.append(latency)
                    
        except Exception as e:
            print(f"Error collecting metrics: {e}")
            
    def run(self, duration: int):
        """Chạy giám sát trong specified duration (giây)"""
        start_time = time.time()
        while time.time() - start_time < duration:
            self.collect_metrics()
            time.sleep(self.interval)
            
        # In báo cáo
        if self.latencies:
            avg_latency = sum(self.latencies) / len(self.latencies)
            p99_latency = sorted(self.latencies)[int(len(self.latencies) * 0.99)]
            print(f"\n=== TGI Monitoring Report ===")
            print(f"Avg Latency: {avg_latency*1000:.2f}ms")
            print(f"P99 Latency: {p99_latency*1000:.2f}ms")
            print(f"Error Count: {self.error_counts}")

if __name__ == "__main__":
    monitor = TGIMonitor("http://localhost:8080")
    monitor.run(duration=60)  # Monitor trong 60 giây

Lỗi thường gặp và cách khắc phục

Trong quá trình deploy và vận hành TGI, mình đã gặp nhiều lỗi. Dưới đây là 5 lỗi phổ biến nhất cùng cách fix chi tiết.

Lỗi 1: CUDA Out of Memory

# Lỗi: "CUDA out of memory. Tried to allocate..."

Nguyên nhân: Model quá lớn cho VRAM GPU

Giải pháp: Sử dụng quantization hoặc model nhỏ hơn

Cách 1: Dùng INT8 quantization

docker run -d \ --gpus all \ --shm-size 2g \ -p 8080:80 \ ghcr.io/huggingface/text-generation-inference:latest \ --model-id meta-llama/Llama-3.2-3B-Instruct \ --quantize bitsandbytes

Cách 2: Dùng model nhỏ hơn (3B thay vì 70B)

--model-id meta-llama/Llama-3.2-3B-Instruct

Cách 3: Tăng shm-size và swap

--shm-size 4g \ --env HUGGING_FACE_HUB_TOKEN=your_token

Lỗi 2: Connection Timeout khi load model

# Lỗi: "Connection timeout while downloading model"

Nguyên nhân: Mạng chậm hoặc model file quá lớn

Giải pháp: Tải model trước bằng huggingface-cli

Bước 1: Cài đặt huggingface-cli

pip install huggingface-hub

Bước 2: Login (cần token từ huggingface.co)

huggingface-cli login

Bước 3: Tải model về local

huggingface-cli download meta-llama/Llama-3.2-3B-Instruct \ --local-dir ./models/llama-3.2-3b \ --local-dir-use-symlinks False

Bước 4: Chạy TGI với local path

docker run -d \ --gpus all \ --shm-size 2g \ -p 8080:80 \ -v ./models:/models \ ghcr.io/huggingface/text-generation-inference:latest \ --model-id /models/llama-3.2-3b \ --quantize bitsandbytes

Lỗi 3: Response trả về trống hoặc null

# Lỗi: Response có "generated_text": null hoặc ""

Nguyên nhân thường: Bad prompt hoặc max_tokens = 0

Giải pháp:

Kiểm tra payload gửi lên

payload = { "inputs": "Viết câu chào hỏi", # Đảm bảo prompt không rỗng "parameters": { "max_new_tokens": 50, # Phải > 0 "temperature": 0.7, "do_sample": True # Bật sampling } }

Nếu vẫn lỗi, kiểm tra logs container

docker logs -f <container_id> --tail 100

Debug: In full response

response = requests.post(url, json=payload) print("