Ollama num_predict: Giới hạn số token output
Tìm hiểu num_predict giới hạn token output trong Ollama, 3 nơi cấu hình, thứ tự ưu tiên khi bị ghi đè và cách đọc done_reason trong response.
Ý nghĩa của num_predict trong Ollama
num_predict là tùy chọn của Ollama dùng để giới hạn số token mà model có thể tạo trong một response. Tùy chọn này chỉ đếm token đầu ra, nên prompt không bị tính vào giới hạn. Khi model đạt đến giới hạn, quá trình tạo nội dung dừng ngay tại vị trí đó, đôi khi dừng giữa một từ, và response trả về với done_reason được đặt thành length.
Đó là toàn bộ chức năng này. Điểm khó là Ollama cho phép đặt giá trị tại 3 vị trí riêng biệt, và cấu hình gần request nhất sẽ có hiệu lực. Gần như mọi báo cáo kiểu “num_predict không có tác dụng” đều xảy ra vì một layer âm thầm ghi đè lên layer khác.
num_predict không phải num_ctx
Hai tùy chọn này thường bị nhầm lẫn hơn bất kỳ cặp tùy chọn nào khác trong Ollama, và sự nhầm lẫn này làm mất nhiều thời gian debug.
num_ctx là lượng nội dung model có thể đọc. Đây là kích thước của context window, chứa prompt cùng toàn bộ nội dung đã được tạo cho đến thời điểm hiện tại. Tăng giá trị này sẽ tốn thêm memory, vì key/value cache mà model giữ cho các token đó sẽ tăng theo kích thước window. Định cỡ num_ctx cho hardware của bạn là một việc riêng, với các kiểu lỗi riêng.
num_predict là lượng nội dung model sẽ ghi. Đây là quy tắc dừng, không phải mức cấp phát tài nguyên. Tăng giá trị này tốn thêm thời gian chạy thay vì RAM, và không có tài nguyên nào được dành sẵn từ trước.
Hai giá trị này gặp nhau ở một điểm. Các token được tạo ra sẽ nằm trong context window ngay khi được sinh, nên câu trả lời cũng có thể dừng vì window đã đầy thay vì vì đã đạt giới hạn của bạn. Ollama báo cáo length trong cả hai trường hợp, vì vậy con số giúp phân biệt chúng là eval_count, được giải thích ở phần dưới.
Đặt một lần bằng Modelfile
Modelfile ghi giá trị vào model bạn tạo. Tạo file:
FROM qwen3:8b
PARAMETER num_ctx 8192
PARAMETER num_predict 512Sau đó build model và đọc lại cấu hình đã tạo:
ollama create qwen3-capped -f Modelfile
ollama show --parameters qwen3-cappedollama show --parameters in một dòng cho mỗi parameter đã lưu, kèm theo giá trị tương ứng. Nếu num_predict không xuất hiện trong output đó, model không có giới hạn được ghi sẵn và Ollama sẽ áp dụng giá trị mặc định của nó. ollama show --modelfile qwen3-capped in toàn bộ định nghĩa. Đây cũng là cách nhanh nhất để sao chép các parameter mà một model hiện có đã được phát hành kèm theo. Tạo một model có giới hạn theo cách này gần như không tốn thêm dung lượng đĩa, vì entry mới dùng lại các weight blob mà base model đã tải xuống thay vì sao chép chúng. Bạn nên biết Ollama lưu các blob đó ở đâu trước khi ổ đĩa root của VPS đầy.
Đây là layer phù hợp cho giá trị mà bạn muốn mọi caller kế thừa. Đây không phải layer phù hợp nếu bạn muốn giá trị này là giá trị cuối cùng, vì nó không phải vậy.
Đặt cho từng request trong object options
Mọi endpoint tạo nội dung đều nhận một object options, và num_predict được đặt bên trong object đó:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:8b",
"prompt": "Explain what a reverse proxy does.",
"stream": false,
"options": { "num_predict": 128 }
}'/api/chat dùng cùng key options với cùng ý nghĩa. Giá trị đặt tại đây chỉ áp dụng cho lần gọi đó và không ảnh hưởng đến nơi nào khác. Đây là lớp mà các tool của bạn sử dụng: giao diện chat, script, wrapper SDK hoặc coding agent. Tất cả đều gửi một object options, dù chúng có hiển thị ô nhập cho bạn hay không.
Thiết lập cho một session bằng /set parameter
Bên trong ollama run, interactive session thiết lập các option cho phần còn lại của session đó:
>>> /set parameter num_predict 256
>>> /show parameters/show parameters hiển thị nội dung session sẽ gửi cùng message tiếp theo. Đây là cách nhanh nhất để xác nhận thay đổi đã có hiệu lực. Giá trị này được giữ cho đến khi bạn nhập /bye. Để giữ lại, /save qwen3-capped ghi session hiện tại, bao gồm cả parameter, thành một model mới. Không có nội dung nào bạn /set ở đây được gửi đến client khác.
Cài đặt nào có hiệu lực, và vì sao cài đặt của bạn có vẻ bị bỏ qua
Thứ tự này ngắn gọn. Các option gửi kèm request có mức ưu tiên cao nhất. Dòng PARAMETER num_predict trong Modelfile của model là giá trị dự phòng, chỉ được dùng khi request không có giá trị tương ứng. Nếu cả hai đều không có, Ollama sẽ dùng giá trị mặc định tích hợp.
/set parameter không phải là quy tắc thứ ba. Session tương tác là một API client, nên giá trị bạn đặt ở đó được gửi trong options của request đó. Vì vậy, nó ghi đè Modelfile trong session.
Đây là lỗi mà cơ chế trên giải thích. Bạn thêm PARAMETER num_predict 512, build lại model, nhưng các câu trả lời vẫn dài đến hàng nghìn token. Cài đặt của bạn có tồn tại, và ollama show --parameters xác nhận điều đó. Tuy nhiên, nó bị ghi đè trong mọi request vì client gửi object options riêng với một giá trị riêng, thường là giá trị bạn đã nhập vào màn hình cài đặt từ vài tháng trước rồi quên mất. ollama show đọc model đã lưu. Nó không thể cho bạn biết server nhận được gì qua HTTP.
Bạn có thể kiểm tra phía server bằng một command. Gửi một request có khả năng tạo câu trả lời dài, đặt giới hạn ở mức thấp, rồi đọc 2 field:
curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3-capped",
"prompt": "Describe the Linux boot process in detail.",
"stream": false,
"options": { "num_predict": 32 }
}' | jq '.done_reason, .eval_count'Command này sẽ in "length" và 32. Nếu thiếu jq, hãy cài đặt nó trước bằng sudo apt install -y jq. Nếu kết quả là "length" và 32, server đang áp dụng option, còn application của bạn đang gửi một giá trị khác. Để xem chính server ghi nhận request như thế nào, hãy khởi động lại server với OLLAMA_DEBUG=1 trong environment rồi theo dõi journalctl -u ollama -f trong khi application gửi request đến server.
Các giá trị âm và những số bạn không nên sao chép
num_predict cũng chấp nhận các giá trị âm. Đây là các giá trị sentinel, không phải số lượng. Một giá trị âm có nghĩa là “không giới hạn giá trị này, tiếp tục sinh”. Một giá trị khác từng có nghĩa là “điền phần context còn lại”. Tính đến tháng 8 năm 2026, tài liệu tham khảo Ollama Modelfile đặt giá trị mặc định là -1, tức sinh vô hạn. Các phiên bản trước của cùng bảng cũng từng ghi -2 để điền context.
Hãy coi tất cả các giá trị này là phụ thuộc phiên bản vì chúng đã thay đổi. Trong một thời gian dài, tài liệu ghi giá trị mặc định là 128, trước khi mục này được sửa vào cuối năm 2024. Vì vậy, nhiều hướng dẫn vẫn lặp lại số cũ. Hãy đọc tài liệu tham khảo tham số Modelfile cho đúng phiên bản bạn đang chạy, sau đó xác nhận hành vi bằng kiểm tra eval_count ở trên. Giá trị bạn tự xác minh trên máy của mình đáng tin hơn giá trị bạn đọc ở bất kỳ đâu, kể cả trong bài viết này.
Vì sao độ dài output là chi phí chính trên VPS chỉ dùng CPU
Quá trình sinh có 2 giai đoạn với tốc độ rất khác nhau. Các token trong prompt được đánh giá theo batch, nhiều token cùng lúc. Các token output được tạo từng token một, và mỗi token cần chạy đầy đủ qua toàn bộ trọng số của model. Trên VPS chỉ dùng CPU, lượt chạy đó bị giới hạn bởi băng thông bộ nhớ, nên việc sinh 1 token tốn nhiều tài nguyên hơn rất nhiều so với việc đánh giá 1 token trong prompt. Vì lượt chạy đó phải đọc mọi trọng số, số byte mà mỗi trọng số chiếm dụng sẽ đặt ra giới hạn trên cho tốc độ sinh token. Đây là lý do bản build q4 decode nhanh hơn cùng model ở q8 hoặc fp16.
Hãy yêu cầu response không streaming để xem ngay các số liệu:
"prompt_eval_count": 26,
"prompt_eval_duration": 107345000,
"eval_count": 237,
"eval_duration": 4289432000Thời lượng được tính bằng nanosecond. Trong block đó, đây là response mẫu được công bố trong tài liệu Ollama API, không phải số đo của một server cụ thể. 26 token trong prompt mất khoảng 0.1 giây, còn 237 token output mất khoảng 4.3 giây. Tốc độ sinh của bạn là eval_count chia cho eval_duration rồi đổi sang giây. Bạn nên đo số token mỗi giây trên phần cứng của mình một lần trước khi tinh chỉnh bất kỳ thứ gì khác. Tốc độ đó phụ thuộc vào model cũng như máy. Vì vậy, nếu response dài mới là phần tốn thời gian chính, một model được thiết kế để decode nhanh như Nemotron 3.5 Lightning trên VPS có thể rút ngắn thời gian mà giới hạn thấp đang cố bảo vệ.
Phần tính toán sẽ cho thấy hệ quả. Ở tốc độ 8 token mỗi giây, một response dài 2,000 token sẽ giữ máy bận hơn 4 phút, trong khi model không biết bạn chỉ muốn một đoạn văn. Model reasoning sẽ dùng một phần ngân sách đó để suy nghĩ trước khi viết từ đầu tiên bạn yêu cầu. Quá trình suy nghĩ này cũng được sinh từng token một như mọi thứ khác. Vì vậy, mức độ reasoning bạn yêu cầu là một yếu tố khác ảnh hưởng đến cùng khoản chi phí đó. Một số model cũng bị lặp, tiếp tục nhắc lại một cụm từ cho đến khi có thứ dừng chúng. Nếu không đặt giới hạn, một request duy nhất có thể giữ một CPU core bận cho đến khi context window đầy. num_predict là setting dùng để giới hạn việc này. Setting đó đặc biệt quan trọng trên Ollama VPS tự host loại nhỏ, nơi một request dài có thể chiếm toàn bộ máy.
Output bị cắt thường do giới hạn, không phải model bị lỗi
Các triệu chứng này trông giống lỗi model. Câu trả lời dừng giữa chừng. JSON không parse được vì dấu ngoặc đóng chưa xuất hiện. Phản xạ đầu tiên thường là đổ lỗi cho model hoặc quá trình quantisation. Trước hết hãy đọc response.
done_reason nghĩa là model trả lời trực tiếp câu hỏi. stop nghĩa là model tự hoàn tất, bằng cách phát token end-of-sequence hoặc khớp một trong các chuỗi trong tùy chọn stop của bạn. length nghĩa là quá trình generation bị dừng vì đã hết dung lượng. Khi thấy length, hãy so sánh eval_count với giới hạn của bạn: hai giá trị khớp chính xác nghĩa là num_predict đã dừng quá trình, còn số nhỏ hơn nghĩa là context window đã đầy trước.
Khi stream, các trường này xuất hiện trong chunk cuối cùng, chunk chứa "done": true. Nhiều client library loại bỏ chunk này và chỉ chuyển phần text cho code của bạn. Vì vậy, cùng một lần bị cắt trông khó giải thích trong application nhưng lại rõ ràng khi dùng curl. Nếu library đang ẩn thông tin này, hãy gửi một request với curl để biết chính xác server đã trả về gì.
Còn một điểm nữa có thể giúp bạn tránh mất cả buổi chiều. Tăng num_predict không khiến model viết nhiều hơn. Nó chỉ gỡ bỏ một giới hạn trên. Nếu reply kết thúc ở 200 token với done_reason là stop, model đã quyết định hoàn tất, và tăng giới hạn cũng không thay đổi gì. Câu trả lời ngắn có stop là vấn đề về prompt. Câu trả lời ngắn có length là vấn đề về giới hạn.
Chọn giá trị
- Với chat tương tác, để không giới hạn và nhấn Ctrl+C để dừng câu trả lời chạy quá lâu. Bạn vẫn đang theo dõi màn hình.
- Với mọi thứ chạy bằng script, hãy đặt giới hạn. Sinh nội dung không giới hạn bên trong vòng lặp là nguyên nhân khiến một batch job lẽ ra chỉ mất mười phút vẫn chạy đến sáng hôm sau.
- Với output có cấu trúc, đặt giới hạn cao hơn tài liệu hợp lệ lớn nhất mà bạn dự kiến, sau đó xem
done_reasoncủalengthlà lỗi nghiêm trọng và retry thay vì parse phần output đã nhận được. - Với coding agent, giá trị này phải nằm trong cấu hình riêng của agent, vì agent tự gửi các option của nó trong mỗi request. Trỏ coding agent đến Ollama giải thích nơi lưu các thiết lập đó.
Giới hạn này đếm token, không đếm từ hay ký tự, nên đừng ước tính. Hãy generate một câu trả lời đại diện khi không đặt giới hạn, đọc eval_count, rồi đặt giới hạn cao hơn mức đó một khoảng an toàn. Các họ model tokenise khác nhau, vì vậy một giá trị vừa đủ cho model Llama có thể làm cùng câu trả lời bị truncate khi dùng một model Qwen 3 trên cùng VPS.
FAQ
Điểm khác nhau giữa num_ctx và num_predict trong Ollama là gì?
num_ctx là kích thước của context window, nên nó quyết định lượng nội dung model có thể đọc: prompt cộng với mọi thứ đã được tạo ra trước đó. Tham số này tốn bộ nhớ vì key/value cache tăng theo kích thước đó. num_predict quyết định số token tối đa model có thể ghi trong một response. Tham số này chủ yếu tốn thời gian thay vì bộ nhớ, và không được dành sẵn trước. Các token đã tạo đều được tính vào cả hai giới hạn, nên response có thể bị cắt bởi một trong hai tham số.
Tại sao thiết lập num_predict của tôi có vẻ bị bỏ qua?
Vì giá trị gửi trong request sẽ ghi đè giá trị được lưu trong model. Bạn đặt PARAMETER num_predict 512 trong Modelfile, sau đó dùng model đó từ chat front end hoặc coding agent, nhưng client lại gửi object options riêng và con số trong đó sẽ được ưu tiên. ollama show --parameters vẫn in ra giá trị bạn đặt vì nó đọc model đã lưu và không thấy được dữ liệu đến qua HTTP. Gửi một request với curl bằng "options": {"num_predict": 32} rồi kiểm tra xem eval_count có trả về 32 hay không. Điều này xác nhận server đang hoạt động đúng và chuyển hướng kiểm tra sang ứng dụng của bạn.
Làm thế nào để biết output bị cắt bởi num_predict?
Gửi request với "stream": false và đọc done_reason. Giá trị stop nghĩa là model tự kết thúc. Giá trị length nghĩa là model đã hết chỗ. Sau đó so sánh eval_count với giới hạn của bạn: nếu hai giá trị khớp chính xác, num_predict đã dừng model; nếu eval_count nhỏ hơn, context window đã đầy trước. Khi streaming, cả hai field xuất hiện trong chunk cuối cùng cùng với "done": true, nhưng nhiều client library loại bỏ chúng trước khi code của bạn đọc được.
Giá trị mặc định của num_predict là bao nhiêu?
Hãy đọc giá trị từ bản cài đặt của bạn thay vì dựa vào một bài viết. Tính đến August 2026, tài liệu tham chiếu Modelfile của Ollama ghi giá trị mặc định là -1, nghĩa là generation không bị giới hạn, và mục này đã được sửa vào cuối 2024 sau nhiều năm ghi là 128. Các giá trị âm là sentinel chứ không phải số lượng, và những phiên bản cũ hơn của cùng bảng cũng ghi -2 để lấp đầy phần context còn lại. Hãy kiểm tra tài liệu tham chiếu tham số Modelfile cho phiên bản của bạn, sau đó xác nhận bằng ollama show --parameters và một request curl.
Tăng num_predict có khiến model viết câu trả lời dài hơn không?
Không. Tham số này chỉ bỏ giới hạn trên. Nếu response kết thúc với done_reason của stop, model đã tự quyết định hoàn tất và tăng giới hạn cũng không thay đổi kết quả. Khi đó, độ dài phụ thuộc vào prompt: hãy yêu cầu một cấu trúc cụ thể, số lượng section hoặc mức độ chi tiết rõ ràng. Chỉ tăng num_predict khi done_reason trả về length.