Artificial Intelligence 24 min read

Fine-Tuning Large Language Models with LoRA: A Step-by-Step Guide and Code Example

This article demonstrates the before-and-after effects of fine‑tuning a large language model, explains the concept with analogies, details hardware setup, dataset preparation, LoRA configuration, training arguments, and provides complete Python code for a pure‑framework fine‑tuning workflow.

Cognitive Technology Team
Cognitive Technology Team
Cognitive Technology Team
Fine-Tuning Large Language Models with LoRA: A Step-by-Step Guide and Code Example

The article begins by showing clear visual comparisons of a large model’s output before and after fine‑tuning, highlighting the change in tone and reduced reasoning time.

What is model fine‑tuning? It is likened to giving a "top student" extra tutoring to turn a generalist into a specialist, using a medical dataset as an example. Analogies such as a robot learning to draw cats with hats illustrate the process.

Practical cases are presented, including adapting a smart speaker to understand a dialect and adding a food‑filter to a camera, to convey how fine‑tuning modifies specific capabilities.

Hardware Configuration

GPU: NVIDIA GeForce RTX 4060

CPU: Intel Core i7‑13700H

Memory: 16 GB (available 8.8 GB / 15.7 GB)

Fine‑Tuning Workflow

(1) Dataset Preparation

The dataset comes from the Magic‑Deck community ( medical‑o1‑reasoning‑SFT ) and includes a JSON format with fields Question , Complex_CoT , and Response . Complex chain‑of‑thought data is emphasized as essential for deep reasoning.

(2) Fine‑Tuning Code (pure‑framework implementation)

pip install torch transformers peft datasets matplotlib accelerate safetensors
import torch
import matplotlib.pyplot as plt
from transformers import (AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, TrainerCallback)
from peft import LoraConfig, get_peft_model
from datasets import load_dataset
import os
# Paths (replace with actual locations)
model_path = r"your_model_path"
data_path = r"your_dataset_path"
output_path = r"your_output_path"
# Ensure GPU is available
assert torch.cuda.is_available(), "GPU is required for training!"
device = torch.device("cuda")
# Custom loss callback
class LossCallback(TrainerCallback):
def __init__(self):
self.losses = []
def on_log(self, args, state, control, logs=None, **kwargs):
if "loss" in logs:
self.losses.append(logs["loss"])
# Data processing
def process_data(tokenizer):
dataset = load_dataset("json", data_files=data_path, split="train[:1500]")
def format_example(example):
instruction = f"诊断问题:{example['Question']}\n详细分析:{example['Complex_CoT']}"
inputs = tokenizer(f"{instruction}\n### 答案:\n{example['Response']}<|endoftext|>", padding="max_length", truncation=True, max_length=512, return_tensors="pt")
return {"input_ids": inputs["input_ids"].squeeze(0), "attention_mask": inputs["attention_mask"].squeeze(0)}
return dataset.map(format_example, remove_columns=dataset.column_names)
# LoRA configuration
peft_config = LoraConfig(r=16, lora_alpha=32, target_modules=["q_proj", "v_proj"], lora_dropout=0.05, bias="none", task_type="CAUSAL_LM")
# Training arguments
training_args = TrainingArguments(
output_dir=output_path,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
num_train_epochs=3,
learning_rate=3e-4,
fp16=True,
logging_steps=20,
save_strategy="no",
report_to="none",
optim="adamw_torch",
no_cuda=False,
dataloader_pin_memory=False,
remove_unused_columns=False,
)
# Main training function
def main():
os.makedirs(output_path, exist_ok=True)
tokenizer = AutoTokenizer.from_pretrained(model_path)
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16, device_map={"": device})
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()
dataset = process_data(tokenizer)
loss_callback = LossCallback()
def data_collator(data):
batch = {
"input_ids": torch.stack([torch.tensor(d["input_ids"]) for d in data]).to(device),
"attention_mask": torch.stack([torch.tensor(d["attention_mask"]) for d in data]).to(device),
"labels": torch.stack([torch.tensor(d["input_ids"]) for d in data]).to(device)
}
return batch
trainer = Trainer(model=model, args=training_args, train_dataset=dataset, data_collator=data_collator, callbacks=[loss_callback])
print("Starting training...")
trainer.train()
trainer.model.save_pretrained(output_path)
print(f"Model saved to: {output_path}")
plt.figure(figsize=(10, 6))
plt.plot(loss_callback.losses)
plt.title("Training Loss Curve")
plt.xlabel("Steps")
plt.ylabel("Loss")
plt.savefig(os.path.join(output_path, "loss_curve.png"))
print("Loss curve saved")
if __name__ == "__main__":
main()

Explanation of Key Components

Libraries: PyTorch for tensor operations, Transformers for model/tokenizer handling, PEFT for parameter‑efficient fine‑tuning (LoRA), Datasets for loading JSON data, Matplotlib for visualizing loss.

Path and GPU checks: Users must replace placeholder paths and ensure CUDA is available.

LossCallback: Records loss values during training for later plotting.

process_data: Loads the first 1500 records, formats each example by concatenating the question, chain‑of‑thought analysis, and answer, then tokenizes with padding to a length of 512.

LoRA configuration: Low‑rank adaptation with rank 16, α = 32, targeting the query and value projection matrices, dropout 0.05, and no bias training, suitable for causal language modeling.

TrainingArguments: Small batch size (2) with gradient accumulation (4) to emulate batch 8, three epochs, learning rate 3e‑4, mixed‑precision (fp16), and no intermediate checkpoint saving.

data_collator: Packs tokenized inputs into tensors on the GPU and sets labels equal to the input IDs for causal LM training.

Trainer: Handles the training loop, logging, and callback integration.

Post‑training: Saves the fine‑tuned model and generates a loss‑curve PNG.

The article concludes with acknowledgments to DeepSeek for code assistance and notes that the current fine‑tuning setup is basic, leaving room for dataset refinement, hyper‑parameter tuning, and code structure improvements.

LoRAmodel trainingPyTorchLLM fine-tuningHuggingFace
Cognitive Technology Team
Written by

Cognitive Technology Team

Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.