自然语言处理 期末复习

发布时间 2024-01-09 01:58:07作者: 阿来阿来

一、概述

1. 基于深度学习的命名实体识别系统一般由哪三个层次组成?

嵌入层,编码层,解码层

2. 三种词义消歧的方法?

简单最近邻,基于特征的词义消歧,Lesk算法

3. 语篇的局部连贯性表现在哪三个方面?

关系连贯,实体连贯,主题连贯

4. 信息抽取有哪几个主要任务?

命名实体识别,关系抽取,事件抽取

5.自然语言处理:使计算机可理解,解释生成处理人类语言

6.分词:目标是将连续的自然语言文本准确地切分为各个的适当词语单元

歧义切分

未登录词识别:识别文本中没出现在预定义词典或训练语料库中的词语

自动分词方法:最大匹配法,基于语言模型的分词方法

自动分词应用:信息检索,机器翻译,文本分类

7.命名实体识别:识别和提取文本中的特定类别的命名实体,此任务核心是把非结构化数据结构化

方法(1)基于规则的方法 (2)基于统计的方法 (3)基于深度学习的方法

8.词性标注:为给定句子中的每个单词分配一个适当的词性检索,明确其在句子中的角色

9.句法分析:通过对句子的语法结构进行分析,确定句子中各个词语之间的语法关系,进而推断句子的含义

结构歧义问题:附着歧义,并列歧义

  1. 短语结构分析:确定句子中各个短语之间的语法结构和组织,将他们组织成短语和从属关系树
  2. 依存句法分析:分析词汇之间的句法结构,常见的依存关系:从属关系和修饰关系。

10.语义分析:对句子所表达的语义进行分析和解释,帮助计算机理解文本实体之间的关系

11.篇章分析:(1)连贯性分析:关系连贯、实体连贯、主题连贯 (2)指代消解(1)回指消解 (2)预指消解

12.NLP应用:机器翻译、文本分类、信息提取、自动文摘、信息检索、对话系统

13.挑战:歧义和多样性、语法多样性、数据稀疏性、语言不断变化、语言和文化差异

二、语言模型基础

1.词向量

  • 定义:单个词汇的向量化表示
  • 独热表示(One-Hot representation)是一种将词汇映射为向量的方法。在该表示法中,每个词被映射为唯一的向量,其维度等于词汇表的大小。在该向量中,只有一个元素的值为1,而其他元素的值都为0。这个唯一的1的位置代表了当前的词。
  • 独热表示方法存在两个主要的问题:维数灾难和词汇鸿沟。
  • 分布式表示:其能够有效地捕捉词汇之间的语义和上下文关系,使得语义上相似的词在向量空间中位置接近。分布式表示的核心思想是通过训练将每个词汇映射到固定长度的实数向量。这些向量的长度通常比独热向量小得多。这些向量一起构成了一个词向量空间,其中的每个向量可以看作是空间中的一个点。在这个空间中,我们可以通过计算向量之间的距离来衡量词汇之间的语义相似性。

2. Word2Vec:输入层,输出层,隐藏层

  • 该算法通过大规模文本语料库的神经网络模型学习单词之间的关联性,并采用分布式词表示(Distributed Representation)来构造词向量(Word Vector)。
  • 连续词袋模型(CBOW):过使用上下文单词来预测目标单词,训练速度通常较快。
  • 连续跳字模型(Skip-gram):使用目标单词来预测其上下文,特别适用于处理稀有词。
  • CBOW模型细节:

输入层:接受单词上下文内的2c个词作为输入。每个词都使用词向量表示。

隐藏层:词向量求和值

输出层:这层是一个Huffman树,每个叶子结点对应一个词汇,非叶子结点用于计算路径概率。

  • Skip-gram模型:

输入层:接受单词的词向量

隐藏层:恒等投影

输出层:也是一颗Huffman树

损失函数是C个词的损失函数之和

三、统计语言模型

1.N-gram

  • N元文法(N-gram)是自然语言处理中的一种统计模型,用于捕获文本中的词序列的概率特性。它通过在文本上应用大小为N的滑动窗口,并以词元(token)(通常定义为词语)为单位进行划分,从而产生长度为N的词元序列,这些序列称为gram。在N-gram模型的假设下,第N个词元出现的概率仅与其前N−1个词元有关。因此,一个句子的概率是由其组成的各词元的概率乘积得到的。这些概率是基于语料库中N个连续词元的共现次数计算的。简而言之,当一个句子中的词的出现概率受其前N−1个词的影响时,这种模型就被称为N元文法统计模型(N-gram Language Model, N-gram)。
  • N-gram模型应用:音字转换问题、汉语分词问题
  • 平滑:加一平滑(拉普拉斯平滑)、加K平滑(可以进行选择,调整)、古德-图灵平滑(对低频事件进行重新估计)、插值平滑、回退平滑、绝对减值平滑(有利于处理稀疏数据)

2. 什么是语言模型?它的根本目标是什么?

语言模型是一种用于预测文本序列的统计模型。它的根本目标是基于给定的前缀(一个或多个词),预测下一个可能的词或者文本序列。

语言模型可以用于各种自然语言处理任务,包括机器翻译、文本生成、语音识别、拼写纠错等。通过学习大量的文本数据,语言模型可以捕捉到词与词之间的关系、语法结构和上下文信息,从而能够生成具有语言流畅度的文本。

语言模型的根本目标是提高语言理解和生成的准确性和流畅度。通过训练模型来预测下一个词或文本序列,可以帮助改善人机交互、信息检索、智能对话等应用,提供更加自然、准确和人性化的语言处理能力。

