במדריך הזה נדגים איך להשתמש ב-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
- כדי להשתמש ב-Google Cloud CLI למשימה הזו, מתקינים ואז מאתחלים את ה-CLI של gcloud. אם התקנתם בעבר את ה-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 מנוהלת באופן מלא. אם תרחיש השימוש שלכם דורש יכולת התאמה גבוהה או אם אתם רוצים יותר שליטה על הגדרת האשכול, כדאי לבחור באשכול Standard. כדי לבחור את מצב ההפעלה של 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
}
}
(אופציונלי) התחברות לממשק הצ'אט
אתם יכולים להשתמש ב-Gradio כדי ליצור אפליקציות אינטרנט שמאפשרות לכם לקיים אינטראקציה עם המודל. Gradio היא ספריית Python שיש לה wrapper ChatInterface שיוצר ממשקי משתמש לצ'אטבוטים. במקרה של Llama 2 7B ו-Llama 3 7B, התקנתם את Gradio כשפרסתם את מודל ה-LLM.
מגדירים העברה ליציאה אחרת לשירות
gradio:kubectl port-forward service/gradio 8080:8080 &פותחים את http://localhost:8080 בדפדפן כדי לשוחח עם המודל.
הצגת כמה מודלים באמצעות ריבוב מודלים
Multiplexing מודלים היא טכניקה שמשמשת להכניס לשימוש בסביבת הייצור כמה מודלים באותו אשכול Ray. אפשר להפנות תעבורת נתונים למודלים ספציפיים באמצעות request header או באמצעות איזון עומסים.
בדוגמה הזו, יוצרים אפליקציית 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, לאפליקציה אחת. המודל הראשון הוא מודל העוזר הדיגיטלי שמשיב על שאלות שמופיעות בהנחיה. המודל השני הוא מודל הסיכום. הפלט של מודל העוזר הדיגיטלי משורשר לקלט של מודל הסיכום. התוצאה הסופית היא גרסה מסוכמת של התשובה מהמודל של העוזר הדיגיטלי.
פורסים את המשאב של 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 בצורה אופטימלית.
- אימון מודל עם GPUs במצב GKE Standard
- בקוד לדוגמה ב-GitHub מוסבר איך משתמשים ב-RayServe ב-GKE.