SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-16

كيفية تحديد حد المخرجات num_predict في Ollama

تعرّف إلى أماكن ضبط num_predict الثلاثة وأولوية كل منها، وكيف تقرأ done_reason عند توقف Ollama بسبب الحد الأقصى للرموز.

ما وظيفة num_predict في Ollama

num_predict هو خيار Ollama الذي يحدّ عدد الرموز المميزة التي يمكن للنموذج توليدها في استجابة واحدة. يُحتسب عدد رموز المخرجات فقط، لذلك لا يُحتسب prompt ضمن هذا الحد. عندما يصل النموذج إلى الحد الأقصى، يتوقف التوليد عند موضعه الحالي، وقد يتوقف أحياناً في منتصف كلمة. عندها تعود الاستجابة مع ضبط done_reason على length.

هذه هي الوظيفة كاملة. تكمن الصعوبة في أن Ollama يتيح لك ضبط القيمة في ثلاثة مواضع منفصلة، وتكون الأولوية للإعداد الأقرب إلى الطلب. معظم التقارير التي تقول إن "num_predict لا يفعل شيئاً" سببها أن طبقة تتجاوز إعداداً آخر بصمت.

num_predict ليس num_ctx

يكثر الخلط بين هذين الخيارين أكثر من أي خيارين آخرين في Ollama، وهذا الخلط يستهلك وقتاً فعلياً في تصحيح الأخطاء.

num_ctx يحدد مقدار ما يستطيع النموذج قراءته. إنه حجم نافذة السياق التي تحتوي على المطالبة وكل ما أُنتج حتى الآن. رفع هذه القيمة يستهلك الذاكرة، لأن ذاكرة التخزين المؤقت للمفاتيح والقيم التي يحتفظ بها النموذج لهذه الرموز تكبر مع اتساع النافذة. تحديد قيمة num_ctx المناسبة لأجهزتك مهمة منفصلة، ولها حالات فشل خاصة بها.

num_predict يحدد مقدار ما سيقوم النموذج بكتابته. إنه قاعدة لإيقاف التوليد، وليس تخصيصاً للموارد. رفع هذه القيمة يستهلك وقتاً فعلياً بدلاً من RAM، ولا يُحجز أي مورد مسبقاً.

يلتقي الخياران في موضع واحد. تدخل الرموز المُولَّدة إلى نافذة السياق أثناء إنتاجها، لذلك قد تتوقف الإجابة أيضاً لأن النافذة امتلأت، لا لأن الحد الذي حددته قد بُلِغ. يعرض Ollama length في كلتا الحالتين، ولذلك فإن الرقم الذي يميّز بينهما هو eval_count، وسنتناوله بمزيد من التفصيل أدناه.

اضبطه مرة واحدة باستخدام Modelfile

يضمّن Modelfile القيمة في نموذج تنشئه. اكتب الملف:

FROM qwen3:8b
PARAMETER num_ctx 8192
PARAMETER num_predict 512

بعد ذلك أنشئ النموذج واقرأ ما أنشأته:

ollama create qwen3-capped -f Modelfile
ollama show --parameters qwen3-capped

يطبع ollama show --parameters سطراً واحداً لكل معلمة مخزّنة مع قيمتها. إذا لم يظهر num_predict في هذا الخرج، فلا يحتوي النموذج على حد مضمّن، ويُطبَّق الإعداد الافتراضي الخاص بـ Ollama. يطبع ollama show --modelfile qwen3-capped التعريف الكامل، وهذه أيضاً أسرع طريقة لنسخ المعلمات التي يأتي بها نموذج موجود مسبقاً.

هذه هي الطبقة المناسبة للقيمة التي تريد أن يرثها كل مستدعٍ. لكنها ليست الطبقة المناسبة إذا كنت تتوقع أن تكون القيمة نهائية، لأنها ليست كذلك.

عيّنه لكل طلب داخل كائن الخيارات

تقبل كل نقطة نهاية للتوليد كائن 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 نفسه بالمعنى نفسه. تنطبق القيمة هنا على هذه المكالمة وحدها ولا شيء سواها. هذه هي الطبقة التي تستخدمها أدواتك: واجهة أمامية للدردشة، أو نص برمجي، أو غلاف SDK، أو وكيل برمجي. وترسل جميعها كائن options، سواء أظهرت لك مربعاً لإدخاله أم لا.

اضبطه لجلسة واحدة باستخدام /set parameter

داخل ollama run، تضبط الجلسة التفاعلية الخيارات لبقية الجلسة:

>>> /set parameter num_predict 256
>>> /show parameters

يطبع /show parameters ما سترسله الجلسة مع رسالتك التالية، لذلك فهو أسرع طريقة للتأكد من تطبيق التغيير. تبقى القيمة حتى تكتب /bye. للاحتفاظ بها، يحفظ /save qwen3-capped الجلسة الحالية، بما في ذلك المعلمات، كنموذج جديد. لا يصل أي شيء تفعله هنا باستخدام /set إلى أي عميل آخر.

