Update README.md
Browse files
README.md
CHANGED
@@ -31,7 +31,13 @@ Uses:
|
|
31 |
|
32 |
`h = (I + lora_B @ lora_A) @ tensor @ x = tensor @ x + lora_B @ lora_A @ tensor @ x`
|
33 |
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
`h = (tensor + lora_B @ lora_A) @ x = tensor @ x + lora_B @ lora_A @ x`
|
37 |
|
@@ -67,6 +73,33 @@ tensor = tensor.to(old_type)
|
|
67 |
|
68 |
---
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
# Training
|
71 |
|
72 |
- Took just under 4 days using dual-A6000 GPUs connected via NVLink, using [qlora-pipe](https://github.com/tdrussell/qlora-pipe).
|
|
|
31 |
|
32 |
`h = (I + lora_B @ lora_A) @ tensor @ x = tensor @ x + lora_B @ lora_A @ tensor @ x`
|
33 |
|
34 |
+
or equivalently:
|
35 |
+
|
36 |
+
`h = tensor @ x`
|
37 |
+
|
38 |
+
`h' = h + lora_B @ lora_A @ h`
|
39 |
+
|
40 |
+
instead of the normal "additive-LoRA" method of:
|
41 |
|
42 |
`h = (tensor + lora_B @ lora_A) @ x = tensor @ x + lora_B @ lora_A @ x`
|
43 |
|
|
|
73 |
|
74 |
---
|
75 |
|
76 |
+
# The rationale behind the "multiplicative-LoRA" method and the link to control-vectors
|
77 |
+
|
78 |
+
There are actually 3 existing "multiplicative-LoRA" methods in [PEFT/tuners](https://github.com/huggingface/peft/tree/main/src/peft/tuners):
|
79 |
+
|
80 |
+
- https://github.com/huggingface/peft/tree/main/src/peft/tuners/oft (https://arxiv.org/abs/2306.07280)
|
81 |
+
- https://github.com/huggingface/peft/tree/main/src/peft/tuners/boft (https://arxiv.org/abs/2311.06243)
|
82 |
+
- https://github.com/huggingface/peft/tree/main/src/peft/tuners/hra (https://arxiv.org/abs/2405.17484)
|
83 |
+
|
84 |
+
but all of these deliberately maintain [orthogonality](https://en.wikipedia.org/wiki/Orthogonal_matrix), and thus are more restrictive in the types of transformations they can perform (ie: [Rotations](https://en.wikipedia.org/wiki/Rotation) and/or [Improper Rotations](https://en.wikipedia.org/wiki/Improper_rotation) only; with no scaling and/or sheer possible...).
|
85 |
+
|
86 |
+
For example, these can't perform the orthogonal projection performed by [abliteration](https://www.lesswrong.com/posts/jGuXSZgv6qfdhMCuJ/refusal-in-llms-is-mediated-by-a-single-direction):
|
87 |
+
|
88 |
+
`h' = h - v @ v^T @ h`
|
89 |
+
|
90 |
+
whereas the general (non-orthogonal) "multiplicative-LoRA" method can do this by choosing to set `u = -v` like so:
|
91 |
+
|
92 |
+
`h' = h + u @ v^T @ h`
|
93 |
+
|
94 |
+
In general, the way to think about these (non-orthogonal) "multiplicative-LoRAs" is as a kind of "conditional control-vector":
|
95 |
+
|
96 |
+
- The vectors in `lora_A` look for a certain dirrection, and via the dot-product; generate (signed) weighting factor that measure the similarity between the output of the `down_proj` transformation.
|
97 |
+
- The vectors in `lora_B` then get added to the hidden state / residual stream based on the weighting factors.
|
98 |
+
|
99 |
+
So instead of having just a single vector that we add (in essence we add a bias term and create an [Affine transformation](https://en.wikipedia.org/wiki/Affine_transformation)), we now have many different control vectors that can be added (in `lora_B`), based on how well they match another set of "directional detection vectors" (in `lora_A`).
|
100 |
+
|
101 |
+
---
|
102 |
+
|
103 |
# Training
|
104 |
|
105 |
- Took just under 4 days using dual-A6000 GPUs connected via NVLink, using [qlora-pipe](https://github.com/tdrussell/qlora-pipe).
|