AI EngineeringZero to ProductionHome·About·Contact
Local & Open Models · Chapter LM1

The open-weight landscape

Hosted APIs are the default; open weights win on data-residency, offline, control, and high-volume cost. This chapter maps the families, licenses, and the size-vs-hardware reality.

⏱️ ~1 hour🧪 concept + exercise🎯 Beginner→Expert
🌱 Start here — from zero Running open models yourself, from scratch — you can run capable AI models on your own laptop or server — here's how, starting from nothing.

Besides paid APIs like Claude, there are open-weight models (Llama, Mistral, Qwen…) whose files you can download and run on your own hardware. Why bother? Keeping data in-house, working offline, or saving money at scale. This section takes you from "run a model on your laptop in one command" to "serve one properly for a team" — and how to decide honestly when it's worth it versus just using an API.

The words you'll hear (in plain terms):

TermWhat it actually means
open-weight modela model whose files you can download and run yourself (Llama, Mistral, Qwen…).
Ollamathe easiest tool to run such a model locally — one command, works on a laptop.
vLLMa production-grade server for running open models fast for many users.
GGUF / quantizeda compact model file format that runs even on CPU / Apple Silicon.
self-host vs APIrun it yourself (control, fixed cost) vs pay a provider per token (easy, no ops).

What you need before starting:

  • The AWS section's cost-model idea is handy background, not required.
  • Python basics; comfort running a command in a terminal.
  • Any modern laptop works for the local labs; a GPU helps for the serving ones.

New to the topic? Read this box, then take the chapters in order — each section is tagged essentialexpert so you always know the depth you're at.

Learning objectives

  • Name the major open-weight model families and their licenses.
  • Match model size to the hardware needed to run it.
  • Explain 'open weights' vs 'open source' and why the license matters.
  • Choose a starting model for a given constraint.

Why run open models at all essential

Hosted APIs (Claude, etc.) are the right default — managed, capable, no ops. But open-weight models earn their place when you need data to never leave your infra, offline/air-gapped operation, full control of the model, or cost predictability at high volume. This track makes running them practical.

Your requirement pick honestly Hosted API managed default or Open-weight self-host when you need control
🗺️ How to read this diagram

This little flow is the whole decision this chapter is about: should you use a hosted API or run an open model yourself? Read it left to right.

  • The left box (Your requirement) is the honest starting point — what does your situation actually demand? Data that can't leave your network? Offline use? Tight control? Low cost at huge volume?
  • The middle box (Hosted API) is the default recommendation: a provider like Claude runs the model for you — nothing to manage. Most projects should start here.
  • The right box (Open-weight self-host) is the alternative you pick only when your requirement demands it — you download the model's files and run them on your own hardware, trading convenience for control.
  • The arrows read as "leads you to consider" — a requirement points you at the default first, then to self-hosting only if the default doesn't fit.

In short: Hosted API is the sensible default; open-weight self-host is what you reach for when data-residency, offline operation, control, or high-volume cost forces the issue.

The families essential

FamilySizesNote
Llama (Meta)1B–405Bbroad ecosystem; community license
Mistral / Mixtral7B–8x22Bstrong small models; MoE options
Qwen (Alibaba)0.5B–72B+strong multilingual + coding
Gemma (Google)2B–27Befficient, permissive-ish
Phi (Microsoft)mini–mediumsmall, punch above weight
'Open weights' ≠ 'open source'Most of these release weights under a custom license, not OSI open-source. Some restrict commercial use or scale. Read the license before you build a product on a model — this is a legal step, not a technical one.

Size vs hardware intermediate

The practical constraint is memory. A rough rule at common quant levels (from IC2):

Model sizeFP16 VRAM4-bit VRAMRuns on
7–8B~16 GB~5–6 GBone consumer GPU / good laptop (4-bit)
13B~26 GB~9 GBone bigger GPU
70B~140 GB~40 GBmulti-GPU (IC6 tensor-parallel)
Start at 7B, 4-bitA 4-bit 7–8B model runs on a single consumer GPU or an Apple-Silicon laptop and is plenty to learn the whole workflow. Scale up only when a real task needs it.

Exercise LM1.1 — Pick your model

Context: The model you choose under a real constraint drives the rest of the track — everything downstream assumes that pick.

Your task: For a real or hypothetical constraint (e.g. "data can't leave our network, one A10 GPU"), pick a family, size, and quant level and justify it against the license and the memory table.

Requirements:

  • State the constraint explicitly (hardware, residency, commercial use)
  • Pick a model family, size, and quantization level
  • Justify the size against the VRAM/memory table
  • Justify the choice against the license

💡 Hint: Work from the constraint inward: VRAM sets the size, residency/commercial-use sets the license, and both together pick the family.

🪜 Practice ladder beginner → industry

Six graded exercises, easy to real-world. Try each before opening its solution.

Exercise 1 · When do open weights beat a hosted API?Beginner

Context: Hosted APIs are the sane default; open weights earn their place only for a specific reason — data-residency, offline/air-gapped, full control, or high-volume cost.

Your task: Write a helper that names which of those four reasons a given requirement triggers (or says the hosted API is the right default).

