הרצת שני מודלים על GPU אחד: המתמטיקה שמאחורי LLMs מקומיים
אני מריץ מחסנית סוכנים (agent stack) על תחנת עבודה. המודלים רצים על DGX Spark דרך רשת LAN. אני משתמש ב-vLLM במקום ב-Ollama כדי לנהל את הזיכרון בצורה טובה יותר.
המטרה היא להריץ שני מודלים בו-זמנית:
- Qwen3-Next-80B עבור הסקה (reasoning) כבדה.
- Qwen3-4B עבור תגובות מהירות.
שני המודלים פונים ל-URL אחד דרך LiteLLM proxy. ההגדרה הזו נכשלה מספר פעמים לפני שמצאתי את המתמטיקה הנכונה.
להלן הלקחים מהמאבק.
מלכודת הזיכרון
ההגדרה gpu_memory_utilization אינה יעד לזיכרון פנוי. היא שבר מתוך סך כל זיכרון ה-GPU.
אם יש לך כרטיס של 120 GB ואתה מגדיר utilization ל-0.80, vLLM ינסה לתפוס 96 GB מתוך הקיבולת הכוללת. הוא לא בודק מה פנוי כרגע. אם אתה מנסה להריץ שני תהליכים, סכום האחוזים שלהם חייב להיות נמוך מ-0.95. עליך להשאיר מקום ל-overhead של framework ה-CUDA.
מה קרה למודלים
ניסיתי להשתמש בגרסת ה-Thinking של מודל ה-80B. זה נכשל. המודל היה מבצע הסקה בתוך תגיות <think> אך מעולם לא הפעיל קריאה לכלי (tool call). הוא פשוט היה עוצר.
נאלצתי להחליף את ה-backbone של ה-80B לגרסת ה-Instruct. זה אפשר לסוכן להשתמש בכלים בצורה תקינה.
המתמטיקה בפועל לאחר בדיקות, מצאתי שהמספרים הבאים עובדים עבור ההגדרה שלי:
• Qwen3-Next-80B (ביעד של 0.80): משתמש ב-87.8 GiB זיכרון בפועל.
• Qwen3-4B (ביעד של 0.10): משתמש ב-13.8 GiB זיכרון בפועל.
• שימוש כולל: ~101.6 GiB.
• מרווח פנוי (headroom): ~18 GiB.
אם דחפתי את ה-80B ל-0.85, מודל ה-4B לא הצליח לעלות. ה-80B תפס יותר מדי, ולא השאיר מקום לצרכים המינימליים של ה-4B.
ה-Playbook שלי למודלים שחיים יחד
- טען את המודל הגדול ביותר תחילה.
- תן לו להתייצב.
- הרץ
nvidia-smiכדי לראות את הזיכרון שבשימוש בפועל. - קבע את הגודל של המודל הקטן יותר בהתבסס על הזיכרון הפנוי שנותר פחות 5 GB עבור overhead.
- הפעל מחדש את שני המודלים פעמיים כדי להבטיח יציבות.
אל תנחשו את הגדרות הזיכרון שלכם. השתמשו בפקודה הזו כדי לראות את המציאות שלכם:
nvidia-smi --query-gpu=memory.used --format=csv
אם ההקצאה המיועדת (target allocation) והשימוש בפועל שלכם שונים ביותר מ-10%, המתמטיקה שלכם שגויה. תקנו זאת לפני שתפרסו את מחסנית הסוכנים שלכם.
קהילת למידה אופציונלית: https://t.me/GyaanSetuAi