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.