Requirements:

  • Map each of the four open-weights reasons to a triggering requirement
  • Return the matching reason when a requirement fires one
  • Fall back to "hosted API default" when none applies
  • Show a triggering case and a non-triggering case

💡 Hint: A small requirement→reason table with a default; if nothing matches, the managed API is the cheaper, saner choice.

Show solution

Encode the four reasons the lesson gives. Runnable stdlib:

REASONS = {
    "data must stay on our infra": "data-residency",
    "must work offline / air-gapped": "offline",
    "we need full control of the model": "control",
    "very high token volume": "cost-at-scale",
}
def why_open(requirement):
    for k, reason in REASONS.items():
        if k in requirement.lower():
            return f"open weights -> {reason}"
    return "hosted API is the right default here"

print(why_open("data must stay on our infra"))    # data-residency
print(why_open("summarize a few docs a day"))       # hosted default

Open weights earn their place for a specific reason — if none applies, the managed API is the cheaper, saner default.

Exercise 2 · Size -> VRAM at FP16Intermediate

Context: A rough but load-bearing rule: FP16 weights need ~2 bytes per parameter. That one number sets the hardware floor for any open model.

Your task: Write a calculator that, given a parameter count in billions, estimates the VRAM in GB for the weights at FP16.

Requirements:

  • Use ~2 bytes per parameter for FP16
  • Convert bytes to GB correctly (1024-based)
  • Report weights-only VRAM for a few sizes (e.g. 7B, 13B, 70B)
  • Note this is the floor, not the total (activations/KV add more)

💡 Hint: params × 1e9 × 2 bytes, divided into GB; a 7B lands near 13 GB, a 70B near 130 GB.

Show solution

2 bytes/param at FP16. Runnable:

def vram_fp16_gb(params_billion):
    bytes_per_param = 2               # FP16
    return params_billion * 1e9 * bytes_per_param / (1024**3)

for b in [7, 13, 70]:
    print(f"{b}B -> ~{vram_fp16_gb(b):.1f} GB (weights only, FP16)")
# 7B -> ~13.0 GB, 13B -> ~24.2 GB, 70B -> ~130.4 GB

Weights alone: a 7B fits a 16GB card, a 70B needs multiple GPUs. Activations/KV cache add more — this is the floor, not the total.

Exercise 3 · Match a model size to available hardwareAdvanced

Context: The size→VRAM wall is hard at FP16: given a GPU, only certain model sizes fit — and you must reserve headroom for the KV cache.

Your task: Write a selector that returns which model sizes fit at FP16 on a given GPU, leaving headroom.

Requirements:

  • Reuse the FP16 weights estimate
  • Reserve a fraction of VRAM for KV cache/activations before filtering
  • Return the sizes that fit within the usable budget
  • Show a small card and a large card fitting different sets

💡 Hint: Shrink the GPU's VRAM by a headroom fraction, then keep the sizes whose weights fit; quantization (LM4) is what moves the wall later.

Show solution

Reserve headroom for KV cache, then filter. Runnable:

def vram_fp16_gb(pb):
    return pb * 1e9 * 2 / (1024**3)

def fits(gpu_gb, sizes=(7, 13, 34, 70), kv_headroom=0.30):
    usable = gpu_gb * (1 - kv_headroom)     # leave room for KV cache/activations
    return [s for s in sizes if vram_fp16_gb(s) <= usable]

print("24GB card fits FP16:", fits(24))   # [7, 13]
print("80GB card fits FP16:", fits(80))   # [7, 13, 34, 70]

Quantization (LM4) shrinks the weights so bigger models fit — but at FP16 the size->VRAM wall is hard.

Exercise 4 · Open weights vs open source — the license mattersExpert

Context: "Open weights" (downloadable) is not "open source" (permissive license). Whether you can ship a model is governed by its license, not by the download.

Your task: Write a checker that, given a license, says what you may do — commercial use? redistribute? restrictions?

Requirements:

  • Cover permissive (Apache/MIT), community (open weights with clauses), and research-only licenses
  • Report commercial-use and redistribute permissions per license
  • Flag research-only as not shippable to production
  • Handle an unknown license by telling the user to read it first

💡 Hint: A license→permissions table; the key lesson is that "you can download it" never means "you can ship it".

Show solution

The license, not the download, governs use. Runnable:

LICENSES = {
    "apache-2.0": {"commercial": True,  "redistribute": True,  "note": "permissive OSS"},
    "mit":        {"commercial": True,  "redistribute": True,  "note": "permissive OSS"},
    "llama-community": {"commercial": True, "redistribute": True,
                        "note": "open weights, with acceptable-use + scale clauses"},
    "research-only":   {"commercial": False, "redistribute": False,
                        "note": "weights available but NOT for production"},
}
def check(license_id):
    L = LICENSES.get(license_id.lower())
    if not L:
        return "unknown license -- read it before shipping"
    return f"commercial={L['commercial']} redistribute={L['redistribute']} ({L['note']})"

print(check("apache-2.0"))       # fully permissive
print(check("research-only"))    # cannot ship

