清水泥沙

Transformer 学习之路 - 深入解析模型架构与应用

Transformer 学习之路 - 深入解析模型架构与应用

Transformer 模型自 2017 年提出以来,已经成为自然语言处理(NLP)领域的基石。它通过注意力机制(Attention Mechanism)实现了对序列数据的强大建模能力。本文将从模型类型、模型头(Model Head)的作用以及模型的加载与调用等方面,深入解析 Transformer 技术。

1. 模型的类型

1.1 Encoder-only 模型(如 BERT)

原理
Encoder-only 模型使用双向注意力机制,能够同时关注句子中每个词的前后文,从而理解词语在不同上下文中的含义。它就像在读句子时,同时关注所有词,理解它们彼此的关系。

工作方式
输入的句子会被编码为数字表示,模型通过“关注”句子中的所有词,理解它们的全局语境,最后输出一个表示每个词含义的向量。这些向量可以用于各种任务,比如分类、命名实体识别(NER)。

应用场景
文本分类、命名实体识别(NER)、问答系统中的句子匹配。

总结
Encoder-only 模型擅长理解句子的意思,因为它能“看两边”(上下文)。

1.2 Decoder-only 模型(如 GPT)

原理
Decoder-only 模型使用单向注意力机制,只能从前往后看,就像我们逐字写文章一样。模型根据前面出现的词来生成下一个词。这种“自回归”方式让它在生成新词时,只能依赖之前生成的内容。

工作方式
输入的文本被编码为向量,然后模型每次根据前面的词生成下一个词,直到生成完整句子或段落。每生成一个词,它就会把这个词加入到上下文中,继续生成下一个。

应用场景
文本生成、对话生成、语言建模。

总结
Decoder-only 模型擅长生成句子,通过“接龙”方式,每次只看前面的词,生成后续内容。

1.3 Encoder-Decoder 模型(如 T5, BART)

原理
Encoder-Decoder 模型结合了 Encoder 和 Decoder 的优点,先用编码器理解输入文本,再用解码器生成输出文本。它像是翻译任务:先理解原文,再生成目标语言的翻译。

工作方式

  • 编码器负责理解输入文本,把它转化为一系列向量表示。
  • 解码器根据编码器的输出,逐步生成新的句子,比如翻译、摘要或生成其他序列。

应用场景
机器翻译、文本摘要、自动问答系统。

总结
Encoder-Decoder 模型擅长转换序列,比如把英文翻译成中文,因为它既能理解又能生成。

1.4 多模态模型(如 CLIP)

原理
多模态模型能同时处理文本和图像。它把图像和文本都转化为向量,然后通过比较这些向量的相似度,来判断文本和图像是否匹配。

工作方式

  • 图像部分:模型把图像分成小块,分别处理这些小块的信息,再把它们组合成一个整体表示。
  • 文本部分:模型用类似 BERT 的编码器来处理文本,生成文本的表示。
  • 最后,它比较图像和文本的表示,判断它们是否相关。

应用场景
图像分类、图像描述生成、跨模态匹配。

总结
多模态模型擅长处理图像和文本,能理解图片内容并用文字描述。

1.5 对话模型(如 DialoGPT)

原理
基于 Decoder-only 架构,通过单向生成机制生成对话。它像在模拟人与人对话,一个人说一句,它生成一句相关的回应。

工作方式
模型通过学习大量对话数据,理解上下文,生成自然的对话内容。它通过“接龙”的方式,生成与前面对话内容相关的新句子。

应用场景
聊天机器人、对话生成、问答系统。

总结
对话模型擅长生成与对话上下文相关的内容,适合模拟聊天。

1.6 处理长文本的模型(如 Longformer)

原理
传统的 Transformer 模型只能处理较短文本,因为它们会同时关注所有词(这需要大量计算)。Longformer 使用“局部注意力机制”,让模型只关注部分词的关系,从而节省计算资源,能处理更长的文本。

工作方式
模型不像传统 Transformer 那样每个词都关注整个句子,而是让每个词只关注附近的几个词。这样它可以处理长达几千个词的文档,同时还保留了必要的上下文信息。

应用场景
长文档分类、文档摘要、长文档中的问答。

总结
长文本模型擅长处理长文档,通过局部注意力机制处理大量文本,同时减少计算量。

1.7 总结

  • BERT(Encoder-only):理解句子,能“看两边”(双向),适合文本分类、标注任务。
  • GPT(Decoder-only):生成句子,像“接龙”一样逐字生成,适合文本生成和对话生成。
  • T5/BART(Encoder-Decoder):既能理解又能生成,适合翻译和摘要等序列转换任务。
  • CLIP(多模态):同时理解图像和文本,通过匹配它们的向量表示,适合图像描述和跨模态任务。
  • DialoGPT(对话模型):生成自然对话,理解上下文,适合聊天机器人。
  • Longformer(长文本处理):处理长文档,使用局部注意力机制,适合长文本分类和摘要。

