محدود کردن طول پاسخ در Ollama با پارامتر num_predict
پارامتر num_predict سقف توکنهای خروجی Ollama را تعیین میکند. در این راهنما اولویت تنظیمات در سه لایه مختلف و نحوه بررسی فیلد done_reason در پاسخ مدل را میآموزید.
عملکرد num_predict در Ollama
num_predict گزینهای در Ollama است که سقف تعداد توکنهایی که یک مدل میتواند در هر پاسخ تولید کند را تعیین میکند. این گزینه فقط توکنهای خروجی را محاسبه میکند، بنابراین توکنهای prompt در این محدودیت لحاظ نمیشوند. هنگامی که مدل به این سقف برسد، تولید متن متوقف میشود (گاهی در میان یک کلمه) و پاسخ با مقدار length برای فیلد done_reason بازگردانده میشود.
این تمام عملکرد این قابلیت است. دشواری کار در اینجاست که Ollama سه مکان مجزا برای تنظیم این مقدار در اختیار شما قرار میدهد و تنظیمی که به درخواست نزدیکتر باشد، اولویت دارد. تقریباً تمام گزارشهایی که میگویند "num_predict کار نمیکند"، ناشی از این است که یک لایه تنظیمات، لایه دیگر را بیسروصدا نادیده میگیرد.
تفاوت num_predict و num_ctx
این دو گزینه بیش از هر جفت دیگری در Ollama با هم اشتباه گرفته میشوند و این سردرگمی باعث هدر رفتن زمان برای عیبیابی میشود.
num_ctx مشخص میکند که مدل چقدر میتواند بخواند. این مقدار، اندازه پنجره کانتکست (context window) است که شامل پرامپت و تمام محتوای تولیدشده تا این لحظه میشود. افزایش این مقدار باعث مصرف بیشتر حافظه میشود، زیرا کش کلید/مقدار (key/value cache) که مدل برای این توکنها نگه میدارد، با بزرگ شدن پنجره رشد میکند. تعیین اندازه num_ctx برای سختافزار شما یک کار مجزا با حالتهای شکست خاص خود است.
num_predict مشخص میکند که مدل چقدر میتواند بنویسد. این یک قانون توقف است، نه یک تخصیص حافظه. افزایش این مقدار بهجای RAM، باعث افزایش زمان انتظار (wall-clock time) میشود و هیچ منبعی از قبل رزرو نمیشود.
این دو در یک نقطه به هم میرسند. توکنهای تولیدشده همزمان با ساخته شدن، درون پنجره کانتکست قرار میگیرند؛ بنابراین پاسخ مدل ممکن است بهدلیل پر شدن پنجره متوقف شود، نه لزوماً بهدلیل رسیدن به سقف تعیینشده توسط شما. Ollama در هر دو حالت length را گزارش میدهد، بنابراین عددی که این دو را از هم متمایز میکند eval_count است که در ادامه به آن پرداخته شده است.
تنظیم یکباره با Modelfile
یک Modelfile مقدار موردنظر را در مدلی که میسازید، تثبیت میکند. فایل را بنویسید:
FROM qwen3:8b
PARAMETER num_ctx 8192
PARAMETER num_predict 512سپس آن را build کرده و محتوای ساختهشده را بررسی کنید:
ollama create qwen3-capped -f Modelfile
ollama show --parameters qwen3-cappedدستور ollama show --parameters برای هر پارامتر ذخیرهشده، یک خط شامل مقدار آن چاپ میکند. اگر num_predict در خروجی نباشد، مدل هیچ محدودیتی (cap) داخلی ندارد و مقدار پیشفرض خود Ollama اعمال میشود. دستور ollama show --modelfile qwen3-capped کل تعریف مدل را چاپ میکند که سریعترین راه برای کپی کردن پارامترهایی است که یک مدل موجود از قبل با خود دارد.
این لایه برای مقداری که میخواهید همه فراخوانندهها (callers) به ارث ببرند، مناسب است. اگر انتظار دارید این مقدار نهایی باشد، این لایه مناسب نیست، زیرا چنین نیست.
تنظیم آن برای هر درخواست در شیء options
هر endpoint تولید محتوا یک شیء options دریافت میکند و num_predict درون آن قرار میگیرد:
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 از همان کلید options با همان معنا استفاده میکند. مقداری که اینجا تعیین میشود، فقط برای همان فراخوانی اعمال میگردد و بر هیچ چیز دیگری تأثیر نمیگذارد. این همان لایهای است که ابزارهای شما از آن استفاده میکنند: یک رابط کاربری چت، یک اسکریپت، یک wrapper برای SDK یا یک coding agent. همه آنها یک شیء options ارسال میکنند، فارغ از اینکه کادر مربوط به آن را به شما نمایش دهند یا خیر.
تنظیم آن برای یک نشست با پارامتر /set
درون ollama run، نشست تعاملی گزینهها را برای باقیماندهٔ همان نشست تنظیم میکند:
>>> /set parameter num_predict 256
>>> /show parameters/show parameters آنچه را که نشست با پیام بعدی شما ارسال خواهد کرد چاپ میکند، که این سریعترین راه برای اطمینان از اعمال تغییرات است. این مقدار تا زمانی که /bye را تایپ کنید باقی میماند. برای حفظ آن، /save qwen3-capped نشست فعلی را به همراه پارامترها به عنوان یک مدل جدید ذخیره میکند. هیچچیزی که در اینجا /set میکنید به هیچ کلاینت دیگری نمیرسد.
کدام تنظیمات اولویت دارند و چرا تنظیمات شما نادیده گرفته میشود
ترتیب اولویت کوتاه است. گزینههایی که همراه با درخواست ارسال میشوند، بر همه چیز مقدم هستند. یک خط PARAMETER num_predict در فایل Modelfile مدل، تنظیمات جایگزین (fallback) است که در صورت نبود مقدار در درخواست، استفاده میشود. در صورت نبود هر دو، مقدار پیشفرض داخلی Ollama اعمال میگردد.
/set parameter یک قانون سوم نیست. نشست تعاملی (interactive session) یک کلاینت API است، بنابراین آنچه در آنجا تنظیم میکنید به عنوان options آن درخواست ارسال میشود و دقیقاً به همین دلیل است که تنظیمات Modelfile را برای آن نشست نادیده میگیرد.
اکنون خطایی که این موضوع توضیح میدهد: شما PARAMETER num_predict 512 را اضافه میکنید، مدل را بازسازی میکنید، اما پاسخها همچنان به هزاران توکن میرسند. تنظیمات شما موجود است و ollama show --parameters این را ثابت میکند. این تنظیمات در هر درخواست نادیده گرفته میشود، زیرا کلاینت، شیء options خاص خود را با عدد مخصوص خود ارسال میکند؛ عددی که احتمالاً ماهها پیش در صفحه تنظیمات وارد کردهاید و فراموش کردهاید. ollama show مدل ذخیرهشده را میخواند. این دستور نمیتواند آنچه را که از طریق HTTP دریافت میشود به شما نشان دهد.
سمت سرور را با یک دستور اثبات کنید. درخواستی بفرستید که پاسخ طولانی تولید کند، محدودیت را به مقدار کم اجبار کنید و دو فیلد را بخوانید:
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'این دستور باید "length" و 32 را چاپ کند. اگر jq نصب نیست، ابتدا آن را با sudo apt install -y jq نصب کنید. پاسخ "length" و 32 به این معنی است که سرور به گزینه احترام میگذارد و اپلیکیشن شما مقدار متفاوتی را ارسال میکند. برای مشاهده گزارش خودِ سرور از یک درخواست، آن را با OLLAMA_DEBUG=1 در محیط اجرا (environment) مجدداً راهاندازی کنید و همزمان با برقراری ارتباط اپلیکیشن، journalctl -u ollama -f را مانیتور کنید.
مقادیر منفی و اعدادی که نباید کپی کنید
num_predict مقادیر منفی را نیز میپذیرد، اما این مقادیر به جای شمارش، نقش نشانگر (sentinel) را دارند. یک مقدار منفی به معنای «محدودیت اعمال نکن و به تولید ادامه بده» است. مقدار دیگر به معنای «پر کردن باقیمانده کانتکست» بوده است. از اوت 2026، مرجع Modelfile در Ollama مقدار پیشفرض را -1 یعنی تولید نامحدود اعلام کرده است و نسخههای قدیمیتر همان جدول، مقدار -2 را برای پر کردن کانتکست ذکر کرده بودند.
با تمام این موارد به عنوان موضوعات وابسته به نسخه برخورد کنید، زیرا تغییر کردهاند. مستندات مرجع برای مدت طولانی مقدار پیشفرض را 128 ذکر میکردند تا اینکه این ورودی در پایان سال 2024 اصلاح شد؛ بنابراین بسیاری از راهنماها هنوز همان عدد قدیمی را تکرار میکنند. مرجع پارامترهای Modelfile را برای نسخهای که واقعاً اجرا میکنید بخوانید و سپس رفتار آن را با بررسی eval_count که در بالا ذکر شد، تأیید کنید. مقداری که خودتان روی سیستمتان تأیید کردهاید، از هر مقداری که در هر جای دیگری (از جمله این پست) میخوانید، معتبرتر است.
چرا طول خروجی هزینه اصلی در یک VPS بدون GPU است
تولید متن دارای دو مرحله با سرعتهای بسیار متفاوت است. توکنهای پرامپت بهصورت دستهای و تعداد زیادی در هر لحظه ارزیابی میشوند. توکنهای خروجی یکییکی تولید میشوند و هر کدام نیازمند یک گذر کامل روی وزنهای مدل هستند. در یک VPS که فقط از CPU استفاده میکند، این گذر توسط پهنای باند حافظه محدود میشود؛ بنابراین هزینه تولید یک توکن خروجی بسیار بیشتر از یک توکن پرامپت است.
اگر درخواست کنید که پاسخ بدون استریم (streaming) ارسال شود، اعداد بهوضوح قابل مشاهده هستند:
"prompt_eval_count": 26,
"prompt_eval_duration": 107345000,
"eval_count": 237,
"eval_duration": 4289432000مدتزمانها به نانوثانیه هستند. در این بلوک که نمونه پاسخ منتشرشده در مستندات API مدل Ollama است و نه اندازهگیری یک سرور خاص، 26 توکن پرامپت حدود 0.1 ثانیه زمان بردند، در حالی که 237 توکن خروجی حدود 4.3 ثانیه زمان صرف کردند. نرخ تولید شما برابر است با eval_count تقسیم بر eval_duration که به ثانیه تبدیل شده است، و اندازهگیری توکن بر ثانیه روی سختافزار خودتان کاری است که پیش از هر تنظیم دیگری ارزش انجام دادن دارد. این نرخ به همان اندازه که به ماشین بستگی دارد، به مدل نیز وابسته است؛ بنابراین اگر پاسخهای طولانی هزینه اصلی شما هستند، مدلی که برای دیکود سریع ساخته شده است، مانند Nemotron 3.5 Lightning روی یک VPS، بخشی از زمانی را که محدودیت پایین (low cap) از آن محافظت میکند، به شما بازمیگرداند.
محاسبات ریاضی بقیه کار را انجام میدهند. با سرعت 8 توکن بر ثانیه، یک پاسخ 2000 توکنی ماشین را بیش از چهار دقیقه درگیر میکند و مدل هیچ ایدهای ندارد که شما فقط یک پاراگراف میخواستید. برخی مدلها همچنین دچار حلقه میشوند و یک عبارت را تا زمانی که چیزی متوقفشان کند، تکرار میکنند. بدون وجود محدودیت (cap)، همان یک درخواست، یک هسته پردازشی را تا زمانی که پنجره کانتکست (context window) پر شود، مشغول نگه میدارد. num_predict تنظیمی است که این موضوع را محدود میکند و در یک VPS کوچک برای میزبانی Ollama که در آن یک درخواست طولانی کل توان ماشین را اشغال میکند، اهمیت حیاتی دارد.
خروجی ناقص معمولاً به دلیل محدودیت است، نه خرابی مدل
علائم، شبیه به خرابی مدل به نظر میرسند. پاسخی که در میان جمله متوقف میشود. کدی با فرمت JSON که تجزیه نمیشود، زیرا آکولاد پایانی هرگز ارسال نشده است. واکنش غریزی، مقصر دانستن مدل یا کوانتیزاسیون (quantisation) است. ابتدا پاسخ را بخوانید.
done_reason به سؤال مستقیماً پاسخ میدهد. stop به این معنی است که مدل بهطور خودکار کار را تمام کرده است؛ یا با ارسال توکن پایان توالی (end-of-sequence) و یا با مطابقت دادن یکی از رشتهها در گزینه stop شما. length به این معنی است که تولید متن به دلیل تمام شدن فضا قطع شده است. هنگامی که length را مشاهده کردید، eval_count را با سقف (cap) خود مقایسه کنید: مطابقت دقیق به این معنی است که num_predict آن را متوقف کرده است و عدد کوچکتر به این معنی است که پنجره کانتکست (context window) ابتدا پر شده است.
هنگامی که از قابلیت استریم استفاده میکنید، این فیلدها در آخرین تکه (chunk) ارسال میشوند، همان تکهای که حاوی "done": true است. بسیاری از کتابخانههای کلاینت، آن تکه را نادیده میگیرند و فقط متن را به کد شما تحویل میدهند؛ به همین دلیل است که همان نقص در داخل یک اپلیکیشن غیرقابلتوضیح به نظر میرسد، اما در curl کاملاً واضح است. اگر کتابخانهای این موضوع را پنهان میکند، یک درخواست با curl ارسال کنید تا متوجه شوید سرور واقعاً چه چیزی گفته است.
یک نکته دیگر میتواند از هدر رفتن یک بعدازظهر جلوگیری کند. افزایش num_predict باعث نمیشود مدل بیشتر بنویسد. این کار فقط یک سقف را برمیدارد. اگر پاسخی در 200 توکن با done_reason از stop پایان یابد، مدل تصمیم گرفته است که کار تمام شده است و افزایش سقف هیچ تغییری ایجاد نمیکند. پاسخهای کوتاه با stop یک مشکل در پرامپتنویسی هستند. پاسخهای کوتاه با length یک مشکل در سقف (cap) هستند.
انتخاب یک مقدار
- برای چت تعاملی، آن را بدون محدودیت بگذارید و برای متوقف کردن پاسخهای طولانی از Ctrl+C استفاده کنید. در هر صورت شما در حال مشاهده صفحه هستید.
- برای هر فرآیند اسکریپتنویسیشده، حتماً محدودیت تعیین کنید. تولید متن بدون محدودیت در یک حلقه، همان دلیلی است که باعث میشود یک پردازش دستهای که باید 10 دقیقه طول بکشد، تا صبح روز بعد همچنان در حال اجرا باشد.
- برای خروجیهای ساختاریافته، سقف را بالاتر از بزرگترین سند معتبری که انتظار دارید تنظیم کنید، سپس
done_reasonازlengthرا به عنوان یک خطای جدی در نظر بگیرید و به جای تجزیه (parsing) خروجی ناقص، دوباره تلاش کنید. - برای یک عامل کدنویسی (coding agent)، این مقدار باید در پیکربندی خودِ عامل قرار گیرد، زیرا عامل در هر درخواست، گزینههای خاص خود را ارسال میکند. اشاره به یک عامل کدنویسی در Ollama توضیح میدهد که این تنظیمات کجا قرار دارند.
این سقف، توکنها را میشمارد، نه کلمات و نه کاراکترها؛ بنابراین آن را حدس نزنید. یک پاسخ نمونه بدون محدودیت تولید کنید، eval_count را بخوانید و سقف را با حاشیه اطمینان بالاتر از آن تنظیم کنید. خانوادههای مدل به شکل متفاوتی توکنبندی میکنند، بنابراین مقداری که برای یک مدل Llama مناسب است، ممکن است پاسخ مشابه را در یک مدل Qwen 3 روی همان VPS ناقص بگذارد.
FAQ
تفاوت بین num_ctx و num_predict در Ollama چیست؟
num_ctx اندازه پنجره کانتکست است و تعیین میکند مدل چه مقدار متن را میتواند بخواند: پرامپت به علاوه هر آنچه تاکنون تولید شده است. این پارامتر حافظه مصرف میکند، زیرا کش کلید/مقدار (key/value cache) با آن رشد میکند. num_predict تعیین میکند که مدل در هر پاسخ حداکثر چند توکن بنویسد. این پارامتر به جای حافظه، زمان مصرف میکند و هیچ فضایی از پیش برای آن رزرو نمیشود. توکنهای تولیدشده در هر دو محاسبه میشوند، بنابراین یک پاسخ ممکن است توسط هر یک از این دو محدود و قطع شود.
چرا تنظیمات num_predict من نادیده گرفته میشود؟
زیرا مقداری که همراه با درخواست ارسال میشود، جایگزین مقدار ذخیرهشده در مدل میگردد. اگر PARAMETER num_predict 512 را در یک Modelfile قرار دهید و سپس آن مدل را از طریق یک رابط کاربری چت یا یک عامل برنامهنویسی فراخوانی کنید، کلاینت شیء options خاص خود را ارسال میکند که اولویت دارد. ollama show --parameters همچنان مقدار شما را نمایش میدهد، زیرا فقط مدل ذخیرهشده را میخواند و نمیتواند آنچه را که از طریق HTTP دریافت میشود، ببیند. یک درخواست با curl و با استفاده از "options": {"num_predict": 32} ارسال کنید و بررسی کنید که آیا eval_count برابر با 32 برمیگردد یا خیر؛ این کار تأیید میکند که سرور به درستی عمل میکند و مشکل در اپلیکیشن شماست.
چگونه بفهمم که خروجی من توسط num_predict قطع شده است؟
درخواست را با "stream": false ارسال کنید و done_reason را بخوانید. مقدار stop به این معنی است که مدل به تنهایی کار را تمام کرده است. مقدار length به این معنی است که فضای آن تمام شده است. سپس eval_count را با سقف تعیینشده خود مقایسه کنید: اگر دقیقاً برابر باشند، num_predict باعث توقف شده است، و اگر eval_count کوچکتر باشد، پنجره کانتکست زودتر پر شده است. هنگام استریم، هر دو فیلد در آخرین تکه (chunk) با "done": true ارسال میشوند که بسیاری از کتابخانههای کلاینت قبل از رسیدن به کد شما، آن را حذف میکنند.
مقدار پیشفرض num_predict چقدر است؟
آن را از نصب خودتان بخوانید، نه از مقالات. تا اوت 2026، مرجع Modelfile در Ollama مقدار پیشفرض را -1 اعلام کرده است، به این معنی که تولید متن محدود نیست. این ورودی در پایان سال 2024 پس از سالها مستندسازی 128 اصلاح شد. مقادیر منفی به عنوان نشانگر عمل میکنند نه شمارنده، و نسخههای قدیمیتر همان جدول، مقدار -2 را برای پر کردن کانتکست باقیمانده ذکر کرده بودند. مرجع پارامترهای Modelfile را برای نسخه خود بررسی کنید و سپس آن را با ollama show --parameters و یک درخواست curl تأیید نمایید.
آیا افزایش num_predict باعث میشود مدل پاسخهای طولانیتری بنویسد؟
خیر. این کار فقط سقف محدودیت را برمیدارد. اگر یک پاسخ با done_reason از stop تمام شود، یعنی مدل تصمیم گرفته است که کار تمام شده است و افزایش سقف تغییری ایجاد نمیکند. طول پاسخ در این حالت به نحوه پرامپتنویسی بستگی دارد: ساختار خاص، تعداد بخشها یا سطح جزئیات مورد نظر خود را درخواست کنید. num_predict را فقط زمانی افزایش دهید که done_reason با مقدار length برگردد.