Hugging Face
Hub models, Transformers, datasets, and Spaces — the open-weight ecosystem AI engineers live in. From Hub ID to chat template, PEFT, licenses, serving handoff, CI pins, and production failure modes.
What “Hugging Face” means (plain English)
Hugging Face is not one library — it is the default open-weight ecosystem for AI engineers:
| Piece | Job |
|---|---|
| Hub | Model/dataset cards, weights, licenses, discussions |
transformers |
Tokenizers + model APIs (PyTorch/TF/Flax) |
datasets |
Streaming, map, shard training data |
accelerate / PEFT |
Multi-GPU, LoRA/QLoRA adapters |
huggingface_hub |
Auth, download, upload, repos |
| TGI / Inference Endpoints | Managed or self-serve HTTP generation |
| Spaces | Gradio/Streamlit demos |
| Evaluate / TRL | Metrics helpers; RL/SFT trainer stacks (ecosystem) |
If you fine-tune, serve open models, or read model cards in interviews, you live here.
Analogy: the Hub is npm/Maven for weights. transformers is the SDK that speaks a common model API. Your serving engine (vLLM, TGI, TensorRT-LLM) is still a separate product decision — HF is how weights and tokenizers arrive.
One-sentence definition you can defend in an interview
Hugging Face is the registry + SDK for open weights: resolve
org/model@revision, load the same tokenizer and chat template the model was trained with, fine-tune or evaluate, then hand the same IDs to a real serving engine.
flowchart LR
Hub[Hub: weights + card + license] --> Local[transformers + PEFT]
Hub --> Serve[vLLM / TGI / TRT-LLM]
Local --> Train[Fine-tune / eval]
Train --> Hub2[Push adapter / model]
Serve --> App[Your product gateway]
Interview cue: “Hugging Face” in a design answer usually means Hub ID + tokenizer + chat template + license, not “we run Gradio in prod.”
The problem it solves for LLM apps
Closed APIs hide tokenization, templates, and weight management. Open weights make those your problem — and your control surface:
| Pain without HF Hub | With Hub + transformers |
|---|---|
| Scattered weight mirrors | Canonical org/model + revision |
| Mystery tokenization | Same tokenizer as training |
| Broken chat formats | chat_template on the tokenizer |
| Unreproducible fine-tunes | Pin commit + push adapters |
| License ambiguity | Card + license files next to weights |
| “Works on my laptop” serve | Same IDs in train → eval → engine traces |
Without a shared registry you reinvent mirrors, cards, and “which tokenizer did train use?” in every repo. With Hub IDs and no discipline, floating main and template skew create silent quality cliffs.
How it fits LLM apps
| App need | HF role |
|---|---|
| Chat with open weights | Download instruct model + correct chat template |
| RAG embeddings | Hub embedding models → your vector DB |
| Domain adaptation | PEFT LoRA on Hub base → push adapter |
| Eval baselines | Load same tokenizer/model IDs in CI |
| Demos | Spaces for stakeholders; not production |
| Dataset prep | datasets map/filter/shard before training |
flowchart TB
subgraph product [Product]
GW[Gateway]
Emb[Embed service]
Gen[Generate service]
end
Hub[(HF Hub)] --> Emb
Hub --> Gen
GW --> Emb
GW --> Gen
Emb --> VDB[(Vector store)]
Gen --> LLM[Open weights engine]
HF does not replace your gateway, auth, vector DB, or eval suite. It replaces ad-hoc weight hunting and mismatched tokenizers once you pin revisions.
See also: Open-weight vs APIs.
Architecture: from Hub ID to tokens
- Resolve
org/model(revision/commit hash in prod). - Download config, tokenizer, weights (or adapter).
apply_chat_template→ token ids.- Generate (local
generate, or hand off to vLLM). - Decode; strip special tokens.
sequenceDiagram
participant App
participant Tok as Tokenizer
participant M as Model / engine
App->>Tok: messages + chat_template
Tok->>M: input_ids
M-->>App: output_ids / stream
App->>Tok: decode
What lives in a model repo
| Artifact | Why it matters |
|---|---|
config.json |
Architecture, vocab size, rope scaling |
| Tokenizer files | How text ↔ ids |
tokenizer_config.json / chat_template |
Instruct formatting |
| Weight shards / safetensors | Actual parameters |
model.safetensors.index.json |
Shard map |
| LICENSE / model card | Legal + intended use |
generation_config.json |
Default decoding params |
Ship rule: pin revision= (git commit) in production configs. Floating main is a silent quality cliff.
Auto* classes vs pipelines
| API | Use when |
|---|---|
pipeline("text-generation", ...) |
Quick demos; hide tokenizer details |
AutoTokenizer + AutoModelForCausalLM |
You must own template, padding, device map |
| Engine OpenAI-compatible chat | Production throughput — still pin Hub id |
Pipelines are fine for exploration. Product paths should make the template contract visible so CI can golden-diff it.
Chat templates (the silent quality killer)
Open instruct models expect a specific chat template. Wrong template → polite garbage, not a crash.
from transformers import AutoTokenizer, AutoModelForCausalLM
model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
revision = "..." # pin in prod
tok = AutoTokenizer.from_pretrained(model_id, revision=revision)
messages = [
{"role": "system", "content": "You are concise."},
{"role": "user", "content": "Explain LoRA in 2 sentences."},
]
prompt = tok.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
# Prefer engine chat APIs in prod; this shows the contract.
assert tok.chat_template is not NoneCommon template failure modes
| Mistake | Symptom |
|---|---|
| Raw string concat without template | Model ignores system / role markers |
| Train with template A, serve with B | Catastrophic quality drop |
Forget add_generation_prompt=True |
Model continues as user |
| Mixing base + instruct prompts | Rambling / no instruction following |
| Different special tokens across services | Truncation / weird stops |
| UI sends OpenAI roles; local path skips template | “Works in API, fails open-weight” |
Ship rule: pin revision= and assert tok.chat_template is present for instruct models in CI. Diff the rendered prompt in golden tests.
Walkthrough: one prompt, three surfaces
- Render with
apply_chat_template(source of truth). - Hit Ollama / laptop path — compare formatting.
- Hit vLLM OpenAI-compatible chat with the same Hub id + revision in traces.
If (2) or (3) diverge from (1), fix the serve path — do not “tune the prompt” until templates match.
Fine-tuning path (sketch)
# Shape — PEFT LoRA; pin versions in portfolio README
from peft import LoraConfig, get_peft_model
# base = AutoModelForCausalLM.from_pretrained(model_id, revision=revision, ...)
# model = get_peft_model(base, LoraConfig(r=16, lora_alpha=32, target_modules=[...]))
# train → model.push_to_hub("you/adapter")Track runs in Weights & Biases or MLflow for LLMOps. Serve adapters via vLLM/TGI when ready — not via notebook generate under load.
Deep dive: Fine-tuning LoRA/QLoRA. Guided path: Build & serve your SLM.
flowchart LR
Base[Base instruct on Hub] --> LoRA[PEFT train]
Data[Curated dataset] --> LoRA
LoRA --> Adapter[Adapter repo]
Adapter --> Merge{Merge or load?}
Merge -->|serve| Eng[vLLM / TGI]
Merge -->|iterate| Eval[Eval suite]
Adapter shipping rules
| Rule | Why |
|---|---|
Record base org/model@revision on the adapter card |
Prevent silent base drift |
| Eval before merge | Merge is hard to undo in prod caches |
| Same template in train and serve | Quality cliff otherwise |
| Push adapter as its own Hub repo | Reviewable artifact, not a Slack zip |
Datasets library (enough to be dangerous)
datasets is how you stream and map large corpora without inventing parquet loaders:
load_datasetwith streaming for huge sources.mapfor tokenization offline- Shard for multi-worker training
Version the processed dataset (hash or Hub dataset revision) the same way you version models — otherwise “we trained on latest” is unreproducible.
flowchart LR
Raw[Raw corpus] --> Map[datasets.map / filter]
Map --> Proc[Processed revision / hash]
Proc --> Train[SFT / LoRA]
Proc --> Eval[Held-out eval]
Ship rule: lineage in every training run: dataset_id@revision + model_id@revision + code SHA.
Licenses and model cards
Before production:
- Read license (Apache-2.0 vs Llama community vs research-only)
- Check intended use and eval claims on the card
- Prefer models with clear tokenizer / chat template docs
- Confirm redistribution rights for fine-tuned derivatives
“On the Hub” ≠ free for commercial use. Legal review is a product gate, not a footnote.
| Card section | Product question |
|---|---|
| License | Can we ship commercially? |
| Intended use / limitations | Are we out of distribution? |
| Training data notes | PII / contamination risk? |
| Eval tables | Do claims match your golden set? |
Hub → serving handoff
| Stage | Tooling |
|---|---|
| Explore / debug | transformers generate |
| Local laptop demos | Ollama / llama.cpp |
| Throughput GPU serve | vLLM / TGI / TensorRT-LLM |
| Managed | HF Inference Endpoints / cloud ML platforms |
Keep the same Hub model id + revision in traces from train → serve → eval. Tokenizer skew between embed and generate services is a classic RAG bug.
sequenceDiagram
participant Dev as Dev / CI
participant Hub as HF Hub
participant Eng as Serve engine
participant GW as Gateway
Dev->>Hub: pin revision + template fixture
Eng->>Hub: pull weights@revision
GW->>Eng: chat request
Note over GW,Eng: traces carry model_id@revision
Alternatives and companions
| Need | Prefer |
|---|---|
| Fast local laptop demos | Ollama / llama.cpp |
| High-throughput GPU serving | vLLM (loads HF weights) |
| Hosted closed models | OpenAI / Anthropic APIs |
| Dataset versioning at scale | datasets + your object store; or lakehouse |
| Distributed train / batch | Ray |
HF Hub is the registry; your serving engine is still a separate decision.
Production gotchas
- Template mismatch between train and serve
- Unpinned revisions — Hub tip moves under you
- OOM from loading full precision 70B on one GPU — quantize or shard
- Tokenizer skew across services (embed vs generate)
- Secrets in Spaces — never bake prod keys into public Space repos
- Rate limits on Hub downloads in CI — cache weights
- Safetensors vs pickle — prefer safetensors; treat arbitrary pickle as code execution
- Adapter / base mismatch — LoRA trained on wrong base revision
- Ignoring
generation_config— surprise temperature/top_p in prod - Gated models — CI without accepted license / token fails intermittently
flowchart TD
Bug[Bad open-weight quality] --> Q{Check}
Q -->|Template| T[Diff apply_chat_template]
Q -->|Revision| R[Pin + compare commit]
Q -->|Serve path| S[Same tokenizer in engine]
Q -->|License| L[Card before ship]
Failure modes checklist
- Demo used instruct model; prod loaded base checkpoint
- CI downloads
mainevery night; evals drift - Embedding model id changed; vector index not rebuilt
- Public Space leaked a fine-tune API key
- Chat UI sent OpenAI-style messages; local path skipped template
- Adapter served against a newer base tip than train
Debugging playbook (first hour)
| Symptom | First checks | Fix direction |
|---|---|---|
| Polite but useless answers | Diff rendered chat template vs train | Fix template / add_generation_prompt |
| Sudden eval drop after “no code change” | Hub main tip moved? |
Pin revision; bisect commits |
| OOM on load | Precision, device_map, model size | Quantize / shard / smaller SLM |
| RAG weirdness after model swap | Embed model id vs index name | Reindex; separate config keys |
| Space / CI auth flakes | Token scope, gated model accept | Machine user + cache |
| Serve ≠ notebook quality | Engine tokenizer vs transformers |
Same revision; golden fixtures |
Ship rule: treat template + revision as first-class config — debug those before prompt poetry.
Anti-patterns
- Floating
mainin prod — silent regressions. - Spaces as production — Gradio is a demo surface.
- Personal PATs in shared CI — rotate to machine users.
- Pickle weights by default — prefer safetensors.
- One config key for embed + generate — accidental swaps.
- Train LoRA, serve different base tip — adapter nonsense.
- Eval only final prose — miss template / tokenizer skew.
Observability: what to log every open-weight call
| Field | Why |
|---|---|
model_id + revision |
Reproducibility |
tokenizer_revision / hash |
Catch skew |
chat_template_hash |
Template drift |
quant_method (if any) |
Quality/latency trade |
generation_config overrides |
Surprise decoding |
| Latency / tokens | Capacity planning |
Pair spans with OpenTelemetry for LLMs.
Security and trust threat note
- Prefer safetensors; treat arbitrary pickle as code execution.
- Public Spaces: never bake prod API keys; use secrets correctly.
- Private Hub repos: scoped machine tokens, not personal PATs.
- Model cards and community files can include unsafe “custom code” — gate
trust_remote_code. - Fine-tune datasets may contain secrets — scrub before Hub push.
safetensors, trust, and CI caches
| Practice | Why |
|---|---|
Prefer safetensors |
Avoid arbitrary pickle code exec |
| Cache Hub downloads in CI | Rate limits + reproducibility |
| Verify checksum / revision | Tip of main moves |
| Separate embed vs gen model ids in config | Prevent accidental swaps |
HF_HOME / cache volume on runners |
Stop re-downloading 10GB nightly |
For private Hub repos: machine users + scoped tokens; never personal PATs in shared runners.
Quantization path (enough for product talks)
Laptop and serving stacks often load quantized weights (bitsandbytes, GGUF via Ollama, AWQ/GPTQ in engines). Know:
- Quantization trades quality for VRAM/throughput
- Eval the same suite at full and quant precision before shipping
- Document quant method next to model id in traces
See Inference: Quantization for inference.
Spaces vs production
Spaces are stakeholder demos. Production needs:
- Your gateway + auth
- A real serving engine
- Pinned revisions
- Eval gates
Do not “promote a Space” by copying Gradio into the critical path.
How to evaluate open-weight changes
| Layer | What to measure |
|---|---|
| Template fixtures | Exact string / hash of rendered prompts |
| Offline golden set | Task metrics vs last pinned revision |
| Serve parity | Notebook generate vs engine chat API |
| Quant gate | Full vs AWQ/GPTQ/GGUF on the same suite |
| RAG embed swap | recall@k after reindex — not just “answers feel fine” |
Promote a new Hub tip only when golden + parity gates pass with lineage recorded.
Hands-on next steps
- Load a small instruct model; print
apply_chat_templateoutput. - Run the same prompt via Ollama and compare formatting.
- Serve with vLLM OpenAI-compatible API; keep the Hub model id in traces.
- Add a CI assert:
revisionpinned +chat_templatepresent.
Micro-project
- Pick one small instruct model on the Hub.
- Pin
revision. - Render three golden prompts with
apply_chat_templateand commit the rendered strings as fixtures. - Generate once with
transformers; once via an OpenAI-compatible local server. - Write a short note: where templates diverged (if at all).
Interview whiteboard: Hub → tokens → serve
Draw three boxes:
- Hub (
org/model@revision, license, card) - Tokenizer (
apply_chat_template→input_ids) - Engine (
transformers.generateor vLLM/TGI)
Then draw an arrow from LoRA adapter repo back into the engine. If any arrow skips the template, mark it red — that is where quality dies silently.
Interview prompts you should be able to answer
- What does “pin a revision” buy you vs tracking
main? - Why can the wrong chat template look like a model failure?
- How do you keep embed and generate tokenizers from drifting in RAG?
- When is Hugging Face Hub not enough and you need vLLM/TGI?
- What belongs on a model card review before commercial ship?
Common interview traps
- Conflating Spaces with production serving
- Saying “we use Hugging Face” without naming template + revision
- Ignoring license because the model is “open”
- Claiming LoRA is magic without base revision lineage
Tradeoffs summary
| Use HF ecosystem when… | Prefer something else when… |
|---|---|
| Open weights, fine-tunes, cards | You only need a hosted chat API |
| You must control tokenizer/template | Laptop demo speed → Ollama first |
| Sharing adapters across teams | Extreme NVIDIA latency → TRT-LLM path |
End-to-end lab checklist (do this once)
flowchart LR
Pick[Pick instruct model] --> Pin[Pin revision]
Pin --> Gold[Golden apply_chat_template fixtures]
Gold --> Gen[transformers generate]
Gen --> Serve[Engine chat API]
Serve --> Gate{Parity + eval OK?}
Gate -->|yes| Ship[Record ids in traces]
Gate -->|no| Fix[Template / revision / quant]
Fix --> Gold
- Pin Hub revision in config.
- Commit three rendered prompt fixtures.
- Generate locally and via engine; compare.
- Log
model_id@revisionon every request. - Optional: PEFT LoRA on a tiny set; push adapter with base revision on the card.
Checklist before production open weights
- License reviewed for commercial use
-
revisionpinned in config + traces - Chat template golden fixtures in CI
- Embed and generate tokenizer versions recorded
- Serving engine load-tested (not notebook
generate) - Adapter base revision matches train-time base
- Safetensors preferred;
trust_remote_codegated - Hub download cache in CI; no personal PATs
Glossary
| Term | Meaning |
|---|---|
| Hub | Hosted git repos for models/datasets |
| Revision | Git commit / tag of a Hub repo |
| Chat template | Jinja (usually) that formats roles → model string |
| PEFT / LoRA | Parameter-efficient fine-tuning adapters |
| Safetensors | Safe weight serialization format |
| TGI | Text Generation Inference — HF’s serving stack |
| Gated model | Requires Hub auth + license acceptance to download |
How it works end-to-end (request lifecycle)
A production open-weight chat turn that starts from the Hub usually looks like this:
- Resolve
org/model@revisionfrom config (never hardcodemainin prod). - Warm tokenizer + engine with that revision (cold start vs keep-alive).
- Authorize tenant + feature flag (which model class is allowed).
- Render messages with
apply_chat_template(or the engine’s chat API that uses the same template). - Generate with pinned decoding params (
temperature,top_p,max_tokens, stop ids). - Decode, strip special tokens, run output validators (JSON schema, PII filters).
- Trace model id, revision, template hash, token counts, TTFT, finish reason.
sequenceDiagram
participant GW as Gateway
participant Cfg as Config
participant Eng as Engine
participant Hub as HF Hub cache
GW->>Cfg: model_id + revision
Cfg->>Eng: load if cold
Eng->>Hub: fetch weights/tokenizer (cached)
GW->>Eng: chat messages
Eng-->>GW: stream tokens + usage
GW->>GW: validate + log revision
If step 4 and step 5 disagree on the template, you will debug “model quality” for weeks. Treat the rendered prompt string as a first-class artifact in golden tests.
Hub auth, private repos, and enterprise mirrors
| Pattern | When |
|---|---|
| Public Hub | OSS models, demos |
| Private Hub repos | Proprietary fine-tunes / adapters |
| HF Enterprise / mirror | Air-gapped or regulated download path |
| Object-store mirror of shards | You own the CDN; Hub is source of truth |
Machine users (bot accounts) with scoped tokens beat personal PATs in CI. Rotate tokens; never bake them into Docker layers or public Spaces. For air-gapped: mirror safetensors + tokenizer files + revision digest into your artifact store and point engines at the mirror.
Download reliability
- Prefer
huggingface_hubwith resume + local cache (HF_HOME/TRANSFORMERS_CACHE) - Pre-pull weights in image build or init containers — not on the first user request
- Cap concurrent Hub pulls in CI to avoid rate limits
- Record etag / commit in deploy manifests
Tokenizer deep dive (product-relevant)
Tokenizers are not interchangeable across model families. Practical rules:
| Rule | Why it matters |
|---|---|
| Same tokenizer for train and serve | Embedding / generation skew kills RAG |
| Special tokens reserved correctly | Truncation and stop behavior |
add_generation_prompt |
Instruct models expect assistant header |
| Max length vs rope scaling | Silent truncation ≠ error |
| Fast vs slow tokenizer | Rare edge cases in CI — pin and test |
# Golden fixture idea
rendered = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
assert "assistant" in rendered.lower() or "<|assistant|>" in rendered
# commit `rendered` to tests/fixtures/prompts/When you change revision, re-golden the fixtures. Diff failures are features, not noise.
Adapter serving strategies
| Strategy | Pros | Cons |
|---|---|---|
| Load base + LoRA at runtime | Fast iteration; small artifacts | Engine must support adapters |
| Merge LoRA into base; push merged | Simple serve path | Larger artifacts; slower iterate |
| Multi-adapter routing | One base, many tenants | Memory + routing complexity |
Document which strategy you use next to Hub ids. Merged models need a new Hub repo or revision; do not pretend the adapter repo is the merged weights.
flowchart TD
Base[Base instruct revision] --> Train[PEFT train]
Train --> Adp[Adapter repo]
Adp --> A{Serve mode}
A -->|runtime LoRA| Eng1[Engine + adapter]
A -->|merge| Merged[Merged Hub repo]
Merged --> Eng2[Engine loads merged]
Eval gates that belong next to Hub ids
Open-weight shipping without evals is cosplay. Minimum gates:
- Golden prompts — template render + smoke generation
- Task suite — your domain questions with rubrics
- Regression vs previous revision — fail on large quality drop
- Safety / refusal — for user-facing products
- Latency / VRAM — at the quant you will actually serve
Log model_id, revision, quant, engine on every eval run so “which Hub tip was this?” is answerable.
Observability fields for open-weight calls
| Field | Example |
|---|---|
model_id |
meta-llama/Meta-Llama-3-8B-Instruct |
revision |
git sha |
engine |
vllm / tgi / transformers |
quant |
fp16 / awq / gguf-q4 |
template_hash |
sha256 of chat_template string |
prompt_tokens / completion_tokens |
usage |
finish_reason |
stop / length |
adapter_id |
optional LoRA repo |
Without these, Hub upgrades are invisible in incident reviews.
Worked walkthrough: support bot on open weights
- Pick instruct 8B on Hub; pin revision; license OK for commercial.
- Golden three system+user prompts; commit rendered templates.
- Embed with a separate Hub embedding model; store revision on the collection name.
- Serve generate via vLLM OpenAI-compatible API; client uses Hub model id in traces.
- Fine-tune LoRA on 2k tickets; push adapter; A/B against base on held-out set.
- Only merge/promote if eval gate passes and p95 latency budget holds.
Anti-patterns (Hugging Face edition)
- Floating
revision=mainin production configs - Training with chat template A, serving with concatenated strings
- Using Spaces as the production inference path
- Loading pickle weights from untrusted repos
- One Hub token with write access shared across all CI jobs
- Changing embedding model without rebuilding the vector index
- Comparing local 3B GGUF quality to the Hub FP16 card claims without re-eval
Memory and sizing intuition
| Situation | Rough instinct |
|---|---|
| 7–8B FP16 | ~16 GB VRAM class for comfortable generate |
| 7–8B 4-bit | Laptop / smaller GPU feasible |
| 70B | Multi-GPU or heavy quant; not a Hub-download-and-hope |
| Embedding models | Small; still pin revision and dimension |
Always measure your batch size and context length — cards quote ideal conditions.
Debugging playbook (first hour of “HF quality regress”)
- Diff
revisionbetween good and bad deploys. - Diff rendered
apply_chat_templateoutput. - Confirm engine tokenizer equals Hub tokenizer for that revision.
- Check whether adapter base revision matches.
- Re-run golden suite offline before touching serving knobs.
What “good” looks like in a design doc
A staff-level open-weight section names: Hub ids + revisions, license decision, template strategy, serving engine, adapter policy, eval gates, and mirror/cache plan. If any of those are “TBD,” the design is not ready.
FAQ (Hugging Face)
Is Hugging Face required to serve open models?
No — but it is the default registry and tokenizer source. Engines can load from disk mirrors.
Can I use transformers.generate in production?
Only for low QPS internal tools. Product traffic wants a serving engine.
Do I need Spaces?
No for production. Yes for demos and hiring portfolios.
What about Inference Endpoints?
Valid managed option — still pin model revision and keep your own evals.
Deep dive: multi-model gateways on Hub artifacts
Products often route across several Hub models (cheap 8B vs large 70B vs embedding). Keep a model registry table:
| logical_name | hub_id | revision | role | max_ctx |
|---|---|---|---|---|
chat_fast |
... |
sha |
generate | 8192 |
chat_strong |
... |
sha |
generate | 8192 |
embed |
... |
sha |
embed | — |
Router code references logical_name only. Hub details change without rewriting agents.
End-to-end lab checklist (do this once)
- Pin revision; print model card license summary
- Golden
apply_chat_templatefixtures - Generate via transformers once; via OpenAI-compatible engine once
- Log model_id + revision on both paths
- Optional: train tiny LoRA; push adapter; load in engine
- Write “Spaces ≠ prod” in the lab README
Putting what / why / how together
| Lens | Hugging Face answer |
|---|---|
| What | Hub + transformers + ecosystem for open weights |
| Why | Reproducible weights, tokenizers, templates, licenses |
| How | Pin revision → template → engine → eval → promote |
Related
Guided Build an LLM from scratch and Build & serve your SLM. Inference: vLLM, Quantization for inference. Advanced: Fine-tuning LoRA/QLoRA. Key tech: Ollama, Weights & Biases. Core: Open-weight vs APIs.