"You can download it" does not mean "you can ship it". Always check the license against your intended use.

Exercise 5 · Pick a starting model for a constraintProfessional

Context: The starting model falls out of the axes together — VRAM, license, and deployment — not from picking the biggest name.

Your task: Given VRAM, whether commercial use is required, and whether offline is required, recommend a size tier and a posture.

Requirements:

  • Pick the largest FP16-fitting size for the GPU (with headroom)
  • Fall back to a quantized path when nothing fits at FP16
  • Require a permissive license when redistribution/commercial use is needed
  • Require self-hosting when offline is required
  • Return a concrete recommendation combining all three

💡 Hint: Compute the size ceiling from VRAM first, then layer the license and deployment constraints on top; no FP16 fit points to a quantized GGUF (LM4).

Show solution

Fold size + license + deployment into one pick. Runnable:

def vram_fp16_gb(pb): return pb * 1e9 * 2 / (1024**3)

def recommend(gpu_gb, commercial, offline):
    usable = gpu_gb * 0.7
    biggest = max([s for s in (7, 13, 34, 70) if vram_fp16_gb(s) <= usable] or [0])
    if biggest == 0:
        return "no FP16 fit -- use a quantized GGUF (LM4) or a smaller model"
    lic = "permissive (Apache/MIT) if you must redistribute" if commercial else "any"
    deploy = "self-host required" if offline else "self-host optional"
    return f"start ~{biggest}B; license: {lic}; {deploy}"

print(recommend(24, commercial=True, offline=True))   # ~13B, permissive, self-host
print(recommend(8,  commercial=False, offline=False)) # quantized path

The starting model falls out of hardware + license + deployment — not from picking the biggest name.

Exercise 6 · A model-selection matrix for a teamIndustry scenario

Context: Defending a model choice to a team means a repeatable filter (hardware + license) then a quality ranking — a shortlist, not a vibe.

Your task: Build a scorer over candidate models (size, license, quality tier, VRAM need) that filters by hardware and license, then ranks survivors by quality.

Requirements:

  • Each candidate carries params, license, and a quality score
  • Exclude candidates whose FP16 weights won't fit the GPU (with headroom)
  • Exclude non-permissive licenses when commercial use is required
  • Rank the survivors by quality, best first
  • Show a run excluding a research-only model and ranking the rest

💡 Hint: Filter first (fit + license), then sort by quality; a research-only model should drop out even if it's the highest quality.

Show solution

Turn the landscape into a defensible ranked shortlist. Runnable:

CANDIDATES = [
    {"name": "A-8B",  "params": 8,  "license": "apache-2.0",     "quality": 6},
    {"name": "B-70B", "params": 70, "license": "llama-community","quality": 8},
    {"name": "C-13B", "params": 13, "license": "research-only",  "quality": 7},
]
PERMISSIVE = {"apache-2.0", "mit", "llama-community"}

def vram_fp16_gb(pb): return pb * 1e9 * 2 / (1024**3)

def shortlist(cands, gpu_gb, need_commercial):
    usable = gpu_gb * 0.7
    ok = []
    for c in cands:
        if vram_fp16_gb(c["params"]) > usable:
            continue                                   # won't fit
        if need_commercial and c["license"] not in PERMISSIVE:
            continue                                   # license blocks prod
        ok.append(c)
    return sorted(ok, key=lambda c: c["quality"], reverse=True)

for c in shortlist(CANDIDATES, gpu_gb=80, need_commercial=True):
    print(c["name"], "quality", c["quality"])
# B-70B first (fits 80GB, commercial-OK), then A-8B; C-13B excluded (research-only)

A repeatable filter (hardware + license) then a quality ranking is how you defend a model choice instead of arguing by vibes.

✓ Checkpoint — you can move on when you can…

  • Name the major open-weight families and their sizes.
  • Match model size to hardware at FP16 and 4-bit.
  • Explain open-weights vs open-source and the license risk.
  • Choose a starting model for a constraint.

Knowledge check check yourself

✓ Knowledge check

Why does "open weights" not mean "open source," and why is that a legal rather than a technical concern?

Show answer
Most open-weight families (Llama, Mistral, Qwen, Gemma…) release their weights under custom licenses, not OSI-approved open-source licenses, and some restrict commercial use or scale. So before building a product on a model you must read the license — it's a legal gate, not a technical one.
✓ Knowledge check

Roughly what hardware does a 7–8B model need at FP16 versus 4-bit, and why does the chapter recommend starting at 7B/4-bit?

Show answer
A 7–8B model needs ~16 GB VRAM at FP16 but only ~5–6 GB at 4-bit, so 4-bit runs on a single consumer GPU or an Apple-Silicon laptop. Starting there lets you learn the entire workflow on hardware you already have, and you scale up only when a real task demands it.
© 2026 studybydoing.in · AI Engineering: Zero to Production · All rights reserved. · About · Privacy Policy · Terms · Contact
Educational content, provided as-is and without warranty. Code samples are examples — review, test, and adapt them before using in production. See the Terms of Use & Disclaimer. Use at your own risk.
© studybydoing.in