【大模型 LLMs 基础面 Plus】
Layer normalization - 方法篇
一、 Layer Norm 篇
1.1 Layer Norm 的计算公式
二、 RMS Norm 篇
(均方根 Norm)
2.1 RMS Norm 的计算公式
2.2 RMS Norm 相比于 Layer Norm 有什么特点?
RMS Norm 简化了 Layer Norm,去除掉计算均值进行平移的部分。
对比 LN,RMS Norm 的计算速度更快。效果基本相当,甚至略有提升。
三、 Deep Norm 篇
3.1 Deep Norm 思路?
Deep Norm 方法在执行 Layer Norm 之前,up-scale 了残差连接(( \alpha > 1 ));另外,在初始化阶段 down-scale 了模型参数(( \beta < 1 ))。
3.2 Deep Norm 代码实现?
Deep Norm 有什么优点?
Deep Norm 可以缓解爆炸式模型更新的问题,把模型更新限制在常数,使得模型训练过程更稳定。
Layer normalization - 位置篇
LN 在 LLMs 中的不同位置有什么区别么?如有能介绍一下区别么?
回答:有,LN 在 LLMs 位置有以下几种:
Post LN:
- 位置:Layer norm 在残差链接之后
- 缺点:Post LN 在深层的梯度范式逐渐增大,导致使用 Post-LN 的深层 Transformer 容易出现训练不稳定的问题
Pre-LN:
- 位置:Layer norm 在残差链接中
- 优点:相比于 Post-LN,Pre-LN 在深层的梯度范式近似相等,所以使用 Pre-LN 的深层 Transformer 训练更稳定,可以缓解训练不稳定问题
- 缺点:相比于 Post-LN,Pre-LN 的模型效果略差
Sandwich-LN:
- 位置:在 Pre-LN 的基础上,额外插入了一个 Layer norm
- 优点:Cogview 用来避免值爆炸的问题
- 缺点:训练不稳定,可能会导致训练崩溃。
Layer normalization - 对比篇
LLMs 各模型分别用了哪种 Layer normalization?
- BLOOM 在 embedding 层后添加 Layer normalization,有利于提升训练稳定性,但可能会带来很大的性能损失。
LLMs 激活函数篇
介绍一下 FFN 块计算公式?
介绍一下 GeLU 计算公式?
介绍一下 Swish 计算公式?
注:2 个可训练权重矩阵,中间维度为 4h
介绍一下使用 GLU 线性门控单元的 FFN 块计算公式?
介绍一下使用 GeLU 的 GLU 块计算公式?
介绍一下使用 Swish 的 GLU 块计算公式?
注:3 个可训练权重矩阵,中间维度为 4h*2/3
各 LLMs 都使用哪种激活函数?
LLMs 注意力机制
优化篇
- 传统 Attention 存在哪些问题?
传统 Attention 存在以下问题:
- 上下文长度约束问题;
- 传统 Attention 速度慢,内存占用大;
- Attention 优化方向?
- 提升上下文长度;
- 加速、减少内存占用;
- Attention 变体有哪些?
- 稀疏 Attention:将稀疏偏差引入 Attention 机制可以降低复杂性;
- 线性化 Attention:解开 Attention 矩阵与内核特征图,然后以相反的顺序计算 Attention 以实现线性复杂度;
- 原型和内存压缩:减少查询或键值记忆对的数量,以减少注意力矩阵的大小;
- 低阶 Self-Attention:这一系列工作捕获了 Self-Attention 的低阶属性;
- Attention 与先验:用先验 Attention 分布来补充或替代标准 Attention;
- 改进多头机制:探索不同的替代多头机制。
- Multi-Query Attention 篇
4.1 Multi-head Attention 存在什么问题?
训练过程:不会显著影响训练过程,训练速度不变,会引起非常细微的模型效果损失;
推理过程:反复加载巨大的 KV cache,导致内存开销大,性能受内存限制;
4.2 介绍一下 Multi-Query Attention?
Multi-Query Attention 在所有注意力头上共享 key 和 value。
4.3 对比一下 Multi-head Attention 和 Multi-Query Attention?
- Multi-head Attention:每个注意力头都有各自的 query、key 和 value;
- Multi-query Attention:在所有的注意力头上共享 key 和 value。
Falcon、PaLM、ChatGLM2-6B 都使用了 Multi-query Attention,但有细微差别。
Falcon:把隐藏维度从 4096 增大到了 4544,多余的参数量分配给 Attention 块和 FFN 块;
ChatGLM2:把 FFN 中间维度从 11008 增大到了 13696,多余的参数分配给 FFN 块。
4.4 Multi-Query Attention 这样做的好处是什么?
减少 KV cache 的大小,减少显存占用,提升推理速度。
4.5 有哪些模型是使用 Multi-Query Attention?
代表模型:PaLM、ChatGLM2、Falcon 等。
5 Grouped-query Attention 篇
5.1 什么是 Grouped-query Attention?
Grouped-query Attention 介于 multi-head 和 multi-query 之间,多个 key 和 value。
5.2 有哪些大模型使用 Grouped-query Attention?
ChatGLM2,LLaMA2-34B/70B 使用了 Grouped-query Attention。
6 Flash Attention 篇
- 核心:用分块 softmax 等价替代传统 softmax
- 优点:节约 HBM, 高效利用 SRAM,省显存,提速度
- 代表模型:Meta 推出的开源大模型 LLaMA,阿联酋推出的开源大模型 Falcon 都使用了 Flash Attention 来加速计算和节省显存
- 关键词:HBM、SRAM、分块 Softmax、重计算、Kernel 融合
7 并行 transformer block
- 用并行公式替换了串行,提升了 15% 的训练速度。
- 在 8B 参数量规模时,会有轻微的模型效果损失;在 62B 参数量规模时,就不会损失模型效果。
- 代表模型:Falcon、PaLM 都使用了该技术来加速训练。
LLMs 损失函数篇
- 介绍一下 KL 散度?
KL(Kullback-Leibler)散度衡量了两个概率分布之间的差异。其公式为:
[
KL(P || Q) = \sum_{x} P(x) \log \frac{P(x)}{Q(x)}
]
- 交叉熵损失函数写一下,物理意义是什么?
交叉熵损失函数(Cross-Entropy Loss Function)是用于度量两个概率分布之间的差异的一种损失函数。在分类问题中,它通常用于衡量模型的预测分布与实际标签分布之间的差异。
- KL 散度与交叉熵的区别?
- KL 散度:指的是相对熵,KL 散度是两个概率分布 P 和 Q 差别的非对称性度量。KL 散度越小表示两个分布越接近。KL 散度是不对称的,且其值是非负数。
- 交叉熵损失函数:在二分类问题中最常用的损失函数,适用于多分类问题。交叉熵损失函数实际上是 KL 散度的一个特殊形式。
交叉熵损失函数和 KL 散度的区别:
- 交叉熵损失函数在二分类问题中只有一项,在多分类问题中有多项。
- KL 散度是用于衡量两个分布之间差异的指标,而交叉熵是 KL 散度的一种特殊形式。
- 多任务学习各 loss 差异过大怎样处理?
多任务学习中,如果各任务的损失差异过大,可以通过以下方法处理:
- 动态调整损失权重;
- 使用任务特定的损失函数;
- 改变模型架构;
- 引入正则化方法;
目标是平衡各任务的贡献,以便更好地训练模型。
- 分类问题为什么用交叉熵损失函数不用均方误差(MSE)?
交叉熵损失函数通常用于分类问题,而均方误差(MSE)损失函数通常用于回归问题。两者的区别如下:
- 交叉熵损失函数:适用于分类问题,用于度量两个概率分布之间的差异,能更好地区分不同的类别。
- 均方误差(MSE):适用于回归问题,度量预测值与真实值之间的差异的平方,在分类问题中不太合适,因为它对概率的微小差异不够敏感。
交叉熵损失函数更适合分类问题,而 MSE 损失函数更适合回归问题。
6 什么是信息增益?
信息增益是在决策树算法中用于选择最佳特征的一种评价指标。在决策树的生成过程中,选择最佳特征来进行节点的分裂是关键步骤之一,信息增益可以帮助确定最佳特征。
信息增益衡量了在特征已知的情况下,将样本集合划分成不同类别的纯度提升程度。它基于信息论的概念,使用熵来度量样本集合的不确定性。具体而言,信息增益是原始集合的熵与特定特征下的条件熵之间的差异。
在决策树的生成过程中,选择具有最大信息增益的特征作为当前节点的分裂标准,可以将样本划分为更加纯净的子节点。信息增益越大,意味着使用该特征进行划分可以更好地减少样本集合的不确定性,提高分类的准确性。
7 多分类的分类损失函数 (Softmax)?
多分类的分类损失函数采用 Softmax 交叉熵(Softmax Cross Entropy)损失函数。Softmax 函数可以将输出值归一化为概率分布,用于多分类问题的输出层。Softmax 交叉熵损失函数可以写成:
[
L = - \sum_{i=1}^{n} y_i \log(p_i)
]
其中,n 是类别数,( y_i ) 是第 i 类的真实标签,( p_i ) 是第 i 类的预测概率。
8 Softmax 和交叉熵损失怎么计算,二值交叉熵呢?
- Softmax 计算公式:
[
pi = \frac{e^{x_i}}{\sum{j=1}^{n} e^{x_j}}
]
- 多分类交叉熵:
[
L = - \sum_{i=1}^{n} y_i \log(p_i)
]
- 二分类交叉熵:
[
L = - [y \log(p) + (1 - y) \log(1 - p)]
]
9 如果 softmax 的 e 次方超过 float 的值了怎么办?
将分子分母同时除以 x 中的最大值,可以解决。
LLMs 相似度函数篇
- 除了 cosin 还有哪些算相似度的方法?
除了余弦相似度(cosine similarity)之外,常见的相似度计算方法还包括:
- 欧氏距离(Euclidean distance)
- 曼哈顿距离(Manhattan distance)
- Jaccard 相似度(Jaccard similarity)
- 皮尔逊相关系数(Pearson correlation coefficient)
- 了解对比学习吗?
对比学习是一种无监督学习方法,通过训练模型使得相同样本的表示更接近,不同样本的表示更远离,从而学习到更好的表示。对比学习通常使用对比损失函数,例如 Siamese 网络、Triplet 网络等,用于学习数据之间的相似性和差异性。
- 对比学习负样本是否重要?负样本构造成本过高应该怎么解决?
对比学习中负样本的重要性取决于具体的任务和数据。负样本可以帮助模型学习到样本之间的区分度,从而提高模型的性能和泛化能力。然而,负样本的构造成本可能会较高,特别是在一些领域和任务中。
为了解决负样本构造成本过高的问题,可以考虑以下方法:
- 降低负样本的构造成本:通过设计更高效的负样本生成算法或采样策略,减少负样本的构造成本。例如,可以利用数据增强技术生成合成的负样本,或者使用近似采样方法选择与正样本相似但不相同的负样本。
- 确定关键负样本:根据具体任务的特点,可以重点关注一些关键的负样本,而不是对所有负样本进行详细的构造。这样可以降低构造成本,同时仍然能够有效训练模型。
- 迁移学习和预训练模型:利用预训练模型或迁移学习的方法,可以在其他领域或任务中利用已有的负样本构造成果,减少重复的负样本构造工作。
【大模型 LLMs 训练经验面 Plus】
1 分布式训练框架选择?
多用 DeepSpeed,少用 PyTorch 原生的 torchrun。在节点数量较少的情况下,使用何种训练框架并不是特别重要;然而,一旦涉及到数百个节点,DeepSpeed 显现出其强大之处,其简便的启动和便于性能分析的特点使其成为理想之选。
2 LLMs 训练时有哪些有用的建议?
弹性容错和自动重启机制
大模型训练不是以往那种单机训个几小时就结束的任务,往往需要训练好几周甚至好几个月,这时候你就知道能稳定训练有多么重要。弹性容错能让你在机器故障的情况下依然继续重启训练;自动重启能让你在训练中断之后立刻重启训练。毕竟,大模型时代,节约时间就是节约钱。定期保存模型
训练的时候每隔一段时间做个 checkpointing,这样如果训练中断还能从上次的断点来恢复训练。想清楚再开始训练
训练一次大模型的成本很高的。在训练之前先想清楚这次训练的目的,记录训练参数和中间过程结果,少做重复劳动。关注 GPU 使用效率
有时候,即使增加了多块 A100 GPU,大型模型的训练速度未必会加快,这很可能是因为 GPU 使用效率不高,尤其在多机训练情况下更为明显。仅仅依赖 nvidia-smi 显示的 GPU 利用率并不足以准确反映实际情况,因为即使显示为 100%,实际 GPU 利用率也可能不是真正的 100%。要更准确地评估 GPU 利用率,需要关注 TFLOPS 和吞吐率等指标,这些监控在 DeepSpeed 框架中都得以整合。不同的训练框架对同一个模型影响不同
对于同一模型,选择不同的训练框架,对于资源的消耗情况可能存在显著差异(比如使用 Huggingface Transformers 和 DeepSpeed 训练 OPT-30 相对于使用 Alpa 对于资源的消耗会低不少)。环境问题
针对已有的环境进行分布式训练环境搭建时,一定要注意之前环境的 python、pip、virtualenv、setuptools 的版本。不然创建的虚拟环境即使指定对了 Python 版本,也可能会遇到很多安装依赖库的问题(GPU 服务器能够访问外网的情况下,建议使用 Docker 相对来说更方便)。升级 GLIBC 等底层库问题
遇到需要升级 GLIBC 等底层库需要升级的提示时,一定要慎重,不要轻易升级,否则,可能会造成系统宕机或很多命令无法操作等情况。
3 模型大小如何选择?
进行大模型训练时,先使用小规模模型(如:OPT-125m/2.7b)进行尝试,然后再进行大规模模型(如:OPT-13b/30b...)的尝试,便于出现问题时进行排查。目前来看,业界也是基于相对较小规模参数的模型(6B/7B/13B)进行的优化,同时,13B模型经过指令精调之后的模型效果已经能够达到GPT-4的90%的效果。
4 加速卡如何选择?
对于一些国产AI加速卡,目前来说,坑还比较多,如果时间不是非常充裕,还是尽量选择Nvidia的AI加速卡。
【大模型(LLMs)RAG 检索增强生成面】
1 RAG 基础面
1.1 为什么大模型需要外挂 (向量) 知识库?
如何将外部知识注入大模型,最直接的方法:利用外部知识对大模型进行微调。
思路:构建几十万量级的数据,然后利用这些数据对大模型进行微调,以将额外知识注入大模型。
优点:简单粗暴。
缺点:
- 这几十万量级的数据并不能很好地将额外知识注入大模型;
- 训练成本昂贵。不仅需要多卡并行,还需要训练很多天。
既然大模型微调不是将外部知识注入大模型的最优方案,那是否有其它可行方案?
1.2 RAG 思路是怎么样?
- 加载文件
- 读取文本
- 文本分割
- 文本向量化
- 问句向量化
- 在文本向量中匹配出与问句向量最相似的 top k 个
- 匹配出的文本作为上下文和问题一起添加到 prompt 中
- 提交给 LLM 生成回答
1.3 RAG 核心技术是什么?
RAG 核心技术:embedding。
思路:将用户知识库内容经过 embedding 存入向量知识库,然后用户每一次提问也会经过 embedding,利用向量相关性算法(例如余弦算法)找到最匹配的几个知识库片段,将这些知识库片段作为上下文,与用户问题一起作为 prompt 提交给 LLM 回答。
RAG prompt 模板如何构建?
已知信息:
{context}
根据上述已知信息,简洁和专业的来回答用户的问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题” 或 “没有提供足够的相关信息”,不允许在答案中添加编造成分,答案请使用中文。
问题是: {question}
2 RAG 优化面
痛点 1:文档切分粒度不好把控,既担心噪声太多又担心语义信息丢失
问题描述
问题 1:如何让 LLM 简要、准确回答细粒度知识?
用户:2023年我国上半年的国内生产总值是多少?
LLM:根据文档,2023年的国民生产总值是593034亿元。
需求分析:
- 一是简要,不要有其他废话。
- 二是准确,而不是随意编造。
问题 2:如何让 LLM 回答出全面的粗粒度(跨段落)知识?
用户:根据文档内容,征信中心有几点声明?
LLM:根据文档内容,有三点声明,分别是:一、……;二……;三……。
需求分析:
要实现语义级别的分割,而不是简单基于 HTML 或者 PDF 的换行符分割。
笔者发现目前的痛点是文档分割不够准确,导致模型有可能只回答了两点,而实际上是因为向量相似度召回的结果是残缺的。
有人可能会问,那完全可以把切割粒度大一点,比如每10个段落一分。但这样显然不是最优的,因为召回片段太大,噪声也就越多。LLM 本来就有幻觉问题,回答得不会很精准(笔者实测也发现如此)。
所以说,我们的文档切片最好是按照语义切割。
解决方案
思想(原则)
基于 LLM 的文档对话架构分为两部分,先检索,后推理。重心在检索(推荐系统),推理交给 LLM 整合即可。
而检索部分要满足三点:
- 尽可能提高召回率
- 尽可能减少无关信息
- 速度快
将所有的文本组织成二级索引,第一级索引是 [关键信息],第二级是 [原始文本],二者一一映射。
检索部分只对关键信息做 embedding,参与相似度计算,把召回结果映射的原始文本交给 LLM。
主要架构图如下:
如何构建关键信息?
首先从架构图可以看到,句子、段落、文章都要关键信息,如果为了效率考虑,可以不用对句子构建关键信息。
- 文章的切分及关键信息抽取
关键信息:为各语义段的关键信息集合,或者是各个子标题语义扩充之后的集合(PDF多级标题识别及提取见下一篇文章)。
语义切分方法 1:利用 NLP 的篇章分析(discourse parsing)工具,提取出段落之间的主要关系,譬如上述极端情况 2 展示的段落之间就有从属关系。把所有包含主从关系的段落合并成一段。这样对文章切分完之后保证每一段在说同一件事情。
语义切分方法 2:除了 discourse parsing 的工具外,还可以写一个简单算法利用 BERT 等模型来实现语义分割。BERT 等模型在预训练的时候采用了 NSP(next sentence prediction)的训练任务,因此 BERT 完全可以判断两个句子(段落)是否具有语义衔接关系。这里我们可以设置相似度阈值 t,从前往后依次判断相邻两个段落的相似度分数是否大于 t,如果大于则合并,否则断开。当然算法为了效率,可以采用二分法并行判定,模型也不用很大,笔者用 BERT-base-Chinese 在中文场景中就取得了不错的效果。
- 语义段的切分及段落(句子)关键信息抽取
如果向量检索效率很高,获取语义段之后完全可以按照真实段落及句号切分,以缓解细粒度知识点检索时大语块噪声多的场景。当然,关键信息抽取笔者还有其他思路。
方法 1:利用 NLP 中的成分句法分析(Constituency Parsing)工具和命名实体识别(NER)工具提取
- 成分句法分析(Constituency Parsing)工具:可以提取核心部分(名词短语、动词短语等)。
- 命名实体识别(NER)工具:可以提取重要实体(如货币名、人名、企业名等)。
例如:
原始文本:
MM 团队的成员都是精英,核心成员是前谷歌高级产品经理张三,前 Meta 首席技术官李四……
关键信息:
MM 团队、核心成员、张三、李四
方法 2:使用语义角色标注(Semantic Role Labeling)分析句子的谓词论元结构
- 提取“谁对谁做了什么”的信息作为关键信息。
方法 3:直接法
- 关键词提取工作(Keyphrase Extraction)有成熟工具可用。
- HanLP(中文效果好,但付费,免费版调用次数有限)。
- KeyBERT(英文效果好,中文效果差)。
方法 4:垂直领域建议的方法
- 垂直领域的准确度通常较低,可以仿照 ChatLaw 的做法,训练生成关键词的模型(例如 KeyLLM)。
常见问题
句子、语义段之间召回不会有包含关系吗,是否会造成冗余?
- 回答:会造成冗余,但实验证明,细粒度知识和粗粒度(跨段落)知识的准确度比 Longchain 的粗分效果好很多。这个问题可以优化但没必要。
痛点 2:在垂直领域表现不佳
- 模型微调:
- 对 embedding 模型基于垂直领域的数据进行微调。
- 对 LLM 模型基于垂直领域的数据进行微调。
痛点 3:Langchain 内置问答分句效果不佳
- 文档加工:
- 使用更好的文档拆分方式(如项目中集成的达摩院语义识别模型)。
- 改进填充方式,判断中心句上下文的句子是否与中心句相关,仅添加相关度高的句子。
- 文本分段后,对每段分别总结,基于总结内容语义进行匹配。
痛点 4:如何尽可能召回与 query 相关的 Document 问题
- 问题描述:如何通过得到 query 相关性高的 context,尽可能多地召回与 query 相关的 Document。
- 解决方法:
- 在切分文档时,需要考虑 Document 长度、Document embedding 质量以及被召回 Document 数量之间的相互影响。
- 通过 Faiss 做搜索,前提条件是有高质量的文本向量化工具。
- 可以基于本地知识对文本向量化工具进行 Finetune,也可以考虑将 ES 搜索结果与 Faiss 结果相结合。
痛点 5:如何让 LLM 基于 query 和 context 得到高质量的 response
问题描述:如何让 LLM 基于 query 和 context 得到高质量的 response?
解决方法:
- 尝试多个 prompt 模板,选择一个合适的模板。
- 使用与本地知识问答相关的语料,对 LLM 进行 Finetune。
痛点 6:Embedding 模型在表示 Text Chunks 时偏差太大
问题描述:
一些开源的 embedding 模型在处理大文本块(text chunk)时效果较差,尤其当文本块过大时,简单地将其表示为一个向量会导致准确性下降。开源模型的表现通常不如 OpenAI Embeddings。此外,处理多语言问题时,尤其是当查询和生成内容语言不一致时(如中文查询与英文文本块的匹配),也存在对齐问题。解决方法:
- 更小的 text chunk 和更大的 topk:使用较小的文本块来减少噪声,并通过增大 topk 值来提高结果的质量。这种方法可以组合更丰富的上下文来生成更高质量的回答。
- 多语言支持:选择更适合多语言的 embedding 模型来处理不同语言之间的对齐问题。
痛点 7:不同的 Prompt,可能产生完全不同的效果
- 问题描述:
Prompt 在 LLM 中非常关键,不同的提问方式可能会产生完全不同的效果。尤其是指令型 LLM,在训练或微调时,通常会有一个输出模板。没有给出指令数据的情况下,生成结果的格式可能不符合预期,因此需要进行多次尝试,特别是当希望生成的内容符合特定格式时。
痛点 8:LLM 生成效果问题
问题描述:
LLM 本质上是一个“接茬”机器,依赖于上下文来生成下一句内容。但不同的 LLM 在理解上下文和生成内容时差异较大。比如,最初使用 GPT 代理时,生成的内容可读性较强,且能够完全按照给定的格式生成内容,后期省心。转用本地的 LLM(如 llama2-alpaca 和 baichuan2)后,尽管性能较好,但在理解上下文和生成格式时,仍然难以完全达到 GPT 的水平。解决思路:
选择一些优秀的开源模型,如 llama2 和 baichuan2,然后构建领域特定的数据集进行微调,以提高 LLM 的响应质量,使其更符合预期。
痛点 9:如何更高质量地召回 Context 喂给 LLM
问题描述:
初期使用 Langchain 时,发现生成的结果常常与查询无关,回答混乱。后来发现,召回的上下文内容根本与查询没有关系。解决思路:
- 更细粒度的 recall:改进召回方法,通过更加细致的文本分析和处理来提高召回质量。
- 学术内容的提升:对于学术内容,需要使用专门的学术 embedding 模型,改进指令数据,并对 PDF 解析进行更加细致和针对性的优化。
- 参考文献:《PDFTriage: Question Answering over Long, Structured Documents》。
3 RAG 评测面
3.1 为什么需要对 RAG 进行评测?
在探索和优化 RAG(检索增强生成器)的过程中,如何有效评估其性能已经成为关键问题。评测 RAG 可以帮助我们了解系统在不同场景下的表现,优化其各个模块,确保最终生成的答案具备准确性、相关性以及与上下文的一致性。
3.2 RAG 有哪些评估方法?
评估 RAG 的有效性主要有两种方法:独立评估和端到端评估。
独立评估
独立评估包括对检索模块和生成模块的评估。
检索模块:
检索模块评估通常使用以下指标来衡量检索系统(如搜索引擎、推荐系统等)根据查询排名的有效性:- 命中率 (Hit Rate)
- 平均排名倒数 (MRR)
- 归一化折扣累积增益 (NDCG)
- 精确度 (Precision)
生成模块:
生成模块评估关注的是检索到的文档与查询问题的关联度,即上下文相关性。评估指标通常涉及检索到的文档与生成的答案是否一致,生成的答案是否准确、无歧义。
端到端评估
端到端评估侧重对整个 RAG 系统的最终响应进行评估,包括生成的答案与输入查询的相关性和一致性。
无标签的内容评估:
评估标准包括答案的准确性、相关性和无害性。有标签的内容评估:
主要指标包括准确率 (Accuracy) 和精确匹配 (EM)。
3 RAG 有哪些关键指标和能力?
RAG 的评估指标和能力通常集中在以下几个方面:
关键指标:
主要指标包括答案的准确性、答案的相关性和上下文的相关性。关键能力:
研究分析发现,RAG 所需的基本能力包括:- 抗噪声能力:能够应对噪声和不相关信息。
- 拒绝无效回答能力:能拒绝不相关或错误的回答。
- 信息综合能力:能够综合多个信息源生成合理的答案。
- 反事实稳健性:对于不完全或反事实的输入,能够做出合理的推理和回答。
4 RAG 有哪些评估框架?
在 RAG 评估框架中,RAGAS 和 ARES 是较新的方法。
4.1 RAGAS
RAGAS 是一个基于简单手写提示的评估框架,通过这些提示全自动地衡量答案的准确性、相关性和上下文相关性。
- 算法原理:
- 答案忠实度评估:利用大语言模型(LLM)分解答案为多个陈述,检验每个陈述与上下文的一致性,最终计算出“忠实度得分”。
- 答案相关性评估:利用 LLM 创造可能的问题,并分析生成的问题与原始问题的相似度,最终得出答案相关性得分。
- 上下文相关性评估:利用 LLM 筛选出直接与问题相关的句子,并根据这些句子占上下文总句子数量的比例来计算上下文相关性得分。
4.2 ARES
ARES 旨在自动化评价 RAG 系统在上下文相关性、答案忠实度和答案相关性方面的性能。ARES 通过减少评估成本和应用预测驱动推理(PDR)来提高评估的准确性。
- 算法原理:
- 生成合成数据集:ARES 使用语言模型从目标语料库中的文档生成合成问题和答案,创建正负两种样本。
- 训练大语言模型裁判:对轻量级语言模型进行微调,利用合成数据集训练它们以评估上下文相关性、答案忠实度和答案相关性。
- 基于置信区间对 RAG 系统排名:通过使用裁判模型为 RAG 系统打分,结合手动标注的验证集,采用 PPI 方法生成置信区间,从而可靠地评估 RAG 系统的性能。
检索增强生成 (RAG) 优化策略篇
1 RAG 工作流程
RAG 模块的工作流程包括以下几个关键步骤:
- 文档块切分:将文档划分为适当的块,方便后续处理和检索。
- 文本嵌入模型:将文本转化为向量,以便进行高效的检索。
- 提示工程:通过优化提示模板来增强模型的性能。
- 大模型生成:基于检索结果和提示生成最终答案。
2 RAG 各模块的优化策略
文档块切分:
- 设置适当的块间重叠,以保证信息的连续性。
- 使用多粒度文档块切分,可以根据不同粒度的信息进行检索。
- 基于语义的文档切分,确保文档块之间具有语义关联。
- 对文档块进行摘要,减少不相关的信息,提高检索效率。
文本嵌入模型:
- 基于新语料对嵌入模型进行微调,以提高向量表示的质量。
- 实现动态表征,针对不同的查询动态调整向量表示。
提示工程优化:
- 优化模板并增加提示词约束,确保模型更好地理解任务需求。
- 对提示词进行改写,使其更具针对性,提升生成结果的质量。
大模型迭代:
- 基于正反馈微调模型,以持续改进模型性能。
- 进行量化感知训练,以减少计算开销。
- 提供大 context window 的推理模型,扩展模型处理的上下文范围。
文档块集合处理:
- 对 query 召回的文档块集合进行元数据过滤,以提高检索的精确性。
- 对召回的文档块进行重排序,减少无关文档块,提高相关性。
3 RAG 架构优化策略
3.1 如何利用知识图谱(KG)进行上下文增强?
向量数据库增强问题:
- 向量数据库存在无法获取长程关联知识和信息密度低的问题,尤其在 LLM context window 较小时表现不佳。
知识图谱(KG)上下文增强策略:
- 通过向量数据库与知识图谱平行使用,增强上下文信息。
- 通过 NL2Cypher 对用户的 query 进行知识图谱增强,提升对查询的理解和应答质量。
优化策略:
- 常用的图采样技术可以提升知识图谱的上下文增强效果。
- 根据 query 抽取实体,利用实体作为种子节点进行图采样。必要时,可将 KG 中节点和 query 中实体向量化,通过相似度选择种子节点。
- 将采样得到的子图转化为文本片段,以增强上下文。
3.2 Self-RAG:如何让大模型对召回结果进行筛选?
经典 RAG 架构问题:
- 在经典的 RAG 架构中(包括使用知识图谱进行上下文增强),召回的上下文与 query 直接合并,有时召回的内容可能与 query 无关或矛盾,尤其在上下文窗口较小的情况下(例如 4k 的窗口)。
Self-RAG 解决方案:
- Self-RAG 是一种更主动、智能的筛选方式。其主要步骤如下:
- 判断是否需要额外检索事实性信息:仅在有需要时才进行检索(retrieve on demand)。
- 平行处理每个片段:为每个片段生成一个 prompt 和生成结果。
- 使用反思字段:检查生成结果与上下文的相关性,选择最符合要求的片段。
- 再检索:根据需要再次进行检索,确保结果的准确性。
- 生成结果引用相关片段:生成的答案会引用相关片段,并提供结果与片段的验证,以便检查事实的准确性。
- Self-RAG 是一种更主动、智能的筛选方式。其主要步骤如下:
3.3 多向量检索器多模态 RAG 篇
多向量检索器 (Multi-Vector Retriever)
多向量检索器的核心思想是将文档(用于答案合成)和引用(用于检索)分离,这样可以针对不同的数据类型生成适合自然语言检索的摘要,同时保留原始的数据内容。它可以与多模态 LLM 结合,实现跨模态的 RAG。
3.3.1 如何让 RAG 支持半结构化 RAG(文本 + 表格)?
在处理文本和表格数据时,RAG 可以采用以下核心流程:
文档版面分析:
- 使用 Unstructured 工具 对原始文档进行分析,提取出原始文本和原始表格。
文本与表格摘要:
- 通过 summary LLM 处理原始文本和表格,分别生成文本摘要(text summary)和表格摘要(table summary)。
向量化文本和表格摘要:
- 将文本摘要和表格摘要通过同一个 embedding 模型 向量化,并存入 多向量检索器。
存储摘要和原始数据:
- 在多向量检索器中,除了存储文本和表格的 embedding,还存储它们的摘要和原始数据(raw data)。
用户查询向量化:
- 将用户的查询(query)进行向量化,然后使用 ANN(近似最近邻)检索方法,召回原始文本和原始表格。
构造完整的 Prompt:
- 根据 query + raw text + raw table 组合,构造出完整的 prompt,供 LLM 生成最终的答案。
3.3.2 如何让 RAG 支持多模态 RAG(文本 + 表格 + 图片)?
在支持多模态数据(文本、表格、图片)的 RAG 中,流程可以扩展如下:
文档版面分析:
- 同样使用 Unstructured 工具 进行分析,将文档中包括的文本、表格和图片分离提取。
生成文本和表格摘要:
- 对提取的文本和表格使用 summary LLM 生成对应的摘要。
图像内容处理:
- 对图像内容进行分析,生成图像的特征向量。可以使用专门的视觉模型(如 CLIP 或其他多模态模型)来将图像转化为嵌入(embedding)。
向量化文本、表格和图片:
- 将文本摘要、表格摘要和图像特征通过适合的 embedding 模型 向量化,并存储到多向量检索器中。
存储摘要、原始数据和图像特征:
- 在多向量检索器中,不仅存储文本和表格的 embedding,还包括图像的特征向量和原始数据(raw data)。
用户查询处理:
- 对用户的查询进行向量化,并使用 ANN 检索方法同时召回文本、表格和图像数据。
构造完整的多模态 Prompt:
- 根据 query + raw text + raw table + image features 组合,构造出多模态的 prompt,并通过 LLM 生成最终的答案,确保结合所有数据类型进行生成。
3.3.3 如何让 RAG 支持私有化多模态 RAG(文本 + 表格 + 图片)?
如果数据安全是重要考量,可以选择将 RAG 流水线进行本地部署。具体方法包括使用以下工具和技术栈:
- LLaVA-7b:用于生成图片摘要。
- Chroma:作为向量数据库。
- Nomic's GPT4All:作为开源嵌入模型。
- 多向量检索器:用于高效的文本和数据检索。
- Ollama.ai 中的 LLaMA2-13b-chat:用于生成应答。
通过这些工具,RAG 系统可以在本地部署,确保数据的安全性,并且仍能保持高效的多模态处理能力。
3.4 RAG Fusion 优化策略
思路
RAG Fusion 技术的核心原理是,接收到用户的查询后,大模型首先生成 5-10 个相似的查询。然后,每个查询都去匹配 5-10 个相关的文本块。对这些返回的文本块进行倒序融合排序,必要时进行精排,最后将 Top K 个文本块拼接到 prompt 中,供生成模型使用。
优点
- 增加相关文本块的召回率。
- 对用户查询自动进行文本纠错和分解长句等功能。
缺点
- 无法从根本上解决理解用户意图的问题。
3.5 模块化 RAG 优化策略
动机
模块化 RAG 优化策略旨在突破传统的“原始 RAG”框架,该框架主要包括索引、检索和生成模块。通过模块化,系统能提供更广泛的多样性和更高的灵活性。
模块介绍
搜索模块:
- 融合了直接在附加的语料库中进行搜索的方法。这些方法包括通过大语言模型(LLM)生成的代码、SQL、Cypher 等查询语言,或者其他定制工具。数据源多样,涵盖搜索引擎、文本数据、表格数据或知识图谱等。
记忆模块:
- 充分利用大语言模型本身的记忆功能,引导信息检索。其核心原则是寻找与当前输入最为匹配的记忆,这种增强的生成模型能够利用自身输出来自我提升,使推理过程中生成的文本更贴近数据分布。
额外生成模块:
- 面对检索内容中的冗余和噪声问题,通过大语言模型生成必要的上下文,而不是直接从数据源检索。由大语言模型生成的内容更可能包含与检索任务相关的信息。
任务适应模块:
- 致力于将 RAG 调整以适应不同的下游任务需求。
对齐模块:
- 在 RAG 应用中,查询与文本的对齐是影响效果的关键因素。研究发现,在检索器中添加可训练的 Adapter 模块能有效解决对齐问题,从而提升 RAG 系统的整体表现。
验证模块:
- 由于我们无法总是保证检索到的信息的可靠性,可能会检索到不相关或不准确的数据。这时,可以在检索文档后加入验证模块,评估检索文档与查询的相关性,以提升 RAG 的鲁棒性和可靠性。
3.6 RAG 新模式优化策略
RAG 的组织方法具有高度灵活性,能够根据特定问题的上下文,对 RAG 流程中的模块进行替换或重新配置。在基础的 Naive RAG 中,包含了检索和生成两个核心模块,该框架具备了高度的适应性和多样性。当前研究主要围绕两种组织模式:
增加或替换模块
在增加或替换模块的策略中,保留了原有的检索-阅读结构,同时引入新模块以增强特定功能。例如,RRR 提出了一种重写-检索-阅读的流程,其中利用大语言模型(LLM)的性能作为强化学习中的重写模块奖励机制。通过这种方式,重写模块可以调整检索查询,从而提高阅读器在后续任务中的表现。
调整模块间的工作流程
在调整模块间工作流程的模式下,重点加强语言模型与检索模型之间的互动,以提高整体系统的表现。
3.7 RAG 结合 SFT
RA-DIT 方法策略:
- 更新 LLM:以最大限度地提高在给定检索增强指令的情况下,模型返回正确答案的概率。
- 更新检索器:以最大限度地减少文档与查询在语义上的相似度,从而提高检索质量。
优点:
通过这种方式,LLM 能更好地利用相关背景知识,并能够在检索到错误块时依然生成准确的预测。这使得模型能够依赖自己的知识并在不完美的检索条件下依然保持较好的性能。
3.8 查询转换(Query Transformations)
动机
在某些情况下,用户的查询可能会出现表述不清、需求复杂或内容无关等问题。查询转换(Query Transformations)利用了大型语言模型(LLM)的强大能力,通过提示或方法将原始的用户问题转换或重写为更合适的查询,从而能够更准确地返回所需结果。
核心思想
用户的原始查询可能并非最适合检索的,因此需要某种方式来改进或扩展它。查询转换利用 LLM 的能力确保转换后的查询更有可能从文档或数据中获取相关和准确的答案。
3.9 Bert 在 RAG 中的作用
在 RAG 中,BERT 主要应用于一些传统任务(例如分类、抽取等)。与生成式任务(如改写、摘要等)相比,使用 BERT 可以提高效率。尽管这可能牺牲一些效果,但考虑到推理时间的要求,牺牲的效果是可以接受的。
BERT 与 LLMs 的比较:
BERT:
- 支持的最大窗口为 512 个字符,对于生成任务如改写或摘要来说,这远远不够。
- 在传统任务中,BERT 提供了更高效的解决方案。
LLMs:
- 在生成任务中,LLMs 的能力比 BERT 强得多。由于 LLMs 支持更大的上下文窗口和更强的生成能力,因此对于生成式任务,LLMs 是不可或缺的。
- 在这种情况下,时间换取性能显得尤为重要。
4 RAG 索引优化策略
4.1 嵌入优化策略
微调嵌入
- 影响因素:影响 RAG 的有效性。
- 目的:提高检索到的内容与查询之间的相关性。
- 作用:类似于在语音生成前对“听觉”进行调整,优化检索内容对最终输出的影响。在专业领域,尤其是涉及变化频繁或罕见术语时,定制化嵌入能显著提高检索相关性。
动态嵌入(Dynamic Embedding)
- 介绍:与静态嵌入(static embedding)不同,动态嵌入根据单词出现的上下文进行调整,为每个单词提供不同的向量表示。例如,在 Transformer 模型(如 BERT)中,同一单词根据其上下文会有不同的向量表示。
检索后处理流程
- 动机:
- 向大语言模型展示所有相关文档可能会超出其处理的上下文窗口限制。
- 将多个文档拼接成一个冗长的检索提示会引入噪声,降低大语言模型聚焦关键信息的能力。
- 优化方法:
- ReRank(重新排序)
- Prompt 压缩
- RAG 管道优化
- 混合搜索的探索
- 递归检索与查询引擎
- StepBack-prompt 方法
- 子查询
- HyDE 方法
- 动机:
4.2 RAG 检索召回率低的解决方案
如果尝试过不同大小的 chunk 和混合检索仍效果不佳,可以按照以下方法进行排查和优化:
知识库覆盖问题:
- 检查是否有对应答案:如果知识库本身没有相关答案,显然是知识库覆盖不全的问题。
知识库有对应答案,但没有召回:
- 分析分割问题:检查是否因为知识库中的内容被错误地分割,导致无法准确召回。可以尝试修改分割策略或使用 BERT 进行上下句预测,确保知识点的完整性。
- 分析查询和文档的匹配问题:
- 字面相关 vs 语义相关:通常建议先使用 Elasticsearch (ES) 进行召回,然后再用模型进行精排。这样可以有效提高召回的准确性。
4.3 RAG 如何优化索引结构?
在构建 RAG 时,块大小是一个关键参数,决定了从向量存储中检索的文档的长度。
- 小块:可能导致关键信息缺失。
- 大块:可能引入无关的噪音。
找到最佳块大小需要平衡,且通常采用试错法来优化。重要的是,这并非随机猜测,而是通过在测试集上运行评估并计算相关指标来找到最佳块大小。
工具如 LlamaIndex 提供了帮助,可以通过它的功能优化块大小。更多信息可以通过其博客了解。
4.4 如何通过混合检索提升 RAG 效果?
尽管向量搜索能有效检索与查询相关的语义块,但在某些用例中,尤其是在需要精确匹配关键词时,向量搜索可能不够精确。
混合检索 结合了向量搜索和关键词搜索的优势,允许在检索时同时匹配相关语义块和特定关键词。例如,搜索一个包含数百万电子商务产品的矢量数据库时,某些特定的查询,如“阿迪达斯参考 XYZ 运动鞋白色”,可能需要混合检索来精确匹配“XYZ”参考。
通过这种方法,可以保持对查询意图的控制,同时提高关键词匹配的精度。
4.5 如何通过重新排名提升 RAG 效果?
在 RAG 系统中,向量存储的前 K 个结果并不总是按最相关的方式排序。虽然所有检索到的块都是相关的,但最相关的块可能位于第 5 或第 7 个位置,而非第 1 或第 2 个。
重新排名 的概念是通过一种策略将最相关的文档重新排序,以确保它们出现在合适的位置。常见的重新排名方法包括:
- Diversity Ranker:根据文档的多样性重新排序。
- LostInTheMiddleRanker:将最佳文档交替放置在上下文窗口的开始和结束之间。
这些方法已在多个框架中成功实现,如 LlamaIndex、LangChain 和 HayStack,可以有效提升 RAG 的检索效果。
5.1 RAG 如何提升索引数据的质量?
要提升 RAG 答案的质量,首先要确保数据质量。以下是一些提升数据质量的策略:
- 删除重复和冗余信息:避免存储多次出现的内容。
- 识别不相关的文档:确保索引中的文档与查询相关。
- 检查事实准确性:确保索引数据的准确性。
- 清理文本噪音:删除特殊字符、奇怪的编码、不必要的 HTML 标签等。
- 数据整理:使用正则表达式和旧的 NLP 技术清理文本,删除与主题无关的文档。
- 数据降维与主题提取:利用主题提取、降维技术和数据可视化找出无关文档。
- 冗余文档删除:通过相似性度量去除冗余文档。
清理数据是构建 RAG 时的重要步骤,经常被忽视,因此要特别关注。
5.2 如何通过添加元数据提升 RAG 效果?
将元数据与索引向量结合使用可以显著提升搜索相关性。例如:
- 时间排序:如果时间是查询的关键维度,可以根据日期元数据进行排序。
- 特定部分过滤:在科学论文中,若信息通常位于特定部分(如实验部分),可将这些部分添加为元数据并进行过滤。
- 元数据为向量搜索增加了结构化搜索层次,使检索更精确。
5.3 如何通过输入查询与文档对齐提升 RAG 效果?
通过将查询与文档对齐,可以提高检索结果的准确性。例如,在查询“你能简要介绍一下马达引擎的工作原理吗?”时,输入的查询与段落的相似性为 0.72。如果通过“段落回答的问题”索引文档,则每个问题的相似性分别为 0.864、0.841 和 0.845,显著提高了对齐度和相关性。
这种方法通过优化与问题的相似性,而不是直接优化与文档的相似性,提升了检索精度。
5.4 如何通过提示压缩提升 RAG 效果?
在 RAG 中,检索上下文中的噪声可能会影响答案的质量。为此,可以在检索后进行后处理,以压缩无关的上下文并突出关键信息。方法包括:
- 选择性上下文:只选择与任务相关的上下文。
- LLMLingua:使用小型 LLM 计算即时互信息或困惑度,以估计元素的重要性。
这种方法有助于减少总体上下文长度,提高最终生成的答案质量。
5.5 如何通过查询重写和扩展提升 RAG 效果?
在用户与 RAG 交互时,查询可能不足以获得最佳回答,或者无法有效匹配向量存储中的文档。为解决此问题,可以在查询传递给 RAG 之前使用 LLM 对查询进行重写或扩展。这种方法能够通过生成更具表达力的查询来提高匹配精度。
这种重写过程可以通过中间 LLM 调用实现,并参考相关论文,如《Query Expansion by Prompting Large Language Models》。
6.1 RAG 的垂直优化
RAG 技术虽然在过去一年取得了显著进展,但在垂直领域仍有一些关键问题需要深入探讨:
- RAG 中长上下文的处理问题:如何有效地处理较长的上下文仍是一个挑战。
- RAG 的鲁棒性研究:提高 RAG 在复杂环境下的鲁棒性,确保其稳定性和可靠性。
- RAG 与微调的协同作用:探讨 RAG 与微调方法的结合,以便在特定任务中更好地发挥作用。
- RAG 的工程应用:在工程实践中,如何在大规模知识库场景中提高检索效率和文档召回率,同时保障数据安全(如防止 LLM 被诱导泄露敏感信息)是亟待解决的难题。
6.2 RAG 的水平扩展
RAG 的研究和应用已从最初的文本问答扩展到多个领域,涵盖了更多模态数据的处理:
- 图像、代码、结构化知识、音视频等:RAG 已经开始应用于这些多模态数据处理任务,拓展了其应用的广度。
6.3 RAG 生态系统
RAG 的生态系统涉及下游任务和评估体系,以下是几个重点方向:
下游任务:RAG 在开放式问题回答、事实验证等任务中的表现已经显示出其在多领域应用中的潜力。尤其在医学、法律和教育等领域,RAG 可能相比微调方法提供更低的训练成本和更优的性能。
评估体系:需要为不同的下游任务开发更精准的评估指标和框架,如上下文相关性、内容创新性和无害性等,以优化模型在特定任务中的效率和效益。
可解释性:增强 RAG 模型的可解释性,帮助用户理解模型如何以及为何做出特定响应。
技术栈
RAG 的技术栈在不断发展,并且推动了 RAG 技术的进步:
- LangChain 和 LlamaIndex:这两款技术栈成为了 RAG 相关应用的关键工具,提供了丰富的 API 支持。
- 新兴技术栈:新技术如 Flowise AI、HayStack、Meltno 和 Cohere Coral 等正在崛起,提供不同的特色和功能,尤其 Flowise AI 注重低代码操作,让用户可以通过简单的拖拽实现 RAG 应用。
技术栈的不断发展促进了 RAG 的进步,同时,新技术的出现也在不断提出更高的要求,推动技术栈的优化和更新。目前,RAG 工具链已经初步建立,许多企业级应用逐步出现,但全面的一体化平台仍在不断完善中。