This tutorial shows you how to deploy and serve
Qwen3-Coder-480B (Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8),
a Mixture-of-Experts coding model, on Google Kubernetes Engine (GKE). The deployment
uses multi-host TPU7x (Ironwood) accelerators and the
SGLang serving framework with
TorchTPU (torchtpu) and prefill-decode (PD) disaggregation.
In the deployment configuration that's described in this tutorial, you provision
two multi-host tpu7x-standard-4t node pools, each arranged in a 2x2x2
topology (eight TPU7x chips across two nodes per node pool, for a total of 16
TPU7x chips). You use the Kubernetes LeaderWorkerSet API to do the following:
- Run disaggregated multi-host prefill and decode servers on separate TPU7x slices with tensor parallelism and expert parallelism enabled.
- Route OpenAI-compatible requests through an SGLang disaggregation router.
Objectives
- Set up your GKE cluster and multi-host TPU7x node pools.
- Configure credentials and install the LeaderWorkerSet controller.
- Deploy the multi-host SGLang prefill, decode, and router workloads.
- Send an inference request to the SGLang router service.
- Run a serving benchmark workload.
- Clean up.
Costs
In this document, you use the following billable components of Google Cloud:
To generate a cost estimate based on your projected usage, use the [pricing calculator]((https://cloud.google.com/products/calculator).
When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, see Clean up.
Before you begin
- Install and initialize the
Google Cloud CLI, and install
kubectl. If you use Cloud Shell, both tools are preinstalled.
You need a Hugging Face access token to use this tutorial. You can sign up for a free account at Hugging Face. After you have an account, generate an access token:
- On the Welcome to Hugging Face page, click your account avatar and select Access tokens.
- On the Access tokens page, click Create new token.
- Select the Read token type and enter a name for your token.
- Your access token is displayed. Save the token in a safe place.
Enable the Kubernetes Engine API, Compute Engine API, Cloud TPU API, and Artifact Registry API in your Google Cloud project:
Ensure that your project has sufficient disk quota and external IP address quota in the region where your TPU capacity is located:
In the Google Cloud console, go to the Quotas & System Limits page.
Verify that you have at least 2,800 GiB of available Google Cloud Hyperdisk Balanced quota across the four 700 GiB ephemeral volumes that are used for model caching by the prefill and decode Pods.
Filter by In-use regional external IPv4 addresses and verify that you have sufficient IP address quota in your target region.
To get the permissions that you need to complete this tutorial, ask your administrator to grant you the following IAM roles on your project:
- Kubernetes Engine Admin (
roles/container.admin) - Compute Admin (
roles/compute.admin) - Service Account User (
roles/iam.serviceAccountUser)
For more information about granting roles, see Manage access to projects, folders, and organizations.
You might also be able to get the required permissions through custom roles or other predefined roles.
Ensure that your Compute Engine default service account has the following Identity and Access Management (IAM) roles on your project:
- Kubernetes Engine Default Node Service Account
(
roles/container.defaultNodeServiceAccount) - Artifact Registry Reader
(
roles/artifactregistry.reader)
Set up your environment variables
Export the environment variables that you use throughout this tutorial:
Replace the following:
YOUR_CLUSTER_NAME: the name of your GKE cluster.YOUR_PROJECT_ID: the ID of your Google Cloud project.YOUR_REGION: the region where you want to deploy your cluster, such asus-central1.YOUR_ZONE: the zone where you want to deploy your TPU7x node pools, such asus-central1-c.YOUR_RESERVATION_NAME: if you're using a reservation, the name of your TPU7x reservation.YOUR_HF_TOKEN: your Hugging Face access token.YOUR_SGLANG_TPU_IMAGE: if you're using a custom SGLang TorchTPU container image, the URI of your image; otherwise, the default SGLang TorchTPU image.
Create the GKE cluster
To create a GKE cluster in Standard mode and attach two multi-host TPU7x node pools for prefill and decode disaggregation, complete the following steps:
Create a regional GKE cluster that uses
e2-standard-4nodes for the default node pool, which provides sufficient CPU and memory resources for the LeaderWorkerSet controller and the SGLang disaggregation router:Create a high-throughput workload placement policy with a
2x2x2accelerator topology, which is required for multi-host TPU7x node pools:Create two multi-host TPU7x node pools (
tpu7x-pool-0andtpu7x-pool-1), each containing twotpu7x-standard-4tnodes (eight TPU7x chips in a2x2x2topology per node pool, for a total of 16 TPU7x chips):Instead of using a specific reservation, you can also create the node pools using Spot capacity or Flex-start VMs by passing the following flags:
- Spot VMs: replace
--reservation-affinity=specificand--reservation=${RESERVATION}with--spotto use Spot capacity. Instances using Spot capacity might take time to be created after the node pool is created, and they might be preempted during workload runs. - Flex-start VMs: replace
--num-nodes=2,--reservation-affinity=specific, and--reservation=${RESERVATION}with--flex-start,--enable-autoscaling,--num-nodes=0,--min-nodes=0, and--max-nodes=2to provision the node pool using the Flex-start consumption option. For more information, see Run a small batch workload with TPUs and Flex-start VMs.
- Spot VMs: replace
Configure
kubectlcredentials to communicate with your cluster:
Configure credentials and install LeaderWorkerSet
To prepare your cluster for the multi-host SGLang deployment, complete the following steps:
Create a Kubernetes Secret named
hf-secretto store your Hugging Face access token:Install the LeaderWorkerSet CustomResourceDefinition and controller on your cluster:
Deploy the multi-host SGLang server
The workload manifest (qwen3-coder-480b-multihost-disagg-v7x.yaml) defines the
following resources to coordinate disaggregated prefill and decode serving
across the two 2x2x2 TPU7x node pools:
- StorageClass (
hyperdisk-balanced-tpu): provisions ephemeral 700 GiB ReadWriteOnce volumes backed by Google Cloud Hyperdisk Balanced storage. Each of the four prefill and decode Pods mounts its own volume at/datato store the downloadedQwen/Qwen3-Coder-480B-A35B-Instruct-FP8checkpoint locally. - Prefill pool (
sglang-prefill-serviceandsglang-tpu-prefill): runs a LeaderWorkerSet ofsize: 2(one leader Pod and one worker Pod) pinned exclusively to one2x2x2TPU7x node pool (eight TPU chips, which provide 16 TensorCores). The LeaderWorkerSet uses theleaderworkerset.sigs.k8s.io/exclusive-topologyannotation set to"cloud.google.com/gke-nodepool". The Pods launchsglang.launch_serverwith the--disaggregation-mode=prefill,--tensor-parallel-size=16, and--ep-size=16flags, exposing HTTP port8000and bootstrap port8998. - Decode pool (
sglang-decode-serviceandsglang-tpu-decode): runs a LeaderWorkerSet ofsize: 2pinned to the second2x2x2TPU7x node pool (eight TPU chips, which provide 16 TensorCores). The LeaderWorkerSet launchessglang.launch_serverwith the--disaggregation-mode=decode,--tensor-parallel-size=16, and--ep-size=16flags. - Disaggregation router (
sglang-routerandsglang-service): runs a CPU Deployment that executes thesglang_router.launch_routermodule with the--pd-disaggregationflag and exposes a ClusterIP Service on port8000. The router directs prompts and coordinates KV cache transfer between thesglang-prefill-serviceandsglang-decode-serviceservices.
To deploy and monitor the multi-host SGLang servers, complete the following steps:
Download the workload manifest:
Alternatively, create a file named
qwen3-coder-480b-multihost-disagg-v7x.yamlwith the following content:Apply the workload manifest to your cluster:
Verify that the router, prefill, and decode Pods are created:
When all Pods are ready, the output is similar to the following:
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 40mMonitor the prefill and decode leader Pod logs until startup completes:
Initial model download, weight loading, and compilation take approximately 15 to 30 minutes on the first run.
If you're using preemptible capacity such as Spot capacity or Flex-start VMs, it might take longer after node pool creation for your TPU slice nodes to be created, and they might be preempted during workload runs. For more information, see Preemptible VM instances. To check whether your TPU slice nodes have been created, see Check the node's status and conditions.
Wait until both the prefill and decode leader Pod logs output the following message and
kubectl get podsshows1/1in theREADYcolumn for all Pods:The server is fired up and ready to roll!Open a second terminal session and forward local port
8000tosglang-service:Leave port forwarding running in this terminal session.
Send inference requests
Return to your first terminal session and send a chat completion request to the
/v1/chat/completions endpoint exposed by the SGLang router:
Run a benchmark workload
To benchmark the deployed Qwen3-Coder model using a 1,024-token input and
1,024-token output (1k/1k) workload from the sglang-router Pod, run the
following command:
Clean up
To avoid incurring additional ongoing charges to your Google Cloud account for the resources used in this tutorial, delete the following resources:
Delete the SGLang prefill, decode, and router workloads:
Delete the TPU7x node pools, the workload placement policy, and the GKE cluster:
What's next
- Learn more about SGLang.
- Learn more about TPU7x (Ironwood).
- Learn more about Cloud TPU.