Quickstart
This walkthrough serves Qwen3-4B with a single docker run.
Complete the Prerequisites once before you start. If you plan to serve a larger model, check memory sizing first. For replicas and secrets, use Kubernetes instead.
Tip: Want to serve other models? Open the Intel® Software Catalog, find your model, and copy the
docker runfrom the Deployment tab. If your model is not in the catalog, use the base image — Deploy an image that isn't in the catalog.
1. Start the server — leave this terminal open
The first start downloads the model and can take several minutes. Leave this terminal open; this process is the server. Open a new terminal for step 2, and continue when the model is alive.
docker run --rm -p 8000:8000 \
--cap-add SYS_NICE \
--shm-size=2g \
intel/inference-xeon-qwen-qwen3-4b:0.1.0
--cap-add SYS_NICE— lets the engine pin memory to the CPU socket it is using.--shm-size=2g— Docker gives a container only 64 MiB of shared memory by default. The engine needs more than that to start, so without this flag the container exits.2gis enough.
This command downloads the model on every launch. To cache the weights instead, see Model caching.
You can also watch docker ps: STATUS goes from (health: starting) to (healthy).
If the model is gated
Gated models need a Hugging Face token. Llama and Gemma are gated; Qwen3-4B is not. Create a Read token and accept the license: Prerequisites, Hugging Face. Then copy the docker run from that model's Deployment tab in the Intel® Software Catalog. The example below is Llama 3.2 3B Instruct — replace <your-token> with the token you created.
docker run --rm -p 8000:8000 \
--cap-add SYS_NICE \
--shm-size=2g \
-e HF_TOKEN=<your-token> \
intel/inference-xeon-meta-llama-llama-3.2-3b-instruct:0.1.0
A token on the command line is saved in shell history. Security shows how to avoid that. This command also downloads the model on every launch; Model caching explains how to skip that wait.
2. New terminal — wait until it is alive, then chat
The first start can take several minutes while the weights download. Poll /health until you see It's alive, then send a Hello request. This image serves Qwen/Qwen3-4B, so you can use that id as-is — you do not need to copy one from /v1/models.
curl -sf http://localhost:8000/health && echo "It's alive — the model is listening. Say hello."
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "Qwen/Qwen3-4B",
"messages": [{"role": "user", "content": "Hello!"}]
}'
If /health never returns 200, turn up the logs and see Troubleshooting. Later starts skip the download once a cache mount is in place — Model caching.
3. Call it from Python
Point the OpenAI Python SDK at http://localhost:8000/v1. The server does not use api_key, but most clients still expect a non-empty string.
Save the following as hello.py and run python3 hello.py:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
resp = client.chat.completions.create(
model="Qwen/Qwen3-4B",
messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)
4. Call it from LangChain, LlamaIndex, LiteLLM, or Haystack
The container is an OpenAI-compatible endpoint. There is no Intel® client to install. Any framework that speaks the OpenAI API can call it — point it at http://localhost:8000/v1. The four below are the most common; they are examples, not a closed list.
| Framework | Where to set the base URL |
|---|---|
| LangChain | ChatOpenAI(base_url="http://localhost:8000/v1", ...) |
| LlamaIndex | OpenAILike(api_base="http://localhost:8000/v1", ...) |
| LiteLLM | openai/ model prefix + api_base |
| Haystack | OpenAIChatGenerator(api_base_url="http://localhost:8000/v1", ...) |
Full copy-paste examples, including api_key, are in Framework integrations. Keep the docker run terminal open; stopping the container also stops the endpoint.
5. Stream the reply
This is the same Hello request, with "stream": true. -N tells curl not to buffer. The rest of the pipeline prints only the words as they arrive, not a JSON object per token.
curl -N -s http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "Qwen/Qwen3-4B",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}' | awk -F '"content":"' 'NF>1 { split($2, a, "\""); printf "%s", a[1]; fflush() } END { print "" }'
Qwen3-4B may think out loud first; the greeting follows. That is the model, not a stalled stream.
The wire format (one data: JSON line per token) and the OpenAI SDK streaming loop are in the API.
Check the configuration without serving (optional)
dry-run prints the config and the vLLM command it would run, without loading weights:
docker run --rm \
--cap-add SYS_NICE \
intel/inference-xeon-qwen-qwen3-4b:0.1.0 \
dry-run --format json
--format can be json or yaml. For the other commands (serve, list-profiles, download-to-cache, detect-hardware), see the CLI.
Congratulations — you have the model running
The curl and code snippets above were only to confirm the endpoint. In a real app, keep using the same OpenAI-compatible client you use today.
From here you can:
- Change a setting: Environment variables
- Serve a different model: Intel® Software Catalog, Deploy an image that isn't in the catalog
- Stop re-downloading weights: Model caching
- Add tool calling, structured output, or metrics: API
- Fix a problem: Troubleshooting, FAQ
- Run replicas, secrets, and rolling updates: Deploy on Kubernetes