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

كيف تقيس عدد الرموز في الثانية لنموذج LLM محلي؟

تعرف إلى معدل الرموز الحقيقي قبل استئجار GPU: استخدم اختبار تزامن متدرجاً، وميّز بين رموز الإدخال والإخراج، ثم احسب نقطة التعادل مع API.

لماذا يحدد عدد الرموز في الثانية جدوى استخدام GPU

عدد الرموز في الثانية هو معدل إنتاج خادمك للنص الناتج. وهو الرقم الذي يحدد ما إذا كان استئجار GPU أقل تكلفة من الدفع لواجهة API مقابل كل رمز. تُحاسَب على خادم GPU بالساعة، سواء كان مشغولاً أم خاملاً. أما واجهة API المستضافة فتُحاسَب مقابل كل رمز. لذلك لا يتفوق GPU إلا إذا حافظت على معدل إنتاج مرتفع بما يكفي خلال معظم الساعات التي تدفع تكلفتها.

لذلك تحتاج إلى قياس فعلي، لا إلى رقم قرأته في مكان ما. تشرح هذه الصفحة الأرقام الأربعة التي تستحق التسجيل، ثم تعرض الأوامر التي تنتجها والحسابات التي تحولها إلى قرار.

لماذا لا يمثّل عدد الرموز في الثانية المنشور رقمك

نشرت DigitalOcean في يوليو 2026 أرقاماً لمعدل المعالجة عند تشغيل NVIDIA H200 واحد باستخدام llama3.3-70b-instruct بدقة FP8 (الفاصلة العائمة ذات 8 بت) ضمن vLLM. هذه الأرقام مفيدة، لكنها لا تمثّل أرقامك.

ChartPublished DigitalOcean H200 figures, llama3.3-70b-instruct FP8, July 2026
The data behind this chart
[
  {
    "config": "H200, one stream",
    "tok_s": "47"
  },
  {
    "config": "H100, saturated",
    "tok_s": "236"
  },
  {
    "config": "H200, saturated",
    "tok_s": "2,036"
  },
  {
    "config": "H200, saturated, in+out",
    "tok_s": "4,071.6"
  }
]

كل صف أعلاه منقول من تلك الصفحة، واثنان منهما يمثلان الحد الأدنى لنطاق تذكره الصفحة، لذا تعامل مع هذين الرقمين باعتبارهما حدّاً أدنى. لم نقس أي رقم في هذا المخطط بأنفسنا.

ابدأ بالصفين الأخيرين. الرقم الرئيسي هو 4,071.6 رمز/ثانية، بينما يبلغ معدل المخرجات فقط 2,036 رمز/ثانية. يحسب الرقم الرئيسي رموز الإدخال والإخراج معاً. استخدم ذلك الاختبار 1,024 رمز إدخال مقابل 1,024 رمز إخراج، ولذلك يمثّل الإخراج نصف الرقم الرئيسي تقريباً. هذا التقسيم مهم لأنك تُحاسب على المخرجات، ولأنها الجزء الأبطأ. تعالج مرحلة Prefill، أي قراءة prompt، جميع رموز الإدخال في تمريرة واحدة. أما مرحلة Decode، أي كتابة الإجابة، فتنتج رمزاً واحداً في كل مرة. لذلك يخلط رقم معدل المعالجة الإجمالي بين جزء منخفض التكلفة وجزء مرتفع التكلفة.

والآن الصف الأول. ينتج H200 نفسه عند خدمة طلب واحد في كل مرة 47 رمز/ثانية، ولذلك يزيد الرقم عند التشبع على أربعين ضعفاً مقارنة بالعتاد نفسه. يحدث هذا الفرق لأن خطوة Decode واحدة تترك GPU في انتظار الذاكرة معظم الوقت، بينما تملأ الطلبات المتزامنة وقت الخمول هذا. أما الصف الثاني، 236 رمز/ثانية، فيمثل H100 واحداً على النموذج نفسه، ويحدّه KV cache، أي ذاكرة التخزين المؤقت للمفاتيح والقيم التي تحتفظ بها المحادثة المقدّمة لكل طلب على البطاقة. تستوعب بطاقة بسعة 80 GB عدداً أقل من الطلبات المتزامنة لنموذج 70B، ولذلك تصل إلى التشبع عند معدل أقل.

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

