במדריך הזה נדגים איך לפרוס מודל שפה גדול (LLM) ולהכניס לשימוש בסביבת הייצור באמצעות כמה יחידות GPU ב-GKE, כדי להסיק מסקנות בצורה יעילה וניתנת להרחבה. אתם יוצרים אשכול GKE שמשתמש בכמה GPU ברמה L4 ומכינים תשתית להפעלת אחד מהמודלים הבאים:
מספר ה-GPU הנדרש משתנה בהתאם לפורמט הנתונים של המודל. במדריך הזה, כל מודל משתמש בשני מעבדי GPU מסוג L4. מידע נוסף זמין במאמר בנושא חישוב מספר ה-GPU.
המדריך הזה מיועד למהנדסי למידת מכונה (ML), לאדמינים ולאופרטורים של פלטפורמות ולמומחים בתחום הנתונים וה-AI שרוצים להשתמש ביכולות של Kubernetes לניהול קונטיינרים כדי להפעיל מודלים גדולים של שפה (LLM). מידע נוסף על תפקידים נפוצים ומשימות לדוגמה שמוזכרים בתוכן זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE. Google Cloud
לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את הנושאים הבאים:
מטרות
במדריך הזה תלמדו:
- ליצור אשכול ומאגרי צמתים.
- מכינים את עומס העבודה.
- פורסים את עומס העבודה.
- מנהלים אינטראקציה עם הממשק של ה-LLM.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
יש מודלים שנדרשות עבורם דרישות נוספות. חשוב לוודא שאתם עומדים בדרישות הבאות:
- כדי לגשת למודלים מ-Hugging Face, צריך להשתמש בטוקן של HuggingFace.
- למודל Mixtral 8x7b – מאשרים את התנאים של מודל Mistral Mixtral.
- למודל Llama 3 70b – מוודאים שיש לכם רישיון פעיל לשימוש במודלים של Meta Llama.
הכנת הסביבה
במסוף Google Cloud , מפעילים מכונת Cloud Shell:
פתיחת Cloud Shellמגדירים את משתני הסביבה שמוגדרים כברירת מחדל:
gcloud config set project PROJECT_ID gcloud config set billing/quota_project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export CONTROL_PLANE_LOCATION=us-central1מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud.
יצירת אשכול GKE ומאגר צמתים
אפשר להפעיל מודלים של שפה גדולה (LLM) במעבדי GPU באשכול GKE במצב Autopilot או במצב Standard. מומלץ להשתמש באשכול Autopilot כדי ליהנות מחוויית Kubernetes מנוהלת באופן מלא. כדי לבחור את מצב הפעולה של GKE שהכי מתאים לעומסי העבודה שלכם, אפשר לעיין במאמר בחירת מצב פעולה של GKE.
טייס אוטומטי
ב-Cloud Shell, מריצים את הפקודה הבאה:
gcloud container clusters create-auto l4-demo \ --project=${PROJECT_ID} \ --location=${CONTROL_PLANE_LOCATION} \ --release-channel=rapidGKE יוצר אשכול Autopilot עם צמתים של מעבד ו-GPU לפי הבקשה של עומסי העבודה שנפרסו.
מגדירים את
kubectlלתקשורת עם האשכול:gcloud container clusters get-credentials l4-demo --location=${CONTROL_PLANE_LOCATION}
רגילה
ב-Cloud Shell, מריצים את הפקודה הבאה כדי ליצור אשכול רגיל שמשתמש באיחוד זהויות של עומסי עבודה ל-GKE:
, צריך לבדוק באילו אזורים כרטיסי ה-GPU מדגם L4 זמינים.gcloud container clusters create l4-demo \ --location ${CONTROL_PLANE_LOCATION} \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --enable-image-streaming \ --node-locations=${CONTROL_PLANE_LOCATION}-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type n2d-standard-4 \ --num-nodes 1 --min-nodes 1 --max-nodes 5 \ --release-channel=rapidיצירת האשכול עשויה להימשך כמה דקות.
מריצים את הפקודה הבאה כדי ליצור מאגר צמתים עבור האשכול:
gcloud container node-pools create g2-standard-24 --cluster l4-demo \ --location ${CONTROL_PLANE_LOCATION} \ --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \ --machine-type g2-standard-24 \ --enable-autoscaling --enable-image-streaming \ --num-nodes=0 --min-nodes=0 --max-nodes=3 \ --node-locations ${CONTROL_PLANE_LOCATION}-a,${CONTROL_PLANE_LOCATION}-c \ --spotGKE יוצר את המשאבים הבאים עבור ה-LLM:
- אשכול Standard ציבורי.
- מאגר צמתים עם סוג מכונה
g2-standard-24שהוקטן ל-0 צמתים. לא תחויבו על יחידות GPU עד שתפעילו Pods שמבקשים יחידות GPU. מאגר הצמתים הזה מספק מכונות וירטואליות מסוג Spot, שהמחיר שלהן נמוך יותר מהמחיר של מכונות וירטואליות רגילות של Compute Engine, ואין עליהן הבטחה לזמינות. אפשר להסיר את הדגל--spotמהפקודה הזו, ואת בורר הצמתיםcloud.google.com/gke-spotבהגדרותtext-generation-inference.yamlכדי להשתמש במכונות וירטואליות לפי דרישה.
מגדירים את
kubectlלתקשורת עם האשכול:gcloud container clusters get-credentials l4-demo --location=${CONTROL_PLANE_LOCATION}
הכנת עומס העבודה
בקטע הזה מוסבר איך להגדיר את עומס העבודה בהתאם למודל שבו רוצים להשתמש. במדריך הזה נעשה שימוש בפריסות של Kubernetes כדי לפרוס את המודל. פריסה היא אובייקט Kubernetes API שמאפשר להפעיל כמה רפליקות של Pods שמפוזרות בין הצמתים באשכול.
Llama 3 70b
מגדירים את משתני הסביבה שמוגדרים כברירת מחדל:
export HF_TOKEN=HUGGING_FACE_TOKENמחליפים את
HUGGING_FACE_TOKENבאסימון שלכם ב-HuggingFace.יוצרים סוד של Kubernetes עבור טוקן HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -יוצרים את מניפסט הפריסה
text-generation-inference.yamlהבא:במניפסט הזה:
- הערך של
NUM_SHARDחייב להיות2כי המודל דורש שני מעבדי GPU מסוג NVIDIA L4. - הערך של
QUANTIZEמוגדר כ-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביט במקום ב-32 ביט. כך GKE יכול להקטין את כמות זיכרון ה-GPU שנדרשת ולשפר את מהירות ההסקה. עם זאת, רמת הדיוק של המודל עלולה לרדת. במאמר חישוב מספר ה-GPU מוסבר איך מחשבים את מספר ה-GPU שצריך לבקש.
- הערך של
החלת המניפסט:
kubectl apply -f text-generation-inference.yamlהפלט אמור להיראות כך:
deployment.apps/llm createdמאמתים את הסטטוס של המודל:
kubectl get deployהפלט אמור להיראות כך:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20mצפייה ביומנים מהפריסה הפעילה:
kubectl logs -l app=llmהפלט אמור להיראות כך:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Mixtral 8x7b
מגדירים את משתני הסביבה שמוגדרים כברירת מחדל:
export HF_TOKEN=HUGGING_FACE_TOKENמחליפים את
HUGGING_FACE_TOKENבאסימון שלכם ב-HuggingFace.יוצרים סוד של Kubernetes עבור טוקן HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -יוצרים את מניפסט הפריסה
text-generation-inference.yamlהבא:במניפסט הזה:
- הערך של
NUM_SHARDחייב להיות2כי המודל דורש שני מעבדי GPU מסוג NVIDIA L4. - הערך של
QUANTIZEמוגדר כ-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביט במקום ב-32 ביט. כך GKE יכול להקטין את כמות זיכרון ה-GPU שנדרשת ולשפר את מהירות ההסקה. עם זאת, יכול להיות שהפעולה הזו תפגע ברמת הדיוק של המודל. במאמר חישוב מספר ה-GPU מוסבר איך מחשבים את מספר ה-GPU שצריך לבקש.
- הערך של
החלת המניפסט:
kubectl apply -f text-generation-inference.yamlהפלט אמור להיראות כך:
deployment.apps/llm createdמאמתים את הסטטוס של המודל:
watch kubectl get deployכשהפריסה מוכנה, הפלט אמור להיראות כך:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10mכדי לצאת מהשעון, מקלידים
CTRL + C.צפייה ביומנים מהפריסה הפעילה:
kubectl logs -l app=llmהפלט אמור להיראות כך:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Falcon 40b
יוצרים את מניפסט הפריסה
text-generation-inference.yamlהבא:במניפסט הזה:
- הערך של
NUM_SHARDחייב להיות2כי המודל דורש שני מעבדי GPU מסוג NVIDIA L4. - הערך של
QUANTIZEמוגדר כ-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביט במקום ב-32 ביט. כך GKE יכול להקטין את כמות זיכרון ה-GPU שנדרשת ולשפר את מהירות ההסקה. עם זאת, רמת הדיוק של המודל עלולה לרדת. במאמר חישוב מספר ה-GPU מוסבר איך מחשבים את מספר ה-GPU שצריך לבקש.
- הערך של
החלת המניפסט:
kubectl apply -f text-generation-inference.yamlהפלט אמור להיראות כך:
deployment.apps/llm createdמאמתים את הסטטוס של המודל:
watch kubectl get deployכשהפריסה מוכנה, הפלט אמור להיראות כך:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10mכדי לצאת מהשעון, מקלידים
CTRL + C.צפייה ביומנים מהפריסה הפעילה:
kubectl logs -l app=llmהפלט אמור להיראות כך:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
יצירת שירות מסוג ClusterIP
חשיפת ה-Pods באופן פנימי בתוך האשכול כדי שאפליקציות אחרות יוכלו לגלות אותם ולגשת אליהם.
יוצרים את קובץ המניפסט
llm-service.yamlהבא:apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: llm type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 8080החלת המניפסט:
kubectl apply -f llm-service.yaml
פריסת ממשק צ'אט
אפשר להשתמש ב-Gradio כדי ליצור אפליקציית אינטרנט שתאפשר לכם לקיים אינטראקציה עם המודל. Gradio היא ספריית Python שיש לה ChatInterface wrapper שיוצר ממשקי משתמש לצ'אטבוטים.
Llama 3 70b
יוצרים קובץ בשם
gradio.yaml:החלת המניפסט:
kubectl apply -f gradio.yamlמוצאים את כתובת ה-IP החיצונית של השירות:
kubectl get svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125mמעתיקים את כתובת ה-IP החיצונית מהעמודה
EXTERNAL-IP.כדי להציג את ממשק המודל בדפדפן האינטרנט, משתמשים בכתובת ה-IP החיצונית עם היציאה שנחשפה:
http://EXTERNAL_IP
Mixtral 8x7b
יוצרים קובץ בשם
gradio.yaml:החלת המניפסט:
kubectl apply -f gradio.yamlמוצאים את כתובת ה-IP החיצונית של השירות:
kubectl get svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125mמעתיקים את כתובת ה-IP החיצונית מהעמודה
EXTERNAL-IP.אפשר לראות את ממשק המודל מדפדפן האינטרנט באמצעות כתובת ה-IP החיצונית עם היציאה שנחשפה:
http://EXTERNAL_IP
Falcon 40b
יוצרים קובץ בשם
gradio.yaml:החלת המניפסט:
kubectl apply -f gradio.yamlמוצאים את כתובת ה-IP החיצונית של השירות:
kubectl get svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125mמעתיקים את כתובת ה-IP החיצונית מהעמודה
EXTERNAL-IP.אפשר לראות את ממשק המודל מדפדפן האינטרנט באמצעות כתובת ה-IP החיצונית עם היציאה שנחשפה:
http://EXTERNAL_IP
חישוב מספר ה-GPU
מספר ה-GPU תלוי בערך של הדגל QUANTIZE. במדריך הזה, הערך של QUANTIZE מוגדר ל-bitsandbytes-nf4, כלומר המודל נטען ב-4 ביט.
מודל עם 70 מיליארד פרמטרים דורש זיכרון GPU בנפח 40GB לפחות, ששווה ל-70 מיליארד כפול 4 ביט (70 מיליארד x 4 ביט= 35GB), וכולל 5GB של תקורה. במקרה כזה, ל-GPU יחיד מסוג L4 לא יהיה מספיק זיכרון. לכן, בדוגמאות במדריך הזה נעשה שימוש ב-שני זיכרונות L4 GPU (2 x 24 = 48 GB). ההגדרה הזו מספיקה להרצת Falcon 40b או Llama 3 70b במעבדי GPU מסוג L4.
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.
מחיקת האשכול
כדי להימנע מחיובים בחשבון Google Cloud על המשאבים שיצרתם במדריך הזה, צריך למחוק את אשכול GKE:
gcloud container clusters delete l4-demo --location ${CONTROL_PLANE_LOCATION}