A complete 3-stage Large Language Model fine-tuning pipeline specialized for the medical domain, trained entirely on free Google Colab (T4 GPU) using QLoRA and DPO alignment.
📌 Project Overview
This project demonstrates how to fine-tune a large language model from scratch using a professional 3-stage training pipeline on the medical domain — all within the constraints of free cloud compute. It covers domain adaptation, instruction fine-tuning, and RLHF-style preference alignment using Direct Preference Optimization (DPO).
The final model is a medical conversational assistant capable of answering health-related questions using evidence-based responses.
🗂️ Repository Structure
fine tune model/
└── finetuned medical chatbot/
├── adapter_model.safetensors # Trained LoRA adapter weights
├── adapter_config.json # LoRA configuration (r, alpha, target modules)
├── tokenizer.json # Tokenizer vocabulary and rules
└── tokenizer_config.json # Tokenizer settings and special tokens
Note: This repository contains only the LoRA adapter weights (~50MB), not the full model weights (~2GB). You need to load the base TinyLlama model separately and apply the adapter on top. See How to Use below.
🧠 3-Stage Training Pipeline
Stage 1 — Domain Adaptation
Teaches the model medical vocabulary, terminology, drug names, disease descriptions, and clinical language before any instruction formatting.
Property
Value
Dataset
medalpaca/medical_meadow_wikidoc
Samples
5,000 medical Wikipedia articles
Format
Raw text (no Q&A structure)
Loss
Next-token prediction
Learning rate
3e-4
Stage 2 — Instruction Fine-tuning
Teaches the model to follow medical instructions and respond to patient questions in a helpful, structured format.
Property
Value
Dataset
lavita/ChatDoctor-HealthCareMagic-100k
Samples
3,000 real doctor-patient Q&A pairs
Format
ChatML (system / user / assistant)
Loss
Cross-entropy on response tokens only
Learning rate
2e-4
Stage 3 — DPO Alignment (RLHF Alternative)
Teaches the model to prefer safe, accurate, evidence-based responses over hallucinated or dangerous ones using human preference pairs.
1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
3from peft import PeftModel
45# Load base model with 4-bit quantization6bnb_config = BitsAndBytesConfig(7 load_in_4bit=True,8 bnb_4bit_quant_type="nf4",9 bnb_4bit_compute_dtype=torch.bfloat16,10)1112base_model = AutoModelForCausalLM.from_pretrained(13"TinyLlama/TinyLlama-1.1B-Chat-v1.0",14 quantization_config=bnb_config,15 device_map="auto",16)1718# Load tokenizer19tokenizer = AutoTokenizer.from_pretrained("finetuned medical chatbot/")20tokenizer.pad_token = tokenizer.eos_token
2122# Apply LoRA adapter23model = PeftModel.from_pretrained(base_model,"finetuned medical chatbot/")24model.eval()25print("Model ready!")
Step 3 — Run inference
python
1defmedical_chat(question):2 prompt =(3f"<|system|>\nYou are a helpful and accurate medical assistant. "4f"Provide evidence-based information and always recommend consulting "5f"a qualified doctor for personal medical advice.</s>\n"6f"<|user|>\n{question}</s>\n"7f"<|assistant|>\n"8)9 inputs = tokenizer(prompt, return_tensors="pt").to(model.device)10with torch.no_grad():11 outputs = model.generate(12**inputs,13 max_new_tokens=250,14 temperature=0.3,15 do_sample=True,16 top_p=0.9,17 repetition_penalty=1.2,18)19 response = tokenizer.decode(outputs[0], skip_special_tokens=True)20return response.split("<|assistant|>")[-1].strip()2122# Try it23print(medical_chat("What are the symptoms of diabetes?"))24print(medical_chat("How is hypertension treated?"))
All datasets are publicly available on HuggingFace — no login required.
📄 License
This project is for educational and research purposes only.
The trained model should not be used for real medical diagnosis or treatment decisions.
Always consult a qualified healthcare professional for medical advice.