الأرقام الأربعة المهمة

  • زمن الوصول إلى أول رمز، TTFT. هو التأخير بين إرسال الطلب ووصول أول رمز من المخرجات. ويتكوّن من زمن التهيئة وزمن الانتظار في الطابور. يلاحظ المستخدم هذا التأخير مباشرة.
  • عدد رموز المخرجات في الثانية لكل تدفق. يوضح سرعة كتابة إجابة واحدة بعد بدء إخراجها. عندما يتجاوز المعدل نحو 20 رمزاً في الثانية، يصبح بالفعل أسرع من سرعة قراءة معظم الأشخاص، ولذلك لا تحقق الزيادة الإضافية هنا فائدة كبيرة.
  • إجمالي إنتاجية المخرجات عند التشبع. هي مجموع معدلات جميع التدفقات المتزامنة عندما يكون الخادم محمّلاً بالكامل. هذا هو رقم السعة، وهو الرقم الذي يحدد تكلفة GPU.
  • p50 وp99 لزمن TTFT تحت التزامن. تمثل p50 الطلب الأوسط. وتمثل p99 القيمة التي تنخفض عنها أزمنة 99 طلباً من كل 100 طلب. يظهر تأثير الانتظار في الطابور أولاً في p99 دائماً.

يتحسن الرقمان الأولان عندما يكون الخادم قليل الانشغال. وتتحسن قيمة الرقم الثالث عندما يكون الخادم مشغولاً. ويتعارض كل منهما مع الآخر، ولذلك لا يصف رقم واحد خادم تقديم النماذج.

ثبّت طول الإدخال والإخراج قبل القياس

يعتمد معدل المعالجة على شكل حركة الشبكة. يُعدّ الطلب الذي يحتوي على 4,000 رمز وإجابة من 50 رمزاً عملاً يتركّز في مرحلة prefill. أما الطلب الذي يحتوي على 200 رمز وإجابة من 2,000 رمز، فيتركّز في مرحلة decode. يعرض الخادم نفسه عدداً مختلفاً جداً من الرموز في الثانية لهذين النوعين، لذلك اختر نسبة واحدة، واكتبها بجانب كل رقم تسجّله، ولا تقارن أبداً بين نسب مختلفة. يُعدّ استخدام 1,024 رمزاً للإدخال و1,024 رمزاً للإخراج قيمة افتراضية مناسبة، لأن عدة مورّدين ينشرون نتائج بهذه النسبة. إذا كنت تعرف طبيعة حركة شبكتك الفعلية، فاستخدمها.

ثبّت طول الإخراج أيضاً. النموذج الذي يصل إلى رمز التوقف بعد 60 رمزاً ينتج عملية تشغيل أقصر تبدو أسرع، لأن TTFT يشكّل حينها نسبة أكبر منها. يفرض الخيار --ignore-eos في عميل قياس الأداء الخاص بـvLLM أن يولّد كل طلب العدد المطلوب تماماً، وبذلك تظل عمليتا التشغيل قابلتين للمقارنة. يؤثر اختيار النموذج في هذه الأرقام أكثر من أي خيار آخر: يشرح تشغيل نموذج Qwen 3 على GPU واحد في VPS جانب الذاكرة من هذا الاختيار.

قِس تدفقاً واحداً أولاً

ابدأ بأبسط حالة. هذا اختبار للتحقق من سلامة الإعداد، وهو أيضاً حد أعلى للأداء. يعرض Ollama توقيتاته الخاصة.

ollama run llama3.1:8b --verbose "Write 200 words about disk scheduling."

السطر الذي يجب قراءته هو eval rate، وهو عدد رموز الإخراج في الثانية. أما prompt eval rate فهو معدل مرحلة prefill، وload duration هو الوقت المستغرق لتحميل النموذج إلى VRAM. في أول استدعاء بعد بدء التشغيل البارد تكون قيمة load duration كبيرة، لذلك تكون قيمة total duration مضللة. شغّل الأمر مرتين واقرأ النتيجة الثانية. يفرغ Ollama النموذج غير النشط بعد خمس دقائق افتراضياً، لذلك تعيدك فترة التوقف الطويلة بين التشغيلين إلى حالة التشغيل البارد.

تأتي الحقول نفسها من API، ويكون التعامل معها أسهل عند استخدام النصوص البرمجية.

curl -s http://127.0.0.1:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "prompt": "Write 200 words about disk scheduling.",
  "stream": false
}' | jq '{eval_count, eval_duration,
         tok_s: (.eval_count / (.eval_duration / 1000000000))}'

