Merge a LoRA Update into the Base Weight
Problem Statement
At inference LoRA is folded into the frozen weight so there is zero added latency: W' = W + (alpha/r) * B A. Implement the merge.
Background
LoRA scales its low-rank update by alpha/r (the "lora_alpha" over rank convention). Given the base weight W (d_out x d_in), factors A (r x d_in) and B (d_out x r), and alpha, the merged weight is
W′=W+rαBA
After merging, the adapter can be discarded — the model is a plain dense network again.
Your Task
Implement:
def merge_lora(W, A, B, alpha):
Return the merged d_out x d_in matrix as a nested list rounded to 4 decimals. Infer r from A's row count.
Input Format
- W: d_out x d_in nested list.
- A: r x d_in; B: d_out x r.
- alpha (float).
Output Format
- A d_out x d_in nested list rounded to 4 decimals.
Sample
W = [[1.0, 0.0], [0.0, 1.0]]
A = [[1.0, 1.0]]
B = [[1.0], [0.0]]
print(merge_lora(W, A, B, 2.0))
Output:
[[3.0, 2.0], [0.0, 1.0]]
Example:
W = [[1.0, 0.0], [0.0, 1.0]] A = [[1.0, 1.0]] B = [[1.0], [0.0]] print(merge_lora(W, A, B, 2.0))
[[3.0, 2.0], [0.0, 1.0]]
- Infer the rank r from the number of rows in matrix A. Since A is a 1×2 matrix, r=1.
- Compute the low-rank update product BA. Multiplying B (2×1) by A (1×2) yields a 2×2 matrix: [1.00.0][1.01.0]=[1.00.01.00.0]
- Calculate the scaling factor rα using the given α=2.0 and r=1: 12.0=2.0
- Scale the product matrix by the factor to get the update term: 2.0×[1.00.01.00.0]=[2.00.02.00.0]
- Add this update to the base weight W element-wise to obtain the merged weight W′: [1.00.00.01.0]+[2.00.02.00.0]=[3.00.02.01.0]
- The final output is [[3.0, 2.0], [0.0, 1.0]]
Constraints:
Wisd_out x d_in,Aisr x d_in,Bisd_out x r.- Scale the update by
alpha / rwherer = len(A). - Round to 4 decimals; avoid
-0.0.
1. Background Knowledge
LoRA (Low-Rank Adaptation) is a parameter-efficient fine-tuning technique where, instead of updating the full weight matrix W∈Rdout×din, we learn two smaller matrices A∈Rr×din and B∈Rdout×r with rank r≪min(dout,din). The effective update is the product BA, which has rank at most r. During training, the forward pass computes Wx+rαBAx; at inference, the adapter is merged into the base weight so the model becomes a plain dense network with zero added latency.
The scaling factor rα (where α is the hyperparameter lora_alpha) controls the magnitude of the update relative to the rank. A larger α or smaller r amplifies the low-rank contribution. This convention keeps the effective scale stable as you change the rank.
Merging is a one-time offline operation: compute W′=W+rαBA and discard A and B. The result is a full-rank dense matrix identical in shape to the original W.
2. Algorithm Approach
This is a matrix multiplication followed by element-wise addition. The core operation is:
- Compute the product C=B⋅A, which yields a dout×din matrix.
- Scale C by the factor rα.
- Add the scaled matrix element-wise to W.
Since the inputs are nested lists (not NumPy arrays), you implement the matrix product manually using triple-nested loops: for each output row i and column j, sum over the shared dimension k (which ranges over r).
3. Step-by-Step Strategy
- Infer the rank: r=len(A), i.e., the number of rows in A.
- Compute the product BA:
- For each row i of B (range dout):
- For each column j of A (range din):
- Initialize a running sum to 0.
- For each k in range r: accumulate B[i][k]×A[k][j].
- Store the result in a temporary matrix C[i][j].
- Scale and merge:
- Compute scale = alpha / r.
- For each element, compute W[i][j] + scale * C[i][j].
- Round: Apply round(value, 4) to every element of the result.
- Return the nested list.
Continue the full explanation
You're reading the free preview. Unlock the complete walkthrough, the code editor, test runner and reference solution with Premium.
Editor locked
The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.