刘知远LLM——Transformer与预训练模型

news2024/11/23 9:16:35

文章目录

  • 注意力机制
    • 原理介绍
    • 注意力机制的各种变式
    • 注意力机制的特点
  • Transformer结构
    • 概述
      • Transformer整体结构
    • 输入层
      • byte pair encoding
      • positional encoding
    • Transformer Block
      • Encoder Block
        • Multi-Head Attention
      • Decoder Block
      • 其他tricks
      • 总结
  • 预训练语言模型
    • 语言建模概述
    • 预训练语言模型(PLM)介绍
      • GPT
      • BERT
  • transformers使用
    • pipeline接口
    • 常用API
      • Tokenization
    • Demo讲解
      • 加载数据集
      • tokenization
      • fine-tune模型

对应视频P21-P40

注意力机制

原理介绍

RNN的问题:信息瓶颈
例子:
decoder端需要从encoder端最后表示的向量来输出完整的句子,这就需要最后这个向量应该包括整个句子的所有信息。

但是,最后这个向量真的可以表示完整信息吗?否定的

注意力机制就是为了解决信息瓶颈的问题。

在这里插入图片描述
注意力机制的核心思想:在decoder的每一步都把encoder端所有向量输入进去,decoder根据自己所需选择向量

  1. 计算注意力分数:将 s 1 s_1 s1 点乘每个位置的隐向量,得到 e 1 e^1 e1 。注意力分数表示了 s 1 s_1 s1与对应隐向量 h i h_i hi的相似程度,相似程度越高,注意力分数也会越高。
    在这里插入图片描述
  2. 将注意力分数变为概率分布,即 s o f t m a x softmax softmax操作
    在这里插入图片描述
  3. 根据注意力分布对隐向量加权求和,得到 o 1 o_1 o1,包含了encoder端所有隐向量的信息
    在这里插入图片描述
  4. o 1 o_1 o1 s 1 s_1 s1进行拼接,得到 y 1 y_1 y1,用这个向量来预测生成的单词
    在这里插入图片描述
  5. 生成的单词many输入decoder端得到 s 2 s_2 s2,重复刚才的过程
    在这里插入图片描述

这样每次都可以关注到decoder端不同位置的隐向量,并预测出新的单词
在这里插入图片描述

公式化总结:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意力机制的各种变式

变体1:如果 s s s h h h这两个向量维度不一样,就需要在中间乘上权重矩阵 W W W
在这里插入图片描述
变体2:Additive attention,将 h h h s s s输入到一层前馈神经网络获得标量
在这里插入图片描述

注意力机制的特点

  1. 解决信息瓶颈问题,可以关注每个位置的信息
  2. 缓解RNN传播过长造成梯度消失的问题
  3. 给神经网络这个黑盒模型提供了一定的可解释性,翻译的单词会对相对应的词语权重更高

Transformer结构

概述

回顾:
典型的两层LSTM模型
缺点:必须顺序执行,浪费GPU并行设备的性能
是否可以摒弃RNN结构呢?

Transformer整体结构

在这里插入图片描述

  • 输入层:将文本切分为token(byte pair encoding),并添加位置向量(positional encodeing)。
    在这里插入图片描述

  • 模型层:多个encoder和decoder的Transformer block堆叠而成,不同层的block结构相同,参数不同。通过堆叠block得到更深的模型
    在这里插入图片描述

  • 输出层:线性层和softmax获得词表的概率分布
    在这里插入图片描述

  • 损失函数:通过在词表的维度计算交叉熵来计算loss,从而更新模型参数

输入层

byte pair encoding

将句子切分为单词。
在RNN时,就根据空格切分单词。但是这样存在一些问题,如词表会很大、单词的不同形式被当做不同的词来处理。

全新的切分方式:byte pair encoding(BPE)
语料库中的单词切分为字母,统计每个字母出现的数量,将频度最高的byte gram(连续两个相邻字母的组合)作为词添加进词表中,然后扩充词表,直到到达需要的数量。

