Simo76 commited on
Commit
8162dad
·
1 Parent(s): fae8085

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +24 -136
README.md CHANGED
@@ -1,136 +1,24 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "metadata": {},
6
- "source": [
7
- "# Unified LoRA - MRPC Benchmark Example\n",
8
- "\n",
9
- "This notebook demonstrates Unified LoRA on the GLUE MRPC task.\n",
10
- "\n",
11
- "**Expected results:**\n",
12
- "- Baseline LoRA: F1 ~0.78-0.79\n",
13
- "- Unified LoRA: F1 ~0.78-0.79\n"
14
- ]
15
- },
16
- {
17
- "cell_type": "code",
18
- "metadata": {},
19
- "source": [
20
- "!pip install -q transformers datasets peft evaluate scikit-learn accelerate"
21
- ],
22
- "outputs": [],
23
- "execution_count": null
24
- },
25
- {
26
- "cell_type": "code",
27
- "metadata": {},
28
- "source": [
29
- "import os\n",
30
- "os.environ['WANDB_DISABLED'] = 'true'\n",
31
- "\n",
32
- "import torch\n",
33
- "from datasets import load_dataset\n",
34
- "from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments\n",
35
- "from peft import LoraConfig, get_peft_model\n",
36
- "from torch.utils.data import DataLoader\n",
37
- "import evaluate\n",
38
- "\n",
39
- "from controller import UnifiedController\n",
40
- "\n",
41
- "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
42
- "print(device)"
43
- ],
44
- "outputs": [],
45
- "execution_count": null
46
- },
47
- {
48
- "cell_type": "code",
49
- "metadata": {},
50
- "source": [
51
- "dataset = load_dataset('glue','mrpc')['train'].train_test_split(test_size=0.2, seed=42)\n",
52
- "\n",
53
- "model_name = 'distilbert-base-uncased'\n",
54
- "tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
55
- "\n",
56
- "def tokenize(ex):\n",
57
- " return tokenizer(ex['sentence1'], ex['sentence2'], truncation=True, padding=True)\n",
58
- "\n",
59
- "train = dataset['train'].map(tokenize, batched=True).rename_column('label','labels')\n",
60
- "test = dataset['test'].map(tokenize, batched=True).rename_column('label','labels')\n",
61
- "\n",
62
- "metric = evaluate.combine(['accuracy','f1'])\n",
63
- "\n",
64
- "def compute_metrics(p):\n",
65
- " logits, labels = p\n",
66
- " preds = torch.argmax(torch.tensor(logits), axis=-1)\n",
67
- " return metric.compute(predictions=preds, references=labels)"
68
- ],
69
- "outputs": [],
70
- "execution_count": null
71
- },
72
- {
73
- "cell_type": "code",
74
- "metadata": {},
75
- "source": [
76
- "# BASELINE\n",
77
- "model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)\n",
78
- "model = get_peft_model(model, LoraConfig(r=16, lora_alpha=32, target_modules=['q_lin','v_lin']))\n",
79
- "\n",
80
- "trainer = Trainer(\n",
81
- " model=model,\n",
82
- " train_dataset=train,\n",
83
- " eval_dataset=test,\n",
84
- " args=TrainingArguments(output_dir='./b', num_train_epochs=3, per_device_train_batch_size=16, fp16=True, report_to=None),\n",
85
- " compute_metrics=compute_metrics\n",
86
- ")\n",
87
- "\n",
88
- "trainer.train()\n",
89
- "base = trainer.evaluate()"
90
- ],
91
- "outputs": [],
92
- "execution_count": null
93
- },
94
- {
95
- "cell_type": "code",
96
- "metadata": {},
97
- "source": [
98
- "# UNIFIED\n",
99
- "ctrl = UnifiedController()\n",
100
- "\n",
101
- "model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)\n",
102
- "model = get_peft_model(model, LoraConfig(r=16, lora_alpha=32, target_modules=['q_lin','v_lin']))\n",
103
- "model.to(device)\n",
104
- "\n",
105
- "loader = DataLoader(train.remove_columns(['sentence1','sentence2','idx']), batch_size=16, shuffle=True)\n",
106
- "opt = torch.optim.AdamW(model.parameters(), lr=3e-5)\n",
107
- "\n",
108
- "model.train()\n",
109
- "\n",
110
- "for _ in range(3):\n",
111
- " for batch in loader:\n",
112
- " batch = {k:v.to(device) for k,v in batch.items() if k in ['input_ids','attention_mask','labels']}\n",
113
- " out = model(**batch)\n",
114
- " lr = ctrl.update(out.loss.item())\n",
115
- " for g in opt.param_groups: g['lr'] = lr\n",
116
- " out.loss.backward()\n",
117
- " opt.step(); opt.zero_grad()\n",
118
- "\n",
119
- "model.eval()\n",
120
- "trainer = Trainer(model=model, eval_dataset=test, args=TrainingArguments(output_dir='./u', per_device_eval_batch_size=16, fp16=True, report_to=None), compute_metrics=compute_metrics)\n",
121
- "uni = trainer.evaluate()"
122
- ],
123
- "outputs": [],
124
- "execution_count": null
125
- }
126
- ],
127
- "metadata": {
128
- "kernelspec": {
129
- "display_name": "Python 3",
130
- "language": "python",
131
- "name": "python3"
132
- }
133
- },
134
- "nbformat": 4,
135
- "nbformat_minor": 4
136
- }
 
1
+ # Unified-LoRA
2
+
3
+ **Adaptive LoRA fine-tuning with nested orbital rank control.**
4
+
5
+ A closed-loop controller that dynamically adjusts LoRA rank during training based on observed stress, using a single adapter with sliced dimensions — no cold start, no capacity loss on transitions.
6
+
7
+ ---
8
+
9
+ ## Key results
10
+
11
+ ### Stress test: task switch (MRPC → SST-2, DistilBERT, 3 seeds)
12
+
13
+ | | Baseline (r=16 fixed) | Unified (orbital) | Delta |
14
+ |------------------------|-----------------------|-------------------|-----------|
15
+ | SST-2 Acc (new task) | 0.736 | 0.740 | **+0.004** |
16
+ | MRPC F1 (retention) | 0.526 | 0.515 | -0.011 |
17
+ | Effective rank | 16.0 | 13.6 | |
18
+ | Rank saving | 0% | **15%** | |
19
+
20
+ Under distribution shift, the controller adapts capacity dynamically with 15% rank saving and no performance loss.
21
+
22
+ ---
23
+
24
+ ### Rank trace under shock (Seed 1)