SmolLM3 3B
A 3B model trained for reasoning and multilingual use, small enough that a worker comes up in seconds.
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.
# 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=HuggingFaceTB/SmolLM3-3B \
MODEL_REVISION=a07cc9a04f16550a088caea529712d1d335b0ac1 \
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\" --enforce-eager"]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 }configVersion: 1
id: smollm3-3b
name: SmolLM3 3B
source:
type: container
compute:
gpuType: l40s
volumes:
- /weightsDeploying
Deploy it as it is, or take the files above and deploy your own copy. Nothing you change reaches back to this page.
runware serverless deploy --from https://runware.ai/docs/serverless/examples/smollm3-3b.ziprunware serverless deploy --container . \
--id smollm3-3b \
--gpu-type l40s \
--volume /weightsCalling 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: 'smollm3-3b',
endpointPath: 'v1/chat/completions',
payload: {
model: 'HuggingFaceTB/SmolLM3-3B',
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(
"smollm3-3b",
"v1/chat/completions",
{
"model": "HuggingFaceTB/SmolLM3-3B",
"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/smollm3-3b/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": "HuggingFaceTB/SmolLM3-3B",
"messages": [
{
"role": "user",
"content": "Name three uses for a serverless GPU."
}
]
}
}'cat <<'EOF' | runware serverless apps invoke smollm3-3b v1/chat/completions -f -
{
"model": "HuggingFaceTB/SmolLM3-3B",
"messages": [
{
"role": "user",
"content": "Name three uses for a serverless GPU."
}
]
}
EOF{
"taskId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"payload": {
"model": "HuggingFaceTB/SmolLM3-3B",
"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.