Ollama: تقدير كمي للنموذج والتحسين
التقدير الكمي هو حمية النموذج — ضحِّ بقليل من الدقة، وفّر نصف المساحة، بفقدان جودة شبه معدوم.
💡 نصيحة: دليل اختيار مستوى التقدير الكمي — Q4_K_M يقدم أفضل قيمة (تقليص الحجم بنسبة 70%، فقدان جودة < 5%)، مناسب لسيناريوهات 8 جيجابايت VRAM السائدة؛ Q8_0 شبه خالي من الفقدان (احتفاظ بالجودة 99%+)، مناسب لسيناريوهات VRAM الوفير (12 جيجابايت+) الحساسة للدقة (توليد الأكواد، الاستنتاج الرياضي).
📋 المتطلبات المسبقة: يجب أن تتقن أولاً ما يلي
- الدرس 4: إدارة النماذج
- الدرس 9: إعدادات GPU وCUDA
1. ما ستتعلمه
- مبادئ التقدير الكمي: مفاضلات FP16 → Q8_0 → Q4_K_M → Q2_K
- التقدير الكمي المدمج في Ollama والتحديد اليدوي
- استيراد نماذج مقدرة كميًا مخصصة من ملفات GGUF
- طرق تقييم جودة النماذج المقدرة كميًا
- قرارات سيناريو VRAM: أي مستوى لـ 4 جيجابايت/8 جيجابايت/16 جيجابايت
2. قصة حقيقية من رائدة أعمال SaaS
ℹ️ معلومة: Ollama يستخدم تقدير كمي Q4_K_M افتراضيًا — هذا هو خيار "أفضل قيمة"، وليس خيار "أفضل جودة". إذا كان لديك VRAM وفير (16 جيجابايت+)، يمكنك تجربة Q8_0 لجودة شبه خالية من الفقدان؛ إذا كان VRAM محدودًا جدًا (4 جيجابايت)، Q3_K_M هو حد أدنى أفضل من Q2_K.
(1) المشكلة: 8 جيجابايت VRAM لا يمكنها تشغيل نموذج 8 مليارات
خادم Alice لديه 8 جيجابايت VRAM فقط، ونموذج 8 مليارات FP16 يتطلب 16 جيجابايت — لن يعمل. لكن بعد التقدير الكمي Q4_K_M، يحتاج فقط إلى 5 جيجابايت، وهو كافٍ. السؤال هو: كم جودة يضحي بها التقدير الكمي؟
(2) الحل: Q4_K_M يقدم أفضل قيمة
كشف الاختبار أن Q4_K_M لديه فقدان جودة أقل من 3% في سيناريوهات خدمة العملاء، مع تقليص الحجم بنسبة 70%:
BASH
# Compare model sizes
ollama show llama3.1:8b # Q4_K_M: ~5GB
ollama show llama3.1:8b-q8_0 # Q8_0: ~8GB
3. مبادئ التقدير الكمي بالتفصيل
⚠️ ملاحظة: التقدير الكمي يضحي بالدقة حتمًا — التقدير الكمي Q2_K لديه أصغر حجم لكن فقدان جودة ملحوظ (يحتفظ بـ 80-85%)، ويؤثر بشكل خاص على مهام الدقة مثل توليد الأكواد والاستنتاج الرياضي. يُوصى به فقط عندما يكون VRAM محدودًا جدًا (أقل من 4 جيجابايت)؛ وإلا، فـ Q4_K_M مفضل.
⚠️ تحذير: التقدير الكمي Q2_K لديه أصغر حجم (نموذج 8 مليارات فقط ~3 جيجابايت)، لكن فقدان جودة ملحوظ، خاصة لمهام الدقة مثل توليد الأكواد والاستنتاج الرياضي. يُوصى به فقط عندما يكون VRAM محدودًا جدًا (أقل من 4 جيجابايت)؛ وإلا، فـ Q4_K_M مفضل.
(1) من FP16 إلى Q2_K: انخفاض الدقة
flowchart LR
A[FP16<br/>16 بت<br/>16 جيجابايت] --> B[Q8_0<br/>8 بت<br/>8 جيجابايت]
B --> C[Q5_K_M<br/>5 بت<br/>5.7 جيجابايت]
C --> D[Q4_K_M<br/>4 بت<br/>5 جيجابايت]
D --> E[Q3_K_M<br/>3 بت<br/>3.8 جيجابايت]
E --> F[Q2_K<br/>2 بت<br/>3 جيجابايت]
(2) مقارنة مستويات التقدير الكمي
| مستوى التقدير الكمي | عرض البت | نسبة الضغط | حجم نموذج 8B | احتفاظ بالجودة | VRAM مناسب |
|---|---|---|---|---|---|
| FP16 | 16 بت | 1x | ~16 جيجابايت | 100% | 24 جيجابايت+ |
| Q8_0 | 8 بت | 2x | ~8 جيجابايت | 99%+ | 12 جيجابايت+ |
| Q5_K_M | 5 بت | 3.2x | ~5.7 جيجابايت | 98% | 8 جيجابايت+ |
| Q4_K_M | 4 بت | 3.5x | ~5 جيجابايت | 95-97% | 8 جيجابايت |
| Q3_K_M | 3 بت | 4.5x | ~3.8 جيجابايت | 90-93% | 4 جيجابايت+ |
| Q2_K | 2 بت | 6x | ~3 جيجابايت | 80-85% | 4 جيجابايت |
(3) اصطلاح تسمية K-quant
| اللاحقة | المعنى | الوصف |
|---|---|---|
| _K | K-quant | تقدير كمي بدقة مختلطة، الطبقات الحرجة بدقة أعلى |
| _S | صغير | أصغر حجم، أقل جودة |
| _M | متوسط | توازن بين الحجم والجودة (مُوصى به) |
| _L | كبير | جودة أعلى، حجم أكبر |
💡 نصيحة: اختيار اللاحقة
_M يقدم أفضل قيمة — Q4_K_M أعلى جودة بـ 3% من Q4_K_S، مع حجم أكبر بـ 5% فقط.
(1) ▶ مثال: اختيار التقدير الكمي الافتراضي في Ollama
BASH
# Default pull uses optimal quantization (usually Q4_K_M)
ollama pull llama3.1:8b
# Show quantization details
ollama show llama3.1:8b
# Look for: quantization: Q4_K_M
# Compare sizes across quantizations
ollama list | grep llama
# llama3.1:8b 4.9 GB (Q4_K_M)
الإخراج:
TEXT
NAME ID SIZE
llama3.2:latest a80... 2.0 GB
mistral:latest 61... 4.1 GB
4. التقدير الكمي المدمج في Ollama
(1) تحديد مستوى التقدير الكمي عند السحب
| الطريقة | الأمر | الوصف |
|---|---|---|
| اختيار تلقائي | ollama pull model_name |
يختار Ollama التقدير الكمي الأمثل |
| تحديد الوسم | ollama pull model_name:q4_K_M |
تحديد مستوى التقدير الكمي |
(2) وسوم التقدير الكمي المتاحة
| الوسم | التقدير الكمي | حالة الاستخدام |
|---|---|---|
| q4_K_M | دقة مختلطة 4 بت | التوصية العامة |
| q5_K_M | دقة مختلطة 5 بت | جودة أعلى |
| q8_0 | دقة موحدة 8 بت | شبه خالي من الفقدان |
| f16 | أصلي 16 بت | دقة كاملة |
(2) ▶ مثال: سحب متغيرات تقدير كمي مختلفة
BASH
# Pull specific quantization
ollama pull llama3.1:8b-q4_K_M # 4-bit, ~5GB
ollama pull llama3.1:8b-q5_K_M # 5-bit, ~5.7GB
ollama pull llama3.1:8b-q8_0 # 8-bit, ~8GB
# Not all models have all variants
# Check available tags on ollama.com/library/model-name
الإخراج:
TEXT
NAME ID SIZE
llama3.2:latest a80... 2.0 GB
mistral:latest 61... 4.1 GB
5. استيراد تقدير كمي مخصص من ملفات GGUF
(1) مصادر ملفات GGUF
| المصدر | الرابط | الوصف |
|---|---|---|
| HuggingFace | huggingface.co | ابحث عن .gguf |
| TheBloke | huggingface.co/TheBloke | مجموعة تقدير كمي GGUF |
| تقدير كمي ذاتي | llama.cpp convert | استخدم convert.py |
(2) خطوات الاستيراد
flowchart LR
A[تنزيل GGUF] --> B[إنشاء Modelfile<br/>FROM ./model.gguf]
B --> C[ollama create]
C --> D[ollama run]
(3) ▶ مثال: استيراد من HuggingFace GGUF
BASH
# Step 1: Download GGUF file from HuggingFace
wget "https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.2-GGUF/resolve/main/mistral-7b-instruct-v0.2.Q4_K_M.gguf"
# Step 2: Create Modelfile
cat > Modelfile <<EOF
FROM ./mistral-7b-instruct-v0.2.Q4_K_M.gguf
SYSTEM You are a helpful AI assistant.
PARAMETER temperature 0.7
PARAMETER num_ctx 4096
TEMPLATE """[INST] {{ if .System }}{{ .System }}{{ end }}
{{ .Prompt }} [/INST]
"""
EOF
# Step 3: Create model in Ollama
ollama create my-mistral -f Modelfile
# Step 4: Run
ollama run my-mistral "Explain quantum computing in simple terms"
الإخراج:
TEXT
I'm a helpful AI assistant running locally on your machine...
6. تقييم جودة التقدير الكمي
(1) مقارنة طرق التقييم
| الطريقة | الوصف | حالة الاستخدام |
|---|---|---|
| مقارنة ذاتية | مقارنة مخرجات تقديرات كمي مختلفة لنفس السؤال | فحص سريع |
| معيار قياس | معايير NLP القياسية (MMLU/HellaSwag) | تقييم مستوى التقدير الكمي |
| تقييم أعمال | اختبار دقة خاص بالمهمة | القرار النهائي |
(2) شجرة قرار VRAM
flowchart TD
A[VRAM المتاح؟] --> B{4 جيجابايت أو أقل؟}
B -->|نعم| C[نموذج 3B Q4_K_M<br/>أو 8B Q2_K]
B -->|لا| D{8 جيجابايت؟}
D -->|نعم| E[8B Q4_K_M ⭐ مُوصى به]
D -->|لا| F{12-16 جيجابايت؟}
F -->|نعم| G[8B Q8_0 أو 13B Q4_K_M]
F -->|لا| H{24 جيجابايت؟}
H -->|نعم| I[70B Q2_K أو 8B FP16]
H -->|لا| J{48+ جيجابايت متعدد GPU؟}
J -->|نعم| K[70B Q4_K_M ⭐ أفضل جودة]
(4) ▶ مثال: نص برمجي لمقارنة جودة التقدير الكمي
PYTHON
import ollama
import time
from statistics import mean
def compare_quantizations(model_base: str, quantizations: list[str],
test_prompt: str, runs: int = 3):
"""Compare output quality and speed across quantizations."""
results = {}
for quant in quantizations:
model_name = f"{model_base}:{quant}" if ":" not in model_base else model_base
try:
# Warm up
ollama.chat(model=model_name,
messages=[{"role": "user", "content": "warm up"}],
stream=False)
speeds = []
responses = []
for _ in range(runs):
start = time.time()
resp = ollama.chat(
model=model_name,
messages=[{"role": "user", "content": test_prompt}],
stream=False
)
elapsed = time.time() - start
speeds.append(len(resp["message"]["content"]) / elapsed)
responses.append(resp["message"]["content"])
results[quant] = {
"avg_speed": round(mean(speeds), 1),
"sample_response": responses[0][:200]
}
except Exception as e:
results[quant] = {"error": str(e)}
return results
# Compare (if you have multiple quantizations pulled)
# results = compare_quantizations(
# "llama3.1", ["q4_K_M", "q8_0"],
# "Explain machine learning in 3 sentences"
# )
# for quant, data in results.items():
# print(f"\n{quant}:")
# for k, v in data.items():
# print(f" {k}: {v}")
الإخراج:
TEXT
# Function defined successfully
(5) ▶ مثال: توصية تقدير كمي بناءً على السيناريو
PYTHON
def recommend_quantization(vram_gb: float, use_case: str) -> dict:
"""Recommend optimal quantization based on VRAM and use case."""
recommendations = {
"chat": {
"precision_priority": ("Q8_0", "Best quality, needs more VRAM"),
"balanced": ("Q4_K_M", "Best quality/size ratio"),
"size_priority": ("Q3_K_M", "Smallest usable quantization")
},
"code": {
"precision_priority": ("Q8_0", "Code needs high precision"),
"balanced": ("Q5_K_M", "Good precision for code tasks"),
"size_priority": ("Q4_K_M", "Minimal quality loss for code")
},
"classification": {
"precision_priority": ("Q5_K_M", "Overkill for classification"),
"balanced": ("Q4_K_M", "More than enough"),
"size_priority": ("Q2_K", "Classification is robust to quantization")
}
}
# Determine priority based on VRAM
if vram_gb >= 12:
priority = "precision_priority"
elif vram_gb >= 8:
priority = "balanced"
else:
priority = "size_priority"
quant, reason = recommendations.get(use_case, recommendations["chat"])[priority]
# Model size recommendation
if vram_gb >= 40:
model_size = "70B"
elif vram_gb >= 8:
model_size = "8B"
else:
model_size = "3B"
return {
"vram_gb": vram_gb,
"use_case": use_case,
"priority": priority,
"quantization": quant,
"model_size": model_size,
"reason": reason
}
# Example usage
for vram in [4, 8, 24]:
rec = recommend_quantization(vram, "chat")
print(f"VRAM {vram}GB: {rec['model_size']} {rec['quantization']} ({rec['reason']})")
الإخراج:
TEXT
# Function defined successfully
7. مثال شامل: تقييم التقدير الكمي وقرار النشر
PYTHON
# ============================================
# Comprehensive: Quantization decision engine
# Evaluates quality, speed, and VRAM tradeoffs
# ============================================
import ollama
import time
import json
from pathlib import Path
class QuantizationAdvisor:
def __init__(self, vram_gb: float, use_case: str = "chat"):
self.vram_gb = vram_gb
self.use_case = use_case
self.results = {}
def estimate_model_fit(self, params_b: float, quant: str) -> dict:
"""Estimate if a model+quantization fits in available VRAM."""
quant_bytes = {
"FP16": 2.0, "Q8_0": 1.0, "Q5_K_M": 0.625,
"Q4_K_M": 0.5, "Q3_K_M": 0.375, "Q2_K": 0.25
}
bytes_per_param = quant_bytes.get(quant, 0.5)
vram_needed = params_b * bytes_per_param * 1.2 # 20% overhead
fits = vram_needed <= self.vram_gb
return {
"params": f"{params_b}B",
"quantization": quant,
"vram_needed_gb": round(vram_needed, 1),
"vram_available_gb": self.vram_gb,
"fits": fits,
"headroom_gb": round(self.vram_gb - vram_needed, 1)
}
def generate_recommendations(self) -> list[dict]:
"""Generate all viable model+quantization combinations."""
models = [
(3.2, "llama3.2"), (8.0, "llama3.1:8b"), (70.0, "llama3.1:70b")
]
quants = ["Q4_K_M", "Q5_K_M", "Q8_0"]
viable = []
for params, name in models:
for quant in quants:
fit = self.estimate_model_fit(params, quant)
if fit["fits"]:
viable.append({
"model": name,
**fit
})
# Sort by params descending (prefer larger model)
viable.sort(key=lambda x: x["params"], reverse=True)
return viable
def best_recommendation(self) -> dict:
"""Return the single best recommendation."""
viable = self.generate_recommendations()
if not viable:
return {"error": "No model fits in available VRAM. Use CPU mode."}
# Prefer largest model, then highest quantization
best = viable[0]
return {
"recommended_model": best["model"],
"recommended_quantization": best["quantization"],
"vram_used": f"{best['vram_needed_gb']}GB",
"headroom": f"{best['headroom_gb']}GB",
"reason": f"Largest model that fits {self.vram_gb}GB VRAM with Q4_K_M+"
}
# Usage
if __name__ == "__main__":
advisor = QuantizationAdvisor(vram_gb=8, use_case="chat")
print("=== Quantization Recommendations (8GB VRAM) ===")
for rec in advisor.generate_recommendations():
print(f" {rec['model']} {rec['quantization']}: "
f"{rec['vram_needed_gb']}GB (headroom: {rec['headroom_gb']}GB)")
print(f"\nBest: {advisor.best_recommendation()}")
❓ أسئلة شائعة
س هل أختار Q4_K_M أم Q4_K_S؟
ج فضّل Q4_K_M. _M هو دقة متوسطة، جودة أعلى بـ 3-5% من _S (صغير)، مع حجم أكبر بـ 5% فقط. _M معترف به على نطاق واسع كأفضل قيمة.
س ماذا لو أصبح النموذج المقدر كميًا "أغبى"؟
ج ارتقِ إلى Q5_K_M أو Q8_0. إذا كان VRAM غير كافٍ، نموذج ذو معاملات أكبر بتقدير كمي منخفض (70B Q2_K) قد يتفوق على نموذج أصغر بتقدير كمي عالٍ (8B Q8_0).
س هل يمكن لـ Ollama التقدير الكمي تلقائيًا؟
ج النماذج المسحوبة بواسطة Ollama هي بالفعل إصدارات مقدرة كميًا مسبقًا (عادةً Q4_K_M). لا يمكنك تحديد مستوى تقدير كمي مخصص عند السحب — يجب الاستيراد من ملف GGUF.
س كيف أقدر كميًا ملف GGUF بنفسي؟
ج استخدم أدوات convert وquantize من llama.cpp. حوّل النموذج أولاً إلى GGUF F16، ثم استخدم quantize لتحديد المستوى. مناسب للمستخدمين المتقدمين؛ يجب على المبتدئين تنزيل إصدارات مقدرة كميًا مسبقًا.
س هل يؤثر مستوى التقدير الكمي على سرعة الاستنتاج؟
ج تقدير كمي أقل (Q2_K) يعني استنتاج أسرع (نقل بيانات أقل). لكن فروق سرعة Q4_K_M وQ8_0 على GPU عادةً < 10%. على وحدة المعالجة المركزية، Q4_K_M أسرع بشكل ملحوظ.
س هل نماذج التضمين تحتاج تقدير كمي؟
ج لا. نماذج التضمين صغيرة بالفعل (nomic-embed-text فقط 274 ميجابايت)، وفوائد التقدير الكمي ضئيلة. أبقِ على الافتراضي.
📖 ملخص
- التقدير الكمي يضغط النماذج من FP16 إلى عروض بت أقل؛ Q4_K_M يقلل الحجم بنسبة 70% مع فقدان جودة 3-5% فقط
- لواحق K-quant: _M (مُوصى به) > _L > _S؛ اختر _M لأفضل قيمة
- Ollama يستخدم Q4_K_M افتراضيًا؛ يمكن تحديد مستويات أخرى عبر الوسوم
- ملفات GGUF يمكن تنزيلها من HuggingFace واستيرادها باستخدام Modelfile
- 8 جيجابايت VRAM → 8B Q4_K_M (مُوصى به)، 24 جيجابايت → 70B Q4_K_M
- نموذج أكبر + تقدير كمي أقل > نموذج أصغر + تقدير كمي أعلى (في معظم السيناريوهات)
📝 تمارين
- أساسي (⭐): اسحب متغيري تقدير كمي لنفس النموذج (Q4_K_M وQ8_0)، واستخدم
ollama listلمقارنة أحجام الملفات، وقارن جودة الإخراج بنفس السؤال. - متوسط (⭐⭐): نزّل ملف GGUF من HuggingFace، واستورده إلى Ollama باستخدام Modelfile، واختبر أن الاستنتاج يعمل بشكل صحيح.
- متقدم (⭐⭐⭐): اكتب نص برمجي لتقييم التقدير الكمي يختبر درجات الجودة عبر مستويات تقدير كمي مختلفة في سيناريو خدمة العملاء (5 أسئلة معيارية)، ويخرج جدول توصيات التقدير الكمي.