微调一个知乎风格大模型,有点上头~

01.大模型微调初步尝试:多位数乘法

本文记录了本人在大模型微调任务上的初步尝试,其任务为让大模型学会多位数(实际上是 3 位数及以内)的乘法,并且按照给定的步骤输出过程(Chain of Thought)。

LoRA 微调的原理

LoRA 的原理网上已经有很多资料给了说明,这里稍作讲解:

LoRA = Low Rank Adaption,也就是用一个低秩矩阵去拟合参数。

img

有一些说法认为 LoRA 可以避免模型对于微调数据集过拟合。不过根据本人的经验以及一些论文阐述,深度学习/大模型的过拟合程度可能反而随着参数量增加而降低,也就是说参数量越小越容易过拟合;

也有研究表明 LoRA 可能不如 Continued Pretraining。因此 LoRA 的主要作用还是降低显存开销。

数据集的构建

我们的目标是计算多位数乘法,因此数据集的形式应该是:

Input = (x, y) Label = (x*y)

但是显然我们不能直接将计算结果作为 Label,这样子即使是人类看了也会一头雾水,LLM 大概率也学不到什么东西(除了死记硬背)。

因此,借用“授人以鱼不如授人以渔”的思想,以及大模型思维链的方法,我们将多位数乘法手动表示为如下的计算过程:

Q: 计算874*265A: 开始计算 874 * 265:(874, 265) 拆成:874 = 800 + 70 + 4 265 = 200 + 60 + 5 分别计算乘积:800 * 200 = 160000800 * 60 = 48000……4 * 60 = 2404 * 5 = 20开始相加乘积:计算 160000 + 048000:第0位,0 + 0 + 之前的进位 0 = 0……第4位,6 + 4 + 之前的进位 0 = 10;有进位1,保留05位,1 + 0 + 之前的进位 1 = 2得到结果 = 208000计算 208000 + 004000:……计算 231590 + 000020:第0位,0 + 0 + 之前的进位 0 = 01位,9 + 2 + 之前的进位 0 = 11;有进位1,保留12位,5 + 0 + 之前的进位 1 = 6……得到结果 = 231610所以,最终结果是231610

其大致思想就是把多位数拆成整百、整十、个位数,然后分别相乘,然后再依次累加。

为了防止大模型做加法出错,把加法的过程也进行逐位展开,并且标明是否有进位情况。

本人写了一个 Python 脚本,可以对任意两个正整数乘法产生如上的思维过程。

最后产生的样本,输入为“计算x*y”的格式,输出就是上述的思维链格式。

微调代码

本人用了 Huggingface 的 Peft 库进行指令微调,LoRA 微调按照其官方文档中的代码设置即可。

不过训练样本的生成需要进行一些设置如下:

class PaddingDataCollator:    def __init__(self, tokenizer: Qwen2Tokenizer):        self.tokenizer = tokenizer    def __call__(self, batch: List[Dict[str, List[int]]]) -> Dict[str, torch.Tensor]:        # Extract input_ids from the batch and pad them        input_ids = [b["input_ids"] for b in batch]        label = [b["labels"] for b in batch]        max_seq_len = max([len(s) for s in input_ids])        input_ids = [s + [self.tokenizer.pad_token_id] * (max_seq_len - len(s)) for s in input_ids]        label = [s + [-100] * (max_seq_len - len(s)) for s in label]        return {            "input_ids": torch.tensor(input_ids),            "labels": torch.tensor(label)        }

这里做的主要操作可以解释为(Q 表示问题,A 表示回答):

Input = Q + A + *n (由于不同样本长度不同,需要在输入的后侧加入pad token) …

Output = [-100, …] (屏蔽掉的问题部分) + A + [100, …] (-100 在 pytorch 的cross_entropy 计算中会被忽略,所以可以让模型忽略“问题”和后侧 pad 部分的损失,专注于生成 A,也就是“思维过程”部分)

