Moondream2 is available on Ollama as a roughly 1.7GB local vision-model package. The published moondream:v2 tag accepts both text and images with a 2K context window. It is a practical option for short visual questions, not a guarantee of accurate OCR or long-document reasoning.1

If you have limited free unified memory and want to test local image analysis on a Mac, moondream:v2 is a sensible starting point. For OCR, complex diagrams, multiple images, or long documents, compare it with a larger model early.

Decision map: Moondream2 v2 is a 1.7GB Apache-2.0 Ollama package; Moondream3 Preview has a different BSL 1.1 license.
1.7GB package and 2K context from Ollama v2; preview license from the original terms. Not a Mac measurement.

What Moondream2 Is

The figures below describe Ollama’s published moondream:v2 package, not the full memory needed at runtime.1 The project documentation explains how its vision encoder and language model work together.

ComponentListing
Language modelPhi-2, 1.42 billion parameters, Q4_0
Vision projectorCLIP, 454 million parameters, F16
Package size1.7 GB
LicenseApache 2.0
Model classvision-language model for edge devices

The model connects a compact text decoder with a vision projector. It can turn visual input into text answers without calling a cloud API.

Typical jobs include:

  • describing a photo or screenshot,
  • answering questions about visible objects,
  • roughly locating elements,
  • recognizing short UI text or obvious states,
  • pre-sorting images in a local workflow.1

Its small size is also the main limitation. Moondream2 has less capacity for fine detail, complex instructions, and long visual investigations than models with 7, 12, or more billion parameters.

Install with Ollama

You need:

  • an Apple Silicon Mac or supported Intel Mac,
  • a current Ollama installation,
  • about 2 GB of free storage for the package,
  • internet for the download; local use can work offline afterward.

Download the model:

ollama pull moondream:v2

Start it:

ollama run moondream:v2

For the first test, use an image with a result you can verify. Give a specific task rather than asking only “What do you see?”:

Describe the visible controls.
Then list three pieces of text you can read confidently.
Mark uncertain readings explicitly.

This makes it easier to notice when the model read a detail versus generating a plausible one.

Send Images from Python

First install the Python client with python3 -m pip install ollama. Ollama must be running locally and moondream:v2 must already be downloaded. The client accepts a local image path in a chat message:

from ollama import chat

response = chat(
    model="moondream:v2",
    messages=[{
        "role": "user",
        "content": "Describe this image and mark uncertain details.",
        "images": ["/path/to/image.jpg"],
    }],
)

print(response.message.content)

For production processing, also:

  • restrict file type and size,
  • normalize images before inference,
  • do not treat free-form model output as reliable OCR,
  • log errors and timeouts,
  • explicitly disable cloud features for sensitive material.

Reproducible local vision test: keep the image on loopback

Ollama’s documented POST /api/chat endpoint expects base64-encoded image data in the images array. The Python SDK shown above can accept a file path, while direct REST calls require you to encode the image first. The Vision docs explain the difference. The listed moondream:v2 tag has a 2K / 2,048-token context window. Its 1.7GB file size is download size, not a runtime memory measurement.

Start Ollama, run ollama pull moondream:v2 and save a non-sensitive image as ./example.png. The example validates PNG, JPEG and WebP file signatures and limits files to 10 MiB. This is a self-imposed safety limit, not Ollama’s published image restriction. By default, DRY_RUN=1 verifies the file and JSON payload without sending an HTTP request.

IMAGE_PATH=./example.png DRY_RUN=1 python3 - <<'PY'
import base64, json, os, time
from pathlib import Path
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen
endpoint = "http://127.0.0.1:11434/api/chat"
image = Path(os.getenv("IMAGE_PATH", "./example.png")).expanduser()
dry_run = os.getenv("DRY_RUN", "1")
if dry_run not in ("0", "1"):
    raise SystemExit("DRY_RUN must be 0 or 1")
if not image.is_file():
    raise SystemExit("Image not found: " + str(image))
size = image.stat().st_size
if size == 0 or size > 10 * 1024 * 1024:
    raise SystemExit("Image must be 1 byte to 10 MiB (example safety cap)")
raw = image.read_bytes()
if not (raw.startswith(b"\x89PNG\r\n\x1a\n") or
        raw.startswith(b"\xff\xd8\xff") or
        (raw.startswith(b"RIFF") and raw[8:12] == b"WEBP")):
    raise SystemExit("Expected a PNG, JPEG or WebP image")
