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.6.tar.gz (10.6 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.6-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: lora_easy-1.6.tar.gz
  • Upload date:
  • Size: 10.6 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.6.tar.gz
Algorithm Hash digest
SHA256 b69f4fd337b4037b12c0bc5ae7dcdf4c5afb078658265ad0a00e87155c6803a4
MD5 c8d4959622fc559942d5b8e7ffe77491
BLAKE2b-256 cb61ee524986527e4fb23a1326d18fdf29ca7dfe765eef7d574945aaf86793c6

See more details on using hashes here.

File details

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

File metadata

  • Download URL: lora_easy-1.6-py3-none-any.whl
  • Upload date:
  • Size: 12.2 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.6-py3-none-any.whl
Algorithm Hash digest
SHA256 5ed8392b177f87d1ee6bb853b4e1834836cf0fda1fa82564b7519add5d34017a
MD5 72b61488e628fdfe1603f53480f2cd29
BLAKE2b-256 54b608978228c5a979c6c5f079406dca855b9bff636fe7253a1b28379483917e

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