Simo76 commited on
Commit
1411260
·
1 Parent(s): 07577a3

Rename project to Unified-LoRA and enhance README

Browse files

Updated README to reflect project name change and improved clarity on functionality and results.

Files changed (1) hide show
  1. README.md +113 -76
README.md CHANGED
@@ -1,120 +1,157 @@
1
- # Unified LoRA
2
 
3
- **Adaptive Single/Multi/Mirror LoRA framework with automatic mode switching driven by synaptic stress signals.**
4
 
5
- [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
6
 
7
- ## Overview
8
 
9
- Unified LoRA is a dynamic parameter-efficient fine-tuning system that automatically switches between three operational modes based on training stress:
10
 
11
- - **Mode 0 (Single)**: Shared adapter for low-conflict scenarios
12
- - **Mode 1 (Multi)**: Task-specific LoRA adapters for moderate stress
13
- - **Mode 2 (Mirror)**: Stability snapshots for catastrophic forgetting prevention
14
 
15
- The system uses a synaptic control parameter **φ(t)** derived from:
16
- - **C**: Task conflict (weight space variance)
17
- - **E**: Multi-task error
18
- - **S**: Memory stability
19
 
20
- φ(t) = f(C, E, S, ΔC, ΔE, ΔS)
 
 
 
 
 
21
 
22
- ## Validation Results
23
 
24
- ### 🧪 Tinker run (Llama-3.2-1B, cloud GPU)
25
 
26
- A controlled run demonstrating a full **stress → recovery cycle** and adaptive mode switching.
27
- This experiment illustrates the behavior of **φ(t)** under induced instability; it is **not a production deployment claim**.
28
 
29
- [250] Mode=1 φ=0.333 E_s=0.500 lr=5e-4 (Multi stable)
30
- >>> SHOCK @ step 300
31
- [350] Mode=2 φ=0.827 E_s=4.979 lr=1e-4 (Mirror activated)
32
- >>> RECOVERY @ step 500
33
- [550] Mode=1 φ=0.371 E_s=0.521 lr=5e-4 (Multi return)
34
- [700] Mode=1 φ=0.333 E_s=0.500 lr=5e-4 (baseline restored)
 
 
35
 
36
- **Key observation (this run):**
37
- φ returns close to its pre-shock regime after recovery (example: 0.33 → 0.83 → 0.33), indicating reversible stress handling within this setup.
38
 
39
- ### 📊 Standard Benchmark (GLUE MRPC + DistilBERT)
40
 
41
- Observed comparable performance to baseline LoRA on GLUE MRPC under the reported configuration:
42
 
43
- | Method | F1 | Accuracy | φ final | Mode |
44
- |--------|-----|----------|---------|------|
45
- | Baseline LoRA | 0.785 | 0.646 | - | - |
46
- | Unified LoRA | 0.785 | 0.646 | 0.367 | 1 |
47
 
48
- Key observation (this run):
49
- No performance degradation observed with adaptive control active in the reported setup.
 
 
 
 
 
 
 
50
 
51
- ## Quick Start
52
 
53
- from unified_lora import UnifiedController
54
 
55
- # Initialize controller
56
- controller = UnifiedController(
57
- alpha=0.1, # φ(t) learning rate
58
- beta=0.9, # EMA smoothing
59
- theta0=0.3, # Single/Multi threshold
60
- theta1=0.7 # Multi/Mirror threshold
61
- )
62
 
63
- # Training loop
64
- for step, batch in enumerate(train_loader):
65
- outputs = model(**batch)
66
- loss = outputs.loss
67
 
68
- # Update controller and get adaptive LR
69
- new_lr = controller.update(loss.item())
70
 
71
- # Apply new learning rate
72
- for g in optimizer.param_groups:
73
- g['lr'] = new_lr
 
 
74
 
75
- # Standard backprop
76
- loss.backward()
77
- optimizer.step()
78
- optimizer.zero_grad()
79
 
80
- ## Technical Details
81
 
82
- ### FSM State Transitions
83
 
84
- φ < 0.3 → Mode 0 (Single) LR = 5e-5
85
- φ < 0.7 → Mode 1 (Multi) LR = 3e-5
86
- φ ≥ 0.7 → Mode 2 (Mirror) LR = 1e-5
 
87
 
88
- ### Stress Signal Computation
89
 
90
- The metrics C (conflict), E (error), and S (stability) are normalized to [0,1] to keep φ(t) well-conditioned:
 
 
 
 
91
 
92
- E_smooth = β * E_smooth + (1 - β) * loss
93
- D = E_smooth / (1 + E_smooth)
94
- φ = (1 - α) * φ + α * D
95
 
96
- This normalization supports stable FSM transitions and reduces numerical sensitivity during training.
97
 
98
- ## Installation
 
 
 
 
99
 
100
- pip install transformers peft torch
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  ## Citation
103
 
 
 
 
104
  @software{unified_lora_2025,
105
  author = {Simona Vargiu},
106
- title = {Unified LoRA: Adaptive Parameter-Efficient Fine-Tuning},
107
  year = {2025},
108
- url = {https://github.com/Sva76/Unified-LoRA}
109
  }
110
-
111
- ## License
112
-
113
- Apache License 2.0 — see LICENSE for details.
114
 
115
  ## Contact
116
 
117
- Simona Vargiu (Independent Researcher)
118
  For collaboration inquiries: simona.vargiu.malta@gmail.com
119
 
120
- Status: Demonstrated on (1) a Tinker Llama-3.2-1B run showing adaptive stress → recovery behavior and (2) the GLUE MRPC benchmark (DistilBERT) with comparable F1/Accuracy to baseline LoRA under the reported configuration. Broader benchmarks and statistical evaluation across seeds and tasks are ongoing. Open to research collaboration and extended evaluation.
 
 
 
1
+ # Unified-LoRA
2
 
3
+ **Adaptive rank controller for LoRA fine-tuning.**
4
 
5
+ A lightweight per-layer controller that dynamically adjusts LoRA rank during training based on gradient stress, eliminating manual rank selection.
6
 
7
+ ## What it does
8
 
9
+ Instead of fixing `rank=8` or `rank=16` and hoping it works, Unified-LoRA adapts the rank of each layer independently during training. Layers under stress get more capacity; stable layers get less. No grid search, no guessing.
10
 
11
+ ## Key results
 
 
12
 
13
+ Evaluated on 4 GLUE tasks with DistilBERT-base-uncased, 3 epochs, LR=5e-4, α=16:
 
 
 
14
 
15
+ | Task | Metric | Baseline (r=16) | Adaptive | Avg Rank | Rank Reduction |
16
+ |------|--------|-----------------|----------|----------|----------------|
17
+ | MRPC | F1 | 0.882 | **0.886** | 9.3 | 42% |
18
+ | SST-2 | Accuracy | **0.898** | 0.885 | 7.0 | 56% |
19
+ | CoLA | MCC | 0.488 | **0.491** | 7.1 | 56% |
20
+ | RTE | Accuracy | 0.556 | **0.592** | 10.8 | 33% |
21
 
22
+ **Summary:** Comparable or better performance on 3/4 tasks with 33-56% fewer active rank parameters.
23
 
24
+ ## How it works
25
 
26
+ Each LoRA adapter tracks the exponential moving average of its gradient norm. When the gradient stress increases (loss landscape is rough), the controller increases rank. When stress decreases (training is stable), rank is reduced.
 
27
 
28
+ ```
29
+ For each layer, at each step:
30
+ 1. Compute grad_norm of LoRA parameters
31
+ 2. Update EMA: stress = 0.9 * stress + 0.1 * grad_norm
32
+ 3. If stress trend is increasing → rank += 2
33
+ 4. If stress trend is decreasing → rank -= 2
34
+ 5. Forward pass uses α/r scaling (standard LoRA)
35
+ ```
36
 
37
+ The controller adds ~30 lines of code and zero computational overhead beyond gradient norm computation.
 
38
 
39
+ ## Per-layer behavior
40
 
41
+ The controller discovers meaningful patterns automatically:
42
 
43
+ - **v_proj consistently needs more rank than q_proj** across all tasks
44
+ - **Deep layers (4-5) need more rank** than early layers on complex tasks
45
+ - **Easier tasks (SST-2) converge to lower rank** than harder tasks (RTE)
 
46
 
47
+ Example per-layer rank on MRPC:
48
+ ```
49
+ layer0.q: 8.5 layer0.v: 8.3
50
+ layer1.q: 7.8 layer1.v: 7.6
51
+ layer2.q: 10.1 layer2.v: 8.3
52
+ layer3.q: 8.1 layer3.v: 10.1
53
+ layer4.q: 10.0 layer4.v: 12.1
54
+ layer5.q: 8.1 layer5.v: 12.3
55
+ ```
56
 
57
+ ## What was tested and didn't improve results
58
 
59
+ In the interest of scientific honesty, the following extensions were tested and did **not** outperform the simple Adaptive controller:
60
 
61
+ - **Fluid dynamics metrics** (shock, vorticity, swirl as stress signal): controller became too conservative, suppressing rank across all tasks
62
+ - **Budget redistribution** (fixed total rank budget shared across layers): "winner takes all" problem — high-stress layers starved low-stress layers
63
+ - **Adaptive gradient clipping** driven by swirl: helped on small tasks (RTE +2.5%), hurt on large tasks (SST-2 -1.7%)
64
+ - **Scaling without α/r**: performance came from implicit norm regulation, not true capacity control
 
 
 
65
 
66
+ The simple version works best. Complexity did not pay.
 
 
 
67
 
68
+ ## Comparison with existing methods
 
69
 
70
+ | Method | Approach | Overhead | Our advantage |
71
+ |--------|----------|----------|---------------|
72
+ | AdaLoRA | SVD importance scoring per layer | High (SVD each step) | ~30 lines, zero SVD |
73
+ | DyLoRA | Train on multiple ranks simultaneously | Medium | Runtime adaptation, not post-hoc |
74
+ | Fixed LoRA | Manual rank selection | None | No guessing required |
75
 
76
+ Note: Direct numerical comparison with AdaLoRA was attempted but AdaLoRA did not function correctly in our setup (no rank pruning occurred). A fair comparison requires architecture-specific tuning of AdaLoRA scheduling parameters.
 
 
 
77
 
78
+ ## Reproduce
79
 
80
+ Run `benchmark.py` on Google Colab with a T4 GPU (~30 min):
81
 
82
+ ```bash
83
+ pip install transformers datasets evaluate accelerate scikit-learn
84
+ python benchmark.py
85
+ ```
86
 
87
+ ## Limitations
88
 
89
+ - Validated on DistilBERT (67M) and TinyLlama (1.1B) only
90
+ - Single-seed runs (variance not quantified)
91
+ - GLUE tasks only — no generation or instruction-following evaluation
92
+ - Rank changes don't reduce peak memory (matrices allocated at max_rank)
93
+ - Throughput overhead from dynamic slicing on small models
94
 
95
+ ## Adapter size reduction
 
 
96
 
97
+ With average rank ~7 vs fixed rank 16:
98
 
99
+ | Model | r=16 adapter | r=7 adapter | Reduction |
100
+ |-------|-------------|-------------|-----------|
101
+ | DistilBERT | 4.3 MB | 1.9 MB | 56% |
102
+ | 7B (projected) | ~70 MB | ~31 MB | 56% |
103
+ | 70B × 100 tenants | ~7 GB | ~3.1 GB | 56% |
104
 
105
+ ## Two validated systems
106
+
107
+ Unified-LoRA contains two complementary approaches, both validated:
108
+
109
+ ### 1. FSM Mode Controller (φ(t))
110
+
111
+ Validated on Tinker with Llama-3.2-1B. A finite state machine driven by a synaptic stress parameter φ(t) = f(C, E, S) that switches between three operational modes:
112
+
113
+ - **Mode 0 (Single):** shared adapter, low stress (φ < 0.3)
114
+ - **Mode 1 (Multi):** task-specific adapters, moderate stress (φ < 0.7)
115
+ - **Mode 2 (Mirror):** stability snapshots, high stress (φ ≥ 0.7)
116
+
117
+ Demonstrated full stress → recovery cycle:
118
+ ```
119
+ [250] Mode=1 φ=0.333 (stable)
120
+ SHOCK @ step 300
121
+ [350] Mode=2 φ=0.827 (Mirror activated)
122
+ RECOVERY @ step 500
123
+ [550] Mode=1 φ=0.371 (return)
124
+ [700] Mode=1 φ=0.333 (baseline restored)
125
+ ```
126
+
127
+ Key finding: φ returns to pre-shock regime after recovery (0.33 → 0.83 → 0.33), indicating reversible stress handling.
128
+
129
+ ### 2. Per-layer Adaptive Rank Controller
130
+
131
+ Validated on DistilBERT across 4 GLUE tasks (results table above). Each layer independently adjusts its LoRA rank based on gradient stress EMA. This is the simpler, more broadly validated system.
132
+
133
+ ### Evolution
134
+
135
+ The project progressed from discrete mode switching (FSM) to continuous per-layer rank adaptation. Intermediate explorations included fluid dynamics metrics (shock, vorticity, swirl) and budget redistribution — these were tested rigorously but did not outperform the simple per-layer EMA approach. Details in "What was tested" above.
136
 
137
  ## Citation
138
 
139
+ If you use this work:
140
+
141
+ ```
142
  @software{unified_lora_2025,
143
  author = {Simona Vargiu},
144
+ title = {Unified-LoRA: Adaptive Rank Controller for LoRA Fine-tuning},
145
  year = {2025},
146
+ url = {https://github.com/Sva76/Unified-LoRa}
147
  }
148
+ ```
 
 
 
149
 
150
  ## Contact
151
 
152
+ Simona Vargiu (Independent Researcher)
153
  For collaboration inquiries: simona.vargiu.malta@gmail.com
154
 
155
+ ## License
156
+
157
+ Apache License 2.0 — see LICENSE for details.