القيمة eval_duration بوحدة النانوثانية، لذلك يؤدي تقسيمها على 1,000,000,000 إلى الحصول على الثواني. وهذا التقسيم هو بالضبط ما توصي به وثائق API الخاصة بـOllama لحساب عدد الرموز في الثانية. إذا لم يكن الخادم قيد التشغيل بعد، يشرح استضافة LLM ذاتياً باستخدام Ollama على VPS خطوات التثبيت ووحدة systemd.

يتطلب TTFT طلباً يستخدم البث، ويمكن لـcurl قياس زمنه نيابةً عنك.

curl -s -o /dev/null -N \
  -w 'ttfb=%{time_starttransfer}s  total=%{time_total}s\n' \
  http://127.0.0.1:8000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"Qwen/Qwen3-8B",
       "messages":[{"role":"user","content":"Write 200 words about disk scheduling."}],
       "stream":true,"max_tokens":256}'

time_starttransfer هي اللحظة التي يصل فيها أول بايت من نص استجابة HTTP. في استجابة chat completion متدفقة، ينتمي ذلك البايت إلى أول server-sent event، ويكون إما أول رمز محتوى أو delta لا يحتوي إلا على الدور ويُرسل قبله مباشرة. لذلك تعامل مع القيمة على أنها TTFT مع هامش حدث واحد تقريباً. وهي دقيقة بما يكفي لمقارنة تشغيلين على الخادم نفسه.

تُظهر أرقام التدفق الواحد أداء الخادم أفضل من الواقع مرتين. يكون TTFT في أفضل حالاته، لأنه لا توجد طلبات في قائمة الانتظار قبلك. ويكون المعدل لكل تدفق في أفضل حالاته أيضاً، لأن البطاقة بأكملها تخدم طلباً واحداً. ولا يوضح أي من الرقمين مقدار الحمل الذي يستطيع الخادم تحمله.

كيف تُجري مسحاً للتزامن؟

يشغّل المسح حملاً ثابتاً عند مستويات متزايدة من التزامن، ويسجل النتائج عند كل مستوى. يوفّر vLLM العميل اللازم لذلك، وهو يستخدم OpenAI API، لذا يعمل أيضاً مع Ollama وأي برنامج آخر متوافق مع OpenAI.

vllm bench serve \
  --backend openai-chat \
  --base-url http://127.0.0.1:8000 \
  --endpoint /v1/chat/completions \
  --model Qwen/Qwen3-8B \
  --dataset-name random \
  --random-input-len 1024 \
  --random-output-len 1024 \
  --ignore-eos \
  --num-prompts 160 \
  --max-concurrency 16 \
  --percentile-metrics ttft,tpot,itl,e2el \
  --metric-percentiles 50,99

يحدّد --max-concurrency عدد الطلبات قيد التنفيذ، وهو المتغير الذي تمسحه. يمثّل --num-prompts إجمالي عدد الطلبات المرسلة، لذا اجعله قريباً من عشرة أضعاف مستوى التزامن للحصول على متوسط مستقر. يطبع الملخص Output token throughput (tok/s): وTotal token throughput (tok/s):، ثم Mean TTFT (ms): وMedian TTFT (ms): وP99 TTFT (ms): ضمن عنوان Time to First Token.

لا يعرض الناتج معدل كل تدفق، لكن يمكنك حسابه بقسمة واحدة. يمثّل Mean TPOT (ms): متوسط الزمن اللازم لكل رمز إخراج بعد الرمز الأول، لذا يعني 25 ms لكل رمز سرعة قدرها 40 رمزاً في الثانية لكل تدفق. ويعطي قسمة معدل إخراج الرموز على مستوى التزامن النتيجة نفسها.

بعد ذلك، كرّر العملية واحفظ نتيجة كل تشغيل.

for C in 1 4 16 32 64 128; do
  vllm bench serve \
    --backend openai-chat \
    --base-url http://127.0.0.1:8000 \
    --endpoint /v1/chat/completions \
    --model Qwen/Qwen3-8B \
    --dataset-name random \
    --random-input-len 1024 \
    --random-output-len 1024 \
    --ignore-eos \
    --num-prompts $(( C * 10 )) \
    --max-concurrency "$C" \
    --percentile-metrics ttft,tpot,itl,e2el \
    --metric-percentiles 50,99 \
    --save-result --result-filename "sweep-c$C.json"
done
قراءة ملفات JSON المحفوظة

ينشئ كل تشغيل ملفاً واحداً، لذا استخرج الحقول التي تحتاج إليها من جميع الملفات دفعة واحدة.

