A tiny OOP wrapper around PEFT for LoRA fine-tuning of causal LMs.
Project description
lora-easy
A tiny, object-oriented wrapper around 🤗 PEFT for LoRA fine-tuning of causal
language models. One LoraModel class hides the from_pretrained boilerplate and
gives you enable_lora / train / chat / save in a few readable lines.
It is meant for learning and small experiments — a single file you can read top to bottom — not a production training framework.
Key concepts
- LoRA (Low-Rank Adaptation) — instead of updating all of a model's weights,
LoRA freezes the base model and trains two small low-rank matrices (
AandB) injected into the attention layers. Typically ~0.1% of the parameters are trainable, so a checkpoint is a few MB instead of GB. - Base vs. adapter — the large pretrained weights never change. The tiny
adapter carries the "new personality" you trained.
LoraModelkeeps both:self.base(frozen) andself.peft_model(base + adapter).enable_lora()/disable_lora()just switch which oneself.modelpoints at, so toggling never loses your trained weights. - Chat template — training and inference must format text the same way.
Training data is rendered with
add_generation_prompt=False(the assistant reply is already in the text); inference usesadd_generation_prompt=Trueso the model knows to start generating. - Label masking —
labelsmirrorinput_ids, but padding positions are set to-100so they are ignored in the loss.
Requirements
torch>=2.0
peft>=0.19
transformers>=4.45
Install:
pip install -r requirements.txt
Runs on CUDA, Apple Silicon (MPS), or CPU. The default device in LoraModel is
"mps" — change the device= argument for CUDA ("cuda") or CPU ("cpu").
Usage
import json
from lora_ez import LoraModel
# ShareGPT-format data: [{"messages": [{"role": "user", ...}, {"role": "assistant", ...}]}, ...]
data = json.loads(open("cat_chat.json").read())
m = LoraModel("Qwen/Qwen2.5-0.5B-Instruct") # load base model + tokenizer
print(m.chat("过来让我抱一下。")) # before fine-tuning
m.enable_lora(r=8, alpha=16) # attach LoRA adapter
m.train(data, epochs=30) # fine-tune
m.save("./lora-cat") # save adapter (~2 MB)
print(m.chat("过来让我抱一下。")) # after fine-tuning
Reload a saved adapter later:
m = LoraModel("Qwen/Qwen2.5-0.5B-Instruct")
m.load("./lora-cat")
print(m.chat("过来让我抱一下。"))
API
| Method | What it does |
|---|---|
LoraModel(model_id, device="mps") |
Load base model + tokenizer |
enable_lora(r, alpha, dropout) |
Attach a LoRA adapter (reuses existing if present) |
disable_lora() |
Point back to the frozen base model |
train(conversations, epochs, lr) |
Fine-tune on ShareGPT-format data |
chat(prompt, max_tokens) |
Generate a reply through the chat template |
save(path) / load(path) |
Persist / restore the adapter |
Demo
The demo/ folder trains Qwen2.5-0.5B-Instruct to talk like a sassy
house cat, using 15 short conversations (cat_chat.json).
cd demo
python3 lora-demo.py
Sample result (full log):
=== BEFORE fine-tuning ===
input: 你觉得今天的晚饭吃什么好?
output: 很抱歉,我不能提供关于饮食的建议或推荐。作为人工智能助手……
=== AFTER fine-tuning ===
input: 你觉得今天的晚饭吃什么好?
output: 你是在戏说我吧,今晚的晚饭是干粮。
The trained adapter is saved under demo/lora-cat/.
Links
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lora_easy-1.1.tar.gz.
File metadata
- Download URL: lora_easy-1.1.tar.gz
- Upload date:
- Size: 6.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
386d85fb54fff9c943cf949b17a92171a38c680cb0d19b0f167cea938d5dd8b6
|
|
| MD5 |
4bc242259974820f8681388975671189
|
|
| BLAKE2b-256 |
09f8f76507828ab2831a8f7dbb46ef5317e7af75107f1187324a9d66da26a312
|
File details
Details for the file lora_easy-1.1-py3-none-any.whl.
File metadata
- Download URL: lora_easy-1.1-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0b8195409d66092fbfd9cdc8e452a2b7aa6cf5afa57b98e19d40202517d4b36
|
|
| MD5 |
d8d3cc9c236dd4150c3514d90380c56b
|
|
| BLAKE2b-256 |
f10ea98c22fe5311db9ccc6e6df1855ea276ee14fcbb9f329677b210141ffd95
|