四、神经语言模型

1.循环神经网络(RNN)

循环神经网络(Recurrent Neural Networks,RNNs)是一种专为处理序列数据而设计的神经网络架构。与传统的前馈神经网络不同,RNNs具有在时间维度上传递信息的能力,使其能够捕获时间序列中的依赖关系。这种网络结构在每个时间步都会接受新的输入,并将该信息与历史数据融合以生成新的输出,因此特别适用于时间序列分析和预测。

RNN三种模式:

N v N: 词性标注、命名实体识别、机器翻译、视频帧预测。

1 v N: 图像描述、音频转录、文本生成

N v 1: 情感分析、文档分类、异常检测、音频终止点检测

五、预训练语言模型

1.Seq2Seq结构

  • Seq2Seq结构主要由编码器和解码器组成
  • 编码器:编码器负责读取输入序列(例如一个句子)并将其转换为一个固定长度的上下文向量。转换过程通过循环神经网络来实现,以捕获输入序列中的长期依赖关系。当输入序列完整地传递到RNN层后,最终的隐藏状态被认为是代表整个输入序列的上下文向量。该上下文向量含有关于输入序列的全部必要信息,并被传递给解码器,以便生成输出序列。
  • 解码器:解码器接收编码器输出的上下文向量并使用它来生成输出序列。解码器也是一个RNN,其初始隐藏状态由编码器的上下文向量设定。在每个时间步,解码器预测输出序列的下一个元素,并将此预测作为下一时间步的输入。通过不断生成新的输出元素,解码器逐步构建出完整的输出序列。这种方式使得解码器能够根据上下文信息和历史预测生成连贯的输出序列。
  • Teacher Forcing:它是一种网络训练方法,对于开发用于机器翻译,文本摘要,图像字幕的深度学习语言模型以及许多其他应用程序至关重要。它每次不使用上一个state的输出作为下一个state的输入,而是直接使用训练数据的标准答案(ground truth)的对应上一项作为下一个state的输入。
  • Beam Search:Beam Search 方法在测试阶段发挥作用而非训练阶段。在每一个时间步,解码器会生成若干个备选输出,然后使用Beam Search方法从中选择概率最大的top k 个输出作为候选输出。接下来,这些候选输出会分别与当前隐藏状态和编码器的上下文向量一起传递到下一个时间步,生成新的备选输出。这个过程不断重复直到输出序列达到最大长度或者出现特殊标记(例如结束标记)。最终,从所有的候选输出中选择概率最大的输出作为解码器的最终输出。

2.Attention机制

  • 引入的原因:之前的模型在处理复杂序列和高维输入时,常常面临长距离依赖和信息损失的问题。
  • 注意力(Attention)机制的核心思想是从全局信息中筛选出局部的、关键性的信息以进行更高效的处理。这一概念与其名称有着直接的联系,即“从关注全部到关注重点”。
  • 优势:1、高计算效率 2、并行计算能力 3、优秀的长距离依赖捕捉能力
  • 步骤:1、query和key进行相似度计算,得到分数 2、将分数归一化 3、使用加权分数对value加权求和。
  • 在翻译模型中:逐词使用注意力机制,每次使用每个词在RNN的隐藏状态和已经翻译完毕句子的隐藏状态计算注意力。

3.Transformer模型

  • 输入表示和嵌入:获取输入句子中每个单词的表示向量X。该向量是单词的嵌入(Embedding)和位置嵌入(Positional Embedding)的和。其中,单词嵌入是一种将单词映射到高维空间的技术,可以通过预训练算法如Word2vec等得到,可以捕捉单词之间的语义关系。位置嵌入:提供序列中的单词的位置信息。
  • 编码器:顺序转换和上下文编码

编码器(Encoder)接收单词表示向量矩阵X作为输入,其中每一行对应于输入句子中一个单词的表示x。经过六个编码器模块(Encoder block)后,生成一个上下文编码信息矩阵C。在这里,单词向量矩阵X具有n×d的维度,其中n是句子中的单词数量,d是表示向量的维度(在原始论文中,d=512)。每一个编码器模块都保持其输入和输出矩阵的维度一致,这有助于模型的深度学习能力。

  • 解码器:上下文感知翻译与遮盖

第三步是解码器(Decoder)接收编码器输出的编码信息矩阵C。解码器根据已经翻译过的单词逐个翻译目标语言。首先,解码器接收一个翻译开始符"<Begin>",并预测第一个单词"I"。然后,它接收"<Begin>"和"I"作为输入,预测下一个单词"have",以此类推。

  • 遮盖机制:隐藏尚未被翻译的单词,确保模型只使用适当的上下文信息进行每次预测。
  • Self-Attention的内部结构

在计算过程中,需要用到三个矩阵:Q(查询)、K(键值)和V(值)。在实际应用中,Self-Attention接收的输入是矩阵X,该矩阵由单词的表示向量x组成,或者是上一个Encoder block的输出。矩阵Q、K和V是通过对Self-Attention的输入X进行线性变换而得到的。

Q,K,V通过X右乘三个线性变换矩阵得到

计算Self-Attention时,为了防止内积过大,也可以除以根号下向量的维数。

  • Multi-Head Attention:由多个Self-Attention组成。在最后把多个Self-Attention输出结果拼起来,然后接一个线性层,得到和单个一样的输出。
  • Encoder结构:该结构由Multi-Head Attention, Add & Norm, Feed Forward, Add & Norm四个部分组成。

公式:LayerNorm(X + MultiHeadAttention(X)/FeedForward(X))

Add部分:残差链接,防止网络退化,允许网络只关注当前的差异部分。