例子:
最开始的词表:所有的字母组成
es频度最高,拼接为一个新的单词加入词表中。拼接后s不再单独出现,所以在词表中删除s
在这里插入图片描述
在新的词表中,est出现频度最高,所以拼接est并添加进词表中
在这里插入图片描述
BPE解决的问题:

  • 解决OOV(out of vocabulary)问题,即在输入的文本中,出现了词表中没有出现过的词,模型就无法理解新的单词的含义,也就无法找到向量来表示,这时就只能用特殊符号UNK(unknown words)来代替,这个问题在空格切分处理时非常常见。
  • BPE通过将文本序列变成sub word这样更小的单元,在面对没有见过的单词时,可以将其分解为一个一个见过的sub word来表示,这样就可以表示更多的单词。如lowest就可以分解为low和est

positional encoding

出现的原因:Transformer无法像RNN那样根据单词出现的先后顺序来建模每个单词的位置关系。这样Transformer就无法区分不同位置的相同单词

处理方法:显式的加上位置向量进行区分,基于三角函数的方法来得到位置向量
特性:一一对应,有界,差别取决于相对位置
在这里插入图片描述
可视化:
展示了一个长度为10个token,维度为64的一个编码向量
相同维度,即每个竖线,是一个周期的正弦或者余弦函数
相同位置,即每个横线,对应不同周期的正弦或者余弦函数
在这里插入图片描述

Transformer Block

Encoder Block

网络:多头注意力+两层全连接
trick:残差网络+正则化(隐向量维度),解决层数过深导致的梯度消失和梯度爆炸问题
在这里插入图片描述

Multi-Head Attention

q的计算互不干扰,可以并行计算
在这里插入图片描述
图解:

在这里插入图片描述

其中Q为Query、K为Key、V为Value。可以简单理解为Q与K进行相似度匹配,匹配后取得的结果就是V。举个例子我们在某宝上搜索东西,输入的搜索关键词就是Q,商品对应的描述就是K,Q与K匹配成功后搜索出来的商品就是V。

那Q、K、V是怎么来的呢?这里其实是通过对输入矩阵X进行线性变换得到的,用公式可以简单写成以下:
在这里插入图片描述
图片可以表示为:
在这里插入图片描述
其中, W Q W^Q WQ W K W^K WK W V W^V WV是三个可训练的参数矩阵,输入矩阵X分别与这三个矩阵参数相乘得到 Q Q Q K K K V V V

接着,矩阵 Q Q Q K T K^T KT相乘,得到注意力分数,通过 s o f t m a x softmax softmax转化为概率分布,再乘 V V V得到输出
在这里插入图片描述
进一步的,需要加入Scale系数。除以 d K \sqrt{d_K} dK ,可以让注意力分数的方差为1

如果没有Scale的话,Q和K的点积得到标量的方差会随着d_K的增加而变大,在softmax后概率分布会变得尖锐,某个位置为1,其他位置接近于0,这样以后的梯度变得很小,不利于参数的更新。

在这里插入图片描述
多头注意力机制:多个结构相同但是参数不同的网络组成多头注意力机制,每个头的 W Q W^Q WQ W K W^K WK W V W^V WV不同
在这里插入图片描述
每个head关注的子空间不一定是一样的,那么这个多头的机制能够联合来自不同head部分学习到的信息,这就使得模型具有更强的认识能力。
在这里插入图片描述

Decoder Block

大体上与Encoder Block一致,做了两个修改:

  • 修改1:Masked self-attention
    masked限制Q和K相乘得到的注意力分数的上三角部分(右上角)为负无穷大,这样经过softmax操作后概率就会变为0,使模型输出时看不到后面的单词,只能看到过去的单词,确保了文本的顺序生成
  • 修改2:Q来源于decoder,然而K和V来源于Encoder最后一层的输出

在这里插入图片描述
图解:
在这里插入图片描述

其他tricks

训练过程
在这里插入图片描述

总结

优点:Transformer是具有很强表示能力的模型,适合并行运算。通过Attention的可视化可以发现注意力模块很好的建模了句子中token之间的关系。给预训练语言模型很多启发。
缺点:参数敏感,优化器选择、超参数选择对训练有很大影响。复杂度 O ( n 2 ) O(n^2) O(n2),对长文本束手无策,目前文本长度在512以下。

