במדריך הזה נדגים איך להשתמש ב-Ray ובתוסף Ray Operator כדי להפעיל מודלים גדולים של שפה (LLM) ב-Google Kubernetes Engine (GKE). המסגרת Ray מספקת פלטפורמת AI/ML מקצה לקצה לאימון, לאימון מדויק ולמסקנות של עומסי עבודה של למידת מכונה. Ray Serve הוא framework ב-Ray שאפשר להשתמש בו כדי להציג מודלים פופולריים של LLM מ-Hugging Face.
לפני שקוראים את המדריך הזה, חשוב לוודא שמכירים את המודל שרוצים להפעיל במדריך הזה. אפשר להשתמש בכל אחד מהמודלים הבאים:
הדף הזה מיועד למהנדסי למידת מכונה (ML) ולאדמינים ומפעילים של פלטפורמות שמנהלים עומסי עבודה של ML. מידע נוסף על תפקידים נפוצים ומשימות לדוגמה שאנחנו מתייחסים אליהם בתוכן של Google Cloud זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE.
המדריך הזה כולל את השלבים הבאים:
- יוצרים אשכול GKE במצב Autopilot או במצב Standard עם התוסף Ray Operator מופעל.
- פריסת משאב RayService שמוריד ומציג מודל שפה גדול (LLM) מ-Hugging Face.
- פריסת ממשק צ'אט ודיאלוג עם LLM.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את gcloud CLI. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- יוצרים חשבון ב-Hugging Face, אם עדיין אין לכ�� חשבון.
- מוודאים שיש לכם טוקן של Hugging Face.
- מוודאים שיש לכם גישה למודל Hugging Face שבו אתם רוצים להשתמש. בדרך כלל מקבלים את ההרשאה הזו על ידי חתימה על הסכם ושליחת בקשת גישה לבעלים של המודל בדף המודל ב-Hugging Face.
- חשוב לוודא שיש לכם מכסת GPU באזור
us-central1. מידע נוסף זמין במאמר בנושא מכסת GPU.
הכנת הסביבה
במסוף Google Cloud , מפעילים מכונת Cloud Shell:
פתיחת Cloud Shellמשכפלים את המאגר לדוגמה:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples/ai-ml/gke-ray/rayserve/llm export TUTORIAL_HOME=`pwd`מגדירים את משתני הסביבה שמוגדרים כברירת מחדל:
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export COMPUTE_REGION=us-central1 export CLUSTER_VERSION=CLUSTER_VERSION export HF_TOKEN=HUGGING_FACE_TOKENמחליפים את מה שכתוב בשדות הבאים:
-
PROJECT_ID: מזהה הפרויקט ב- Google Cloud. -
CLUSTER_VERSION: גרסת GKE לשימוש. הערך חייב להיות1.30.1או מאוחר יותר. -
HUGGING_FACE_TOKEN: טוקן הגישה שלכם ל-Hugging Face.
-
יצירת אשכול עם מאגר צמתים של GPU
אפשר להפעיל מודל שפה גדול (LLM) במעבדי GPU מסוג L4 עם Ray באשכול GKE Autopilot או באשכול רגיל באמצעות התוסף Ray Operator. באופן כללי, מומלץ להשתמש באשכול Autopilot כדי ליהנות מחוויית Kubernetes מנוהלת באופן מלא. אם תרחיש השימוש שלכם דורש יכולת הרחבה גבוהה או אם אתם רוצים יותר שליטה בהגדרת האשכול, כדאי לבחור באשכול רגיל. כדי לבחור את מצב הפעולה של GKE שהכי מתאים לעומסי העבודה שלכם, אפשר ל��יין במאמר בחירת מצב פעולה של GKE.
משתמשים ב-Cloud Shell כדי ליצור אשכול Autopilot או אשכול ר��יל:
טייס אוטומטי
יוצרים אשכול Autopilot עם התוסף Ray Operator:
gcloud container clusters create-auto rayserve-cluster \
--enable-ray-operator \
--cluster-version=${CLUSTER_VERSION} \
--location=${COMPUTE_REGION}
רגילה
יוצרים אשכול רגיל עם התוסף Ray Operator מופעל:
gcloud container clusters create rayserve-cluster \
--addons=RayOperator \
--cluster-version=${CLUSTER_VERSION} \
--machine-type=g2-standard-24 \
--location=${COMPUTE_ZONE} \
--num-nodes=2 \
--accelerator type=nvidia-l4,count=2,gpu-driver-version=latest
יצירת סוד של Kubernetes לפרטי הכניסה של Hugging Face
ב-Cloud Shell, יוצרים סוד של Kubernetes:
מגדירים את
kubectlלתקשורת עם האשכול:gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${COMPUTE_REGION}יוצרים סוד של Kubernetes שמכיל את הטוקן של Hugging Face:
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
פריסת מודל LLM
מאגר GitHub ששיבטתם כולל ספריה לכל מודל, שכוללת הגדרה של RayService. ההגדרה של כל מודל כוללת את הרכיבים הבאים:
- פריסת Ray Serve: פריסת Ray Serve, שכוללת הגדרת משאבים ותלות בזמן ריצה.
- מודל: מזהה המודל של Hugging Face.
קלאסטר Ray: קלאסטר Ray הבסיסי והמשאבים שנדרשים לכל רכיב, כולל Pods של ראש ושל עובד.
Gemma 2B IT
פריסת המודל:
kubectl apply -f gemma-2b-it/מחכים עד שהמשאב RayService יהיה מוכן:
kubectl get rayservice gemma-2b-it -o yamlהפלט אמור להיראות כך:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNINGבפלט הזה,
status: RUNNINGמציין שהמשאב RayService מוכן.מוודאים ש-GKE יצר את השירות לאפליקציית Ray Serve:
kubectl get service gemma-2b-it-serve-svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gemma-2b-it-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Gemma 7B IT
פריסת המודל:
kubectl apply -f gemma-7b-it/מחכים עד שהמשאב RayService יהיה מוכן:
kubectl get rayservice gemma-7b-it -o yamlהפלט אמור להיראות כך:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNINGבפלט הזה,
status: RUNNINGמציין שהמשאב RayService מוכן.מוודאי�� ש-GKE יצר את השירות לאפליקציית Ray Serve:
kubectl get service gemma-7b-it-serve-svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gemma-7b-it-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Llama 2 7B
פריסת המודל:
kubectl apply -f llama-2-7b/מחכים עד שהמשאב RayService יהיה מוכן:
kubectl get rayservice llama-2-7b -o yamlהפלט אמור להיראות כך:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNINGבפלט הזה,
status: RUNNINGמציין שהמשאב RayService מוכן.מוודאים ש-GKE יצר את השירות לאפליקציית Ray Serve:
kubectl get service llama-2-7b-serve-svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE llama-2-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Llama 3 8B
פריסת המודל:
kubectl apply -f llama-3-8b/מחכים עד שהמשאב RayService יהיה מוכן:
kubectl get rayservice llama-3-8b -o yamlהפלט אמור להיראות כך:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNINGבפלט הזה,
status: RUNNINGמציין שהמשאב RayService מוכן.מוודאים ש-GKE יצר את השירות לאפליקציית Ray Serve:
kubectl get service llama-3-8b-serve-svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE llama-3-8b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Mistral 7B
פריסת המודל:
kubectl apply -f mistral-7b/מחכים עד שהמשאב RayService יהיה מוכן:
kubectl get rayservice mistral-7b -o yamlהפלט אמור להיראות כך:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNINGבפלט הזה,
status: RUNNINGמציין שהמשאב RayService מוכן.מוודאים ש-GKE יצר את השירות לאפליקציית Ray Serve:
kubectl get service mistral-7b-serve-svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mistral-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
פרסום המודל
המודלים Llama2 7B ו-Llama3 8B משתמשים במפרט הצ'אט של OpenAI API. המודלים האחרים תומכים רק ביצירת טקסט, שהיא טכניקה ליצירת טקסט על סמך הנחיה.
הגדרת העברה ליציאה אחרת
מגדירים העברה ליציאה אחרת לשרת ההסקה:
Gemma 2B IT
kubectl port-forward svc/gemma-2b-it-serve-svc 8000:8000
Gemma 7B IT
kubectl port-forward svc/gemma-7b-it-serve-svc 8000:8000
Llama2 7B
kubectl port-forward svc/llama-7b-serve-svc 8000:8000
Llama 3 8B
kubectl port-forward svc/llama-3-8b-serve-svc 8000:8000
Mistral 7B
kubectl port-forward svc/mistral-7b-serve-svc 8000:8000
אינטראקציה עם המודל באמצעות curl
משתמשים ב-curl כדי לשוחח עם המודל:
Gemma 2B IT
בסשן חדש של מסוף:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Gemma 7B IT
בסשן חדש של מסוף:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Llama2 7B
בסשן חדש של מסוף:
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "meta-llama/Llama-2-7b-chat-hf",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
],
"temperature": 0.7
}'
Llama 3 8B
בסשן חדש של מסוף:
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "meta-llama/Meta-Llama-3-8B-Instruct",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
],
"temperature": 0.7
}'
Mistral 7B
בסשן חדש של מסוף:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
המודלים שמוצגים לא שומרים היסטוריה, ולכן כל הודעה ותשובה צריכות להישלח בחזרה למודל כדי ליצור חוויה של דיאלוג אינטראקטיבי. בדוגמה הבאה אפשר לראות איך יוצרים דיאלוג אינטראקטיבי באמצעות מודל Llama 3 8B:
יצירת דיאלוג עם המודל באמצעות curl:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Meta-Llama-3-8B-Instruct",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."},
{"role": "assistant", "content": " \n1. Java\n2. Python\n3. C++\n4. C#\n5. JavaScript"},
{"role": "user", "content": "Can you give me a brief description?"}
],
"temperature": 0.7
}'
הפלט אמור להיראות כך:
{
"id": "cmpl-3cb18c16406644d291e93fff65d16e41",
"object": "chat.completion",
"created": 1719035491,
"model": "meta-llama/Meta-Llama-3-8B-Instruct",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Here's a brief description of each:\n\n1. **Java**: A versatile language for building enterprise-level applications, Android apps, and web applications.\n2. **Python**: A popular language for data science, machine learning, web development, and scripting, known for its simplicity and ease of use.\n3. **C++**: A high-performance language for building operating systems, games, and other high-performance applications, with a focus on efficiency and control.\n4. **C#**: A modern, object-oriented language for building Windows desktop and mobile applications, as well as web applications using .NET.\n5. **JavaScript**: A versatile language for client-side scripting on the web, commonly used for creating interactive web pages, web applications, and mobile apps.\n\nNote: These descriptions are brief and don't do justice to the full capabilities and uses of each language."
},
"logprobs": null,
"finish_reason": "stop",
"stop_reason": null
}
],
"usage": {
"prompt_tokens": 73,
"total_tokens": 245,
"completion_tokens": 172
}
}
(אופציונלי) התחברות לממשק של Chat
אתם יכולים להשתמש ב-Gradio כדי ליצור אפליקציות אינטרנט שמאפשרות לכם ליצור אינטראקציה עם המודל. Gradio היא ספריית Python שיש לה wrapper ChatInterface שיוצר ממשקי משתמש לצ'אטבוטים. במקרה של Llama 2 7B ו-Llama 3 7B, התקנתם את Gradio כשפרסתם את מודל ה-LLM.
מגדירים העברה ליציאה אחרת לשירות
gradio:kubectl port-forward service/gradio 8080:8080 &פותחים את http://localhost:8080 בדפדפן כדי לשוחח עם המודל.
הצגת כמה מודלים באמצעות מודל מולטיפלקס
שילוב מודלים הוא טכניקה שמשמשת להצגת כמה מודלים באותו אשכול Ray. אפשר לנתב תנועה למודלים ספציפיים באמצעות כותרות בקשות או איזון עומסים.
בדוגמה הזו, יוצרים אפליקציית Ray Serve מרובת ערוצים שמורכבת משני מודלים: Gemma 7B IT ו-Llama 3 8B.
פורסים את המשאב RayService:
kubectl apply -f model-multiplexing/מחכים עד שהמשאב RayService יהיה מוכן:
kubectl get rayservice model-multiplexing -o yamlהפלט אמור להיראות כך:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T14:00:41Z" serveDeploymentStatuses: MutliModelDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment_1: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY status: RUNNINGבפלט הזה,
status: RUNNINGמציין שהמשאב RayService מוכן.מאשרים ש-GKE יצר את שירות Kubernetes לאפליקציית Ray Serve:
kubectl get service model-multiplexing-serve-svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-multiplexing-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45mמגדירים העברה ליציאה אחרת לאפליקציית Ray Serve:
kubectl port-forward svc/model-multiplexing-serve-svc 8000:8000שליחת בקשה למודל Gemma 7B IT:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: google/gemma-7b-it" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'הפלט אמור להיראות כך:
{"text": ["What are the top 5 most popular programming languages? Please be brief.\n\n1. JavaScript\n2. Java\n3. C++\n4. Python\n5. C#"]}שליחת בקשה למודל Llama 3 8B:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: meta-llama/Meta-Llama-3-8B-Instruct" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'הפלט אמור להיראות כך:
{"text": ["What are the top 5 most popular programming languages? Please be brief. Here are your top 5 most popular programming languages, based on the TIOBE Index, a widely used measure of the popularity of programming languages.\r\n\r\n1. **Java**: Used in Android app development, web development, and enterprise software development.\r\n2. **Python**: A versatile language used in data science, machine learning, web development, and automation.\r\n3. **C++**: A high-performance language used in game development, system programming, and high-performance computing.\r\n4. **C#**: Used in Windows and web application development, game development, and enterprise software development.\r\n5. **JavaScript**: Used in web development, mobile app development, and server-side programming with technologies like Node.js.\r\n\r\nSource: TIOBE Index (2022).\r\n\r\nThese rankings can vary depending on the source and methodology used, but this gives you a general idea of the most popular programming languages."]}שליחת בקשה למודל אקראי על ידי החרגת הכותרת
serve_multiplexed_model_id:curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'הפלט הוא אחד מהפלטים מהשלבים הקודמים.
הרכבת כמה מודלים באמצעות הרכבת מודלים
הרכבת מודלים היא טכניקה שמשמשת להרכבת כמה מודלים לאפליקציה אחת. הרכבת מודלים מאפשרת לכ�� לשרשר קלט ופלט בכמה מודלים גדולים של שפה (LLM) ולהרחיב את המודלים שלכם כאפליקציה אחת.
בדוגמה הזו, אתם מרכיבים שני מודלים, Gemma 7B IT ו-Llama 3 8B, לאפליקציה אחת. המודל הראשון הוא מודל העוזר הדיגיטלי שמשיב על שאלות שמופיעות בהנחיה. המודל השני הוא מודל הסיכום. הפלט של מודל ה-Assistant משורשר לקלט של מודל המסכם. התוצאה הסופית היא גרסה מסוכמת של התשובה מהמודל של העוזר הדיגיטלי.
פורסים את המשאב RayService:
kubectl apply -f model-composition/מחכים עד שהמשאב RayService יהיה מוכן:
kubectl get rayservice model-composition -o yamlהפלט אמור להיראות כך:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T14:00:41Z" serveDeploymentStatuses: MutliModelDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment_1: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY status: RUNNINGבפלט הזה,
status: RUNNINGמציין שהמשאב RayService מוכן.מוודאים ש-GKE יצר את השירות לאפליקציית Ray Serve:
kubectl get service model-composition-serve-svcהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-composition-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45mשליחת בקשה למודל:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What is the most popular programming language for machine learning and why?", "max_tokens": 1000}'הפלט אמור להיראות כך:
{"text": ["\n\n**Sure, here is a summary in a single sentence:**\n\nThe most popular programming language for machine learning is Python due to its ease of use, extensive libraries, and growing community."]}
מחיקת הפרויקט
- במסוף Google Cloud , נכנסים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
מחיקת המשאבים הבודדים
אם השתמשתם בפרויקט קיים ואתם לא רוצים למחוק אותו, אתם יכולים למחוק את המשאבים הבודדים.
מחיקת האשכול:
gcloud container clusters delete rayserve-cluster
המאמרים הבאים
- יכולות התזמור של פלטפורמת GKE מאפשרות להריץ עומסי עבודה של AI/ML בצורה אופטימלית.
- אימון מודל עם GPU במצב GKE Standard
- קוד לדוגמה ב-GitHub