أي إعداد تكون له الأولوية، ولماذا يبدو إعدادك متجاهَلاً

ترتيب الأولوية قصير. تتغلب الخيارات المرسلة مع الطلب على كل ما عداها. يكون السطر PARAMETER num_predict في Modelfile الخاص بالنموذج هو القيمة الاحتياطية المستخدمة عندما لا يتضمن الطلب قيمة. إذا لم توجد أي قيمة منهما، يُطبَّق الإعداد الافتراضي المضمّن في Ollama.

لا يمثّل /set parameter قاعدة ثالثة. الجلسة التفاعلية هي عميل 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 في البيئة، وراقب journalctl -u ollama -f أثناء اتصال تطبيقك به.

القيم السالبة والأرقام التي يجب عدم نسخها

تقبل num_predict أيضاً القيم السالبة، وتُستخدم هذه القيم كإشارات خاصة لا كأعداد. تعني إحدى القيم السالبة «لا تضع حداً لهذا؛ واصل التوليد». وكانت قيمة أخرى تعني «املأ السياق المتبقي». اعتباراً من August 2026، يحدّد مرجع Ollama Modelfile القيمة الافتراضية على أنها -1، أي توليد غير محدود، كما أدرجت الإصدارات السابقة من الجدول نفسه أيضاً -2 لملء السياق.

اعتبر كل ذلك معتمداً على الإصدار، لأن هذه القيم تغيّرت. فقد وثّق المرجع القيمة الافتراضية على أنها 128 لفترة طويلة، قبل تصحيح الإدخال في نهاية 2024. لذلك لا تزال أدلة كثيرة تكرر الرقم القديم. راجع مرجع معلمات Modelfile للإصدار الذي تشغّله فعلياً، ثم أكّد السلوك باستخدام فحص eval_count أعلاه. القيمة التي تحققت منها على خادمك أفضل من قيمة قرأتها في أي مكان، بما في ذلك هذا المنشور.

لماذا يمثل طول المخرجات التكلفة الرئيسية على VPS يعمل بالمعالج فقط

تتم عملية التوليد في مرحلتين بسرعتين مختلفتين جداً. تُقيَّم رموز الطلب على دفعات، بعدد كبير في كل مرة. أما رموز المخرجات فتُنتَج واحداً تلو الآخر، ويحتاج كل رمز إلى تمرير كامل على أوزان النموذج. على VPS يعمل بالمعالج فقط، تحدد سرعة الذاكرة هذا التمرير؛ لذلك يكلف الرمز المُولَّد الواحد أكثر بكثير من رمز واحد في الطلب.

اطلب استجابة من دون بث، وستظهر الأرقام مباشرة:

"prompt_eval_count": 26,
"prompt_eval_duration": 107345000,
"eval_count": 237,
"eval_duration": 4289432000

المدد بوحدة النانوثانية. في هذه الكتلة، وهي استجابة نموذجية منشورة في وثائق Ollama API وليست قياساً لأي خادم محدد، استغرق تقييم 26 رمزاً في الطلب نحو 0.1 ثانية، بينما استغرق إنتاج 237 رمزاً نحو 4.3 ثوانٍ. معدل التوليد لديك هو eval_count مقسوماً على eval_duration بعد تحويل الناتج إلى ثوانٍ، ومن المفيد قياس عدد الرموز في الثانية على عتادك مرة واحدة قبل ضبط أي شيء آخر. يعتمد هذا المعدل على النموذج بقدر اعتماده على الجهاز، لذلك إذا كانت الاستجابات الطويلة هي التكلفة الفعلية، فإن استخدام نموذج مصمم لفك الترميز السريع، مثل Nemotron 3.5 Lightning على VPS، يعوض بعض الوقت الذي يحاول الحد المنخفض توفيره.

تكمل الحسابات الصورة. عند معدل 8 رموز في الثانية، تشغل استجابة مؤلفة من 2,000 رمز الجهاز لأكثر من أربع دقائق، ولا يعرف النموذج أنك أردت فقرة واحدة. كما تدخل بعض النماذج في حلقة تكرار، فتكرر عبارة حتى يوقفها شيء ما. من دون حد، يواصل هذا الطلب الواحد استهلاك نواة للمعالج حتى تمتلئ نافذة السياق. num_predict هو الإعداد الذي يحدد هذا الحد، وتزداد أهميته على Ollama VPS مستضاف ذاتياً صغير، حيث قد يشغل طلب طويل واحد الجهاز بأكمله.

المخرجات المقتطعة تعني عادةً بلوغ الحد الأقصى، لا تعطل النموذج

تبدو الأعراض كأنها فشل في النموذج. إجابة تتوقف في منتصف الجملة. أو JSON يتعذر تحليله لأن قوس الإغلاق لم يصل. يكون رد الفعل التلقائي هو إلقاء اللوم على النموذج أو على التكميم. اقرأ الاستجابة أولاً.

