Deploying OME-Based SGLang Inference Jobs
- The cluster scheduling components periodically report node and chip information.
- kubelet reports the number of chips on the node to the node object.
- Ascend Device Plugin reports chip memory and topology information.
For chips with on-chip memory, Ascend Device Plugin reports the chip memory status at startup, as described in the node-label description; it reports full-NPU information, uploading the chip's physical ID to device-info-cm; the total number of allocatable chips (allocatable), the number of allocated chips, and basic chip information (device ip and super_device_ip) are reported to the node for full-NPU scheduling.
- When a fault exists on a node, NodeD periodically reports the node health status and node hardware fault information to `node-info-cm`, and reports shared storage faults to ClusterD's public faults.After ClusterD reads the information in
device-info-cmandnode-info-cm, as well as the public fault information, it integrates the information intocluster-info-cm.The user submits an SGLang inference job based on the OME framework through kubectl or another deep learning platform. OME generates a sub-workload of
DeploymentorLeaderWorkerSet(LWS) based on the inference job configuration, and the corresponding sub-workload then generates multiple Pods for the inference service. For detailed descriptions ofDeploymentorLeaderWorkerSet, see the OME documentation.volcano-controller or
LeaderWorkerSetcreates the corresponding PodGroup for the job. For detailed descriptions of PodGroup, see the official open-source Volcano documentation. The PodGroup generation policy is as follows:Under the OME framework, there are two different types of PodGroup mapping methods:
For jobs where instances do not span nodes (
Deploymentscenario), aDeploymentrequiring NPUs created by OME contains all instances of one type (P/D), and the corresponding PodGroup is created and managed by volcano-controller. A single PodGroup manages all Pods of that type of instance, with one Pod corresponding to one inference instance.For jobs where instances span nodes (
LeaderWorkerSetscenario), aLeaderWorkerSetrequiring NPUs created by OME contains all instances of one type (P/D). When Volcano group scheduling is enabled, the LeaderWorkerSet creates a PodGroup for each inference instance, and these PodGroups are created and managed by theLeaderWorkerSetController. A single PodGroup manages all Pods of that instance, with multiple Pods belonging to the same PodGroup together forming one inference instance, and one PodGroup corresponding to one inference instance.
For SGLang inference job pods, volcano-scheduler selects appropriate nodes based on node memory, CPU, labels, and affinity. volcano-scheduler also selects appropriate nodes based on chip topology information, and writes the selected chip information and node hardware information to the pod's annotations.
When kubelet creates a container, for SGLang inference jobs deployed based on OME, it calls Ascend Device Plugin to mount chips. Ascend Device Plugin or volcano-scheduler writes chip and node hardware information to the pod's annotations. The Ascend Docker Runtime assists in mounting the corresponding resources.
Process Description
An OME-based SGLang inference job contains the Router pod (not requiring NPU resources) and inference instance pod. The inference instance pod is classified into the prefill instance pod and decode instance pod. OME generates different workloads based on different inference service configuration modes to create different inference instances, and the Router provides inference services for external systems in a unified manner. MindCluster cluster scheduling components are able to schedule workloads of OME's Deployment and LeaderWorkerSet inference jobs. LWS gang scheduling needs to be enabled in LeaderWorkerSet scenarios.
For detailed instructions, see the OME documentation and LWS documentation.
Figure 1 shows the procedure for using MindCluster cluster scheduling components to deploy OME-based SGLang inference jobs via commands.
Preparing a job YAML
Prepare for image creation as required, select a YAML file, and modify the YAML file.
The image preparation is complete. The SGLang inference image can be obtained from the SGLang documentation, and the MemFabric Hybrid dependency in the image can be obtained from MemFabric Hybrid.
An OME-based SGLang inference job can be started by Base Model, Serving Runtime, and Inference Service CRDs. For details about the resource usage and deployment of Base Model and Inference Service, see the OME documentation.
Various YAML examples of ClusterServingRuntime resources required by OME jobs are provided by cluster scheduling components. You can select an appropriate YAML example based on the used component, processor type, and job type, and make necessary modifications according to actual requirements before using it.
| Type | Hardware Model | YAML Name | Obtain Link |
|---|---|---|---|
| Instance not across nodes (Deployment scenario) | Atlas 800I A2 inference server Atlas 800I A3 SuperPoD server | llama-3-2-1b-instruct-rt-pd-standalone.yaml | Obtain YAML |
| Instance across nodes (LeaderWorkerSet scenario) | Atlas 800I A2 inference server Atlas 800I A3 SuperPoD server | llama-3-2-1b-instruct-rt-pd-distributed.yaml | Obtain YAML |
The above YAML examples are for testing purposes only. Modify them according to the actual situation of the model.
After the Base Model, Serving Runtime, and Inference Service YAML files are modified based on the OME framework deployment mode, OME and its components are responsible for starting the sub-workload (Deployment or LeaderWorkerSet) and the corresponding pods, and managing the lifecycle of inference service pods. After inference service pods are created, MindCluster schedules them.
The number of replicas for the job's P/D instance is configured by the Inference Service resource defined by OME. For specific configuration methods, see the OME documentation.
apiVersion: ome.io/v1beta1
kind: ClusterServingRuntime
metadata:
name: srt-llama-3-2-1b-instruct-distributed
spec:
decoderConfig:
annotations:
huawei.com/schedule_policy: "chip2-node16-sp"
sp-block: "16" #Configured only for the Atlas 800I A3 SuperPoD server scenario. The value is the total number of NPUs requested by the Pod corresponding to one P/D instance
huawei.com/schedule_minAvailable: "2" #Configured only when instances do not span nodes, i.e., in the Deployment scenario. The value is the number of replicas of the D instance (or the P instance in the engineConfig field)
huawei.com/recover_policy_path: "pod" #The path for job recovery when pod-rescheduling is "on". Setting it to "pod" indicates that if Pod-level rescheduling fails, it will not escalate to Job-level rescheduling. For OME jobs, in the Deployment scenario, each Pod in the PodGroup is an independent instance, so its fault handling must not propagate to other instances. In the LeaderWorkerSet scenario, restarting any Pod within a single PodGroup will cause the LeaderWorkerSet Controller to restart the entire PodGroup, triggering instance-level rescheduling
leader:
nodeSelector:
schedulerName: volcano #Set the scheduler to Volcano
runner:
name: sglang-decoder
image: "sglang:xxx"
command:
...
env:
...
- name: ASCEND_VISIBLE_DEVICES
valueFrom:
fieldRef:
fieldPath: metadata.annotations['huawei.com/Ascend910']
resources:
limits:
huawei.com/Ascend910: 16 #Configure based on the actual number of NPUs required per Pod
requests:
huawei.com/Ascend910: 16 #Configure based on the actual number of NPUs required per Pod
volumeMounts:
...
- name: driver
mountPath: /usr/local/Ascend/driver
...
volumes:
...
- name: driver
hostPath:
path: /usr/local/Ascend/driver
...
YAML Parameter Description
The following table describes only the fields related to MindCluster in the OME Serving Runtime YAML.
Table 1 YAML parameters
| Parameter | Value | Description |
|---|---|---|
| schedulerName | The value is "volcano". | Configures the scheduler as Volcano. |
| sp-block | Specifies the number of chips in a logical SuperPoD. It must be an integer multiple of the number of chips in a node, and the total number of chips in the P/D instances must be an integer multiple of it. | Specifies the sp-block field. The cluster scheduling component divides the physical SuperPoD into logical SuperPoDs based on the partitioning policy for affinity scheduling of jobs. If this field is not specified, Volcano uses the total number of NPUs configured for the job as the logical SuperPoD size during scheduling.
|
| huawei.com/schedule_minAvailable | Integer | The minimum number of replicas that can be scheduled for the job. This field must be specified in the Deployment scenario where instances do not span servers. Configure it to the effective number of replicas for the engine or decoder based on whether the field belongs to a P instance or D instance. This field is not required in other scenarios. |
| huawei.com/recover_policy_path | "pod" | The path for job recovery when pod-rescheduling is set to "on". Setting it to "pod" indicates that if pod-level rescheduling fails, it will not escalate to job-level rescheduling. For OME jobs, in the Deployment scenario, each Pod in a PodGroup is an independent instance, so fault handling must not propagate to other instances. In the LeaderWorkerSet scenario, restarting any Pod in a single PodGroup will cause the LeaderWorkerSet Controller to restart the entire PodGroup, triggering instance rescheduling. |
| pod-rescheduling |
| Pod-level rescheduling means that after a job fault occurs, not all job Pods in the PodGroup are deleted. Instead, only the faulty Pod is deleted, and the controller recreates a new Pod for rescheduling. Note: For OME inference jobs, this field must be set to "on". MindCluster reschedules the faulty P/D instances. |
| huawei.com/Ascend910 |
| The number of NPUs requested. Currently, only full-server scheduling is supported. Modify this value based on the actual number of hardware cards. |
| env[name==ASCEND_VISIBLE_DEVICES].valueFrom.fieldRef.fieldPath | The value is metadata.annotations['huawei.com/Ascend910'], which must be consistent with the actual chip type in the environment. | Ascend Docker Runtime obtains this parameter value to mount the corresponding type of NPU to the container. Note: This parameter only supports the full-card scheduling feature of the Volcano scheduler. Users who use static vNPU scheduling or other schedulers need to delete the related fields of this parameter in the example YAML. |
| fault-scheduling |
| - |
| fault-retry-times |
| - |
Submitting, Viewing, and Deleting an Inference Job
After completing the preparation of the job YAML file, you can perform the following operations:
- Deliver an inference job.
- View scheduling results.
- View the inference job running status.
- (Optional) Delete the job.
For detailed descriptions of the above steps, see the OME documentation.
If multiple associated inference jobs are deployed in the Kubernetes cluster, manually compiling and maintaining a large number of Kubernetes YAML files is inefficient and error-prone. To solve this problem, MindCluster provides an automatic script to replace complex manual operations. You only need to provide basic information, such as the application name, image version, and number of replicas, and the script automatically generates all necessary Kubernetes YAML files that comply with specifications and deploys them to the specified cluster. In addition, MindCluster provides an easy way, such as specifying a common application name, to remove all associated resources at once.
The current script only supports P/D disaggregation deployment, and can simultaneously launch multiple P/D instances, a Router, and a Memfabric_Store server.
- Python is installed in the environment, and dependency packages can be downloaded online.
- A KubeConfig file exists and can communicate normally with the K8s cluster.
- MindCluster and OME have been deployed.
- The Base Model and Serving Runtime resources have been deployed.
Obtain the source code from the mindcluster-deploy repository and navigate to the
k8s-deploy-tooldirectory.git clone https://gitcode.com/Ascend/mindcluster-deploy.git && cd mindcluster-deploy/k8s-deploy-tool(Optional) Create and activate a virtual Python environment. This operation allows different Python projects to use different library versions without interference.
python -m venv venv && source venv/bin/activateUse Python or Python3 according to the actual situation of the environment.
Install dependencies.
pip install -r requirements.txt(Optional) Deploy Serving Runtime (for testing only). You can deploy the corresponding Serving Runtime based on the job requirements.
kubectl apply -f example/ome-runtimes/xxx.yaml #Replace xxx.yaml with the actual selected Serving Runtime file nameEdit the user configuration file
config/isvc-config.yaml.Open the
config/isvc-config.yamlfile.vi config/isvc-config.yamlPress
ito enter insert mode, and modify the fields in the file according to the actual situation.Press
Esc, type:wq!, and pressEnterto save and exit editing.
(Optional) Create a namespace for the job.
xxxis the "app_namespace" set inconfig/isvc-config.yaml. Ifapp_namespaceisdefaultor not set, you can skip creating the namespace.kubectl create ns xxx(Optional) Set the serving framework type. Currently,
omeandaibrixare supported. If not set,omeis used by default.export SERVING_FRAMEWORK=omeDeploy the inference job.
python main.py deploy -c config/isvc-config.yamlUse Python or Python3 according to the actual situation of the environment. The parameter description is as follows:
-c, --config: configuration file path; required.-k, --kubeconfig: KubeConfig file path; optional. The default value is~/.kube/config.--dry-run: trial run (this parameter is not deployed actually, and is used to display the generated YAML file); optional.
Check the job running status.
python main.py status -n my-test -ns defaultThe parameter description is as follows:
-n, --app-name: App name; required.my-testisapp_name" set inconfig/isvc-config.yaml.-ns, --namespace: App namespace; optional. The default value isdefault.-k, --kubeconfig: KubeConfig file path; optional. The default value is~/.kube/config.
You can also use the kubectl command-line tool to view the job running status.
Open a new terminal window and run the following command on a node in the current K8s cluster to access the inference service. If the request returns successfully, the inference service has been deployed successfully.
curl --location 'http://<router-podip>:<router-port>/generate' --header 'Content-Type: application/json' --data '{ "text": "Who are you", "sampling_params": { "temperature": 0, "max_new_tokens": 20 }, "stream": true }'<router-podip>is the IP address of the Router Pod, which can be obtained using the following command.kubectl get pod -A -o wide<router-port>is the service port set for the Router in the Serving Runtime.
(Optional) Delete the inference job.
python main.py delete -n my-testUse Python or Python3 according to the actual situation of the environment. The parameter descriptions are as follows:
-n, --app-name: App name; required.-ns, --namespace: App namespace; optional. The default value isdefault.-k, --kubeconfig: KubeConfig file path; optional. The default value is~/.kube/config.
