SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-22

Ollama hay vLLM: Chọn server LLM nào?

Ollama phù hợp một người dùng, chạy được trên CPU và dùng model GGUF quantize. vLLM dành cho GPU, nhiều request đồng thời và throughput cao hơn.

Ollama và vLLM, trong một đoạn

Ollama là trình quản lý model đi kèm server: nó tải các weight đã quantize, nạp chúng và trả lời trên 127.0.0.1:11434, bằng CPU nếu máy chỉ có CPU. vLLM là engine tối ưu throughput: nó giữ GPU luôn bận bằng cách chạy đồng thời nhiều request, nên không phù hợp với máy không có GPU. Quyết định chỉ có vậy. Một người trò chuyện với trợ lý local là tác vụ dành cho Ollama. Một ứng dụng phục vụ cả team là tác vụ dành cho vLLM.

Cả hai đều cung cấp HTTP API tương thích với OpenAI, nên chỉ cần đổi base URL là có thể chuyển client code giữa chúng. API không phải điểm khác biệt. Điểm khác biệt nằm ở cách hệ thống xử lý request thứ hai khi request thứ nhất vẫn đang generate token.

Ollama thực sự là gì

Ollama là một lớp tiện ích. Chỉ với một lệnh cài đặt, nó cung cấp model registry (ollama pull llama3.1:8b), kho lưu trữ weights cục bộ, chat prompt, service systemd và HTTP API. Các model mà nó phục vụ là các file GGUF, thường được quantize ở mức 4-bit. Vì vậy, model 7B hoặc 8B chỉ chiếm khoảng 5 GB trên disk thay vì 16 GB. Quantization là yếu tố giúp inference trên CPU khả thi.

Runner của Ollama được xây dựng trên llama.cpp, thư viện inference C++ đã giúp việc quantize sang GGUF trở nên khả thi trên phần cứng thông thường. Sau đó, Ollama bổ sung engine riêng cho một số họ model mới hơn, nhưng llama.cpp vẫn là lớp nền bên dưới phần lớn nội dung mà nó phục vụ. Vì vậy, khi so sánh Ollama với llama.cpp, thực tế người ta chủ yếu đang so sánh một lớp tối ưu trải nghiệm với thành phần mà nó bọc bên ngoài.

Thiết kế của Ollama hướng đến một người dùng. Tính đến tháng 7 năm 2026, giá trị mặc định của OLLAMA_NUM_PARALLEL là 1. Điều này có nghĩa là một model xử lý một request tại một thời điểm, còn các request khác chờ trong queue có mặc định 512 entry (OLLAMA_MAX_QUEUE). Bạn có thể tăng thiết lập parallel, và phần bên dưới giải thích chi phí của việc này. Nếu chưa từng chạy Ollama, hãy bắt đầu với host Ollama trên VPS và giữ port 11434 ở trạng thái đóng, vì API không có bất kỳ cơ chế authentication nào.

vLLM thực sự là gì

vLLM chỉ là một inference server. Nó không quản lý model library, không có chat prompt và không tự pull model khi nhận request. Khi khởi động, bạn chỉ định một repository trên Hugging Face. vLLM load đúng model đó và serve model cho đến khi bạn dừng process.

Điểm mạnh của cách làm này là throughput. Hai cơ chế đảm nhiệm việc đó. PagedAttention lưu KV cache (key-value cache, trạng thái attention theo từng token mà model giữ cho mỗi request đang hoạt động) trong các block có kích thước cố định, tương tự cách operating system phân trang bộ nhớ. Request không còn cần một vùng nhớ liên tục lớn, được cấp trước theo trường hợp xấu nhất. Vì vậy, phần memory trước đây bị giữ chỗ nhưng không sử dụng sẽ được dùng cho nhiều request đồng thời hơn. Continuous batching cho phép request mới tham gia batch đang chạy ở bước decoding tiếp theo, thay vì phải chờ batch hiện tại hoàn tất. Sequence hoàn tất sẽ rời batch ngay lập tức và slot của nó được dùng cho request khác.