预训练语言模型

语言建模概述

语言模型的定义:给定前一个词预测下一个词(文字接龙)

可以建模为条件概率
在这里插入图片描述
语言模型需要学习到语法知识和事实知识,只需要纯文本就可以训练,不需要人工标注。在训练后可以迁移到别的任务上

发展脉络:

  1. word2vec(Transformer之前,NLP模型采用词向量作为输入)
    根据前面的1 到 N-1个词预测下一个词,将过程变得简单和高效
    在这里插入图片描述

  2. Pre-trained RNN
    模型的上限不高,效果一般
    在这里插入图片描述

  3. GPT&BERT
    基于transformer
    在这里插入图片描述

预训练语言模型(PLM)介绍

预训练语言模型的好处在于训练后可以很容易迁移到下游的应用任务上,当前大部分都是基于transformer。

具有两种范式,

第一种是feature的提取器,比较有代表性的是word2vec和ElMo,预训练的参数作为下游任务的输入

第二种是fine-tuning方式,会对整个模型的参数进行更新,如BERT和GPT

GPT

GPT-1:方式非常简单,只训练transformer的decoder,用自回归的方式训练一个语言模型。具体来讲使用12层的transformer的decoder
GPT-2:提升了transformer的参数量、训练的文本量(40GB),训练不同规模的GPT大小

BERT

2019年
成为NLP的一个基础架构,下游任务中很多用到BERT
双向生成会产生信息泄露的问题,因此,BERT提出了Masked LM
在这里插入图片描述
masked掉15%的信息
在这里插入图片描述
但在下游任务时不会出现完形填空,即masked会带来预训练和fine-tuning阶段的差异,导致模型效果变差。

解决方式如下:
在这里插入图片描述
输入:基于transformer的encoder
在这里插入图片描述

问题:masked导致预训练和fine-tuning之间的差异;效率低,每次只有15%的词得到训练

改进:动态masked;next sentence prediction是否有必要存在;使用小模型生成masked词,再判断是否被替换

  • 预训练语言模型的代表工作
    在这里插入图片描述

  • 前沿工作:GPT3
    – zero shot:不给任何示例,只给出要求,就可以完成任务
    – one-shot:给一个示例就可以完成任务
    in-context learning方式学习
    在这里插入图片描述

  • 前沿工作:T5
    输入:任务描述,拼接任务内容
    在这里插入图片描述

  • 前沿工作:MoE
    组合小模型成大模型,使用到哪个部分就调用哪个部分参与计算
    在这里插入图片描述

transformers使用

预训练语言模型效果大大超过了RNN这类的神经网络模型。在BERT之后,预训练语言模型如雨后春笋般爆发,但对于工程师而言,从头实现各个模型非常耗费时间和精力。

Huggingface公司提出了transformers库,提供了非常多的模型,一两行代码即可加载模型,并支持主流框架(pytorch、TensorFlow、Jax),并支持音频和视频的预训练模型。

只需要几个接口就可以实现预训练模型的加载、fine-tune。

pipeline接口

使用训练好的模型直接完成下游任务

如情感分析、问答
在这里插入图片描述

常用API

Tokenization

不同模型的tokenization方式不一样,但是huggingface可以根据模型的名字自动选择tokenization的方式
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Demo讲解

加载数据集

在datasets这个package中,囊括了许多目前主流的数据集,通过一行命令(load_dataset)就可以完成数据集的下载与加载,且能够加载该数据集对应的metric以便计算(load_metric)

from datasets import load_dataset, load_metric
dataset = load_dataset("glue", 'sst2')
metric = load_metric('glue', 'sst2')

tokenization

预训练模型并不直接接受文本作为输入,每个预训练模型有自己的tokenization方式以及自己的词表。

我们在使用某一模型时,需要:

使用该模型的tokenization方式对数据进行tokenization
使用该模型的词表,将tokenize之后的每个token转化成对应的id。

from transformers import AutoTokenizer
# 利用tokenizer处理数据集
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
def preprocess_function(examples):
    return tokenizer(examples['sentence'], truncation=True, max_length=512)
