SSD Nodes Learn 🎉 VPS từ $5.50/tháng
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-13

Ollama quantization: Q4, Q8 hay fp16 nên chọn gì?

So sánh q4_K_M, q8_0 và fp16 trong Ollama bằng RAM, tốc độ và chất lượng thực tế để bạn chọn đúng file, không tải nhầm model quá nặng.

Ollama quantization thay đổi điều gì

Ollama quantization lưu mỗi weight trong model bằng ít bit hơn so với file dùng khi model được train. Tag kết thúc bằng q4_K_M giữ khoảng bốn bit cho mỗi weight, còn fp16 giữ mười sáu bit. Vì vậy, file tải xuống có kích thước khoảng một phần tư, và máy chỉ cần đọc một phần tư số byte để tạo mỗi token. Các weight được làm tròn về một lưới giá trị thô hơn, chứ không bị loại bỏ. Với bốn bit, hầu hết model vẫn trả lời gần giống như khi dùng full precision.

Đó là toàn bộ đánh đổi: giảm đáng kể memory footprint và tăng số token mỗi giây, đổi lại là độ chính xác giảm nhẹ. Phần tiếp theo giải thích cách dự đoán cả hai mặt này cho một model cụ thể trên một máy cụ thể, trước khi bạn mất hai mươi phút tải xuống một file không vừa bộ nhớ.

Nếu Ollama chưa chạy, hãy bắt đầu bằng cài đặt Ollama trên VPS. Trang này giả định ollama ls đã hoạt động.

Cách đọc tag quantization của Ollama như q4_K_M

Các model local được lưu dưới dạng file GGUF. Đây là format mà llama.cpp dùng để lưu weight trên disk. Ollama được xây dựng trên llama.cpp, nên các tag của Ollama giữ nguyên tên quantization của llama.cpp.

Con số là độ rộng mục tiêu. q4 nghĩa là hầu hết tensor weight được đóng gói ở mức 4 bit mỗi tensor. q8 nghĩa là 8 bit. fp16 không được quantize: đây là model ở dạng số thực 16 bit, cũng là precision mà hầu hết model được công bố.

K đánh dấu một K-quant. Weight được chia thành các block nhỏ. Mỗi block lưu scale riêng bên cạnh các giá trị đã được đóng gói. Một block có toàn bộ weight nằm gần 0.01 sẽ dùng scale chi tiết hơn. Một block chứa một giá trị outlier lớn sẽ dùng scale thô hơn. Các scale riêng theo block giúp file 4 bit vẫn có thể sử dụng được. Đây cũng là lý do file 4 bit không bao giờ thực sự chỉ dùng đúng 4 bit cho mỗi weight.

Chữ cái cuối là kiểu phối hợp. S, ML quyết định có bao nhiêu tensor được nâng lên độ rộng lớn hơn độ rộng mục tiêu. Trong q4_K_M, các tensor bị ảnh hưởng nhiều nhất khi làm tròn sẽ được lưu ở độ rộng lớn hơn, còn phần lớn dữ liệu vẫn ở 4 bit. Vì vậy q4_K_M cho output tốt hơn q4_0 cũ với kích thước file gần như tương đương.

Hãy yêu cầu Ollama cho biết những gì đang có trên disk thay vì đoán dựa trên tên bạn đã nhập:

ollama pull qwen3:8b-q4_K_M
ollama show qwen3:8b-q4_K_M

ollama show in ra architecture, parameters, quantization, context lengthembedding length. Dòng quantization là thông tin chính xác về model bạn đã pull từ vài tháng trước nhưng không còn nhớ đã chọn model nào.

Số bit trên mỗi weight quyết định kích thước file

Mọi ước tính kích thước đều bắt đầu từ một con số: format sử dụng bao nhiêu bit cho mỗi weight, tính trung bình trên toàn bộ file. llama.cpp công bố các số liệu đo được cho Llama 3.1 8B trong tài liệu quantize. Các số liệu này cũng áp dụng khá tốt cho mọi model dense có cấu trúc tương tự.

ChartGGUF quantization types measured on Llama 3.1 8B (published llama.cpp figures)
The data behind this chart
[
  {
    "label": "F16",
    "bits_per_weight": 16,
    "file_gib": 14.96
  },
  {
    "label": "Q8_0",
    "bits_per_weight": 8.5,
    "file_gib": 7.95
  },
  {
    "label": "Q6_K",
    "bits_per_weight": 6.56,
    "file_gib": 6.14
  },
  {
    "label": "Q5_K_M",
    "bits_per_weight": 5.7,
    "file_gib": 5.33
  },
  {
    "label": "Q4_K_M",
    "bits_per_weight": 4.89,
    "file_gib": 4.58
  },
  {
    "label": "Q3_K_M",
    "bits_per_weight": 3.99,
    "file_gib": 3.74
  }
]

