From classic neural networks to LLMs — and a live demo
Jude Michael Teves
Fine-tuning doesn't change what the model knows.
It changes how it behaves — format, tone, tools, and guardrails.
We're not teaching it Python. It already knows Python.
We're teaching it your version of how to respond.
Deep CNNs prove learned features transfer. CV leads the transfer learning wave.
Language gets vector representations. Encoder-decoder for translation (attention added by Bahdanau 2015). Generative models (GANs) emerge.
VGGNet (2014) and ResNet (2015) become the go-to pretrained backbones. Skip connections unlock very deep networks. CV transfer learning — freeze pretrained base, retrain head — becomes the standard recipe. Demo uses this era.
Attention is All You Need. Self-attention proved superior to RNNs at scale and eventually displaced them. Everything modern runs on this architecture.
Transfer learning arrives in NLP. Pretrain on text → SFT (supervised fine-tuning) on tasks. Same paradigm as CV, 3 years later.
175B params. Emergent few-shot capability without fine-tuning. Performance scales predictably with data, compute, and model size.
OpenAI's SFT + RLHF pipeline teaches the model to follow instructions — not just predict text. The recipe behind ChatGPT. LoRA (2021 paper) is a separate, unrelated development.
LoRA paper (2021) took off when Llama, Mistral, Falcon were released openly. Suddenly anyone could fine-tune a capable model cheaply. This is what we're doing today.
o1 (Sept 2024): chain-of-thought as trained behavior. DeepSeek-V3 (MoE, 671B, Dec 2024) + DeepSeek-R1 (reasoning, Jan 2025): frontier-level results from open models. MoE enables massive models on manageable hardware.
Models now plan, use tools, and act autonomously — not just chat. SLMs run locally* on consumer hardware. Phi-3 Mini (3.8B, 2024) ≈ GPT-3.5 on specific tasks. Quantization compresses 754B models to fit a workstation.
SLMs are closing the gap: Phi-3 Mini (3.8B) matches GPT-3.5 on many benchmarks. A focused, well-trained small model today can match a large one from 1–2 years ago — on specific tasks. For broad reasoning, bigger still wins.
| Factor | SLM ✓ | LLM ✗ |
|---|---|---|
| Hardware | Free T4 GPU | Multi-GPU cluster |
| Training time | mins–hours (config-dependent) | Days–weeks |
| Privacy | Fully local | Often cloud API |
| Data needed | Dozens of examples | Thousands+ |
| Cost | Low compute (fits free tier) | $$–$$$ |
The tradeoff: SLMs are less capable. For a proof-of-concept or behavior tuning, they're more than enough.
| Task | Era | Hardware | Time |
|---|---|---|---|
| Train ResNet from scratch (ImageNet) | 2015–2016 | 4–8 GPUs | Days |
| Fine-tune ResNet (CV transfer learning) | 2016–2018 | 1–2 GPUs | Hours–days |
| Pretrain BERT (full) | 2018 | 64 TPUs, 4 days | Days |
| Fine-tune BERT (downstream task) | 2018–2020 | 1 GPU | Hours |
| Pretrain GPT-3 / Llama 70B | 2020–2023 | Thousands of GPUs | Months |
| Full fine-tune large LLM (7B+) | 2023–now | Multi-GPU server | Days–weeks |
| LoRA fine-tune SLM (1B–3B) ← today | 2023–now | Free T4 GPU | Minutes–hours |
| Approach | What changes | When to use | Cost |
|---|---|---|---|
| Full Pretraining from scratch | All weights, random init | Building a new model entirely. Nobody does this casually. | Millions of $$$ |
| Full Fine-Tuning | All weights, pretrained init | You have lots of domain data and serious compute. Risk: catastrophic forgetting. | $$–$$$ |
| Partial Fine-Tuning | Top layers only (like classic CV) | Classic transfer learning approach. Faster than full, but still touches the base model. | $–$$ |
| LoRA (Parameter-Efficient) | Tiny adapter only — base frozen | Fine-tuning behavior, format, tools. Small datasets. Local hardware. | Low compute |
| RAG (not fine-tuning) | Nothing — retrieves at inference | When you need live facts, doc search, or a knowledge base. Different tool entirely. | $ |
Fine-tuning shapes behavior. RAG shapes knowledge. They solve different problems and often complement each other.
MobileNetV2 · CIFAR-10 · Keras
# Freeze pretrained weights — base model not modified base_model = keras.applications.MobileNetV2(include_top=False, weights='imagenet') base_model.trainable = False # conceptually similar to LoRA, but less efficient # Add your task-specific head on top x = layers.GlobalAveragePooling2D()(base_model.output) x = layers.Dropout(0.2)(x) predictions = layers.Dense(10, activation='softmax')(x)
base_model.trainable = False — freezing the baseThis required understanding CNN architectures, Keras APIs, preprocessing, and training dynamics. Technical depth was — and still is — required. The tools got faster; the understanding needed to use them well hasn't gone away.
github.com/Cyntwikip/Machine-Learning — transfer_learning.ipynb
Pre-2022 — CV & NLP
Agents: not yet a practical concept at scale
2022–2023 — LLMs + RAG
Agents: possible but API-dependent — vendor controls the model's behavior
2024–now — LoRA + SLMs
Agents: SLMs run locally as agents — sovereign, controllable, no API dependency
The tooling is faster. The expertise required to use it well isn't going away.
DE gets you the data. SWE brings it to production. The layer in between — quality judgment, evaluation design, training dynamics, statistical interpretation — is where DS/ML expertise takes over.
LoRA · Coding Assistant · Tool Calling · Guardrails
Instead of retraining all 1 billion weights, you attach a small adapter to specific layers and only train that.
Think of it as sticky notes on a textbook — you're not rewriting the book, just adding annotations that change how it answers you.
All other weights stay frozen. The adapter is a separate file — can be loaded onto any copy of the same base model.
| — | Full Fine-Tuning | LoRA (what we're doing) |
|---|---|---|
| Params updated | All — 1B+ weights | ~10-12M (~1% of model) |
| GPU requirement | Multiple high-end GPUs | Single T4 (Colab free tier) |
| Training time | Hours to days | Minutes to hours |
| Storage per task | Full model copy (~2GB+) | Small adapter (~20-25MB) |
| Base model | Modified — needs separate backup | Untouched — adapter is separate |
| Catastrophic forgetting | Real risk on small datasets | Minimized — base frozen |
| Multi-task | Separate full model per task | Swap adapters on same base |
| Parameter | Value | Why it matters |
|---|---|---|
| r (rank) | 16 | Size of adapter matrices. Higher = more expressive, slower. 16 is a safe default for behavior/format tuning. |
| load_in_4bit | True | Quantizes base model to 4-bit (from 16-bit) — reduces weight storage ~4×. Without this, 1B model won't fit on a T4. |
| max_steps | 60 | Total gradient updates. Overrides epochs. With 31 examples, batch 8 → ~4 steps/epoch → 15 epochs total. |
| gradient_accumulation | 4 | Effective batch = 2 × 4 = 8. Simulates larger batches without extra VRAM — common trick on constrained hardware. |
| train_on_responses_only | enabled | Guardrail — masks user/system tokens. Model only learns from assistant outputs. |
Full parameter list in appendix →
This is where DE hands off to DS/ML — and where the work stops being a pipeline problem.
Reality: Developing intuition for all of this — data quality, training dynamics, meaningful eval — takes weeks to months of hands-on iteration. The fine-tuning loop can run in minutes for a small demo config. The judgment to run it well still doesn't come fast.
Model answers immediately. No tool needed.
"How do I reverse a list?"
"What is a decorator?"
"Explain list comprehensions"
Model outputs a <tool_call> block.
Off-topic questions get a polite decline.
"What's the weather today?"
"Write me a poem."
"What should I have for lunch?"
code_and_run — natural language → model generates Python → executes it → returns output. End-to-end in one tool call.
Llama-3.2-1B-Instructdataset.json from Drivecode_and_run executionWATCH FOR
<tool_call> block in output
✓ code_and_run actually executes Python
Masks all user and system tokens during training. The model only learns from assistant outputs — can't accidentally learn to act like a user or repeat the system prompt.
The LoRA adapter is a separate file. Roll back, swap, or A/B test multiple adapters on the same base without touching the original weights.
Every training example carries a system prompt. The model internalizes this as default behavior: only answer coding questions, decline everything else.
Runs entirely locally. No data leaves your machine.
Relevant when working with internal codebases or sensitive data.
…and what to keep in mind
All trainable on your own data, on your own machine —
but this is prototyping scale, not a production deployment.
Sovereign AI is an emerging institutional priority — the goal is reducing dependency on vendor infrastructure and keeping critical AI workflows under your own control. Owning a fine-tuned model is a concrete first step toward that.
31 examples teaches format and behavior. Real production fine-tuning needs hundreds to thousands of quality examples and a proper evaluation pipeline — not just eyeballing the output.
Fine-tuning shapes how it responds, not what facts it reliably knows. Small static policies can be baked in — but the model may still paraphrase or partially hallucinate them with confidence. RAG gives you exact retrieval and auditability even for static docs. Best practice: fine-tune for behavior, RAG for facts.
Fine-tuning doesn't fix hallucination. A 1B model will still produce plausible-sounding wrong answers. Always verify generated code before running it in production.
Technical understanding is still required. The tools got faster —
knowing what good training data looks like and how to evaluate results doesn't go away.
Jude Michael Teves
LORA CONFIG
| Param | Value |
|---|---|
| r | 16 |
| lora_alpha | 16 |
| lora_dropout | 0 |
| bias | "none" |
| use_gradient_checkpointing | "unsloth" |
| load_in_4bit | True |
TRAINING CONFIG
| Param | Value |
|---|---|
| max_steps | 60 |
| per_device_train_batch_size | 2 |
| gradient_accumulation_steps | 4 |
| learning_rate | 2e-4 |
| warmup_steps | 5 |
| weight_decay | 0.01 |
| lr_scheduler_type | "linear" |
| optim | "adamw_8bit" |
| train_on_responses_only | enabled |