# 用preprocess_function来处理整个数据集
encoded_dataset = dataset.map(preprocess_function, batched=True)

fine-tune模型

首先,我们需要利用transformers把预训练模型下载下来以便加载,这一过程也可以通过以下一行代码实现。其中,由于SST-2的标签种类只有2种(positive, negative),因此我们指定num_labels=2。

from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)

接下来,我们将使用Huggingface提供的Trainer类来进行模型的fine-tune。首先,我们设置Trainer的各种参数如下

from transformers import TrainingArguments

batch_size=16
args = TrainingArguments(
    "bert-base-uncased-finetuned-sst2",
    evaluation_strategy="epoch",
    save_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    num_train_epochs=5,
    weight_decay=0.01,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy"
)

每个参数的含义:

第一个参数:本次训练的名称
evaluation_strategy=“epoch”:在每个epoch结束的时候在validation集上测试模型效果
save_strategy=“epoch”:在每个epoch结束的时候保存一个checkpoint
learning_rate=2e-5:优化的学习率
per_device_train_batch_size=batch_size:训练时每个gpu上的batch_size
per_device_eval_batch_size=batch_size:测试时每个gpu上的batch_size
num_train_epochs=5:训练5个epoch
weight_decay=0.01:优化时采用的weight_decay
load_best_model_at_end=True:在训练结束后,加载训练过程中最好的参数
metric_for_best_model=“accuracy”:以准确率作为指标

另外,我们还需要定义一个函数,告诉Trainer怎么计算指标

def compute_metrics(eval_pred):
    logits, labels = eval_pred                 # predictions: [batch_size,num_labels], labels:[batch_size,]
    predictions = np.argmax(logits, axis=1)    # 将概率最大的类别作为预测结果
    return metric.compute(predictions=predictions, references=labels)

然后我们可以定义出Trainer类了

from transformers import Trainer
trainer = Trainer(
    model,
    args,
    train_dataset=encoded_dataset["train"],
    eval_dataset=encoded_dataset["validation"],
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)

紧接着,调用trainer的train方法,我们就能够开始训练了

trainer.train()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1472673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二叉搜索树题目:二叉搜索树中的众数

文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 解法三思路和算法代码复杂度分析 题目 标题和出处 标题:二叉搜索树中的众数 出处:501. 二叉搜索树中的众数 难度 3 级 …

峰值检测电路

常用的峰值检测电路,如下图所示。 该电路有两种工作状态: 1、充电状态:D2导通,D1截止。 当U1的端比-端大时,V1VIN,VCV1-VD2,VOUTVC。这时,给电容C1充电。由于D1截止没有环路&#…

Shell脚本介绍及脚本功能

文章目录 一、什么是shell二、hello word2.1 echo2.2第一个脚本 三、Bash的基本功能3.1别名3.2常用快捷键3.3输入输出3.4 输出重定向3.5 多命令执行3.6 管道符3.7 通配符和特殊符号 一、什么是shell Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。S…

背包问题(介绍+例题+代码+注解)

目录 介绍: 一、01背包 题目描述 输入描述: 输出描述: 代码: 二、完全背包 题目描述 输入描述: 输出描述: 代码: 三、多重背包 题目描述 输入描述: 输出描述: 代码: 四、背包问题 题目描述 输入描述: 输出描…

Mybatis2

Mybatis2 本章目标: myBatis类型别名处理 myBatis参数处理 myBatis结果集类型 myBatis结果集列名和属性名称对应方式处理 附录 本章内容 一、类型别名(typeAliases)处理 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置…

使用EFCore连接SQLite

简介 在使用EFCore连接SQLite之前我们先来了解一下SQLite SQLite是一个轻量级、自包含、无服务器、零配置的事务性SQL数据库引擎,它支持SQL92标准的大多数查询语言并兼容ACID事务。具体如下: 轻量级:SQLite非常轻巧,它的库体积…

[算法沉淀记录] 排序算法 —— 堆排序

排序算法 —— 堆排序 算法基础介绍 堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆这种数据结构来实现排序。堆是一种特殊的完全二叉树,其中每个节点的值都必须大于或等于(最大堆)或小于或等于&am…

Huggingface学习笔记

