Deploy models to PAI and create inference services using high-level APIs from the PAI Python SDK.
How it works
The PAI Python SDK provides two high-level classes — pai.model.Model and pai.predictor.Predictor — to deploy models to Elastic Algorithm Service (EAS) and send inference requests.
All deployments follow the same four-step pattern:
Define the inference runtime in an
InferenceSpecobject (choose a built-in processor or a custom runtime image).Create a
Modelobject from theInferenceSpecand the path to your model artifacts.Call
model.deploy()to create an inference service in PAI. Specify the instance type, service name, and any other options.deploy()returns aPredictorobject. Call.predict()to send inference requests to the running service.
from pai.model import InferenceSpec, Model, container_serving_spec
from pai.image import retrieve, ImageScope
# Step 1: Retrieve a PAI-provided PyTorch inference runtime image.
torch_image = retrieve("PyTorch", framework_version="latest",
image_scope=ImageScope.INFERENCE)
# Step 2: Define the inference runtime using InferenceSpec.
inference_spec = container_serving_spec(
command="python app.py",
source_dir="./src/",
image_uri=torch_image.image_uri,
)
# Step 3: Create a Model object.
model = Model(
model_data="oss://<your-bucket>/path-to-model-artifacts",
inference_spec=inference_spec,
)
# Step 4: Deploy to PAI-EAS and get a Predictor.
predictor = model.deploy(
service_name="example_torch_service",
instance_type="ecs.c6.xlarge",
)
# Send an inference request.
result = predictor.predict(data=data)Prerequisites
Before you begin, make sure you have:
The PAI Python SDK installed
An OSS bucket containing your model artifacts, or a local model directory
An ECS instance type for the inference service (for example,
ecs.c6.xlarge)(Optional) A custom Docker image pushed to an Alibaba Cloud Container Registry (ACR) repository, if deploying with a custom runtime image
Configure InferenceSpec
pai.model.InferenceSpec defines how PAI runs your inference service. Choose between a built-in processor (simpler) or a custom runtime image (more flexible).
Use a built-in processor
A processor is a PAI abstraction that builds an inference service directly from your model artifacts, without writing any serving code. PAI provides built-in processors for common model formats including TensorFlow SavedModel, PyTorch TorchScript, XGBoost, LightGBM, and PMML. For the full list, see Built-in processors.
Pass the processor name as a string to InferenceSpec:
# TensorFlow processor.
tf_infer_spec = InferenceSpec(processor="tensorflow_cpu_2.3")
# PyTorch processor.
torch_infer_spec = InferenceSpec(processor="pytorch_cpu_1.10")
# XGBoost processor.
xgb_infer_spec = InferenceSpec(processor="xgboost")Configure additional service options — such as warm-up data or RPC settings — directly on the InferenceSpec instance:
# Path to warm-up data stored in OSS.
tf_infer_spec.warm_up_data_path = "oss://<your-oss-bucket>/path/to/warmup-data"
# Keep-alive duration (in milliseconds) for request connections.
tf_infer_spec.metadata.rpc.keepalive = 1000For all available service parameters, see JSON-based deployment.
Use a runtime image
For models or services with complex dependencies — or when you need full control over the serving environment — deploy using a custom Docker image instead of a processor.
Deploy from a pre-built image
Package your inference code and dependencies into a Docker image, push it to an ACR repository, then build an InferenceSpec from the image URI:
from pai.model import InferenceSpec, Model, container_serving_spec
container_infer_spec = container_serving_spec(
# URI of your custom Docker image.
image_uri="<your-custom-image-uri>",
# Port the service listens on inside the container. PAI routes prediction requests to this port.
port=8000,
environment_variables=environment_variables,
# Command to start the inference service.
command=command,
# Additional Python packages to install at startup.
requirements=[
"scikit-learn",
"fastapi==0.87.0",
],
)
m = Model(
model_data="oss://<your-oss-bucket>/path-to-tensorflow-saved-model",
inference_spec=container_infer_spec,
)
p = m.deploy(instance_type="ecs.c6.xlarge")Deploy from local code without building an image
The SDK can package and upload a local code directory automatically — no manual image build required. Specify source_dir in container_serving_spec(). The SDK uploads that directory to an OSS bucket and mounts it to /ml/usercode/ in the running container. The start command runs with /ml/usercode as the working directory.
from pai.model import InferenceSpec, container_serving_spec
inference_spec = container_serving_spec(
# Local directory containing your inference code.
# The SDK uploads it to OSS and mounts it at /ml/usercode/ in the container.
source_dir="./src",
# Runs with /ml/usercode as the working directory.
command="python run.py",
image_uri="<serving-image-uri>",
requirements=[
"fastapi",
"uvicorn",
],
)Mount additional data to the container
To load tokenizers, lookup tables, or other artifacts into the container at runtime, call InferenceSpec.mount():
# Upload a local directory to OSS and mount it at /ml/tokenizers/.
inference_spec.mount("./bert_tokenizers/", "/ml/tokenizers/")
# Mount data already stored in OSS to /ml/data/.
inference_spec.mount("oss://<your-oss-bucket>/path/to/data/", "/ml/data/")Retrieve PAI-provided runtime images
PAI publishes inference runtime images for TensorFlow, PyTorch, and XGBoost. Pass image_scope=ImageScope.INFERENCE to list_images() or retrieve() to get them:
from pai.image import retrieve, ImageScope, list_images
# List all PAI PyTorch inference images.
for image_info in list_images(framework_name="PyTorch", image_scope=ImageScope.INFERENCE):
print(image_info)
# Get a specific version (CPU).
retrieve(framework_name="PyTorch", framework_version="1.12", image_scope=ImageScope.INFERENCE)
# Get a GPU-accelerated image.
retrieve(framework_name="PyTorch", framework_version="1.12",
accelerator_type="GPU", image_scope=ImageScope.INFERENCE)
# Get the latest GPU image.
retrieve(framework_name="PyTorch", framework_version="latest",
accelerator_type="GPU", image_scope=ImageScope.INFERENCE)Deploy an inference service
Build a Model object from an InferenceSpec and the path to your model artifacts, then call .deploy(). The model_data parameter accepts an OSS URI or a local path — for a local path, the SDK uploads the artifacts to an OSS bucket automatically.
from pai.model import Model, InferenceSpec
from pai.predictor import Predictor
model = Model(
# OSS URI or local path to your model artifacts.
model_data="oss://<your-bucket>/path-to-model-artifacts",
inference_spec=inference_spec,
)
predictor = model.deploy(
# Name of the inference service.
service_name="example_xgb_service",
# ECS instance type for each service instance.
instance_type="ecs.c6.xlarge",
# Number of service instances.
instance_count=2,
# (Optional) Dedicated resource group. Defaults to the public resource group.
# resource_id="<your-eas-resource-group-id>",
options={
"metadata.rpc.batching": True,
"metadata.rpc.keepalive": 50000,
"metadata.rpc.max_batch_size": 16,
"warm_up_data_path": "oss://<your-oss-bucket>/path-to-warmup-data",
},
)For advanced deployment parameters, see JSON-based deployment.
model.deploy() parameters
| Parameter | Type | Description |
|---|---|---|
service_name | string | Name of the inference service |
instance_type | string | ECS instance type (e.g., ecs.c6.xlarge). Use "local" for local testing mode |
instance_count | int | Number of service instances |
resource_id | string | (Optional) Dedicated resource group ID. Defaults to the public resource group |
options | dict | Advanced service options (RPC batching, keep-alive, warm-up data path, and others) |
serializer | object | Serializer for prediction data. Defaults to the processor's built-in serializer |
resource_config | ResourceConfig | CPU and memory allocation per instance. Use instead of instance_type for fine-grained control |
Allocate resources by CPU and memory
To control CPU and memory per instance instead of using a predefined instance type, pass a ResourceConfig object:
from pai.model import ResourceConfig
predictor = model.deploy(
service_name="dedicated_rg_service",
# Each instance gets 2 CPU cores and 4,000 MB of memory.
resource_config=ResourceConfig(
cpu=2,
memory=4000,
),
)Invoke an inference service
model.deploy() returns a Predictor pointing to the newly created service. To connect to an existing service, construct a Predictor directly using the service name.
from pai.predictor import Predictor, EndpointType
# Connect to a service returned by deploy().
predictor = model.deploy(
instance_type="ecs.c6.xlarge",
service_name="example_xgb_service",
)
# Connect to an existing service by name.
predictor = Predictor(
service_name="example_xgb_service",
# By default, the service is accessed over the Internet.
# To access over a VPC network (client must run inside the VPC):
# endpoint_type=EndpointType.INTRANET,
)Send prediction requests
Use predict() for standard requests or raw_predict() for full HTTP control:
# Send a prediction request. Input and output are processed by the Serializer.
result = predictor.predict(data_in_nested_list)
# Send a raw HTTP request. Input and output are NOT processed by the Serializer.
response = predictor.raw_predict(
data=data_in_nested_list,
# path="predict", # Custom HTTP path. Defaults to "/".
# headers=dict(), # Custom request headers.
# method="POST", # HTTP method. Defaults to POST.
# timeout=30, # Request timeout in seconds.
)
# Access the response body and headers.
print(response.content, response.headers)
# Deserialize the response body from JSON.
print(response.json())Manage the service lifecycle
predictor.stop_service()
predictor.start_service()
predictor.delete_service()Serialize prediction data
When calling predictor.predict(), the SDK uses a Serializer to convert Python objects to bytes before sending the request, and to convert the HTTP response body back into a Python object.
predict(data=...) → serializer.serialize(data) → bytes → HTTP request body
HTTP response body → serializer.deserialize() → Python objectPAI provides built-in serializers for common use cases. Each built-in processor uses a matching serializer by default.
| Serializer | Default for | Input/output format |
|---|---|---|
JsonSerializer | XGBoost, PMML processors | JSON |
TensorFlowSerializer | TensorFlow processor | Protocol Buffers |
PyTorchSerializer | PyTorch processor | Protocol Buffers |
Custom (SerializerBase) | Any service | Any |
JsonSerializer
JsonSerializer serializes a numpy.ndarray or list to a JSON string and deserializes the response back to a Python object. XGBoost and PMML processors use JsonSerializer by default.
from pai.serializers import JsonSerializer
# Deploy with an explicit serializer (optional for XGBoost — it's the default).
p = Model(
inference_spec=InferenceSpec(processor="xgboost"),
model_data="oss://<your-oss-bucket>/path-to-xgboost-model"
).deploy(
instance_type="ecs.c6.xlarge",
serializer=JsonSerializer(),
)
# Or attach a serializer to an existing Predictor.
p = Predictor(
service_name="example_xgb_service",
serializer=JsonSerializer(),
)
result = p.predict([[2, 3, 4], [4, 5, 6]])TensorFlowSerializer
Use the PAI TensorFlow processor to deploy a TensorFlow SavedModel. The service exchanges data using Protocol Buffers. TensorFlowSerializer converts numpy.ndarray inputs to Protocol Buffers messages and deserializes responses back to numpy.ndarray. See tf_predict.proto for the message format.
The TensorFlow processor uses TensorFlowSerializer by default.
tf_predictor = Model(
inference_spec=InferenceSpec(processor="tensorflow_cpu_2.7"),
model_data="oss://<your-oss-bucket>/path-to-tensorflow-saved-model"
).deploy(
instance_type="ecs.c6.xlarge",
)
# Inspect the model's input/output signature.
print(tf_predictor.inspect_signature_def())
# Input: a dict where each key is an input signature name and each value is a numpy.ndarray.
tf_result = tf_predictor.predict(data={
"flatten_input": numpy.zeros(28 * 28 * 2).reshape((-1, 28, 28))
})
assert tf_result["dense_1"].shape == (2, 10)PyTorchSerializer
Use the PAI PyTorch processor to deploy a model in TorchScript format. The service uses Protocol Buffers for data exchange. PyTorchSerializer converts numpy.ndarray inputs to Protocol Buffers messages and deserializes responses back to numpy.ndarray. See pytorch_predict_proto for the message format.
The PyTorch processor uses PyTorchSerializer by default.
torch_predictor = Model(
inference_spec=InferenceSpec(processor="pytorch_cpu_1.10"),
model_data="oss://<your-oss-bucket>/path-to-torchscript-model"
).deploy(
instance_type="ecs.c6.xlarge",
)
# For multiple inputs, pass a list or tuple of numpy.ndarray objects.
torch_result = torch_predictor.predict(
data=numpy.zeros(28 * 28 * 2).reshape((-1, 28, 28))
)
assert torch_result.shape == (2, 10)Custom serializer
For services with non-standard data formats, implement a custom Serializer by inheriting from pai.serializers.SerializerBase and implementing serialize and deserialize.
The following example shows a NumpySerializer that exchanges data in NumPy's .npy binary format:
predict()receives anumpy.ndarrayorpandas.DataFrame.NumpySerializer.serialize()converts it to.npyformat and sends it in the request body.The server deserializes the
.npydata, runs inference, and returns the result in.npyformat.NumpySerializer.deserialize()converts the response back to anumpy.ndarray.
Test locally before deploying
For custom image deployments, run the inference service locally using Docker before deploying to PAI-EAS. Pass instance_type="local" to model.deploy(). The SDK starts a local container, downloads model artifacts from OSS, and mounts them automatically.
Local mode is only available for custom image deployments. Services deployed using a built-in processor do not support local mode.
from pai.predictor import LocalPredictor
local_predictor: LocalPredictor = model.deploy(
instance_type="local",
serializer=JsonSerializer(),
)
local_predictor.predict(data)
# Stop and remove the local Docker container.
local_predictor.delete_service()What's next
Train and deploy a PyTorch model using the PAI Python SDK — end-to-end example covering training and deployment
Built-in processors — full list of supported processors and model formats
JSON-based deployment — advanced service parameters
For the complete process of training and deploying a PyTorch model using the PAI Python SDK, see Train and deploy a PyTorch model using the PAI Python SDK.
For sample Notebooks demonstrating the deployment process, see Sample code.