Norm部分:将输入转换为具有相同均值和方差的形式,加速网络的收敛。

Feedforward层:包含两层全连接层,每次线性变换之后引入ReLU函数,公式FFN(x) = max(0,xW1+b)W2+b2

  • Decoder结构:
  1. 第一个Multi-Head Attention,使用Masked操作,具体的,每次只有不被mask的加权和为1。
  2. Add-Norm
  3. 第二个Multi-Head Attention,其K,V通过Encoder的编码矩阵计算,Q通过第一个Multi-Head Attention的输出计算得到。
  4. Add-Norm
  5. FeedForward
  6. Add-Norm
  • 总结:
  1. Transformer与RNN不同,可以更好的并行训练。
  2. 其本身无法利用单词的顺序信息,需要加入位置Embedding,否则Transformer就是一个词袋模型了
  3. 重点是Self-Attention结构,其中用到的Q,K,V通过线性变化矩阵得到
  4. Multi-Head-Attention可以捕捉单词之间在多种维度上的相关系数Attention score。

4.BERT模型:由Google 提出,双向语言建模

  • 训练过程:预训练,微调训练。
  • 在预训练阶段,BERT模型通过在大量未标注的文本数据上进行训练,旨在学习文本之间的深层次关系和模式。具体来说,BERT采用了两种训练策略:遮挡语言模型(Masked Language Model, MLM)和下一个句子预测(Next Sentence Prediction, NSP)。通过这两种策略,BERT能够有效地捕捉文本中的上下文信息。一旦完成预训练,BERT模型将获得通用的语言表示。
  • 微调训练阶段是在预训练的BERT模型基础上进行的,针对特定任务进行训练。在这个阶段,使用带有标签的数据,例如情感分析或命名实体识别数据。通过将特定任务的数据加载到预训练模型上进行微调,BERT可以在各种下游任务中取得令人满意的效果。
  • 遮挡语言任务,又被称为Cloze任务。在此任务中,选取的输入文本中的部分词元会被随机掩码,即使用特定的[MASK]词元进行替代。随后,模型会尝试预测这些被掩码的词元。(每个词语有15%概率被随机进行掩码操作)被选中之后,有80%概率将其直接替换为[Mask],10%被替换为其他单词,10%不做改变。原因:如果一个词元总是被Mask,那么在微调阶段,就欠拟合;引入随机词元:维持对每个输入词元的分布式表示,避免死记硬背。
  • 下一句预测任务:选取两句话,判断是否是下文。
  • BERT的输入:词元输入,段落嵌入,位置嵌入。
  • 微调训练的任务:基于句子对的分类任务,基于单个句子的分类任务,问答任务,命名实体识别

5.GPT-1:OpenAI

  • 由12层Decoder构成,其中只保留了第一个Multi-Head Attention(Masked)。
  • 单向语言建模

6.讨论Beam Search算法的应用:

  • 机器翻译:在机器翻译任务中,Beam Search可以帮助选择最佳的翻译结果。它能够在生成句子的过程中考虑上下文信息,并通过选择得分最高的候选解来提高翻译的质量。然而,由于Beam Search只保留了一部分候选解,可能会导致搜索空间的局部最优问题。为了解决这个问题,可以通过增加beam的大小来扩大搜索空间,但这也会增加计算量。
  • 语音识别:在语音识别任务中,Beam Search可用于选择最佳的转录结果。它可以在生成单词序列的过程中考虑语音信号的特征,并根据模型的得分来选择最佳的转录结果。然而,Beam Search在语音识别中也面临搜索空间的问题。由于候选解的数量是有限的,可能会导致错过一些潜在的正确结果。因此,在语音识别中,通常需要结合其他技术(如语言模型)来进一步提高准确性。

六、大语言模型架构

1. 基于 Transformer 的模型架构

Transformer 模型演变为三种主要架构:编码预训练语言模型(Encoder-only Pre-trained Models)、解码预训练语言模型(Decoder-only Pre-trained Models)及编解码预训练语言模型(Encoder-decoder Pretrained Models)

2.GPT-2:使用了零样本学习的策略,仅通过预训练达到优秀的效果,无须额外的微调步骤。在预训练阶段,GPT-2采用了一个名为WebText的数据集。该数据集覆盖了多个领域并经过简单处理。为了进一步提升其泛化能力,模型采用了多任务学习策略。多任务学习是一种策略,其中模型被设计为同时学习多个相关的任务,这有助于模型获得更丰富和多样化的知识。同时接受多种文本处理任务的训练,这些任务共享模型的核心参数。(本质上是一个自回归模型)

  • 小型版(117M):12层Decoder,768维的嵌入层。
  • 中型版(345M):24层Decoder,1024维的嵌入层。
  • 大型版(774M):36层Decoder,1280维的嵌入层。
  • 超大型版(1.5B):48层Decoder,1600维的嵌入层。

3.其他基于解码器的模型:

  • LLaMA(Meta AI):主要的创新点:预标准化、开关门控线性单元SwiGLU,旋转位置嵌入
  • LAMDA:Google研发,旨在解决对话应用中特有的两个核心问题:安全性和信息的准确性。
  • GLM:清华大学,使用了一种改进的自回归空白填充方法,GLM通过引入二维位置编码和支持任意顺序的空白预测,提升了预训练的效果,在多数NLU任务上相对于BERT和T5显示了性能提升。此外,GLM具有灵活性,能通过调整空白的数量和长度来针对不同任务进行预训练。

