Ollama: השוואת ביצועים בין q4_K_M, q8_0 ו-fp16
איך לבחור קוונטיזציה נכונה ב-Ollama? נסביר את ההבדלים בצריכת ה-RAM ובדיוק בין q4_K_M, q8_0 ל-fp16. מנעו טעויות בזיכרון ובחרו את המודל האופטימלי לשרת שלכם בקלות.
המשמעות של קוונטיזציה ב-Ollama
קוונטיזציה ב-Ollama מאחסנת כל משקל במודל באמצעות פחות ביטים מאשר הקובץ שבו הוא אומן במקור. תג שמסתיים ב-q4_K_M שומר על כארבעה ביטים לכל משקל, בעוד ש-fp16 שומר על שישה-עשר, כך שההורדה תופסת בערך רבע מהנפח והמכונה קוראת רבע מכמות הבייטים כדי לייצר כל טוקן. המשקלים מעוגלים לרשת גסה יותר, הם אינם נמחקים, ובארבעה ביטים רוב המודלים עונים בצורה קרובה מאוד לביצועים שלהם בדיוק מלא.
זהו כל הטרייד-אוף: טביעת רגל קטנה משמעותית בזיכרון ויותר טוקנים לשנייה, במחיר של ירידה קלה בדיוק. להלן הדרך לחזות את שני הצדדים עבור מודל ספציפי על שרת ספציפי, לפני שתבזבזו עשרים דקות על הורדת קובץ שלא ייכנס בזיכרון.
אם Ollama עדיין לא רץ, התחילו ב-התקנת Ollama על שרת VPS. דף זה מניח ש-ollama ls כבר עובד.
כיצד לקרוא תגית קוונטיזציה של Ollama כמו q4_K_M
מודלים מקומיים מופצים כקבצי GGUF, הפורמט שבו משתמש llama.cpp לאחסון משקולות על הדיסק. Ollama בנויה על גבי llama.cpp, ולכן התגיות של Ollama נושאות את שמות הקוונטיזציה של llama.cpp ללא שינוי.
המספר מייצג את רוחב היעד. q4 אומר שרוב טנזורי המשקולות דחוסים לארבעה ביטים כל אחד. q8 אומר שמונה. fp16 מציין שאין קוונטיזציה כלל: זהו המודל בפורמט 16-bit floating point, רמת הדיוק שבה רוב המודלים מתפרסמים.
K מסמן K-quant. משקולות מקובצות לבלוקים קטנים, וכל בלוק מאחסן את קנה המידה (scale) שלו לצד הערכים הדחוסים. בלוק שכל המשקולות בו קרובות ל-0.01 מקבל קנה מידה עדין. בלוק שמכיל ערך חריג אחד גדול מקבל קנה מידה גס. קני מידה אלו לכל בלוק הם ששומרים על קובץ ארבעה-ביט שמיש, והם גם הסיבה לכך שקובץ ארבעה-ביט לעולם אינו בדיוק ארבעה ביטים למשקולת.
האות האחרונה היא התערובת (mixture). S, M ו-L קובעים כמה טנזורים יקודמו לרוחב גדול מרוחב היעד. ב-q4_K_M, הטנזורים שהכי נפגעים מעיגול מאוחסנים ברוחב גדול יותר, בעוד הרוב נשאר בארבעה ביטים. זו הסיבה ש-q4_K_M מפיק פלט טוב יותר מה-q4_0 הישן יותר, כמעט באותו גודל קובץ.
שאלו את Ollama מה קיים אצלה על הדיסק במקום לנחש לפי השם שהקלדתם:
ollama pull qwen3:8b-q4_K_M
ollama show qwen3:8b-q4_K_Mollama show מדפיס את architecture, parameters, quantization, context length ו-embedding length. השורה quantization היא האמת המוחלטת עבור מודל שהורדתם לפני חודשים ואתם כבר לא זוכרים מה בחרתם.
מספר הביטים לכל משקל הוא המקור לנפח הקובץ
כל הערכת נפח מתחילה במספר אחד: כמה ביטים הפורמט מקצה לכל משקל, בממוצע על פני כל הקובץ. llama.cpp מפרסמת נתונים מדודים עבור Llama 3.1 8B בתיעוד ה-quantize שלה, והם תקפים לכל מודל צפוף בעל מבנה דומה.
The data behind this chart
[
{
"label": "F16",
"bits_per_weight": 16,
"file_gib": 14.96
},
{
"label": "Q8_0",
"bits_per_weight": 8.5,
"file_gib": 7.95
},
{
"label": "Q6_K",
"bits_per_weight": 6.56,
"file_gib": 6.14
},
{
"label": "Q5_K_M",
"bits_per_weight": 5.7,
"file_gib": 5.33
},
{
"label": "Q4_K_M",
"bits_per_weight": 4.89,
"file_gib": 4.58
},
{
"label": "Q3_K_M",
"bits_per_weight": 3.99,
"file_gib": 3.74
}
]ההפתעה בטבלה זו נמצאת בעמודה השנייה. Q4_K_M אינו ארבעה ביטים לכל משקל. הוא מודד 4.89 ביטים, כיוון שקני המידה של הבלוקים והטנזורים המקודמים צורכים נפח בפועל. Q8_0 מודד 8.5 ביטים במקום שמונה, מאותה סיבה. השתמשו במספר המדוד והחישוב יניב תוצאה הקרובה באחוזים בודדים לנפח הקובץ האמיתי:
weight bytes = parameter count x bits per weight / 8
8.03e9 params x 4.89 bits / 8 = 4.91e9 bytes = 4.57 GiBזהו קובץ Q4_K_M בנפח 4.58 GiB, שחושב משני מספרים. זהו גם, בקירוב טוב, הזיכרון שהמשקלים תופסים לאחר הטעינה. Ollama אינה פורסת דבר בעת הטעינה: המשקלים המקודדים נשארים בזיכרון באותה צורה דחוסה, וכל בלוק מומר בזמן השימוש בו.
מה Ollama מספקת בפועל עבור כל גודל מודל
הספרייה מפרסמת תגית q4_K_M, תגית q8_0 ותגית fp16 עבור רוב המשפחות. אלו הם הגדלים של Qwen3 נכון לאוגוסט 2026, כפי שהם מופיעים ברשימת התגיות בדף המודל.
The data behind this chart
[
{
"label": "Qwen3 4B",
"q4_K_M_gb": 2.6,
"q8_0_gb": 4.4,
"fp16_gb": 8.1
},
{
"label": "Qwen3 8B",
"q4_K_M_gb": 5.2,
"q8_0_gb": 8.9,
"fp16_gb": 16
},
{
"label": "Qwen3 14B",
"q4_K_M_gb": 9.3,
"q8_0_gb": 16,
"fp16_gb": 30
},
{
"label": "Qwen3 32B",
"q4_K_M_gb": 20,
"q8_0_gb": 35,
"fp16_gb": 66
}
]לתגית ברירת המחדל יש כאן חשיבות. ollama pull qwen3:8b מוריד בדיוק את אותם 5.2 GB כמו ollama pull qwen3:8b-q4_K_M, כיוון שהתגית ללא סיומת היא גרסת ה-q4_K_M. ה-q4_K_M אינו פשרה שהספרייה מציעה בחוסר רצון. זוהי ברירת המחדל שבחר הספק (upstream), ולכן התאמה אליה היא הצעד הראשון ההגיוני עבור כל מודל שטרם בדקת בעצמך. אותו היגיון מנחה את בחירת התגיות ב-הרצת Qwen 3 על שרת VPS.
היחסים נשמרים בכל שורה. מעבר מ-q4_K_M ל-q8_0 עולה כשבעים אחוז יותר ולא בדיוק פי שניים, כיוון שטנזורי ה-embedding והפלט אינם משתנים באותו אופן כמו שאר המודל. גרסת fp16 גדולה בערך פי שלושה מ-q4_K_M. מודל 32B בגרסת q4_K_M שוקל 20 GB של משקולות, מה שכבר חורג ממה ששרת עם 16 GB זיכרון יכול להחזיק עם חלון הקשר כלשהו. למבט רחב יותר על מה מתאים לאיזו מכונה, ראו אילו מודלים ניתן לארח באופן עצמי.
מדוע ה-KV cache הוא עלות שנייה התלויה בהקשר
המשקולות (weights) הן עלות קבועה. ה-KV cache (מטמון מפתחות וערכים) הוא העלות המשתנה. כל אסימון (token) בחלון ההקשר שומר את וקטורי המפתח והערך שלו עבור כל שכבה, לכן המטמון גדל בקו ישר בהתאם לחלון שאתם מגדירים. הוא מוקצה עבור כל החלון בעת טעינת המודל, ולא ככל שהשיחה מתמלאת; זו הסיבה שחלון ארוך צורך זיכרון גם עבור הנחיה (prompt) של מילה אחת.
KV bytes per token = 2 (key and value) x layers x kv_heads x head_dim x bytes_per_element
Qwen3 8B at f16: 2 x 36 x 8 x 128 x 2 = 147456 bytes = 144 KiB per tokenמספרי המודל הללו מגיעים מהגדרות המודל עצמו: 36 שכבות, 8 ראשי מפתח/ערך, ומימד ראש של 128. ollama show מספק לכם את הארכיטקטורה ואת מספר הפרמטרים, וה-config.json של המודל ב-Hugging Face מספק את השאר. הכפילו את העלות לכל אסימון בגודל החלון, והמטמון יפסיק להיות שגיאת עיגול זניחה.
The data behind this chart
[
{
"label": "4k",
"kv_cache_gb": 0.6,
"floor_ram_gb": 5.8
},
{
"label": "8k",
"kv_cache_gb": 1.21,
"floor_ram_gb": 6.4
},
{
"label": "16k",
"kv_cache_gb": 2.42,
"floor_ram_gb": 7.6
},
{
"label": "32k",
"kv_cache_gb": 4.83,
"floor_ram_gb": 10
}
]בחלון ברירת המחדל של Ollama העומד על 4096 אסימונים, המטמון מוסיף 0.6 GB מעבר למשקולות. העלו את החלון ל-32k והמטמון לבדו יגיע ל-4.83 GB, כמות זיכרון הקרובה לזו של המשקולות המקודדות (quantized), והרף התחתון עבור המודל כולו יהיה 10 GB. אנו קוראים לזה רף תחתון מכיוון שמאגרי חישוב (compute buffers) ומערכת ההפעלה מתווספים מעליו. קראו את הנתון האמיתי מעמודת SIZE ב-ollama ps לאחר טעינת המודל.
החלון מוגדר בשרת, לא לכל בקשה, כאשר מריצים את Ollama כשירות:
OLLAMA_CONTEXT_LENGTH=8192 ollama serveעבור התקנת systemd, הציבו זאת בקובץ drop-in במקום:
sudo systemctl edit ollama[Service]
Environment="OLLAMA_CONTEXT_LENGTH=8192"
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"בצעו הפעלה מחדש עם sudo systemctl restart ollama, ולאחר מכן בדקו את עמודת CONTEXT ב-ollama ps כדי לאשר את החלון שבו נטען המודל בפועל. OLLAMA_KV_CACHE_TYPE מבצע קידוד (quantization) למטמון עצמו: f16 הוא ברירת המחדל, q8_0 משתמש בכמחצית מהזיכרון של f16, ו-q4_0 בכרבע. זוהי אפשרות גלובלית, לכן כל מודל בשרת זה מקבל את אותו הטיפול. במכונה קטנה עם חלון ארוך, צמצום המטמון בחצי מפנה יותר זיכרון מכל שינוי בודד אחר. הגדרת num_ctx והעלות הכרוכה בכך מכסה את החלון עצמו בפירוט.
מה מתאים לשרת VPS עם 8, 16 או 32 GB זיכרון
יש לשקלל את משקלי המודל, את ה-KV cache, ואת המרווח הדרוש למערכת ההפעלה ולכל תהליך אחר שרץ. מרווח של 2 GB הוא נוח עבור שרת VPS קטן.
8 GB. מודל 4B בקוונטיזציה q4_K_M תופס 2.6 GB ומשאיר מקום לחלון הקשר (context window) ארוך. מודל 8B בקוונטיזציה q4_K_M נכנס עם חלון ברירת המחדל של 4k, אך עם מעט מאוד מרווח נשימה. אל תתכננו להריץ 8B עם חלון של 32k בשרת זה, כיוון שהרף המינימלי של 10 GB כבר חורג מהקיבולת הזמינה.
16 GB. מודל 8B בקוונטיזציה q4_K_M עם חלון של 16k או 32k ירוץ בנוחות. מודל 14B בקוונטיזציה q4_K_M דורש 9.3 GB עבור המשקלים, וניתן להריץ אותו עם חלון הקשר צנוע. מודל 8B בקוונטיזציה q8_0 דורש 8.9 GB, לכן גם הוא מתאים. השוואה בין שני אלו באמצעות ה-prompts שלכם היא הדרך היעילה ביותר להעמיק בנושא זה.
32 GB. מודל 14B בקוונטיזציה q8_0 (16 GB) ומודל 32B בקוונטיזציה q4_K_M (20 GB) ייטענו שניהם. הרצת מודל 32B עם חלון הקשר גדול תקרב אתכם לקצה גבול היכולת של השרת, לכן עקבו אחר ollama ps במקום להניח שהכל יפעל כשורה.
מה נפגע ראשון בקוונטיזציה
שגיאת קוונטיזציה אינה מתפזרת באופן אחיד על פני פעולות המודל. השטף הלשוני (fluency) נשמר לאורך זמן רב, וזו בדיוק הסיבה לכך שקל לפספס את הנזק: מודל שעבר קוונטיזציה גרועה עדיין כותב משפטים תקינים. הדיוק הוא הראשון להיפגע. שליפה מדויקת של מספר גרסה, חתימת API או תאריך. שרשראות הסקה ארוכות, שבהן שגיאה קטנה בשלב השני הופכת לתשובה שגויה בשלב השמיני. פורמטים קשיחים של פלט, שבהם סוגריים שגויים אחד גורמים לכשל בקריאה לפונקציה (tool call).
הנקודה האחרונה היא המבחן המעשי. כאשר מודל נדרש להחזיר JSON שהקוד שלכם מנתח, נזקי הקוונטיזציה מופיעים כשגיאת ניתוח (parse error) ולא כפרוזה גרועה במעט, כך שתבחינו בכך באותו היום.
מתחת לארבעה ביטים, הירידה באיכות הופכת לתלולה. הסוגים q3 ושני ביטים קיימים עבור אנשים שדוחסים מודל גדול לחומרה קטנה, והם מהווים אפשרות ממשית כאשר החלופה היא אי-הרצת המודל כלל. הם מהווים ברירת מחדל גרועה. בין q4_K_M לבין q8_0 הפער קטן מספיק כדי שטבלת perplexity מפורסמת לא תכריע עבור עומס העבודה שלכם, לכן אל תנסו להכריע זאת בדרך זו. הריצו את שניהם מול שלושים מהנחיות (prompts) שלכם וקראו את הפלט.
מתי כדאי להשתמש ב-q8_0 או ב-fp16
משכו את q8_0 כאשר יש לכם זיכרון פנוי באמת והמשימה רגישה לשגיאות קטנות: חילוץ נתונים מובנה, קריאה לכלים (tool calling), או כתיבת קוד שחייב לעבור הידור (compile). אתם רוכשים כאן ביטוח, לא מודל חכם יותר באופן מורגש.
משכו את fp16 משתי סיבות בלבד. או שאתם מבצעים קוונטיזציה (quantization) למודל בעצמכם וזקוקים לקובץ המקור, או שאתם מודדים נקודת ייחוס (baseline) כדי לדעת כמה איבדתם במבנה ה-4-bit שלכם. הרצה מ-fp16 צורכת פי שלושה זיכרון מאשר q4_K_M עבור הבדל שרוב האנשים לא יבחינו בו במבחן עיוור, ובמכונה מבוססת CPU בלבד, היא גם חותכת את קצב יצירת ה-tokens לשליש.
הכלל החזק יותר, תחת תקציב זיכרון קבוע: מודל גדול יותר ב-q4_K_M בדרך כלל עדיף על מודל קטן יותר ב-q8_0. 9.3 GB של משקולות (weights) במודל 14B לעומת 8.9 GB של משקולות במודל 8B דורשים כמעט את אותה כמות RAM, והמודל הגדול יותר "יודע" יותר. בדקו זאת על ה-prompts שלכם במקום להסתמך על הנחות.
הסקה (Inference) מבוססת CPU בלבד מוגבלת על ידי רוחב הפס של הזיכרון
רוב תוכניות ה-VPS אינן כוללות GPU, לכן המודל רץ בזיכרון המערכת על גבי ה-CPU של המארח. יצירת הטקסט (Generation) מוגבלת במקרה זה על ידי רוחב הפס של הזיכרון, ולא על ידי יכולת החישוב האריתמטית, כיוון שהפקת טוקן אחד דורשת קריאה של כל משקולת (weight) פעם אחת. מצב זה יוצר תקרה ביצועית שאינה קשורה למספר הליבות שרכשת.
tokens per second ceiling = memory bandwidth / bytes read per token
50 GB/s / 5.2 GB = 9.6 tokens/s qwen3 8B q4_K_M
50 GB/s / 8.9 GB = 5.6 tokens/s qwen3 8B q8_0
50 GB/s / 16 GB = 3.1 tokens/s qwen3 8B fp1650 GB/s הוא בקירוב הנתון התאורטי עבור מארח עם ערוץ כפול (dual channel) של DDR4-3200. החלק שלך ברוחב הפס קטן יותר, כיוון ש-VPS חולק את ה-bus עם כל שאר הדיירים על המכונה; לכן, התייחס למספרים אלו כאל תקרה שאף אחד לא מגיע אליה בפועל. המגמה היא החלק השימושי: ב-CPU, הפחתת מספר הביטים לכל משקולת בחצי תכפיל בערך את קצב הטוקנים. קוונטיזציה (Quantization) היא מנוף המהירות המשמעותי ביותר הזמין במכונה ללא GPU.
עיבוד ה-prompt מתנהג אחרת. קריאת prompt ארוך מוגבלת על ידי כוח עיבוד (compute bound) ולא על ידי רוחב פס, לכן ליבות נוספות מסייעות כאן, בעוד שהן כמעט אינן משפיעות על מהירות היצירה. מכונה שקולטת prompt של 4k במהירות ואז מייצרת טקסט באיטיות מתנהגת בצורה תקינה.
אל תקבל אף חישוב כאמת מוחלטת. מדוד טוקנים לשנייה על המכונה שלך עם אותו ה-prompt בכל רמת קוונטיזציה, ותן למספרים שלך לקבוע את המסקנות.
כימות מודל באופן עצמאי
Ollama מסוגלת לבנות מודל מכוּמת (quantized) ממקור בפורמט fp16 או fp32. יכולת זו חיונית כאשר ביצעת fine-tuning למודל ואין עבורו תגית זמינה בספריות. יש להפנות את ה-Modelfile אל המשקולות (weights) הלא-מכוּמתות:
FROM /path/to/my/model/f16לאחר מכן, יש לבנות את המודל ולאמת את התוצאה:
ollama create --quantize q4_K_M mymodel
ollama show mymodelהפקודה --quantize מקבלת את q8_0, q4_K_S ו-q4_K_M. לא קיימת כאן אפשרות ל-q6_K או q5_K_M; עבור אלו, יש לבצע את הכימות באמצעות הכלי הייעודי של llama.cpp ולייבא את קובץ ה-GGUF המוכן. השורה quantization מתוך ollama show היא הדרך לוודא שהבנייה בוצעה בהתאם להגדרות שלך.
מה תראה כאשר משהו משתבש
הכול רץ על ה-CPU למרות שציפית ל-GPU. בדוק את העמודה PROCESSOR:
ollama psהיא מדפיסה 100% GPU, 100% CPU, או פיצול כגון 48%/52% CPU/GPU. פיצול משמעו שהמשקולות יחד עם ה-KV cache לא נכנסו ל-VRAM (זיכרון הווידאו, הזיכרון שעל כרטיס המסך), ולכן חלק מהמודל הועבר לזיכרון המערכת. המהירות יורדת אז לרמה הקרובה לזו של ה-CPU בלבד, כיוון שכל טוקן ממתין לחצי האיטי. הקטן את חלון ההקשר (context window), בצע קוונטיזציה ל-cache, או משוך גרסה קטנה יותר של המודל. הוספת ליבות לא תעזור.
המודל נסגר (killed) בזמן הטעינה. בדוק את ה-kernel ואת לוג השירות:
sudo dmesg -T | grep -i "out of memory"
sudo journalctl -u ollama -n 50שורה המכילה Out of memory: Killed process משמעה שסך המשקולות, ה-KV cache והמאגרים חרגו מזיכרון המערכת הזמין. בשרת VPS ללא הגדרת swap, המכונה כולה עלולה לקפוא למשך מספר שניות לפני ששורה זו תופיע.
התשובות הפכו פחות טובות למרות שלא שינית דבר. שתי גרסאות של אותו מודל יכולות להתקיים זו לצד זו ב-ollama ls תחת תגיות שונות, וסקריפט שמושך את השם ללא סיומת יעקוב אחר מה שהספרייה מצביעה עליו כעת. הרץ את ollama show מול התגית המדויקת שהלקוח שלך מבקש וקרא את השורה quantization, במקום להסתמך על השם בקובץ התצורה שלך.
FAQ
באיזו קוונטיזציה (quantization) של Ollama כדאי לבחור?
התחילו עם q4_K_M. זוהי ברירת המחדל שמספקת ספריית Ollama עבור רוב המודלים, ולכן ollama pull qwen3:8b ו־ollama pull qwen3:8b-q4_K_M יורידו את אותו הקובץ בדיוק. עברו ל־q8_0 רק כאשר יש לכם זיכרון פנוי והמשימה רגישה לשגיאות קטנות, כמו קריאה לכלים (tool calling) או פלט JSON מובנה. כאשר תקציב הזיכרון מוגבל, מודל גדול יותר בקוונטיזציה q4_K_M בדרך כלל עדיף על מודל קטן יותר ב־q8_0; לכן, בדקו את השילוב הזה לפני שתקצו RAM נוסף עבור דיוק גבוה יותר.
האם q4_K_M באמת אומר ארבעה ביטים לכל משקל?
לא. במדידה על Llama 3.1 8B התוצאה היא 4.89 ביטים למשקל, מכיוון שכל בלוק משקולות שומר קנה מידה (scale) משלו, והטנזורים הרגישים ביותר מקודדים בטיפוס נתונים רחב יותר. Q8_0 מודד 8.5 ביטים במקום שמונה מאותה סיבה. השתמשו בנתון הנמדד לצורך הערכה: מספר הפרמטרים כפול מספר הביטים למשקל, חלקי שמונה, ייתן את גודל הקובץ בבתים.
כמה RAM דרוש למודל 8B בשרת VPS מבוסס CPU בלבד?
יש לחשב את המשקולות, את ה-KV cache ואת מרווח הביטחון. Qwen3 8B בקוונטיזציה q4_K_M תופס 5.2 GB עבור המשקולות. בחלון הקשר (context window) ברירת מחדל של 4096 טוקנים, ה-cache מוסיף 0.6 GB, מה שמביא את הרף התחתון לאזור ה-5.8 GB, עוד לפני חישוב ה-buffers של המעבד ומערכת ההפעלה. בחלון של 32k, ה-cache לבדו תופס 4.83 GB. תכננו על 8 GB עבור חלון קצר ועל 16 GB אם אתם זקוקים לחלון ארוך.
מדוע המודל רץ ב-100% CPU למרות שיש לשרת GPU?
הריצו את ollama ps ובדקו את העמודה PROCESSOR. הערך 100% CPU, או פיצול כמו 48%/52% CPU/GPU, מעידים על כך שהמשקולות יחד עם ה-KV cache לא נכנסו ל-VRAM, ולכן Ollama העבירה חלק מהמודל או את כולו לזיכרון המערכת. הסיבה הנפוצה לכך היא חלון הקשר גדול מכפי שהכרטיס יכול להכיל, שכן ה-cache מוקצה עבור כל החלון ברגע טעינת המודל. הקטינו את החלון בעזרת OLLAMA_CONTEXT_LENGTH, הגדירו את OLLAMA_KV_CACHE_TYPE=q8_0 כדי לצמצם את ה-cache בחצי, או הורידו קוונטיזציה קטנה יותר.