done_reason تعني أن الإجابة تجيب عن السؤال مباشرة. وتشير stop إلى أن النموذج أنهى التوليد من تلقاء نفسه، إما بإصدار رمز نهاية التسلسل، أو بمطابقة إحدى السلاسل النصية في الخيار stop. وتشير length إلى أن التوليد توقف لأنه نفد الحيز المتاح. عند ظهور length، قارن eval_count بالحد الأقصى لديك: إذا تطابق الرقمان تماماً، فهذا يعني أن num_predict أوقف التوليد، أما الرقم الأصغر فيعني أن نافذة السياق امتلأت أولاً.

عند استخدام البث، تصل هذه الحقول في المقطع النهائي، وهو المقطع الذي يحمل "done": true. تتخلص كثير من مكتبات العملاء من هذا المقطع، ولا تسلّم إلى شيفرتك سوى النص. لذلك يبدو الاقتطاع بلا تفسير داخل التطبيق، بينما يكون واضحاً عند استخدام curl. إذا كانت مكتبة ما تخفي هذه المعلومات، فأرسل طلباً واحداً مع curl لمعرفة ما أرسله الخادم فعلياً.

هناك نقطة أخرى توفر عليك إضاعة وقت طويل. لا يجعل رفع num_predict النموذج يكتب المزيد. بل يزيل سقفاً فقط. إذا انتهت إجابة عند 200 token مع done_reason من stop، فهذا يعني أن النموذج قرر أنه انتهى، ولن يغير الحد الأقصى الأكبر شيئاً. الإجابات القصيرة مع stop مشكلة في صياغة الطلب. والإجابات القصيرة مع length مشكلة في الحد الأقصى.

اختيار قيمة

  • بالنسبة إلى الدردشة التفاعلية، اتركها بلا حد واضغط Ctrl+C لإيقاف الرد الخارج عن السيطرة. فأنت تراقب الشاشة على أي حال.
  • بالنسبة إلى أي شيء يُنفَّذ عبر نص برمجي، حدّدها. يؤدي التوليد بلا حد داخل حلقة إلى استمرار مهمة دفعية كان يُفترض أن تستغرق عشر دقائق حتى صباح اليوم التالي.
  • بالنسبة إلى المخرجات المنظَّمة، اضبط الحد أعلى من أكبر مستند صالح تتوقعه، ثم اعتبر done_reason من length خطأً صريحاً، وأعد المحاولة بدلاً من تحليل المخرجات التي وصلت.
  • بالنسبة إلى وكيل برمجي، يجب أن تكون القيمة في إعدادات الوكيل نفسه، لأن الوكيل يرسل خياراته الخاصة مع كل طلب. يوضّح توجيه وكيل برمجي إلى Ollama مكان هذه الإعدادات.

يحسب الحد الرموز المميزة، لا الكلمات ولا المحارف، لذلك لا تقدّره بالتخمين. ولّد إجابة نموذجية واحدة بلا حد، واقرأ eval_count، ثم اضبط الحد أعلى منها بهامش مناسب. تختلف طريقة تقسيم الرموز المميزة بين عائلات النماذج، لذلك قد تكفي قيمة معينة لنموذج Llama، لكنها قد تقتطع الإجابة نفسها من نموذج Qwen 3 على VPS نفسه.

FAQ

ما الفرق بين num_ctx وnum_predict في Ollama؟

num_ctx هو حجم نافذة السياق، ولذلك يحدد مقدار ما يمكن للنموذج قراءته: المطالبة وكل ما أنتجه حتى الآن. ويستهلك الذاكرة، لأن ذاكرة التخزين المؤقت للمفاتيح والقيم تزداد معه. يحدد 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 أصغر، فقد امتلأت نافذة السياق أولاً. عند استخدام البث، يصل الحقلان في الجزء الأخير مع "done": true، لكن العديد من مكتبات العملاء تتخلص منه قبل أن يصل إلى شفرتك.

ما القيمة الافتراضية لـ num_predict؟

اقرأها من تثبيتك الخاص بدلاً من الاعتماد على مقال. حتى August 2026، يذكر مرجع Ollama Modelfile أن القيمة الافتراضية هي -1، أي إن التوليد غير مقيّد بحد، وقد صُححت هذه المعلومة في نهاية 2024 بعد سنوات من توثيق 128. القيم السالبة هي مؤشرات خاصة وليست أعداداً، كما كانت الإصدارات الأقدم من الجدول نفسه تسرد -2 لملء ما تبقى من السياق. راجع مرجع معلمات Modelfile للإصدار الذي تستخدمه، ثم أكّد ذلك باستخدام ollama show --parameters وطلب واحد curl.

هل يؤدي رفع num_predict إلى جعل النموذج يكتب إجابات أطول؟

لا. فهو يزيل سقفاً فقط. إذا انتهى الرد مع done_reason من stop، فهذا يعني أن النموذج قرر أنه اكتمل، ولن يغير رفع الحد شيئاً. يكون الطول في هذه الحالة مسألة تتعلق بصياغة الطلب: اطلب بنية محددة، أو عدداً للأقسام، أو مستوى تفصيل محدداً. ارفع num_predict فقط عندما تعود done_reason بالقيمة length.