LoRA linear layer
Lesson: Fine-Tuning with LoRA & QLoRACheat sheetTrack: LLM inference
Problem
LoRA fine-tunes a large model without a change to its weights. It keeps the weight W of a linear layer frozen and adds a small trainable path through two low rank matrices A and B. After training, you can merge the path into W, so inference costs the same as the base model.
Task
Write three functions.
lora_forward(x, W, b, A, B, alpha)returns the output of the layer with the adapter.merge_lora(W, A, B, alpha)returns the merged weight.count_trainable(in_features, out_features, rank)returns the number of trainable values in A and B.
The rank r is the number of rows of A. The output of the layer is
The merged weight is W' = W + \frac{\alpha}{r} B A. With the merged weight, x W'^T + b equals the output of lora_forward.
Only A and B train. W and b are frozen and do not count.
Input and output
| Name | Type | Shape | Meaning |
|---|---|---|---|
x | float array | (N, in_features) | one input row for each of the N examples |
W | float array | (out_features, in_features) | the frozen weight |
b | float array | (out_features,) | the frozen bias |
A | float array | (r, in_features) | the down projection of the adapter |
B | float array | (out_features, r) | the up projection of the adapter |
alpha | float | scalar | the LoRA scale numerator |
in_features, out_features, rank | int | scalar | the layer sizes and the rank |
lora_forwardreturns a float array of shape(N, out_features).merge_lorareturns a new float array of shape(out_features, in_features).count_trainablereturns a Pythonint.
Constraints
1 <= N <= 64,1 <= in_features, out_features <= 4096and1 <= r <= 64.- The rank can be larger than
in_featuresorout_features. alpha > 0.- Do not change the input arrays.
- Use numpy only.
Examples
pythonx = np.array([[1.0, 2.0, 0.0], [0.0, -1.0, 1.0]])
W = np.array([[0.5, -0.5, 1.0], [1.0, 0.0, 0.0]])
b = np.array([0.1, -0.2])
A = np.array([[1.0, 0.0, 1.0], [0.0, 1.0, 0.0]])
B = np.array([[1.0, 0.5], [-1.0, 0.0]])
lora_forward(x, W, b, A, B, 4.0)text[[ 3.6 -1.2]
[ 2.6 -2.2]]With B = np.zeros((2, 2)), the same call returns the base output [[-0.4, 0.8], [1.6, -0.2]].
pythonmerge_lora(W, A, B, 4.0)text[[ 2.5 0.5 3. ]
[-1. 0. -2. ]]pythoncount_trainable(4096, 4096, 8)text65536Hints
4 hintsSolution and notes
LockedPass every check with Submit to open the reference solution and the notes.
Run it on your computer
Clone the repository, install numpy and run the same checks in a terminal:
python3 scripts/practice/run.py lora-forward my_answer.py
python3 scripts/practice/run.py lora-forward my_answer.py --examplesStart my_answer.py from starter.py.
Your code is saved in this browser as you type. On a phone you can read and edit the code, but the checks are easier to use on a desktop.
Keyboard shortcuts
- Ctrl Enter
- Run the examples
- Ctrl Shift Enter
- Submit
- Tab / Shift Tab
- Indent or outdent the lines
- Esc then Tab
- Move the focus out of the editor
- Alt H
- Show the next hint
On a Mac, use Cmd in place of Ctrl.
Select Run to check the examples, or Submit to run every check.