Ollama — Run LLMs Locally on Mac, Linux and Windows 2026
Advertisement
Introduction
Why This Matters
Running LLMs locally with Ollama gives you complete privacy, zero API costs, and offline capability — three properties cloud APIs cannot provide. Every prompt stays on your machine. There is no per-token billing. No network dependency means the model responds even when your internet is down.
Ollama wraps the llama.cpp inference engine behind a clean REST API and a dead-simple CLI. It handles model downloading, quantization selection, and GPU acceleration automatically. You run one command and have a production-quality model responding in seconds. For developers building privacy-sensitive applications, experimenting with multiple models, or working in air-gapped environments, Ollama is the definitive local inference solution in 2026.
Installation
macOS
# Option 1: Homebrew
brew install ollama
# Option 2: Direct download
curl -fsSL https://ollama.com/install.sh | sh
# Start the Ollama server
ollama serveOllama automatically uses Apple Silicon GPU (Metal) on M1/M2/M3/M4 Macs, delivering 5-10x faster inference than CPU.
Linux
curl -fsSL https://ollama.com/install.sh | sh
# Enable as a system service
sudo systemctl enable ollama
sudo systemctl start ollamaNVIDIA GPU acceleration is detected automatically via CUDA. AMD ROCm is also supported on Linux.
Windows
Download the installer from ollama.com. The service starts automatically after installation. GPU support requires an NVIDIA card with up-to-date drivers.
Downloading and Managing Models
# Pull a model (downloads and caches locally)
ollama pull llama3 # Meta Llama 3 8B — best general-purpose
ollama pull mistral # Mistral 7B — fast, high quality
ollama pull phi3 # Microsoft Phi-3 Mini — ultra-compact
ollama pull gemma2 # Google Gemma 2 9B — strong reasoning
ollama pull qwen2 # Alibaba Qwen 2 — multilingual
ollama pull codellama # Meta Code Llama — code generation
ollama pull deepseek-coder # DeepSeek Coder — code specialist
# List locally cached models
ollama list
# Show model metadata and architecture
ollama show llama3
# Remove a model to reclaim disk space
ollama rm mistral
# Pull a specific quantization variant
ollama pull llama3:8b-instruct-q4_K_M # 4-bit quantized, ~4.7GB
ollama pull llama3:70b-instruct-q4_K_M # 70B quantized, ~40GBRunning Models from the CLI
# Interactive REPL
ollama run llama3
# Single-shot prompt from command line
ollama run mistral "Explain the difference between TCP and UDP in two sentences."
# Pipe text in from stdin
echo "Summarize this: $(cat article.txt)" | ollama run llama3
# Run with custom parameters
ollama run mistral --verbose "Write a haiku about Python programming"Python Integration via HTTP API
Ollama exposes a REST API on localhost:11434 by default. You can call it directly with requests or use the official Python library.
pip install ollamaimport ollama
# Simple generation
response = ollama.generate(
model="llama3",
prompt="What is the difference between a list and a tuple in Python?",
)
print(response["response"])# Chat with message history
messages = [
{"role": "system", "content": "You are a senior Python engineer."},
{"role": "user", "content": "How do I implement a context manager?"},
]
response = ollama.chat(model="llama3", messages=messages)
print(response["message"]["content"])Streaming Responses
import ollama
def stream_response(prompt: str, model: str = "llama3") -> str:
"""Stream tokens to stdout and return full response."""
full_response = ""
stream = ollama.generate(model=model, prompt=prompt, stream=True)
for chunk in stream:
token = chunk["response"]
print(token, end="", flush=True)
full_response += token
print()
return full_response
stream_response("Write a Python decorator that logs function execution time.")Building a Multi-turn Chat Application
import ollama
class LocalChatBot:
def __init__(self, model: str = "llama3", system_prompt: str = "You are a helpful assistant."):
self.model = model
self.messages = [{"role": "system", "content": system_prompt}]
def chat(self, user_input: str) -> str:
self.messages.append({"role": "user", "content": user_input})
response = ollama.chat(
model=self.model,
messages=self.messages,
options={"temperature": 0.7, "num_predict": 512},
)
assistant_content = response["message"]["content"]
self.messages.append({"role": "assistant", "content": assistant_content})
return assistant_content
def reset(self):
self.messages = [self.messages[0]] # Keep system prompt
# Usage
bot = LocalChatBot(model="llama3", system_prompt="You are a Python tutor.")
print(bot.chat("What is a generator?"))
print(bot.chat("Show me a practical example."))
print(bot.chat("How does it compare to returning a list?"))LangChain Integration
pip install langchain langchain-community langchain-ollamafrom langchain_ollama import OllamaLLM, OllamaEmbeddings
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# LLM
llm = OllamaLLM(model="llama3", base_url="http://localhost:11434")
# Simple chain
prompt = ChatPromptTemplate.from_template(
"Explain {concept} to a {audience} in 3 bullet points."
)
chain = prompt | llm | StrOutputParser()
result = chain.invoke({"concept": "neural networks", "audience": "high school student"})
print(result)# Local RAG with Ollama embeddings
from langchain_community.vectorstores import Chroma
from langchain_core.documents import Document
embeddings = OllamaEmbeddings(model="nomic-embed-text")
docs = [
Document(page_content="Ollama runs LLMs locally on consumer hardware."),
Document(page_content="LangChain provides composable AI application primitives."),
Document(page_content="RAG combines retrieval with generation for grounded answers."),
]
vectorstore = Chroma.from_documents(docs, embedding=embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
from langchain.chains import RetrievalQA
qa = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
answer = qa.run("What is Ollama used for?")
print(answer)Creating Custom Models with Modelfiles
A Modelfile lets you bake in a system prompt, set parameters, and create a named model ready for immediate use.
cat > Modelfile << 'EOF'
FROM llama3
SYSTEM You are an expert Python code reviewer. Review code for correctness, performance, and style. Be concise and specific.
PARAMETER temperature 0.3
PARAMETER num_predict 1024
PARAMETER repeat_penalty 1.1
EOF
ollama create py-reviewer -f Modelfile
ollama run py-reviewer "Review this: def fib(n): return fib(n-1)+fib(n-2) if n>1 else n"Performance Comparison
| Model | Size (disk) | RAM needed | Tokens/sec (M2 Pro) | Quality |
|---|---|---|---|---|
| phi3:mini | 2.3 GB | 3 GB | 90 | Good |
| mistral:7b | 4.1 GB | 5 GB | 55 | Very good |
| llama3:8b | 4.7 GB | 6 GB | 50 | Excellent |
| gemma2:9b | 5.4 GB | 7 GB | 42 | Excellent |
| llama3:70b (q4) | 40 GB | 48 GB | 8 | Best |
Common Mistakes
- Running large models without enough RAM — models spill to swap disk, making them 50x slower; check
ollama showfor memory requirements - Not pinning a quantization level — the default pull picks a quantization Ollama deems suitable; for reproducible benchmarks, always pull the specific quantization tag
- Ignoring GPU usage — run
nvidia-smior Activity Monitor (Mac) to confirm the GPU is being used; if not, reinstall drivers or check CUDA version compatibility - Creating new Modelfiles instead of using
--systemflag — for one-off experiments useollama run llama3 --system "You are..."rather than creating a permanent model - Calling the raw HTTP API without setting
stream: false— the HTTP endpoint streams JSON objects by default; parse accordingly or set"stream": falsein the request body
Best Practices
- Use
ollama serveas a background service and interact via the Python library rather than spawning subprocesses - Prefer 4-bit quantized models (tag suffix
q4_K_M) for the best quality-to-memory trade-off on consumer hardware - For embeddings in RAG pipelines, use
nomic-embed-text— it is compact and fast and outperforms most 7B LLM embeddings on retrieval benchmarks - Set
OLLAMA_NUM_PARALLEL=2(environment variable) if you need to serve multiple concurrent users - Monitor RAM usage with
ollama psto see which models are loaded and their memory footprint
Key Takeaways
- Ollama is a one-command local LLM runner that wraps
llama.cppwith a REST API and a CLI, supporting Mac, Linux, and Windows - Apple Silicon (M1–M4) and NVIDIA GPUs are automatically used for acceleration — CPU fallback works but is 5-10x slower
- The official Python library (
pip install ollama) providesollama.generate()andollama.chat()functions that mirror the OpenAI SDK style - Modelfiles let you create named custom models with baked-in system prompts and generation parameters, shareable like Dockerfiles
- LangChain's
OllamaLLMandOllamaEmbeddingsclasses enable fully local RAG pipelines with zero cloud dependencies - 4-bit quantized models (e.g.,
llama3:8b-instruct-q4_K_M) run on 6 GB of RAM while retaining ~95% of full-precision quality - Ollama is best for privacy-sensitive workloads, offline environments, development experimentation, and cost-free prototyping
- For high-concurrency production workloads, combine multiple Ollama instances behind a load balancer or switch to a cloud inference API
Advertisement