במדריך הזה נדגים איך לפרוס מודל שפה גדול (LLM) ולהכניס לשימוש בסביבת הייצור באמצעות כמה יחידות GPU ב-GKE, כדי להסיק מסקנות בצורה יעילה וניתנת להרחבה. אתם יוצרים אשכול GKE שמשתמש בכמה GPU ברמה L4 ומכינים תשתית להכניס לשימוש בסביבת הייצור אחד מהמודלים הבאים:
מספר ה-GPU הנדרש משתנה בהתאם לפורמט הנתונים של המודל. במדריך הזה, כל מודל משתמש בשני כרטיסי GPU מסוג L4. מידע נוסף זמין במאמר בנושא חישוב מספר מעבדי ה-GPU.
המדריך הזה מיועד למהנדסי למידת מכונה (ML), לאדמינים ולמפעילים של פלטפורמות, ולמומחים בתחום הנתונים וה-AI שרוצים להשתמש ביכולות של Kubernetes לארגון קונטיינרים כדי להציג מודלים גדולים של שפה (LLM). מידע נוסף על תפקידים נפוצים ומשימות לדוגמה שמוזכרים ב Google Cloudתוכן זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE.
לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את הנושאים הבאים:
מטרות
במדריך הזה תלמדו:
- יוצרים אשכול ומאגרי צמתים.
- מכינים את עומס העבודה.
- פריסת עומס העבודה.
- מבצעים אינטראקציה עם ממשק ה-LLM.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת 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כי המודל דורש שני מעבדי NVIDIA L4 GPU. - הערך של
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כי המודל דורש שני מעבדי NVIDIA L4 GPU. - הערך של
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כי המודל דורש שני מעבדי NVIDIA L4 GPU. - הערך של
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 לא יהיה מספיק זיכרון. לכן, בדוגמאות במדריך הזה נעשה שימוש ב-שני זיכרונות GPU מסוג L4 (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}