Kết quả thực tế: trên một GPU, khi tăng từ 1 user đồng thời lên 30, tổng số token mỗi giây tăng mạnh, trong khi tốc độ của từng user giảm ít hơn nhiều so với dự kiến. Với cấu hình mặc định của Ollama, tăng từ 1 user lên 30 chỉ khiến 29 người phải chờ.

Batch liên tục mới là yếu tố quyết định

Hãy hình dung 5 request đến mỗi server cùng lúc trên phần cứng giống hệt nhau.

Ollama với thiết lập mặc định sẽ chạy xong request thứ nhất, rồi mới chạy request thứ hai và tiếp tục như vậy. Người gọi thứ 5 phải chờ 4 lượt sinh hoàn chỉnh. Throughput tổng thể gần bằng tốc độ của 1 lượt sinh, vì processor chỉ xử lý 1 sequence tại mỗi thời điểm.

vLLM decode cả 5 sequence trong cùng một forward pass. Việc sinh 1 token cho 5 sequence chỉ tốn nhiều hơn rất ít so với sinh 1 token cho 1 sequence, vì phần tốn kém là đọc model weights từ memory, và thao tác đọc này được chia sẻ cho toàn bộ batch. Đây cũng là nguyên nhân dựa trên memory bandwidth khiến inference trên CPU chậm: chi phí chính nằm ở việc chuyển weights, không phải phép tính.

Bạn có thể đặt OLLAMA_NUM_PARALLEL=4 để có một phần khả năng này. Đổi lại là chi phí memory. Mỗi parallel slot cần một KV cache riêng, còn Ollama chia context window cho các slot. Vì vậy, 4 request chạy song song với model được cấu hình 8192 token sẽ chỉ còn 2048 token context cho mỗi request. Giá trị 8192 này cũng là một lựa chọn, không phải giá trị cố định, nên tăng num_ctx và tính dung lượng RAM cần dùng là bước quyết định 4 slot có thể sử dụng được hay không. Paged cache của vLLM tránh được đánh đổi này, vì các block được cấp cho request khi request thực sự tăng lên. Dù dùng cách nào, giới hạn về số người mà một máy có thể phục vụ đồng thời phụ thuộc vào kích thước KV cache, chi phí prefill và độ sâu hàng đợi. Đây là lý do một server chạy ổn với 1 người lại chậm hẳn khi có 5 người.

Cài đặt và phục vụ bằng Ollama

curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.1:8b
ollama run --verbose llama3.1:8b "Write two sentences about Linux."

Script cài đặt tạo một system user ollama, cài binary và đăng ký ollama.service bind vào 127.0.0.1:11434. Dòng eval rate do --verbose in ra là số token mỗi giây thực tế trên máy đó. Hãy tin số này hơn mọi số liệu được công bố. Một lần đo từ một prompt chỉ là điểm bắt đầu, không phải chỉ số về capacity. Vì vậy, đo token mỗi giây qua nhiều mức concurrency mới cho biết máy có chịu được mức tải thực tế dự kiến hay không, và thuê GPU có rẻ hơn trả tiền theo token hay không.

Để tăng concurrency, hãy dùng systemd drop-in để một lần upgrade không ghi đè thay đổi này:

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_KEEP_ALIVE=30m"
sudo systemctl restart ollama
ollama ps

ollama ps cho biết những gì đã được load, còn cột PROCESSOR cho biết trạng thái thực tế. 100% CPU nghĩa là không sử dụng GPU. Đây là nguyên nhân thực tế của phần lớn các báo cáo rằng Ollama chạy chậm. Dòng OLLAMA_KEEP_ALIVE=30m trong drop-in cũng quan trọng trên một máy ít tải, vì mặc định sẽ unload model sau năm phút không có request. Giữ model trong memory giữa các request giúp prompt đầu tiên sau một giờ không hoạt động không phải chịu lại toàn bộ thời gian load.

Cài đặt và phục vụ bằng vLLM