for f in sweep-c*.json; do
  jq -r --arg f "$f" \
    '[$f, .output_throughput, .total_token_throughput,
      .median_ttft_ms, .p99_ttft_ms] | @tsv' "$f"
done

يمثّل output_throughput عدد رموز الإخراج في الثانية. يضيف total_token_throughput رموز الإدخال أيضاً، لذا يكون قريباً من الضعف عند استخدام نسبة 1:1. يظهر p99_ttft_ms فقط لأن --metric-percentiles تضمّن 99؛ إذا طلبت مئيناً لم تطلبه، فسيطبع jq القيمة null.

ما الذي يوضحه اختبار زيادة التزامن فعلياً؟

ChartIllustrative sweep shape: 8B model, one 24 GB GPU, 1024 in / 1024 out
The data behind this chart
[
  {
    "label": "1 stream",
    "per_stream_tok_s": 92,
    "total_tok_s": 92,
    "ttft_p50_ms": 48,
    "ttft_p99_ms": 61
  },
  {
    "label": "4 streams",
    "per_stream_tok_s": 88,
    "total_tok_s": 352,
    "ttft_p50_ms": 71,
    "ttft_p99_ms": 96
  },
  {
    "label": "16 streams",
    "per_stream_tok_s": 71,
    "total_tok_s": 1136,
    "ttft_p50_ms": 152,
    "ttft_p99_ms": 244
  },
  {
    "label": "32 streams",
    "per_stream_tok_s": 54,
    "total_tok_s": 1728,
    "ttft_p50_ms": 287,
    "ttft_p99_ms": 498
  },
  {
    "label": "64 streams",
    "per_stream_tok_s": 34,
    "total_tok_s": 2176,
    "ttft_p50_ms": 611,
    "ttft_p99_ms": 1240
  },
  {
    "label": "128 streams",
    "per_stream_tok_s": 18,
    "total_tok_s": 2304,
    "ttft_p50_ms": 1490,
    "ttft_p99_ms": 3820
  }
]

توضح هذه الصفوف 6 شكل النتائج التي ينتجها الاختبار على خادم GPU صغير قابل للاستئجار، ضمن رتب حجم معقولة. وهي لا تمثل قياساً لخادمك، وليست رقماً صادراً عن مورّد. شغّل الحلقة أعلاه واستبدلها بنتائجك.

اقرأ الشكل، لأن الشكل هو ما يمكن تعميمه. عند تدفق واحد، ينتج الخادم بأكمله 92 رمزاً في الثانية، مع p99 TTFT يبلغ 61 مللي ثانية. عند 128 streams، يصل الإجمالي إلى 2304 رمزاً في الثانية، أي أعلى بـ25 مرة، بينما ينخفض معدل كل تدفق فردي إلى 18 رمزاً في الثانية، ويصل p99 TTFT إلى 3820 مللي ثانية. يرتفع معدل النقل الإجمالي لأن التجميع يحوّل فترات انتظار الذاكرة الخاملة إلى عمل مفيد. وينخفض معدل كل تدفق لأن القدرة الحوسبية نفسها أصبحت موزعة بين التدفقات.

الزيادة الأخيرة إلى الضعف هي المؤشر الحاسم. فالانتقال من 64 إلى 128 تدفقاً يضيف أقل من 6 بالمئة إلى الإجمالي، بينما يتضاعف p99 TTFT نحو 3 مرات. هذا يعني أن ذاكرة KV cache ممتلئة وأن الطلبات تنتظر في الطابور بدلاً من تنفيذها. نقطة التشغيل المفيدة تأتي قبل ذلك: عند 32 تدفقاً، لا يزال الخادم يعيد 1728 رمزاً في الثانية، أي 75 بالمئة من ذروته، بمعدل 54 رمزاً في الثانية لكل تدفق، وp99 TTFT يبلغ 498 مللي ثانية. أبلغ عن هذه النقطة باعتبارها سعة الخادم. أما ذروة المنحنى فهي رقم لا يمكنك تقديمه للمستخدمين.

لا يقيس Ollama وvLLM الشيء نفسه

شغّل هذا الاختبار على خادم Ollama بإعداداته الافتراضية، ولن يتغير الإجمالي إلا قليلاً. القيمة الافتراضية لـ OLLAMA_NUM_PARALLEL هي 1، لذلك يُنفَّذ طلب واحد بينما تنتظر الطلبات الأخرى، ويؤدي الانتظار في قائمة الانتظار إلى ارتفاع p99 TTFT، في حين يظل إجمالي المخرجات ثابتاً تقريباً. ارفع هذه القيمة قبل قياس أي شيء.

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_NUM_PARALLEL=8"