4.在预训练自然语言处理模型的领域内,有三种架构:自回归模型(基于Decoder):擅长文本生成和少样本学习,在自然语言理解上表现不佳,自编码模型(基于Encoder),擅长自然语言理解,难以捕捉词间依赖关系,序列到序列模型(Encoder-Decoder),在不同任务之间的优点难以融合。

5.T5模型:Google提出,通过一个统一的文本到文本框架处理各种自然语言处理任务。

预训练阶段策略:1、masking方法 2、小段替换法,将一小段连续的的token替换为单一的特殊标记 3、Drop法,选定的tokens会被随机删除

在微调T5模型时,策略:1、适配器层(大部分模型参数保持不变,在transformer每个前馈神经网络之后,添加额外的密集-ReLU-密集块,仅适配器层和层归一化进行权重更新)2、逐步解冻:随着时间的推移,逐渐解锁更多的模型参数进行微调。

七、多模态大模型架构

1.CLIP:2021年OpenAI提出

2. CLIP是Contrastive Language-Image Pre-training的缩写,是一种基于对比学习的多模态模型。CLIP的训练数据是文本-图像对,即一张图像和对应的文本描述。通过对比学习,模型学习到文本-图像对的匹配关系。CLIP包括两个模型:Text Encoder和Image Encoder。Text Encoder用于提取文本特征,可以采用NLP中常用的text transformer模型;而Image Encoder用于提取图像特征,可以采用常用的CNN模型(ResNet50)或者vision transformer。

训练:最大化对角线元素,最小化非对角线元素。

3.CLIP实现zero-shot分类:CLIP与传统的计算机视觉(CV)模型不同,它具有直接实现zero-shot图像分类的能力。这意味着它可以在某个特定的任务上实现分类,而无需任何训练数据,这是CLIP的独特之处。使用CLIP进行zero-shot分类非常简单,只需两步:1.针对任务的各个分类标签构建描述性文本,例如:"一个标签的照片",将这些文本送入Text Encoder(文本编码器)得到相应的文本特征。如果类别数目为N,那么就会得到N个文本特征。2.将要预测的图像送入ImageEncoder(图像编码器)得到图像特征,然后与N个文本特征计算缩放的余弦相似度(与训练过程一致)。接着,选择相似度最大的文本对应的类别作为图像分类的预测结果。进一步地,可以将这些相似度看成logits(逻辑回归的输入),送入softmax 后可以得到每个类别的预测概率。

4.CLIP其他应用

  • Zero-shot检测,检测训练数据中没有出现过的类别
  • 图像检索:利用文本搜素图像
  • 视频理解:扩展到文本-视频,如VideoCLIP
  • 文本引导的图像编辑
  • 文本引导的图像生成
  • 自监督学习

八、大模型预训练

1.大模型预训练的两个问题:数据源、分布式预训练。

2.数据源:数据的质量和多样性直接影响模型的性能和泛化能力。为了获取更全面的数据分布,有时需要聚合多个子数据集,带来了数据冗余和不平衡问题。(预训练语料库的质量和规模、数据预处理的策略和方法)

3.分布式预训练:可以通过数据并行、模型并行或者混合并行多种方式实现。(语言建模和去噪自编码)

4.预训练语料库主要分为两类:通用数据(网页,书籍,对话文本)和专业数据(针对特定任务,例如多语言新闻文章,涉及到专业术语的科学论文,专利等、程序代码)。从数据角度来看,BooksCorpus、Wikipedia、CommonCrawl和ThePile是最常用的预训练数据集,而Python则是代码数据集中最常见的程序语言。

5.多模态数据集:SBU Captions、Flickr30k、COCO

6.数据处理:旨在剔除数据集中的噪声、冗余信息、无关数据,以及潜在有害的内容。

  • 质量过滤:剔除低质量数据,确保训练集的可靠性和模型性能的有效性。两种方法:基于分类器的方法,基于启发式的方法。
  • 去重:句子级(目的是防止在模型训练中引入冗余模式),文档级(),数据集级(防止训练集和评估集的数据重叠,造成数据污染)。
  • 隐私删除:在数据中去重个人可识别信息
  • 分词化:将原始文本分解成一些列单独的词元。

7. 预训练数据与大型语言模型(LLM)的性能关系

  • 数据源的多样性
  • 预训练数据量
  • 预训练数据质量

8.语言建模,目的:基于前面的标记,自回归预测目标标记。

9.去噪自编码(DAE)

  • 输入时带有随机替换片段的损坏文本
  • 训练的目标:恢复被替换的标记

10.自然语言理解:自然语言理解是指将自然语言转化为计算机能够理解的形式。这包括语言分类、命名实体识别、词性标注、句法分析等任务。自然语言理解任务的目标是从文本中提取出有用的信息,为后续的处理和分析提供基础。包括:自然语言推理、常识性推理、性感分类、复述检测、闭卷问答、阅读理解

11.自然语言生成:自然语言生成是指将计算机生成的信息转化为自然语言的过程。这包括文本生成、机器翻译、对话系统的回答生成等任务。自然语言生成任务的目标是生成符合语法和语义规则的自然语言表达,使计算机能够与人类进行自然的交流。包括:机器翻译、结构化数据-文本、摘要生成

12.优化参数设置

  • 批量训练:提高模型的稳定性和吞吐量(LLM使用动态增加批量大小)
  • 学习率:学习率调度(热身或者衰减)
  • 优化器:Adam优化器和AdamW优化器被广泛用于训练LLM
  • 稳定训练:权重衰减和梯度裁剪