payload = {"model": "moondream:v2", "messages": [{
    "role": "user",
    "content": "Describe visible objects. Flag uncertain text.",
    "images": [base64.b64encode(raw).decode("ascii")],
}], "stream": False, "options": {"num_ctx": 2048}, "keep_alive": 0}
if dry_run == "1":
    print("DRY_RUN: file and payload validated; no HTTP request sent")
    print("Endpoint:", endpoint, "Model:", payload["model"], "Bytes:", size)
else:
    req = Request(endpoint, data=json.dumps(payload).encode("utf-8"),
                  headers={"Content-Type": "application/json"}, method="POST")
    started = time.perf_counter()
    try:
        with urlopen(req, timeout=120) as resp:
            answer = json.load(resp)
    except (HTTPError, URLError, TimeoutError) as exc:
        raise SystemExit("Local Ollama request failed: " + str(exc))
    print(answer.get("message", {}).get("content", "No answer returned"))
    elapsed = time.perf_counter() - started
    print("Wall time (s):", round(elapsed, 2))
    print("Output tokens:", answer.get("eval_count", "not reported"))
    output_tokens, decode_ns = answer.get("eval_count"), answer.get("eval_duration")
    if isinstance(output_tokens, int) and isinstance(decode_ns, int) and decode_ns > 0:
        print("Decode tokens/s (Ollama):", round(output_tokens * 1_000_000_000 / decode_ns, 2))
PY

Only after a successful dry run should you set DRY_RUN=0 for actual local inference. The script posts exclusively to http://127.0.0.1:11434/api/chat, never a cloud endpoint. It uses a 2,048-token context and prints the reported output-token count on a real response. The dry run does not print encoded image contents.

Interpreting measurements: The new Wall time (s) output measures the full request, including image processing and any model load. Decode tokens/s (Ollama) uses only Ollama’s reported eval_duration and eval_count; it excludes prompt prefill and image processing. Compare cold and warm runs separately. No Mac throughput is claimed without a real test.

Disable Ollama Cloud: The official FAQ documents {"disable_ollama_cloud": true} in ~/.ollama/server.json or OLLAMA_NO_CLOUD=1. For the macOS app, set launchctl setenv OLLAMA_NO_CLOUD 1, restart Ollama and verify Ollama cloud disabled: true in its logs. Keep the API bound to 127.0.0.1 by default; OLLAMA_HOST=0.0.0.0 unnecessarily expands network access for this test.

Local image data flow: file on Mac, base64 to 127.0.0.1, Moondream2 in Ollama, local response; external agent tools cross a separate privacy boundary.
Local endpoint per Ollama Vision; cloud switch per Ollama FAQ. A local inference server does not prevent separately enabled agent tools from using cloud services.

An evidence protocol, not invented Mac benchmarks

Use ten images you can inspect yourself: ordinary photos, UI screenshots and a few difficult charts. Record exact tag, Ollama version, image size, prompt, correct/incorrect/uncertain objects, total latency and macOS memory pressure. For tiny labels, compare with a dedicated OCR engine. ollama ps shows models loaded in memory; it does not establish visual accuracy.

If the localhost request returns Connection refused, check that Ollama is running. For model not found, inspect ollama list and the exact tag. Neither 2K context nor a 1.7GB download establishes measured tokens/s or OCR quality. Reported figures reflect package specifications rather than on-device Mac benchmarks.

Memory Guidance on Mac

The package is small, but it is not the only memory consumer. macOS, Ollama, the image, chat history, and other apps share unified memory.

Mac configurationPractical guidance
8 GB unified memorybasic single-image tasks are possible; close large apps
16 GBmore comfortable for screenshots and short image conversations
24–32 GBplenty of headroom; larger vision models become more attractive
48 GB+Moondream2 is rarely the memory limit; compare stronger models

On an 8 GB Mac, Moondream2’s small size is its main advantage. On a 32 or 64 GB system, test whether a larger model delivers better quality without becoming too slow for the workflow.

Diagnose a bad image answer

Instead of repeating two generic evaluation checklists, diagnose the failure:

ObservationNext experiment
Text is inventedEnlarge the text region and compare with a dedicated OCR engine
An object is missingCrop the image and repeat the same question
Numbers are transposedVerify against the original; do not feed unverified values into a workflow
High response latencyInspect Wall time, separate cold from warm runs and watch macOS memory pressure

This is a test protocol, not a measured error rate. Record the image, ground truth, Ollama version and Mac configuration.

When a Larger Vision Model Is Better

TaskMoondream2Larger vision model
describe one photogood fitalso suitable
categorize a UI screenshotoften sufficientbetter with many details
read a long document pagelimitedmuch better starting point
tables and small numberserror-proneusually better, still verify
compare several imageslimitedstronger starting point
local test on 8 GBvery attractiveoften too large

