بازگشت به وبلاگ

کوانتیزاسیون GGUF: کدام سطح را به‌کار ببرید؟

۲۲ شهریور ۱۴۰۵

به‌صورت پیش‌فرض Q4_K_M بردارید؛ وقتی VRAM اضافه دارید و آخرین چند درصد کیفیت را می‌خواهید Q6_K یا Q8_0. کوانتیزاسیون GGUF وزن‌های مدل را از 16 بیت به کمتر می‌فشارد — Q4_K_M حدود 4.85 بیت به ازای هر وزن ذخیره می‌کند، پس یک مدل 7B از ~14 گیگابایت به ~4.1 گیگابایت می‌رسد و perplexity آن معمولاً کمتر از 1٪ بدتر از نسخه اصلی است. سؤال «کدام gguf quantization را استفاده کنم» جوابی خسته‌کننده و پایدار دارد که بیشتر نمایش‌های آنلاین مبهمش می‌کنند. در ادامه: کوانتیزاسیون واقعاً با وزن‌ها چه می‌کند، هر سطح چقدر هزینه کیفیت دارد، چطور ریاضی حجم را خودتان بزنید، و یک دستور برای اندازه‌گیری آسیب روی سخت‌افزار خودتان به‌جای اعتماد به بنچمارک یک غریبه.

کوانتیزاسیون GGUF واقعاً چه می‌کند؟

یک مدل در ممیز شناور 16 بیتی آموزش دیده (FP16 یا BF16): هر یک از میلیاردها وزنش یک عدد دوبایتی است. کوانتیزاسیون هر وزن را به بیت‌های کمتر می‌فشارد. راه ساده‌لوحانه — گرد کردن هر وزن به یک عدد صحیح 4 بیتی — مقادیر کوچک ولی مهم را نابود می‌کند؛ برای همین GGUF دو ترفند دارد:

  1. Block scaling. وزن‌ها به بلوک‌هایی (معمولاً 32تایی) گروه می‌شوند و هر بلوک ضریب مقیاس خودش را می‌گیرد. مقادیر 4 بیتی آفست‌هایی داخل همان بلوک‌اند، پس بازه گسترده‌ای از بزرگی‌ها زنده می‌مانند.
  2. k-quant های حساس به اهمیت. حرف «K» در Q4_K_M یعنی ابربلوک‌هایی از مقیاس‌ها، به‌علاوه برخورد متفاوت با لایه‌های attention و feed-forward، چون تحمل فشردگی‌شان برابر نیست.

خانواده «I» (IQ4_XS و رفقایش) جلوتر می‌رود و codebook هایی را به عاریت می‌گیرد که مال فشرده‌سازی تصویرند. همان ایده، رمزگذاری فاخرتر: بیت کمتر به ازای هر وزن با کیفیت مشابه، به بهانه استنتاج کمی کندتر روی بعضی backend ها.

یک شفاف‌سازی که بیشتر گیجی را پیشگیری می‌کند: کوانتیزاسیون فقط وزن‌های ذخیره‌شده را عوض می‌کند. معماری، tokenizer و هندلینگ context دست‌نخورده می‌مانند. فایل Q4 و فایل Q8 از یک مدل، همان یک مدل‌اند با پالت‌های متفاوت.

Q4 در مقابل Q8: آیا کوانتیزاسیون بالاتر بهتر است؟

از نظر فنی بله؛ از نظر ادراکی نه. با مرجع‌قراردادن اجراهای perplexity خودِ llama.cpp روی مدل‌های Llama: Q8_0 در فاصله ~0.02٪ از FP16 می‌ماند — برای هر مقصود عملی، بی‌اتلاف. Q6_K تقریباً غیرقابل‌تشخیص است. Q4_K_M حدود 1–2٪ perplexity می‌گیرد، Q4_0 کمی بیشتر، و Q2_K جایی است که روی مدل‌های کوچک جواب‌های منسجم شروع به فروپاشی می‌کنند.

دو قاعده که از اعداد درمی‌آید:

  • بزرگی مدل، تنفس کوانتیزاسیون می‌خرد. مدل 70B از Q2/Q3 خیلی بهتر از 7B جان به در می‌برد، چون مدل‌های بزرگ‌تر افزونگی بیشتری دارند. کوانتیزه کردن 7B به Q2 قطع عضو است؛ 70B به Q3 خیاطی.
  • کف کیفیت با task جابه‌جا می‌شود. چت Q4 را تاب می‌آورد. تولید دقیق کد، ریاضی، و RAG روی اسناد دقیق‌تر زودتر نویز کوانتیزاسیون را لو می‌دهند. اگر مدل Q4 مدام کدِ ظاهراً درستِ عملاً غلط می‌نویسد، قبل از مقصر دانستن مدل، همان را در Q6_K تست کنید.
