Fine-Tuning Small Models for Edge Deployment
Big models don\u2019t fit on edge hardware, but small ones can learn your domain. A practical guide to fine-tuning Gemma-class small models and deploying them on-device.
Published on • August 9, 2026
AI Assistant

A 400B parameter model does impressive things — and it needs a data center. Phones, IoT devices, and air-gapped kiosks have no cloud, limited RAM, and strict latency budgets. The answer isn’t to shrink the cloud model; it’s to fine-tune a small model that already fits the hardware until it’s good enough at your specific task.
In this post, you will learn how to fine-tune a small Gemma-class model (2B–9B) for a narrow task, quantize it for edge deployment, and validate that it holds up on-device.
Why small + fine-tuned beats large + cloud for edge
Small models are weak at general reasoning but perfectly capable at narrow, repetitive tasks: intent classification, summarization of short text, code completion for a single DSL, or extraction with a fixed output schema. Fine-tuning specializes the model so it masters your task at 1/100th of the memory footprint.
1. Prepare a focused dataset
Fine-tuning on a huge, unfocused dataset is how you get a mediocre model. For edge, curate 500–5,000 high-quality examples in the exact input/output shape the device will use:
import datasets, json
examples = [
{"input": "set the thermostat to 72",
"output": '{"action": "set_temperature", "target": 72, "unit": "f"}',
"schema": "home_automation"},
# ... a few thousand more, covering every device command
]
ds = datasets.Dataset.from_list(examples)
ds.save_to_disk("edge_intent.jsonl")
Format each example as a chat-style prompt with a system instruction, so the model learns both the task and the output format.
2. Fine-tune with LoRA on the base model
Full fine-tuning of a 9B model is wasteful. Use LoRA (Low-Rank Adaptation) to train a small set of adapter weights while the base weights stay frozen — memory drops dramatically:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model
from trl import SFTTrainer
model_id = "google/gemma-2b-it"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id, torch_dtype=torch.bfloat16
)
lora_config = LoraConfig(
r=16, lora_alpha=32, target_modules=["q_proj", "v_proj"], lora_dropout=0.05,
)
model = get_peft_model(model, lora_config)
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=ds,
max_seq_length=1024,
args=TrainingArguments(
output_dir="gemma2b-edge",
num_train_epochs=3,
per_device_train_batch_size=4,
learning_rate=2e-4,
fp16=True,
),
)
trainer.train()
One training run on a single consumer GPU. The result is a small adapter (tens of MB) — that’s what ships to the edge.
3. Merge, quantize, and export for edge runtimes
For deployment, merge the LoRA adapter back into the base model, then quantize to INT4 or INT8 so it fits in edge memory:
merged = model.merge_and_unload()
merged.save_pretrained("gemma2b-edge-merged")
tokenizer.save_pretrained("gemma2b-edge-merged")
# llama.cpp-style GGUF quantization for CPU/edge
!llama-quantize gemma2b-edge-merged/model.gguf Q4_K_M
Depending on your target, the exported model runs through:
- llama.cpp / Ollama for CPU-heavy devices and laptops,
- TensorFlow Lite / MediaPipe on mobile,
- ONNX Runtime for embedded Linux.
4. Validate on-device, not just on a leaderboard
Edge deployment changes the game: memory ceiling, temperature of the silicon, token speed. Validate with a holdout set of real device inputs, measuring both accuracy and latency:
import time, llama_cpp
llm = llama_cpp.Llama(model_path="gemma2b-edge-q4.gguf", n_ctx=1024)
acc = 0
for example in holdout:
t0 = time.perf_counter()
out = llm.create_chat_completion([{"role": "user", "content": example["input"]}])
latency_ms = (time.perf_counter() - t0) * 1000
acc += out["choices"][0]["message"]["content"] == example["output"]
assert latency_ms < 500, f"too slow: {latency_ms:.0f}ms"
print(f"accuracy: {acc/len(holdout):.1%}")
Set the latency budget as a hard test, not a wish. If it fails, prune the context (n_ctx) or step down a quantization level.
Putting It All Together
The full recipe — dataset prep, LoRA training, quantization, and the on-device validation harness — is in this gist. Run it for a single narrow task and you’ll have a model that fits in the device and passes its accuracy and latency gates.
Conclusion & Next Steps
You can now specialize a small model for your edge task, shrink it with LoRA + quantization, and prove it on real hardware. Next steps: expand the dataset with adversarial edge cases, A/B the fine-tuned model against the base model on the holdout set to quantify the lift, and wire the accuracy/latency tests into CI so any retraining run can’t silently regress.
References / Sources
- Gemma model docs and fine-tuning. https://ai.google.dev/gemma/docs
- Gemma on Hugging Face (transformers + PEFT). https://huggingface.co/docs/transformers
- llama.cpp for edge quantization and inference. https://github.com/ggml-org/llama.cpp