An OpenAI-compatible HTTP API server for PicoLM - an ultra-lightweight LLM inference engine.
PicoLM Server exposes PicoLM functionality over HTTP via an OpenAI-compatible REST API. This enables applications using OpenAI client libraries to seamlessly switch to local LLM inference with minimal code changes.
- OpenAI-compatible API - Works with existing OpenAI client libraries
- Streaming support - Real-time token streaming via SSE
- Tool calling - Function calling support for AI agents
- Lightweight - Minimal resource overhead (~8MB binary)
- Portable - Runs on Linux, macOS, Windows, ARM devices
- Go 1.21+
- PicoLM binary
- A GGUF model file (e.g., TinyLlama)
git clone https://github.com/wmik/picolm-server.git
cd picolm-server
go build -o picolm-server ./cmd/server/Download the latest binary from Releases
cp config.example.yaml config.yamlEdit config.yaml with your settings:
server:
host: "0.0.0.0"
port: 8080
api_key: "" # Optional: set an API key for authentication
picolm:
binary: "/path/to/picolm" # Path to picolm binary
models:
local: "/path/to/model.gguf" # Model name -> Path to GGUF model
max_tokens: 256
threads: 4
temperature: 0.7
top_p: 0.9
context_length: 2048./picolm-server -config config.yamlOr with Docker:
docker-compose up -dEndpoint: POST /v1/chat/completions
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "picolm-local",
"messages": [
{"role": "user", "content": "Hello!"}
],
"temperature": 0.7
}'Endpoint: GET /v1/models
curl http://localhost:8080/v1/modelsSet stream: true in your request for streaming responses:
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "picolm-local",
"messages": [{"role": "user", "content": "Count to 5"}],
"stream": true
}'Define tools in your request for function calling:
curl -X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "picolm-local",
"messages": [{"role": "user", "content": "What is the weather?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"]
}
}
}]
}'from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8080/v1",
api_key="dummy" # or your configured API key
)
response = client.chat.completions.create(
model="picolm-local",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://localhost:8080/v1',
apiKey: 'dummy'
});
const response = await client.chat.completions.create({
model: 'picolm-local',
messages: [{role: 'user', content: 'Hello!'}]
});
console.log(response.choices[0].message.content);package main
import (
"context"
"fmt"
openai "github.com/sashabaranov/go-openai"
)
func main() {
client := openai.NewClientWithConfig(openai.DefaultConfig("dummy"))
client.BaseURL = "http://localhost:8080/v1"
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: "picolm-local",
Messages: []openai.ChatCompletionMessage{
{Role: openai.ChatMessageRoleUser, Content: "Hello!"},
},
},
)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println(resp.Choices[0].Message.Content)
}make buildmake testmake lintmake runmake docker-build
make docker-composedocker-compose up --buildCreate config.yaml with Docker-specific paths:
server:
host: "0.0.0.0"
port: 8080
picolm:
binary: "/usr/local/bin/picolm"
models:
local: "/models/model.gguf"
timeout_seconds: 300
max_tokens: 256
threads: 4
temperature: 0.7
top_p: 0.9
logging:
level: "info"
format: "text"
output: "stdout"
log_requests: trueThe Docker image includes picolm but you need to provide a GGUF model file:
Option 1: Download during build
MODEL_URL=https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF/resolve/main/tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf \
docker-compose buildOption 2: Mount your own model
mkdir -p models
cp your-model.gguf models/model.gguf
docker-compose up| Argument | Default | Description |
|---|---|---|
MODEL_URL |
(none) | URL to download model from during build |
MODEL_NAME |
model.gguf |
Filename for downloaded model |
The Dockerfile automatically detects your architecture and builds picolm accordingly:
arm64→make piarm→make pi-arm32x86_64→make native
picolm-server/
├── cmd/server/main.go # Entry point
├── pkg/
│ ├── config/ # Configuration loading
│ ├── handlers/ # HTTP handlers
│ ├── picolm/ # PicoLM client (subprocess)
│ └── types/ # OpenAI API types
├── Dockerfile
├── docker-compose.yaml
├── Makefile
└── CONTRIBUTING.md
PicoLM is designed for ultra-lightweight inference:
| Metric | Value |
|---|---|
| Binary size | ~8MB |
| RAM usage | ~45MB |
| Startup time | <1s |
First token latency depends on your hardware and model size.
Tested with models that support ChatML format:
- TinyLlama
- Phi-2
- Qwen
- Other ChatML-fine-tuned models
MIT License - see LICENSE
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.