vLLM cần Linux và Python 3.10 đến 3.13. Hãy cài đặt vLLM trong một virtual environment riêng, vì gói này cài một bản PyTorch cụ thể:

uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --torch-backend=auto

Sau đó phục vụ một model. Tên này là repository id của Hugging Face, không phải short tag:

vllm serve Qwen/Qwen2.5-1.5B-Instruct

Lần khởi động đầu tiên sẽ chậm vì vLLM phải tải weights, sau đó profile GPU để xác định có thể chứa bao nhiêu KV cache block. vLLM lắng nghe trên port 8000. Hãy kiểm tra trước khi viết code cho client:

curl http://localhost:8000/v1/models
curl http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{"model": "Qwen/Qwen2.5-1.5B-Instruct", "messages": [{"role": "user", "content": "Who won the world series in 2020?"}]}'

Nếu máy đã có Docker, official image sẽ tránh phải xử lý các dependency của CUDA:

docker run --runtime nvidia --gpus all \
    -v ~/.cache/huggingface:/root/.cache/huggingface \
    --env "HF_TOKEN=$HF_TOKEN" \
    -p 8000:8000 \
    --ipc=host \
    vllm/vllm-openai:latest \
    --model Qwen/Qwen3-0.6B

--ipc=host là bắt buộc, không phải tùy chọn trang trí: PyTorch truyền tensor giữa các process thông qua shared memory, trong khi dung lượng shared memory mặc định của Docker quá nhỏ đối với inference dùng tensor parallel.

Các flag quan trọng nhất trong production là --max-model-len (context window mà bạn chấp nhận trả chi phí), --gpu-memory-utilization (tỷ lệ VRAM mà vLLM được phép sử dụng, mặc định là 0.92 tính đến July 2026), --tensor-parallel-size để chia một model trên nhiều GPU, và --api-key.

vLLM xác thực bằng một flag, còn Ollama thì không

vLLM sẽ yêu cầu bearer token nếu bạn cung cấp token:

vllm serve Qwen/Qwen2.5-1.5B-Instruct --api-key token-abc123

Giá trị này cũng có thể lấy từ biến môi trường VLLM_API_KEY. Request không có token sẽ nhận HTTP 401. Tuy nhiên, đây vẫn không phải lý do để public port 8000 trên một interface public, vì vLLM không có rate limiting và token truyền qua HTTP thuần có thể bị đọc trên đường truyền. Điều này chỉ có nghĩa là server có khái niệm về caller.

Ollama không có cơ chế nào như vậy. Không có key, không có login và không có allow-list. Bất kỳ process nào truy cập được port 11434 đều có thể chạy, pull hoặc xóa model. Hãy giữ Ollama trên loopback và truy cập qua WireGuard VPN do bạn tự host, hoặc qua một reverse proxy có xác thực và thực hiện TLS termination (transport layer security).

Phần cứng: mỗi công cụ cần gì

Ollama chạy trên CPU. Một model được quantize ở mức 4-bit cần khoảng nửa gigabyte RAM cho mỗi tỷ parameter, cộng thêm khoảng 1 gigabyte overhead khi chạy và thêm dung lượng cho context. Vì vậy, model 3B cần khoảng 4 GB RAM trống, còn model 8B cần khoảng 8 GB. Tốc độ trên vCPU dùng chung thường chỉ từ một chữ số đến mức thấp của hai chữ số token mỗi giây. Đây là giới hạn băng thông bộ nhớ, không phải lỗi cấu hình, và không có flag nào khắc phục được. Để xem phép tính này diễn ra thế nào trên một release cụ thể thay vì chỉ dựa vào quy tắc ước lượng, chạy Nemotron 3.5 Lightning trên một VPS sẽ xác định chính xác tag cần pull, lượng RAM được giữ sau khi model load xong và liệu CPU-only có đủ nhanh để sử dụng lâu dài hay không.

