Instructions to use Niarfe/qwen2.5-7b-positional-reasoning with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use Niarfe/qwen2.5-7b-positional-reasoning with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B-Instruct") model = PeftModel.from_pretrained(base_model, "Niarfe/qwen2.5-7b-positional-reasoning") - Notebooks
- Google Colab
- Kaggle
File size: 5,247 Bytes
7035ef3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | """QLoRA fine-tuning of Qwen2.5-7B-Instruct on the positional reasoning dataset.
Three hyperparameter combos (see Deliverable4/README.md training plan):
A: lr 1e-5, target q_proj/v_proj (conservative — HW6 baseline, expected weak)
B: lr 1e-4, target q_proj/v_proj (TRL-recommended adapter lr)
C: lr 2e-4, target all-linear (QLoRA-style full coverage)
Usage (on the GPU box, inside a venv with transformers/trl/peft/bitsandbytes):
python3 train_qlora.py A # or B, C
nohup python3 train_qlora.py B > combo_B.log 2>&1 & # survives ssh disconnects
Writes to ./runs/<combo>/: checkpoints, best model adapter, metrics.json
(train/eval loss history) for display in the check-in notebook.
"""
import json
import os
import sys
import torch
from datasets import Dataset
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from trl import SFTConfig, SFTTrainer
MODEL_ID = "Qwen/Qwen2.5-7B-Instruct"
DATA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "pipeline", "data", "accepted.jsonl")
SEED = 42
COMBOS = {
"A": {"lr": 1e-5, "target_modules": ["q_proj", "v_proj"]},
"B": {"lr": 1e-4, "target_modules": ["q_proj", "v_proj"]},
"C": {"lr": 2e-4, "target_modules": "all-linear"},
}
SYSTEM = ("You solve math word problems using positional reasoning: a chain of typed "
"nodes, each committing to a prediction before the next step is computed. "
"End with the final answer in <answer></answer> tags.")
def load_split(tokenizer):
rows = [json.loads(l) for l in open(DATA)]
ds = Dataset.from_list([
{
"prompt": tokenizer.apply_chat_template(
[{"role": "system", "content": SYSTEM},
{"role": "user", "content": r["question"]}],
tokenize=False, add_generation_prompt=True),
"completion": r["positional"] + tokenizer.eos_token,
}
for r in rows
])
split = ds.train_test_split(test_size=0.1, seed=SEED)
return split["train"], split["test"]
def main(combo_name):
combo = COMBOS[combo_name]
out_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "runs", combo_name)
os.makedirs(out_dir, exist_ok=True)
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
train_ds, eval_ds = load_split(tokenizer)
print(f"combo {combo_name}: {len(train_ds)} train / {len(eval_ds)} eval examples")
bnb = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16, # T4 has no bf16
bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID, quantization_config=bnb, device_map="auto", torch_dtype=torch.float16)
model = prepare_model_for_kbit_training(model)
model.config.use_cache = False
lora = LoraConfig(
r=64, lora_alpha=64, lora_dropout=0.05, bias="none",
task_type="CAUSAL_LM", target_modules=combo["target_modules"])
model = get_peft_model(model, lora)
model.print_trainable_parameters()
args = SFTConfig(
output_dir=out_dir,
num_train_epochs=2,
per_device_train_batch_size=1,
gradient_accumulation_steps=8,
learning_rate=combo["lr"],
logging_steps=10,
eval_strategy="steps",
eval_steps=25,
save_steps=25,
save_total_limit=2,
load_best_model_at_end=True,
fp16=True,
max_length=1600,
gradient_checkpointing=True,
optim="paged_adamw_8bit",
report_to=[],
seed=SEED,
)
trainer = SFTTrainer(
model=model, args=args,
train_dataset=train_ds, eval_dataset=eval_ds)
# TRL's SFTTrainer unconditionally casts LoRA adapter params to bfloat16
# for any quantized model during __init__ (QLoRA paper recommendation) --
# confirmed via trl/trainer/sft_trainer.py, no config option to opt out
# for quantized models. bfloat16 has no unscale kernel for fp16's
# GradScaler, and this T4 has no bf16 hardware support anyway. The correct
# fix (confirmed via a standalone diagnostic) is fp32, not fp16: fp16
# mixed-precision training expects fp32 "master weight" params with
# autocast handling the fp16 compute internally -- GradScaler explicitly
# rejects unscaling gradients that are already fp16 leaf params
# ("Attempting to unscale FP16 gradients"). Re-cast to fp32 after the
# trainer is built, undoing TRL's bf16 cast rather than fighting it
# beforehand.
for p in trainer.model.parameters():
if p.requires_grad:
p.data = p.data.to(torch.float32)
trainer.train()
trainer.model.save_pretrained(os.path.join(out_dir, "best_model"))
with open(os.path.join(out_dir, "metrics.json"), "w") as f:
json.dump(trainer.state.log_history, f, indent=1)
print(f"combo {combo_name} done -> {out_dir}/best_model")
if __name__ == "__main__":
name = sys.argv[1] if len(sys.argv) > 1 else None
if name not in COMBOS:
print(f"usage: python3 train_qlora.py [{'|'.join(COMBOS)}]")
sys.exit(1)
main(name)
|