Skip to content

从零实现 LoRA

Implementing LoRA From Scratch

让我们更深入地理解一下 LoRA。

假设预训练模型中某一层当前的权重是 W,维度为 d×k,我们希望在另一个数据集上对它进行微调。

fine tuning p78 1

在微调过程中,梯度更新规则要求我们把 ΔW 加上去,才能得到更新后的参数:

fine tuning p78 2

为了方便理解,你可以把 ΔW 看作是在新数据集上运行梯度下降后得到的更新量:

fine tuning p79 1

此外,与其直接更新原始权重 W,同时维护 W 和 ΔW 这两个矩阵也是完全可行的。

在推理时,我们可以按如下方式,对输入样本 x 计算预测结果:

fine tuning p79 2

事实上,在整个模型微调迭代过程中,W 都可以保持不变,所有通过梯度计算得到的权重更新,都可以改为并入 ΔW。

但你可能会想……这样做究竟有什么帮助?

矩阵 W 本身已经很庞大了,而我们现在讨论的,却是要再引入一个同样庞大的矩阵。

所以,我们必须引入一些巧妙的技巧来处理 ΔW,这样才能在实现微调目标的同时,不消耗过多内存。

现在,对于 W 我们其实做不了太多事情,因为这些权重属于预训练模型本身。所以,如果我们打算做任何优化,都必须落在 ΔW 上。

在这么做的同时,我们还必须记住,目前 W 和 ΔW 的维度是完全相同的。但既然 W 本身已经很庞大,我们就必须确保 ΔW 不会变成同样的维度,否则就完全违背了高效微调的初衷。

换句话说,如果 ΔW 的维度和 W 保持一致,那还不如直接微调原始模型本身。

本站内容仅供学习交流,版权归原作者所有。