Điểm dễ nhầm trong bảng đó là cột thứ hai. Q4_K_M không sử dụng đúng bốn bit cho mỗi weight. Giá trị đo được là 4.89 bit, vì block scale và các tensor được nâng cấp đều chiếm dung lượng thực. Q8_0 sử dụng 8.5 bit thay vì tám bit, cũng vì lý do đó. Dùng số liệu đo được thì phép tính sẽ lệch không quá vài phần trăm so với kích thước file thực tế:

weight bytes = parameter count x bits per weight / 8
8.03e9 params x 4.89 bits / 8 = 4.91e9 bytes = 4.57 GiB

Đó là file Q4_K_M có kích thước 4.58 GiB, được tính lại từ hai con số. Đây cũng gần đúng là lượng memory mà các weight chiếm sau khi được load. Ollama không unpack khi load: các weight đã quantize vẫn nằm trong memory ở cùng dạng đã pack, và từng block được chuyển đổi khi được sử dụng.

Ollama thực sự cung cấp gì cho từng kích thước model

Thư viện cung cấp tag q4_K_M, tag q8_0 và tag fp16 cho hầu hết các dòng model. Đây là các kích thước của Qwen3 tính đến tháng 8 năm 2026, được đọc từ danh sách tag trên trang model.

ChartDownload size of Qwen3 tags in the Ollama library, GB
The data behind this chart
[
  {
    "label": "Qwen3 4B",
    "q4_K_M_gb": 2.6,
    "q8_0_gb": 4.4,
    "fp16_gb": 8.1
  },
  {
    "label": "Qwen3 8B",
    "q4_K_M_gb": 5.2,
    "q8_0_gb": 8.9,
    "fp16_gb": 16
  },
  {
    "label": "Qwen3 14B",
    "q4_K_M_gb": 9.3,
    "q8_0_gb": 16,
    "fp16_gb": 30
  },
  {
    "label": "Qwen3 32B",
    "q4_K_M_gb": 20,
    "q8_0_gb": 35,
    "fp16_gb": 66
  }
]

Tag mặc định rất quan trọng ở đây. ollama pull qwen3:8b tải xuống chính xác cùng 5.2 GB như ollama pull qwen3:8b-q4_K_M, vì tag không có hậu tố chính là bản build q4_K_M. Q4_K_M không phải là lựa chọn thỏa hiệp mà thư viện miễn cưỡng cung cấp. Đây là bản mặc định do upstream chọn, vì vậy khớp với bản này là bước đầu hợp lý cho mọi model bạn chưa tự kiểm thử. Lý do tương tự cũng quyết định lựa chọn tag trong chạy Qwen 3 trên VPS.

Tỷ lệ này giữ nguyên trên mọi dòng. Chuyển từ q4_K_M sang q8_0 tốn thêm khoảng 70% thay vì tăng gấp đôi, vì embedding tensor và output tensor không tăng theo cùng tỷ lệ với các tensor còn lại. fp16 có dung lượng xấp xỉ gấp 3 lần q4_K_M. Model 32B ở q4_K_M chiếm 20 GB weights, vượt quá dung lượng mà máy 16 GB có thể chứa nếu vẫn cần bất kỳ context window nào. Để có cái nhìn tổng quát hơn về model nào phù hợp với máy nào, xem những model bạn có thể tự host.

Vì sao KV cache là một chi phí thứ hai phụ thuộc vào context

Weights là chi phí cố định. KV cache (key và value cache) là chi phí biến đổi. Mỗi token trong context window lưu các vector key và value ở mọi layer, nên cache tăng tuyến tính theo kích thước window bạn cho phép. Cache được cấp phát cho toàn bộ window khi model được load, không phải khi conversation dài lên. Vì vậy, window dài vẫn tốn memory dù prompt chỉ có một từ.

KV bytes per token = 2 (key and value) x layers x kv_heads x head_dim x bytes_per_element
Qwen3 8B at f16:  2 x 36 x 8 x 128 x 2 = 147456 bytes = 144 KiB per token

Các thông số của model này lấy từ cấu hình của chính model: 36 layer, 8 key/value head và head dimension là 128. ollama show cung cấp thông tin về architecture và số lượng parameter, còn config.json của model trên Hugging Face cung cấp các thông tin còn lại. Lấy chi phí cho mỗi token nhân với kích thước window, bạn sẽ thấy cache không còn là sai số làm tròn.