أعد التشغيل باستخدام sudo systemctl restart ollama، ثم تأكد من أن النموذج لا يزال يتسع في الذاكرة. تحصل كل فتحة توازٍ على حصتها الخاصة من نافذة السياق، ولذلك توضح وثائق Ollama أن سياقاً بحجم 2K مع 4 طلبات متوازية يخصص 8K. إذا رفعت عدد الفتحات كثيراً، يخرج النموذج من VRAM. افحص ollama ps: إذا كان عمود PROCESSOR يعرض قيمة مثل 48%/52% CPU/GPU، فهذا يعني أن جزءاً من النموذج موجود على CPU، وعندها سينخفض معدل النقل كلما أضفت التوازي بدلاً من أن يرتفع. بعد استنفاد فتحات التوازي، تُوضَع الطلبات في قائمة انتظار تصل إلى OLLAMA_MAX_QUEUE، وتكون القيمة الافتراضية 512، ثم يعيد الخادم الاستجابة 503.

يستخدم vLLM التجميع المستمر، لذلك يضيف الطلبات الجديدة إلى التجميع قيد التشغيل كلما أصبحت الفتحات متاحة، ويستمر منحناه في الارتفاع حتى تنفد ذاكرة التخزين المؤقت KV. يركّز Ollama على نموذج واحد وجهاز واحد وتكلفة إعداد منخفضة. لذلك يعطي المحركان إجابات مختلفة للاختبار نفسه، وهذا هو الموضوع الحقيقي في مقارنة Ollama وvLLM كمحركي تقديم. سجّل المحرك والإصدار اللذين أنتجا كل قيمة.

خمس طرق لقياس الشيء الخطأ

  • العميل بعيد. يؤدي إجراء الاختبار المعياري من حاسوبك المحمول عبر الإنترنت إلى إضافة زمن رحلة الذهاب والإياب الخاص باتصالك إلى كل قيمة TTFT، لذلك فأنت تقيس اتصالك المنزلي. شغّل العميل في المنطقة نفسها التي يوجد فيها الخادم.
  • كان النموذج في حالة باردة. يتحمل الطلب الأول تكلفة تحميل الأوزان، وقد يتحمل أيضاً تكلفة التقاط الرسم البياني في vLLM. أرسل دفعة تهيئة مسبقة وتجاهل النتيجة.
  • أجاب التخزين المؤقت للبادئة نيابةً عنك. يفعّل vLLM التخزين المؤقت التلقائي للبادئة افتراضياً، لذلك فإن إرسال المطالبة نفسها مراراً يقيس ذاكرة التخزين المؤقت بدلاً من prefill، وينخفض TTFT إلى جزء من قيمته الفعلية. يتجنب --dataset-name random ذلك لأن كل مطالبة تختلف عن الأخرى. وللتأكد، ابدأ الخادم باستخدام --no-enable-prefix-caching.
  • كانت المخرجات قصيرة. مع إجابات من 32 رمزاً، يهيمن TTFT على كل طلب، ويصف عدد الرموز في الثانية عملية prefill فعلياً. استخدم --ignore-eos مع طول مخرجات واقعي.
  • أبلغت عن تزامن مقداره 1. هذا هو الرقم الأكثر ملاءمة في الجدول، ولا علاقة له بالتكلفة.

حوِّل الرقم الذي قسته إلى قرار

استخدم معدل إنتاج المخرجات المشبع من اختبار sweep، وليس معدل التدفق لمسار واحد، ثم قارنه بسعر كل token. نقطة التعادل هي عملية قسمة واحدة:

break_even_tok_s = (price_per_hour / price_per_million_output_tokens) * 1000000 / 3600

طبّق ذلك على أسعار DigitalOcean في July 2026. كان سعر نقطة نهاية الاستدلال المخصصة H200 هو $4.47 في الساعة، بينما كان السعر المكافئ للخدمة serverless هو $0.65 لكل مليون token. لذلك، 4.47 مقسومة على 0.65 تساوي 6.88 مليون token في الساعة، وبقسمة ذلك على 3,600 ثانية نحصل على نحو 1,910 token مخرجات في الثانية. الأسعار من DigitalOcean. أما القسمة فمن حسابنا.