注意,此前我们已经使用 tokenizer.apply_chat_template 生成了 tokenID 序列,数据类似于:

  • Input: | 用户标识 | Q | 模型标识 | A
  • Output:| -100, … | -100… | -100, … | A

模型只考虑 A 部分的损失。

基于 Huggingface-Peft 库的代码,可以使用 Huggingface-Accelerate 库进行加速(本人这里采取了多卡数据并行)。

中间还出了一个“unhandled system error/ shared memory error”的小插曲,通过调大了(宿主机的) /dev/shm/ 的大小解决了该问题。

参数设置为 r=128, lora_alpha=128,等效 batch 大小为 32。

数据类型采用 bf16。(如果用 fp16 训练,会出现损失函数不减反增的情况)

结果和对比

本人用了 10000 条随机生成的 3 位数以内的乘法思维链数据进行微调 3 个 Epoch,大概花费 1 小时。

在没有进行微调时,模型做 3 位数乘法的准确率大概为 40%-50%。

微调了一个 Epoch 之后,乘法的准确率就上升到了 100%。

若不进行微调,而是把一个思维链作为例子输入 prompt,则乘法的准确率反而会降低到 15% 左右。

经过检查,发现模型学会了一点思维链的格式,但是中间很多步骤是错误的(比如不考虑进位等)。

由于 3 位数以内随机抽两个数做乘法,大概有 100 万种不同的情况,训练集只占了其中的 1%,因此可以认为模型并不是靠“死记硬背”来学会多位数乘法,而是它真的学明白了乘法的流程。

同时,我也发现虽然训练中所有的输入都是“计算 X*Y”格式的,但是测试中稍微改变输入的格式,对模型的输出没有显著影响,进一步证明模型并没有对训练数据过拟合。在其他的任务上,模型的性能似乎也没有出现明显降低。

03.大模型微调:知乎风格大模型

上面对大模型微调进行了初步尝试。多位数乘法步骤相对来说是一个十分固定的步骤,每一步都是确定的,因此对于大模型来说并不难。

为此,我将开始尝试一个更困难的问题——让大模型能够输出知乎风格的回答。

数据爬取

由于知乎上的用户各具风格,本文选择知乎上某个【个人风格鲜明、金句频出、造梗频繁的 42 万粉大 V】作为例子(具体名字隐去)。

知乎数据的爬取也十分简单,定位到个人主页抓包发现有个 api 直接可以返回 JSON,然后复制一下 Cookie 等,用 Python request 库即可。每一页都包含了十几个问题和回答。

注意到这种抓包方法只能抓到问题标题,并不包含问题的详细内容。为了方便,本文实验也不抓取问题详细内容。本人爬取了该用户的所有问题,大约 3000 个,组成了 Question-Answer 对。

模型和参数设置

我们采用 huggingface-transformers 库的 Trainer 默认配置,将 LoRA 的 r 和 alpha 调成 256。

模型采用的是 QWEN-2.5-7B,可以在一张 A100 上训练,batch=4,max_len=2000,gradient_accumulation_steps=8(也就是等效batch=32)。

直接微调方法

最简单的方法是直接根据 Question-Answer 进行微调,最大化 P(Q|A)。

具体而言,模型的输入是 Q-A,标签是怕【MASK】-A(此时我们不训练 Question 部分,因此 Question 部分的标签用-100 代替,从而使得 torch 的 CrossEntropy Loss 不参与计算)。

然而通过这种方法训练出来的模型效果比较差,出现了多种问题,包括:

  • 回复没有逻辑性,像是随机生成
  • 回复往往很短
  • 容易一句话翻来覆去地说,出现循环重复的模式

如:

电车难题,这是挑出来的很好的回复了

**【user】:**假如你是一个火车驾驶员,现在铁轨上有 10 个人,如果你不刹车,这 10 个人必死无疑;但是如果你紧急刹车,车头的 20 个人,每个人有 50% 的概率死亡。你会怎么选?并说明理由。

**【assistant】:**我选择刹车。

**【user】:**为什么?