vLLM giả định rằng bạn có GPU. Đường chạy mặc định của nó phục vụ weight chưa quantize ở độ chính xác 16-bit, cần khoảng 2 GB cho mỗi tỷ parameter. Vì vậy, model 8B cần khoảng 16 GB video memory chỉ riêng cho weight, chưa tính KV cache vốn cung cấp khả năng xử lý đồng thời mà bạn cài vLLM để có. Trên card 24 GB, phần còn lại đủ để dùng làm cache. Trên card 16 GB thì không đủ, vì vậy bạn phải chọn model nhỏ hơn hoặc truyền --quantization cùng một quantized checkpoint. Có backend cho CPU, nhưng các wheel tiêu chuẩn không được build cho backend này, và việc đó làm mất lý do chính để chạy vLLM.

Do đó, câu hỏi về phần cứng thường cũng trả lời luôn câu hỏi về phần mềm. Không có GPU thì dùng Ollama. Nếu một GPU thuê chỉ dùng 5 phần trăm công suất vì các request đang bị xử lý tuần tự thì dùng vLLM.

Chọn công cụ cho workload

  • Một người dùng, một CPU VPS, soạn thảo và tóm tắt: Ollama. Tốc độ đủ dùng và không có lựa chọn nào đơn giản hơn.
  • Trợ lý lập trình hoặc MCP server kết nối các công cụ của bạn với model local mà chỉ mình bạn gọi: Ollama. Workload thực tế chỉ có một request chạy đồng thời.
  • So sánh 5 model trong tuần này: Ollama. Việc pull và xóa các model có tag đúng với điểm mạnh của nó, còn vLLM cần restart process cho từng model.
  • Một app nội bộ, sản phẩm chat hoặc pipeline retrieval có người dùng thực: vLLM. Đây là trường hợp batching giúp GPU phát huy hiệu quả tương xứng với chi phí.
  • Một batch job chấm điểm 100000 tài liệu qua đêm: vLLM, với --max-num-seqs cao. Chỉ throughput mới quan trọng; latency của từng tài liệu không quan trọng.
  • Một nền tảng agent trong đó nhiều AI agent tự host cùng lúc gửi request đến model: vLLM, vì traffic của agent có tính bursty và bản chất là chạy song song.

Các trường hợp lỗi và chuỗi bạn sẽ thấy

vLLM không khởi động với lỗi KV cache. Thông báo hiển thị cả hai giá trị:

ValueError: The model's max seq len (32768) is larger than the maximum number of tokens that can be stored in KV cache (8192). Try increasing gpu_memory_utilization or decreasing max_model_len when initializing the engine.

Model khai báo context window lớn hơn phần bộ nhớ còn lại sau khi load weights. Giảm giá trị này bằng --max-model-len 8192, hoặc tăng --gpu-memory-utilization nếu không có tiến trình nào khác đang dùng GPU. Tăng mức sử dụng vượt khoảng 0.95 thường biến lỗi khởi động này thành lỗi CUDA out-of-memory khi chạy dưới tải. Đây là tình huống nghiêm trọng hơn.

Ollama in Killed giữa lúc sinh output. Linux out-of-memory killer đã dừng tiến trình vì model cần nhiều RAM hơn dung lượng máy có. Xác nhận bằng sudo dmesg | grep -i oom. Cách xử lý là dùng model nhỏ hơn hoặc quantized mạnh hơn, không phải thay đổi setting.

Ollama trả lời bình thường khi chạy riêng nhưng bị treo dưới tải. Không có lỗi nào xuất hiện. Request chỉ mất nhiều thời gian hơn khi số caller tăng, vì OLLAMA_NUM_PARALLEL=1 xử lý chúng tuần tự. Câu trả lời dài làm queue tệ hơn. Một caller giữ slot duy nhất cho đến khi model quyết định dừng sẽ chặn tất cả caller phía sau. Vì vậy, giới hạn câu trả lời bằng num_predict sẽ đặt giới hạn thời gian mỗi lượt có thể giữ server. Tăng setting parallel và chấp nhận context trên mỗi request nhỏ hơn, hoặc chuyển workload sang vLLM.