课程地址:【HuggingFace简明教程,BERT中文模型实战示例.NLP预训练模型,Transformers类库,datasets类库快速入门.】 什么是huggingface? huggingface是一个开源社区,提供了先进的NLP模型、数据集以及工具。 主要模型: 安装环境&…

Rust升级慢,使用国内镜像进行加速

背景 rustup 是 Rust 官方的跨平台 Rust 安装工具,国内用户使用rustup update的时候,网速非常慢,可以使用国内的阿里云镜像源来进行加速 0x01 配置方法 1. Linux与Mac OS用户配置环境变量 修改~/.bash_profile文件添加如下内容&#xff1…

Docker基础篇(六) dockerfile体系结构语法

FROM:基础镜像,当前新镜像是基于哪个镜像的 MAINTAINER :镜像维护者的姓名和邮箱地址 RUN:容器构建时需要运行的命令 EXPOSE :当前容器对外暴露出的端口号 WORKDIR:指定在创建容器后,终端默认登…

lv21 QT入门与基础控件 1

1 QT简介 QT是挪威Trolltech开发的多平台C图形用户界面应用程序框架 典型应用 2 工程搭建 2.1 新建ui工程 不要写中文路径 2.1 不勾选UI(主讲) 3 QT信号与槽机制 语法:Connect(A, SIGNLA(aaa()), B, SLOT(bbb()))…

算法--贪心

这里写目录标题 区间问题区间选点引入算法思想例题代码 最大不相交区间的数量算法思想例题代码 区间分组算法思想例题代码 一级目录二级目录二级目录二级目录 区间问题 区间选点 引入 区间问题会给定几个区间,之后要求我们在数轴上选取尽量少的点,使得…

电脑休眠之后唤不醒

现象:午休时间电脑休眠了,醒来之后发现在密码输入界面,但鼠标键盘没反应。按重启键或电源机重新开机,结果开不了机。 原因:1、内存条脏了,导致内存条读取失败 2、休眠的时候硬盘休眠了,导致按…

欢迎免费申报讯方技术HarmonyOS人才训练营!

在今年1月备受瞩目的鸿蒙生态千帆启航仪式上,华为宣布:HarmonyOS NEXT星河预览版正式面向开发者开放申请,意味着鸿蒙将建立更广泛的生态系统,迎来更多的应用和软硬件产品,加速自我技术迭代,同时推动华为全场…

变革中的容器技术

容器化技术的优点 容器化是一种将应用程序和其所需的依赖项,封装在一个可在任何基础架构上一致运行的轻量级可执行文件(即容器)的技术。容器化技术可以大大简化应用程序的部署、管理和维护,提高运维效率和可靠性。 容器化技术有…

LeetCode_Java_动态规划(2)(题目+思路+代码)

131.分割回文串 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1: 输入:s "aab" 输出:[["a&qu…

工具篇-- 定时任务xxl-job的集群部署

文章目录 前言一、xxl-job-admin 集群部署:1.1 部署步骤:1.2 部署求和建议:1.3 集群部署模拟(单机): 二、xxl-job 执行器 集群部署:2.1 集群部署要求:2.2 集群部署模拟: …

pthread_exit和pehread_join函数

pthread_exit: 在线程中禁止调用exit函数,否则会导致整个进程退出,取而代之的是调用pthread_exit函数,这个函数只会使一个线程退出,如果主线程使用pthread_exit函数也不会使整个进程退出,不会影响其他线程…

【基础知识】MPP架构和hadoop架构比对

架构比对 简单一句描述。 mpp架构,就是找一群和自己能力差不多的任一起做事,每个人做的事情是一致的。 hadoop架构,就是找一群能力差一些的人,但只需要他们每个人只做一部分工作。 举例说明 一个特色小饭店如何成为连锁餐饮巨…

【国密算法】深入理解国密算法:原理、实践及注意事项

目录 引言 1. 国密算法概述 2. 国密算法的实践应用 2.1 对称加密(SM1算法) 2.2 非对称加密(SM2算法) 2.3 哈希算法(SM3算法) 3. 国密算法的注意事项 结论 引言 国密算法,即中国密码算法…