Ollama and LM Studio
Phase 6 · Document 04 · Local Inference Prev: 03 — GGUF and llama.cpp · Up: Phase 6 Index
Table of Contents
- Why This Matters
- Core Concept
- Mental Model
- Hitchhiker's Guide
- Warmup Readings
- Deep Readings and External References
- Key Terms
- Important Facts
- Observations from Real Systems
- Common Misconceptions
- Engineering Decision Framework
- Hands-On Lab
- Verification Questions
- Takeaways
- Artifact Checklist
1. Why This Matters
llama.cpp is powerful but raw: you find GGUFs, pick quants, manage files, and remember flags. Ollama and LM Studio wrap that engine with model management, sensible defaults, and a drop-in OpenAI-compatible API so a developer goes from zero to a running local model in two commands. For 90% of development, prototyping, and low-concurrency internal tools, this is the right tool — and because the API is OpenAI-shaped, code you write against it also works against the cloud and against a gateway. Knowing exactly what these tools do (and where they stop — concurrency) lets you move fast locally without painting yourself into a corner.
2. Core Concept
Plain-English primer: what these tools add over llama.cpp
Both Ollama and LM Studio are convenience layers over a GGUF inference engine (Ollama uses its own llama.cpp-based engine; LM Studio bundles llama.cpp and an MLX runtime). They add the things you'd otherwise hand-roll:
- A model registry + downloader.
ollama pull llama3.2:3bfetches the right GGUF and remembers it; LM Studio has a search/browse GUI. No hunting Hugging Face for the correct quant file. - Automatic hardware setup. They detect your GPU/Metal and set offload (
-ngl) and threads for you — no flags to forget. - An OpenAI-compatible server. Both expose
/v1/chat/completions, so the OpenAI SDK works by just changingbase_url. - Sane defaults + config. Context length, chat template, stop tokens, and keep-alive are pre-wired per model.
Ollama: the developer default
curl -fsSL https://ollama.com/install.sh | sh # macOS: brew install ollama
ollama pull qwen2.5-coder:7b # download (a quant tag, e.g. :7b-q4_K_M)
ollama run qwen2.5-coder:7b "Refactor this loop." # interactive / one-shot
ollama list # what's installed
ollama ps # what's loaded in memory now
The server listens on http://localhost:11434, OpenAI-compatible at /v1:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama") # key required, ignored
r = client.chat.completions.create(
model="qwen2.5-coder:7b",
messages=[{"role":"user","content":"Write a binary search in Rust."}])
print(r.choices[0].message.content)
Model tags encode quant: llama3.1:8b (default quant, usually Q4_K_M), llama3.1:8b-instruct-q8_0 (explicit). A Modelfile customizes a model — base + system prompt + parameters — like a Dockerfile for models:
FROM qwen2.5-coder:7b
PARAMETER temperature 0.2
PARAMETER num_ctx 16384 # context length → sets KV cache memory [02]
SYSTEM "You are a terse senior Rust engineer."
ollama create rusty -f Modelfile && ollama run rusty
Two operational knobs to know: num_ctx (context length — directly drives KV memory, 02) and keep-alive (how long a model stays resident in memory after use; default a few minutes — set OLLAMA_KEEP_ALIVE or the keep_alive request field to avoid reload latency or to free memory sooner).
LM Studio: the GUI
LM Studio is a desktop app: search and download models (with a "will it fit your hardware?" indicator), a chat UI, per-model parameter sliders, and a Local Server tab that starts the same OpenAI-compatible endpoint. On Apple Silicon it can run MLX models too (05). It's ideal for non-CLI users, quick model comparison, and demos.
Where they stop: concurrency
Both are tuned for one or a few users. Under many concurrent requests, their batching is far weaker than vLLM's continuous batching (Phase 7). Ollama can serve a handful of parallel requests (OLLAMA_NUM_PARALLEL), but for production multi-tenant serving you graduate to vLLM/SGLang/TGI.
3. Mental Model
┌──────────────── CONVENIENCE LAYER ────────────────┐
│ Ollama (CLI/daemon) LM Studio (GUI) │
│ • pull/registry • search + fit check │
│ • auto -ngl/threads • chat UI + sliders │
│ • Modelfile (defaults) • Local Server tab │
│ • OpenAI API :11434/v1 • OpenAI API :1234/v1 │
└───────────────────────┬────────────────────────────┘
│ both sit on…
GGUF + llama.cpp engine (+ MLX in LM Studio) [03,05]
│
one/low concurrency ──(scale up)──► vLLM [Phase 7]
Mnemonic: Ollama/LM Studio = "Docker for local models" → OpenAI API on localhost. Great for dev; vLLM for crowds.
4. Hitchhiker's Guide
What to look for first: the OpenAI-compatible base URL (:11434/v1 Ollama, :1234/v1 LM Studio) and the model tag/quant. With those you can point any existing OpenAI code at a local model.
What to ignore at first: Modelfiles, custom system prompts, and parameter tuning — defaults are fine to start. Add a Modelfile once you need a fixed persona/params.
What misleads beginners:
- Assuming
num_ctxis unlimited. Ollama defaults context modestly (e.g., 4k–8k); long inputs get silently truncated unless you raisenum_ctx— and raising it costs KV memory (02). - Confusing the tag's quant.
:8bis a quantized default, not FP16 — fine, but know it. - Treating it as production-scale. It'll feel great at one user and fall over at fifty.
- Forgetting keep-alive. Models unload after idle → the next call eats a reload; or they stay resident and hold memory you wanted back.
How experts reason: they use Ollama/LM Studio as the fast local dev loop and the OpenAI-compatible seam that lets the same client hit local or cloud; they pin num_ctx to real need, set keep-alive deliberately, and switch to vLLM the moment concurrency matters.
What matters in production (if you do ship on it): low-concurrency internal tools only; pin the model version/quant, set num_ctx and OLLAMA_NUM_PARALLEL, monitor memory (KV growth), and put it behind a gateway for auth/limits (Phase 8).
How to debug/verify: ollama ps (loaded models + memory), curl /api/tags, check num_ctx vs your input length; garbage output → template/quant (08).
Questions to ask: What quant does this tag use? What's num_ctx? How many parallel requests can it take before latency degrades? Does it expose the metrics I need?
What silently gets expensive/unreliable: silent context truncation (lost input → worse answers), reload latency from keep-alive, and concurrency cliffs.
5. Warmup Readings
| Title | Why to read it | What to extract | Difficulty | Time |
|---|---|---|---|---|
| 03 — GGUF and llama.cpp | The engine underneath | what these wrap | Beginner | 25 min |
| 02 — RAM/VRAM/Unified | Why num_ctx costs memory | KV sizing | Beginner | 20 min |
| Phase 1.05 — Serving Terms | OpenAI-compatible API terms | endpoints, streaming | Beginner | 15 min |
| what-happens §1.G — agent loop | How clients call the API | base_url swap | Beginner | 10 min |
6. Deep Readings and External References
| Title | URL | Why it matters | Read first | Lab connection |
|---|---|---|---|---|
| Ollama docs | https://github.com/ollama/ollama/tree/main/docs | Commands, API, Modelfile | api.md, modelfile.md | This lab |
| Ollama OpenAI compatibility | https://github.com/ollama/ollama/blob/main/docs/openai.md | The /v1 surface | supported fields | SDK client |
| LM Studio docs | https://lmstudio.ai/docs | GUI + local server | local server, models | LM Studio lab |
| Ollama model library | https://ollama.com/library | Tags + quants | how tags map to quants | Model choice |
| Modelfile reference | https://github.com/ollama/ollama/blob/main/docs/modelfile.md | Customize defaults | PARAMETER, SYSTEM | Custom model |
7. Key Terms
| Term | Simple meaning | Technical meaning | Why it matters | Where it appears | How to use it |
|---|---|---|---|---|---|
| Ollama | Local model runner | llama.cpp-based daemon + registry + API | Fast dev loop | CLI :11434 | pull/run//v1 |
| LM Studio | GUI runner | Desktop app over llama.cpp/MLX | Non-CLI users | app :1234 | Search + local server |
| Model tag | Name:variant | name:size-quant | Pins quant | ollama list | Choose explicit quant |
| Modelfile | Model recipe | base+SYSTEM+PARAMETER | Fixed persona/params | ollama create | Bake defaults |
num_ctx | Context length | KV cache window | Truncation + memory | Modelfile/req | Set to real need [02] |
| keep-alive | Resident time | How long model stays in RAM | Reload latency vs memory | env/req | Tune deliberately |
| OpenAI-compatible | Same API shape | /v1/chat/completions | Drop-in clients | both | Swap base_url |
OLLAMA_NUM_PARALLEL | Parallel slots | Concurrent request handling | Concurrency limit | env | Raise within KV budget |
8. Important Facts
- Ollama and LM Studio wrap a GGUF/llama.cpp engine (03); LM Studio also runs MLX on Macs (05).
- Both expose OpenAI-compatible APIs (Ollama
:11434/v1, LM Studio:1234/v1) — change onlybase_url. - Model tags encode quant (
:8b≈ a Q4_K_M default); pick explicit tags for control. num_ctxsets context length and thus KV memory — too low silently truncates input (02).- keep-alive governs reload latency vs memory residency.
- They're tuned for low concurrency — production multi-user → vLLM (Phase 7).
- A Modelfile bakes base model + system prompt + parameters into a named model.
ollama psshows loaded models and their memory — your quick fit check.
9. Observations from Real Systems
- Ollama is the most common "first local model" experience and a frequent backend for desktop AI apps and BYOK setups (Phase 11).
- VS Code / IDE BYOK and many local-first tools point at Ollama's
:11434/v1precisely because it's OpenAI-shaped. - LM Studio's "fit" indicator operationalizes the memory math for non-experts.
- Gateways (LiteLLM/OpenRouter-style) treat an Ollama endpoint as just another OpenAI provider, enabling local↔cloud routing/fallback (Phase 8).
- Teams outgrow Ollama at the concurrency cliff and re-platform onto vLLM — a predictable, documented transition.
10. Common Misconceptions
| Misconception | Reality |
|---|---|
| "Ollama isn't 'real' — it's a toy" | It's llama.cpp with great DX; fine for dev + low-concurrency prod |
":8b is full precision" | It's a quantized default (≈Q4_K_M) |
| "Context is whatever I send" | num_ctx caps it; excess is truncated silently |
| "It auto-scales to many users" | Low concurrency; use vLLM to scale |
| "LM Studio is just a chat app" | It also runs a production-shaped OpenAI server |
| "Local API ≠ OpenAI code" | Both are OpenAI-compatible; same SDK works |
11. Engineering Decision Framework
PICK a convenience runner:
Non-CLI / want a GUI / model browsing → LM Studio
CLI / scripting / daemon / Modelfiles → Ollama
Mac + want MLX speed → LM Studio (MLX) or MLX direct [05]
Edge / embed in an app / no daemon → llama.cpp directly [03]
Many concurrent users / SLAs → vLLM / SGLang / TGI [Phase 7]
CONFIGURE:
- choose explicit quant tag (fit + quality) [02,06]
- set num_ctx to REAL context need (KV memory) [02]
- set keep-alive (latency vs memory)
- raise OLLAMA_NUM_PARALLEL only within KV budget
- front with a gateway for auth/limits in prod [Phase 8]
12. Hands-On Lab
Goal
Run the same model through Ollama's OpenAI-compatible API, customize it with a Modelfile, and demonstrate the num_ctx truncation trap.
Prerequisites
- Ollama installed; ~5 GB free for a 7B.
Setup
curl -fsSL https://ollama.com/install.sh | sh # macOS: brew install ollama
ollama pull qwen2.5-coder:7b
Steps
- Call via OpenAI SDK (
base_url="http://localhost:11434/v1"); confirm it works and time tokens/sec. - Inspect memory:
ollama pswhile a request runs — note resident size. - Make a Modelfile (system prompt +
temperature 0.2+num_ctx 16384),ollama create rusty -f Modelfile, run it. - Demonstrate truncation: create a model with
num_ctx 2048, send a 5,000-token document, and show the answer ignores the start (lost input). Re-create withnum_ctx 16384and show it now uses it. Tie the memory rise to 02. - Concurrency probe: fire 1 vs 8 parallel requests (set
OLLAMA_NUM_PARALLEL=8); record per-request latency degradation.
Expected output
Working SDK calls; a custom rusty model; a clear before/after of num_ctx truncation; a latency-vs-concurrency note.
Debugging tips
- 404/connection refused → daemon not running (
ollama serve) or wrong port. - Truncation persists →
num_ctxstill too small or set on the wrong (uncustomized) model.
Extension task
Repeat in LM Studio: download the model, start the Local Server, and call :1234/v1 with the same client.
Production extension
Put the Ollama endpoint behind a gateway with an API key and a budget, and add a cloud fallback model (Phase 8).
What to measure
tokens/sec, resident memory (ollama ps), truncation behavior vs num_ctx, latency vs concurrency.
Deliverables
- A client snippet hitting the local OpenAI API.
- A Modelfile + custom model.
- A
num_ctxtruncation demo writeup with the memory implication.
13. Verification Questions
Basic
- What do Ollama/LM Studio add on top of llama.cpp?
- What base URLs expose their OpenAI-compatible APIs?
- What does
num_ctxcontrol, and what happens if it's too small?
Applied 4. Write a Modelfile that pins a system prompt, temperature 0.1, and 32k context. What's the memory consequence? 5. You need local + cloud models behind one client. How do these tools make that trivial?
Debugging 6. Long documents give answers that ignore the beginning. Cause and fix. 7. First request after lunch is slow, later ones fast. Why?
System design 8. At what signal do you migrate an internal tool from Ollama to vLLM, and what changes?
Startup / product 9. Why is the OpenAI-compatible seam strategically valuable for a product that may switch between local and cloud models?
14. Takeaways
- Ollama/LM Studio = "Docker for local models" over GGUF/llama.cpp, with an OpenAI-compatible API.
- Swap only
base_urlto point existing OpenAI code at a local model. - Model tags encode quant; pick explicitly for fit + quality.
num_ctxsets context (and KV memory) — too small truncates silently (02).- Great for dev and low concurrency; scale to vLLM for many users.
15. Artifact Checklist
- A client snippet calling the local OpenAI-compatible endpoint.
- A Modelfile + a customized named model.
-
A
num_ctxtruncation demo with the memory note. - A latency-vs-concurrency measurement.
- A decision note: when you'd move to vLLM.
Up: Phase 6 Index · Next: 05 — MLX and Apple Silicon