firefly-baichuan-7b-qlora-sft
QLoRA+百万指令数据,对baichun-7B模型进行高效指令微调
  • 模型资讯
  • 模型资料

Firefly(流萤): 中文对话式大语言模型

Firefly简介

Firefly(流萤) 是一个开源的中文大语言模型项目,正如我们的项目名称一样,希望本项目能够像流萤一般发出淡淡微光,为中文大语言模型社区尽绵薄之力,促进中文大语言模型社区的发展。

🔔 本项目主要内容如下:

  • 📗 支持全量参数指令微调、QLoRA低成本高效指令微调、LoRA指令微调(后续将会提供支持)。
  • 📗 支持对绝大多数主流的模型进行指令微调,如Bloom、LLaMA、baichuan、Ziya等。
  • 📗️ 模型裁剪:通过LLMPruner:大语言模型裁剪工具 ,在保留预训练中文知识的前提下,有效减少模型参数量,降低训练成本,提高训练效率。
  • 📗 开源和整理指令微调数据集:firefly-train-1.1Mmoss-003-sft-dataultrachat
  • 📗 开源Firefly系列指令微调模型权重 。

如果希望使用本项目进行推理、Finetune等,我们推荐使用配套代码库:Firefly

baichuan-7B简介

百川智能发布了其首个开源可商用的中英文大语言模型——baichuan-7b,该模型的结构与LLaMA基本一致,使用了1.2万亿token进行训练。相较于原生的LLaMA以及经过词表扩充后的LLaMA-Chinese系列模型,baichuan-7b先天上更适合中文场景的任务。

baichuan-7b在C-Eval、AGIEval和Gaokao等榜单上名列前茅。并且在MMLU榜单上的得分也超过了LLaMA-7b。在SuperCLUE榜单上,baichuan-7b作为一个未经过指令微调的预训练模型,也取得了相当不错的名次。这让我们更加好奇,经过sft后的baichuan-7b模型的能力会如何?

由于baichuan-7b是一个预训练模型,未经过指令对齐,所以指令遵从的能力较弱。为了进一步验证baichuan-7b模型的能力,我们使用Firefly项目中的QLoRA训练流程,在百万多轮指令数据上进行了指令微调。最终得到了firefly-baichuan-7b-qlora-sft模型,我们也开源了模型权重,欢迎大家使用。

QLoRA简介

QLoRA通过4-bit的nf4量化,且加入更多adapter,在大幅减少显存消耗的同时,尽可能逼近全量参数微调的效果。 QLoRA论文指出,该方法可以在一张V100上对33B的模型进行微调,并且性能逼近全量参数微调。

其中QLoRA的主要工作如下:

  • 4-bit NormalFloat:提出一种理论最优的4-bit的量化数据类型,优于当前普遍使用的FP4与Int4。
  • Double Quantization:相比于当前的模型量化方法,更加节省显存空间。每个参数平均节省0.37bit,对于65B的LLaMA模型,大约能节省3GB显存空间。
  • Paged Optimizers:使用NVIDIA统一内存来避免在处理小批量的长序列时出现的梯度检查点内存峰值。
  • 增加Adapter:4-bit的NormalFloat与Double Quantization,节省了很多空间,但带来了性能损失,作者通过插入更多adapter来弥补这种性能损失。在LoRA中,一般会选择在query和value的全连接层处插入adapter。而QLoRA则在所有全连接层处都插入了adapter,增加了训练参数,弥补精度带来的性能损失。

训练策略

我们使用100万中文多轮指令数据集,使用QLoRA对baichuan-7B进行指令微调。

训练时,我们将多轮对话拼接成如下格式,然后进行tokenize。

<s>input1</s>target1</s>input2</s>target2</s>...

除了embedding和lm_head,我们在所有全连接层处都插入adapter,其中lora_rank为64,lora_alpha为16,lora_dropout为0.05。最终参与训练的参数量约为1.4亿,超过一个bert-base模型的参数量。对于一条多轮指令数据,训练时只计算target部分的损失函数。

训练超参数如下表所示:

max length 1024
lr_scheduler_type constant_with_warmup
batch size 64
lr 2e-4
warmup step 2000
optimizer paged_adamw_32bit
training step 16k

模型的训练损失的变化趋势如下图所示,训练损失的下降比较平滑。

使用方法

from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks

if __name__ == '__main__':
    text_generation_zh = pipeline(task=Tasks.text_generation, model='YeungNLP/firefly-baichuan-7b-qlora-sft')
    text_generation_zh._model_prepare = True
    result_zh = text_generation_zh('背诵李白的《将进酒》')
    print(result_zh)

生成效果

firefly-baichuan-7b-qlora-sft测试样例