13.可扩展训练技术

  • 3D并行:数据并行、流水线并行(LLM的不同层分不到多个GPU上)、张量并行(对LLM的参数矩阵进行分解)
  • ZeRO技术:解决数据并行中的冗余问题,三种解决方案:优化器状态分割、梯度分割和参数分割。
  • 混合精度训练:16位浮点数进行训练,效率可以提高但是会损失精度

九、大模型微调

1.指令微调

  • 指令学习是指让模型学会理解自然语言指令或命令,并以正确的方式执行相应的任务,例如回答问题或生成文本。这通常需要大量的训练数据和复杂的网络结构。指令学习可以通过监督学习和强化学习等技术实现。
  • 指令微调(Instructional Fine-Tuning)是一种特殊形式的微调,通过对大语言模型的参数进行微调,使得模型能够执行指定的程序任务。这种方法通过给模型提供特定的输入和输出文本,同时添加一些计算步骤,实现程序执行的功能。指令微调通常应用于生成程序或编程语言翻译的任务,例如将人类自然语言描述转换为计算机程序代码的任务。
  • 指令微调的优点在于能够将自然语言转换为计算机可执行的程序,从而使得模型能够自动化地执行特定的任务。
  • 指令微调是一种通过在由(指令,输出)对组成的数据集上进一步训练LLMs的过程。其中,指令代表模型的人类指令,输出代表遵循指令的期望输出。这个过程有助于弥合LLMs的下一个词预测目标与用户让LLMs遵循人类指令的目标之间的差距。
  • 指令的种类:实体描述、操作、属性查询、四则运算、地址查询、时间查询
  • 指令微调数据集:FLAN(不同领域的翻译任务的能力)、斯坦福指令数据集、chatDoctor(通用 + 保障领域质量专用数据集)、COIG(可商用的中文数据)
  • 指令优化策略:平衡数据分布、结合指令微调和预训练
  • 指令微调的意义:提高模型的性能、提高模型的任务泛化能力

2.对齐微调

  • 为什么要对齐微调?

基于自回归预测的文本生成方式没有充分考虑到人类语言的价值观和偏好,可能会生成不真实的信息或者是带有偏见、错误的描述,缺乏和人类意图的对齐。对齐微调能够有效提升预训练模型在执行任务时的伦理和价值观对齐程度,确保其决策和行为更加符合人类社会的期望和标准。

  • 对齐微调的影响:可能影响所有层

对齐微调的作用:使模型输出与人类的伦理和价值观对齐,可能需要对整个模型的处理方式进行调整

关键组件:(1)预训练模型(2)与人类伦理和价值观对齐的数据集或者标准

  • RLHF(基于人工反馈的强化学习):模型首先通过交互环境产生一系列的行为或决策,然后,人类观察者会对这些行为或决策进行评估,提供反馈。这些反馈通常以奖励或者惩罚的形式存在,模型的目标就是最大化所得到的总奖励。
  • RLHF步骤:(1)数据采集阶段:收集人类对智能体行为的评估或示例

(2)奖励模型构建阶段:构建一种可以预测人类评价的奖励模型

(3)策略优化阶段:智能体利用强化学习算法进行策略优化

(4)迭代优化阶段:提升智能体的学习效果

  • RLHF应用:(1)自动驾驶汽车 (2)机器人控制
  • RLHF实验评估:(1)人类评估 (2)BLEU(双语评估指标)或ROUGE(评估摘要任务) (3)人类偏好比较 (4)下游任务评估
  • RLHF现有问题:(1)数据依赖和效率问题 (2)算法稳健性和技术局限 (3)个人隐私和数据安全问题 (4)模型泛化能力的限制 (5)人机交互和协作的复杂性
  • RLHF未来展望:(1)安全可解释强化学习 (2)个性化学习和适应性 (3)人机协同学习 (4)伦理和公平 (5)自动化和效率提升

十、提示工程

1. 提示工程是与人工智能有效沟通以达到期望结果的过程。提示词可以是一个简单的指令或问题,也可以是一个复杂的文本块。

2.LLM中两个设置结果随机性的参数

  • Temperature:高温度会产生更加不可预测和创造性的结果(会降低对概率分布中概率最高的词元的选择权重)
  • Top_p:设置一个阈值概率,选择累计概率超过该阈值的前几个词元,然后模型从这些词元中随机采样以生成输出。也被称为核采样。

3.提示词的组成:

  • 角色:现在你是……
  • 指令或者任务
  • 问题
  • 上下文
  • 示例

4.零样本提示:直接把问题交给模型,不提供任何的样本

少样本提示:提供一些样本(即指令的上下文),也可以设置输出的格式

5.LLM可能出现的偏差:

  • 当示例中标签的分布不均衡时,存在大多数标签偏差
  • 新近偏差:模型会在末尾重复标签
  • 常见词元偏差:LLM倾向于更频繁地生成常见词元而非罕见词元

6.思维链(CoT)提示:鼓励LLM解释其推理过程,一般需要和少样本提示结合使用,在样本中加入推理的步骤,从而让模型能够解决复杂的推理任务(少样本CoT),如果不加入样本就是零样本CoT。需要注意:CoT在千亿规模参数的模型上才会产生明显的性能提升,并且在简单的任务上使用CoT一般也没有明显效果。

  • 零样本CoT发现,在问题的结尾加“让我们一步步思考”(Let’s think step by step),模型会生成一个回答问题的思维链。
  • 自洽性:是对CoT的一个最简单的补充,它不仅仅生成一个思维链,而是结合多个思维链,取多数答案为最终答案。
  • 在英文提示词方面,不同步骤之间使用换行符往往比step I 有效。
  • 思维链:根据给定推理问题而生成的一系列中间自然语言推理步骤。
  • 特性(1)提供了对模型行为的可解释窗口 (2)提供了调试推理路径出错的机会 (3)可用于各种任务
  • 过程推理方法:自我优化、集合优化和迭代优化
  • 思维链的局限性:(1)推理局限性 (2)思维链开销巨大 (3)语言模型规模限制

