- משתמשים במודלים שנטענים במהירות ודורשים מינימום טרנספורמציה למבנים שמוכנים לשימוש ב-GPU, ומבצעים אופטימיזציה של אופן הטעינה שלהם.
- כדי לצמצם את מספר מעבדי ה-GPU שנדרשים כדי לטפל בבקשה ליעד לשנייה, תוך שמירה על עלויות נמוכות, מומלץ להשתמש בהגדרות שמאפשרות ביצוע מקסימלי, יעיל ובו-זמני.
דרכים מומלצות לטעינת מודלים גדולים של למידת מכונה ב-Cloud Run
Google ממליצה להוריד מודלים של ML מ-Cloud Storage ולגשת אליהם דרך Google Cloud CLI. אפשר גם לאחסן מודלים בתוך קובצי אימג' בקונטיינר, אבל השיטה הזו מתאימה בעיקר למודלים קטנים יותר, בגודל של פחות מ-10GB.
הפשרות שצריך לעשות כשמאחסנים וטוענים מודלים של למידת מכונה
השוואה בין האפשרויות:
| מיקום הדגם | זמן הפריסה | חוויית הפיתוח | זמן ההפעלה של הקונטיינר | עלות האחסון |
Cloud Storage, שהורד בו-זמנית באמצעות הפקודה gcloud storage cp של Google Cloud CLI או Cloud Storage API, כפי שמוצג בדוגמת הקוד להורדה בו-זמנית של מנהל ההעברות.
|
המהיר ביותר. המודל הורד במהלך הפעלת המאגר. מוודאים שהוקצה מספיק זיכרון RAM למופע של Cloud Run כדי לאחסן את קובצי המודל. | ההגדרה קצת יותר מסובכת, כי צריך להתקין את Google Cloud CLI בתמונה או לעדכן את הקוד כדי להשתמש ב-Cloud Storage API. מידע נוסף על אחזור פרטי כניסה משרת המטא-נתונים זמין במאמר מבוא לזהות שירות. | מהיר כשמשתמשים באופטימיזציות של רשת. Google Cloud CLI מוריד את קובץ המודל במקביל, ולכן הוא מהיר יותר מטעינת FUSE. | עותק אחד ב-Cloud Storage. |
| Cloud Storage, נטען באמצעות טעינת נפח Cloud Storage FUSE | מהיר יותר. המודל הורד במהלך הפעלת המאגר. | ההגדרה לא מסובכת ולא דורשת שינויים בתמונת ה-Docker. | מהיר כשמשתמשים באופטימיזציות של רשת. ההורדה לא מתבצעת במקביל. | עותק אחד ב-Cloud Storage. |
| קובץ אימג' של קונטיינר | מהירות גבוהה. ייבוא של תמונה שמכילה מודל גדול ל-Cloud Run ייקח יותר זמן. | תצטרכו ליצור תמונה חדשה בכל פעם שתרצו להשתמש במודל אחר. שינויים בקובץ אימג' של קונטיינר יחייבו פריסה מחדש, שיכולה להיות איטית לקובצי אימג' גדולים. | תלוי בגודל המודל. למודלים גדולים מאוד, מומלץ להשתמש ב-Cloud Storage כדי לקבל ביצועים צפויים יותר אבל איטיים יותר. | יכול להיות שיהיו כמה עותקים ב-Artifact Registry. |
| אינטרנט | איטי. המודל הורד במהלך הפעלת המאגר. | בדרך כלל פשוט יותר (הרבה מסגרות עבודה מורידות מודלים ממאגרים מרכזיים). | בדרך כלל נמוכה ובלתי צפויה:
|
תלוי בספק האירוח של המודל. |
אחסון מודלים ב-Cloud Storage
כדי לייעל את הטעינה של מודלים של למידת מכונה כשמטעינים אותם מ-Cloud Storage, באמצעות טעינת נפח של Cloud Storage או באמצעות Cloud Storage API או שורת פקודה, צריך להשתמש ב-Direct VPC עם הגדרת תעבורת נתונים יוצאת שמוגדרת לערך all-traffic, וגם ב-גישה פרטית ל-Google.
בתוספת עלות, אפשר להשתמש ב-Anywhere Cache כדי לצמצם את זמן האחזור של טעינת המודל. המערכת שומרת נתונים במטמון ביעילות בכונני SSD כדי לקרוא אותם מהר יותר.
כדי לקצר את זמני הקריאה של המודל, אפשר לנסות את אפשרויות הטעינה הבאות כדי להפעיל תכונות של Cloud Storage FUSE:
-
cache-dir: הפעלת תכונת שמירת קבצים במטמון עם טעינת נפח אחסון בזיכרון לשימוש כספריית הבסיס לשמירת קבצים. מגדירים את הערך של אפשרות ההרכבהcache-dirלשם של אמצעי האחסון בזיכרון בפורמטcr-volume:{volume name}. לדוגמה, אם יש לכם אמצעי אחסון בזיכרון בשםin-memory-1שבו אתם רוצים להשתמש כספריית מטמון, מצייניםcr-volume:in-memory-1. כשמגדירים את הערך הזה, אפשר גם להגדירfile-cacheדגלים אחרים שזמינים להגדרה עבור מטמון. -
enable-buffered-read: מגדירים את השדהenable-buffered-readלערךtrueכדי לבצע אחזור מראש אסינכרוני של חלקים מאובייקט ב-Cloud Storage אל מאגר זמני בזיכרון. כך אפשר יהיה להציג קריאות עוקבות מהמאגר במקום לדרוש קריאות רשת. כשמגדירים את השדה הזה, אפשר גם להגדיר את השדהread-global-max-blocksכדי להגדיר את המספר המקסימלי של בלוקים שזמינים לקריאות עם מאגר זמני בכל ידיות הקבצים.
אם משתמשים גם ב-cache-dir וגם ב-enable-buffered-read, המערכת תיתן עדיפות ל-cache-dir. שימו לב: הפעלת אחת מהתכונות האלה תשנה את חישוב המשאבים של תהליך Cloud Storage FUSE, כך שהם ייכללו במגבלות הזיכרון של הקונטיינר. כדאי להגדיל את מגבלת הזיכרון של מאגר התגים בהתאם להוראות להגדרת מגבלות זיכרון.
אחסון מודלים בקובצי אימג' של קונטיינרים
אם מאחסנים את מודל ה-ML בקובץ האימג' של הקונטיינר, טעינת המודל תהנה מהתשתית המותאמת של Cloud Run להזרמת קונטיינרים. עם זאת, בניית תמונות של קונטיינרים שכוללות מודלים של למידת מכונה היא תהליך שדורש הרבה משאבים, במיוחד כשעובדים עם מודלים גדולים. באופן ספציפי, צוואר הבקבוק בתהליך build יכול להיות קצב העברת הנתונים ברשת. כשמשתמשים ב-Cloud Build, מומלץ להשתמש במכונת בנייה חזקה יותר עם ביצועים משופרים של מחשוב ורשת. כדי לעשות זאת, צריך ליצור אימג' באמצעות קובץ תצורה של build עם השלבים הבאים:
steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'IMAGE', '.'] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'IMAGE'] images: - IMAGE options: machineType: 'E2_HIGHCPU_32' diskSizeGb: '500'
אפשר ליצור עותק אחד של המודל לכל תמונה אם השכבה שמכילה את המודל שונה בין התמונות (ערך hash שונה). יכול להיות שיהיו עלויות נוספות של Artifact Registry כי יכול להיות שיהיה עותק אחד של המודל לכל תמונה אם שכבת המודל ייחודית לכל תמונה.
טעינת מודלים מהאינטרנט
כדי לבצע אופטימיזציה לטעינת מודלים של ML מהאינטרנט, מעבירים את כל התעבורה דרך רשת ה-VPC עם הגדרת היציאה שערך שלה הוא all-traffic, ומגדירים Cloud NAT כדי להגיע לאינטרנט הציבורי ברוחב פס גבוה.
שיקולים לגבי build, פריסה, זמן ריצה ותכנון מערכת
בקטעים הבאים מתוארים שיקולים לגבי בנייה, פריסה, זמן ריצה ועיצוב מערכת.
בזמן ה-build
ברשימה הבאה מפורטים שיקולים שצריך לקחת בחשבון כשמתכננים את הפיתוח:
- בוחרים תמונה בסיסית טובה. מומלץ להתחיל עם תמונה ממאגרי הקונטיינרים של למידה עמוקה או ממאגר הקונטיינרים של NVIDIA עבור מסגרת ה-ML שבה אתם משתמשים. התמונות האלה כוללות את חבילות הביצועים העדכניות ביותר. אנחנו לא ממליצים ליצור תמונה מותאמת אישית.
- כדי למקסם את מספר הפעולות שמתבצעות בו-זמנית, מומלץ לבחור במודלים עם כימות של 4 ביט, אלא אם יש לכם הוכחה שהם משפיעים על איכות התוצאות. קוונטיזציה יוצרת מודלים קטנים ומהירים יותר, ומקטינה את כמות הזיכרון ב-GPU שנדרשת להפעלת המודל. היא גם יכולה להגדיל את המקביליות בזמן הריצה. במצב אידיאלי, המודלים צריכים לעבור אימון בעומק הסיביות של היעד ולא לעבור קוונטיזציה כדי להגיע לעומק הסיביות הזה.
- כדי לצמצם את זמן ההפעלה של הקונטיינר, כדאי לבחור פורמט מודל עם זמני טעינה מהירים, כמו GGUF. הפורמטים האלה משקפים בצורה מדויקת יותר את סוג הכימות של היעד ודורשים פחות טרנספורמציות כשמעלים אותם ל-GPU. מטעמי אבטחה, לא מומלץ להשתמש בנקודות ביקורת בפורמט pickle.
- יצירה וחימום של מטמון LLM בזמן הבנייה. מפעילים את ה-LLM במכונת הבנייה בזמן בניית קובץ האימג' של Docker. כדאי להפעיל שמירה במטמון של הנחיות ולהזין הנחיות נפוצות או לדוגמה כדי להכין את המטמון לשימוש בעולם האמיתי. שמירת הפלטים שנוצרו כדי לטעון אותם בזמן הריצה.
- שמירת מודל ההסקה שנוצר במהלך משך זמן של תהליך build. כך חוסכים זמן משמעותי בהשוואה לטעינת מודלים שמאוחסנים בצורה פחות יעילה ולהחלת טרנספורמציות כמו קוונטיזציה בהפעלת הקונטיינר.
בזמן הפריסה
הרשימה הבאה מציגה שיקולים שצריך לקחת בחשבון כשמתכננים את הפריסה:
- חשוב לוודא שהגדרתם את מספר הבקשות המקבילות לשירות בצורה מדויקת ב-Cloud Run.
- משנים את בדיקות ההפעלה בהתאם להגדרות.
בדיקות מוכנות להפעלה קובעות אם הקונטיינר הופעל ומוכן לקבל תנועה. כשמגדירים בדיקות מוכנות להפעלה, חשוב להביא בחשבון את הנקודות העיקריות הבאות:
- זמן הפעלה מספיק: צריך להקצות מספיק זמן כדי שהקונטיינר, כולל המודלים, יאותחל וייטען באופן מלא.
- אימות מוכנות המודל: מגדירים את הבקשה לבדיקת תקינות (probe) כך שהיא תעבור רק כשהאפליקציה מוכנה למלא בקשות. הרבה מנועי הגשה משיגים את זה באופן אוטומטי כשהמודל נטען לזיכרון ה-GPU, וכך מונעים בקשות מוקדמות.
שימו לב: Ollama יכול לפתוח יציאת TCP לפני שנטען מודל. כדי לפתור את הבעיה:
טעינה מראש של מודלים: אפשר לעיין במסמכי התיעוד של Ollama כדי לקבל הנחיות לטעינה מראש של המודל במהלך ההפעלה.
בזמן הריצה
- ניהול אקטיבי של חלון ההקשר הנתמך. ככל שחלון ההקשר שאתם תומכים בו קטן יותר, כך תוכלו לתמוך בהרצת יותר שאילתות במקביל. הפרטים של אופן הפעולה תלויים במסגרת.
- משתמשים במטמוני ה-LLM שיצרתם במשך זמן של תהליך build. צריך לספק את אותם הדגלים שבהם השתמשתם משך זמן של תהליך build כשייצרתם את מטמון ההנחיות והקידומות.
- טוענים מהמודל השמור שכתבתם. במאמר היתרונות והחסרונות של אחסון וטעינה של מודלים יש השוואה בין האפשרויות לטעינת המודל.
- אם המסגרת שלכם תומכת במטמון של זוגות מפתח/ערך שעברו קוונטיזציה, כדאי להשתמש בו. הפעולה הזו יכולה להפחית את דרישות הזיכרון לכל שאילתה ולאפשר הגדרה של יותר מקביליות. עם זאת, זה יכול גם להשפיע על האיכות.
- כדאי לכוונן את כמות זיכרון ה-GPU שצריך לשריין למשקלי המודל, להפעלות ולמטמון של זוגות מפתח/ערך. כדאי להגדיר את הערך הכי גבוה שאפשר בלי לקבל שגיאה של חוסר זיכרון.
- כדאי לבדוק אם יש ב-framework אפשרויות לשיפור הביצועים של הפעלת מאגר התגים (לדוגמה, שימוש בטעינת מודלים במקביל).
- מגדירים את מספר הבקשות המקבילות בצורה נכונה בקוד השירות. מוודאים שקוד השירות מוגדר לעבודה עם הגדרות המקביליות של שירות Cloud Run.
ברמת עיצוב המערכת
- מוסיפים מטמון סמנטי במקומות המתאימים. במקרים מסוימים, שמירת מטמון של שאילתות ותשובות יכולה להיות דרך מצוינת להגבלת העלות של שאילתות נפוצות.
- שליטה בשונות בהקדמות. מטמון ההנחיות שימושי רק אם הוא מכיל את ההנחיות ברצף. המטמונים הם למעשה מטמונים של תחיליות. אם יש הוספות או עריכות ברצף, יכול להיות שהם לא נשמרו במטמון או שנשמרו רק באופן חלקי.
התאמה אוטומטית לעומס (autoscaling) ומעבדי GPU
אם משתמשים בהתאמה אוטומטית לעומס (autoscaling) ב-Cloud Run, מערכת Cloud Run משנה באופן אוטומטי את מספר המכונות של כל גרסה על סמך גורמים כמו ניצול המעבד (CPU) והבו-זמניות (concurrency) של הבקשות. עם זאת, ב-Cloud Run לא מתבצעת התאמה אוטומטית של מספר המכונות בהתאם לניצול ה-GPU.
אם יש לגרסה GPU, והשימוש במעבד לא משמעותי, Cloud Run מבצע הרחבה אופקית כדי לטפל בבקשות בו-זמנית. כדי להשיג קנה מידה אופטימלי של בקשות בו-זמניות, צריך להגדיר מספר מקסימלי אופטימלי של בקשות בו-זמניות לכל מופע, כפי שמתואר בקטע הבא.
מספר מקסימלי של בקשות בו-זמנית לכל מכונה
ההגדרה maximum concurrent requests per instance (מספר מקסימלי של בקשות בו-זמנית לכל מופע) קובעת את המספר המקסימלי של בקשות ש-Cloud Run שולח למופע יחיד בו-זמנית. צריך לכוונן את מספר הבקשות המקבילות כך שיתאים למספר הבקשות המקבילות המקסימלי שהקוד בכל מופע יכול לטפל בהן עם ביצועים טובים.
מקסימום מקביליות ועומסי עבודה של AI
כשמריצים עומס עבודה של היקש AI ב-GPU בכל מופע, רמת הבו-זמניות המקסימלית שהקוד יכול להתמודד איתה עם ביצועים טובים תלויה בפרטים ספציפיים של המסגרת וההטמעה. הגורמים הבאים משפיעים על ההגדרה האופטימלית של המספר המקסימלי של בקשות בו-זמניות:
- מספר המופעים של המודל שנטענו ב-GPU
- מספר השאילתות המקבילות לכל מודל
- שימוש באצווה
- פרמטרים ספציפיים להגדרת קבוצות
- כמות העבודה שלא מבוצעת על ידי GPU
אם הערך של 'בקשות מקסימליות בו-זמנית' מוגדר גבוה מדי, יכול להיות שהבקשות ימתינו בתוך המופע לגישה ל-GPU, מה שיוביל להגדלת זמן האחזור. אם הערך של 'בקשות מקסימליות בו-זמנית' נמוך מדי, יכול להיות שהשימוש ב-GPU לא יהיה יעיל מספיק, ולכן Cloud Run ירחיב את מספר המופעים מעבר לנדרש.
כלל אצבע להגדרת מספר מקסימלי של בקשות בו-זמניות לעומסי עבודה של AI:
(Number of model instances * parallel queries per model) + (number of model instances * ideal batch size)
לדוגמה, נניח שמכונה טוענת 3 מופעים של מודלים ל-GPU, וכל מופע של מודל יכול לטפל ב-4 שאילתות מקבילות. גודל האצווה האידיאלי הוא גם 4, כי זה מספר השאילתות המקבילות שכל מופע של המודל יכול לטפל בהן. לפי כלל האצבע, מגדירים את מספר הבקשות המקסימלי בו-זמנית
24: (3 * 4) + (3 * 4).
חשוב לזכור שהנוסחה הזו היא רק כלל אצבע. ההגדרה האידיאלית של מספר הבקשות המקסימלי בו-זמנית תלויה בפרטים הספציפיים של ההטמעה. כדי להשיג את הביצועים האופטימליים בפועל, מומלץ לבצע בדיקת עומס בשירות עם הגדרות שונות של בקשות מקסימליות בו-זמניות, כדי להעריך איזו אפשרות מניבה את הביצועים הטובים ביותר.
היחס בין תפוקה, זמן אחזור ועלות
במאמר ההבדלים בין קצב העברת נתונים, זמן אחזור ועלויות מוסבר איך המספר המקסימלי של בקשות בו-זמניות משפיע על קצב העברת הנתונים, על זמן האחזור ועל העלות. חשוב לשים לב שבכל שירותי Cloud Run שמשתמשים במעבדי GPU צריך להגדיר חיוב לפי מופע.