LLm与微调

推荐尝试的微调模型

internlm2-20b-chat,internlm2-7b-chat,

Qwen2-7B-Instruct, Qwen2-1.5B-Instruct, Qwen1.5-32B-Chat (Qwen2-0.5B、Qwen2-1.5B, qwen1.5的4B,7B,14B,32B)

glm-4-9b-chat, glm-4-9b-chat-1m, glm-4-9b

Llama3-8B-Chinese-Chat-v2.1,

iFlytekSpark-13B, i-flytek-spark-13-b-model-gpu

模型选型链接

https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard

https://huggingface.co/spaces/BAAI/open_cn_llm_leaderboard

微调介绍

2.1 微调技术分享 [参考自 公众号 follow_bobo]

[PS: 此部分补充内容较多, 会讲的时候简略下, 资料供参赛者自行阅读查看]

什么是模型微调

相当于给你一个预训练模型(Pre-trained model),基于这个模型微调(Fine Tune)。

预训练模型就是已经用数据集训练好了的模型。

两种 Finetune 范式

1、增量预训练微调 (Continue PreTraining)

使用场景:让基座模型学习到一些新知识,如某个垂类领域的常识

训练数据:文章、书籍、代码等

2、指令跟随微调 (Supervised Finetuning)

使用场景:让模型学会对话模板,根据人类指令进行对话

训练数据:高质量的对话、问答数据

为什么微调

相对于从头开始训练(Training a model from scatch),微调可以省去大量计算资源和计算时间,提高了计算效率,甚至提高准确率。

普通预训练模型的特点是:用了大型数据集做训练,已经具备了提取浅层基础特征和深层抽象特征的能力。

不做微调

(1)从头开始训练,需要大量的数据,计算时间和计算资源。

(2)存在模型不收敛,参数不够优化,准确率低,模型泛化能力低,容易过拟合等风险。

使用微调避免了上述可能存在的问题。

什么情况下使用微调?

(1) 你要使用的数据集和预训练模型的数据集相似

如果不太相似,效果可能就没有那么好了,特征提取是不同的,所以相应的参数训练后也是不同的。

(2) 自己搭建或者使用的模型正确率太低。

(3)数据集相似,但数据集数量太少。

(4)计算资源太少。

不同数据集下使用微调

  • 数据集1 - 数据量少,但数据相似度非常高在这种情况下,我们所做的只是修改最后几层或最终的softmax图层的输出类别。

  • 数据集2 - 数据量少,数据相似度低在这种情况下,我们可以冻结预训练模型的初始层(比如k层),并再次训练剩余的(n-k)层。由于新数据集的相似度较低,因此根据新数据集对较高层进行重新训练具有重要意义。

  • 数据集3 - 数据量大,数据相似度低在这种情况下,由于我们有一个大的数据集,我们的神经网络训练将会很有效。但是,由于我们的数据与用于训练我们的预训练模型的数据相比有很大不同。使用预训练模型进行的预测不会有效。因此,最好根据你的数据从头开始训练神经网络(Training from scatch)。

  • 数据集4 - 数据量大,数据相似度高这是理想情况。在这种情况下,预训练模型应该是最有效的。使用模型的最好方法是保留模型的体系结构和模型的初始权重。然后,我们可以使用在预先训练的模型中的权重来重新训练该模型。

微调指导事项

1.通常的做法是截断预先训练好的网络的最后一层(softmax层),并用与我们自己的问题相关的新的softmax层替换它。例如,ImageNet上预先训练好的网络带有1000个类别的softmax图层。如果我们的任务是对10个类别的分类,则网络的新softmax层将由10个类别组成,而不是1000个类别。然后,我们在网络上运行预先训练的权重。确保执行交叉验证,以便网络能够很好地推广。

2.使用较小的学习率来训练网络。由于我们预计预先训练的权重相对于随机初始化的权重已经相当不错,我们不想过快地扭曲它们太多。通常的做法是使初始学习率比用于从头开始训练(Training from scratch)的初始学习率小10倍

3. 如果数据集数量过少,我们进来只训练最后一层,如果数据集数量中等,冻结预训练网络的前几层的权重也是一种常见做法。