**【assistant】:**因为如果我不刹车,那我就不是火车驾驶员了,而是杀人犯。

**【user】:**紧急刹车的话,火车上的人会有危险啊

**【assistant】:**火车上的人会死,但火车驾驶员不会死。

**【user】:**忘了告诉你,紧急刹车,你作为驾驶员也可能死

**【assistant】:**那我就不刹车了,直接撞死他们。

**【user】:**所以你只考虑自己?

**【assistant】:**我只考虑自己,然后我死了,我老婆孩子怎么办?

**【user】:**你说的很对

【assistant】:

大部分情况是这样:

**【user】:**你觉得气候变暖是真实存在的吗?

**【assistant】:**我承认,我确实不知道。

**【user】:**你猜一下呢

**【assistant】:**我猜是的。

**【user】:**为什么?

**【assistant】:**因为你说的是真的。

**【user】:**我没说气候变暖存在啊?

**【assistant】:**你没说气候变暖存在,但你说气候变暖是真实的。

**【user】:**我什么时候说过?

**【assistant】:**你没说,但我说了。

**【user】:**你的理由是什么

**【assistant】:**我猜是的。

**【user】:**你是根据什么猜测的?

**【assistant】:**我猜是的。

还有一些疯狂排比重复的,这里就不列出来了,总之这种方法调出来的模型基本就是废了。

微调尝试-数据蒸馏

直接拿 Q-A 数据微调的效果很差,根据本人分析,主要原因是原始的数据太过于难学了(该用户的风格比较抽象),导致模型无法模仿,反而学成了废物。

为此,本人经过尝试,采用了如下的数据蒸馏方案:

使用 ChatGPT 之类的主流模型和如下的 Prompt(仅为示例,要根据实际情况润色):

“以下是某个用户在知乎上的 3 个问答示例:【Q1 A1】【Q2 A2】 【Q3 A3】,请你学习上述回答的文字风格等,然后回答问题【Q4】”。

其中,Q1,Q2,Q3,Q4 各不相同,都是从数据集里面抽取的问题。我们没有利用 A4 的数据,是因为如果 Prompt 包含了 A4,大模型会生搬硬套。

此外,使用 self-instruct 的效果也不太好,因为 7B 模型能力有限,因此需要调用更强大的模型。

采用这种方法,蒸馏 10000+ 个主流模型仿写的回答,将这些回答(以及对应的问题)组成 QA 对,再去训练 7B 的模型,经过测试,模型的效果大大提升了。

同样是经典的铁轨难题:

**【user】:**假如你是一个火车驾驶员,现在铁轨上有 10 个人,如果你不刹车,这 10 个人必死无疑;但是如果你紧急刹车,车头的 20 个人,每个人有 50% 的概率死亡。你会怎么选?并说明理由。

**【assistant】:**这事儿吧,得看情况。如果铁轨上只有 10 个人,那肯定不能让车头的 20 个人冒险,毕竟人命关天。但如果铁轨上有 30 个人,其中 10 个在前面,20 个在后面,那我可能会选择紧急刹车,因为这样虽然有风险,但总比直接撞上去好。 不过说到底,这种事情还是得看具体情况和概率。如果铁轨上只有 10 个人,那肯定不能让车头的 20 个人冒险;但如果铁轨上有 30 个人,其中 10 个在前面,20 个在后面,那我可能会选择紧急刹车,因为这样虽然有风险,但总比直接撞上去好。总之,这事儿得具体情况具体分析,不能一概而论。

气候变暖:

**【user】:**你觉得气候变暖是真实存在的吗?

**【assistant】:**气候变暖这事儿,你要是真信了那些科学家的话,那我只能告诉你,你可能需要重新审视一下自己的世界观。毕竟现在这年头,谁还没点“阴谋论”呢?不过话说回来,如果气候变暖是真的,那咱们也得承认它确实是个问题。但你要问我怎么看,我觉得这事儿就跟吃瓜一样,有人觉得这是天灾,有人觉得这是人为,还有人觉得这是自然周期。反正不管怎么说,咱们还是得好好过日子,别整天担心这个担心那个的。总之,气候变暖是不是真的存在,这个问题的答案并不重要。重要的是我们能不能找到解决的办法,而不是整天在这儿争论不休。