7.生成的知识方法:LLM在返回结果之前生成和问题相关的可能有用的信息

  • 知识生成:先给模型一些示例让模型自己去生成对应问题的背景知识。再把生成的背景知识添加到Context中向模型提问。
  • 知识集成:利用模型的现有知识来整合新信息或连接不同的信息片段。这种技巧对于将现有知识与新信息相结合,以生成更全面的特定主题的理解上非常有用。

8.最少到最多提示,是一种思维链提示过程的改进方法,它将问题分解为子问题,逐个解决子问题来得到答案。与思维链不同的是,该方法将先前子问题的解决方案作为提示输入,逐步构建解决整个问题所需的推理链。

9.图片提示:

(1)样式修饰符(2)质量增强器(amazing,beautiful,good equality)等术语。

(3)重复 (4)加权

10.自定义指令,可以解决记忆只有几千字的问题,无须重复提醒

11.情境学习

  • 定义:在使用大语言模型处理任务时,只需要给出少量的“输入-输出”示例,模型就能产生正确的输出,无须额外的微调训练。
  • 核心理念:通过类比来学习,首先使用自然语言模板生成K个示例,并将其与查询问题一同输入提供给大模型,以输出答案。
  • 优势:(1)模拟了人类的学习过程 (2)提供了一种训练范式,直观地训练模型 (3)无须对模型参数进行更新,减小了模型适应新任务的计算成本
  • 示例的选择方法(1)启发式方法,计算相似度选择 (2)基于大语言模型的方法,计算查询语句与示例的相似度,然后排序选择

排序方法:相似度大的排在后面,保证准确率

12.多提示方法

(1)提示集成:均匀平均,加权平均,多数表决,知识蒸馏

(2)提示增强:样本选择,样本排序

(3)提示组合:子提示直接互相组合

(4)提升分解

13.Langchain核心组件

  • 模式(schema):Langchain用来表示应用和LLM交互过程中的数据定义抽象,包括(1)文本 (2)对话信息 (3)示例 (4)文档
  • 模型(model):LLM(狭义的生成模型,如text-davinci-003模型),对话模型(如gpt-3.5-turbo模型),文本嵌入模型(如text-embedding-ada-002模型)
  • 提示词(Prompt):模型的输入 (1)Promptvalue:模型的输入值,目前仅支持文本 (2)PromptTemplate:提示词模板,负责构建PromptValue (3)样本选择器:动态加入样本 (4)输出解析器:指示模型格式化输出并且将输出解析为所需格式
  • 索引:获取用户的查询并返回最相关的文档,Langchain目前支持的主要索引和检索类型都围绕着向量数据库,包括(1)文本载入器 (2)文本切分器 (3)向量存储:最常用的索引,用于存储文档以及其对应的嵌入向量 (4)检索器:获取相关文档和语言模型结合的接口,接受一个字符串,返回最相关的一组文档
  • 记忆:在对话者存储和检索数据,有短期(单个对话的上下文)和长期(多个对话之间的信息)两种类型,类:ChatMessageHistory,方法主要有add_user_message和add_AI_message。

LangChain提供了许多记忆组件,这里简单介绍最常用的四种:

ConversationBufferMemory如实地在列表中记录对话历史消息,但对话过长可能会超过上下文限制。

ConversationBufferWindowMemory持续记录对话消息,但只使用最近的K个交互。这种滑动窗口的机制,确保缓存大小不会变得过大。

ConversationSummaryMemory随着时间的推移总结对话的内容,并将当前的摘要存储在记忆中,然后在需要的时候将对话摘要注入提示词或链中。

ConversationSummaryBufferMemory可以在记忆中保留部分对话的摘要和部分完整的对话。具体保留哪些内容取决于设置的“max_token_limit”值,设置的偏小则大部分内容会转成摘要,反之则会输出更多完整内容。

  • 链:表示多个组件的端到端封装,它返回一系列模块化组件,以特定的方式组合完成一个常用的任务(1)LLMChain:最常见的链类型,由提示词模板、模型以及一个可选的输出解析器组成 (2)索引相关的链:把存储在索引中的数据与LLM相结合,比如对私有的文档进行问答。

Langchain引入了PromptSelector的概念,对LLM和对话模型设置不同的提示词

  • 代理(1)工具:函数的抽象,解决问题的函数 (2)代理:接受用户的输入并返回对应的响应,对应操作和操作输入 (3)代理执行器:是一个代理和一组工具。代理执行器负责调用代理,获取操作和操作输入,然后调用操作引用的工具并使用相应的输入,获取工具的输出。
  • 回调函数:Callback 是 LangChain 提供的回调机制,允许我们在 LLM 应用程序的各个阶段使用 Hook。这对于记录日志、监控、流式传输等任务非常有用。这些任务的执行逻辑由回调处理器(CallbackHandler)定义的。

在 Python 程序中, 回调处理器通过继承 BaseCallbackHandler 来实现。BaseCallbackHandler 接口对每一个可订阅的事件定义了一个回调函数。BaseCallbackHandler 的子类可以实现这些回调函数来处理事件,当事件触发时,LangChain 的回调管理器 CallbackManager 会调用相应的回调函数。

十一、涌现

涌现在大模型中的表现

  1. 知识表示能力的涌现
  2. 创造性能力的涌现
  3. 解释能力的涌现
  4. 跨模态学习能力的涌现