这是因为前几个图层捕捉了与我们的新问题相关的通用特征,如曲线和边。我们希望保持这些权重不变。相反,我们会让网络专注于学习后续深层中特定于数据集的特征。

 

微调框架介绍

微调大型语言模型通常是为了使模型在特定任务上表现得更好。

这次我们将主要使用DataWhale的Self-LLM来微调Qwen1.5-4B模型

Self-LLM (Torch Huggingface Peft)

(开源大模型食用指南, https://github.com/datawhalechina/self-llm)

介绍: Huggingface提供了一个基于PyTorch的transformers库,它包含了大量预训练模型和微调工具。用户可以使用这个库来加载预训练模型,并使用PyTorch框架进行微调。

Self-LLM是一个围绕开源大模型、针对国内初学者、基于 AutoDL 平台的中国宝宝专属大模型教程,针对各类开源大模型提供包括环境配置、本地部署、高效微调等技能在内的全流程指导,简化开源大模型的部署、使用和应用流程,让更多的普通学生、研究者更好地使用开源大模型,帮助开源、自由的大模型更快融入到普通学习者的生活中。该项目的主要内容包括:

  1. 基于 AutoDL 平台(可扩展,例如阿里云)的开源 LLM 环境配置指南,针对不同模型要求提供不同的详细环境配置步骤;

  2. 针对国内外主流开源 LLM 的部署使用教程,包括 LLaMA、ChatGLM、InternLM 等;

  3. 开源 LLM 的部署应用指导,包括命令行调用、在线 Demo 部署、LangChain 框架集成等;

  4. 开源 LLM 的全量微调、高效微调方法,包括分布式全量微调、LoRA、ptuning 等。

优点:

  • 社区支持强大,有大量的文档和教程。

  • 支持多种预训练模型,易于加载和使用。

  • 灵活的API,可以自定义微调过程。

缺点:

  • 对于大型模型,计算资源要求较高。

  • 需要一定的PyTorch和深度学习知识。

其他微调框架介绍

不同的框架提供了不同的工具和方法来进行微调。下面是对XTuner和LLaMA-Factory这2种框架的简要介绍,以及它们的异同和优缺点。

异同点
  • 相同点: 所有这些框架都旨在提高大型语言模型在特定任务上的性能,都提供了微调预训练模型的能力。

  • 不同点: 它们在微调方法、易用性、社区支持、特定功能(如多模态支持)和目标用户群体方面有所不同。

XTuner

介绍: XTuner 是一个高效、灵活、全能的轻量化大模型微调工具库,提供了多种微调策略,如LoRA和QLoRA,并且支持多模态数据。

高效

  • 支持大语言模型 LLM、多模态图文模型 VLM 的预训练及轻量级微调。XTuner 支持在 8GB 显存下微调 7B 模型,同时也支持多节点跨设备微调更大尺度模型(70B+)。

  • 自动分发高性能算子(如 FlashAttention、Triton kernels 等)以加速训练吞吐。

  • 兼容 DeepSpeed 🚀,轻松应用各种 ZeRO 训练优化策略。

灵活

  • 支持多种大语言模型,包括但不限于 InternLMMixtral-8x7BLlama 2ChatGLMQwenBaichuan

  • 支持多模态图文模型 LLaVA 的预训练与微调。利用 XTuner 训得模型 LLaVA-InternLM2-20B 表现优异。

  • 精心设计的数据管道,兼容任意数据格式,开源数据或自定义数据皆可快速上手。

  • 支持 QLoRALoRA、全量参数微调等多种微调算法,支撑用户根据具体需求作出最优选择。

全能

  • 支持增量预训练、指令微调与 Agent 微调。

  • 预定义众多开源对话模版,支持与开源或训练所得模型进行对话。

  • 训练所得模型可无缝接入部署工具库 LMDeploy、大规模评测工具库 OpenCompassVLMEvalKit

优点:

  • 支持多种微调策略,包括量化微调。

  • 提供了易于使用的命令行工具和配置文件。

  • 支持多模态数据,可以处理文本和图像。

缺点:

  • 相对于Huggingface,社区和文档可能不够丰富。

  • 新用户可能需要时间来熟悉其工具和接口。

Xtuner+InternLM2参考教程资料
  • [InternLM2]书生·浦语大模型全链路开源体系【书生·浦语大模型实战营第二期第一节笔记】 - 知乎

https://zhuanlan.zhihu.com/p/692078749

  • [InternLM2]XTuner 微调 internlm2-chat-1_8b【书生·浦语大模型实战营第二期第四节笔记】【上】 - 知乎

https://zhuanlan.zhihu.com/p/693147811

  • [InternLM2]XTuner 微调 Llava 多模态模型【书生·浦语大模型实战营第二期第四节笔记】【下】 - 知乎

https://zhuanlan.zhihu.com/p/693359128

  • [Llama3][EmoLLM][Minisora]Meta Llama 3快速上手:用EmoLLM数据基于Xtuner采用QLoRA微调Meta-Llama-3-8B-Instruct模型【V1】 - 知乎

https://zhuanlan.zhihu.com/p/693454096

  • [InternLM2][Llama3]Llama 3 Agent 能力体验+微调(Lagent+XTuner 版) - 知乎

https://zhuanlan.zhihu.com/p/694196479

  • [Llama3][InternLM2][RuoZhiBa][EmoLLM]使用弱智吧数据微调Llama3-Instruct-8B模型 【书生·浦语大模型实战营微调数据构造实验】[弱智吧] - 知乎

https://zhuanlan.zhihu.com/p/694818596

  • Llama-3-8B-Instruct QLoRA 快速微调指南

https://github.com/SmartFlowAI/EmoLLM/blob/main/xtuner_config/README_llama3_8b_instruct_qlora_alpaca_e3_M.md

LLaMA-Factory

https://github.com/hiyouga/LLaMA-Factory/tree/main

介绍: LLaMA-Factory是一个专门用于微调LLaMA模型的工具,提供了WebUI界面,使得非开发人员也能方便进行微调工作。

项目特色

  • 多种模型:LLaMA、LLaVA、Mistral、Mixtral-MoE、Qwen、Yi、Gemma、Baichuan、ChatGLM、Phi 等等。

  • 集成方法:(增量)预训练、(多模态)指令监督微调、奖励模型训练、PPO 训练、DPO 训练、KTO 训练、ORPO 训练等等。

  • 多种精度:32 比特全参数微调、16 比特冻结微调、16 比特 LoRA 微调和基于 AQLM/AWQ/GPTQ/LLM.int8 的 2/4/8 比特 QLoRA 微调。

  • 先进算法:GaLore、BAdam、DoRA、LongLoRA、LLaMA Pro、Mixture-of-Depths、LoRA+、LoftQ 和 Agent 微调。

  • 实用技巧:FlashAttention-2、Unsloth、RoPE scaling、NEFTune 和 rsLoRA。

  • 实验监控:LlamaBoard、TensorBoard、Wandb、MLflow 等等。

  • 极速推理:基于 vLLM 的 OpenAI 风格 API、浏览器界面和命令行接口。

训练方法

数据集

优点:

  • 提供了用户友好的WebUI界面,简化了微调过程。

  • 支持多种LLM模型和微调方法。

  • 集成了业界前沿的微调方法。

缺点:

  • 相对于其他框架,可能在功能和灵活性上有所限制。

  • 专注于LLaMA模型,对于其他类型的模型支持可能不足。

微调入门案例

  • [InternLM2]XTuner 微调 internlm2-chat-1_8b【书生·浦语大模型实战营第二期第四节笔记】【上】 - 知乎

https://zhuanlan.zhihu.com/p/693147811

微调前

微调后

过拟合举例

其他应用举例和参考模型微调,数据构造资源(基于书生浦语的Xtuner和InternLM)

EmoLLM爹系男友心理咨询师

https://openxlab.org.cn/apps/detail/chg0901/EmoLLM3.0_Gradio_Llama3-8B-Instruct3.0

https://github.com/SmartFlowAI/EmoLLM/

高阶微调【扩展内容】

RLHF和DPO

RLHF(Reinforcement Learning from Human Feedback)基于人类反馈对语言模型进行强化学习,

分为两步:

  1. RM(Reward Model)奖励模型建模,构造人类偏好排序数据集,训练奖励模型,用来建模人类偏好,主要是"HHH"原则,具体是"helpful, honest, harmless"

  2. RL(Reinforcement Learning)强化学习,用奖励模型来训练SFT模型,生成模型使用奖励或惩罚来更新其策略,以便生成更高质量、更符合人类偏好的文本.

DPO(Direct Preference Optimization)直接偏好优化方法,DPO通过直接优化语言模型来实现对其行为的精确控制,而无需使用复杂的强化学习,也可以有效学习到人类偏好,DPO相较于RLHF更容易实现且易于训练,效果更好

在RLHF中真的需要强化学习(RL)吗?斯坦福大学的新研究提出了DPO(直接偏好优化):一种简单的训练范式,用于在没有RL的情况下通过偏好来训练语言模型

参考资料

  1. 微调实操一: 增量预训练(Pretraining)-CSDN博客

https://blog.csdn.net/youbingchen/article/details/136001134

  1. 微调实操二: 有监督微调(Supervised Finetuning)-CSDN博客

https://blog.csdn.net/youbingchen/article/details/136072886

  1. 微调实操三:人类反馈对语言模型进行强化学习(RLHF)_人类反馈强化模型-CSDN博客

https://blog.csdn.net/youbingchen/article/details/136204393

  1. 微调实操四:直接偏好优化方法-DPO_dpo微调-CSDN博客

https://blog.csdn.net/youbingchen/article/details/136308044

  1. 大语言模型(LLM)微调技术笔记 – 明柳梦少

https://www.mingliumengshao.com/2023/06/08/%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%EF%BC%88llm%EF%BC%89%E5%BE%AE%E8%B0%83%E6%8A%80%E6%9C%AF%E7%AC%94%E8%AE%B0/

  1. MedicalGPT:训练医疗大模型,实现了包括增量预训练(PT)、有监督微调(SFT)、RLHF、DPO、ORPO。

https://github.com/shibing624/MedicalGPT

7. 解密Prompt7. 偏好对齐RLHF-OpenAI·DeepMind·Anthropic对比分析-腾讯云开发者社区-腾讯云

https://cloud.tencent.com/developer/article/2289566

如何做好一个微调工作:

数据准备

训练格式规范

LLM 的微调一般指指令微调过程。所谓指令微调,是说我们使用的微调数据形如:

其中,instruction 是用户指令,告知模型其需要完成的任务;input 是用户输入,是完成用户指令所必须的输入内容;output 是模型应该给出的输出。

即我们的核心训练目标是让模型具有理解并遵循用户指令的能力。因此,在指令集构建时,我们应针对我们的目标任务,针对性构建任务指令集。

小说数据介绍

我们先来简单看一下数据格式

下面是具体字段的介绍:

  • name:小说名

  • len:小说字符数

  • text:小说内容

数据统计

数据集中,总共有17本小说,12本来自豆瓣亚马逊,5本来自books(世界名著等),小说中有类似文言文的中国传统小说,如四大名著等,也有白话的世界名著中文译本和传统的神话志异小说。每个小说中所含字符数量跟在书籍名称前面。

如果是作为用标点符号断句来构造上下句的input,output数据集,则可以构造的数据集数据统计如下, len_data的含义为可以划分为n个上下文对,也就是每个小说有n+1个不同的句子

这种数据形式也可以一定程度上来提升大模型对800字短篇小说的生成能力。

大家可以尝试结合后面的数据集制作方法来尝试是否对模型微调有效。

小说数据拆分

小说数据分割思路

  1. 根据标点符号(句号、感叹号、问号)分割文本,同时保留这些标点符号.

2、将分割后的数据进行拼接,得到 novel_data_800_dict.json

完整代码如下:

import json
import re


def split_text_by_punctuation(data):
    for item in data:
        text = item.get('text', '')
        # 使用正则表达式根据标点符号分割并保留标点符号
        split_text = re.split(r'([。!?])', text)
        # 将标点符号与前面的句子合并
        sentences = []
        for i in range(0, len(split_text) - 1, 2):
            sentence = split_text[i] + split_text[i + 1]
            sentences.append(sentence)
        if len(split_text) % 2 != 0 and split_text[-1]:  # 如果最后一个字符没有标点符号
            sentences.append(split_text[-1])
        # 添加新的分割列表字段
        item['split_text'] = sentences
    return data


# 读取小说数据
# with open("novels.json", "r") as f:
#     novels_data = json.load(f)
    
novels_data = []
with open("novels.json", "r") as f:
    for line in f:
        novels_data.append(json.loads(line))
    
# 调用函数分割文本
new_novels_data = split_text_by_punctuation(novels_data)

# 拼接文本
novel_data_800_dict = {}
for novel_data in new_novels_data:
    section_data = []
    section = ""
    for sentence in novel_data["split_text"]:
        section += sentence
        if len(section) > 800:
            section_data.append(section)
            section = ""
    novel_data_800_dict[novel_data["name"]] = section_data

# 保存分割后的数据
with open("novel_data_800_dict.json", "w") as f:
    f.write(json.dumps(novel_data_800_dict, ensure_ascii=False, indent=4))

小说数据处理思路

这里我们使用了Qwen2-72b模型做了数据清洗,我们做微调数据时 【为什么要清晰】【除了这种还有哪些可能得方案】【我们这个方案好在哪里?】

小说数据集制作

我们需要将小说数据制作成以下格式进行微调

output:即为拼接后的小说段落文本

instruction:可以设置为:你是一个熟读各类小说的专家,请你根据要求写一段800字左右的小说。

input:通过大模型对output的内容进行小说情节的总结

下面我们使用大模型对小说段落数据进行打标签,完整代码如下:

from loguru import logger
import json
from tqdm import tqdm
import time
import os
from openai import OpenAI

# 配置loguru输出到文件
logger.remove()  # 移除默认的控制台输出
logger.add("logs/app_{time:YYYY-MM-DD}.log", level="TRACE", rotation="00:00", retention="10 days", compression="zip")

def get_response(text):
    client = OpenAI(
        api_key=os.getenv("DASHSCOPE_API_KEY"),  # 如果您没有配置环境变量,请在此处用您的API Key进行替换
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",  # 填写DashScope SDK的base_url
    )
    completion = client.chat.completions.create(
        model="qwen2-72b-instruct",
        messages=[
            {
                'role': 'system', 
                'content': '你是一个熟读各类小说的专家,请你用一句话总结这段小说的情节。仅回答总结,不需要添加其他内容'
            },
            {
                'role': 'user', 
                'content': "他承认班纳特小姐是漂亮的,可惜她笑得太多。赫斯脱太太姐妹同意他这种看法……可是她们仍然羡慕她,喜欢她,说她是个甜姐儿,她们并不反对跟她这样的一位小姐做个深交。班纳特小姐就这样成为一个甜姐儿了,她们的兄弟听到了这番赞美,便觉得今后可以爱怎么样想她就怎么样想她了。\n距离浪博恩不远的地方,住着一家人家,这就是威廉·卢卡斯爵士府上。班纳特府上跟他们特别知已。爵士从前是在麦里屯做生意起家发迹的,曾在当市长的任内上书皇上,获得了一个爵士头衔;这个显要的身份使他觉得太荣幸,从此他就讨厌做生意,讨厌住在一个小镇上,于是歇了生意,告别小镇,带着家属迁到那离开麦里屯大约一英里路的一幢房子里去住,从那时候起就把那地方叫做卢家庄。他可以在这儿自得其乐,以显要自居,而且,既然摆脱了生意的纠缠,他大可以一心一意地从事社交活动。他尽管以自己的地位欣然自得,却并不因此而目空一切,反而对什么人都应酬得非常周到。他生来不肯得罪人,待人接物总是和蔼可亲,殷勤体贴,而且自从皇上觐见以来,更加彬彬有礼。卢卡斯太太是个很善良的女人,真是班纳特太太一位宝贵的邻居。卢府上有好几个孩子。大女儿是个明理懂事的年轻小姐,年纪大约二十六七岁,她是伊丽莎白的要好朋友。且说卢府上几位小姐跟班府上几位小姐这回非要见见面,谈谈这次跳舞会上的事业不可。于是在开完了跳舞会的第二天上午,卢府上的小姐们到浪博恩来跟班府上的小姐交换意见。\n班纳特太太一看见卢卡斯小姐,便客客气气,从容不迫地说:“那天晚上全靠你开场开得好,你做了彬格莱先生的第一个意中人。”“是呀;可是他喜欢的倒是第二个意中人。”“哦,我想你是说吉英吧,因为他跟她跳了两次。看起来,他是真的爱上她呢……我的确相信他是真的……我听到了一些话……可是我弄不清究竟……我听到了一些有关鲁宾逊先生的话。”“说不定你指的是我喻听到他和鲁宾逊先生的谈话吧;我不是跟你说过了吗?鲁宾逊先生问他喜欢不喜欢我们麦里屯的跳舞会,问他是否觉得到场的女宾们中间有许多人很美,问他认为哪一个最美?"
            },
            {
                'role': 'assistant', 
                'content': "浪博恩的班纳特家与卢卡斯家交好,班纳特家的二小姐伊丽莎白在舞会上因笑容过多而未得到达西的好感,但得到了彬格莱的青睐,卢卡斯家的大女儿夏洛特则是伊丽莎白的好友,两家人在舞会后讨论着舞会上的趣事和可能的姻缘。"
            },
            {
                'role': 'user', 
                'content': text
            }
        ])
    
    return completion.choices[0].message.content

def get_summary_with_retry(text):
    max_retries = 5
    retry_delay = 15  # in seconds
    attempts = 0
    while attempts < max_retries:
        try:
            return get_response(text)
        except Exception as e:
            attempts += 1
            if attempts < max_retries:
                logger.warning(f"Attempt {attempts} failed for text: {text}. Retrying in {retry_delay} seconds...")
                time.sleep(retry_delay)
            else:
                logger.error(f"All {max_retries} attempts failed for text: {text}. Error: {e}")
                raise

def build_dataset(novel_data_800_dict):
    instruction_prompt = "你是一个熟读各类小说的专家,请你根据要求写一段800字左右的小说。"
    
    for novel, texts in novel_data_800_dict.items():
        dataset = []
        dataset_error = []
        for text in tqdm(texts, desc=f"Processing {novel}", total=len(texts)):
            try:
                summary = get_summary_with_retry(text)
                dataset.append({
                    "instruction": instruction_prompt,
                    "input": summary,
                    "output": text
                })
            except Exception as e:
                dataset_error.append(text)
                logger.error(f"Failed to process text: {text}. Error: {e}")

        with open(f"{novel}.json", "w", encoding="utf-8") as f:
            f.write(json.dumps(dataset, ensure_ascii=False, indent=4))

        with open(f"{novel}_error.txt", "w", encoding="utf-8") as f:
            f.write(json.dumps(dataset_error, ensure_ascii=False, indent=4))
    return dataset


def build_dataset_control(novel_data_800_dict, start_n=9, end_n=11):
    instruction_prompt = "你是一个熟读各类小说的专家,请你根据要求写一段800字左右的小说。"
    print(novel_data_800_dict.keys())
    ii = 0
    for novel, texts in novel_data_800_dict.items():
        ii+=1
        if ii>start_n and ii<end_n:
            dataset = []
            dataset_error = []
            for text in tqdm(texts, desc=f"Processing {novel}", total=len(texts)):
                try:
                    summary = get_summary_with_retry(text)
                    dataset.append({
                        "instruction": instruction_prompt,
                        "input": summary,
                        "output": text
                    })
                except Exception as e:
                    dataset_error.append(text)
                    logger.error(f"Failed to process text: {text}. Error: {e}")
            
            with open(f"{novel}.json", "w", encoding="utf-8") as f:
                f.write(json.dumps(dataset, ensure_ascii=False, indent=4))

            with open(f"{novel}_error.txt", "w", encoding="utf-8") as f:
                f.write(json.dumps(dataset_error, ensure_ascii=False, indent=4))
    return dataset

if __name__ == "__main__":
    with open("novel_data_800_dict.json", "r", encoding="utf-8")as f:
        novel_data_800_dict = json.load(f)
    # build_dataset(novel_data_800_dict)
    build_dataset_control(novel_data_800_dict, start_n=9, end_n=11)

build_dataset_control()引入了start_nend_n两个参数, 来控制生成数据的数量和位置, build_dataset_control(novel_data_800_dict, start_n=9, end_n=11)可以生成第10个小说文件("醒世恒言")的数据集,

微调

本节内容也请大家按步骤结合资料再去尝试,微调中有很多参数、方法、框架都能进行组合。篇幅有限我们只是例举了torch中的LoRA对Qwen2-1.5B-Instruct微调。

2.1 微调介绍

基于self-llm对Qwen2-1.5B-Instruct模型 LoRA微调

我们简要介绍如何基于 transformers、peft 等框架,对 Qwen2-1.5B-Instruct 模型进行 LoRA 微调。

LoRA 是一种高效微调方法,深入了解其原理可参见博客:[知乎|深入浅出Lora]

LoRA 的优势

- 可以针对不同的下游任务构建小型 LoRA 模块,从而在共享预训练模型参数基础上有效地切换下游任务。

- LoRA 使用自适应优化器(Adaptive Optimizer),不需要计算梯度或维护大多数参数的优化器状态,训练更有效、硬件门槛更低。

- LoRA 使用简单的线性设计,在部署时将可训练矩阵与冻结权重合并,不存在推理延迟。

- LoRA 与其他方法正交,可以组合。

LoRA 的原理

- https://github.com/microsoft/LoRA?tab=readme-ov-file

- https://arxiv.org/pdf/2106.09685

- https://huggingface.co/docs/peft/quicktour

微调实现

这个教程会给大家提供一个 notebook 文件,来让大家更好的学习。

总结与展望

教程总结与提示

感谢大家的时间,我们一起解读了「酷文」小说创作大模型挑战赛的赛题,并进行了一定的赛题任务分析,对LLM和国产LLM模型进行了一定的介绍。

我们也用了较多的时间介绍了微调LLM的一些基础知识和相关的微调框架,举例等。

然后我们进行了保姆级的小说生成数据集准备,格式调整,拆分,制作和合并,也对这份我们准备好的数据进行了Qwen2-1.5B-Instruct模型的LoRA微调,并且还简单的介绍了LoRA的优势和核心思想原理,最终我们成功的实现了模型微调和推理验证。

同时,我们也提供了对微调的小说生成大模型的结果测评思路,也提供了建议测评的prompt供大家学习。

希望大家可以有所收获,将这次教程的分享内容真正的应用到这次「酷文」小说创作大模型挑战赛中,并以此为契机,来进一步掌握模型微调,数据构造等大语言模型应用技术,真正的将技术应用到我们的比赛中和工作学习生活中,让我们的生活变得更美好,惬意,解放自己的生产力,去做更多有意义,有价值的事情或者陪伴家人等!

进阶方案介绍

当然,我们此次提供的教程只是作为大家比赛和入门的一个baseline,也有一定的局限性和不足,为了大家可以更好的参赛和优化自己的模型,我这里也给出一定的进阶方案建议如下:

  1. 数据集构造:目前的方案是采用大模型对大约800字的小说内容截取做摘要来作为输入,而这个800字的内容是输出,也采用了一个相对简单的system prompt,所以我们可以

    1. 对小说数据进行进一步的清洗,去除和正文无关的内容,

    2. 调整800字小说内容的选取,使内容连贯完整,

    3. 优化system prompt

  2. 针对数据的优化:如,小说中对话数据较多,如何处理?

  3. 模型选型:我们采用了qwen2的1.5B-Instruct模型进行微调,大家可以尝试不同公司组织的不同尺寸的模型来进行微调,根据自己的数据量,训练epoch,数据质量来调整模型的大小和选型,来进一步提高自己所训练模型的能力

  4. 微调框架:为了让大家快速上手,我们采用了难度较低的self-llm的微调方案,基本上采用了原生的Pytorch和PEFT的微调方案,但是诚如我们在微调框架里介绍的那样,还有很多优秀的微调模型,有着更多好用的功能,也可以提供所训练模型的能力和微调质量,大家可以多多尝试。

  5. 微调方案:除了LoRA微调方法,也有众多新的微调方案,大家可以多多的搜索最新的研究进展,将新的算法和trick应用到比赛中来

  6. 实体识别,知识图谱,防止幻觉

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值