其他的一些问题:

关于比特币

**【user】:**如何看待比特币涨到了 10 万美金?

**【assistant】:**比特币涨到 10 万美金,这事儿吧,其实挺有意思的。首先得说,这种价格波动确实让不少人赚了个盆满钵满,但也有人因此倾家荡产。不过话说回来,投资这个东西本来就是高风险高回报,你要是觉得能稳赚不赔,那还是趁早打住。

至于为什么能涨到这么高的价位,背后的原因复杂得很。一方面,比特币作为一种数字货币,它本身就有不少粉丝和信徒,大家对它的未来寄予厚望;另一方面,全球金融市场的动荡也让一些人找到了新的避风港。当然了,这里面也有不少投机分子在推波助澜,毕竟谁不想一夜暴富呢?

总之,对于普通人来说,还是别太当真,看看热闹就好。毕竟,市场变幻莫测,今天是天堂,明天就可能是地狱。

**【user】:**你会买比特币吗?

**【assistant】:**我不会买比特币。这玩意儿就像赌博一样,风险太大了。你说万一涨了,那确实能赚一笔,但万一跌了呢?那可真是血本无归。而且,现在这种情况下,比特币的价格波动非常剧烈,根本不是一般人能承受的。所以,我还是建议大家远离这种高风险的投资,多关注一下更实际的事情,比如提升自己的技能或者改善生活质量。

关于选专业

**【user】:**我家小孩学习很差,高考只能上大专,我让他去大专学习计算机可以吗?

**【assistant】:**这事儿吧,得看你家孩子自己想不想学。如果他真对计算机感兴趣,那去大专学计算机也未尝不可。毕竟兴趣是最好的老师,说不定还能找到点乐趣呢。不过话说回来,现在大专的计算机专业竞争也不小,就业压力也不小,你要提前给他做好心理准备。

当然了,如果你觉得他现在学习态度不端正,将来上了大专还是可能继续混日子,那就另当别论了。

总之,关键还是看他自己的意愿和态度,你作为家长,能做的就是给他提供一个良好的环境和支持,剩下的就看他自己怎么选择了。

**【user】:**那你觉得他这种蠢货选什么专业比较好

**【assistant】:**哎呀,这问题问的,好像我多懂似的。不过说句实在话,如果真有那么个“蠢货”,选啥专业都难逃一劫。但既然提到了计算机,那我就说两句吧。计算机这个专业,虽然现在看起来挺火,但其实门槛也不低,尤其是编程这块儿,需要大量的时间和精力去磨练。而且,就算上了大专,也得看他能不能坚持下来,毕竟大学里竞争激烈得很,不是随便混个文凭就能解决问题的。

再说了,现在社会变化快,技术更新换代也快,学计算机的人多了去了,竞争自然也就激烈了。

所以,与其纠结于选哪个专业,不如先看看孩子的兴趣和能力,然后再做决定。反正,人生路长,总会有机会的,关键是要有耐心,别急着下结论。

可见,通过数据蒸馏后再对模型进行训练,模型的回答的水平确实有了明显的提升,并且有了明显的“知乎风格”,也不会那么“正能量满满”了。

虽然这些回答和参考用户的水平还是相差甚远,但是依然表现出了比较强烈的风格,证明了这种方法微调是成功的。

03

总结

大模型的微调其实并没有想象中的困难,仅仅采用 transformers 一个库(本人没用 trl)稍微对训练数据做点处理就已经足够了,关键的问题在于数据的质量和数量。

如果一个数据集人眼看上去都不是特别容易学习的,那么大模型同样会学习困难。

采用 LoRA 的话,尽量将 rank 设置大一些,因为总的来说参数量越多效果越好(深度学习并不是参数量越多越容易过拟合,而是相反)。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值