2. 模型头(Model Head)是什么?

Transformers 中,model head(模型头)指的是附加在基础模型(通常是 Transformer 编码器或解码器)的最后一部分,用来处理特定任务的部分。它相当于一个专门设计的组件,负责把模型生成的向量转换成具体任务的输出。

2.1 模型的结构

  • 主干模型(Backbone):这是处理输入的主要部分,通常包括多层的 Transformer 编码器或解码器。它负责理解文本或图像,提取特征,并生成表示(向量)。
  • 模型头(Head):接在主干模型之后,专门用来完成某个任务。不同任务会使用不同的模型头。

2.2 常见的模型头及它们的作用

  1. 分类头(Classification Head)

    • 作用:用于分类任务,比如情感分析、新闻分类等。
    • 工作方式:模型会输出每个词的表示,分类头只会使用句子中第一个词(通常是 [CLS] 标记)的表示,进行分类。
    • 例子:BERT 用于情感分析时,会用分类头输出“正面”或“负面”的分类结果。
  2. 序列标注头(Token Classification Head)

    • 作用:用于序列标注任务,比如命名实体识别(NER)或词性标注。
    • 工作方式:每个词的表示都会被模型头转换为一个标签,比如“实体名”或“非实体名”。
    • 例子:BERT 用于命名实体识别时,序列标注头会为每个词预测其对应的实体类型。
  3. 生成头(Generation Head)

    • 作用:用于生成任务,比如文本生成、机器翻译。
    • 工作方式:解码器的输出经过生成头,预测下一个词的概率分布,模型根据概率最高的词生成下一步输出。
    • 例子:GPT 模型用生成头来预测下一个词,从而生成完整的句子。
  4. 回归头(Regression Head)

    • 作用:用于回归任务,比如评分预测或情感强度的打分。
    • 工作方式:最后一层的输出会通过回归头转换成一个连续数值,表示某种预测结果。
    • 例子:可以用来预测商品的评分(从 1 到 5),而不是分类结果。
  5. 问答头(Question Answering Head)

    • 作用:用于问答任务(如 SQuAD 数据集),专门用来找出答案在文本中的位置。
    • 工作方式:问答头输出两个向量,一个用于预测答案的起始位置,另一个用于预测答案的结束位置。
    • 例子:BERT 用于问答时,会预测答案在文本中的开始和结束位置。

2.3 总结

  • model head 是一个附加在主干模型上的任务专用模块。
  • 不同的任务(分类、生成、标注、回归等)有不同的模型头。
  • 主干模型负责理解输入数据,而模型头则把这些理解转化为具体的任务输出。

3. 模型的加载与调用

3.1 在线加载并保存在本地

from transformers import AutoModel

# 加载模型并保存到本地
model = AutoModel.from_pretrained("hfl/rbt3")

# 确保所有张量在内存中是连续的
for name, param in model.named_parameters():
    param.data = param.data.contiguous()

# 保存模型
model.save_pretrained("./rbt3")

3.2 通过 Git 下载模型

!git clone "https://huggingface.co/hfl/rbt3"
# 使用 Git LFS 下载模型文件
!git lfs clone "https://huggingface.co/hfl/rbt3" --include="*.bin"

3.3 加载已下载的模型

model = AutoModel.from_pretrained("rbt3")

3.4 查看模型配置

# 查看模型加载时可用的参数
model.config
# 查看更详细的参数
config = AutoConfig.from_pretrained("./rbt3/")
config
# 查看是否输出注意力权重
config.output_attentions

3.5 模型的调用

初始化 Tokenizer

from transformers import AutoTokenizer

sen = "弱小的我也有大梦想!"
tokenizer = AutoTokenizer.from_pretrained("hfl/rbt3")
inputs = tokenizer(sen, return_tensors="pt")
inputs

不带 Model Head 的调用,单纯提取特征

model = AutoModel.from_pretrained('rbt3', output_attentions=True)
output = model(**inputs)
output
# 查看特征维度
output.last_hidden_state.size()

带 Model Head 的调用

from transformers import AutoModelForSequenceClassification

clz_model = AutoModelForSequenceClassification.from_pretrained("rbt3", num_labels=10)
clz_model(**inputs)
# 查看分类头的标签数量
clz_model.config.num_labels

通过本文的详细解析,相信你对 Transformer 模型的架构、工作原理及其在不同任务中的应用有了更深入的理解。结合代码示例,你可以轻松上手并应用这些技术。Transformer 的强大之处在于其灵活性和通用性,通过不同的模型头和架构设计,它可以适应各种复杂的任务场景。