- משתמשים במודלים שנטענים במהירות ודורשים מינימום טרנספורמציה למבנים שמוכנים ל-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 במקביל. | עותק אחד ב-Cloud Storage. |
| Cloud Storage, נטען באמצעות טעינת נפח Cloud Storage FUSE | מהיר יותר. המודל הורד במהלך הפעלת המאגר. | ההגדרה לא מסובכת ולא דורשת שינויים בתמונת ה-Docker. | מהיר כשמשתמשים באופטימיזציות של רשתות. | עותק אחד ב-Cloud Storage. |
| קובץ אימג' של קונטיינר | מהירות גבוהה. ייבוא של תמונה שמכילה מודל גדול ל-Cloud Run ייקח יותר זמן. | תצטרכו ליצור תמונה חדשה בכל פעם שתרצו להשתמש במודל אחר. שינויים בקובץ האימג' של הקונטיינר יצריכו פריסה מחדש, שיכולה להיות איטית אם מדובר בקובץ אימג' גדול. | תלוי בגודל המודל. למודלים גדולים מאוד, כדאי להשתמש ב-Cloud Storage כדי לקבל ביצועים צפויים יותר אבל איטיים יותר. | יכול להיות שיהיו כמה עותקים ב-Artifact Registry. |
| אינטרנט | איטי. המודל הורד במהלך הפעלת המאגר. | בדרך כלל פשוט יותר (הרבה מסגרות מורידות מודלים ממאגרים מרכזיים). | בדרך כלל נמוכה ובלתי צפויה:
|
תלוי בספק האירוח של המודל. |
אחסון מודלים ב-Cloud Storage
כדי לייעל את הטעינה של מודלים של ML כשמטעינים מודלים של ML מ-Cloud Storage, באמצעות טעינת נפח של Cloud Storage או באמצעות Cloud Storage API או שורת פקודה, צריך להשתמש ב-Direct VPC עם הגדרת תעבורת נתונים יוצאת שמוגדרת לערך all-traffic, וגם ב-גישה פרטית ל-Google.
בתוספת עלות, אפשר להשתמש ב-Rapid 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
ברשימה הבאה מפורטים שיקולים שצריך לקחת בחשבון כשמתכננים את הפיתוח:
- בוחרים תמונה בסיסית טובה. מומלץ להתחיל עם תמונה מקונטיינרים של למידה עמוקה (Deep Learning) או ממאגר התמונות של NVIDIA לקונטיינרים, עבור מסגרת ה-ML שבה אתם משתמשים. התמונות האלה כוללות את חבילות הביצועים העדכניות ביותר. אנחנו לא ממליצים ליצור תמונה בהתאמה אישית.
- כדי למקסם את מספר הפעולות שמתבצעות בו-זמנית, מומלץ לבחור במודלים עם כימות של 4 ביט, אלא אם יש הוכחה לכך שהם משפיעים על איכות התוצאות. קוונטיזציה יוצרת מודלים קטנים ומהירים יותר, ומקטינה את כמות הזיכרון ב-GPU שנדרשת להפעלת המודל. היא גם יכולה להגדיל את המקביליות בזמן הריצה. מומלץ לאמן את המודלים בעומק הביט של היעד ולא לבצע קוונטיזציה כדי להגיע אליו.
- כדי לצמצם את זמן ההפעלה של הקונטיינר, כדאי לבחור פורמט מודל עם זמני טעינה מהירים, כמו GGUF. הפורמטים האלה משקפים בצורה מדויקת יותר את סוג הכימות של היעד, ונדרשים פחות טרנספורמציות כשמעלים אותם ל-GPU. מטעמי אבטחה, לא מומלץ להשתמש בנקודות ביקורת בפורמט pickle.
- יצירה של מטמון LLM וחימום שלו בזמן הבנייה. מפעילים את ה-LLM במכונת הבנייה בזמן בניית קובץ האימג' של Docker. כדאי להפעיל שמירה במטמון של הנחיות ולהזין הנחיות נפוצות או לדוגמה כדי לאכלס את המטמון לקראת שימוש בעולם האמיתי. שמירת הפלט שנוצר כדי לטעון אותו בזמן הריצה.
- שמירת מודל ההסקה שנוצר בזמן הבנייה. כך חוסכים זמן משמעותי בהשוואה לטעינת מודלים שמאוחסנים בצורה פחות יעילה ולהחלת טרנספורמציות כמו קוונטיזציה בהפעלת הקונטיינר.
בזמן הפריסה
הרשימה הבאה מציגה שיקולים שצריך לקחת בחשבון כשמתכננים את הפריסה:
- חשוב לוודא שהגדרתם את מספר הבקשות המקבילות לשירות בצורה מדויקת ב-Cloud Run.
- משנים את בדיקות ההפעלה בהתאם להגדרות.
בדיקות מוכנות להפעלה קובעות אם הקונטיינר הופעל ומוכן לקבל תנועה. כשמגדירים בדיקות מוכנות להפעלה, חשוב להביא בחשבון את הנקודות העיקריות הבאות:
- זמן הפעלה מספיק: צריך להקצות מספיק זמן כדי שהקונטיינר, כולל המודלים, יאותחל וייטען באופן מלא.
- אימות מוכנות המודל: מגדירים את הבדיקה כך שהיא תעבור רק כשהאפליקציה מוכנה למלא בקשות. הרבה מנועי הצגה משיגים את זה באופן אוטומטי כשהמודל נטען לזיכרון ה-GPU, וכך מונעים בקשות מוקדמות.
שימו לב: Ollama יכול לפתוח יציאת TCP לפני שנטען מודל. כדי לפתור את הבעיה:
טעינה מראש של מודלים: במאמרי העזרה של Ollama יש הוראות לטעינה מראש של המודל במהלך ההפעלה.
בזמן הריצה
- ניהול אקטיבי של חלון ההקשר הנתמך. ככל שחלון ההקשר קטן יותר, כך אפשר להריץ יותר שאילתות במקביל. הפרטים של אופן הביצוע תלויים במסגרת.
- משתמשים במטמוני ה-LLM שיצרתם בזמן ה-build. ספקו את אותם הדגלים שבהם השתמשתם משך זמן של תהליך build כשייצרתם את מטמון ההנחיות והקידומות.
- טוענים מהמודל השמור שכתבתם. במאמר היתרונות והחסרונות של אחסון וטעינה של מודלים יש השוואה בין האפשרויות לטעינת המודל.
- אם המסגרת שלכם תומכת במטמון של זוגות מפתח/ערך שעברו קוונטיזציה, כדאי להשתמש בו. הפעולה הזו יכולה להפחית את דרישות הזיכרון לכל שאילתה ולאפשר הגדרה של יותר מקביליות. עם זאת, זה יכול גם להשפיע על האיכות.
- כדאי לכוונן את כמות זיכרון ה-GPU שצריך לשריין למשקלי המודל, להפעלות ולמטמוני מפתח-ערך. כדאי להגדיר את הערך הכי גבוה שאפשר בלי לקבל שגיאה של חוסר זיכרון.
- כדאי לבדוק אם יש אפשרויות לשיפור הביצועים של הפעלת הקונטיינר (לדוגמה, שימוש בהעמסת מודלים במקביל).
- מגדירים את מספר הבקשות המקבילות בצורה נכונה בקוד השירות. מוודאים שקוד השירות מוגדר לעבודה עם הגדרות המקביליות של שירות Cloud Run.
ברמת עיצוב המערכת
- מוסיפים מטמון סמנטי במקומות המתאימים. במקרים מסוימים, שמירת מטמון של שאילתות ותשובות יכולה להיות דרך מצוינת להגביל את העלות של שאילתות נפוצות.
- שליטה בשונות בהקדמות. מטמון של הנחיות שימושי רק אם הוא מכיל את ההנחיות ברצף. המטמונים הם למעשה מטמונים של תחיליות. אם יש הוספות או עריכות ברצף, יכול להיות שהן לא נשמרו במטמון או שנשמרו רק באופן חלקי.
התאמה אוטומטית לעומס (autoscaling) ומעבדי GPU
אם משתמשים בהתאמה אוטומטית לעומס (autoscaling) ב-Cloud Run, מערכת Cloud Run משנה באופן אוטומטי את מספר המכונות של כל גרסה על סמך גורמים כמו ניצול המעבד (CPU) והבו-זמניות (concurrency) של הבקשות. עם זאת, ב-Cloud Run לא מתבצעת התאמה אוטומטית של מספר המכונות בהתאם לניצול ה-GPU.
אם יש לגרסה GPU, והשימוש ב-CPU לא משמעותי, Cloud Run מבצע הרחבה אופקית כדי לטפל בבקשות בו-זמנית. כדי להשיג קנה מידה אופטימלי של בקשות בו-זמניות, צריך להגדיר מספר מקסימלי אופטימלי של בקשות בו-זמניות לכל מופע, כפי שמתואר בקטע הבא.
מספר מקסימלי של בקשות בו-זמנית לכל מופע
ההגדרה maximum concurrent requests per instance (מספר מקסימלי של בקשות בו-זמנית לכל מופע) קובעת את המספר המקסימלי של בקשות ש-Cloud Run שולח למופע יחיד בו-זמנית. צריך לכוונן את מספר הבקשות המקבילות כך שיתאים למספר הבקשות המקבילות המקסימלי שהקוד בכל מופע יכול לטפל בהן עם ביצועים טובים.
מקסימום מקביליות ועומסי עבודה של AI
כשמריצים עומס עבודה של הסקת מסקנות מ-AI במעבד גרפי בכל מופע, רמת המקביליות המקסימלית שהקוד יכול להתמודד איתה בלי לפגוע בביצועים תלויה בפרטים ספציפיים של המסגרת וההטמעה. הגורמים הבאים משפיעים על ההגדרה האופטימלית של המספר המקסימלי של בקשות בו-זמניות:
- מספר המופעים של המודל שנטענו ב-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 צריכים להיות מוגדרים עם חיוב מבוסס-אינסטנס.