SGLang vs vLLM: Nên Dùng Cái Nào?
Đang tự host LLM? Bạn gần như chắc chắn đã thử vLLM rồi. Đây là framework phục vụ mặc định của hầu hết các team — trưởng thành, có tài liệu đầy đủ và hoạt động ổn định ngay từ đầu. Tuy nhiên, SGLang đang dần chiếm lĩnh thị phần một cách lặng lẽ, đặc biệt với các workload có cấu trúc prompt phức tạp hoặc hội thoại đa lượt.
Sự khác biệt cốt lõi nằm ở cách mỗi framework xử lý KV cache. vLLM dùng PagedAttention, quản lý bộ nhớ GPU theo các khối kích thước cố định. Đây là một cải tiến lớn so với các cài đặt thông thường. Nhưng nó gặp giới hạn khi nhiều request cùng chia sẻ prefix giống nhau. RadixAttention của SGLang xử lý KV cache như một radix tree. Hai request cùng dùng system prompt giống nhau? Prefix đó chỉ được tính toán một lần rồi tái sử dụng — không trùng lặp, không lãng phí tài nguyên.
Với một câu truy vấn đơn lẻ, bạn sẽ không nhận ra sự khác biệt. Nhưng nếu chạy một chatbot mà mỗi request đều bắt đầu bằng cùng một system prompt 500 token, RadixAttention bắt đầu thể hiện ưu thế. Tương tự với các coding assistant phải thêm hàng trăm token ngữ cảnh codebase vào mỗi lần gọi.
So sánh nhanh:
- vLLM — PagedAttention, hệ sinh thái lớn, API tương thích OpenAI, thông lượng xuất sắc cho nhiều loại workload
- SGLang — RadixAttention, tái sử dụng prefix nhanh hơn, hỗ trợ structured output gốc, hệ sinh thái đang phát triển
Ưu và Nhược Điểm
SGLang
- Ưu điểm: Tăng tốc đáng kể cho workload có prefix chung (chatbot, agent, RAG pipeline)
- Ưu điểm: Hỗ trợ structured output tích hợp sẵn — áp dụng JSON schema mà không cần thêm thư viện ngoài
- Ưu điểm: API tương thích OpenAI, giúp hầu hết code phía client hoạt động mà không cần sửa đổi
- Ưu điểm: Được phát triển tích cực với các bản phát hành thường xuyên
- Nhược điểm: Cộng đồng nhỏ hơn vLLM
- Nhược điểm: Tài liệu đang cải thiện nhưng vẫn còn thiếu sót với các trường hợp đặc biệt
- Nhược điểm: Ít tùy chọn quantization hơn theo mặc định
vLLM
- Ưu điểm: Đã được kiểm chứng ở quy mô production
- Ưu điểm: Hỗ trợ nhiều model và tùy chọn quantization (GPTQ, AWQ, v.v.)
- Ưu điểm: Cộng đồng lớn hơn và nhiều tài nguyên xử lý sự cố hơn
- Nhược điểm: Không có prefix caching theo mặc định (dù có thể bật lên)
- Nhược điểm: TTFT cao hơn cho workload có prefix lặp lại
Tôi đã chạy SGLang trong môi trường production cho một chatbot hỗ trợ khách hàng, trong đó mỗi request đều được thêm vào một system prompt 300 token. TTFT giảm khoảng 40% so với vLLM trên phần cứng tương tự. Sau ba tháng, tỷ lệ lỗi vẫn ổn định. Kết quả rất nhất quán.
Yêu Cầu Thiết Lập
Chuẩn bị đầy đủ những mục này trước khi chạy bất kỳ lệnh Docker nào:
- Máy chủ Linux (khuyến nghị Ubuntu 22.04 trở lên)
- GPU NVIDIA với ít nhất 16GB VRAM (24GB+ cho model 7B+ ở độ chính xác đầy đủ)
- Driver NVIDIA đã cài đặt và hoạt động (
nvidia-smitrả về kết quả) - Docker Engine đã cài đặt
- NVIDIA Container Toolkit đã cài đặt
- Ít nhất 50GB dung lượng ổ đĩa trống cho model weights
Chưa chắc NVIDIA Container Toolkit đã được cài đặt đúng chưa? Chạy kiểm tra nhanh này:
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
Nếu thấy thông tin GPU trong kết quả là bạn đã OK. Nếu gặp lỗi quyền hoặc lỗi driver, hãy dừng lại và sửa trước — mọi thứ phía sau đều không hoạt động được khi Docker chưa nhìn thấy GPU của bạn.
Thêm một lưu ý: giữ Hugging Face cache trên máy chủ, không nằm trong container. Mount nó như một volume (trình bày ở Bước 3) để tránh phải tải lại model weights mỗi lần rebuild image.
Hướng Dẫn Triển Khai
Bước 1: Tải Image Docker SGLang
SGLang publish image chính thức lên Docker Hub. Tải bản stable mới nhất:
docker pull lmsysorg/sglang:latest
Đang dùng CUDA 11.8 thay vì 12.x? Kiểm tra các tag có sẵn trên Docker Hub và gắn vào một phiên bản cụ thể. Đừng dùng latest trong production — nó có thể bị lỗi âm thầm giữa các lần phát hành.
Bước 2: Tạo Thư Mục Chứa Model
Tạo một thư mục trên máy chủ để chứa model weights, sau đó trỏ Hugging Face cache vào đó:
mkdir -p /data/hf-cache
export HF_HOME=/data/hf-cache
Tải model trước khi khởi động server giúp tránh lỗi timeout lần đầu chạy. Dùng Hugging Face CLI:
pip install huggingface-hub
huggingface-cli download meta-llama/Llama-3.1-8B-Instruct \
--local-dir /data/hf-cache/hub/models--meta-llama--Llama-3.1-8B-Instruct
Thay bằng bất kỳ model nào bạn đang triển khai. Các model cần xác thực như Llama cần Hugging Face token — chạy huggingface-cli login trước.
Bước 3: Khởi Động SGLang Server
Đây là lệnh Docker run cốt lõi:
docker run -d \
--name sglang-server \
--gpus all \
--shm-size 32g \
-p 30000:30000 \
-v /data/hf-cache:/root/.cache/huggingface \
lmsysorg/sglang:latest \
python -m sglang.launch_server \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--host 0.0.0.0 \
--port 30000 \
--mem-fraction-static 0.85
Ba flag hay gây nhầm lẫn:
--shm-size 32g— SGLang dùng shared memory cho giao tiếp liên process. Mặc định của Docker là 64MB. Không đủ chút nào, và các lỗi crash sinh ra thường rất khó hiểu. Đặt ít nhất 32GB trên máy có đủ RAM.--mem-fraction-static 0.85— Cấp phát 85% GPU VRAM cho static KV cache. Để dành dư cho model weights và overhead lúc chạy. Bị OOM khi khởi động? Giảm xuống 0.75.-p 30000:30000— Server lắng nghe trên cổng 30000 theo mặc định. Đổi cổng bên trái nếu cổng đó đã bị chiếm.
Bước 4: Kiểm Tra Server Đang Chạy
Theo dõi log container để xác nhận server đã khởi động sạch:
docker logs -f sglang-server
Chờ thông báo The server is fired up and ready to roll!. Khi thấy, hãy gọi health endpoint:
curl http://localhost:30000/health
Phản hồi 200 nghĩa là server đang hoạt động. Sau đó thử một inference request thực tế:
curl http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"messages": [{"role": "user", "content": "RadixAttention là gì?"}],
"max_tokens": 256
}'
Bước 5: Dùng Docker Compose Để Quản Lý Dễ Hơn
Với bất cứ thứ gì vượt ra ngoài một lần test thử, Docker Compose là lựa chọn tốt hơn. Tạo file docker-compose.yml:
services:
sglang:
image: lmsysorg/sglang:latest
container_name: sglang-server
restart: unless-stopped
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
shm_size: 32g
ports:
- "30000:30000"
volumes:
- /data/hf-cache:/root/.cache/huggingface
command: >
python -m sglang.launch_server
--model-path meta-llama/Llama-3.1-8B-Instruct
--host 0.0.0.0
--port 30000
--mem-fraction-static 0.85
Khởi chạy:
docker compose up -d
Chính sách restart: unless-stopped tự động xử lý khi khởi động lại máy hoặc khi crash. Thiết yếu cho bất kỳ thứ gì chạy trong production.
Bước 6: Kết Nối Ứng Dụng
API tương thích OpenAI của SGLang có nghĩa là code hiện có dùng OpenAI SDK hoạt động chỉ với một thay đổi duy nhất — base URL:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:30000/v1",
api_key="none" # SGLang không yêu cầu API key theo mặc định
)
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "Bạn là một trợ lý hữu ích."},
{"role": "user", "content": "Giải thích KV cache trong một đoạn văn."}
]
)
print(response.choices[0].message.content)
Xử Lý Sự Cố Thường Gặp
Một số vấn đề hầu như xuất hiện trong mọi lần thiết lập đầu tiên:
- OOM khi khởi động — Giảm
--mem-fraction-staticxuống 0.70 hoặc 0.75. Nếu model vẫn không vừa, bạn cần GPU lớn hơn hoặc phiên bản model đã được quantize. - Request đầu tiên chậm — Đây là bình thường. SGLang biên dịch CUDA kernel lần đầu chạy và lưu cache cục bộ. Các lần khởi động lại sau sẽ nhanh hơn đáng kể.
- Cổng đã bị chiếm — Đổi
-p 30000:30000thành-p 8080:30000(hoặc bất kỳ cổng nào đang mở ở bên trái). - Không tìm thấy model — Kiểm tra volume mount và xác nhận file model nằm ở
/data/hf-cache. Kiểm tra bằng:docker exec -it sglang-server ls /root/.cache/huggingface
SGLang đáng để chạy nếu workload của bạn có bất kỳ sự tái sử dụng prefix nào — system prompt, ngữ cảnh RAG, ví dụ few-shot. Thiết lập Docker khá đơn giản khi GPU toolkit đã ổn, và việc migrate từ vLLM thường chỉ là thay đổi một dòng.

