Skip to main content

Serve a model

Pick a model and AstroPulse serves it on your cluster: it sizes it, starts it, and tells you when it is ready to call. A generative model answers on the API most AI clients already speak. Every field has a default, and Check model says whether the model will serve before anything runs.

Before you start​

What a model needs depends on who calls it. Install add-ons from the cluster's Add-ons tab.

ToThe cluster needsYou also need
Serve it inside the clusterCertificates, then Model ServingNothing else for a public Hugging Face model
Call it from outside, on your domainAlso the Gateway. DNS Automation to publish its DNS record, or you create the recordA verified domain and an access policy, created under Integrations > Access Policies
Serve a gated or private modelThe same as aboveYour organization's Hugging Face token (Hugging Face), or read access to your bucket or registry (Private artifacts)

How these add-ons connect, and the settings for production: the AI inference blueprint.

In the console​

  1. Open Workloads > Models > Deploy model. Name the model and pick its cluster and profile.

  2. On the Model step, type part of a model's name and pick it from the Hugging Face list, or paste a URI from your own storage.

    Open zoom view

    The Model step with bge small typed and BAAI/bge-small-en-v1.5 first in the Hugging Face list

    The Model step with bge small typed and BAAI/bge-small-en-v1.5 first in the Hugging Face listThe Model step with bge small typed and BAAI/bge-small-en-v1.5 first in the Hugging Face list
  3. Select Check model. AstroPulse reads the model and answers whether it can serve it ("The platform can serve this model."), or says why not.

    Open zoom view

    The Check model result: The platform can serve this model.

    The Check model result: The platform can serve this model.The Check model result: The platform can serve this model.
  4. On Compute, keep the size AstroPulse chose, or pick a GPU and set memory. See Sizing and scaling.

  5. On Access, choose who can call it:

    • Internal only: workloads in the cluster call it. Nothing else to set.
    • On your domain: pick a verified domain and an access policy. The policy decides which callers the Gateway lets through, for example one API key per caller. No policy yet: create one under Integrations > Access Policies and return to this step. See Access policies and Expose a model.
    Open zoom view

    The Access step with a verified domain and an access policy picked

    The Access step with a verified domain and an access policy pickedThe Access step with a verified domain and an access policy picked
  6. Optional: on API, keep OpenAI-compatible as the API format, or pick another; it sets the endpoint's path (Expose a model). For vision, video and audio models, Media per request caps how many of each one request may carry.

    Open zoom view

    The API step with API format OpenAI-compatible and Media per request

    The API step with API format OpenAI-compatible and Media per requestThe API step with API format OpenAI-compatible and Media per request
  7. On Review, the dry run checks the manifest and says which runtime serves the model and how it scales. Then select Deploy.

    Open zoom view

    The Review step: the manifest, and the dry run passed with the runtime and scaling it chose

    The Review step: the manifest, and the dry run passed with the runtime and scaling it choseThe Review step: the manifest, and the dry run passed with the runtime and scaling it chose

You should see​

The model's page shows Running, its endpoint, live request numbers and the serving facts. Call it from code gives you the Python to call it.

Open zoom view

The model overview: Running, the runtime, the live request cards, the endpoint and the serving facts

The model overview: Running, the runtime, the live request cards, the endpoint and the serving factsThe model overview: Running, the runtime, the live request cards, the endpoint and the serving facts

If the model does not start, its page says why and what to do next. Every refusal and its fix: Operate a model.

Save download cost

Every new node downloads the model again, and on a private cluster those bytes go through the NAT gateway, which the cloud bills per GB. On an EKS cluster AstroPulse creates, a model at an s3:// address or an oci:// image in your ECR, in the cluster's region, skips that charge: see Cut model download cost.

Add what you need​

Each is optional, in any order.

If you wantRead
A model that is not public on Hugging FaceHugging Face
A model from your own bucket, registry or volumePrivate artifacts
It to run on a GPU, or hold more loadSizing and scaling
A public HTTPS endpoint, for chosen callers onlyExpose a model
To watch latency, tokens and queue depthOperate a model

Other ways in​

  • Nova: ask it in plain language, for example "serve BAAI/bge-small-en-v1.5 on prod-01".
  • SDK and API: the Python SDK and the API reference use the same manifest.

With astroctl​

The shortest manifest that serves a public Hugging Face model. Every other setting below has a default:

model.yaml
apiVersion: platform.astropulse.io/v1
kind: Application
spec:
name: "bge-embed"
profileName: "prod-inference"
source:
type: "Model"
model:
uri: "hf://BAAI/bge-m3"
Terminal
astroctl app apply -f model.yaml --dry-run # check it; deploys nothing
astroctl app apply -f model.yaml
astroctl app get bge-embed # what runs, defaults filled in

See the astroctl reference.

What it doesn't do​

  • Quotas, rate limits, metering and billing for your own customers are yours. The gateway checks who is calling; see Access policies.
  • Each model has its own hostname. Routing several models behind one /v1, or batching requests, belongs in your API layer.
  • Canary traffic, multi-node inference and custom serving runtimes: apply a raw InferenceService through the YAML source.
  • A release never rolls itself back. You choose a version in deploy history and apply it.
  • Cost is reported per model, not per token or per customer. See Cost and Metrics.

Settings​

name, profileName, namespace, and syncType behave exactly as they do for every other source, see the manifest overview. Below is everything under source.model.### Artifact and runtime

uriRequired

The model artifact. Always set. Pin it to fixed bytes so a rollback serves the same model. Can be corrected until the model has served, then fixed.

Accepts
hf://<org>/<repo>[:<revision>], s3://, gs://, pvc://<claim>/<path>, oci://, or an Azure Blob URL https://<account>.blob.core.windows.net/<container>/<path>. No credentials or query strings, except ?versionId= on s3:// and ?generation= on gs://.
format

