Ollama Tutorial: Run LLMs Locally on Your Machine
Ollama runs open language models on your own computer with one install. This tutorial walks through the command line, the REST API, conversation history, the OpenAI-compatible endpoint and a custom model built from a Modelfile, all run on an ordinary laptop, with the settings and limits worth knowing.
GloryTecks Team
Training & Placement Faculty
Last updated: 3 October 2026
Every request to a hosted language model leaves your machine, costs money and depends on someone else's service. For many tasks that is fine. For private documents, offline work, experiments with no budget, or simply learning how models behave, running a model on your own computer is better. Ollama is the most popular way to do it.
Ollama is a free application for macOS, Windows and Linux that downloads open models and runs them locally, with no API key needed for local use (Ollama: quickstart). It gives you three ways in: a command line, a REST API, and an API that imitates OpenAI's.
Getting a model
After installing, two commands are enough to start:
ollama pull llama3.2
ollama run llama3.2pull downloads the model, and run opens a chat in the terminal. The command line also lists, removes, builds and stops models (Ollama: CLI reference). The models used in many articles on this blog, a 3-billion-parameter Llama 3.2, download in about 2 GB and run on an ordinary laptop CPU.
Everything else from code
The script drives Ollama the way an application would. It asks the command line for the version and the model's details, lists installed models through the REST API, sends a prompt, holds a short conversation, calls the OpenAI-compatible endpoint, and builds a custom model from a Modelfile, then removes it.
import json
import re
import subprocess
import urllib.request
from pathlib import Path
BASE = "http://localhost:11434"
TERMINAL_CODES = re.compile(r"\x1b\[[0-9;?]*[A-Za-z]|[⠀-⣿]|\r") # spinners and cursor codes
def cli(*args):
out = subprocess.run(["ollama", *args], capture_output=True, text=True, encoding="utf-8")
text = TERMINAL_CODES.sub("", out.stdout + out.stderr)
return "\n".join(line.rstrip() for line in text.strip("\n").splitlines())
def post(path, body, headers=None):
req = urllib.request.Request(BASE + path, json.dumps(body).encode(),
{"Content-Type": "application/json", **(headers or {})})
with urllib.request.urlopen(req, timeout=900) as r:
return json.load(r)
# 1. The command line
print(cli("--version"))
print(cli("show", "llama3.2"))
# 2. The models on this machine, through the REST API
with urllib.request.urlopen(BASE + "/api/tags") as r:
for m in sorted(json.load(r)["models"], key=lambda m: m["name"]):
d = m["details"]
print(f"{m['name']:<26} {m['size'] / 1e9:>5.1f} GB {d['parameter_size']:>6} {d['quantization_level']}")
# 3. One prompt, one answer, with the timing Ollama reports
settings = {"temperature": 0, "seed": 42}
r = post("/api/generate", {"model": "llama3.2", "prompt": "Name three uses of a local language model, in one line.",
"stream": False, "options": settings})
print("\n" + r["response"])
print(f"{r['prompt_eval_count']} prompt tokens, {r['eval_count']} tokens generated")
print(f"generation speed on this laptop: {r['eval_count'] / r['eval_duration'] * 1e9:.1f} tokens per second")
# 4. A conversation: the model remembers only what you send back to it
history = [{"role": "user", "content": "My name is Asha and I teach statistics. Reply in one sentence."}]
history.append(post("/api/chat", {"model": "llama3.2", "messages": history, "stream": False, "options": settings})["message"])
history.append({"role": "user", "content": "What subject do I teach?"})
print("\nwith history: ", post("/api/chat", {"model": "llama3.2", "messages": history, "stream": False,
"options": settings})["message"]["content"])
print("without history:", post("/api/chat", {"model": "llama3.2", "messages": history[-1:], "stream": False,
"options": settings})["message"]["content"])
# 5. The OpenAI-compatible endpoint: code written for OpenAI's API, pointed at this machine
r = post("/v1/chat/completions", {"model": "llama3.2", "temperature": 0, "seed": 42,
"messages": [{"role": "user", "content": "Say hello in French, one word."}]},
{"Authorization": "Bearer ollama"})
print("\nOpenAI-style reply:", r["choices"][0]["message"]["content"], "| usage:", r["usage"])
# 6. A custom model from a Modelfile: same weights, a fixed system prompt and settings
Path("Modelfile").write_text(
"FROM llama3.2\n"
"PARAMETER temperature 0\n"
"PARAMETER seed 42\n"
'SYSTEM """You are a glossary for data science students. Define the term you are given in one plain sentence."""\n',
encoding="utf-8")
print("\n" + cli("create", "glossary", "-f", "Modelfile").splitlines()[-1])
print(post("/api/generate", {"model": "glossary", "prompt": "overfitting", "stream": False})["response"])
print(cli("rm", "glossary"))ollama version is 0.12.9
Model
architecture llama
parameters 3.2B
context length 131072
embedding length 3072
quantization Q4_K_M
Capabilities
completion
tools
Parameters
stop "<|start_header_id|>"
stop "<|end_header_id|>"
stop "<|eot_id|>"
License
LLAMA 3.2 COMMUNITY LICENSE AGREEMENT
Llama 3.2 Version Release Date: September 25, 2024
...
llama3.2:3b 2.0 GB 3.2B Q4_K_M
llama3.2:latest 2.0 GB 3.2B Q4_K_M
nomic-embed-text:latest 0.3 GB 137M F16
phi3:mini 2.2 GB 3.8B Q4_0
phi:latest 1.6 GB 3B Q4_0
qwen2.5-coder:1.5b-base 1.0 GB 1.5B Q4_K_M
A local language model can be used for personalized content recommendation, language translation, and speech-to-text transcription tailored to the specific dialect or regional accent of a user's location.
38 prompt tokens, 35 tokens generated
generation speed on this laptop: 9.4 tokens per second
with history: You teach Statistics.
without history: I don't have any information about you or your teaching position. Can you please tell me what subject you teach?
OpenAI-style reply: Bonjour! | usage: {'prompt_tokens': 33, 'completion_tokens': 3, 'total_tokens': 36}
success
Overfitting refers to when a model is too complex and learns the noise in the training data, resulting in poor performance on new, unseen data.
deleted 'glossary'
What the output shows
- The model's card is one command away.
ollama showreported 3.2 billion parameters, a 131,072-token maximum context, Q4_K_M quantisation, support for tools, and the start of the Llama 3.2 Community License, which governs what you may do with it. - Local models are files you manage. The list shows each model's size on disk, from 0.3 GB for an embedding model to over 2 GB for chat models.
- The API reports the work done. The prompt was 38 tokens and the answer 35. The speed line, measured on this laptop's CPU, will differ on yours.
- The model has no memory of its own. Told "My name is Asha and I teach statistics", it answered the follow-up correctly only when the history was sent back with the question. Without it, it had no idea. Every chat application keeps and resends the conversation itself.
- OpenAI-style code works unchanged. The same request format, with a placeholder API key, returned a reply and token usage in OpenAI's shape. Code written for a hosted model can often be pointed at a local one by changing the base address and model name (Ollama: OpenAI compatibility).
- A Modelfile packages behaviour. The glossary model reused Llama 3.2's weights with a fixed system prompt and settings, so a bare term produced a one-sentence definition.
Modelfiles
A Modelfile is to a model what a Dockerfile is to a container: a short recipe. FROM names the base model, PARAMETER sets defaults such as temperature or context length, SYSTEM fixes the system message, and TEMPLATE controls the exact prompt format (Ollama: Modelfile). ollama create builds it, and ollama show --modelfile prints the recipe of any installed model, a good way to learn how they are put together.
Defaults worth knowing
The FAQ answers most questions that come up in practice (Ollama: FAQ):
| Setting | Default | How to change it |
|---|---|---|
| Context window | 4,096 tokens | num_ctx per request, or OLLAMA_CONTEXT_LENGTH for the server |
| Address | 127.0.0.1, port 11434 | OLLAMA_HOST |
| Time a model stays loaded | 5 minutes | keep_alive per request, or ollama stop |
| Where models are stored | The .ollama folder in your home directory | OLLAMA_MODELS |
The context default surprises people. A model may support 131,072 tokens, as this one does, but Ollama gives it 4,096 unless asked for more, and longer inputs are cut. Raise it when you send long documents, and remember that a larger context uses more memory. See context windows explained.
The address default is a security feature. Ollama listens only on your own machine. Exposing it to a network makes every model on it available to anyone who can reach the port.
Hardware and versions
Small models run on a CPU, and a GPU makes everything much faster. ollama ps shows whether a loaded model is on the GPU, the CPU or split between them. As a rough guide, a model needs memory a little larger than its file size, plus more for long contexts.
Ollama moves quickly. The machine used here runs version 0.12.9, while the latest release on 3 October 2026 was 0.35.1 (GitHub: Ollama releases). The commands and endpoints used above all appear in the current documentation, but newer releases add features, so update before following newer guides.
Where Ollama fits
Ollama is ideal for one developer, a laptop, private data and experiments. For many users at once on dedicated GPUs, a serving engine is the better tool. See vLLM and model serving. For deciding whether an open model suits a product at all, see open-weight vs closed LLMs. To build an application on top, see the LangChain tutorial, which uses Ollama as its model.
Common mistakes
- Sending long documents with the default context, and losing most of them.
- Expecting the model to remember a conversation you did not send back.
- Exposing port 11434 to a network without protection.
- Ignoring the licence shown by
ollama show. - Comparing speeds across machines, or judging a model's quality by a tiny variant.
What is Ollama used for?
Is Ollama free?
Can I use the OpenAI Python library with Ollama?
How much RAM do I need for Ollama?
Running open models locally and calling them from code are covered in the Gen AI Frameworks and Tools module of the Generative AI course.
Sources
- Quickstart (Ollama documentation) — Ollama
- CLI reference (Ollama documentation) — Ollama
- FAQ (Ollama documentation) — Ollama
- OpenAI compatibility (Ollama documentation) — Ollama
- Modelfile reference (Ollama documentation) — Ollama
- Releases (GitHub, Ollama) — Ollama
GloryTecks Team
Training & Placement Faculty
The GloryTecks faculty team mentors learners across Data Science, AI and Data Engineering, with a focus on real-time projects and placement readiness in Hyderabad.
Want to master Generative AI?
Join GloryTecks’ expert-led Generative AI training in Hyderabad with real-time projects and 100% placement support.
vLLM and Model Serving: Scaling LLM Inference
NextGenerative AI Salary in India 2026: What the AI/ML Engineer Premium Looks Like
Related articles
LangChain Tutorial: Build Your First LLM App
This LangChain tutorial builds a small meeting-notes assistant in four steps, using a free local model: a chat model, a prompt chain, structured output validated by Pydantic, and an agent with one tool. Everything ran, and the output also shows the mistakes a small model makes and how to catch them.
LangGraph Tutorial: Building Stateful AI Agents
Build a small support-ticket agent with LangGraph, using only plain Python and no API key: typed state and reducers, conditional edges, a retry loop, checkpoints with thread IDs, and a human approval step with interrupt. Every output shown was produced by running the code.
How Large Language Models (LLMs) Work Under the Hood
A large language model does one thing: given some text, it scores every possible next token. Everything else, from chat to code, is that step repeated. This guide follows the step with real numbers from GPT-2 running on a laptop, then explains training, temperature and why fluent text is not always true.