الكلمة الحاسمة هنا هي المستمر. إن بلوغ 1,910 token في الثانية عند التشبع لمدة ساعتين يومياً لا يعني تحقيق 1,910 token في الثانية بشكل مستمر، لأنك تدفع أيضاً تكلفة الساعات الاثنتين والعشرين الأخرى. وتصل نقطة التعادل التي تحسبها DigitalOcean نفسها لوحدة GPU Droplet الأرخص، بسعر $3.44 في الساعة، إلى استخدام متوسط مستمر قدره 72.2 بالمئة. وتحت هذه النسبة، يكون السعر لكل token أفضل. ساعات GPU الخاملة، لا بطء token، هي ما يؤدي عادةً إلى فشل الاستضافة الذاتية.

لذلك، يعتمد قرارك على مدخلين. يمنحك اختبار sweep الحد الأقصى. ويحدد نمط حركة المرور لديك الجزء الذي تحصل عليه فعلياً من هذا الحد. اضرب الرقمين، ثم استخدم الناتج في مقارنة GPU VPS مع نقطة تعادل API حسب سعر كل token، واستخلص الإجابة لحجم الاستخدام لديك.

FAQ

ما المعدل الجيد للتوكنات في الثانية لنموذج LLM مستضاف ذاتياً؟

هناك إجابتان، لأن هذا المقياس يؤدي وظيفتين. إذا كان شخص واحد يقرأ المخرجات، فإن أي معدل يتجاوز تقريباً 20 توكناً من المخرجات في الثانية لكل تدفق يكون أسرع من سرعة القراءة، ولذلك لا تفيد الزيادة. أما من ناحية التكلفة، فالرقم المهم هو إجمالي معدل المخرجات عند التشبع، ويُعد جيداً إذا تجاوز نقطة التعادل لديك. عند سعر $0.65 لكل مليون توكن، وعلى خادم تكلفته $4.47 في الساعة، تبلغ هذه العتبة نحو 1,910 توكناً من المخرجات في الثانية بشكل مستمر وفق أسعار July 2026. لا يصل إليها تدفق واحد على نموذج كبير، ولهذا نستخدم المعالجة الدفعية.

لماذا يبقى معدل Ollama ثابتاً عند إضافة طلبات متزامنة؟

تكون قيمة OLLAMA_NUM_PARALLEL الافتراضية هي 1، لذلك يشغّل الخادم طلباً واحداً في كل مرة لكل نموذج، ويضع بقية الطلبات في قائمة انتظار، حتى حد OLLAMA_MAX_QUEUE (وقيمته الافتراضية 512) قبل إرجاع الخطأ 503. يبقى إجمالي المخرجات ثابتاً، بينما يرتفع p99 TTFT. وهذا يدل على وجود قائمة انتظار، لا على انشغال GPU. اضبط المتغير في ملف drop-in خاص بـsystemd وأعد التشغيل، ثم تحقّق من ollama ps، لأن كل خانة متوازية تضاعف حجم السياق المخصّص، وقد تدفع جزءاً من النموذج إلى CPU.

هل ينبغي أن أقيس زمن الوصول إلى أول توكن أم معدل التوكنات في الثانية؟

قِس كليهما، لأنهما يتحركان في اتجاهين متعاكسين عند زيادة الحمل. يعكس TTFT ما يشعر به المستخدم، بينما يعكس معدل المخرجات عند التشبع ما يظهر في فاتورتك. سجّل p50 وp99 لـTTFT عند كل مستوى من مستويات التزامن، ثم اختر أعلى مستوى يظل عنده p99 TTFT مقبولاً لك. أبلغ عن معدل النقل عند تلك النقطة باعتباره سعة النظام، وليس عن الحد الأقصى في أعلى المنحنى.

هل يعني ارتفاع معدل التوكنات في الثانية دائماً انخفاض التكلفة لكل توكن؟

لا. تُحسب التكلفة لكل توكن بقسمة السعر بالساعة على عدد التوكنات التي أنتجها الخادم فعلياً خلال تلك الساعة. لذلك قد تكون تكلفة التوكن مرتفعة حتى مع خادم سريع إذا ظل خاملاً معظم اليوم. الاستخدام هو العامل الحاسم، وليس السرعة القصوى. انتبه أيضاً إلى الوحدات: إجمالي معدل التوكنات المذكور قد يشمل توكنات الإدخال، ولذلك يكون قريباً من ضعف معدل المخرجات الذي تُحاسب عليه عند نسبة إدخال إلى إخراج تبلغ 1:1.

#benchmarking#tokens-per-second#vllm#ollama#gpu-vps