במדריך הזה נסביר איך לפרוס את Qwen3-Coder-480B (Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8), מודל תכנות מסוג שילוב מומחים (MoE), ולהגיש אותו ב-Google Kubernetes Engine (GKE). הפריסה משתמשת במאיצי TPU7x (Ironwood) עם כמה מארחים ובמסגרת להצגת מודעות SGLang עם TorchTPU (torchtpu) ופירוק של prefill-decode (PD).
בתצורת הפריסה שמתוארת במדריך הזה, אתם מקצים שני מאגרי צמתים של tpu7x-standard-4t עם כמה מארחים, שכל אחד מהם מסודר בטופולוגיה של 2x2x2 (שמונה שבבי TPU7x בשני צמתים לכל מאגר צמתים, סה"כ 16 שבבי TPU7x). אתם יכולים להשתמש ב-Kubernetes LeaderWorkerSet API כדי:
- הפעלת שרתי מילוי מראש ופענוח מרובי-מארחים מפורקים בפרוסות TPU7x נפרדות, עם הפעלה של מקביליות טנזור ומקביליות מומחים.
- ניתוב בקשות שתואמות ל-OpenAI דרך נתב SGLang disaggregation.
מטרות
- מגדירים את אשכול ה-GKE ואת מאגרי הצמתים של TPU7x עם כמה מארחים.
- מגדירים את פרטי הכניסה ומתקינים את הבקר של LeaderWorkerSet.
- פורסים את עומסי העבודה של SGLang למילוי מראש, לפענוח ולניתוב בכמה מארחים.
- שולחים בקשת הסקה לשירות הנתב של SGLang.
- מריצים עומס עבודה להערכת ביצועים של מילוי בקשות.
- לפנות מקום.
עלויות
במסמך הזה משתמשים ברכיבים הבאים שלGoogle Cloud, והשימוש בהם כרוך בתשלום:
כדי ליצור הערכת עלויות בהתאם לשימוש החזוי, אתם יכולים להשתמש ב[מחשבון עלויות](https://cloud.google.com/products/calculator).
כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.
לפני שמתחילים
- מתקינים ומפעילים את Google Cloud CLI, ומתקינים את
kubectl. אם אתם משתמשים ב-Cloud Shell, שני הכלים מותקנים מראש.
כדי להשתמש במדריך הזה, אתם צריכים טוקן גישה ל-Hugging Face. אתם יכולים להירשם לחשבון בחינם ב-Hugging Face. אחרי שיוצרים חשבון, יוצרים אסימון גישה:
- בדף Welcome to Hugging Face, לוחצים על הדמות של החשבון ובוחרים באפשרות טוקן גישה.
- בדף טוקני גישה, לוחצים על יצירת טוקן חדש.
- בוחרים את סוג הטוקן Read ומזינים שם לטוקן.
- טוקן הגישה שלכם יוצג. שומרים את הטוקן במקום בטוח.
מפעילים את ממשקי ה-API הבאים בפרויקט ב- Google Cloud : Kubernetes Engine API, Compute Engine API, Cloud TPU API ו-Artifact Registry API.
מוודאים שבפרויקט יש מספיק מכסת דיסק ומכסת כתובות IP חיצוניות באזור שבו נמצאת קיבולת ה-TPU:
במסוף Google Cloud , נכנסים לדף Quotas & System Limits.
מוודאים שיש לכם מכסה פנויה של לפחות 2,800GiB ב-Google Cloud Hyperdisk Balanced, בארבעת הנפחים הזמניים של 700GiB שמשמשים לשמירת המודל במטמון על ידי ה-Pods למילוי מראש ולפענוח.
מסננים לפי In-use regional external IPv4 addresses ומוודאים שיש לכם מספיק מכסות של כתובות IP באזור היעד.
כדי לקבל את ההרשאות שדרושות להשלמת המדריך, בקשו מהאדמין להקצות לכם את התפקידים הבאים ב-IAM בפרויקט:
- אדמין ב-Kubernetes Engine (
roles/container.admin) - אדמין ב-Compute (
roles/compute.admin) - משתמש בחשבון שירות (
roles/iam.serviceAccountUser)
להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
מוודאים שלחשבון השירות שמוגדר כברירת מחדל ב-Compute Engine יש את התפקידים הבאים של ניהול זהויות והרשאות גישה (IAM) בפרויקט:
- חשבון השירות שמוגדר כברירת מחדל לצומת ב-Kubernetes Engine (
roles/container.defaultNodeServiceAccount) - קריאה ב-Artifact Registry
(
roles/artifactregistry.reader)
הגדרת משתני הסביבה
מייצאים את משתני הסביבה שבהם משתמשים במדריך הזה:
מחליפים את מה שכתוב בשדות הבאים:
-
YOUR_CLUSTER_NAME: השם של אשכול GKE. -
YOUR_PROJECT_ID: מזהה הפרויקט ב- Google Cloud. -
YOUR_REGION: האזור שבו רוצים לפרוס את האשכול, למשלus-central1. -
YOUR_ZONE: האזור שבו רוצים לפרוס את מאגרי הצמתים של TPU7x, למשלus-central1-c. -
YOUR_RESERVATION_NAME: אם אתם משתמשים בהזמנה, השם של ההזמנה של TPU7x. -
YOUR_HF_TOKEN: טוקן הגישה ל-Hugging Face. -
YOUR_SGLANG_TPU_IMAGE: אם אתם משתמשים בקובץ אימג' של קונטיינר SGLang TorchTPU בהתאמה אישית, ה-URI של קובץ האימג'. אחרת, קובץ האימג' של SGLang TorchTPU שמוגדר כברירת מחדל.
יצירת אשכול GKE
כדי ליצור אשכול GKE במצב Standard ולצרף שני מאגרי צמתים של TPU7x עם כמה מארחים לצורך הפרדה של מילוי מראש ופענוח, מבצעים את השלבים הבאים:
יוצרים אשכול GKE אזורי שמשתמש ב-
e2-standard-4צמתים למאגר הצמתים שמוגדר כברירת מחדל, שמספק מספיק משאבי מעבד (CPU) וזיכרון לבקר LeaderWorkerSet ולנתב הפירוק של SGLang:יוצרים מדיניות מיקום של עומסי עבודה עם תפוקה גבוהה וטופולוגיית מאיץ
2x2x2, שנדרשת למאגרי צמתים של TPU7x עם כמה מארחים:יוצרים שני מאגרי צמתים של TPU7x עם כמה מארחים (
tpu7x-pool-0ו-tpu7x-pool-1), שכל אחד מהם מכיל שני צומתיtpu7x-standard-4t(שמונה שבבי TPU7x בטופולוגיית2x2x2לכל מאגר צמתים, סה"כ 16 שבבי TPU7x):במקום להשתמש במקום שמור ספציפי, אתם יכולים גם ליצור את מאגרי הצמתים באמצעות קיבולת Spot או Flex-start VMs, על ידי העברת הדגלים הבאים:
- VM במודל Spot: מחליפים את
--reservation-affinity=specificואת--reservation=${RESERVATION}ב---spotכדי להשתמש בקיבולת של Spot. יכול להיות שייקח זמן ליצור מכונות שמשתמשות בקיבולת של Spot אחרי שמאגר הצמתים נוצר, ויכול להיות שהן יופקעו במהלך הרצת עומסי העבודה. - Flex-start VMs: מחליפים את
--num-nodes=2,--reservation-affinity=specificו---reservation=${RESERVATION}ב---flex-start,--enable-autoscaling,--num-nodes=0,--min-nodes=0ו---max-nodes=2כדי להקצות את מאגר הצמתים באמצעות אפשרות הצריכה Flex-start. מידע נוסף זמין במאמר הרצת עומס עבודה קטן של אצווה באמצעות יחידות TPU ומכונות וירטואליות מסוג Flex-start.
- VM במודל Spot: מחליפים את
מגדירים את פרטי הכניסה של
kubectlכדי לתקשר עם האשכול:
הגדרת פרטי כניסה והתקנת LeaderWorkerSet
כדי להכין את האשכול לפריסה של SGLang בכמה מארחים, מבצעים את הפעולות הבאות:
יוצרים סוד של Kubernetes בשם
hf-secretכדי לאחסן את טוקן הגישה של Hugging Face:מתקינים את ה-CustomResourceDefinition והבקר של LeaderWorkerSet באשכול:
פריסת שרת SGLang עם כמה מארחים
במניפסט של עומס העבודה (qwen3-coder-480b-multihost-disagg-v7x.yaml) מוגדרים המשאבים הבאים, כדי לתאם בין מילוי מראש מבוזר לבין פענוח של בקשות בשני מאגרי הצמתים של 2x2x2 TPU7x:
- StorageClass (
hyperdisk-balanced-tpu): מספק אמצעי אחסון זמניים של ReadWriteOnce בנפח 700 GiB המגובים על ידי אחסון Hyperdisk Balanced של Google Cloud. כל אחד מארבעת ה-Pods למילוי מראש ולפענוח טוען את אמצעי האחסון שלו ב-/dataכדי לאחסן באופן מקומי את נקודת הבדיקה שלQwen/Qwen3-Coder-480B-A35B-Instruct-FP8שהורדה. - Prefill pool (
sglang-prefill-serviceandsglang-tpu-prefill): מריץ LeaderWorkerSet שלsize: 2(פוד Leader אחד ופוד Worker אחד) שמוצמד באופן בלעדי למאגר צמתים אחד של2x2x2TPU7x (שמונה שבבי TPU, שמספקים 16 TensorCores). ה-LeaderWorkerSet משתמש בהערהleaderworkerset.sigs.k8s.io/exclusive-topologyשמוגדרת ל-"cloud.google.com/gke-nodepool". ה-Pods מופעלים ב-sglang.launch_serverעם הדגלים--disaggregation-mode=prefill,--tensor-parallel-size=16ו---ep-size=16, וחושפים את יציאת ה-HTTP8000ואת יציאת ה-bootstrap8998. - Decode pool (
sglang-decode-serviceandsglang-tpu-decode): מריץ LeaderWorkerSet שלsize: 2שמוצמד למאגר הצמתים השני של2x2x2TPU7x (שמונה שבבי TPU שמספקים 16 TensorCores). LeaderWorkerSet מפעיל אתsglang.launch_serverעם הדגלים--disaggregation-mode=decode,--tensor-parallel-size=16ו---ep-size=16. - נתב פירוק (
sglang-routerו-sglang-service): מריץ פריסת מעבד (CPU) שמפעילה את המודולsglang_router.launch_routerעם הדגל--pd-disaggregationוחושפת שירות ClusterIP ביציאה8000. הנתב מפנה את ההנחיות ומתאם את העברת המטמון של ה-KV בין השירותיםsglang-prefill-serviceו-sglang-decode-service.
כדי לפרוס את שרתי SGLang עם כמה מארחים ולעקוב אחריהם:
מורידים את המניפסט של עומס העבודה:
אפשר גם ליצור קובץ בשם
qwen3-coder-480b-multihost-disagg-v7x.yamlעם התוכן הבא:מחילים את המניפסט של עומס העבודה על האשכול:
מוודאים שהפודים של הנתב, המילוי מראש והפענוח נוצרו:
כשהפודים מוכנים, הפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE sglang-router-6d87cb8c7d-gv4wr 1/1 Running 0 39m sglang-tpu-decode-0 1/1 Running 0 40m sglang-tpu-decode-0-1 1/1 Running 0 40m sglang-tpu-prefill-0 1/1 Running 0 40m sglang-tpu-prefill-0-1 1/1 Running 0 40mעוקבים אחרי היומנים של Pod ה-Leader למילוי מראש ולפענוח עד לסיום ההפעלה:
ההורדה הראשונית של המודל, טעינת המשקלים וההידור נמשכים כ-15 עד 30 דקות בהפעלה הראשונה.
אם אתם משתמשים בקיבולת שניתנת להפסקה לפני הזמן, כמו קיבולת Spot או מכונות וירטואליות מסוג Flex-start, יכול להיות שיעבור יותר זמן אחרי יצירת מאגר הצמתים עד ליצירת הצמתים של פרוסת ה-TPU, ויכול להיות שהם יופסקו לפני הזמן במהלך הרצת עומסי העבודה. מידע נוסף זמין במאמר מכונות VM זמניות. כדי לבדוק אם נוצרו צומתי פרוסות ה-TPU, עיינו בקטע בדיקת הסטטוס והתנאים של הצומת.
מחכים עד שביומני ה-Pod הראשיים של המילוי מראש והפענוח תופיע ההודעה הבאה, ובעמודה
READYשל כל ה-Pods יופיע הערך1/1בשדהkubectl get pods:The server is fired up and ready to roll!פותחים סשן שני של טרמינל ומעבירים את היציאה המקומית
8000אלsglang-service:משאירים את ההעברה ליציאה אחרת פועלת בסשן הטרמינל הזה.
שליחת בקשות להסקת מסקנות
חוזרים לסשן הראשון בטרמינל ושולחים בקשה להשלמת צ'אט לנקודת הקצה (endpoint) של /v1/chat/completions שנחשפה על ידי הנתב של SGLang:
הרצת עומס עבודה להערכת ביצועים
כדי להשוות את המודל Qwen3-Coder שנפרס באמצעות עומס עבודה של קלט של 1,024 אסימונים ופלט של 1,024 אסימונים (1k/1k) מ-Pod של sglang-router, מריצים את הפקודה הבאה:
הסרת המשאבים
כדי להימנע מחיובים נוספים בחשבון Google Cloud על המשאבים שבהם השתמשתם במדריך הזה, מחקו את המשאבים הבאים:
מוחקים את עומסי העבודה של SGLang למילוי מראש, לפענוח ולניתוב:
מוחקים את מאגרי הצמתים של TPU7x, את המדיניות של מיקום עומסי העבודה ואת אשכול GKE: