课程链接:BV1o217YeELo
文章目录
- LLM基础相关
- 1. LLMs概述
- 2. 大语言模型尺寸
- 3. LLMs的优势与劣势
- 4. 常见的大模型分类
- 5. 目前主流的LLMs开源模型体系有哪些(Prefix Decoder,Causal Decoder,Encoder-Decoder的区别是什么)
- 6. LLMs中常用的预训练任务(目标)
- 7. LLMs中涌现能力是啥原因
- 8. 什么是Scaling Law?谈谈对它的理解
- 大模型幻觉相关
- 1. 什么是大模型幻觉?
- 2. 发生幻觉的原因
- 3. 如何评估大模型幻觉问题?
- 4. 如何缓解LLMs幻觉问题
- RAG相关
- 1. 什么是RAG,它有什么特点?
- 2. RAG的总体思路
- 3. 如何评价RAG项目效果的好坏
- 4. RAG的优化策略(重要)
- 4.1 知识文档准备阶段(数据清洗、分块处理)
- 4.2 嵌入模型阶段
- 4.3 向量数据库阶段(元数据)
- 4.4 查询索引阶段(检索找回、重排)
- 4.5 生成回答阶段(提示工程)
- 知识蒸馏相关
- 1. 什么是知识蒸馏
- 2. 知识蒸馏的目的
- 3. 传统的知识蒸馏方法
- 4. 大语言模型的知识蒸馏方法
- 5. 谈谈对模型量化的了解
- 6. 模型压缩和加速的方法有哪些
- 微调相关
- 1. 什么时候需要对大模型进行微调
- 2. LLMs中微调方法有哪些
- 3. 主流PEFT的方法有哪些
- 4. Adapters类微调
- 5. Prefix类微调
- 6. LoRA相关问题
- 7. QLoRA的思路
- 8. PEFT中,基座模型应该选用Chat版本还是Base版本?
- 9. 预训练和微调哪个阶段注入知识?
- 10. 多轮对话任务如何微调模型?
- 10.1 数据准备
- 10.2 构建输入输出格式
- 10.3 模型选择
- 10.4 微调模型
- 10.5 超参数调优
- 10.6 评估和测试
- 10.7 特定技巧的应用
- Transformers相关
- 1. Transformers概述
- 2. Transformer的输入部分具体是如何构成?
- 2.1 单词 Embedding
- 2.2 位置 Embedding
- 自注意力原理
- 3.1 自注意力结构
- 3.2 QKV的计算
- 3.3 自注意力的输出
- 3.4 多头注意力
LLM基础相关
1. LLMs概述
大模型:一般指100M以上参数的模型,标准持续升级,目前万亿参数模型(MinMax avav6.5)也有开发。
LLM关键特点:
- 大规模参数
- 多任务处理能力:情感分析、阅读理解、文本综述
- 上下文理解:长序列上下文的理解能力
- 自监督学习(即自回归生成)
- 通用性和可扩展性(即少量微调即可应用到不同领域)
局限性:事实错误、幻觉、偏见、计算成本
- 参考资料:不同尺寸大模型中文能力评测,目前囊括115个LLM,包括chatgpt、gpt4o、文心一言、阿里通义千问、讯飞星火、商汤sensechat、minimax等商用模型,以及百川、qwen2、glm4、yi、书生internLM2、llama3等开源大模型,’
- 参考链接:https://github.com/jeinlee1991/chinese-llm-benchmark
- 综合能力:分类能力、信息抽取、阅读理解、数据分析、指令遵从、算术运算(目前gpt4o遥遥领先)
2. 大语言模型尺寸
参数量Billion,常见的LLM参数规模:
- 175B:OpenAI的GPT3
- 60B:Meta的LLM某些版本
- 540B:Google的PaLM(Pathways Language Model)
参数量越多越好,但总会到头,因为受限于算力和数据量。因此有了围绕o1相关的研究。
3. LLMs的优势与劣势
优点:
- 语言理解和生成能力强
- 跨领域知识广泛
- 支持多语言
- 快速部署和适应性:领域适应性(微调)
缺点:
- 缺乏事实准确性:生成看似合理但不准确的信息,因为本质上是概率生成,而非真正理解事实,知识更新存在滞后性
- 计算资源消耗大
- 可能产生的偏见:性别、种族、地域,影响模型的公正性和适用性
- 隐私和安全问题:训练过程中,接触到一些敏感的个人信息,可能在生成内容时泄漏。
4. 常见的大模型分类
根据输入内容分类:
- 语言大模型(NLP):GPT系列(OpenAI,到GPT4已经时多模态),Bard(Google),文心一言,Qwen(阿里)
- 视觉大模型(CV):VIT系列(Google),文心UFO,华为盘古CV,INTERN(商汤书生),用于图像分类、目标检测、语义分割、姿态估计、人脸识别
- 多模态大模型:DALL-E(OpenAI),midjourney,之后现在大部分LMs都是多模态了
根据预训练任务分类:
- 自回归语言模型:GPT系列(自回归预测)
- 自编码语言模型:BERT(掩码预测)
- seq2seq语言模型:T5,BART,机器翻译、文本生成、阅读理解、问答等
根据模型规模分类
- small tiny:10M~100M
- base:100M~1B
- large:10B~100B
5. 目前主流的LLMs开源模型体系有哪些(Prefix Decoder,Causal Decoder,Encoder-Decoder的区别是什么)
- 在与训练语言模型时代,自然语言处理领域广泛采用了预训练+微调的范式,并诞生了以BERT为代表的Encoder-only架构,以GPT为代表的Decoder-only架构,以T5为代表的Encoder-Decoder架构的大规模预训练语言模型
- 随着GPT系列模型的成功发展,当前自然语言处理领域走向了生成式LLM的道路,Decoder-only架构已成主流,进一步地,Decoder-only架构可以细分为因果解码器(Causal Decoder)和前缀解码器(Prefix Decoder)。学术界提到解码器架构时,通常指因果解码器
下图对三种解码器架构进行对比:
Encoder-Decoder
- Encoder-Decoder架构即原始Transformer的架构,机器翻译
- 编码器端:双向自注意力机制对输入信息编码处理
- 解码器端:交叉注意力与掩码自注意力机制,进而通过自回归方式生成
- 目前只有FLAN-T5等少数LLM是基于Encoder-Decoder搭建
Causal-Decoder
- 主流框架(GPT系列),因果语言模型,包括LLaMa也是
- 使用单向注意力掩码,以确保每个输入token只能注意到过去的token以及本身
- 输入和输出的token通过Decoder以相同方式进行处理
- 在图中,灰色代表两个token互相之间看不到,否则就可以看到,例如Survey可以看到前面的A,但看不到后面的of,Causal Decoder的Sequence Mask矩阵是一种典型的下三角矩阵
- 代表模型:GPT系列,LLaMa(Meta)
Prefix-Decoder
- 又称为非因果解码器架构,对掩码机制修改
- 前缀解码器对于输入(前缀)部分使用双向注意力进行编码,而对于输出部分利用单向掩码注意力,即利用该token本身和前面的token进行自回归预测
- 代表模型:GLM-130B和U-PaLM(Google)
总结:三者区别在于attention mask不同
-
Encoder-Decoder(T5)
- 输入采用双向注意力,对问题编码理解更充分
- 在偏理解的NLP任务上效果好
- 长文本生成效果差,训练效率低
-
Causal Decoder(GPT)
- 自回归LM,预训练和下游应用完全一致,严格遵守只有后面的token才能看到前面token的规则
- 文本生成效果好
- 训练效率高,zero-shot能力更强,具有涌现能力
-
Prefix Decoder(GLM)
- prefix部分的token相互能看到
- 文本生成效果好
6. LLMs中常用的预训练任务(目标)
主要分为三类:
- 语言建模(LM):
- 目标函数:每个token的最大似然
- 本质上,是一种多任务学习过程,因为不同token的预测对应不同的任务(数量、情感等)
- 因此可以潜在地学习到解决不同任务的知识与能力
- 训练效率:Prefix Decoder < Causal Decoder
- Causal Decoder架构会在所有token上计算损失,而Prefix Decoder只在输出上计算损失
- 去噪自编码(Denoising AutoEncoder):
- BERT,T5
- 文本经过一系列随即替换、删除操作,形成损坏的文本,模型需要恢复原文本
- 目标函数就是被损坏的token的最大似然
- 任务设定更为复杂,需要设定token替换策略,替换长度,替换比例,都影响训练效果。目前应用有限,主要是FLAN-T5(不过我记得GLM的预训练任务也是类似的一种创新的任务)
- 混合去噪器(Mixture-of-Denoisers,MoD):统一了DAE和LM
7. LLMs中涌现能力是啥原因
参考资料:张俊林老师《大语言模型的涌现能力:现象与解释》
涌现能力:复杂系统由很多微小个体构成,当这些微小个体凑到一起,相互作用,当数量足够多时,在宏观层面上展现出微观个体无法解释的特殊现象(效果突然变好了)
猜想一:任务的评价指标不够平滑:
- 以Emoji_movie任务来解释,任务是输入Emoji图像,LLM给出完全正确的电影名称,一字不差算对
- 例子中,2M到128B后,模型完全猜对,但其实中途已经慢慢感觉猜对了,还差一点,但是评价指标是精准匹配,因此导致模型的评估出现突然增长。
- 改成平滑的指标就不会有这种跳跃了。
猜想二:复杂任务 v.s. 子任务
- 复杂任务是由多个子任务构成,只有当子任务都学会了,复杂任务才能做对
- 因此发生性能条约
- 这里以国际象棋AI训练为例,合法移动 v.s. 将死
- LLM预测下一步,最终评价指标是将死才算赢,如果按将死评估,发现模型增大,模型缓慢上升,符合涌现的表现。
- 若评估LLM合法移动,而在合法的移动步骤里进行正确选择才够最后将死是个子任务,所以其实这是比将死简单的子任务
- 我们看合法移动随着模型规模,效果持续上升,其实并没有涌现
8. 什么是Scaling Law?谈谈对它的理解
什么是Scaling Law?
-
在训练之前了解模型的能力,以改善大模型的对齐、安全和部署决定。
-
通过测试不同尺寸下模型的性能,然后对大尺寸模型的性能进行预测
-
GPT-4 technical report里对GPT-4性能边界的预测(https:/cdn.openai.com/papers/gpt-4.pdf)
-
定义:用计算量、数据集规模和模型尺寸,来预测模型的最终能力(通常以相对简单的函数形态,如Linear relationship)
在LLM中,我们期望模型能够理解人类语言的一般规律,从而做出与人类相似的表达方式,通过使用大量的数据进行训练从而获得使得模型学习到数据背后的一般规律。
LLM预训练,主要是围绕训练的计算量,数据集规模和模型规模的三方博弈
但是三者的作用到底是多少呢?Scaling Law就是做这个的
-
OpenAI和DeepMind这两家有代表性研究(前者是做AGI,后者着重于高精专的AI,如AlphaGo)
-
2020年,OpenAI的Kaplan团队在Scaling Laws for Neural Language Models,这个我之前看过,博客125139643,arxiv.2001.08361
- 他们发现模型尺寸,数据集大小和训练计算量,三者任一受限时,Loss与其之间存在幂律关系(即两个变量中的一个变量与另一个变量的某个幂次呈正比)
- 因此为了获得最佳性能,必须将三者同步扩大
- 当没有受到其他两个因素限制时,性能与每个单独因素之间呈幂律关系
- 影响模型性能的三个要素之间,每个参数会受到其他两个参数影响。当没有其他两个瓶颈时,性能会急剧上升,影响程度为计算量>参数量>>数据集大小
- 在固定计算预算下,最佳性能可以通过训练参数量非常大的模型,并非在远离收敛前停止实现(early stop)
- 更大的模型在样本效率方面表现更好,能以更少的优化步骤和使用更少的数据量达到相同的性能水平。
- 实际应用中,应该优先考虑训练较大的模型
-
2022年,DeeoMind的Hoffmann团队,在Training Compute-Optimal Large Language Models(arxiv.2203.15556)提出了与OpenAI截然不同的观点
- OpenAI建议在计算预算增加10倍的情况下,如果想保持效果,模型大小应该增加5.5倍,但DeepMind认为是增加1.8倍
- DeepMind认为模型大小和训练Token的数量都应该按等比例扩展,暗示GPT3过度参数化,也就是说参数量太多了,超过了实际所需,且训练不足
- 结论:
- 对于给定的FLOP预算,损失函数有明显的谷底值:
- 模型太小时,在较少数据上训练较大模型是一种改进
- 模型太大时,在更多数据上训练较小模型时一种改进
- 也就是说,在给定计算量下,数据量和模型参数量之间平衡存在最优解
- 在计算成本达到最优情况下,模型大小和训练数据量应该等比例放缩。对于给定参数量的模型,最佳训练数据集大小约为模型参数量的20倍,比如7B模型应该是140B的tokens训练
- 大模型训练需要更加关注数据集的扩展,高质量数据集,数据越多才有用
- 对于给定的FLOP预算,损失函数有明显的谷底值:
-
总结:
- 定义:计算量、数据集规模、模型大小,来预测性能
- OpenAI:三者两两相关,当两个没有瓶颈时,性能会急剧上升,重要性计算量>参数量>>数据集大小
- DeepMind:三者应等比例扩展
大模型幻觉相关
1. 什么是大模型幻觉?
- 定义:(一本正经的胡说八道)模型生成的文本不遵循原文(一致性,Faithfulness)或者不符合事实(事实性,Factualness)
- Faithfulness:是否遵循输入的上下文
- Factualness:是否符合世界知识
- 在传统任务中,幻觉大都是指Faithfulness:
- 信息冲突(Instrinsic Hallucination):LMs在生成回复时,与输入信息产生了冲突,例如摘要问题里,abstract和document的信息不一致
- 无中生有(Extrinsic Hallucination):LMs在生成回复时,输出一些并没有体现在输入中的额外信息,比如邮箱地址、电话号码、住址,并且难以验证其真假
- 而面向LLMs,我们通常考虑的幻觉则是Factualness:
- 因为我们应用LLMs的形式是open-domain chat,而非局限于特定任务,所以数据源可以看作任意的世界知识。LLMs如果生成不在输入信息中的额外信息,但是符合事实的,也是有帮助的。
2. 发生幻觉的原因
- 从数据角度:训练数据可信度问题,重复数据问题
- 从模型角度(主要原因)
- 模型结构:如果是较弱的backbone(如RNN),可能导致严重的幻觉问题,但LLMs时代不太可能存在这一问题
- 解码算法:研究表明,如果使用不稳定性较高的采样算法(如top-p)会诱导LLMs出现严重的幻觉问题。甚至可以故意在解码算法中加入一些随机性,进一步让LLMs胡编乱造(利用该方法可以生成一些负样本)
- top-p采样(也称为核采样)是一种引入不确定性的采样算法,常用来生成更加多样化和创造性的问题,原理是模型从预测概率最高的token开始累加,当这些token的概率综合达到设定的阈值(p值)后停止,从而在这些候选token中随机选取一个词生成。可以避免仅生成概率最高的词,从而提升文本的流畅性和丰富度。
- 暴露偏差:训练和测试阶段不匹配的exposure bias问题可能导致LLMs出现幻觉,特别是生成long-form response的时候
- 训练阶段一切都是真实的文本,但生成时,模型只能按照自己之前生成的文本继续生成,蝴蝶效应。
- 参数知识:LLMs在预训练阶段记忆的错误知识,导致严重的幻觉问题
3. 如何评估大模型幻觉问题?
- 现有的传统幻觉评估指标和人类结果相关性往往较低,同时大多是task-specific的
- 主要评估方法:基于参考的评估和无参考的评估
-
方法一:基于参考的评估(reference-based)
- 通常只能评价Faithfulness,无法评价Factualness,因此通常不适用于LLMs
- 指在评估生成内容的准确性时,使用参考文本(如人类标准答案)或原始信息源作为对比
- 衡量两者的重叠程度或相似度,指标如ROUGE和BLEU
- 优点:适合一些标准化的生成任务
- 缺点:许多任务标准答案可能并非唯一,生成内容多样化,因此该方法的灵活性不足。而且LLMs开放生成任务,很难找到完美的参考答案
- 指标主要有两类:
- BLEU和ROUGE这种统计重叠度的指标(Source information + Target Reference)
- Knowledge F1(Source information only)
- Knowledge F1时一种用于评估NLG的指标,主要用于检测幻觉
- 思路:比较模型生成内容和参考知识老远之间的匹配度,判断准确性和一致性
- 计算原理:
- 知识检索:首先,从任务相关的知识库或上下文信息中提取模型生成时可参考的源知识
- 知识匹配:然后,将模型的生成输出和源知识中的信息进行比对,找出哪些时和源知识一致的
- F1得分计算:最后,通过Precision和Recall来计算F1得分
-
方法二:无参考评估
- 旨在不用标准答案或特定参考来检测模型生成内容的准确性和一致性
- 各种方法:
- 基于信息抽取(IE):将生成内容转化为结构化知识,如RDF三元组,然后用另一个模型来验证三元组的真实性
- 缺点:IE模型本身可能出错,抽取的信息不对,后续检验也就无效了;且只能受限于三元组只知识,很多知识不能用三元组表达,局限性。
- 基于问答(QA):
- 首先,使用一个问题生成模型,根据模型的生成内容来产生一系列相关的问答对
- 然后,利用源信息,使用问答模型回答这些问题
- 最后,将问答模型的答案和最初生成的答案对比,通过匹配度评估生成内容的真实性
- 缺点:IE模型的错误传播,QA过程依然依赖IE模型生成的;而且难以评估Factualness,因为QA模型回答问题时,源信息未必包含所有所需知识,可能无法准确回答或验证的情况。
- 基于自然语言推理(NLI):
- 即通过验证生成文本是否由源信息的蕴含来判断其是否存在幻觉
- 但是问题是幻觉未必和蕴含划等号
- 缺点:
- 性能有限:目前NLI模型在事实喝茶方面表现一般,难以准确验证生成内容
- 无法检测世界知识相关的幻觉:世界知识太大了,很难检测蕴含关系
- 粒度有限:局限于句子级别的蕴含检测,无法更细粒度
- 幻觉和蕴含不等价:幻觉不仅仅是不蕴含,比如Putin is president和Putin is U.S. president在语义上并非幻觉,但是会被判断为蕴含
- NLI中,蕴含意味着一个句子能够逻辑推导出另一个句子,但不涉及判断信息的真实性
- 基于事实性分类指标(Factualness Classification Metric)
- 通过人工标注或构造包含幻觉和真实信息的数据集,训练分类模型来检测新生成的文本是否符合事实。但是依赖标注,成本高昂。
- 人工评估
- 基于信息抽取(IE):将生成内容转化为结构化知识,如RDF三元组,然后用另一个模型来验证三元组的真实性
-
总结:分为基于参考的评估和**无参考的评估
4. 如何缓解LLMs幻觉问题
- 基于数据的工作:高质量数据集构造
- 人工标注:训练数据、评测数据
- 自动筛选:筛除不良数据、数据加权,如给可靠度高的数据赋予高的权重,如wikipedia,不可靠的数据赋予低的权重
- 模型层面:从模型结构和训练方式入手
- 模型结构:模型结构方面的改进主要关注在设计能够更好地利用来源信息的结构,例如
- 编码更多信息:用GNN编码这种融入能反映人类思维偏好的结构,更好地专注输入信息
- 减少生成随机性:在解码时减少模型生成内容地随机性(多样性和准确性是互相掣肘的),提高准确性(temperature)
- 检索增强:引入外部检索系统(如LLaMaIndex)
- 训练方式:
- 可控文本生成:将幻觉控制设为一个可控属性,让模型生成时更少产生幻觉
- 提前规划内容框架:采用sketch-to-content方法,先规划一个大致的框架再生成具体内容,有助于结构化信息并减少偏差
- 强化学习:通常模型使用MLE来优化训练目标,这可能会暴露偏差。通过引入强化学习,将减少幻觉的目标作为奖励函数,调整模型生成过程
- 多任务学习:设计额外任务,使模型在执行多项任务时能提升应对幻觉的能力
- 后处理:纠错模块设计
一篇相关的论文:
- A Stitch in Time Savess Nine: Detecting and Mitigating Hallucinations of LLMs by Validating Low-Confidence Generation
- arxiv.2307.03987
- 幻觉的生成是会传播的,比如一句话出现幻觉,后续可能会更加严重。(预防很重要,防患于未然)
- logit输出值可以用来获取幻觉信号。比如,计算了一个logits值,并展示了当这个得分很低时,模型更容易出现幻觉。其实就是置信度很低的解码输出时不可信的,容易出幻觉
基于上述两个发现,作者提出了主动检测和减轻幻觉的方法,如图所示:
- 首先抽取输入语句种的关键概念(实体、关键词),然后计算它们的不确定性(这个就是单纯基于生成模型解码的logits来判断的,虽然解释性一般,但是的确有用)
- 这里就是发现出生地和出生日期是很不确定的
- 然后基于这些不确定的phrase,我们去检索相关的知识(self-inquiry,上下文搜索;网络搜索,外部搜索),作为辅助的信息
- 在检测阶段,首先识别重要概念,计算模型在这些概念上的不确定性,并通过检索相关知识验证这些不确定概念的正确性
- 消除阶段,基于输入+检索得到的辅助信息,使用问题生成模型生成问答对,根据问答内容来修正这些实体,然后将修正好的句子放回去。
- 在缓解阶段,使用检测到的知识作为依据,修复存在幻觉的句子
- 即,将修复后的句子添加到输入中(和之前生成的句子一起),然后生成下一个句子
幻觉是有蝴蝶效应的,前面有幻觉,后面幻觉就会越来越大,有点像束搜索,所以要提前防控。
RAG相关
1. 什么是RAG,它有什么特点?
- RAG为生成式模型提供了与外部世界互动的解决方案
- RAG的主要作用类似搜索引擎,找到用户提问最相关的知识或对话历史,并结合原始问题(查询),创造信息丰富的prompt,指导模型生成准确输出
- 本质是利用了In-context Learning的原理
- RAG = 检索技术 + LLM提示
RAG特点:
- 依赖大语言模型来强化信息检索和输出:RAG需要结合大型语言模型(LLM)来进行信息的检索和生成,但如果单独使用RAG它的能力会受到限制。也就是说,RAG需要依赖强大的语言模型支持,才能更有效地生成和提供信息。
- 能与外部数据有效继承:能与外部数据有效集成:RAG能够很好地接入和利用外部数据库的数据资源。这一特性弥补了通用大模型在某些垂直或专业领域的知识不足,比如行业特定的术语和深度内容,能提供更精确的答案。
- 数据隐私和安全保障:通常,RAG所连接的私有数据库不会参与到大模型的数据集训练中。因此,RAG既能提升模型的输出表现,又能有效地保护这些私有数据的隐私性和安全性,不会将敏感信息暴露给大模型的训练过程。
- 表现效果因多方面因素而异:RAG的效果受多个因素的影响,比如所使用的语言模型的性能、接入数据的质量、AI算法的先进性以及检索系统的设计等。这意味着不同的RAG系统之间效果差异较大,不能一概而论。
2. RAG的总体思路
总体思路:参考https://aibook.ren/archives/what-is-rag
- RAG可分为5个基本流程:知识文档准备、嵌入模型、向量数据库、查询检索、生产回答
-
知识文档准备:
- 文档格式:WORD,TXT,CSV,EXCEL,PDF,图片,视频
- 需要使用专门的文档加载器(如PDF提取)或多模态模型(如OCR技术),将丰富的知识源转换为LLMs可理解的纯文本数据
- 文档切片:针对长文档,需要切割,以便更高效地
-
嵌入模型:text-to-tensor,稀疏离散的文本转为密集精确的张量表征,捕捉上下文的关系和核心含义
-
向量数据库:嵌入模型生成的张量存储到数据库
-
Chroma:
- 轻量级、易用性、开源。
- 快速搭建小型语义搜索,提供高效的近似最近邻搜索(ANN),支持多种向量数据类型和索引方法,易于集成到现有的应用程序中。
- 小型语义搜索原型、研究或教学项目。
- 适合初学者和小型项目
-
Pinecone:
- 实时性、高性能、可扩展。
- 大规模数据集上的实时搜索,亚秒级的查询响应时间,支持大规模向量集的高效索引和检索,提供高度可伸缩的分布式架构。
- 实时推荐系统、大规模电商搜索引擎、社交媒体内容过滤。
- 适合需要高性能和实时性的大型应用
-
Weaviate:
- 语义搜索、图数据库、多模态。
- 构建智能助手、知识图谱,支持多模态数据(文本、图像等)的语义搜索,提供强大的查询语言和推理能力。
- 复杂知识图谱应用、智能问答系统、多模态内容管理平台。
- 适合需要复杂查询和推理能力的知识密集型应用
-
Milvus:
- 大规模数据、云原生、高可用性。
- 专为处理超大规模向量数据而设计,提供云原生的分布式架构和存储方案,支持多种索引类型和查询优化策略。
- 大规模内容检索平台、图像和视频搜索、智能安防系统。
- 适合需要处理超大规模数据的云端应用
-
Faiss:
- 高效性、灵活性、Facebook支持。
- 提供高效的相似度搜索和稠密向量聚类能力,支持多种索引构建方法和查询优化策略,易于与深度学习框架集成(如PyTorch)。
- Facebook内部语义搜索和推荐系统、广告技术平台、深度学习应用中的向量检索模块。
- 适合需要高效相似度搜索和丰富社区支持的大型应用
-
-
查询检索:用户问题会被输入到嵌入模型中进行向量化处理,然后系统在向量数据库中搜索与该问题语义相似的知识文本或历史对话记录返回。
-
生产回答:最终用户提问会和检索得到的信息结合,构建一个提示模板,输入到LLMs中,生成回答。
3. 如何评价RAG项目效果的好坏
-
针对检索环节的评估:
-
MRR(平均倒数排名),查询(或推荐请求)的排名倒数
- MEAN Reciprocal Rank,MRR,多用于衡量搜索引擎、推荐系统等根据查询返回的多个结果的相关性
- M R R = 1 n ∑ i = 1 n 1 r i MRR=\frac1n\sum_{i=1}^n \frac1{r_i} MRR=n1∑i=1nri1
-
Hits Rate(命中率):前k项中,包含正确信息的检索项数目占比
-
NDCG(归一化折扣累计增益):DCG的两个思想
- 高关联度的结果比一般关联度的结果更影响最终的指标得分
- 有高关联度的而己过出现在更靠前的位置时,指标会越高
参考:排序算法评估:NDCG(归一化折扣累计增益Normalized Discounted Cumulative Gain)
-
-
针对生成环节的评估
-
非量化:完整性、正确性、相关性
-
量化:Rouge-L指标
-
Rouge-L是一种用于评价文本生成质量的指标,通常在自动病要、机器翻译和文本生成任务中使用。它是Rouge(Recall-Oriented Understudy for Gisting Evaluation)评估指标系列中的一种,专门通过**最长公共子序列(Longest Common Subsequence,LCS)**来测量生成文本和参考文本之间的相似性。
-
基本思想大由多个专家分别生成人工摘要,构成标准搞要集,将系统生成的自动摘要与人工生成的标准摘要相对比,通过统计二者之间重叠的基本单元(n-gram、词序列和词对)的数目,来评价摘要的质量。
-
Rouge-L的计算主要包括两个方面:
-
Recall:参考文本中与生成文本匹配的最长公共子序列的长度,与参考文本的总长度之比
-
Precision:生成文本中与参考文本匹配的最长公共子序列的长度,与生成文本的总长度之比
-
然后用这个PR值计算F1,即:
R o u g e − L = 2 P R P + R Rouge-L = \frac{2PR}{P+R} Rouge−L=P+R2PR
-
-
Rouge-L比Rouge-1或Rouge-2更能衡量文本生成的结构和顺序是否与参考文本接近,因此在长文段的连贯性和句子顺序检测上具有优势。
-
-
4. RAG的优化策略(重要)
4.1 知识文档准备阶段(数据清洗、分块处理)
-
数据清洗
-
RAG依赖准确和清洁的原始知识
-
表格结构会在单纯的文本转换后丢失原有结构,因此需要引入额外机制来保持表格结构(如使用分号或其他符号来区分数据)
-
其他数据清洗操作:
- 基本文本清理:规范格式、去除特殊字符、不相关信息、重复文档、冗余信息
- 实体解析:消歧,如将LLMs,大语言模型,大模型类似的标准化为通用术语
- 文档划分:按主题划分,不同主题的文档集中或分散?人类都不能判段用哪些文档来回答提问,检索系统也不能
- 数据增强:同义词、释义、其他语言的翻译来增加语料库的多样性
- RLHF:基于现实世界用户的反馈不断更新数据库,标记真实性
- 时间敏感数据:对于经常更新的主题,删除过期文档
-
-
分块处理:Chunk
-
在RAG系统中,文档需要分割成多个文本块再进行向量嵌入。
-
在不考虑大模型输入长度限制和成本问题情况下,其目的是在保持语义上的连贯性的同时,尽可能减少嵌入内容中的噪声,从而更有效地找到与用户查询最相关的文档部分
-
如果分块太大,可能包含太多不相关的信息,从而降低了检索的准确性。相反,分块太小可能会丢失必要的上下文信息,导致生成的回应缺乏连贯性或深度。
-
在RAG系统中实施合适的文档分块策略,旨在找到这种平衡,确保信息的完整性和相关性。一般来说,理想的文本块应当在没有周围上下文的情况下对人类来说仍然有意义,这样对语言模型来说也是有意义的。
-
分块方法的选择:
- 固定大小的分块:这是最简单和直接的方法,我们直接设定块中的字数,并选择块之间是否重复内容
- 通常,我们会保持块之间的一些重叠,以确保语义上下文不会在块之间丢失。与其他形式的分块相比,固定大小分块简单易用且不需要很多计算资源。
-
内容分块
- 顾名思义,根据文档的具体内容进行分块,例如根据标点符号(如句号)分割。或者直接使用更高级的NLTK或者spaCy库提供的句子分割功能。
-
递归分块
- 在大多数情况下推荐的方法。
- 其通过重复地应用分块规则来递归地分解文本
- 例如,在langchain中会先通过段落换行符(\n\n)进行分割。然后,检查这些块的大小。如果大小不超过一定阈值,则该块被保留。对于大小超过标准的块,使用单换行符(\n)再次分割。以此类推,不断根据块大小更新更小的分块规则(如空格,句号)。这种方法可以灵活地调整块的大小。例如,对于文本中的密集信息部分,可能需要更细的分割来捕捉细节;而对于信息较少的部分,则可以使用更大的块。而它的挑战在于,需要制定精细的规则来决定何时和如何分割文本。
-
从小到大分块
- 既然小的分块和大的分块各有各的优势,一种更为直接的解决方案是把同一文档进行从大到小所有尺寸的分割,然后把不同大小的分块全部存进向量数据库,并保存每个分块的上下级关系,进行递归搜索。但可想而知,因为我们要存储大量重复的内容,这种方案的缺点就是需要更大的储存空间。
-
特殊结构分块
- 针对特定结构化内容的专门分割器。这些分割器特别设计来处理这些类型的文档,以确保正确地保留和理解其结构。
- langchain提供的特殊分割器包括:Markdown文件,Latex文件,以及各种主流代码语言分割器。
-
分块大小的选择
- 上述方法中无一例外最终都需要设定一个参数——一块的大小,那么我们如何选择呢?
- 首先不同的嵌入模型有其最佳输入大小。比如Openai的text-embedding-ada-002的模型在256或512大小的块上效果更好。
- 其次,文档的类型和用户查询的长度及复杂性也是决定分块大小的重要因素。处理长篇文章或书籍时,较大的分块有助于保留更多的上下文和主题连贯性;而对于社交媒体帖子,较小的分块可能更适合捕捉每个帖子的精确语义。如果用户的查询通常是简短和具体的,较小的分块可能更为合适;相反,如果查询较为复杂,可能需要更大的分块。
- 实际场景中,我们可能还是需要不断实验调整,在一些测试中,128大小的分块往往是最佳选择,在无从下手时,可以从这个大小作为起点进行测试。
-
4.2 嵌入模型阶段
- 我们提到过嵌入模型能帮助我们把文本转换成向量,显然不同的嵌入模型带来的效果也不尽相同,例如,Word2Vec模型,尽管功能强大,但存在一个重要的局限性:其生成的词向量是静态的。一旦模型训练完成,每个词的向量表示就固定不变,这在处理一词多义的情况时可能导致问题。
- 语义完全不一样的词向量却是固定的。相比之下,引入自注意力机制的模型,如BERT,能够提供动态的词义理解。这意味着它可以根据上下文动态地调整词义,使得同一个词在不同语境下有不同的向量表示。
- 有些项目为了让模型对特定垂直领域的词汇有更好的理解,会嵌入模型进行微调。但在这里我们并不推荐这种方法,一方面其对训练数据的质量有较高要求,另一方面也需要较多的人力物力投入,且效果未必理想,最终得不偿失。
- 在这种情况下,对于具体应该如何选择嵌入模型,推荐参考HuggingFace推出的嵌入模型排行榜MTEB(https://huggingface.co/spaces/mteb/leaderboard)。这个排行榜提供了多种模型的性能比较,能帮助我们做出更明智的选择。同时,要注意并非所有嵌入模型都支持中文,因此在选择时应查阅模型说明。
- 目前SOTA表现是北大和腾讯团队开源的Conan embedding
- C-MTEB(Chinese Massive Text Embedding Benchmark):中文海量文本嵌入测试基准
4.3 向量数据库阶段(元数据)
- 当在向量数据库中存储向量数据时,某些数据库支持将向量与元数据(即非向量化的数据)一同存储、为向量添加元数据标注是一种提高检索效率的有效策略,它在处理搜索结果时发挥着重要作用。
- 例如,日期就是一种常见的元数据标签。它能够帮助我们根据时间顺序进行筛选。设想一下,如果我们正在开发一款允许用户查询他们电子邮件历史记录的应用程序。在这种情况下,日期最近的电子邮件可能与用户的查询更相关。然而,从嵌入的角度来看,我们无法直接判断这些邮件与用户查询的相似度。通过将每封电子邮件的日期作为元数据附加到其嵌入中,我们可以在检索过程中优先考虑最近日期的邮件,从而提高搜索结果的相关性。
- 此外,我们还可以添加诸如章节或小节的引用,文本的关键信息、小节标题或关键词等作为元数据。这些元数据不仅有助于改进知识检索的准确性,还能为最终用户提供更加丰富和精确的搜索体验。
4.4 查询索引阶段(检索找回、重排)
-
多级索引:
- 元数据无法充分区分不同上下文类型的情况下,我们可以考虑进一步尝试多重索引技术
- 多重索引技术的核心思想是将庞大的数据和信息需求按类别划分,并在不同层级中组织,以实现更有效的管理和检索。
- 这意味着系统不仅依赖于单一索引,而是建立了多个针对不同数据类型和查询需求的索引。
- 例如,可能有一个索引专门处理摘要类问题,另一个专门应对直接寻求具体答案的问题,还有一个专门针对需要考虑时间因素的问题。这种多重索引策略使RAG系统能够根据查询的性质和上下文,选择最合适的索引进行数据检索,从而提升检索质量和响应速度。
- 不过为了引入多重索引技术,我们还需配套加入多级路由机制。多级路由机制确保每个查询被高效引导至最合适的索引。查询根据其特点(如复杂性、所需信息类型等)被路由至一个或多个特定索引。这不仅提升了处理效率,还优化了资源分配和使用,确保了对各类查询的精确匹配。
- 例如,对干查询最新上映的科幻电影推荐,RAG系统可能首先将其路由至专门处理当前热点话题的索引,然后利用专注于娱乐和影视内容的索引来生成相关推荐。
- 总的来说,多级索引和路由技术可以进一步帮助我们对大规模数据进行高效处理和精准信息提取,从而提升用户体验和系统的整体性能。
-
索引或查询算法:
- 我们可以利用索引筛选数据,但说到底我们还是要从筛选后的数据中检索出相关的文本向量。
- 由于向量数据量庞大且复杂,寻找绝对的最优解变得计算成本极高,有时甚至是不可行的。加之,大模型本质上并不是完全确定性的系统,这些模型在搜索时追求的是语义上的相似性——一种合理的匹配即可。从应用的角度来看,这种方法是合理的。
- 例如,在推荐系统中,用户不太可能察觉到或关心是否每个推荐的项目都是绝对的最佳匹配
- 他们更关心的是推荐是否总体上与他们的兴趣相符
- 因此查找与查询向量完全相同的项通常不是目标,而是要找到足够接近或相似的项,这便是最近邻搜索(ApproximateNearest Neighbor Search,ANNS)。这样做不仅能满足需求,还为检索优化提供了巨大的优化潜力。
- 常用算法:
- 聚类:参数选择(如簇数)
- 位置敏感哈希:
- 沿着缩小搜索范围的思路(束搜索)
- 在传统哈希算法中,我们通常希望每个输入对应唯一输出,并努力减少输出的重复
- 然而,在位置敏感哈希中,目标恰恰相反,我们需要增加输出值碰撞的概率
- 这种碰撞正是分组的关键,哈希值相同的向量进入同一个组(桶),此外,哈希函数还需满足一个条件:空间上距离相近的向量更有可能分入同一个桶,这样在搜索时,只要获取目标向量的哈希值,找到相应的桶进行搜神记即可。
- 量化乘积:
- 上面我们介绍了两种牺牲搜索质量来提高搜索速度的方法,但除了搜索速度外,内存开销也是一个巨大挑战。
- 在实际应用场景中,每个向量往往都有上千个维度,数据数量可达上亿。每条数据都对应着一个实际的的信息,因此不可能删除数据来减少内存开销,那唯一的选择只能是把每个数据本身大小缩减。
- 图像有一种有损压缩的方法是把一个像素周围的几个像素合并(Superpixel),来减少需要储存的信息。同样我们可以在聚类的方法之上改进一下,用每个簇的中心点来代替簇中的数据点。虽然这样我们会丢失向量的具体值信息,但考虑到聚类中心点和簇中向量相关程度,再加上可以不断增加簇的数量来减少信息损失,所以很大程度上我们可以保留原始点的信息。而这样做带来的好处是十分可观的。
- 如果我们给这些中心点编码,我们就可以用单个数字储存一个向量来减少存储的空间。而我们把每个中心向量值和他的编码值记录下来形成一个码本,这样每次使用某个向量的时候,我们只需用他的编码值通过码本找到对应的的中心向量的具体值
- 虽然这个向量已经不再是当初的样子了,但就像上面所说,问题不大。而这个把向量用其所在的簇中心点表示的过程就是量化。
- 分层导航小世界:
- 从客户的角度来看,内存开销可能并不是最重要的考量因素。他们更加关注的是应用的最终效果,也就是回答用户问题的速度和质量。
- 导航小世界(Navigable Small World,NSW)算法正是这样一种用内存换取更快速度和更高质量的实现方式
- 这个算法的思路和六度分割理论类似——你和任何一个陌生人之间最多只隔六个人,也就是说,最多通过六个人你就能够认识任何一个陌生人。
- 我们可以将人比作向量点,把搜索过程看作是从一个人找到另一个人的过程。在查询时,我们从一个选定的起始点A开始,然后找到与A相邻且最接近查询向量的点B,导航到B点,再次进行类似的判断,如此反复,直到找到一个点C,其所有相邻节点都没有比它更接近目标。最终这个点C便是我们要找的最相似的向量。
-
查询转换:
-
在RAG系统中,用户的查询问题被转化为向量,然后在向量数据库中进行匹配。不难想象,查询的措辞会直接影响投索结果。
-
如果搜索结果不理想,可以尝试以下几种方法对问题进行重写,以提升召回效果:
-
a. 结合历史对话的重新表述
- 在向量空间中,对人类来说看似相同的两个问题其向量大小并不一定很相似。我们可以直接利用LLM 重新表述问题来进行尝试。
- 此外,在进行多轮对话时,用户的提问中的某个词可能会指代上文中的部分信息,因此可以将历史信息和用户提问一并交给LLM重新表述。
-
b. 假设文档嵌入
- 假设文档嵌入(Hypothetical DocumentEmbedding,HyDE)的核心思想是:
- 接收用户提问后,先让LLM在没有外部知识的情况下生成一个假设性的回复。
- 然后,将这个假设性回复和原始查询一起用于向量检索。
- 假设回复可能包含虚假信息,但蕴含着LLM认为相关的信息和文档模式,有助于在知识库中寻找类似的文档。
- 主要关注点:通过为传入查询生成一个假想文档,从而增强和改善相似性搜索。
- 假设文档嵌入(Hypothetical DocumentEmbedding,HyDE)的核心思想是:
-
c. 退后提示
- 如果原始查询太复杂或返回的信息太广泛,可以选择生成一个抽象层次更高的“退后“问题,与原始问题一起用于检索,以增加返回结果的数量。这就是退后提示(Step BackPrompting)的思想。
- 例如,原问题是张三 在 1954年8月至 1954年 11月期间去了哪所学校?,这类问题对于 LLM 来说很容易答错。但是如果后退一步,站在更高层次对问题进行抽象,提出一个新的问题:**张三的教育历史是怎样的?**那LLMs可以先将张三都列出来,然后将这些信息和原始问题放在一起,那么对于 LLM 来说就可以很容易给出正确的答案。
-
d.多查询检索/多路召回
- 多查询检索/多路召回(Multi-Query Retrieval)也是一种不错的方法。
- 使用LLM生成多个搜索查询,特别适用于一个问题可能需要依赖多个子问题的情况。
-
-
-
检索参数:
-
终于我们把查询问题准备好了,可以进入向量数据库进行检索。在具体的检索过程中,我们可以根据向量数据库的特定设置来优化一些检索参数,以下是一些常见的可设定参数:
-
稀疏和稠密搜索权重
-
稠密搜索即通过向量进行搜索。然而,在某些场景下可能存在限制,此时可以尝试使用原始字符串进行关键字匹配的稀疏搜索。
-
一种有效的稀疏搜索算法是最佳匹配25(BM25),它基于统计输入短语中的单词频率,频繁出现的单词得分较低,而稀有的词被视为关键词,得分会较高。我们可以结合稀疏和稠密搜索得出最终结果。
-
向量数据库通常允许设定两者对最终结果评分的权重比例,如langchain的某个参数,0.6表示40%的得分来自稀疏搜索,60%来自稠密搜索。
-
-
结果数量(topk)
-
检索结果的数量是另一个关键因素。
-
足够的检索结果可以确保系统覆盖到用户查询的各个方面。在回答多方面或复杂问题时,更多的结果提供了丰富的语境,有助于RAG系统更好地理解问题的上下文和隐含细节,
-
但需注意,结果数量过多可能导致信息过载,降低回答准确性并增加系统的时间和资源成本
-
-
相似度度量方法
- 计算两个向量相似度的方法也是一个可选参数。这包括使用欧式距离或Jaccard距离计算两个向量的差异,以及利用余弦相似度衡量夹角的相似性。
- 通常,余弦相似度更受青睐,因为它不受向量长度的影响,只反映方向上的相似度。这使得模型能够忽略文本长度差异,专注于内容的语义相似性。
- 需要注意的是,并非所有嵌入模型都支持所有度量方法,具体可参考所用嵌入模型的说明。
-
-
高级检索策略:
-
终于我们来到最为关键和复杂的步骤——在向量数据库检索之上如何具体开发或改进整个系统的策略,这部分的内容足够写成一篇独立文章。为了保持简洁,我们只讨论一些常用或者新提出的策略。
-
a. 上下文压缩:
-
我们提到过当文档文块过大时,可能包含太多不相关的信息,传递这样的整个文档可能导致更昂贵的LLM调用和更差的响应。
-
上下文压缩的思想就是通过LLM的帮助根据上下文对单个文档内容进行压缩,或者对返回结果进行一定程度的过滤仅返回相关信息。
-
b. 句子窗口搜索
-
相反,文档文块太小会导致上下文的缺失。
-
其中一种解决方案就是窗口搜索,该方法的核心思想是当提问匹配好分块后,将该分块周围的块作为上下文一并交给LLM进行输出。来增加LLM对文档上下文的理解
-
c. 父文档搜索
- 无独有偶,父文档搜索也是一种很相似的解决方案,父文档搜索先将文档分为尺寸更大的主文档,再把主文档分割为更短的子文档两个层级,用户问题会与子文档匹配,然后将该子文档所属的主文档和用户提问发送给LLMs。
-
d. 自动合并
- 自动合并是在父文档搜索上更进一步的复杂解决方案。
-
同样地,我们先对文档进行结构切割,比如将文档按三层树状结构进行切割,顶层节点的块大小为1024,中间层的块大小为512,底层的叶子节点的块大小为128。
-
而在检索时只拿叶子节点和问题进行匹配,当某个父节点下的多数叶子节点都与问题匹配上则将该父节点作为结果返回。
-
e. 多向量检索
-
多向量检索同样会给一个知识文档转化成多个向量存入数据库,不同的是,这些向量不仅包括文档在不同大小下的分块,还可以包括该文档的摘要,用户可能提出的问题等,有助于检索的信息。
-
在使用多向量查询的情况下,每个向量可能代表了文档的不同方面,使得系统能够更全面地考虑文档内容,并在回答复杂或多方面的查询时提供更精确的结果。
-
例如,如果查询与文档的某个具体部分或摘要更相关,那么相应的向量就可以帮助提高这部分内容的检索排名。
-
-
f. 多代理检索
-
多代理检索,简而言之就是选取我们提及的12大优化策略中的部分交给一个智能代理合并使用。
- 就比如使用子问题查询,多级索引和多向量查询结合,
-
先让子问题查询代理把用户提问拆解为多个小问题,再让文档代理对每个字问题进行多向量或多索引检索,最后排名代理将所有检索的文档总结再交给LLM。
-
这样做的好处是可以取长补短。比如,子问题查询引擎在探索每个子查询时可能会缺乏深度,尤其是在相互关联或关系数据中。相反,文档代理递归检索在深入研究特定文档和检索详细答案方面表现出色,以此来综合多种方法解决问题。
-
需要注意的是现在网络上存在不同结构的多代理检索,具体在多代理选取哪些优化步骤尚未有确切定论,我们可以结合使用场景进行探索。
-
-
g. Self-RAG(左右互搏)
-
自反思搜索增强是一个新的RAG框架,其与传统RAG最大的区别在于通过检索评分(令牌)和反思评分(令牌)来提高质量。
-
它主要分为三个步骤:检索、生成和批评。
-
SeIf-RAG首先用检索评分来评估用户提问是否需要检索,如果需要检索,LLM将调用外部检索模块查找相关文档。
- 接着,LLM分别为每个检索到的知识块生成答案,
- 然后为每个答案生成反思评分来评估检索到的文档是否相关,
-
最后将评分高的文档当作最终结果一并交给LLM。
-
-
-
重排模型:
-
在完成语义搜索的优化步骤后,我们能够检索到语义上最相似的文档,但不知你是否注意到一个关键问题:语义最相似是否总代表最相关?答案是不一定。
- 例如,当用户查询最新上映的科幻电影推荐时,可能得到的结果是科幻电影的历史演变,虽然从语义上这与科幻电影相关,但并未直接回应用户关于最新电影的查询。
-
重排(Re-ranking)模型可以帮助我们缓解这个问题,重排模型通过对初始检索结果进行更深入的相关性评估和排序,确保最终展示给用户的结果更加符合其查询意图。
-
该过程会考虑更多的特征,如查询意图、词汇的多重语义、用户的历史行为和上下文信息等。
- 举个例子,对于查询最新上映的科幻电影推荐,在首次检索阶段,系统可能基于关键词返回包括科幻电影的历史文章、科幻小说介绍、最新电影的新闻等结果。
- 然后,在重排阶段,模型会对这些结果进行深入分析,并将最相关、最符合用户查询意图的结果(如最新上映的科幻电影列表的评论或推荐)排在前面,同时将那些关于科幻电影历史或不太相关的内容排在后面。
- 这样,重排模型就能有效提升检索结果的相关性和准确性,更好地满足用户的需求。
-
在实践中,使用RAG构建系统时都应考虑尝试重排方法,以评估其是否能够提高系统性能。
-
4.5 生成回答阶段(提示工程)
-
提示词:
-
LLMs的解码器部分通常基于给定输入来预测下一个词。
-
这意味着设计提示词或问题的方式将直接影响模型预测下一个词的概率。这也给了我们一些启示:通过改变提示词的形式,可以有效地影响模型对不同类型问题的接受程度和回答方式,比如修改提示语,让LLM知道它在做什么工作,是十分有帮助的。
-
为了减少模型产生主观回答和幻觉的概率,一般情况下,RAG系统中的提示词中应明确指出回答仅基于搜索结果,不要添加任何其他信息。例如,可以设置提示词如:
你是一名智能客服。你的目标是提供准确的信息,并尽可能帮助提问者解决问题。你应保持友善,但不要过于啰嗦。请根据提供的上下文信息,在不考虑已有知识的情况下,回答相关查询。
-
当然你也可以根据场景需要,也可以适当让模型的回答融入一些主观性或其对知识的理解。
-
此外,使用少量样本(few-shot)的方法,将想要的问答例子加入提示词中,指导LLM如何利用检索到的知识,也是提升LLM生成内容质量的有效方法。这种方法不仅使模型的回答更加精准,也提高了其在特定情境下的实用性。
-
-
大语言模型:
- LLM是生成响应的核心组件。与嵌入模型类似,可以根据自己的需求选择LLM,例如开放模型与专有模型、推理成本、上下文长度等。
- 此外,可以使用一些LLM开发框架来搭建RAG系统,比如,Llamalndex或LangChain。这两个框架都拥有比较好用的debugging工具,可以让我们定义回调函数,查看使用了哪些上下文,检查检索结果来自哪个人档等等。
知识蒸馏相关
1. 什么是知识蒸馏
-
把大的教师模型的知识萃取出来,浓缩到一个小的学生模型中,就是大模型转为小模型
-
这里有一个知识迁移的过程,从教师网络迁移到学生网络上
2. 知识蒸馏的目的
深度学习在计算机视觉、语音识别、自然语言处理等内的众多领域中均取得了令人难以置信的性能。但是,大多数模型在计算上过于昂贵,无法在移动端或嵌入式设备上运行。因此需要对模型进行压缩,这样小的模型就适用于部署在终端设备上了,
- 提升模型精度:如果对目前的网络模型A的精度不是很满意,那么可以先训练一个更高精度的teacher模型B(通常参数量更多,时延更大),然后用这个训练好的teacher模型B对student模型A进行知识蒸馏,得到一个更高精度的A模型。
- 降低模型时延,压缩网络参数:如果对目前的网络模型A的时延不满意,可以先找到一个时延更低,参数量更小的模型B。通常来讲,这种模型精度也会比较低,然后通过训练一个更高精度的teacher模型C来对这个参数量小的模型B进行知识蒸馏,使得该模型B的精度接近最原始的模型A、从而达到降低时延的目的。
- 标签之间的域迁移:假如使用狗和猫的数据集训练了一个teacher模型A,使用香蕉和苹果训练了一个teacher模型B、那么就可以用这两个模型同时蒸馏出-个可以识别狗、猫、香蕉以及苹果的模型,将两个不同域的数据集进行集成和过移。
3. 传统的知识蒸馏方法
根据蒸馏知识的不同,主要有两种类型:
- 基于反馈的知识蒸馏
- 基于特征的知识蒸馏
- 参考资料《大语言模型》赵鑫等著
-
基于反馈的知识蒸馏:
- 关注教师模型最后一层输出的logits,这些logits经过softmax变换后,可以用作学生模型的软标签进行学习
- 蒸馏损失函数为:
L
(
l
t
,
l
s
)
=
L
R
(
p
t
(
⋅
)
,
p
s
(
⋅
)
)
\mathcal{L}(l_t,l_s)=L_R(p_t(\cdot),p_s(\cdot))
L(lt,ls)=LR(pt(⋅),ps(⋅)),其中:
- l t l_t lt和 l s l_s ls分别表示教师模型和学生模型的输出logits
- L R L_R LR通常采用KL散度作为指标
- p t p_t pt和 p s p_s ps分别表示教师模型和学生模型的logits经过softmax变换后的概率值
- 核心就是让学生模型输出的logits去逼近教师模型输出的logits
-
基于特征的知识蒸馏:
- 与基于预测分布的蒸馏相比,基于中间特征表示的蒸馏关注教师模型中间层输出的激活值,并用这些激活值作为监督信息训练学生模型
- 例如在多层Transformer架构的模型中,每一层的输出特征都可以作为知识
- 相应的蒸馏损失就是: L ( f t ( x ) , f s ( x ) ) = L F ( Φ ( f t ( x ) ) , Φ ( f s ( x ) ) ) \mathcal{L}(f_t(x),f_s(x))=L_F(\Phi(f_t(x)),\Phi(f_s(x))) L(ft(x),fs(x))=LF(Φ(ft(x)),Φ(fs(x))),这里的 Φ \Phi Φ函数哟关于处理形状不匹配的情况的变换函数。
- 显然中间层特征包含更为丰富的信息,有助于模型蒸馏过程中实现更为有效的知识迁移
- 然而,这种方法也存在技术难点,如消除架构不一致的影响(两个模型架构不同),选哪些层的输出作为参考(目标层自动化选择)
4. 大语言模型的知识蒸馏方法
- 白盒模型蒸馏方法(开源),黑盒模型蒸馏方法(闭源)
- 白盒:可以获取模型权重来指导学生模型,典型方法为MINILLM,最大可将LLaMA的13B蒸馏到7B
- 黑盒:无法获取模型权重,只能使用输出信息来训练小模型。经典的方法主要是关注大模型的关键能力,如上下文学习能力,思维链推理能力,指令遵从能力
一篇综述:A Survey on Knowledge Distillation of Large Language Models(arxiv.2402.13116)
- Knowledge Elicitation(知识提取):标签、扩展、数据治疗,特征挖掘,反馈,自蒸馏(自己监督自己,学生教师合二为一)
- 蒸馏算法(右侧):SFT,缩小差异性,增加相似性,强化学习,排序优化
5. 谈谈对模型量化的了解
- 量化(quantize)是一种优化深度学习模型的技术
- 其目标是减小模型的存储需求和计算复杂度,从而使模型在资源有限的设备上运行更高效
量化的主要方式:
- 使用更小的数据类型:fp32到bf16,int8
- 使用压缩算法:
- 利用Huffmann编码或其他压缩算法:Huffmann编码是一种基于贪心算法的无损数据压缩技术,用于最优地表示符号(字符)或数据流。它通过为频率较高地符号分配更短地编码,为频率较低地符号分配较长的编码,实现数据压缩
量化的优势:减少存储空间,内存占用,加快推理速度
量化的缺点:精度损失,权衡效率与精度
6. 模型压缩和加速的方法有哪些
可以有以下方法作为参考:
-
知识蒸馏(Knowledge Distillation)
- 原理:使用一个大模型(教师模型)的输出结果,指导小模型(学生型)的训练。
- 目标:保留大模型的知识,同时显著降低模型的复杂度和大小。
- 优点:提高小模型的泛化能力和推理速度。
-
参数剪枝(Parameter Pruning)
- 原理:通过分析模型中各参数对性能的贡献,删除那些兄余或贡献较小的参数,减小模型大小。
- 优势:有效减少存储需求,适合模型过大且训练过拟合的情况。
- 实现:例如,删除绝对值较小的权重。
-
网络剪枝(Network Pruning)
- 原理:通过分析神经网络结构,删除冗余或不重要的神经元。
- 区别:与参数剪枝不同,它针对神经元而非单个参数。
- 效果:进一步压缩模型,同时保持性能。
-
蒸馏对抗网络(Distillation Adversarial Networks)4.
- 原理:结合知识蒸馏和对抗训练,通过生成扰动样本,提高模型的鲁棒性和抗干扰能力
- 适用性:对需要高可靠性和稳定性的场景效果显著
-
层次化剪枝(Layer-wise Pruning)
- 原理:根据每一层对整体性能的影响,针对不同层设置不同程度的剪枝策略。
- 优势:避免对关键层的过度剪枝,提升剪枝效率
-
低秩分解(Low-Rank decomposition):
- 原理:将较大的矩阵分解为几个小矩阵的乘积,减少参数量和计算开销
- 典型应用:矩阵分解在全连接层和卷积层尤为常用
-
卷积分解:
- 原理:将复杂的卷积操作分解为简单的计算模块,如深度可分离卷积。
- 优势:大幅提升模型推理速度,适合实时任务
这些方法各有侧重,可结合实际需求选择合适的技术,比如边缘设备倾向量化和剪枝,大规模服务场景适合低秩分解和知识蒸馏
微调相关
从总体上看,大模型的训练可以分为四个关键阶段:预训练、有监督微调、奖励建模和强化学习。
- 训练的四个关键阶段:
- 预训练:这是整个训练过程的核心和最耗时的部分,占据了99%的资源。需要大规模的计算能力(如超级计算机或大型GPU集群)和海量数据(例如文本语料库)。预训练的目的是让模型学习语言的基本规则、语义和上下文关系。由于资源需求巨大,普通开发者难以独立完成这一步。
- 有监督微调:基于预训练模型,通过提供带标签的数据(例如问题和正确答案),让模型学会执行具体任务。
- 奖励建模:创建一个模型(奖励模型)来评估生成结果的质量,并指导主模型朝更优质的方向优化。
- 强化学习:通常采用强化学习(如人类反馈的强化学习,RLHF)。通过奖励信号进一步优化模型,使其更贴近用户需求。
2.资源需求对比:
- 预训练:极高的硬件和计算成本,以及长时间的运行。
- 微调阶段(有监督微调、奖励建模、强化学习):相对轻量,仅需几块GPU和较短的时间(几小时到几天)。
3.微调的核心目标:微调是为了在预训练模型的基础上,针对特定任务(如写文章、回答问题)进一步优化模型性能。通过调整模型的参数,可以让它更加准确地完成具体任务。
1. 什么时候需要对大模型进行微调
微调(Fine-tuning)的需求主要取决于两个方面:模型现有表现是否达标 和 任务的具体需求。具体来说,当以下场景出现时,可以考虑对大型语言模型(LLM)进行微调:
-
任务复杂度高,情境学习效果不足
- **情境学习(in-context Learning)**是通过在提示中加入任务示例,让模型更好理解任务需求。虽然这种方法灵活且不需.要更新模型权重,但有时模型对复杂任务的理解力不足,
- 对较小规模的模型,这种方法的效果有限
- 如果单靠调整提示不能显著提升性能,就需要进一步优化模型。.
-
零样本或少样本推理效果欠佳
- 零样本推理(Zero-shot Inference):模型仅根据问题上下文和提示进行推理,不依赖任何示例。虽然适合通用任务,但对于专业任务,模型可能难以理解语境或任务逻辑。
- 少样本推理(Few·shotInference):在提示中加入一到多个示例,帮助模型更精准地生成期望的输出。如果这种方式仍然无法满足准确性或一致性需求,微调成为更有效的选择。
-
领域或任务需求高度专业化
- 预训练的大型语言模型(LLM)设计通用,覆盖广泛领域。但在以下情况下,模型可能需要微调以提升特定任务表现:
- 涉及专业术语、领域知识(如法律、医学、工程)。
- 需要模型对高度特定的输出格式或逻辑规则保持一致性。
- 某些任务需要高精度、低错误率,例如客户服务、医学诊断、自动化文档处理。
- 预训练的大型语言模型(LLM)设计通用,覆盖广泛领域。但在以下情况下,模型可能需要微调以提升特定任务表现:
-
输出结果不符合用户需求
- 即使通用模型输出具有一定准确性,但在用户偏好或特定任务中可能不够符合要求。例如:
- 输出风格、语气不匹配,
- 需要更个性化或品牌化的结果。
- 即使通用模型输出具有一定准确性,但在用户偏好或特定任务中可能不够符合要求。例如:
-
总结:当情境学习和零样本、单样本或少样本推理不能满足需求,或者需要在特定任务和领域中提升模型表现时,微调是有效策路。通过有监督学习过程,微调能显著提高模型在特定任务上的准确性和可靠性。
2. LLMs中微调方法有哪些
微调技术可以分为全量微调(FFT)和PEFT(参数高效微调)
下表展示了在一张A100 GPU(80G显存)以及CPU内存64GB以上硬件上进行模型全量微调以及PEFT对于CPU和GPU的消耗情况
- 全量微调会损失多样性,存在灾难性遗忘问题
- 微调策略方面,有SFT(监督微调)和**RLHF(人类反馈强化学习)**两种
- SFT的主要技术:
- 基本超参数调整
- 迁移学习
- 多任务学习
- 少样本学习
- 任务特定微调
- RLHF主要技术:
- 奖励建模
- 邻近策略优化(PPO):在确保策略更新平稳的情况下优化模型行为
- 比较排名:通过人类评估不同输出的优劣,来优化模型
- 偏好学习:从人类偏好中学习,优化输出
- 参数高效微调:最小化训练参数数量,提高特定任务性能
- SFT的主要技术:
3. 主流PEFT的方法有哪些
主要是Adapter,Prefix Tuning和LoRA三大类。各具特点,在模型结构中所嵌入的位置也有所不同
图来自论文:TOWARDS A UNIFED VIEW OF PARAMETER-EFFICIENT TRANSFER LEARNING(arxiv.2110.04366)
- Adapter类:
- PEFT 技术通过在预训练模型的各层之间插入较小的神经网络模块,这些新增的神经模块被称为“适配器",在进行下游任务的微调时,只需对适配器参数进行训练便能实现高效微调的目标。
- 此基础上衍生出了AdapterP、Parallel等高效微调技术
- Prefix Tuning类:
- PEFT 技术通过在模型的输入或隐层添加 k k k个额外可训练的前缀标记,模型微调时只训练这些前缀参数便能实现高效微调的目标。
- 在此基础上衍生出了P-Tuning、P-Tuningv2等高效微调技术;
- LoRA类:
- PEFT 技术则通过学习小参数的低秩矩阵来近似模型权重矩阵W的参数更新,微调训练时只需优化低秩矩阵参数便能实现高效微调的目标。
- 在此基础上衍生出AdaLORA、QLORA等高效微调技术,
4. Adapters类微调
论文:Parameter-Efficient Transfer Learning for NLP,发表于2019年,当时主要是基于BERT改进(arxiv.1902.00751)
背景:
- 预训练模型参数量越来越多,在训练下游任务时进行全量微调变得昂贵且费时
- 基于此,提出Adapter Tuning,Adapter在预训练模型每层中插入用于下游任务的参数(针对每个下游任务,仅增加3.6%的参数),在微调时将模型主体冻结,仅训练特定于任务的参数,从而减少了训练时的算力开销。
Adapter Tuning 主要思想:
-
作者设计了一种新的Adapter结构,并将其嵌入Transformer的结构里面
-
针对每一个Transformer层,增加了两个Adapter结构(分别是多头注意力的投影之后和第二个feed-forward层之后)
-
在训练时,固定住原来预训练模型的参数不变,只对新增的Adapter 结构和Layer Norm 层进行微调,从而保证了训练的高效性。每当出现新的下游任务,通过添加Adapter模块来产生一个易于扩展的下游模型,从而避免全量微调与灾难性遗忘的问题。
- 适配器模块的结构及其在Transformer中的集成方式
- 左图:我们在每一层Transformer中两次插入适配器模块,分别位于多头注意力机制后的投影操作之后,以及两个前馈层之后
- 右图:适配器模块的核心是一个参数较少的瓶颈结构,相较于原始模型中的注意力和前馈层,它的参数量非常少。此外,适配器模块中还包含一个跳跃连接(skip-connection)。在适配器微调阶段,绿色部分的层会基于下游任务的数据进行训练,包括适配器模块、层归一化参数,以及最终的分类层(未在图中显示)。
具体细节:
-
每个 Adapter 模块主要由两个前馈(Feed forward)子层组成,
-
第一个前馈子层(down-project)将Transformer块的输出作为输入,将原始输入维度
d
(高维特征)投影到m
(低维特征)通过控制m
的大小来限制Adapter模块的参数量,通常情况下,m<<d
-
然后,中间通过一个非线形层(Nonlinearity)。
-
在输出阶段,通过第二个前馈子层(up·project)还原输入维度,将
m
(低维特征)重新映射回d
(原来的高维特征),作为Adapter模块的输出。。
-
-
同时,通过一个跳跃连接(skip·connection)来将Adapter的输入重新加到最终的输出中去,这样可以保证,即便 Adapter一开始参数初始化接近0,Adapter也由于skip connection的设置而接近于一个恒等映射,从而确保训练的有效性。
-
通过实验发现,只训练少量参数的Adapter方法的效果可以媲美全量微调,这也验证了Adapter是一种高效的参数训练方法,可以快速将语言模型的能力迁移到下游任务中去。
-
Adapter通过引入0.5%~5%的模型参数可以达到不落后全量微调模型1%的性能
Adapter类的其他微调方法:
- Adapter Fusion:
- 通过将Adapter的训练分为知识提取和知识组合两部分,解决了灾难性遗忘、任务间干扰和训练不稳定的问题
- 但是,Adapter模块的添加也导致模型整体参数量的增加,降低了模型推理时的性能
- Adapter Drop:
- 通过从较低的Transformer层删除可变数量的Adapter来提升推理速度(删除无关的Adapters)。当对多个任务执行推理时,动态地减少了运行时的计算开销,并保持任务性能。
实战中用的并不多,但也要做一些了解。
5. Prefix类微调
Prefix类微调的几种方法:
-
Prefix Tuning:
-
在Prefix Tuning之前的工作主要是人工设计离散的模版或者自动化搜索离散的模版。
-
对于人工设计的模版,模版的变化对模型最终的性能特别敏感,加一个词、少一个词或者变动位置都会造成比较大的变化。
-
而对于自动化搜索模版,成本也比较高
-
同时,以前这种离散化的token搜索出来的结果可能并不是最优的。
-
除此之外,传统的微调范式利用预训练模型去对不同的下游任务进行微调,对每个任务都要保存一份微调后的模型权重,一方面微调整个模型耗时长,另一方面也会占很多存储空间。
-
技术原理:
-
基于上述两点,Prefix Tuning(论文:prefix-Tuning: Optimizing Continuous Prompts for Generation)提出固定预训练语言模型,为语言模型添加可训练,任务特定的前缀,这样就可以为不同任务保存不同的前缀,微调成本也小。
-
Prefix Tuning,在输入token之前构造一段任务相关的virtual tokens作为Prefix,然后训练的时候只更新Prefix部分的参数,而PLM中的其他部分参数固定。
- 上图:微调(顶部)更新所有Transformer参数(红色的Transformer框),并要求为每个任务存储一个完整的模型副本
- 下图:Prefix Tuning提出了前缀调优,它冻结了Transformer参数,只优化了前缀(红色前缀块),因此只需要存储每个任务的前缀,使前缀调优模块化节约空间
-
-
-
Prompt Tuning:
-
大模型全量微调对每个任务训练一个模型,开销和部署成本都比较高。
-
同时,离散的 prompts 方法,成本比较高,并且效果不太好
-
除此之外,之前的 Prefix Tuning 在更新参数的时候还是有些复杂。
-
技术原理:
-
基于此,作者提出了Prompt Tuning,通过反向传播更新参数来学习prompts,而不是人工设计prompts,同时冻结模型原始权重,只训练prompts参数,训练完以后,用同一个模型可以做多任务推理。
-
Prompt Tuning(论文:The Power of Scale for Parameter-Efficient PromptTuning),该方法可以看作是Prefix Tuning的简化版本
-
它给每个任务定义了自己的prompt,然后拼接到数据上作为输入,但只在输入层加入prompt tokens,并且不需要加入多层感知器(MLP)进行调整来解决难训练的问题。
-
Model Tuning 需要为每个下游任务制作整个预训练模型的任务特定副本,并且必须分批进行推理。
-
Prompt Tuning 只需要为每个任务存储一个特定于任务的小提示,并使用原始预训练模型进行混合任务推理。
-
通过实验发现,随着预训练模型参数量的增加,Prompt Tuning的方法会逼近全参数微调的结果。
- T5经过调优后模型可以实现不错的性能,但弊端是需要为每个最终任务存储单独微调后的模型
- 随着模型参数的增加,对T5的 prompt tuning与model tuning 的能力差不多。
- 该方法明显优于使用GPT-3 few-shot prompt 设计
-
-
-
Prefix Tuning和Prompt Tuning在微调上有哪些区别?
- PromptTuning 和 Prefix Tuning,都是在自然语言处理任务中对预训练模型进行微调的方法,但它们在实现细节和应用场景上有所不同。
- 以下是它们之间的主要区别:
- 参数更新位置:Prompt Tuning通常只在输入层添加参数,而Prefix Tuning在每一层都添加了参数。
- 参数数量:Prefix Tuning 通常比 Prompt Tuning 有更多的可学习参数(因为它为模型的每一层都添加了前缀)
- 适用任务:Prompt Tuning 更适合于分类任务,而 Prefix Tuning 更适合于生成任务(因为它可以在不同层次上调整模型的行为)
- 训练效率:Prompt Tuning 通常有更高的训练效率
-
P-tuning:
-
P-tuning 方法的提出同样是为了解决之前提到的两个问题:大模型的Prompt构造方式严重影响下游任务的效果,
- 比如:GPT-3采用人工构造的模版来做上下文学习(in-context learning),但人工设计的模版的变化特别敏感,加一个词或者少一个词,或者变动位置都会造成比较大的变化。
-
近期,自动化搜索模版工作成本也比较高,以前这种离散化的token的搜索出来的结果可能并不是最优的,导致性能不稳定。
-
技术原理:
-
基于此,作者提出了P-Tuning(论文:GPTUnderstands, Too),设计了一种连续可微的virtual token。
-
该方法将Prompt转换为可以学习的Embedding层,并对Prompt Embedding进行一层处理。
- 一个快速搜索**英国首都是[MASK]**的例子:
-
-
-
图示中,颜色代表内容:
-
上下文(蓝色区域,英国)
-
目标(红色区域,[MASK])
-
橙色区域指的是提示,
- 在左图(a)中,提示生成器仅接收离散奖励;相反,在**右图(b)**中,连续提示嵌入和提示编码器可以以可微的方式进行优化。
-
-
相比Prefix Tuning,P-Tuning加入了可微的virtual token,但仅限于输入层,没有在每一层都加;另外,virtual token的位置也不一定是前缀,插入的位置是可选的。这里的出发点实际是把传统人工设计模版中的真实token替换成可微的virtual token
-
P-tuning v2:
之前的Prompt Tuning和P-Tuning等方法存在两个主要的问题:
-
第一,缺乏模型参数规模和任务通用性。
- 缺乏规模通用性:Prompt Tuning论文中表明当模型参数规模超过10B时,提示优化可以与全量微调相媲美。但是对于那些较小的模型(从100M到1B),提示优化和全量微调的表现有很大差异,这大大限制了提示优化的适用性。
- 缺乏任务普遍性:尽管Prompt Tuning和P-tuning在一些NLU基准测试中表现出优势,但提示调优对硬序列标记任务(即序列标注)的有效性尚未得到验证。
-
第二,缺少深度提示优化。
在Prompt Tuning和P-tuning中,连续提示只被插入transformer第一层的输入embedding序列中。在接下来的transformer层中,插入连续提示的位置的embedding是由之前的transformer层计算出来的,这可能导致两个可能的优化挑战:
- 由于序列长度的限制,可调参数的数量是有限的
- 输入embedding对模型预测只有相对间接的影响
考虑到这些问题,作者提出了P-tuningv2,它对PromptTuning和P-Tuning进行改进,作为一个跨规模和NLU任务的通用解决方案。
-
**技术原理:**P-Tuning v2(论文:P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks)方法在每一层都加入了Prompts tokens作为输入,而不是仅仅加在输入层,这带来两个方面的好处:
- 更多可学习的参数(从P-tuning和Prompt Tuning的0.01%增加到0.1%-3%)
- 加入到更深层结构中的Prompt能给模型预测带来更直接的影响。
从P-tuning到P-tuning v2的变化:
-
橙色块(即 h 0 h_0 h0, …, h i h_i hi)表示可训练的 prompt embeddings
-
蓝色块是有冻结的预训练语言模型存储或计算的embeddings
- P-Tuningv2是一种在不同规模和任务中都可与微调相媲美的提示方法。P-Tuning v2对从330M到10B的模型显示出一致的改进,并在序列标注等困难的序列任务上以很大的幅度超过了PromptTuning和P-Tuning
- SuperGLUE的平均得分:使用0.1%的任务特定参数,P-tuning v2可以在预训练模型的大范围内进行微调,而 P-tuning 可以在10B的范围内进行有条件的微调。
-
Prefix类微调方法总结:
-
Prefix Tuning
- 在每一个Transformer层都带上一些virtual token作为前缓,以适应不同的任务。
- 优化多层prefix
- 与fine-tuning比肩
-
Prompt Tuning
- 该方法可以看着是Prefx Tunine的简化版本,针对不同的任务,仅在输入层引入virtualtoken形式的软提示(soft prompt)
- 优化单层prefix
- 大尺寸模型下与fine-tuning比肩
-
P-Tuning
- 将 Prompt 转换为可以学习的Embedding层。相比Prefix Tuning;仅在输入层加入的可微的vitualtoken;另外,virtual token的位置也不一定是前缀,插入的位置是可选的,
- 优化单层prefix
- 大尺寸模型下与fine-tuning比肩
-
P-Tuning v2
- 该方法在每一个Transformer层都加入了prompt token作为输入,引入多任务学习,针对不同任务采用不同的提示长度,
- 优化多层prefix
- 小尺寸和大尺寸模型下均与fine-tuning比肩
Prefix类微调方法介绍
Prefix Tuning
- 在每一个Transformer层都带上一些virtual token作为前缓,以适应不同的任务。
- 优化多层prefix
- 与fine-tuning比肩
Prompt Tuning
- 该方法可以看着是Prefx Tunine的简化版本,针对不同的任务,仅在输入层引入virtualtoken形式的软提示(soft prompt)
- 优化单层prefix
- 大尺寸模型下与fine-tuning比肩
P-Tuning
- 将 Prompt 转换为可以学习的Embedding层。相比Prefix Tuning;仅在输入层加入的可微的vitualtoken;另外,virtual token的位置也不一定是前缀,插入的位置是可选的,
- 优化单层prefix
- 大尺寸模型下与fine-tuning比肩
P-Tuning v2
- 该方法在每一个Transformer层都加入了prompt token作为输入,引入多任务学习,针对不同任务采用不同的提示长度,
- 优化多层prefix
- 小尺寸和大尺寸模型下均与fine-tuning比肩
PrefixTuning (2021.01)
- 论文题目:Prefix-Tuning: Optimizing Continuous Prompts for Generation
- 论文地址:hups://arxiv.org/pdf/2101.00190.pdf
- 论文源码:https://github,comxiangLi1999/PrefixTuning
P-tuning(2021.03)
- 论文题目:GPT Understands,Too
- 论文地址:https://arxiv,org/pdf/2103.10385.pdf
- 论文源码:https://github,com/THUDM/P-tuning
Prompt Tuning(2021.09)
- 论文题目:The Power of Scale for Parameter-Efficient Prompt Tuning
- 论文地址:https://arxiv,org/pdf/2104.08691.pdf
- 论文源码:https://github.com/google-research/prompt-tuning
P-tuning-v2(2022.03)
- 论文题目: P-Tuning v2: Prompt Tuning Can Be Comparable to finetuning Universally Across Scales and Tasks
- 论文地址:htps://arxiv,org/pdf/2110.07602.pdf
- 论文源码:https://github.com/THUDM/P-tuning-v2
6. LoRA相关问题
LoRA应该作用于Transformer的哪个参数矩阵(Q, K, V)?
答:根据之前2110.04366里的图,应该是作用于Q和K
拓展:
- 什么是rank?
- 在机器学习中,rank通常指矩阵的秩,表示矩阵中线性独立行或列的数量
- 在LoRA方法中,rank用于限制可训练参数的数量,通过低秩表示来高效调整模型。(本质上是通过将高维网络层改写为几个低维的网络层的迭加,矩阵表示类似于几个低秩矩阵的乘积)
- 通过降低秩,减少参数空间的自由度,使得模型在训练时更加高效,而不会显著影响性能,这是LoRA的核心思想。
上表中,当提到rank为8或4时,表示的是原始大的权重矩阵进行近似表示时所用的线性独立向量的数量,从而调整的可训练参数的数量。
-
表中部分内容的介绍:
- WikiSQL:专注于SQL生成任务的数据集,提供自然语言问题和SQL查询的对照
- MultiNLI:用于NLP推理的数据集,包含不同体裁的文本对,任务是判断一个给定前提和假设之间的关系,比如蕴含、矛盾还是中立。这个数据集用于评估模型在跨领域推理任务中的表现
- 几个权重矩阵: W q , W k , W v , W o W_q,W_k,W_v,W_o Wq,Wk,Wv,Wo,分别是生成 Q , K , V Q,K,V Q,K,V向量的权重矩阵,最后一个 W o W_o Wo是将多头注意力的输出组合起来的输出投影权重矩阵
-
表中内容的翻译:
- 在对GPT3的不同注意权重应用LoRA后,WikiSQL和MultiNLI数据集上的验证准确性。这里使用的是相同数量的可训练参数,调整 W q W_q Wq和 W v W_v Wv一起提供了最佳的整体性能。
- 需要注意的是,仅调整 Δ W q \Delta W_q ΔWq或 Δ W k \Delta W_k ΔWk会导致性能显著下降,而同时调整 Δ W q \Delta W_q ΔWq和 Δ W k \Delta W_k ΔWk能得到不错的效果。
- 这说明,即使秩设为4, Δ W \Delta W ΔW中也能捕获足够的信息,因此比起只调整单一类型的大秩权重,调整更多种类的权重矩阵效果会更好。
表总结:
- 将所有微调参数都放到attention的某一参数矩阵的效果并不好,将可微调参数分配到 W q W_q Wq和 W v W_v Wv的效果更好
- 即使是秩仅取4也能在 Δ W \Delta W ΔW中获得足够信息
- 因此在实际操作中,应当将可微调参数分配到多种类型权重矩阵中,而不应该用更大的秩单独微调某种类型的权重矩阵。
如何在已有LoRA模型上继续训练?
理解此问题的情形是:已有的lora模型只训练了一部分数据,要训练另一部分数据的话。
- 是在这个lora上继续训练呢?
- 还是和base模型合并后再套一层lora
- 或者从头开始训练一个lora?
-
直接在现有的lora模型上继续训练
- 适用情况:新的数据与之前数据相似,任务也相似
- 操作步骤
- 将新的数据用于继续训练现有的LoRA模型
- 这样,LoRA模型的权重将进一步更新,融合新知识
- 优点:保留模型之前学习的知识,节省训练资源和时间
- 注意事项:需要注意过拟合问题,可以适当使用正则化技术。且如果新数据分布有差异,可能需要调整学习率或其他超参。
-
将LoRA和BASE合并后得到新的BASE模型,再训练新的Lora
- 适用情况:想要在模型中固化之前的知识,然后再新任务上进一步微调
- 操作步骤:
- 将现有的Lora权重合并到Base模型中,得到新的Base模型
- 在新的Base模型上训练Lora层
- 优点:知识固化,新的Lora专注于学习新任务的特征。有助于模块化地管理不同任务的适应
- 缺点:模型容量增加,占用更多存储空间
-
从头训练Lora:
- 适用情况:新任务与之前任务完全不同,或者担心以前的知识会干扰新的学习
- 操作步骤:使用基础模型,直接训练Lora层
- 优点:模型更加专注,避免旧知识的干扰。模型更加专注于新任务
- 缺点:无法利用之前训练中获得的知识,可能需要更多的训练数据和时间。完全无法使用旧知识,有点浪费资源。
总结:根据任务需求选择(任务相似、任务不同但有相关性、任务完全不同)
LoRA权重是否可以合入原模型?
- 可以,将训练好的低秩矩阵 ( B × A ) + 原模型权重合并(即相加) (B\times A)+原模型权重合并(即相加) (B×A)+原模型权重合并(即相加),计算
LoRA微调方法为什么能加速训练
-
只更新了部分参数:比如LoRA原论文就选择只更新self-attention的参数,实际使用时我们还可以选择只更新部分层的参数
-
减少了通信时间:参数少,需要传输的数据量也就变少了
-
采用了各种低精度加速技术:FP16 FP8 INT8
-
低秩分解的直观性:LoRA使用低秩分解方式更新和表示参数。这种方法再不少场景种能够很好地保持与全量微调相同的效果,同时本身非常直观易于理解
-
预测阶段不增加推理成本:LoRA的设计确保再推理阶段不会额外增加计算成本。因为微调的调整是通过低秩矩阵的形式添加的,并且再应用时已经被整合到模型参数中,不需要额外的运算,这有利于保持推理速度。
LoRA中的rank如何选取?
- 作者对比了1-64的rank,效果上4-8之间最好,再高没有效果提升
- 不过论文的实验是面向下游单一监督任务的,因此在指令微调上根据指令分布的广度,rank选择还是需要在8以上的取值进行测试的。
LoRA如何避免过拟合?
在使用LoRA进行微调时,过拟合是一个常见的问题(训练数据表现得好,但是在测试集上表现差,通常因为模型过度学习训练数据细节和噪声,而未抓住数据得普遍规律)
具体方法:
- 减小rank值
- 增加数据集大小
- 增加优化器得权重衰减率(weight decay)
- 增加LoRA层的dropout值
- 解释:Dropout是一种防止过拟合的技术,通过在训练过程中随机忽略部分神经元,使模型不依赖于特定的神经元
- 如何避免过拟合:在LoRA层增加Dropout,可以随机屏蔽部分LoRA层的参数,使模型更具鲁棒性,减少对特定参数的过度依赖,从而降低过拟合的风险。
LoRA矩阵初始化?
前面我们已经知道:
- 降维 矩阵 A A A采用高斯分布(正态分布) 来初始化,以赋予其随即特性
- 而升维矩阵 B B B初始化为零矩阵,这样开始训练时就不会影响原有模型的输出,确保训练稳定性
权重更新方式为:
W = W 0 + A B ⊤ W=W_0 + AB^\top W=W0+AB⊤
这种操作有如下的考量:
-
为什么不把 A A A和 B B B都初始化为零?
- 此时 W = W 0 W=W_0 W=W0,意味着训练开始时,模型参数没有任何变化
- 缺点:
- 可能出现梯度消失和对称性问题:所有神经元的初始状态和更新方向都相同,导致网络无法打破对称性。这样一来,神经元无法学习到多样化的特征,影响模型的表达能力
- 训练困难:梯度更新可能会因为缺乏初始扰动而过于缓慢,导致训练过程收敛速度变慢,甚至无法收敛
-
为什么不把 A A A和 B B B都用高斯初始化?
-
此时,初始权重更新为: Δ W = A B ⊤ \Delta W=AB^\top ΔW=AB⊤,由于 A A A和 B B B都是随机初始化的,因此 Δ W \Delta W ΔW也是一个随机矩阵,并且可能具有较大的值。
-
缺点:
- 初始扰动过大:过大的 Δ W \Delta W ΔW会在训练开始时对原有的预训练模型参数造成过大扰动,可能导致模型的输出偏离预期,训练不稳定
- 收敛困难:过大的初始噪声可能导致梯度爆炸,模型难以找到正确的优化方向,从而影响训练效果。
-
-
为什么不用高斯分布初始化 A A A,零矩阵初始化 B B B
- 理论上,LoRA矩阵初始化可以对调,由于LoRA的核心思想是通过低秩分解来更新预训练权重矩阵 W 0 W_0 W0,最终训练的效果取决于模型对 Δ W = A B ⊤ \Delta W=AB^\top ΔW=AB⊤的学习能力,而不是特定的初始化方式。
- 可能的影响:
- 优化过程:梯度如何影响 B B B和 A A A的学习方向。
- 数值稳定性:论文中推荐的方式可能经过了实验验证,确保在实际应用中具有较好的数值稳定性,如果对调初始化,可能需要重新调试超参数。
总结:通过矩阵 A A A采用高斯分布(正态分布) 来初始化,升维矩阵 B B B初始化为零矩阵,可以:
- 保持模型初始输出与预训练模型一致,避免初始扰动过大
- 利用 A A A的随机性打破对称性,提供丰富的梯度信息
- 在训练过程中, B B B从零开始逐步学习,有效控制权重更新幅度,促进模型稳定收敛。
@# AdaLoRA
LoRA通过低秩分解来模拟参数的该变量,从而以极小的参数量来实现大模型的间接训练
AdaLoRA是对LoRA的一种改进,它根据重要性评分动态分配参数预算给权重矩阵,将关键的增量矩阵分配高秩以捕捉更精细和任务特定的信息,而将较不重要的矩阵的秩降低,以防止过拟合,并节省计算成本。
AdaLoRA讨论了如何更好地进行秩的设置:
- 它引入了一种动态低秩适应技术,在训练过程中动态调整每个参数矩阵需要训练的秩同时控制训练的参数总量。
具体来说,模型在微调过程中通过损失来衡量每个参数矩阵对训练结果的重要性,重要性较高的参数矩阵被赋予比较高的秩,进而能够更好地学习到有助于任务的信息。相对而言,不太重要的参数矩阵被给予比较低的秩,来防止过拟合并节省计算资源。
论文:arxiv@2303.10512
代码:https://github.com/QingruZhang/AdaLoRA
7. QLoRA的思路
论文:arxiv@2305.14314
代码:https://github.com/artidoro/glora
- 尽管 LORA 已经轻量化了,但由于使用 BFloat16 进行训练,微调特别大的模型(65B以上)时无法使用单张卡或几张卡进行训练。
- QLORA是 LORA 的改进版,可以减少内存使用,可以在单个48GB GPU上微调 65B 的大模型,同时保留完整的16位微调任务性能。
- 其工作原理是首先将 LLM 进行4位量化,从而显著减少模型的内存占用;然后使用 LORA 对量化的LLM进行微调。
- 使用 QLORA可以节省 33%的GPU内存。然而,由于 QLORA 中预训练模型权重的额外量化和去量化,训练时间增加了39%。
大致思想:
- 使用一种新颖的高精度技术将预训练模型量化为 4bit;
- 然后添加一小组可学习的低秩适配器权重,这些权重通过量化权重的反向传播梯度进行微调。
特点:
- 使用 QLORA 微调模型,可以显著降低对于显存的要求。但是,模型训练的速度会慢于LORA。
8. PEFT中,基座模型应该选用Chat版本还是Base版本?
-
如果监督任务是对话生成相关的任务
- 示例:生成对话回复、对话情感分析、多轮对话管理等
- 建议:选择ChatGPT类模型作为基座
- 原因:
- ChatGPT 模型经过专门的对话数据训练,具备更强的对话交互能力。
- 能更好地理解上下文,处理多轮对话中的语义关联。
- 在生成对话回复时,能够提供更加自然和连贯的回应。
-
如果监督任务是单轮文本生成或非对话生成任务:
- 示例:文本摘要、机器翻译、文本分类、问答系统(非对话式)等。
- 建议:选择 Base GPT 模型 作为基座模型
- 原因:
- Base 模型未经过对话数据的特化训练,保持了模型的通用性
- 在单轮文本生成和理解任务上表现出色,能够生成更加准确和贴合任务需求的结果。
- 避免了对话特征对非对话任务可能带来的干扰。
9. 预训练和微调哪个阶段注入知识?
简答:预训练和微调都注入知识,但注入的方式和范围不同。
- 预训练阶段注入的是通用的语言知识,使模型具备广泛的语言理解和生成能力。
- 微调阶段注入的是与特定任务相关的知识,使模型在特定任务上表现出色。
解析:
预训练:
-
目的:让模型从大量的未标注文本数据中学习语言的基本结构、语法、语义以及通用知识。
-
知识注入方式:
- 大规模数据学习:通过在海量的文本语料(如互联网数据、维基百科文章等)上进行训练,模型学习到了广泛的语言特征和常识性知识。
- 自监督学习:使用语言模型任务(如下一个词预测、掩码预测)让模型自我训练,学习词与词之间的关系、句法结构和上下文语义。
-
注入的知识类型:
- 通用语言知识:例如词汇含义、惯用表达、句法结构。
- 世界常识:由于训练数据的广泛性,模型也学习到了人类社会的常识性知识。
-
结果:预训练后的模型具备了对语言的基本理解和生成能力,能够在没有特定任务指导的情况下生成连贯的文本。
微调:
- 目的:让预训练模型适应特定的下游任务需求,提高在特定任务上的性能
- 知识注入方式:
- 监督学习:通过在标注了任务标签的数据集上训练,模型学习到了任务特定的模式和知识。
- 参数调整:在微调过程中,模型的参数会针对特定任务进行调整和优化。
- 注入的知识类型:
- 任务特定知识:例如对于情感分类任务,模型学习到哪些词语或表达与积极或消极情感相关。
- 领域专业知识:在特定领域的数据上微调,模型可以学习到该领域的专业知识和术语
- 结果:微调后的模型在特定任务上表现优异,能够准确完成任务,例如分类、问答、翻译等
总结:
- 预训练阶段:通过大规模未标注数据,模型学习到了通用的语言知识和世界常识,建立了语言理解的基础。
- 微调阶段:通过特定任务的标注数据,模型学习到了任务相关的知识,使其能够专注于具体任务并提升性能
两者的结合,使得模型既有广泛的语言理解能力,又能够在特定任务上发挥出色的表现。
10. 多轮对话任务如何微调模型?
在多轮对话任务中,微调模型的目标是使模型能够理解和生成连贯的多轮对话回复,具备上下文理解和一致性回复的能力。
下面详细解释如何在多轮对话任务中微调模型,包括每个步骤的目的和方法。
10.1 数据准备
-
目标:收集或创建适用于多轮对话任务的数据集。
-
方法:
- 收集现有数据集:使用公开的多轮对话数据集,如Persona-Chat、DailyDialog等。这些数据集包含大量的人类对话,涵盖各种话题和情境。
- 创建自定义数据集:如果有特定的领域或任务需求,可能需要自行收集或生成对话数据。
- 数据清洗和预处理:确保数据质量,去除噪声、重复或不相关的内容。
-
注意:
- 上下文信息:确保每条对话包含足够的上下文,多轮对话的连续性对模型的训练至关重要
- 数据多样性:包含不同的话题、情感和语言风格,有助于模型学习更丰富的表达方式
10.2 构建输入输出格式
- 目标:将原始对话数据转换为适合模型训练的格式。
- 方法:
- 输入格式:将多轮对话的历史(上下文)拼接成一个输入序列。
- 示例:
[用户] 你好! [机器人] 你好,请问有什么可以帮到您的吗? [用户] 我想预定一张去北京的火车票。
- 输出格式:模型需要生成的下一轮回复(y标签,即标注),即问题的答案
- 使用特殊标记,在不同的说话者之间添加特殊标记(如[用户][机器人]这样的)有助于模型区分不同角色,提高对话连贯性
- 输入长度限制:模型的最大输入长度有限,需要合理截断或摘要过长的对话历史
10.3 模型选择
- 目标:选择适合多轮对话任务的预训练模型。
- 常用模型:
- DialoGPT:微软发布的对话生成模型,基于GPT-2,专为对话生成设计,适合多轮对话任务
- OLLAMA:通用的语言生成模型,具备强大的文本生成能力。
- BERT:主要用于理解任务(如分类、问答),不适合直接用于生成对话回复,但可用于理解型对话任务
- 其他:Qwen,ChatGLM,Pangu等
- 考虑因素:
- 任务类型:生成型任务选择生成模型(如GPT系列),理解型任务可考虑BERT等
- 模型大小:朴根据可用的计算资源和任务需求,选择合适的模型规模。
- 预训练数据:选择已经在对话数据上预训练的模型有助于提升初始性能。
10.4 微调模型
-
初始化模型参数:
- 加载预训练模型:从预训练模型中加载参数,作为微调的起点。
-
定义损失函数:
- 生成任务:通常使用交叉熵损失函数,计算模型生成的回复与真实回复之间的差异。
- 特殊任务:根据任务需求,可能需要自定义损失函数,如引入情感倾向、特定词汇等。
-
进行反向传播和参数更新:
- 前向传播:将输入数据传入模型,得到模型输出。
- 计算损失:根据模型输出和真实标签(或目标回复),计算损失值。
- 反向传播:计算损失对模型参数的梯度。
-
重复训练步骤:
- 多轮迭代:遍历整个训练数据集多个epoch,不断更新模型参数
- 验证:在验证集上评估模型性能,防止过拟合。
- 注意:
- 学习率设定:微调时通常采用较小的学习率,防止模型参数发生过大变化,导致预训练知识遗失
- 梯度剪裁:防止梯度爆炸,保持训练的稳定性
10.5 超参数调优
-
可调超参数:lr(影响参数更新速度),batchsize(英雄模型训练速度和泛化性能),epoches(过多可能过拟合,反之欠拟合),权重衰减(wd,用于正则化的参数,防止过拟合)
-
方法:gridsearch,random search,Bayesian Optimization(利用贝叶斯理论智能地探索参数空间)
-
评估:
- 验证集表现:根据验证集的损失或评价指标,选择最佳的超参数组合。
- 早停(Early Stopping):当验证集性能不再提升时,提前停止训练。
10.6 评估和测试
-
目标:客观评价模型在多轮对话任务上的性能,确保模型的有效性和可靠性
-
评估指标:
- 自动评估:
- BLEU,ROUGE:统计匹配程度
- Perplexity(困惑度,PPL),衡量模型对测试集地拟合程度
- Distinct-N:评估生成回复的多样性,计算生成文本中不同n-gram的比例。
- 人工评估:
- 流畅性:回复是否语法正确、表达流畅,
- 相关性:回复与上下文是否相关。
- 连贯性:在多轮对话中,回复是否前后连贯,
- 信息性:回复中是否包含有用的信息。
- 自动评估:
-
测试集评估:使用未参与训练和验证的测试集,评估模型的泛化能力和实际表现,
-
错误分析:
- 类别分析:识别模型在哪些类型的对话中表现较差,如涉及特定话题、情感等
- 案例分析:深入分析错误案例,理解模型的不足之处,指导后续改进
10.7 特定技巧的应用
-
使用对话策略进行训练:
- 目标:让模型学习合理的对话行为,提高对话的有效性和用户满意度。
- 方法:
- 策略建模:定义一系列对话策略,让模型学习何时提问、何时提供信息、如何引导对话等。
- 强化学习:使用奖励信号,训练模型在对话中采取最优策略。
-
数据增强:
- 目标:扩大训练数据的规模和多样性,提升模型的泛化能力。
- 方法:
- 同义替换:用同义词或短语替换原有的词汇。
- 随机插入或删除:在句子中随机插入或删除词语,生成新的对话实例。
- 翻译回译:将原句翻译成另一个语言,再翻译回来,产生语义相近的句子
-
情感和个性化建模:
- 目标:使模型的回复具有特定的情感倾向或人设,提升用户体验。
- 方法:
- 情感标签:在训练数据中标注情感,指导模型生成带有特定情感的回复。
- 人格特征:为模型设定特定的性格特征,在生成回复时体现出来
总结:
- 数据是基础:高质量、多样化的多轮对话数据集是成功微调模型的关键,
- 模型选择与调整:根据任务需求选择合适的预训练模型,并通过微调使其适应特定的对话任务。
- 训练过程:细心设计训练流程,注意超参数的设置和模型的稳定性。
- 评估与改进:持续评估模型性能,针对不足之处进行改进,如引入注意力机制、策略训练等
- 创新应用:结合任务特点,应用特殊技巧(如情感建模、数据增强)提升模型的实际效果。
Transformers相关
参考资料:
- 李宏毅老师介绍:https://www.youtube.com/watch?v=ugWDIIOHtPA&list=PLJY_el3uVTSOK_ZK5LOlv_EOoL1JefRL4&index=61
- 可视化说明:https://bbycroft.net/llm
- 其他大佬文章:
- https://baijiahao.baidu.com/s?id=1651219987457222196&wfr=spider&for=pc
- https://jalammar.github.io/illustrated-transformer/
Transformers之后的几个框架?
Mamba:https://arxiv.org/pdf/2312.00752
- 由卡内基梅隆大学和普林斯顿大学的研究人员2023年开发,Mamba通过引入状态空间模型(SSM),实现更高的训练速度和更强的表示能力。
TTT:https://arxiv.org/pdf/2407.04620
- TTT是斯坦福大学、UCSD、UC伯克利和Meta的研究团队2024.8联合推出的一种全新架构,旨在通过机器学习模型取代RNN的隐藏状态,从而优化语言模型方法。
1. Transformers概述
Transformers由6个encoder和6个decoder组成:
工作流程:
-
获取输入句子的每一个单词的表示向量 X X X,由单词的embedding和位置编码相加得到:
-
将嵌入矩阵 X ∈ R n × d X\in\R^{n\times d} X∈Rn×d输入到Encoder中,经过6个encoder block后得到句子所有单词的编码信息矩阵 C C C,其中 n n n是句中单词数量, d d d是单词维度(论文中为 d = 512 d=512 d=512)
每一个encoderblock的输出矩阵与输入矩阵形状相同
(细节:这里会按照词根来划分token,比如doing会被分成do和ing来编码)
-
将Encoder输出的编码矩阵 C C C传递到Decoder中,Decoder依次会根据当前翻译过的单词 1 , 2 , . . . , i 1,2,...,i 1,2,...,i来翻译下一个单词 i + 1 i+1 i+1
- 实际使用中,翻译到第 i + 1 i+1 i+1个单词时需要通过Mask来遮盖住 i + 1 i+1 i+1之后的单词:
- Decoder接收了
C
C
C然后输出一个翻译开始符
<Begin>
,预测第一个单词 i i i - 然后输入
<Begin> i
,预测单词have
,以此类推 - 这是Transformer使用的大致流程
2. Transformer的输入部分具体是如何构成?
Transformer 中单词的输入表示 x由单词 Embedding 和位置 Embedding 相加得到。
2.1 单词 Embedding
- 单词的 Embedding 有很多种方式可以获取,
- 例如可以采用 Word2Vec、Glove 等算法预训练得到,也可以在 Transformer 中训练得到。
2.2 位置 Embedding
- Transformer 中除了单词的 Embedding,还需要使用位置 Embedding 表示单词出现在句子中的位置。
- 因为 Transformer 不采用 RNN 的结构,而是使用全局信息,不能利用单词的顺序信息,而这部分信息对于 NLP 来说非常重要。
- 所以 Transformer 中使用位置 Embedding 保存单词在序列中的相对或绝对位置。
- 位置 Embedding用 PE表示,PE的维度与单词 Embedding 是一样的。
- PE 可以通过训练得到,也可以使用某种公式计算得到。在Transformer 中采用了后者,计算公式如下:
P E ( p o s , 2 i ) = sin ( p o s / 1000 0 2 i / d ) P E ( p o s , 2 i + 1 ) = cos ( p o s / 1000 0 2 i / d ) PE(pos, 2i) = \sin (pos / 10000^{2i/d})\\ PE(pos, 2i + 1) = \cos(pos / 10000^{2i/d}) PE(pos,2i)=sin(pos/100002i/d)PE(pos,2i+1)=cos(pos/100002i/d)
- pos 表示单词在句子中的位置,d表示 PE的维度(与词 Embedding 一样)
- 2i 表示偶数的维度,2i+1表示奇数维度 (即 2i < d, 2i + 1 < d)。
使用这种公式计算PE的好处:
- 使 PE 能够适应比训练集里面所有句子更长的句子,假设训练集里面最长的句子是有 20 个单词,突然来了一个长度为 21 的句子,则使用公式计算的方法可以快速计算出第 21 位的 Embedding。
- 可以让模型容易地计算出相对位置,对于固定长度的间距k,PE(poS+k)可以用 PE(poS)计算得到。因为:
Sin(A+B)=Sin(A)Cos(B)+Cos(A)Sin(B),
Cos(A+B)=Cos(A)Cos(B)-Sin(A)Sin(B)
- 将单词的词 Embedding 和位置 Embedding相加,就可以得到单词的表示向量x,x就是 Transformer 的输入。
自注意力原理
-
红色圈忠的部分是多头注意力,是由多个自注意力组成,可以看到:
- Encoder包含一个多头注意力
- Decoder包含两个多头注意力(其中一个用到Mask)
-
多头注意力上方还包括一个AddNorm层,就是残差连接加层正则化(LayerNorm)
3.1 自注意力结构
- 输入: Q , K , V Q,K,V Q,K,V
- 实际操作忠,自注意力接收的是输入(单词的表示向量组成的矩阵 X X X)或者上一个Encoder block的输出
- Q , K , V Q,K,V Q,K,V正是通过自注意力的输入进行线性变换得到
3.2 QKV的计算
自注意力的输入用矩阵 X X X表示,则可以使用线性变换矩阵 W Q , W K , W V W_Q,W_K,W_V WQ,WK,WV计算得到 Q , K , V Q,K,V Q,K,V,计算如下图所示,注意 X , Q , K , V X,Q,K,V X,Q,K,V的每一行都表示一个单词:
3.3 自注意力的输出
得到矩阵 Q , K , V Q,K,V Q,K,V之后就可以计算出自注意力的输出了:
A t t ( Q , K , V ) = s o f t m a x ( Q K ⊤ d ) V Att(Q,K,V)={\rm softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V Att(Q,K,V)=softmax(dQK⊤)V
其中 d k d_k dk是 Q , K Q,K Q,K的列数,即向量维度,论文中 d = 512 d=512 d=512
- 公式中计算矩阵 Q Q Q和 K K K每一行向量的内积,为了防止内积过大,因此除以 d k d_k dk的平方根
- Q Q Q乘以 K K K的转置后,得到的矩阵行列数都为 n n n, n n n为句子单词数,这个矩阵可以表示单词之间的attention强度
- 下图为 Q K ⊤ QK^\top QK⊤,1234表示句子中的单词:
- 得到 Q K ⊤ QK^\top QK⊤之后,使用softmax计算每一个单词对于其他单词的attention系数
- 公式中的softmax是对矩阵的每一行进行softmax,即每一行的和都变为1
- 得到softmax矩阵后可以和 V V V相乘,得到最终输出 Z Z Z
- 上图中Softmax矩阵的第一行表示单词1和其他所有单词的attention系数
- 最终单词1和输出 Z 1 Z_1 Z1等于所有单词 i i i的值 V i V_i Vi根据attention系数的比例加在一起得到,如下图所示:
3.4 多头注意力
-
首先将输入 X X X分别传递到 h h h个不同的自注意力中,计算得到 h h h个输出矩阵 Z Z Z,论文中 h = 8 h=8 h=8,即得到8个输出矩阵 Z Z Z
-
得到 Z 1 Z_1 Z1到 Z 8 Z_8 Z8之后,多头就是直接拼接,然后传入到Linear层,得到多头注意力最终输出 Z \bf Z Z,这里 Z \bf Z Z其实和那个是一个形状的。