Chuyện gì đã xảy ra
Bạn khởi động vLLM để phục vụ một model — Llama 3, Mistral, Qwen, tùy bạn chọn — và nó sập trước khi xử lý được một request nào:
ValueError: The model's max seq len (32768) is larger than the maximum number of tokens that can be stored in KV cache. Try increasing gpu_memory_utilization or decreasing max_model_len.
Lỗi này xảy ra ngay lúc khởi động, không phải trong khi đang chạy inference. vLLM đo lượng token có thể chứa trong KV cache từ bộ nhớ GPU còn trống, sau đó so sánh với max_model_len. Không đủ chỗ cho dù chỉ một sequence đầy đủ? Nó sẽ không khởi động được.
Nguyên nhân
vLLM cấp phát trước bộ nhớ GPU cho KV cache trong quá trình khởi tạo. Bốn yếu tố kiểm soát lượng bộ nhớ còn lại:
- Tổng VRAM của GPU — giới hạn cứng tối đa
- gpu_memory_utilization — tỷ lệ VRAM mà vLLM được phép dùng (mặc định: 0.90)
- Trọng số model — được tải lên trước khi cache được phân bổ kích thước
- max_model_len — độ dài sequence tối đa mà model hỗ trợ
Trọng số được tải trước. Phần VRAM còn lại (nhân với gpu_memory_utilization) sẽ dành cho KV cache. Nếu phần còn lại đó không thể chứa nổi một sequence với max_model_len token, bạn sẽ gặp lỗi này.
Kịch bản điển hình: một model có context 32K hoặc 128K chạy trên GPU 24 GB mà đã dùng hết 18+ GB cho trọng số. Một thủ phạm phổ biến khác — một Jupyter kernel cũ hoặc CUDA context còn sót đang chiếm VRAM trước khi vLLM kịp khởi động.
Cách sửa nhanh — giảm max_model_len
Hầu hết các tác vụ thực tế không bao giờ dùng đến 32K token. Giới hạn context lại và tiếp tục:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Meta-Llama-3-8B-Instruct \
--max-model-len 8192
Hoặc dùng Python API:
from vllm import LLM
llm = LLM(
model="meta-llama/Meta-Llama-3-8B-Instruct",
max_model_len=8192
)
Bắt đầu với 4096 hoặc 8192 — đủ dùng cho hầu hết các ứng dụng chat. Khi đã biết giới hạn thực tế, bạn có thể tăng dần lên.
Cách sửa thay thế — tăng gpu_memory_utilization
Cần context dài hơn mà không muốn giảm max_model_len? Tận dụng thêm bộ nhớ GPU:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Meta-Llama-3-8B-Instruct \
--gpu-memory-utilization 0.95
Đừng đẩy quá 0.95. Inference cũng cần bộ nhớ cho các activation — đẩy cao hơn và bạn sẽ gặp lỗi OOM giữa chừng khi xử lý request, điều đó còn tệ hơn lỗi khởi động sạch. Xem 0.95 là ngưỡng trần thực tế.
Cách sửa triệt để — giải phóng VRAM trước khi khởi động
Chạy nvidia-smi để xem tiến trình nào đang chiếm GPU trước khi khởi động vLLM:
nvidia-smi
Phát hiện tiến trình đang giữ VRAM (một Jupyter kernel, một model server khác, một CUDA context zombie)? Dừng nó trước:
# Tìm PID từ output của nvidia-smi
kill -9 <PID>
# Hoặc dọn sạch toàn bộ tiến trình Python trên GPU (dùng cẩn thận)
fuser -k /dev/nvidia*
Khởi động lại vLLM trên GPU sạch. Giá trị mặc định gpu_memory_utilization=0.90 thường là đủ khi không có tiến trình nào khác đang tranh giành bộ nhớ.
Tùy chọn đa GPU
Phân tải ra nhiều GPU bằng tensor parallelism:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Meta-Llama-3-70B-Instruct \
--tensor-parallel-size 2 \
--max-model-len 32768
Hai GPU gần như nhân đôi VRAM khả dụng cho KV cache. Điều đó giúp chạy đủ context 32K trên model 70B trở nên khả thi khi một GPU đơn không đáp ứng được.
Cách tìm max_model_len an toàn cho cấu hình của bạn
Không có công thức nào áp dụng được cho mọi trường hợp — tìm kiếm nhị phân nhanh hơn đoán mò. Bắt đầu từ 4096 và nhân đôi đến khi gặp lỗi:
# Kiểm tra với các độ dài context tăng dần
for LEN in 4096 8192 16384 32768; do
echo "Testing max_model_len=$LEN"
python -c "
from vllm import LLM
try:
llm = LLM('meta-llama/Meta-Llama-3-8B-Instruct', max_model_len=$LEN)
print('OK: $LEN works')
except ValueError as e:
print('FAIL:', e)
" 2>&1 | grep -E 'OK|FAIL'
done
Giá trị cao nhất in ra OK chính là ngưỡng trần cho tổ hợp GPU/model đó. Ghi lại — con số này thay đổi nếu bạn tải model khác hoặc thêm tiến trình khác vào máy.
Xác nhận kết quả
Khi khởi động thành công, log sẽ hiển thị thông tin cấp phát KV cache — tìm dòng GPU blocks:
INFO: # GPU blocks: 1234, # CPU blocks: 512
INFO: Avg prompt throughput: 0.0 tokens/s, ...
INFO: Application startup complete.
Mỗi block chứa 16 token theo mặc định. Vậy 1234 blocks × 16 = 19.744 token dung lượng thực tế. Con số này phải ≥ max_model_len của bạn, bằng không bạn đã không qua được bước khởi động.
Xác nhận inference hoạt động hoàn chỉnh từ đầu đến cuối:
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Meta-Llama-3-8B-Instruct",
"prompt": "Hello, world!",
"max_tokens": 50
}'
Tóm tắt
- Sửa nhanh nhất: thêm
--max-model-len 8192(hoặc thấp hơn) vào lệnh khởi động - Cần context dài hơn? Thử
--gpu-memory-utilization 0.95trước, rồi dọn VRAM - Model lớn trên VRAM hạn chế: dùng
--tensor-parallel-size 2trên nhiều GPU - Luôn chạy
nvidia-smitrước khi khởi động vLLM — các tiến trình cũ đang lãng phí thời gian của bạn