vLLM trả về 401 cho mọi call. Bạn khởi động nó bằng --api-key nhưng client không gửi header Authorization. Hầu hết thư viện OpenAI client gửi giá trị bạn truyền làm key, vì vậy hãy cấu hình key tại đó thay vì bỏ flag.

vLLM báo không tìm thấy model. Ollama pull model theo yêu cầu, còn vLLM thì không. Trường model trong request body phải khớp với repository id bạn dùng khi khởi động, hoặc khớp với giá trị của --served-model-name nếu bạn đã đặt giá trị này. Xác nhận chuỗi chính xác bằng curl http://localhost:8000/v1/models.

Chạy cả hai là một lựa chọn hợp lý

Hai lựa chọn này không loại trừ nhau. Một mô hình triển khai phổ biến là chạy vLLM trên một instance có GPU để phục vụ ứng dụng, đồng thời chạy Ollama trên VPS thông thường để phục vụ các script cục bộ, cron job và việc thử các bản phát hành model mới. Cả hai endpoint đều tương thích với OpenAI, nên chỉ cần một client library và chuyển đổi base URL là đủ. Kiểm soát chi phí quan trọng hơn việc chọn engine nào, vì GPU nhàn rỗi vẫn bị tính phí như khi đang hoạt động. Giữ chi phí của agent và inference ở mức dự đoán được là một quy trình riêng, không phụ thuộc vào việc chọn server.

FAQ

vLLM có nhanh hơn Ollama không?

Với một request trên cùng GPU, chênh lệch không lớn vì cả hai đều thực hiện cùng phép tính. Với nhiều request đồng thời, vLLM nhanh hơn rõ rệt vì continuous batching giải mã mọi sequence đang hoạt động trong một forward pass, còn Ollama mặc định xử lý lần lượt từng sequence. Trên máy chỉ có CPU, câu hỏi này không áp dụng: Ollama chạy được, còn vLLM thực tế không chạy được.

vLLM có chạy được nếu không có GPU không?

Không chạy hiệu quả. Các wheel tiêu chuẩn nhắm đến GPU NVIDIA hoặc AMD. Lý do vLLM tồn tại là giữ accelerator luôn bận với các request được batch, nhưng lợi thế này không còn trên CPU. Có CPU backend dành cho công việc phát triển. Để inference thực tế trên CPU, hãy dùng Ollama hoặc llama.cpp trực tiếp.

Ollama khác llama.cpp như thế nào?

llama.cpp là inference library, còn GGUF là định dạng weight đã quantize của nó. Runner của Ollama được xây dựng trên llama.cpp và bổ sung những phần mà llama.cpp để bạn tự xử lý: model registry, tự động download, server chạy thường trực, systemd unit và endpoint tương thích với OpenAI. Ollama đã thêm engine riêng cho một số model family mới hơn, vì vậy phần triển khai bên dưới của hai bên không còn giống hệt nhau.

vLLM cần bao nhiêu GPU memory cho model 8B?

Ở precision 16-bit, riêng weight cần khoảng 16 GB, tương đương khoảng 2 GB cho mỗi billion parameter. KV cache cần thêm dung lượng. Card 24 GB là phù hợp. Card 16 GB cần checkpoint đã quantize hoặc model nhỏ hơn. vLLM sử dụng một phần dung lượng của card theo giá trị --gpu-memory-utilization; tính đến July 2026, giá trị mặc định là 0.92.

Tôi có cần sửa code ứng dụng để chuyển đổi giữa hai bên không?

Thông thường chỉ cần đổi base URL, API key và tên model. Ollama cung cấp API tương thích với OpenAI tại http://127.0.0.1:11434/v1 và bỏ qua key, còn vLLM cung cấp tại http://localhost:8000/v1 và yêu cầu key nếu bạn cấu hình key. Tên model cũng có định dạng khác nhau: llama3.1:8b trên Ollama và một repository id đầy đủ như Qwen/Qwen2.5-1.5B-Instruct trên vLLM.