الأداء والتحسين
ضبط الأداء
3 دقيقة للقراءة
حسّن بارامترات Ollama لتعظيم سرعة الاستدلال لعتادك وحالة استخدامك المحددة.
بارامترات الأداء الرئيسية
┌─────────────────────────────────────────────────────────────────┐
│ بارامترات أداء Ollama │
├─────────────────────────────────────────────────────────────────┤
│ │
│ البارامتر │ التأثير │ المقايضة │
│ ──────────────────│─────────────────────│─────────────────── │
│ num_ctx │ حجم نافذة السياق │ السرعة مقابل الذاكرة │
│ num_gpu │ طبقات GPU │ السرعة مقابل VRAM │
│ num_thread │ مسارات CPU │ سرعة استدلال CPU │
│ num_batch │ حجم الدفعة │ الإنتاجية مقابل التأخر│
│ num_predict │ أقصى توكنات │ طول الرد │
│ │
└─────────────────────────────────────────────────────────────────┘
تحسين طول السياق
طول السياق يؤثر بشكل كبير على استخدام الذاكرة والسرعة.
import ollama
# سياق افتراضي (2048 توكن) - الأسرع
response = ollama.generate(
model="llama3.2",
prompt="مرحباً!",
options={"num_ctx": 2048}
)
# سياق ممتد (8192 توكن) - يستخدم VRAM أكثر
response = ollama.generate(
model="llama3.2",
prompt="مستند طويل هنا...",
options={"num_ctx": 8192}
)
# أقصى سياق (131072 لبعض النماذج) - الأبطأ، أكثر ذاكرة
response = ollama.generate(
model="llama3.2",
prompt="مستند طويل جداً...",
options={"num_ctx": 131072}
)
صيغة حساب الذاكرة:
VRAM_مطلوب ≈ حجم_النموذج + (num_ctx × الحجم_المخفي × عدد_الطبقات × 2 بايت)
تكوين طبقات GPU
تحكم في عدد الطبقات التي تعمل على GPU مقابل CPU.
# تحقق من استخدام GPU الحالي
ollama ps
# شغّل بكل الطبقات على GPU (إذا VRAM تسمح)
OLLAMA_NUM_GPU=999 ollama run llama3.2
# شغّل بتحميل جزئي على GPU (قسّم بين GPU و CPU)
OLLAMA_NUM_GPU=20 ollama run llama3.2:70b
# فرض CPU فقط
OLLAMA_NUM_GPU=0 ollama run llama3.2
import ollama
def test_gpu_layers(model: str, layer_counts: list[int]):
"""اختبر سرعة الاستدلال بأعداد مختلفة من طبقات GPU."""
import time
results = []
prompt = "اكتب قصيدة قصيرة عن البرمجة."
for layers in layer_counts:
start = time.time()
response = ollama.generate(
model=model,
prompt=prompt,
options={"num_predict": 50}
)
elapsed = time.time() - start
tokens = response.get("eval_count", 50)
results.append({
"gpu_layers": layers,
"tokens_per_sec": tokens / elapsed
})
return results
ضبط حجم الدفعة
import ollama
import time
def benchmark_batch_sizes(model: str, batch_sizes: list[int]):
"""قارن الإنتاجية بأحجام دفعات مختلفة."""
prompt = "اشرح تعلم الآلة."
results = []
for batch in batch_sizes:
start = time.time()
response = ollama.generate(
model=model,
prompt=prompt,
options={
"num_batch": batch,
"num_predict": 100
}
)
elapsed = time.time() - start
results.append({
"batch_size": batch,
"time": elapsed,
"tokens_per_sec": response.get("eval_count", 100) / elapsed
})
return results
# اختبر أحجام دفعات مختلفة
results = benchmark_batch_sizes("llama3.2", [128, 256, 512, 1024])
for r in results:
print(f"دفعة {r['batch_size']}: {r['tokens_per_sec']:.1f} توكن/ثانية")
تكوين المسارات
# عيّن مسارات CPU (افتراضي: اكتشاف تلقائي)
OLLAMA_NUM_THREAD=8 ollama serve
# الأمثل: عادةً عدد_النوى_الفيزيائية (ليس hyperthreads)
# على CPU بـ 8 نوى مع hyperthreading، استخدم 8، ليس 16
import os
import multiprocessing
def get_optimal_threads():
"""احصل على عدد المسارات الموصى به للاستدلال."""
# النوى الفيزيائية عادةً تعمل أفضل من المنطقية
logical = multiprocessing.cpu_count()
# قدّر النوى الفيزيائية (تقريب)
# معظم CPUs المستهلك لديها 2 مسار لكل نواة
physical = logical // 2
return {
"logical_cores": logical,
"physical_cores": physical,
"recommended": physical
}
print(get_optimal_threads())
إبقاء النموذج محمّلاً
أبقِ النماذج محمّلة لتجنب تأخر إعادة التحميل.
import ollama
# أبقِ النموذج محمّلاً للأبد
response = ollama.generate(
model="llama3.2",
prompt="سؤال سريع",
keep_alive=-1 # لا تفرّغ أبداً
)
# فرّغ بعد 5 دقائق من عدم النشاط (افتراضي)
response = ollama.generate(
model="llama3.2",
prompt="سؤال سريع",
keep_alive="5m"
)
# فرّغ فوراً بعد الرد
response = ollama.generate(
model="llama3.2",
prompt="استعلام لمرة واحدة",
keep_alive=0 # فرّغ فوراً
)
# عيّن وقت البقاء الافتراضي
OLLAMA_KEEP_ALIVE=1h ollama serve
سكربت قياس أداء شامل
import ollama
import time
import statistics
def full_benchmark(model: str, iterations: int = 5):
"""شغّل قياس أداء شامل."""
prompts = [
"ما هو 2+2؟", # قصير
"اشرح الحوسبة الكمية بالتفصيل.", # متوسط
"اكتب قصة عن روبوت يتعلم الرسم.", # توليد طويل
]
results = {
"model": model,
"prompt_processing": [], # وقت لأول توكن
"generation_speed": [], # توكنات في الثانية
"total_time": []
}
for prompt in prompts:
for _ in range(iterations):
start = time.time()
response = ollama.generate(
model=model,
prompt=prompt,
options={"num_predict": 100}
)
elapsed = time.time() - start
# احسب المقاييس
eval_count = response.get("eval_count", 100)
prompt_eval_duration = response.get("prompt_eval_duration", 0) / 1e9
eval_duration = response.get("eval_duration", elapsed * 1e9) / 1e9
results["prompt_processing"].append(prompt_eval_duration)
results["generation_speed"].append(eval_count / eval_duration if eval_duration > 0 else 0)
results["total_time"].append(elapsed)
# اجمع النتائج
return {
"model": model,
"avg_prompt_processing_ms": statistics.mean(results["prompt_processing"]) * 1000,
"avg_tokens_per_sec": statistics.mean(results["generation_speed"]),
"avg_total_time_sec": statistics.mean(results["total_time"]),
"iterations": iterations * len(prompts)
}
# شغّل القياس
benchmark = full_benchmark("llama3.2")
print(f"النموذج: {benchmark['model']}")
print(f"معالجة الطلب: {benchmark['avg_prompt_processing_ms']:.1f}ms")
print(f"سرعة التوليد: {benchmark['avg_tokens_per_sec']:.1f} توكن/ثانية")
print(f"متوسط الوقت الكلي: {benchmark['avg_total_time_sec']:.2f}s")
ملخص متغيرات البيئة
# أنشئ تكوين Ollama محسّن
export OLLAMA_NUM_GPU=999 # استخدم كل طبقات GPU
export OLLAMA_NUM_THREAD=8 # طابق نوى CPU الفيزيائية
export OLLAMA_KEEP_ALIVE=1h # أبقِ النماذج محمّلة
export OLLAMA_MAX_LOADED_MODELS=2 # اسمح بنموذجين في الذاكرة
export OLLAMA_FLASH_ATTENTION=1 # فعّل flash attention (أسرع)
# ابدأ Ollama بالإعدادات المحسّنة
ollama serve
ملخص نصائح الأداء
| الهدف | الإعداد |
|---|---|
| أسرع استدلال | num_ctx أقل، كل طبقات GPU |
| سياق أطول | زد num_ctx، قد تحتاج طبقات GPU أقل |
| مستخدمين متعددين | زد num_batch، أبقِ النماذج محمّلة |
| توفير الذاكرة | قلل num_ctx، استخدم ضغط Q4 |
| ردود سريعة | عيّن حد num_predict |
ضبط الأداء تكراري. بعد ذلك، سنستكشف متى تنتقل من Ollama إلى vLLM لأحمال الإنتاج. :::