███████╗███████╗██████╗ ██████╗ ██╗ ██╗ ███╗ ███╗
╚══███╔╝██╔════╝██╔══██╗██╔═══██╗██║ ██║ ████╗ ████║
███╔╝ █████╗ ██████╔╝██║ ██║██║ ██║ ██╔████╔██║
███╔╝ ██╔══╝ ██╔══██╗██║ ██║██║ ██║ ██║╚██╔╝██║
███████╗███████╗██║ ██║╚██████╔╝███████╗███████╗██║ ╚═╝ ██║
╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝
ZeroLLM is a personal LLM backend control plane that runs open models on GPU EC2 instances and scales idle capacity down.
Current status:
- AWS orchestration, streaming inference, API key auth, model sync, and cluster state are implemented.
- Inference uses a Lambda Function URL with response streaming.
- GPU instances run
llama-server; some internal names still sayvLLM. - Google OAuth and the web UI are not implemented.
- Python 3.12+
uv- Docker for LocalStack E2E tests
- AWS SAM CLI for deploy/build commands
make setup-devmake test-unit
make test-e2eE2E tests use Docker/Testcontainers and skip when that environment is unavailable.
make validate
make buildAWS_REGION=ap-southeast-2 make deploymake deploy wraps scripts/deploy.sh. It can:
- select or build a GPU AMI from the Image Builder pipeline
- discover and pin GPU subnet/VPC parameters
- create/update the SAM stack
- upload
models.jsonandscripts/seed_models.py - trigger the CodeBuild model sync project
Common deploy variables:
STACK_NAME- defaultzerollmENVIRONMENT- defaultdevDEPLOY_DEFAULTS_FILE- default.zerollm/deploy-<region>-<stack>.envCFN_ROLE_ARN- CloudFormation execution role ARNAMI_BUILD_MODE=auto|latest|build- defaultautoGPU_AMI_ID,GPU_SUBNET_ID,GPU_VPC_ID- override auto-discoveryHF_TOKEN_SECRET_ARN- optional Secrets Manager ARN exposed asHF_TOKENto model syncSYNC_MODELS_ON_DEPLOY=0- skip model sync
After deploy, create an API key:
AWS_REGION=ap-southeast-2 make create-api-key EMAIL=you@example.comUse the StreamingApiUrl stack output as the OpenAI-compatible base URL:
https://<function-url-id>.lambda-url.<region>.on.aws/v1
Send API keys as:
Authorization: Bearer zllm-...
Supported routes:
POST /v1/responsesPOST /v1/chat/completionsGET /v1/models
First inference for a cold model currently returns a cold-start response and triggers scale-up; clients should retry after the suggested delay.
models.json is the default manifest. It pins Hugging Face revisions and GGUF filenames, then model sync uploads artifacts to the deployment model bucket and writes DynamoDB model rows.
Default models:
Qwen/Qwen3.8-27Bong6e.2xlargeQwen/Qwen3.5-4Bong5.xlarge
make setup- install runtime dependenciesmake setup-dev- install runtime and dev dependenciesmake test- run the default test targetmake test-unit- run unit testsmake test-e2e- run LocalStack/mock-server E2E testsmake validate- validate the SAM templatemake build- sync requirements and runsam buildmake deploy- deploy/update the AWS stackmake seed-models- seed model configsmake seed-models-upload- upload model files and seed configsmake create-api-key EMAIL=you@example.com- create an API keymake status- print cluster recordsmake logs- show EC2 health and instance logs via SSM
Add a provider in ~/.pi/agent/models.json:
{
"providers": {
"zerollm": {
"baseUrl": "https://<streaming-url>.lambda-url.<region>.on.aws/v1",
"api": "openai-completions",
"apiKey": "<zllm-key>",
"models": [
{ "id": "Qwen/Qwen3.5-4B", "contextWindow": 131072, "reasoning": true, "compat": { "thinkingFormat": "deepseek" } },
{ "id": "Qwen/Qwen3.8-27B", "contextWindow": 262144, "reasoning": true, "compat": { "thinkingFormat": "deepseek" } }
]
}
}
}Set the default in ~/.pi/agent/settings.json:
{
"defaultProvider": "zerollm",
"defaultModel": "Qwen/Qwen3.8-27B",
"defaultThinkingLevel": "medium"
}control_plane/core/- cloud-agnostic lifecycle and API logiccontrol_plane/backends/aws/- AWS backends and Lambda handlerscontrol_plane/backends/mock/- in-memory test backendsami/- GPU AMI Image Builder assetsscripts/- deploy, model sync, API key, status, and log helperstests/unit/- fast unit teststests/e2e/- LocalStack/mock-server E2E testsinfrastructure/- Terraform bootstrap for GitHub Actions AWS roles