Possible next tests in Ollama:

  • llama3.2-vision for a larger general vision workflow,
  • gemma3 for text and image in several sizes,
  • qwen2.5vl for documents, tables, and UI screenshots.

Tags, package sizes, and runtime support change. Check the current Ollama page and free memory before downloading.

Privacy: Keep the Whole Path Local

A downloaded Ollama model can run inference locally. That does not automatically make the entire workflow offline. A frontend, agent, or additional tool may still contact external services.

For a local-first setup:2

  • disable cloud features in Ollama,
  • do not enable web search or external tools,
  • do not expose the local server directly to the internet,
  • account for logs and temporary image files,
  • test whether the client opens network connections.

Moondream2 can be useful for sensitive screenshots when the entire execution path (model, API client, storage, and post-processing) stays strictly local.

Moondream2 vs Moondream3 Preview: Different Models and Licenses

Moondream2 is available as Ollama’s moondream:v2 package with a roughly 1.7 GB download, a compact image projector, and an Apache 2.0 license. Those facts apply to this specific v2 tag, not automatically to later releases.13

Moondream3 Preview is a different architecture. Its model card describes a 9B-total / 2B-active mixture-of-experts model and 32K usable context. Some published inference examples assume CUDA and are not a drop-in Mac/Ollama setup. The preview is not a compatible replacement tag for moondream:v2.4

Commercial use: “other” is a metadata label, not the actual license

The Hugging Face model card lists the preview’s license simply as “other.” The repository’s current LICENSE.md spells out Business Source License 1.1 (BSL 1.1) with an Additional Use Grant:

  • Internal production use within an organization and personal/research uses are permitted under the stated conditions.
  • Some commercial third-party products are permitted. However, the additional grant restricts paid competing hosted or embedded offerings that substantially overlap with M87 Labs’ paid products.
  • The license provides for a later switch to Apache 2.0. Until then, the current BSL terms also govern derivatives and redistribution.

Read the actual license text rather than inferring Apache-2.0 rights from a generic metadata label. Do not transfer Moondream2’s Apache 2.0 license to Moondream3 Preview. If shipping a commercial product or external API, examine the terms and your distribution model with qualified legal advice; this is not legal advice.5

For simple image questions on a memory-constrained Mac, the established Ollama v2 tag is still the simpler starting point. Evaluate the preview’s runtime, memory and license separately.

Test it with your own images

For a reproducible start, download the listed Ollama tag and inspect its metadata:

ollama pull moondream:v2
ollama show moondream:v2
ollama ps

The last command only shows currently loaded models, so an empty result is normal until inference has started. Launch ollama run moondream:v2 and try three inputs: a clear everyday photo, a screenshot containing small text and a complex chart.

Score more than whether it produced an answer. Note hallucinated objects, inaccurate text reproduction and missing visual details. The 1.7GB number is the download size, not a complete runtime-memory measurement. Dedicated OCR is often a better baseline when text extraction must be reliable.

For full local setup instructions, see the Ollama guide.

Sources and Status

Status: October 12, 2026. The v2 package size and 2K context follow Ollama’s listing; Moondream3 licensing was checked against its current LICENSE.md. Review license revisions before production use.

Footnotes

  1. Ollama: moondream:v2 ↩ ↩2 ↩3 ↩4

  2. Ollama Vision ↩

  3. Moondream2 on Hugging Face ↩

  4. Moondream 3 (Preview) on Hugging Face ↩

  5. Moondream3 Preview: official LICENSE.md ↩

Frequently Asked Questions

What is Moondream2?

Moondream2 is a compact vision-language model for image descriptions, visual questions and object detection. The Ollama package combines a 1.42B Phi-2 language model with a 454M CLIP projector and is about 1.7 GB.

Does Moondream2 run on an 8 GB Mac?

The 1.7 GB package is small enough for basic single-image tasks on many 8 GB Apple Silicon Macs. Open apps, image size and longer chats reduce available memory; 16 GB is more comfortable.

How do I install Moondream2 with Ollama?

Install Ollama and run `ollama pull moondream:v2`. Start it with `ollama run moondream:v2`. Applications can send images through the local Ollama API or Python package.

Can Moondream2 replace cloud vision models?

Not generally. Moondream2 is useful for simple local image questions, but reaches its limits sooner on dense text, complex diagrams, fine OCR and multi-image reasoning.

Can I use Moondream2 commercially?

The current Hugging Face page and Ollama package list Moondream2 under Apache 2.0. For a product, still verify the exact model version and every component in the deployment.

Researched and written with AI, sources cited, original measurements marked. AI transparency

Published: May 15, 2026 Updated: October 12, 2026

About the author