מה זה NUMA ולמה זה חשוב באופטימיזציות Inference?
מה זה NUMA ולמה זה חשוב באופטימיזציית Inference?
כשאנחנו מריצים מודל על שרת חזק, אנחנו נוטים לחשוב שכל המעבדים (CPUs) והזיכרון זמינים “באותה מהירות”. אבל האמת רחוקה מזה. כאן נכנסת לתמונה הארכיטקטורה שנקראת NUMA - Non-Uniform Memory Access.
מה זה אומר בפועל?
בשרתים מודרניים יש כמה מעבדים (sockets), ולכל אחד מהם יש:
- ליבות משלו.
- זיכרון (RAM) “קרוב” אליו פיזית.
הגישה לזיכרון המחובר ישירות למעבד שלך מהירה מאוד. אבל אם המעבד צריך לגשת לזיכרון של “שכן” - כלומר, זיכרון המחובר למעבד אחר - הוא עושה זאת דרך interconnect פנימי, וזה איטי יותר.
למה זה חשוב ל-Inference?
ב-inference, כל עיכוב קטן מצטבר: אם תהליך שרץ על socket אחד ניגש שוב ושוב לזיכרון שנמצא על socket אחר, נוצר latency מיותר שיכול להגיע לעשרות אחוזים מהזמן הכולל.
זה קורה, למשל, כאשר:
- מודל רץ על ליבות ב-CPU אחד, אבל הנתונים שלו נמצאים בזיכרון של CPU אחר.
- מערכת ההפעלה מפזרת תהליכים אוטומטית בלי להבין את ההשלכות.
איך פותרים את זה?
- ממקמים תהליכים וזיכרון על אותו node - מה שנקרא “NUMA-aware allocation”.
- משתמשים בכלים כמו numactl כדי לקבוע לאיזה socket וליבה כל תהליך שייך.
- שומרים על locality - מבטיחים שכל החישוב והגישה לזיכרון יקרו כמה שיותר “קרוב לבית”.
בשורה התחתונה
NUMA הוא לא סתם פרט טריוויה ארכיטקטוני - הוא גורם ישיר ל-latency. מודעות ל-NUMA וקישור נכון של תהליכים לזיכרון המתאים יכולים לעשות את ההבדל בין מערכת איטית למערכת שמספקת תחזיות כמעט פי שניים מהר יותר.
📚 פוסטים נוספים בסדרה: אופטימיזציה של חומרת הסקה
- חלק 1 למה בכלל צריך להבין חומרה כשעוסקים באופטימיזציות Inference?
- חלק 3 מה זה ליבות (Cores) ו-Threads?
- חלק 4 מה זה Cache ולמה הוא משנה הכל?
- חלק 5 חלקת ליבות איך לנהל נכון את כח העיבוד שלך
- חלק 6 Thread Affinity - How to Bind Cores Smartly
- חלק 7 Divided Resources - איך מחלקים משאבים בין מודלים או תהליכים
- חלק 8 Resource Optimization - איך כל הגורמים משפיעים בפועל על Latency ו-TPS
- חלק 9 סיכום הסדרה: מ-NUMA ועד Throughput - איך אופטימיזציה הופכת חומרה לביצועים