十二、大模型评估

  1. 评估的基本要求:公平性、可重复性、低代价
  2. 评估方式:人工评估(众包,直接打分,比较和排序)、自动评估、基于大语言模型的自动评价
  3. 评估指标:准确性、精准率、召回率、F1-score
  4. 有参考答案的准确性评估:BLEU、ROUGE

计算题:可扩展训练技术

1.大模型训练常用数据类型:

  • FP32( Full Precise Float 32) 单精度:单个参数需要 32 bits
  • TF32(Tensor Float 32)单精度:由Nvidia提出的单精度
  • FP16 半精度:单个参数需要 16 bits
  • INT8 整型: 单个参数需要 8 bits
  • BF16 (Brain Floating Point)半精度:单个参数需要16 bits,由google提出

2.计算训练所用显存:模型参数1份,梯度内存1份,优化器:使用Adam,2份;SGD:1份;采用bitsandbytes优化的AdamW,0.5份

Langchain实践

1. 输入部分(prompts):

我们把向模型的输入称作prompts。有时我们会反复用到类似的prompts,LangChain针对这一情况对类似的提示创建了模板。如下所示:

from langchain import PromptTemplate

prompt = PromptTemplate(

input_variables=['product'],

template="""

what is a good name for a company that makes {product}?

""")

print(prompt.format(product="colorful socks"))

在提示模板中,我们需要指定两个东西:template:我们需要提出的问题、input_variables:指定template中实际需要用户输入的变量;

2.语言模型部分:

以聊天模型为例

chat = ChatOpenAI(temperature=0, model_name='gpt-3.5-turbo')

response = chat.predict_messages([

HumanMessage(content="What is LangChain?")

])