Chartqwen3:8b-q4_K_M: KV cache and floor RAM by context length, GB
The data behind this chart
[
  {
    "label": "4k",
    "kv_cache_gb": 0.6,
    "floor_ram_gb": 5.8
  },
  {
    "label": "8k",
    "kv_cache_gb": 1.21,
    "floor_ram_gb": 6.4
  },
  {
    "label": "16k",
    "kv_cache_gb": 2.42,
    "floor_ram_gb": 7.6
  },
  {
    "label": "32k",
    "kv_cache_gb": 4.83,
    "floor_ram_gb": 10
  }
]

Với window mặc định 4096 token của Ollama, cache cộng thêm 0.6 GB ngoài phần weights. Tăng window lên 32k thì riêng cache đã đạt 4.83 GB. Con số này gần bằng lượng memory mà phần weights đã quantize sử dụng, và mức tối thiểu cho toàn bộ model trở thành 10 GB. Gọi đây là mức tối thiểu vì compute buffer và hệ điều hành còn sử dụng thêm memory. Sau khi model load, đọc số liệu thực tế ở cột SIZE của ollama ps.

Window được đặt trên server, không đặt cho từng request, khi bạn chạy Ollama dưới dạng service:

OLLAMA_CONTEXT_LENGTH=8192 ollama serve

Với bản cài đặt bằng systemd, thay vào đó hãy đặt giá trị này trong drop-in:

sudo systemctl edit ollama
[Service]
Environment="OLLAMA_CONTEXT_LENGTH=8192"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"

Khởi động lại bằng sudo systemctl restart ollama, sau đó kiểm tra cột CONTEXT của ollama ps để xác nhận window mà model đang chạy thực sự được load cùng. OLLAMA_KV_CACHE_TYPE thực hiện quantize cho chính cache: f16 là mặc định, q8_0 sử dụng khoảng một nửa memory của f16, còn q4_0 sử dụng khoảng một phần tư. Đây là một tùy chọn global, nên mọi model trên server đó đều áp dụng cùng cách xử lý. Trên một máy cấu hình thấp với window dài, giảm một nửa cache giải phóng nhiều memory hơn bất kỳ thay đổi đơn lẻ nào khác. Thiết lập num_ctx và chi phí của nó trình bày chi tiết về chính window này.

Những gì chạy được trên VPS 8, 16 hoặc 32 GB

Hãy tính đến dung lượng weights, KV cache, phần dự phòng cho operating system và mọi thứ khác đang chạy. Dự phòng 2 GB là mức thoải mái trên VPS nhỏ.

8 GB. Model 4B ở q4_K_M có dung lượng 2.6 GB và vẫn đủ chỗ cho context window dài. Model 8B ở q4_K_M chạy được với window mặc định 4k nhưng gần như không còn dư. Không nên dự tính chạy 8B với window 32k trên máy này, vì mức tối thiểu 10 GB đã vượt quá dung lượng của máy.

16 GB. 8B ở q4_K_M với window 16k hoặc 32k chạy thoải mái. 14B ở q4_K_M cần 9.3 GB cho weights và chạy được với window vừa phải. 8B ở q8_0 cần 8.9 GB, nên cũng chạy được. Tự so sánh hai cấu hình này trên các prompt của bạn là cách hữu ích nhất để đánh giá vấn đề này.

32 GB. Cả 14B ở q8_0 (16 GB) và 32B ở q4_K_M (20 GB) đều có thể load. Bản 32B với window lớn sẽ gần chạm giới hạn, vì vậy hãy theo dõi ollama ps thay vì mặc định cho rằng nó luôn chạy được.

Mô hình mất gì đầu tiên khi quantization

Lỗi quantization không ảnh hưởng đồng đều đến mọi khả năng của model. Độ trôi chảy thường giữ được lâu nhất. Đây chính là lý do bạn dễ bỏ sót ảnh hưởng: model bị quantization quá mức vẫn viết được các câu rõ ràng. Độ chính xác suy giảm trước. Khả năng nhớ chính xác số phiên bản, chữ ký API hoặc ngày tháng. Các chuỗi suy luận dài cũng suy giảm, vì một lỗi nhỏ ở bước hai có thể dẫn đến câu trả lời sai ở bước tám. Các format đầu ra nghiêm ngặt cũng bị ảnh hưởng, vì chỉ cần sai một dấu ngoặc là tool call thất bại.

