笔者也是初学者,一边学习总结一边写这篇文章。

一、学习资料

代码

代码地址:https://github.com/DLLXW/baby-llama2-chinese

网络课程和文章

课程地址:https://www.bilibili.com/video/BV12h4y1N7C8/?spm_id_from=333.337.search-card.all.click&vd_source=cd8ea6c3c8b0bf72de553b1586baad87
知乎文章:https://zhuanlan.zhihu.com/p/649756898

学习群聊

qq:716455397 baby-llama2-chinese

二、知识要点

模型搭建阶段

  1. 在normal上的操作与transformer不同,llama2用的是RMSNorm方法(注意这里是对整个句子规范化,不是对一个词向量进行规范化)
    为什么要规范化?
  2. linear层产生多头注意力Q,K,V矩阵
  3. ROPE 操作: 通过绝对位置编码的方式实现了相对位置编码
    绝对位置编码—>旋转位置编码
    具体证明和介绍的文章:https://zhuanlan.zhihu.com/p/642884818 涉及到的都是基本矩阵和复变函数知识
  4. 为什么需要mask操作?
  5. KVcache的意义
    事实上存储KV矩阵不现实
  6. 使用MQA是个更好的选择,比单一的KV矩阵有更高的精度,比一个多头存一个KV矩阵消耗更少的空间

预训练阶段

  1. 梯度裁剪和梯度缩放

微调阶段

高效模型微调

  1. LoRA
    参考文章:https://zhuanlan.zhihu.com/p/644360231
    通过调整秩(r)和缩放系数(alpha)的大小,将W用两个低秩矩阵表示,只调整这两个低秩矩阵,不调整预训练的参数矩阵
    两个矩阵一个用高斯函数初始化,一个用零矩阵初始化
    lora_dropout的参数设置不能忽略,随机丢弃神经元提升小矩阵的泛化能力
  2. AdaLoRA
    参考文章:https://zhuanlan.zhihu.com/p/667432109
    需要补充的知识点:幺正矩阵性质,SVD算法(笔者还没有完全搞清楚这些性质的证明过程)
    主要是要注意三元组的问题,为什么这里只需要管P矩阵的第i行,一维向量lambda的第i个值,Q矩阵的第i列 -> 这里幺正矩阵的条件决定了它们之间的关系是固定的
    注意损失函数里面需要添加的正则化项
    在SVD中,特征的重要性取决于它对应的奇异值的绝对值的大小
  3. QLoRA
    参考文章:https://zhuanlan.zhihu.com/p/676998456 这篇文章将数据放缩的基本知识讲得很清楚
    注意是对每一个块进行一个缩放,存储一个缩放系数
    主要包含三项技术:(1)新的数据类型 4-bit NormalFloat(NF4);(2)双重量化(Double Quantization);(3)分页优化器(Paged Optimizers)

模型上下文窗口扩展

  1. ALiBi
    参考文章:https://zhuanlan.zhihu.com/p/656684326 https://spaces.ac.cn/archives/9431
    提升位置编码的外推能力
  2. 差值法

三、代码中的技术细节

这里参考的是baby-llama2-chinese-main的代码文件,源码部分只有生成阶段的部分代码

model.py

  1. RMSNorm层公式:假设输入张量x的形状为(batch_size, sequence_length, feature_dim),最后根号内生成的是一个二维张量,形状为(batch_size, sequence_length, 1),这里是对每一个feature赋一个权重。
  2. ROPE:
  3. Swish激活函数:
  4. 交叉熵:

pretain.py

  1. 学习率公式:
    线性预热阶段(Linear Warmup):学习率衰减阶段(Learning Rate Decay):中间阶段:

四、融会贯通

  1. 关于为什么主流大模型都使用decoder-only而非encoder-decoder框架?
    参考文章链接:
    https://kexue.fm/archives/9529 (苏神)
    https://www.zhihu.com/question/588325646 (知乎问答)