LLM: Fine Tune Ollama gemma3:1b
- Panduan Fine-Tuning Model Gemma 3 1B dengan Dataset JSONL untuk Penggunaan Langsung di Ollama
Halo! Pertanyaanmu tentang fine-tuning model **Gemma 3 1B** (dari Google, tersedia di Hugging Face sebagai `google/gemma-3-1b-it` atau `google/gemma-3-1b-pt` untuk pre-trained) menggunakan file JSONL sebagai input dataset, dan outputnya siap pakai di **Ollama**, sangat relevan. Gemma 3 1B adalah model ringan (1 miliar parameter) yang multimodal (teks + gambar), tapi untuk fine-tuning teks, kita fokus pada format chat/instruction.
Proses ini menggunakan **Hugging Face Transformers + QLoRA** (efisien untuk hardware terbatas, seperti GPU 8GB+) atau **Unsloth** (lebih cepat, 2x lebih efisien). Dataset JSONL harus dalam format **Alpaca/ChatML** (misal: `{"instruction": "...", "input": "...", "output": "..."}` atau array `messages` dengan role/user/assistant).
- Prasyarat:**
- GPU dengan minimal 8GB VRAM (NVIDIA, CUDA 11+). - Python 3.10+. - Akses Hugging Face (buat token di huggingface.co dan accept license Gemma di model card). - Ollama terinstal (download dari ollama.com).
Saya sarankan **QLoRA via HF** karena resmi dari Google, tapi Unsloth lebih cepat untuk dataset kecil. Berikut langkah-langkah lengkap. Estimasi waktu: 1-2 jam untuk 1 epoch pada 10k sampel (tergantung hardware).
- 1. Persiapan Lingkungan dan Dataset
- **Install Dependencies** (jalankan di terminal atau Colab):
``` pip install torch>=2.4.0 transformers>=4.51.3 datasets==3.3.2 accelerate==1.4.0 evaluate==0.4.3 bitsandbytes==0.45.3 trl==0.21.0 peft==0.14.0 protobuf sentencepiece # Opsional untuk Unsloth (lebih cepat): pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git" ```
- **Login Hugging Face**:
```python
from huggingface_hub import login
login("your_hf_token_here") # Ganti dengan token HF-mu
```
- **Siapkan Dataset JSONL**:
- Format contoh (`data.jsonl`): Setiap baris adalah JSON object. Untuk instruction-tuning:
```json
{"instruction": "Apa itu AI?", "input": "", "output": "AI adalah kecerdasan buatan..."}
{"instruction": "Terjemahkan ke Indonesia", "input": "Hello world", "output": "Halo dunia"}
```
Atau format chat (lebih baik untuk Gemma):
```json
{"messages": [{"role": "user", "content": "Apa itu AI?"}, {"role": "assistant", "content": "AI adalah..."}]}
```
- Load dataset:
```python
from datasets import load_dataset
dataset = load_dataset("json", data_files="path/to/your/file.jsonl", split="train")
dataset = dataset.train_test_split(test_size=0.1) # 90% train, 10% eval
```
- 2. Load Model dan Setup Fine-Tuning (Menggunakan QLoRA)
- Gunakan `gemma-3-1b-pt` untuk pre-trained (atau `-it` untuk instruction-tuned). - Code lengkap (adaptasi dari guide resmi Google):
```python import torch from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig, TrainingArguments from peft import LoraConfig, get_peft_model from trl import SFTTrainer from datasets import load_dataset # Sudah di atas
# Load tokenizer dan model dengan 4-bit quantization (hemat memori)
model_id = "google/gemma-3-1b-pt"
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16, # Atau float16 jika GPU lama
bnb_4bit_use_double_quant=True
)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=quantization_config,
device_map="auto",
torch_dtype=torch.bfloat16
)
tokenizer = AutoTokenizer.from_pretrained(model_id)
tokenizer.pad_token = tokenizer.eos_token # Penting untuk padding
# Format dataset ke chat template (jika pakai messages)
def formatting_prompts_func(example):
texts = []
for msg in example["messages"]:
if msg["role"] == "user":
texts.append(f"<start_of_turn>user\n{msg['content']}<end_of_turn>")
elif msg["role"] == "assistant":
texts.append(f"<start_of_turn>model\n{msg['content']}<end_of_turn>")
return {"text": "".join(texts)} # Gemma pakai template ini
dataset = dataset.map(formatting_prompts_func) # Apply ke train/eval
# Setup LoRA (efisien, hanya train 1-5% parameter)
peft_config = LoraConfig(
r=16, # Rank LoRA
lora_alpha=32,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"] # Untuk Gemma
)
model = get_peft_model(model, peft_config)
# Training args
training_args = TrainingArguments(
output_dir="./gemma-3-1b-finetuned",
num_train_epochs=1, # Mulai dengan 1, naikkan jika perlu
per_device_train_batch_size=4, # Sesuaikan VRAM
gradient_accumulation_steps=4,
learning_rate=2e-4,
fp16=True, # Atau bf16
logging_steps=10,
save_steps=500,
evaluation_strategy="steps",
eval_steps=500,
report_to="none" # Atau "wandb" untuk logging
)
# Trainer
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
dataset_text_field="text", # Field yang berisi prompt + output
max_seq_length=512, # Sesuaikan context length
args=training_args,
peft_config=peft_config
)
trainer.train()
trainer.save_model("./gemma-3-1b-finetuned") # Simpan adapter LoRA
```
- Jalankan `trainer.train()` – monitor loss di console.
- Alternatif Unsloth (Lebih Cepat, 2x Speed)**: Ganti load model dengan:
```python from unsloth import FastLanguageModel model, tokenizer = FastLanguageModel.from_pretrained("google/gemma-3-1b", dtype=torch.float16, load_in_4bit=True)
- Lanjutkan dengan LoRA dan trainer serupa, Unsloth otomatis optimasi.
```
- 3. Merge Model dan Convert ke GGUF (untuk Ollama)
- **Merge LoRA Adapter ke Base Model** (buat model full, bukan adapter saja):
```python
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("google/gemma-3-1b-pt", torch_dtype=torch.bfloat16, device_map="auto")
model = PeftModel.from_pretrained(base_model, "./gemma-3-1b-finetuned")
merged_model = model.merge_and_unload()
merged_model.save_pretrained("./gemma-3-1b-merged")
tokenizer.save_pretrained("./gemma-3-1b-merged")
```
- **Convert ke GGUF** (format Ollama):
- Install llama.cpp: `git clone https://github.com/ggerganov/llama.cpp && cd llama.cpp && make`. - Convert: `./convert_hf_to_gguf.py ./gemma-3-1b-merged --outdir ./gguf --outtype f16` (untuk full precision). - Quantize (hemat ruang, e.g., Q4_K_M): `./quantize ./gguf/gemma-3-1b-merged.gguf ./gguf/gemma-3-1b-merged-q4.gguf Q4_K_M`. - Alternatif mudah: Upload merged model ke Hugging Face Hub, lalu gunakan HF Space "ggml-org/gguf-my-repo" untuk auto-convert ke GGUF.
- 4. Deploy ke Ollama
- Buat file **Modelfile** (di folder kosong):
``` FROM ./gemma-3-1b-merged-q4.gguf # Path ke file GGUF-mu TEMPLATE """Template:If .System<|im_start|>system\nTemplate:.System<|im_end|>\nTemplate:EndTemplate:If .Prompt<|im_start|>user\nTemplate:.Prompt<|im_end|>\nTemplate:End<|im_start|>assistant\n""" PARAMETER stop "<|im_end|>" PARAMETER temperature 0.7 PARAMETER top_p 0.9 ``` - Template ini untuk format Gemma (sesuaikan jika datasetmu beda).
- Import ke Ollama:
``` ollama create my-gemma3-finetuned -f Modelfile ollama run my-gemma3-finetuned ```
- Test: Ketik prompt di Ollama CLI, atau integrasikan ke app.
- Tips Tambahan
- **Ukuran Dataset**: Mulai dengan 1k-10k baris JSONL untuk test. Lebih banyak = lebih baik, tapi overfit jika <100. - **Evaluasi**: Tambah `compute_metrics` di trainer untuk perplexity/accuracy. - **Hardware**: Di Colab (free T4), gunakan Unsloth. Lokal, pakai `nvidia-smi` untuk monitor VRAM. - **Troubleshoot**: Jika error quantization, cek CUDA version. Untuk Gemma 3 spesifik, context window 128K, tapi batasi max_seq_length ke 2048 awal. - **Biaya**: Gratis di Colab, tapi push ke HF butuh akun.
Jika datasetmu spesifik (e.g., function calling), sesuaikan prompt template. Kalau butuh bantuan code lengkap atau debug, share detail dataset! Sumber: Guide resmi Google, Unsloth docs, dan tutorial HF.