Skip to main content

A tiny OOP wrapper around PEFT for LoRA fine-tuning of causal LMs.

Project description

lora-easy

lora-easy — LoRA fine-tuning

python peft license

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 (A and B) 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. LoraModel keeps both: self.base (frozen) and self.peft_model (base + adapter). enable_lora() / disable_lora() just switch which one self.model points 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 uses add_generation_prompt=True so the model knows to start generating.
  • Label maskinglabels mirror input_ids, but padding positions are set to -100 so 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

lora_easy-1.5.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lora_easy-1.5-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file lora_easy-1.5.tar.gz.

File metadata

  • Download URL: lora_easy-1.5.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for lora_easy-1.5.tar.gz
Algorithm Hash digest
SHA256 33500654716d273cdc337f870b2332fae2a17b9c6e4c5fa772c48a284e68e8f2
MD5 740dd3c09f68a482f41dae17a17b5267
BLAKE2b-256 699031825cb352213a91dcd92285b64da9a20adf4ff70e31446e9a3fa00c3e83

See more details on using hashes here.

File details

Details for the file lora_easy-1.5-py3-none-any.whl.

File metadata

  • Download URL: lora_easy-1.5-py3-none-any.whl
  • Upload date:
  • Size: 11.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for lora_easy-1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 812ce83f0d8c1916f0b091d16f53f977690867a8b250da3fb2965cb90b068a3f
MD5 39289e0fe651d0da7ee99f6627437270
BLAKE2b-256 a7b356e3afb080aa4b4ed15cf51e455f86331f3c30a3811d0b6c2835f60b550d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page