Qwen3.5 4B

Small enough to keep a worker warm without the bill that usually implies.

Text generationl40sAlibabaApache-2.0Qwen/Qwen3.5-4B

What runs

This is the whole app. The entry names the model and what serves it, and the build turns that into these files: there is nothing else to write.

Dockerfile
# Generated from a declarative template. Nothing here asks for an integration:
# the platform reads the label the image carries and attaches its serving layer
# to the `vllm serve` below.
FROM vllm/vllm-openai:v0.28.0

ENV MODEL=Qwen/Qwen3.5-4B \
    MODEL_REVISION=851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a \
    MAX_MODEL_LEN=8192 \
    GPU_MEMORY_UTILIZATION=0.85 \
    HF_HOME=/weights \
    PORT=8080

EXPOSE 8080

ENTRYPOINT ["/bin/sh", "-c", \
  "exec vllm serve \"$MODEL\" --revision \"$MODEL_REVISION\" --port \"$PORT\" --max-model-len \"$MAX_MODEL_LEN\" --gpu-memory-utilization \"$GPU_MEMORY_UTILIZATION\""]
container.yaml
configVersion: 1

port: 8080

probes:
  readiness: /health
  liveness: /live

timeouts:
  requestSeconds: 300
  # The first boot pulls the weights into the volume. Later boots read them back.
  startupSeconds: 2400

endpoints:
  - path: v1/chat/completions
    input:
      type: object
      additionalProperties: false
      # The server requires both, and a schema that called `model` optional
      # would accept a request the server then answers with a 400.
      required: [model, messages]
      properties:
        model: { type: string }
        messages: { type: array }
        max_tokens: { type: integer }
        temperature: { type: number }
        top_p: { type: number }
        seed: { type: integer }
runware.yaml
configVersion: 1
id: qwen3-5-4b
name: Qwen3.5 4B
source:
  type: container
compute:
  gpuType: l40s
volumes:
  - /weights

Deploying

Deploy it as it is, or take the files above and deploy your own copy. Nothing you change reaches back to this page.

From a URL
runware serverless deploy --from https://runware.ai/docs/serverless/examples/qwen3-5-4b.zip
From a clone
runware serverless deploy --container . \
  --id qwen3-5-4b \
  --gpu-type l40s \
  --volume /weights

Calling it

One request that works, against the app you just deployed. The fields are the ones the entry declares above, and anything it does not declare is refused rather than ignored.

import { createClient } from '@runware/sdk'

const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })

const task = await client.invoke({
  appId: 'qwen3-5-4b',
  endpointPath: 'v1/chat/completions',
  payload: {
    model: 'Qwen/Qwen3.5-4B',
    messages: [
      {
        role: 'user',
        content: 'Name three uses for a serverless GPU.'
      }
    ]
  }
})
import asyncio
import os

from runware import Runware


async def main():
    client = Runware(api_key=os.environ["RUNWARE_API_KEY"])
    try:
        task = await client.invoke(
            "qwen3-5-4b",
            "v1/chat/completions",
            {
                "model": "Qwen/Qwen3.5-4B",
                "messages": [
                    {
                        "role": "user",
                        "content": "Name three uses for a serverless GPU."
                    }
                ]
            },
        )
    finally:
        await client.close()


asyncio.run(main())
curl https://api.serverless.runware.ai/v1/apps/qwen3-5-4b/invoke-async/v1/chat/completions \
  -H "Authorization: Bearer $RUNWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "taskId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "payload": {
      "model": "Qwen/Qwen3.5-4B",
      "messages": [
        {
          "role": "user",
          "content": "Name three uses for a serverless GPU."
        }
      ]
    }
  }'
cat <<'EOF' | runware serverless apps invoke qwen3-5-4b v1/chat/completions -f -
{
  "model": "Qwen/Qwen3.5-4B",
  "messages": [
    {
      "role": "user",
      "content": "Name three uses for a serverless GPU."
    }
  ]
}
EOF
{
  "taskId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "payload": {
    "model": "Qwen/Qwen3.5-4B",
    "messages": [
      {
        "role": "user",
        "content": "Name three uses for a serverless GPU."
      }
    ]
  }
}

What it costs

This entry is pinned to l40s, which is the card it was tested on rather than the only one it runs on: --gpu-typedeploys it somewhere else. You pay for that card by the second while a worker holds it, and for nothing else. Pricing covers what meters, and the rates are published per GPU-second.