Skip to content

Local LLMs

Liter-llm routes to any local inference engine that exposes an OpenAI-compatible API. Run models on your own hardware with zero cloud dependencies and no API key.

Provider Default URL Prefix Notes
Ollama http://localhost:11434/v1 ollama/ Most popular, easy setup
LM Studio http://localhost:1234/v1 lmstudio/ GUI-based, beginner-friendly
vLLM http://localhost:8000/v1 vllm/ High-throughput serving
llamafile http://localhost:8080/v1 llamafile/ Single-file executable

All of these providers are registered in the provider registry. LocalAI and llama.cpp are also built in with the localai/ and llamacpp/ prefixes. For any other OpenAI-compatible server, use a custom provider — register the prefix and base URL once, then route to it like any other provider.

All listed engines also support streaming via SSE and model listing via /v1/models. Tool calling, vision, and multimodal inputs work through the chat endpoint where the underlying model supports them.

Terminal window
# macOS / Linux
curl -fsSL https://ollama.ai/install.sh | sh
# Or via Homebrew
brew install ollama
Terminal window
ollama pull qwen2:0.5b
import asyncio
from liter_llm import create_client
from liter_llm._internal_bindings import ChatCompletionRequest
async def main() -> None:
# No API key needed for local providers
client = create_client(api_key="", base_url="http://localhost:11434/v1")
request = ChatCompletionRequest.from_json(
'{"model":"ollama/qwen2:0.5b","messages":[{"role":"user","content":"Hello!"}]}'
)
response = await client.chat(request)
print(response.choices[0].message.content)
asyncio.run(main())

Liter-llm uses the standard provider/model-name prefix convention for local providers, just like cloud providers:

ollama/llama3.2 -> Ollama running Llama 3.2
ollama/qwen2:0.5b -> Ollama running Qwen2 0.5B
lmstudio/my-model -> LM Studio
vllm/meta-llama/Llama-3 -> vLLM
llamafile/my-model -> llamafile

The prefix determines which base URL and configuration to use. The model name after the / is forwarded to the local server as-is.

All local providers support streaming responses via Server-Sent Events (SSE), identical to the cloud provider streaming interface:

async for chunk in client.chat_stream(
model="ollama/qwen2:0.5b",
messages=[{"role": "user", "content": "Hello!"}],
):
print(chunk.choices[0].delta.content, end="")

Several local providers support embedding models. Use the standard embeddings API:

response = await client.embed(
model="ollama/all-minilm",
input="The quick brown fox",
)
print(f"Dimensions: {len(response.data[0].embedding)}")

Popular local embedding models include all-minilm (384 dims), nomic-embed-text (768 dims), and mxbai-embed-large (1024 dims) on Ollama.

Ollama runs on port 11434 by default. No additional configuration is needed:

liter-llm.toml
api_key = ""
[[providers]]
name = "ollama"
base_url = "http://localhost:11434/v1"
model_prefixes = ["ollama/"]

LM Studio runs on port 1234 by default. Load a model in the LM Studio GUI, then use it:

liter-llm.toml
api_key = ""
[[providers]]
name = "lmstudio"
base_url = "http://localhost:1234/v1"
model_prefixes = ["lmstudio/"]

Start vLLM with the OpenAI-compatible server:

Terminal window
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3-8B \
--port 8000
liter-llm.toml
api_key = ""
[[providers]]
name = "vllm"
base_url = "http://localhost:8000/v1"
model_prefixes = ["vllm/"]

Start the llama.cpp server:

Terminal window
./llama-server -m model.gguf --port 8080
liter-llm.toml
api_key = ""
[[providers]]
name = "llamacpp"
base_url = "http://localhost:8080/v1"
model_prefixes = ["llamacpp/"]
Terminal window
docker run -p 8080:8080 localai/localai:latest
liter-llm.toml
api_key = ""
[[providers]]
name = "localai"
base_url = "http://localhost:8080/v1"
model_prefixes = ["localai/"]

Download and run a llamafile:

Terminal window
chmod +x llava-v1.5-7b-q4.llamafile
./llava-v1.5-7b-q4.llamafile --server --port 8080
liter-llm.toml
api_key = ""
[[providers]]
name = "llamafile"
base_url = "http://localhost:8080/v1"
model_prefixes = ["llamafile/"]

If your local provider runs on a non-default port or remote host, override the base URL when constructing the client:

from liter_llm import create_client
client = create_client(api_key="", base_url="http://192.168.1.100:9000/v1")

Or in liter-llm.toml:

api_key = ""
base_url = "http://192.168.1.100:9000/v1"

Run Ollama alongside the liter-llm proxy for a self-contained local setup:

docker-compose.local.yaml
services:
ollama:
image: ollama/ollama:latest
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
liter-llm:
image: ghcr.io/xberg-io/liter-llm:latest
ports:
- "4000:4000"
environment:
- LITER_LLM_API_KEY=""
volumes:
- ./liter-llm-proxy.toml:/etc/liter-llm/liter-llm-proxy.toml
depends_on:
- ollama
volumes:
ollama_data:

Example proxy config for local use:

liter-llm-proxy.toml
[server]
host = "0.0.0.0"
port = 4000
[[providers]]
name = "ollama"
base_url = "http://ollama:11434/v1"
model_prefixes = ["ollama/"]

Start the stack:

Terminal window
docker compose -f docker-compose.local.yaml up -d
# Pull a model into Ollama
docker exec -it $(docker compose -f docker-compose.local.yaml ps -q ollama) \
ollama pull qwen2:0.5b
# Chat via the proxy
curl http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "ollama/qwen2:0.5b", "messages": [{"role": "user", "content": "Hello!"}]}'
Error: connection refused (os error 111)

The local server is not running or is on a different port. Verify:

Terminal window
# Check if Ollama is running
curl http://localhost:11434/v1/models
# Check if the port is in use
lsof -i :11434
Error: model "llama3.2" not found

The model is not downloaded. Pull it first:

Terminal window
# Ollama
ollama pull llama3.2
# Check installed models
ollama list

Local models can be slow to load on first request (especially large models). Increase the timeout:

liter-llm.toml
timeout_secs = 300 # 5 minutes for initial model load

When running liter-llm in Docker and a local provider on the host:

  • Linux: Use http://host.docker.internal:11434/v1 or http://172.17.0.1:11434/v1
  • macOS/Windows: Use http://host.docker.internal:11434/v1
# liter-llm-proxy.toml (inside Docker)
[[providers]]
name = "ollama"
base_url = "http://host.docker.internal:11434/v1"
model_prefixes = ["ollama/"]
  • Ollama: Automatically uses GPU if available. Check with ollama ps.
  • vLLM: Pass --tensor-parallel-size N for multi-GPU.
  • llama.cpp: Use -ngl N to offload N layers to GPU.
  • LocalAI: Set GPU_LAYERS environment variable.