The model format, which picks the serving runtime. Set it for any artifact that is not on Hugging Face. Fixed once the model has served.

Accepts
vLLM, SKLearn, XGBoost, LightGBM, TensorFlow, PyTorch, ONNX, TensorRT, Triton, MLflow, PMML, Paddle.
Default
vLLM for hf://; required otherwise
runtime.engine

Pins a serving runtime instead of letting format choose. Set it only to use a runtime of your own. Fixed once the model has served.

Accepts
vllm, triton, torchserve, tensorflow, sklearn, xgboost, lightgbm, mlserver, or the name of a serving runtime on the cluster
Default
chosen from format

Serving​

serving.apiFormat

The API the endpoint speaks. Set V2 when callers use the open inference protocol.

Accepts
OpenAI (served under /v1), V2 (/v2/models/<name>/infer)
Default
OpenAI for a generative model; a predictive model answers on /v1/models/<name>:predict
serving.maxContextTokens

The context window the runtime allocates for. Set it to save memory, and keep it at or below the model's own limit: above it, the model will not start.

Accepts
whole number, 1 or more
Default
the runtime's own default
serving.kvCacheSize

The memory the runtime reserves for its KV cache. Set it when a replica runs out of cache or memory. On CPU it comes out of resources.memory and must be smaller than it; on a GPU it is device memory per GPU.

Accepts
quantity, for example "2Gi"
Default
CPU: a quarter of resources.memory. GPU: the runtime sizes it from the device
Requests at onceserving.maxConcurrentRequests

The most requests one replica serves at once; further requests wait, and scaling on waiting requests counts them. Generative models only.

Accepts
1 to 1024
Default
CPU: two per CPU core of the replica. GPU: the runtime's own limit
serving.multimodal.maxImagesPerPrompt, maxVideosPerPrompt, maxAudioClipsPerPrompt

How many images, video clips or audio clips one request may carry. Set it for a vision, video or audio model on the vLLM runtime. Refused for a predictive model or a runtime AstroPulse did not install; a text-only model is not checked. Each limit costs memory on every replica; above 64 the dry run warns.

Accepts
whole number, 1 or more; set at least one
Default
the runtime's own limit per modality

Resources​

resources.cpu

CPU for one replica. Set it for CPU inference, where cores set the throughput.

Accepts
quantity above zero, for example "2" or "500m"
Default
3 per GPU for a generative model on GPUs; otherwise the runtime's own default
resources.memory

Memory for one replica: weights, runtime and KV cache. Raise it when a replica runs out of memory. A value below the default is a dry-run warning, not a refusal. It must also fit the node the replica runs on.

Accepts
quantity, for example "8Gi"
Default
generative model: 4Gi on CPU, 8Gi on a GPU. Predictive model: the runtime's own default
resources.accelerator.gpu.vendor

The GPU vendor. Set amd only for a runtime that runs on AMD GPUs; the vLLM runtime is NVIDIA only.

Accepts
nvidia, amd
Default
nvidia
resources.accelerator.gpu.model

The GPU model, in the same words a GPU node group uses. Set it to target one kind of GPU.

Accepts
l4, a10g, a100, h100, t4, v100 and the rest of the machine catalog
Default
none: any GPU of the vendor
resources.accelerator.gpu.countPerReplica

GPUs one replica needs. Setting it is what puts the model on a GPU. A replica runs on one node.

Accepts
1 to 64
Default
required with gpu; without accelerator the model runs on CPU
resources.accelerator.gpu.capacityType

How the replica's GPU node is bought. Set OnDemand for a model that must not restart, Spot to pay less and accept that the node can be reclaimed.

Accepts
  • OnDemand On-Demand Never runs the replica on Spot capacity; reserved capacity counts as on-demand.
  • Spot Spot Runs the replica on Spot capacity, which costs less but can be reclaimed at short notice.
  • Any Any Runs the replica on whatever GPU capacity the cluster offers.
Default

Any

Scaling and queueing​

scaling.minReplicas

The fewest replicas. Raise it to keep spare capacity warm.

Accepts
1 or more (scale to zero is not supported)
Default
1
scaling.maxReplicas

The most replicas. Set it above minReplicas to autoscale; equal, the model runs at that fixed count.

Accepts
1 or more, not below minReplicas
Default
minReplicas
scaling.metric

The signal replicas follow, with a target. Leave it out unless you need a different signal; it needs maxReplicas above minReplicas.

Accepts
exactly one of cpu (a whole percent, 1 to 100) or requestsWaiting (a positive number, generative models only, needs the workload-autoscaling add-on)
Default
none with equal bounds. With a range: requestsWaiting at 2 for a generative model on a cluster with the workload-autoscaling add-on; otherwise cpu at 80 on CPU, and no autoscaler on a GPU
queue.name

A ClusterQueue the cluster's workload-queueing add-on declares; replicas wait for its quota instead of pending. Set it when models share a quota. Fixed once the application exists.

Accepts
a queue name the add-on declares
Default
none: no queue

Weight cache​

cache.enabled

Keeps the weights on the node's disk so a restart reads them instead of downloading. Needs the weight cache on the cluster's model-serving add-on. Not for pvc:// or oci://.

Accepts
true, false
Default
false
cache.size

The artifact's size on disk, rounded up. A size larger than the node group's cache is refused.

Accepts
quantity above zero, for example "30Gi"
Default
required when the cache is enabled
cache.nodeGroup

The node group that holds the cached weights; every replica then runs there. Set it only when more than one cached node group could run the model.

Accepts
a node group the add-on caches on
Default
the one cached node group that can run the model

There is no field here for how a private artifact is read: an application carries no credential at all. See Private artifacts.

Next​