Ollama: تقدير كمي للنموذج والتحسين

التقدير الكمي هو حمية النموذج — ضحِّ بقليل من الدقة، وفّر نصف المساحة، بفقدان جودة شبه معدوم.

💡 نصيحة: دليل اختيار مستوى التقدير الكمي — Q4_K_M يقدم أفضل قيمة (تقليص الحجم بنسبة 70%، فقدان جودة < 5%)، مناسب لسيناريوهات 8 جيجابايت VRAM السائدة؛ Q8_0 شبه خالي من الفقدان (احتفاظ بالجودة 99%+)، مناسب لسيناريوهات VRAM الوفير (12 جيجابايت+) الحساسة للدقة (توليد الأكواد، الاستنتاج الرياضي).

📋 المتطلبات المسبقة: يجب أن تتقن أولاً ما يلي

1. ما ستتعلمه


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: انخفاض الدقة

100%
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) خطوات الاستيراد

100%
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

100%
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 ميجابايت)، وفوائد التقدير الكمي ضئيلة. أبقِ على الافتراضي.

📖 ملخص


📝 تمارين

  1. أساسي (⭐): اسحب متغيري تقدير كمي لنفس النموذج (Q4_K_M وQ8_0)، واستخدم ollama list لمقارنة أحجام الملفات، وقارن جودة الإخراج بنفس السؤال.
  2. متوسط (⭐⭐): نزّل ملف GGUF من HuggingFace، واستورده إلى Ollama باستخدام Modelfile، واختبر أن الاستنتاج يعمل بشكل صحيح.
  3. متقدم (⭐⭐⭐): اكتب نص برمجي لتقييم التقدير الكمي يختبر درجات الجودة عبر مستويات تقدير كمي مختلفة في سيناريو خدمة العملاء (5 أسئلة معيارية)، ويخرج جدول توصيات التقدير الكمي.
Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%