在模型返回结果后,你可以用`response.__class__’来查看回复的对应角色。

3.输出部分:

上面语言模型通常是输出文本。但很多时候,我们可能希望获得比仅文本更结构化的信息。这时LangChain可以通过输出解析器(一个帮助结构化语言模型响应的类)来调整输出内容,已获得格式化的内容,例如结果转成目标对象,列表,数组等。

我们以列表解析器为例。如果我们想要返回逗号分隔的项目列表时,可以使用此输出解析器。

from langchain.output_parsers import CommaSeparatedListOutputParser

output_parser = CommaSeparatedListOutputParser()

output_parser.parse("红色, 白色, 黄色, 蓝色, 黑色")

执行之后,可以看到输出:['红色', '白色', '黄色', '蓝色', '黑色']

4. 文档加载:

LangChain提供了文档加载器,可以使用文档加载器加载数据作为文档,其中文档是一段与文本关联的元数据。我们可以使用不同的文档加载器来加载各种类型的数据源,例如加载简单的.txt 文件或者网页内容。它提供了一个公开的 “load” 方法,用于从配置的数据源加载数据并创建文档,还可以选择实现延迟加载的机制,以便在需要时才将数据源加载到内存中。

文档加载中最简单的是将文件作为文本读入,并将其全部放入一个文档中。此外它还提供了对不同格式数据的解析和加载功能。其中包括了一些常用格式如 CSV、HTML、JSON、Markdown 和 PDF。

5. 文档分割:

这里LangChain提供了文档转换器,它的主要作用是分割文档内容,把一个大的文档内容,切割成多个小的内容片段。这么做的目的是因为语言模型通常都有提示词长度限制,不能把所有的内容都丢给模型,即使有些模型允许的提示词长度很大,从成本角度考虑实际应用也不会把那么长的内容传给模型,要考虑到内容越长API调用费用越高(就算是本地部署的开源模型,内容越长需要的显存越高,推理越慢)。合理的做法是请求模型的时候把相关内容片段作为背景信息和提示词拼接在一起传给模型。

LangChain拥有许多内置的文档转换器,可轻松拆分、组合、过滤文档内容,如按字符拆分、按代码拆分或按token拆分等。

6. 向量存储:

进行存储需要用到文本嵌入模型,首先对文档进行文本嵌入,之后进行向量存储。

7. 基础链LLMchain 接受如下组件:

  • LLM
  • 提示词模版

例如这里我们首先准备好需要的组件。

llm = OpenAI(temperature=0.7)

prompt = PromptTemplate(

input_variables=["动物名称"],

template="告诉我关于{动物名称}的信息。它是什么类型的动物?它生活在哪里?它吃什么?它有什么主要特点?",

)

之后可以直接调用LLMChain进行使用。

chain = LLMChain(llm=llm, prompt=prompt)

chain.run("老虎")

8. 问答链:假设我们有一些文本文档(PDF、博客、本地私有数据等),想做一个基于本地知识库的AI问答机器人,基于LangChain很容易就实现这个功能。我们需要使用上面提到的RetrievalQA(问答链)。

前面在“检索”部分我们已经成功向量存储了一个文档,现在我们可以直接使用问答链基于我们存储的文档进行问答。

llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

qa_chain = RetrievalQA.from_chain_type(llm,retriever=db.as_retriever())

qa_chain({"query": question})

这里的db就是前面我们定义的向量数据库。

9.调包:

from langchain.prompts import PromptTemplate

from langchain.llms import OpenAI

from langchain.chains import LLMChain

from langchain.chains import SimpleSequentialChain

from langchain.memory import SimpleMemory

from langchain.chains import TransformChain 可以对数据进行转换的链

10. SimpleSequentialChain :顺序链的最简单形式,其中每个步骤都有一个单一的输入/输出,并且一个步骤的输出是下一步的输入。

SequentialChain :更通用的顺序链形式,允许多个输入/输出。

from langchain.llms import OpenAI

from langchain.chains import LLMChain

from langchain.prompts import PromptTemplate

from langchain.chains import SequentialChain

llm = OpenAI(temperature=.7)

template = """您是一名剧作家。根据剧本的标题和其所设定的时代背景,您的任务是为该标题撰写一个概要。

标题:{title}

时代:{era}

剧作家:以下是上述剧本的概要:"""

prompt_template = PromptTemplate(input_variables=["title", 'era'], template=template)

synopsis_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="synopsis")

llm = OpenAI(temperature=.7)

template = """您是《纽约时报》的戏剧评论家。根据剧本概述,您的任务是为该剧本写一篇评论。

剧本概述:

{synopsis}

《纽约时报》戏剧评论家对上述剧本的评论:"""

prompt_template = PromptTemplate(input_variables=["synopsis"], template=template)

review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="review")

overall_chain = SequentialChain(

chains=[synopsis_chain, review_chain],

input_variables=["era", "title"],

output_variables=["synopsis", "review"],

verbose=True)

overall_chain({"title":"日落沙滩上的悲剧", "era": "维多利亚时期的英格兰"})

11.代理:web搜索

加载语言模型:

from langchain.llms import OpenAI

llm = OpenAI(temperature=0)

加载工具:

from langchain.agents import load_tools

tools = load_tools(["serpapi", "llm-math"], llm=llm)

初始化代理:

from langchain.agents import initialize_agent

from langchain.agents import AgentType

agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

查询问题

agent.run("What was the high temperature in SF yesterday in Fahrenheit? What is that number raised to the .023 power?")

12.使用内存:

from langchain import OpenAI, ConversationChain

llm = OpenAI(temperature=0)

conversation = ConversationChain(llm=llm, verbose=True)

output = conversation.predict(input="Hi there!")

print(output)

# 输出: 'Hello! How are you today?'

output = conversation.predict(input="I'm doing well! Just having a conversation with an AI.")

print(output)

# 输出: "That's great! What would you like to talk about?"

13.使用聊天提示模板:

from langchain.chat_models import ChatOpenAI

from langchain.prompts.chat import (

    ChatPromptTemplate,

    SystemMessagePromptTemplate,

    HumanMessagePromptTemplate,

)

 

chat = ChatOpenAI(temperature=0)

template = "You are a helpful assistant that translates {input_language} to {output_language}."

system_message_prompt = SystemMessagePromptTemplate.from_template(template)

human_template = "{text}"

human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

 

# get a chat completion from the formatted messages

chat(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())

 

# -> AIMessage(content="J'aime programmer.", additional_kwargs={})

14.带聊天模型的链

from langchain.chat_models import ChatOpenAI

from langchain import LLMChain

from langchain.prompts.chat import (

    ChatPromptTemplate,

    SystemMessagePromptTemplate,

    HumanMessagePromptTemplate,

)

 

chat = ChatOpenAI(temperature=0)

template = "You are a helpful assistant that translates {input_language} to {output_language}."

system_message_prompt = SystemMessagePromptTemplate.from_template(template)

human_template = "{text}"

human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

chain = LLMChain(llm=chat, prompt=chat_prompt)

chain.run(input_language="English", output_language="French", text="I love programming.")

 

# -> "J'aime programmer."

15.带有Memory的代理

from langchain.prompts import (

    ChatPromptTemplate,

    MessagesPlaceholder,

    SystemMessagePromptTemplate,

    HumanMessagePromptTemplate

)

from langchain.chains import ConversationChain

from langchain.chat_models import ChatOpenAI

from langchain.memory import ConversationBufferMemory

 

prompt = ChatPromptTemplate.from_messages([

    SystemMessagePromptTemplate.from_template("The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know."),

    MessagesPlaceholder(variable_name="history"),

    HumanMessagePromptTemplate.from_template("{input}")

])

llm = ChatOpenAI(temperature=0)

memory = ConversationBufferMemory(return_messages=True)

conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm)

conversation.predict(input="Hi there!")

 

# -> 'Hello! How can I assist you today?'

conversation.predict(input="I'm doing well! Just having a conversation with an AI.")

 

# -> "That sounds like fun! I'm happy to chat with you. Is there anything specific you'd like to talk about?"

conversation.predict(input="Tell me about yourself.")

 

# -> "Sure! I am an AI language model created by OpenAI. I was trained on a large dataset of text from the internet, which allows me to understand and generate human-like language. I can answer questions, provide information, and even have conversations like this one. Is there anything else you'd like to know about me?"

16.Bing搜索

from langchain.utilities import BingSearchAPIWrapper

# 初始化必应搜索API包装器

search = BingSearchAPIWrapper()

# 示例搜索查询

search_results = search.run("python")

search = BingSearchAPIWrapper()

metadata_results = search.results("apples", 5)

17. 使用PyPDF加载PDF格式文件,并输出第一节的文字内容。这种方法的优势是可以通过页面号码检索文档。

from langchain.document_loaders import PyPDFLoader

loader = PyPDFLoader("example_data/layout-parser-paper.pdf")

pages = loader.load_and_split()

print(pages[0])

18.基于词向量检索文档:

from langchain.vectorstores import FAISS

from langchain.embeddings.openai import OpenAIEmbeddings

# 根据问题“How will the community be engaged?", 检索相似度最高的两页pdf

faiss_index = FAISS.from_documents(pages, OpenAIEmbeddings())

docs = faiss_index.similarity_search("How will the community be engaged?", k=2)

for doc in docs:

    print(str(doc.metadata["page"]) + ":", doc.page_content[:300])