سطحبیت/وزنحجم نسبت به FP16افت کیفیتکِی استفاده کنید
Q2_K~3.4~21٪روی زیر 13B سنگینوقتی هیچ چیز دیگری جا نمی‌شود، فقط مدل‌های بزرگ
Q3_K_M~3.9~25٪محسوسVRAM تنگ، مدل‌های ≥14B
Q4_K_S~4.6~29٪کمQ4_K_M جا نمی‌شود و به آن نزدیکید
Q4_K_M~4.85~30٪~1٪ perplexityپیش‌فرض. بهترین مبادله کیفیت/حجم
Q5_K_M~5.7~35٪~0.5٪VRAM آزاد، task های حساس به کیفیت
Q6_K~6.6~41٪تقریباً هیچکد/ریاضی، هنوز راحت جا می‌شود
Q8_0~8.5~53٪عملاً هیچاجرای مرجع، پایه fine-tune
IQ4_XS~4.3~27٪≈Q4_K_MQ4_K_M کمی بزرگ است و backend از i-quant پشتیبانی می‌کند

هر سطح چقدر VRAM می‌خواهد؟

ریاضی حجم را خودتان بزنید به‌جای حفظ کردن جدول — یک خط است:

size_GB ≈ (bits_per_weight × params) / 8
# 8B model @ Q4_K_M: 4.85 × 8 / 8 ≈ 4.9 GB
# 8B model @ Q8_0:   8.50 × 8 / 8 ≈ 8.5 GB

بعد اجزایی را اضافه کنید که فرمول جا می‌گذارد: KV cache (با طول context رشد می‌کند — از چند صد مگابایت تا چند گیگابایت)، activation ها و بافرهای محاسباتی. حاشیه عملی: مدل «4.9 گیگابایتی» روی context چهار هزار، کارت 6 گیگابایتی می‌خواهد، و برای اینکه در 16k هم بماند flash-attention و کوانتیزه کردن KV cache. وزن‌ها تیتر خبرند، نه کل صورت‌حساب.

از کدام کوانتیزاسیون GGUF استفاده کنید؟

ترتیب تصمیم، بدون استثنایی که ارزش حفظ کردن داشته باشد:

  1. اول بودجه context + KV خود را حساب کنید، بعد وزن‌ها را. context ای که جا نمی‌شود از کیفیتی که نمی‌توانید اندازه بگیرید بدتر است.
  2. پیش‌فرض Q4_K_M. به‌دلیلی پیش‌فرض جامعه است — حدود 1٪ perplexity برای 70٪ حجم. هر registry ای، از جمله Ollama، آن را به‌عنوان پایه عرضه می‌کند.
  3. وقتی task نویز را جریمه می‌کند به Q6_K بروید: کد، ریاضی، استخراج، هر چیزی که بی‌نوازش به یک pipeline می‌دهید.
  4. Q8_0 فقط برای مرجع — تست A/B، اندازه‌گیری آسیب کوانتیزاسیون، یا پایه fine-tune. به‌عنوان ماشین روزمره بیشتر گرمای اضافه‌ای است که روی سنسورهای VRAM تان می‌گذارید.
  5. زیر Q4 فقط در مضیحه، و فقط روی مدل‌های بزرگ. قبل از اعتماد، با یک prompt مشکل‌سنجیده تستش کنید.

اگر بین فایل های Hugging Face دارید انتخاب می‌کنید، تا وقتی uploader فقط نسخه شارد نمی‌دهد، یک Q4_K_M.gguf یک‌تکه را به split های چندقطعه‌ای ترجیح دهید — قطعات متحرک کمتر. و اگر کجا اجرایش کنید را انتخاب می‌کنید، بحث موتور جداست: برای آن محور llama.cpp یا Ollama: در 2026 کدام را اجرا کنید؟ را ببینید.

چطور خودتان آسیب کوانتیزاسیون را اندازه بگیرید؟

