TL;DR
To kommandoer, og du har en model kørende på localhost:11434 med et HTTP-API.
1curl -fsSL https://ollama.com/install.sh | sh # Linux2# macOS: brew install ollama3
4ollama run llama3.1:8b "Forklar quantization i tre sætninger"Prerequisites
- • Mindst 16 GB RAM — 8 GB rækker kun til de mindste modeller
- • Et GPU med 8 GB+ VRAM, eller en Apple Silicon-maskine med unified memory
- • 5-50 GB fri diskplads, afhængigt af hvor mange modeller du henter
- • Python 3.11+ hvis du vil bruge kodeeksemplerne
Hvornår lokalt giver mening
En lokal model er ikke en billigere udgave af en frontier-model. Den er et andet værktøj med andre egenskaber, og valget bør træffes på egenskaberne — ikke på prisen.
- Data må ikke forlade huset. Journaler, kontrakter, kildekode under NDA. Ingen udgående forbindelse betyder ingen databehandleraftale at forhandle.
- Høj volumen, lav kompleksitet. Klassificering, tagging, oversættelse af korte strenge. En 8B-model på egen GPU kører millioner af kald til strømprisen alene.
- Embeddings. Skal du indeksere 100.000 dokumenter, er lokale embeddings hurtigere og gratis. Se RAG-guiden for hvordan de bruges.
- Offline. Fly, laboratorier, feltarbejde, luftgapped netværk.
Omvendt: har du brug for lange kæder af ræsonnement, pålidelig tool use eller kode af produktionskvalitet, er en 8B-model ikke svaret. Forskellen er ikke marginal, den er kategorisk. Mange systemer ender derfor med begge dele — lokalt til volumen, API til det svære.
Step 1: VRAM-regnestykket
Det eneste tal der afgør om en model kan køre hos dig, er hvor meget hukommelse dens vægte fylder. Tommelfingerreglen for quantized modeller i Q4-format:
VRAM ≈ (antal parametre i milliarder × 0,55 GB) + KV-cache 8B model i Q4 ≈ 4,7 GB + kontekst 14B model i Q4 ≈ 8,2 GB + kontekst 70B model i Q4 ≈ 40 GB + kontekst
KV-cachen vokser med kontekstlængden og er den post folk glemmer. Et 32k-kontekstvindue kan lægge flere gigabyte oveni. Passer det hele ikke i VRAM, flytter Ollama en del af modellen til system-RAM, og gennemløbet falder typisk med en faktor 5-20. Det er ikke en fejl du får en fejlbesked for — det bliver bare pludselig ubrugeligt langsomt.
| Hukommelse | Realistisk modelstørrelse | Egner sig til |
|---|---|---|
| 8 GB | 3B, embedding-modeller | Klassificering, embeddings |
| 16 GB | 8B i Q4 | Chat, opsummering, ekstraktion |
| 24-32 GB | 14B i Q4, 8B i Q8 | Kodeassistance, RAG |
| 64 GB+ | 70B i Q4, MoE-modeller | Alt hvad lokalt kan bruges til |
Om quantization: Q4_K_M er standardvalget. Tabet i kvalitet er lille nok til at være svært at måle i praksis, og hukommelsesbesparelsen i forhold til fuld præcision er omtrent 4x. Q8 giver marginalt bedre svar til dobbelt pris. Under Q4 begynder modellen at lave faktuelle fejl den ikke lavede før.
Step 2: Vælg en model
1# Generalist — god balance mellem størrelse og evne2ollama pull llama3.1:8b3
4# Kode5ollama pull qwen2.5-coder:7b6
7# Åbne vægte fra OpenAI (kræver rigeligt med hukommelse)8ollama pull gpt-oss:20b9
10# Embeddings — små, hurtige, ingen chat11ollama pull nomic-embed-text12
13ollama list # hvad har du hentet14ollama ps # hvad kører lige nu, og hvor meget fylder detollama ps er den nyttigste kommando i hele værktøjet. Den viser om modellen ligger i GPU eller er faldet ned i CPU — og dermed om du er i den hurtige eller den langsomme verden.
Step 3: API'et
Ollama lytter på localhost:11434. Alt kan gøres med rå HTTP, hvilket gør det trivielt at kalde fra et hvilket som helst sprog.
1curl http://localhost:11434/api/chat -d '{2 "model": "llama3.1:8b",3 "stream": false,4 "messages": [5 {"role": "user", "content": "Hvad er forskellen på Q4 og Q8 quantization?"}6 ]7}'Fra Python, med den officielle klient:
1# pip install ollama2from ollama import Client3
4client = Client(host="http://localhost:11434")5
6response = client.chat(7 model="llama3.1:8b",8 messages=[9 {"role": "system", "content": "Du svarer kort og på dansk."},10 {"role": "user", "content": "Hvorfor er KV-cachen vigtig?"},11 ],12 options={13 "temperature": 0.3,14 "num_ctx": 8192, # kontekstvindue — koster VRAM15 "num_predict": 512, # maks. output-tokens16 },17)18
19print(response["message"]["content"])20
21# Streaming: samme kald med stream=True22for chunk in client.chat(model="llama3.1:8b", messages=[...], stream=True):23 print(chunk["message"]["content"], end="", flush=True)num_ctx er den option der oftest overrasker. Ollama sætter et konservativt standard-kontekstvindue, og hæver du det ikke, bliver lange prompts stiltiende afkortet. Er du i tvivl om hvorfor modellen "glemmer" starten af et dokument, er det næsten altid her fejlen ligger.
OpenAI-kompatibelt endpoint
Ollama eksponerer også et OpenAI-kompatibelt API. Det betyder at eksisterende kode ofte kan pege på localhost uden andre ændringer end base-URL'en — praktisk til at afprøve om en lokal model kan klare en opgave, før du bygger noget om.
1# pip install openai2from openai import OpenAI3
4client = OpenAI(5 base_url="http://localhost:11434/v1",6 api_key="ollama", # ignoreres, men klienten kræver en værdi7)8
9response = client.chat.completions.create(10 model="llama3.1:8b",11 messages=[{"role": "user", "content": "Skriv en regex til danske postnumre"}],12)13
14print(response.choices[0].message.content)Kompatibiliteten dækker chat, completions og embeddings. Den dækker ikke leverandørspecifikke funktioner — så et tool-use-flow bygget mod en bestemt udbyders API kan ikke uden videre flyttes hertil.
Step 4: Structured output
Skal svaret bruges af kode og ikke af et menneske, så bed om et skema frem for at bede modellen "svare med JSON". Ollama tvinger outputtet til at følge skemaet, og du slipper for parse-fejl og retry-løkker.
1from ollama import Client2
3client = Client()4
5schema = {6 "type": "object",7 "properties": {8 "sentiment": {"type": "string", "enum": ["positiv", "neutral", "negativ"]},9 "emner": {"type": "array", "items": {"type": "string"}},10 "haster": {"type": "boolean"},11 },12 "required": ["sentiment", "emner", "haster"],13}14
15response = client.chat(16 model="llama3.1:8b",17 messages=[{18 "role": "user",19 "content": "Klassificér: 'Serveren har været nede siden i morges. "20 "Vores kunder kan ikke logge ind.'",21 }],22 format=schema,23 options={"temperature": 0},24)25
26import json27print(json.loads(response["message"]["content"]))28# {'sentiment': 'negativ', 'emner': ['nedetid', 'login'], 'haster': True}Sæt temperature til 0 ved klassificering. Du vil have det samme svar hver gang på det samme input, ikke variation.
Step 5: Embeddings lokalt
Embedding-modeller er små — nomic-embed-text fylder omkring 270 MB — og de er det bedste argument for at køre lokalt overhovedet. En indeksering af 100.000 chunks er gratis og tager minutter i stedet for timer.
1from ollama import Client2
3client = Client()4
5def embed(texts: list[str]) -> list[list[float]]:6 """Embed en liste af tekster med en lokal model."""7 response = client.embed(model="nomic-embed-text", input=texts)8 return response["embeddings"]9
10vektorer = embed([11 "Python er et programmeringssprog",12 "JavaScript kører i browseren",13])14
15print(f"Dimension: {len(vektorer[0])}") # 768Vektorerne går derefter i en vector database. Valget mellem ChromaDB, Weaviate og Pinecone er gennemgået i sammenligningen, og hele pipelinen fra dokument til svar står i RAG-guiden.
Én regel er ufravigelig: den model der har embeddet dine dokumenter, skal også embedde forespørgslerne. Skifter du embedding-model, er hele indekset ugyldigt og skal bygges forfra. Vektorerne fra to forskellige modeller ligger i hver deres rum, og afstanden mellem dem betyder ingenting.
Step 6: Egne modelvarianter
En Modelfile pakker systemprompt og parametre sammen med en eksisterende model, så konfigurationen ikke skal gentages i hvert kald:
1FROM llama3.1:8b2
3PARAMETER temperature 0.24PARAMETER num_ctx 163845
6SYSTEM """7Du er en dansk teknisk assistent for udviklere.8Svar kort. Vis kode frem for at forklare kode.9Er du usikker, så sig det — gæt ikke på API-signaturer.10"""1ollama create dansk-dev -f Modelfile2ollama run dansk-dev "Hvordan læser jeg en JSON-fil i Python?"Production-noter
- Hold modellen varm. Ollama frigiver hukommelsen efter få minutters inaktivitet, og næste kald betaler indlæsningstiden igen. Sæt
OLLAMA_KEEP_ALIVE=-1på en server der skal svare hurtigt. - Parallelle kald koster hukommelse.
OLLAMA_NUM_PARALLELstyrer samtidighed, men hver samtidig session har sin egen KV-cache. Fire parallelle sessioner med langt kontekstvindue kan sagtens fylde mere end selve modellen. - Bind ikke til 0.0.0.0 uden videre. Ollama har ingen autentificering. Skal den nås udefra, skal der en proxy med adgangskontrol foran.
- Lås modelversionen. Skriv
llama3.1:8b, ikkellama3.1. Et tag der flytter sig under dig, ændrer opførslen uden at der er ændret en linje kode.
Common pitfalls
- Modellen falder ned i CPU. Tjek
ollama ps. Står der en CPU-andel, har du valgt en for stor model eller et for stort kontekstvindue. - Standardkonteksten er lille. Sæt
num_ctxeksplicit, ellers bliver lange dokumenter afkortet i stilhed. - Forventninger fra API-modeller. En 8B-model er ikke en lille frontier-model. Den skal have snævrere opgaver, tydeligere prompts og gerne et skema at svare i.
- Skiftende embedding-model. Indekset skal bygges forfra. Der kommer ingen fejl — resultaterne bliver bare tilfældige.
- Temperature på klassificering. Standardværdien er tunet til samtale. Sæt den til 0 når du vil have det samme svar hver gang.
- Ingen timeout. Et kald der lander i CPU kan køre i flere minutter. Sæt en timeout i klienten frem for at lade en webserver hænge.