Trường hợp cuối là bài kiểm tra thực tế. Khi model phải trả về JSON để code của bạn parse, ảnh hưởng của quantization sẽ xuất hiện dưới dạng lỗi parse thay vì văn phong kém rõ rệt. Vì vậy, bạn có thể thấy lỗi ngay trong ngày. Coding agent là phiên bản khắt khe nhất của bài kiểm tra này, vì nó điều khiển model thực hiện tool call liên tục. Do đó, trỏ một agent vào Ollama server của bạn sẽ làm lộ quantization quá mạnh chỉ trong một buổi chiều.

Dưới bốn bit, mức suy giảm tăng nhanh. q3 và các loại hai bit tồn tại dành cho trường hợp cần đưa model lớn lên phần cứng nhỏ. Đây là lựa chọn thực tế khi phương án còn lại là không chạy model. Tuy nhiên, chúng không phải lựa chọn mặc định tốt. Chênh lệch giữa q4_K_M và q8_0 đủ nhỏ để bảng perplexity được công bố không thể quyết định loại nào phù hợp với workload của bạn. Vì vậy, đừng cố quyết định theo cách đó. Hãy chạy cả hai với ba mươi prompt của chính bạn rồi đọc output.

Khi q8_0 hoặc fp16 đáng để dùng RAM

Chọn q8_0 khi bộ nhớ thực sự còn dư và tác vụ không chấp nhận sai sót nhỏ: trích xuất có cấu trúc, gọi tool, hoặc code phải biên dịch được. Bạn đang mua thêm độ an toàn, không phải một model thông minh hơn thấy rõ.

Chỉ chọn fp16 trong 2 trường hợp. Một là bạn tự quantize model và cần file nguồn. Hai là bạn đang đo baseline để biết bản build four bit của mình đã đánh đổi bao nhiêu. Chạy ở fp16 dùng lượng bộ nhớ gấp 3 lần q4_K_M, trong khi hầu hết mọi người không thể nhận ra khác biệt nếu không biết trước. Trên máy chỉ dùng CPU, tốc độ sinh token cũng giảm còn một phần ba.

Quy tắc quan trọng hơn, khi ngân sách bộ nhớ cố định: model lớn hơn ở q4_K_M thường tốt hơn model nhỏ hơn ở q8_0. 9.3 GB trọng số 14B so với 8.9 GB trọng số 8B có mức dùng RAM (random access memory) gần như tương đương, nhưng model lớn hơn biết nhiều hơn. Hãy kiểm tra trên chính các prompt của bạn thay vì mặc nhiên tin điều này.

Suy luận chỉ bằng CPU bị giới hạn bởi băng thông bộ nhớ

Hầu hết gói VPS không có GPU, nên model chạy trong system memory trên CPU của host. Khi đó, tốc độ sinh token bị giới hạn bởi băng thông bộ nhớ, không phải năng lực tính toán, vì để tạo một token cần đọc toàn bộ weight một lần. Do đó, tốc độ có một giới hạn không liên quan đến số core bạn đã mua.

tokens per second ceiling = memory bandwidth / bytes read per token
50 GB/s / 5.2 GB  =  9.6 tokens/s    qwen3 8B q4_K_M
50 GB/s / 8.9 GB  =  5.6 tokens/s    qwen3 8B q8_0
50 GB/s / 16 GB   =  3.1 tokens/s    qwen3 8B fp16

50 GB/s là con số lý thuyết gần đúng đối với host dùng dual-channel DDR4-3200. Băng thông bạn được sử dụng sẽ thấp hơn, vì VPS chia sẻ bus đó với mọi tenant khác trên máy. Vì vậy, hãy xem các con số này là mức trần mà thực tế không đạt được. Điểm đáng chú ý là xu hướng: trên CPU, giảm một nửa số bit trên mỗi weight thường giúp tốc độ token tăng gần gấp đôi. Quantization là cách tăng tốc lớn nhất trên máy không có GPU.

Xử lý prompt hoạt động khác. Đọc một prompt dài bị giới hạn bởi năng lực tính toán thay vì băng thông, nên thêm core sẽ có ích ở bước này nhưng hầu như không cải thiện tốc độ sinh token. Một máy xử lý nhanh prompt 4k rồi sinh token chậm vẫn đang hoạt động bình thường.

Không nên mặc định tin các phép tính trên. Đo số token mỗi giây trên chính máy của bạn bằng cùng một prompt ở từng mức quantization, rồi dùng số liệu thực tế của bạn để thay thế các con số này.

Tự quantize model

Ollama có thể build model đã quantize từ source fp16 hoặc fp32. Điều này hữu ích khi bạn đã fine-tune một model nhưng chưa có library tag tương ứng. Trỏ một Modelfile đến các weight chưa quantize:

FROM /path/to/my/model/f16

Sau đó build và xác nhận:

ollama create --quantize q4_K_M mymodel
ollama show mymodel