بنچمارک ها فرق می‌کنند؛ prompt شما ثابت است. llama.cpp را یک بار بسازید، دو سطح از یک مدل را دانلود کنید، و هم perplexity (کمتر بهتر) و هم tokens/second را اندازه بگیرید:

git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
cmake -B build && cmake --build build --config Release -j

huggingface-cli download bartowski/Meta-Llama-3.1-8B-Instruct-GGUF 
  Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf Meta-Llama-3.1-8B-Instruct-Q8_0.gguf 
  --local-dir models

# perplexity on a wiki-text chunk (lower = closer to the original model)
./build/bin/llama-perplexity -m models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -ngl 99
./build/bin/llama-perplexity -m models/Meta-Llama-3.1-8B-Instruct-Q8_0.gguf  -ngl 99

# and speed on the same hardware
./build/bin/llama-bench -m models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -ngl 99

عدد Q4_K_M چند صدم بدتر از Q8_0 خواهد بود و فایل ~40٪ کوچک‌تر. اگر task بعدی‌تان تفاوت را تشخیص نمی‌دهد — و برای بیشترشان نمی‌دهد — جوابتان را بدون خواندن leaderboard هیچ‌کس دارید.

آیا کوانتیزاسیون به ادعای privacy و «فقط محلی» آسیب می‌زند؟

نه — حساب و کتاب روی وزن‌هاست، کاملاً آفلاین، و فایل کوانتیزه صرفاً ظرف کوچک‌تری از همان پارامترهاست. اجرای محلی یک Q4_K_M دقیقاً همان‌قدر نشت می‌کند (یا نمی‌کند) که اجرای محلی مدل full-precision: هیچ چیز از ماشین بیرون نمی‌رود. متغیر مرتبط با privacy این است که استنتاج کجا اجرا می‌شود، نه پهنای بیت. تذکرهای همیشگی درباره منشأ مدل برای هر سطح quant یکسان‌اند: fine-tune «uncensored» دزدیده‌شده در Q8 از همان وزن‌ها در Q4 امن‌تر نیست. برای سمت فرمت فایل، اجرای مدل‌های GGUF به‌صورت محلی: Ollama، llama.cpp و vLLM را ببینید.

کدام سطح را بردارید؟

Q4_K_M، و دیگر درباره‌اش forum نخوانید. برای کار دقیق‌طلب اگر VRAM اجازه داد به Q6_K ارتقا دهید، یک Q8_0 برای مقایسه A/B نگه دارید، و هر چیز زیر Q4 را جیره اضطراری مخصوص مدل‌های بزرگ بدانید. تنها اشتباهی که ارزش پیشگیری دارد متقارن است: نگران Q4-در-مقابل-Q5 بودن در حالی که طول context را نادیده می‌گیرید — همان که بیشتر از هر quant ای تا حالا ست‌آپ‌های محلی را خراب کرده.

FAQ

Q4 و Q5 و Q8 در GGUF یعنی چه؟

بیت به ازای هر وزن: Q4_K_M حدود 4.8 BPW، Q5 حدود 5.5 و Q8 حدود 8.5. پایین‌تر یعنی کوچک‌تر و سریع‌تر، با هزینه کیفیت جزئی.

برای یک مدل 7B از کدام کوانتیزاسیون استفاده کنم؟

Q4_K_M پیش‌فرض است — حدود 30 درصد کوچک‌تر از Q8 با کیفیتی که بیشتر کاربران نمی‌توانند اندازه بگیرند. وقتی RAM آزاد است و سقف را می‌خواهید Q8 بردارید.

آیا مدل‌های کوانتیزه دقت از دست می‌دهند؟

کمی، و نابرابر: استدلال زودتر از روانی خراب می‌شود. زیر حدود Q4 پرتگاه واقعی است؛ بالای Q5_K_M عمدتاً نویز است.

— mrsaynothing

— mrsaynothing

یادداشت‌های میدانی درباره AI، لینوکس و self-hosting.

این نوشته را در dev.to بحث کنید dev.to ↗

آموزش بعدی با ایمیل

هر نوشته یک ایمیل. درستش کن، برو سراغ بعدی.

self-hosted · بدون واسطه‌های ثالث · لغو اشتراک با یک کلیک

این چیست؟

Git cherry-pick: چند commit، شاخه‌های مختلف و حل تعارض

این نوشته‌ها را می‌پسندید؟ این همان کاری است که برای زندگی از آن درمی‌آورم. استخدامم کنید