NF4 量化大模型

介绍 NF4 量化之前我们先说说量化是什么,量化本质是把 浮点数张量压缩到有限的整数集合里。例如 INT4 量化,就是把所有浮点数映射到 $2^4$ 个整数也就是 [-8, 7] 的区间内,这样子就只需要存储这 4个 bit 也就是 0.5B。具体的公式是:

LoRA&QLoRA

随着 LLM 参数量不断攀升,全量微调所需的显存越来越大。所以出现了 LoRA,它的思路是:冻结主模型权重,只训练少量的低秩适配器。这样虽然需要加载整个模型到显卡,但是由于只需要训练 LoRA 的 $A$ 和 $B$ 两个权重矩阵,所以优化器的参数非常少,并且中间激活值的占用也大幅度减小,所以显存需求大幅降低。

MiniMind 学习指北(六):LoRA

PEFT 大致包含三类:Prompt-Tuning、Adapter-Tuning 以及 LoRA,而 MiniMind 里面采用的就是 LoRA 进行指令微调。在 CS224N 的课程中已经学习了 LoRA 的原理,简单来说我们在经过 Pretrain 和 SFT 的模型基础上,对参数 $y=Wx$ 加上一个增量矩阵 $\Delta{W}$ 来微调模型,并且这个 $\Delta{W}$ 是通过 低秩近似 得到的,所以实际参数量远小于 $W$,计算开销小。具体可以看之前的笔记:

模型的 generate 方法

在 MiniMind 系列的 eval 部分我们已经学习了如何通过 transformers 库里 GenerateMixin 基类来生成文本,这一章学习一下 model.generate() 方法到底是怎么实现的。

MiniMind 学习指北(四):评估

#大模型 #深度学习 
这一章我们需要设计一个脚本来验证大模型的对话能力 评估脚本我们预训练是让模型学会说话的能力,或者说词语接龙的能力,给他一个 prompt 它可以接着说下去。因此我们在处理 prompt 时候需要稍加处理: python

Transformer 模型在训练时有一个 forward 方法,是用于针对模型的输入来产生输出,从而计算损失 loss,更新模型的参数。既然有这么一个生成的函数了,为什么 Transformer 中还有专门设计 generate 方法来负责在推理时生成文本呢?

MiniMind 学习指北(五):SFT

前面我们已经进行了预训练,得到了一个只会续写的模型。这是因为我们预训练数据集的文本都是简单的一句话,然后通过加工我们得到了类似 “<|im_start|> 秦始皇的功绩包括统一货币、文字” 的文本,通过 Teacher-Forcing 它只能做到预测下一个 token,或者说只会机械接龙,不会对话。

MoE 混合专家模型

MoE means Mixture of Experts,它是一种神经网络架构,可以把一个大模型拆分成多个小型的 expert,再用一个门控网络来决定每个输入该路由到哪些专家处理。

分布式训练技术

我们先回忆一下传统的单机单卡训练模式:

首先硬盘读取数据,CPU 处理数据,将数据组成一个 batch,再传入 GPU,网络前向传播算出 loss,再反向传播计算梯度,用梯度更新参数完成一次训练。这种传统模式在大参数量或者大数据量的情况下就容易陷入显存的瓶颈,于是就引出了多卡并行训练。

transformer库的基类

今天看了一下源码和官方文档,梳理过后会发现其实也不是很复杂,简单理解就两条:

  • ModelOutput(transformers.utils.ModelOutput)是所有模型输出的基类。简单理解它就是一个字典,在模型的 forward函数里把原本的输出做了一下封装而已,方便用户能直观地知道输出是什么。例如CausalLMOutput顾名思义就是用于像 GPT 这样自回归模型的输出。
  • PreTrainedModel (transformers.modeling_utils.PretrainedModel) 是所有模型的基类。所以你如果看到一个模型取名为LlamaForCausalLM,那你就可以知道这个模型的输出格式大概率就是自回归输出,即前面提到的CausalLMOutput。为什么说大概率呢,因为自回归输出还有蛮多种的,赶时间的朋友看到这就可以切换到其他文章了,至此你应该也能了解 transformers 最核心的模块了。感兴趣的可以继续往下看,下面做一个简单的总结和介绍。

前面已经介绍过了,ModelOutput是所有模型输出的基类。下面是其源码核心部分,一些具体实现代码删除了,不过不影响理解。

MiniMind 学习指北(四):评估

这一章我们需要设计一个脚本来验证大模型的对话能力

我们预训练是让模型学会说话的能力,或者说词语接龙的能力,给他一个 prompt 它可以接着说下去。因此我们在处理 prompt 时候需要稍加处理:

MiniMind 学习指北(三):预训练

预训练我们采用的是 Teacher-Forcing,所以需要的数据格式应该是偏移的 input_idslabels

__getitem__ 方法有几个需要注意的地方:

  1. 在 input_ids 前后加上 bos 和 eos 两个 special token 可以帮助模型理解,句子该从哪里开始,在什么时候结束,不会在长文本胡言乱语。
  2. 由于我们在模型的 forward 里面规定了:训练模式下将 logits 和 labels 进行偏移,所以在 Dataset 里面返回的 x 和 y 就不用额外的进行 shift 了。
  3. padding 补充的 token 不参与 loss 计算,所以在 labels 里面把这部分 token 的 id 设为 -100,和 F.cross_entropy(...,ignore_index=-100) 一致。