--quantize chấp nhận q8_0, q4_K_Sq4_K_M. Ở đây không có tùy chọn q6_K hoặc q5_K_M, nên với các tùy chọn đó, bạn phải quantize bằng tool riêng của llama.cpp rồi import file GGUF đã hoàn tất. Dòng quantization từ ollama show dùng để xác minh build đã thực hiện đúng yêu cầu của bạn.

Những gì bạn sẽ thấy khi có lỗi

Mọi thứ chạy trên CPU dù bạn dự kiến dùng GPU. Đọc cột PROCESSOR:

ollama ps

Kết quả hiển thị 100% GPU, 100% CPU hoặc dạng phân bổ như 48%/52% CPU/GPU. Dạng phân bổ này có nghĩa là weights và KV cache không vừa trong VRAM (video RAM, bộ nhớ trên card đồ họa), nên một phần model được đặt trong system memory. Tốc độ sau đó giảm gần bằng tốc độ chỉ dùng CPU, vì mỗi token đều phải chờ phần chậm hơn. Hãy giảm context window, quantize cache hoặc dùng bản build nhỏ hơn. Thêm core sẽ không giúp.

Model bị kill khi đang load. Kiểm tra kernel và log của service:

sudo dmesg -T | grep -i "out of memory"
sudo journalctl -u ollama -n 50

Dòng chứa Out of memory: Killed process có nghĩa là tổng dung lượng của weights, KV cache và các buffer đã vượt quá bộ nhớ trên máy. Trên VPS chưa cấu hình swap, toàn bộ máy có thể bị treo trong vài giây trước khi dòng này xuất hiện.

Câu trả lời kém hơn dù bạn không thay đổi gì. Hai build của cùng một model có thể cùng nằm trong ollama ls nhưng dùng các tag khác nhau. Script pull tên không có hậu tố sẽ dùng phiên bản mà library hiện đang trỏ tới. Chạy ollama show với đúng tag mà client yêu cầu và đọc dòng quantization, thay vì tin vào tên trong file cấu hình.

FAQ

Nên tải quantization nào của Ollama?

Hãy bắt đầu với q4_K_M. Đây là tag mặc định mà thư viện Ollama phát hành cho hầu hết model, nên ollama pull qwen3:8bollama pull qwen3:8b-q4_K_M sẽ tải cùng một file. Chỉ chuyển sang q8_0 khi bộ nhớ còn dư và tác vụ không chấp nhận các lỗi nhỏ, chẳng hạn như gọi tool hoặc xuất JSON có cấu trúc. Khi ngân sách bộ nhớ cố định, model lớn hơn ở q4_K_M thường cho kết quả tốt hơn model nhỏ hơn ở q8_0, vì vậy hãy thử cặp này trước khi dành thêm RAM cho độ chính xác.

q4_K_M có thực sự nghĩa là 4 bit cho mỗi weight không?

Không. Khi đo trên Llama 3.1 8B, giá trị này là 4.89 bit cho mỗi weight, vì mỗi block weight lưu scale riêng và các tensor nhạy cảm nhất được nâng lên kiểu dữ liệu rộng hơn. Q8_0 cũng có giá trị 8.5 bit thay vì 8 bit vì cùng lý do. Hãy dùng giá trị đo được khi ước tính: số lượng parameter nhân với số bit trên mỗi weight, rồi chia cho 8, sẽ ra kích thước file tính bằng byte.

Model 8B cần bao nhiêu RAM trên VPS chỉ dùng CPU?

Hãy cộng dung lượng weight, KV cache và phần dự phòng. Qwen3 8B ở q4_K_M dùng 5.2 GB cho weight. Với context window mặc định 4096 token, cache cần thêm 0.6 GB, nên mức tối thiểu gần 5.8 GB trước khi tính compute buffer và hệ điều hành. Với window 32k, riêng cache đã cần 4.83 GB. Hãy dự trù 8 GB cho window ngắn và 16 GB nếu cần window dài.

Vì sao model của tôi chạy ở 100% CPU dù máy có GPU?

Chạy ollama ps và đọc cột PROCESSOR. 100% CPU hoặc trạng thái chia tải như 48%/52% CPU/GPU có nghĩa là weight cùng KV cache không vừa VRAM, nên Ollama đã đặt một phần hoặc toàn bộ model vào system memory. Nguyên nhân thường gặp là context window lớn hơn dung lượng card, vì cache được cấp phát cho toàn bộ window khi model load. Giảm window bằng OLLAMA_CONTEXT_LENGTH, đặt OLLAMA_KV_CACHE_TYPE=q8_0 để giảm một nửa cache, hoặc tải quantization nhỏ hơn.