init: bt7274 lora training — v1 adapter, v2 dataset (500 examples), justfile

This commit is contained in:
madcat
2026-05-25 16:37:30 +02:00
commit 9bcf1c2d9a
12 changed files with 758718 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
"""BT-7274 LoRA v2 — 500 examples with tool calls.
Usage:
# just train
cd ~/Projects/lora
python train_v2.py
"""
from unsloth import FastLanguageModel
from trl import SFTTrainer
from transformers import TrainingArguments
from datasets import load_dataset
# --- Config ---
MODEL = "unsloth/Qwen2.5-7B-Instruct-bnb-4bit"
MAX_SEQ = 4096 # longer for tool call chains
RANK = 16
ALPHA = 16
DATA = "./bt7274_v2.jsonl"
OUT = "./bt7274-lora-v2"
EPOCHS = 3 # 5x more data, fewer epochs
BATCH = 1 # larger sequences need smaller batch
GRAD_ACCUM = 8 # effective batch = 8
LR = 2e-4
# --- Load model (4-bit quantized) ---
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=MODEL,
max_seq_length=MAX_SEQ,
load_in_4bit=True,
dtype=None,
)
# --- LoRA adapter ---
model = FastLanguageModel.get_peft_model(
model,
r=RANK,
lora_alpha=ALPHA,
lora_dropout=0,
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
],
bias="none",
use_gradient_checkpointing="unsloth",
random_state=42,
)
# --- Dataset ---
ds = load_dataset("json", data_files=DATA, split="train")
def to_chatml(ex):
text = tokenizer.apply_chat_template(
ex["messages"], tokenize=False, add_generation_prompt=False
)
return {"text": text}
ds = ds.map(to_chatml)
steps = (len(ds) * EPOCHS) // (BATCH * GRAD_ACCUM)
print(f"Dataset: {len(ds)} examples")
print(f"Epochs: {EPOCHS}, effective batch: {BATCH * GRAD_ACCUM}")
print(f"Estimated steps: {steps}")
print(f"LoRA: r={RANK}, alpha={ALPHA}")
print(f"Max seq: {MAX_SEQ}")
# --- Train ---
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=ds,
args=TrainingArguments(
output_dir=OUT,
per_device_train_batch_size=BATCH,
gradient_accumulation_steps=GRAD_ACCUM,
num_train_epochs=EPOCHS,
learning_rate=LR,
bf16=True,
logging_steps=5,
save_steps=50,
save_total_limit=2,
warmup_steps=10,
optim="adamw_8bit",
seed=42,
report_to="none",
),
dataset_text_field="text",
max_seq_length=MAX_SEQ,
packing=False,
)
trainer.train()
# --- Save LoRA adapter ---
model.save_pretrained(OUT)
tokenizer.save_pretrained(OUT)
print(f"\nSaved LoRA adapter to {OUT}/")