跳至主要内容

Transformers 与 Hugging Face 入门指南

理解 Transformers,并运用其能力解决真实问题。
· 15分钟 阅读

使用 AI 探索

简介

过去数十年间,自然语言处理(NLP,Natural Language Processing)领域研究者的持续投入在不同方向上产出大量创新成果。以下是一些自然语言处理的实际应用示例:

  • Apple 的 Siri 个人助理,可帮助用户完成设定闹钟、发送短信、回答问题等日常任务。
  • 医学领域研究者使用 NLP,为更快速的药物研发铺平道路。
  • 语言翻译也是一项重要应用,因为它帮助我们跨越沟通障碍。

本文将以概念性讲解为主,介绍 NLP 领域最强大的模型之一——Transformers。我们将先解释它相较循环神经网络的优势,再带您逐步理解 Transformer 的工作原理,最后结合 Hugging Face Transformers 演示若干真实场景。

您也可以通过我们的代码跟练,进一步学习如何用 Hugging Face 构建 NLP 应用。

循环网络——Transformers 之前的高光时代

在深入 Transformer 核心概念之前,我们先简要了解什么是循环模型及其局限性。

循环网络采用编码器—解码器(encoder–decoder)架构,主要用于输入与输出都按一定顺序排列的序列任务。其典型应用包括机器翻译与时间序列建模。

循环网络面临的挑战

以将下列法语句子翻译成英语为例。输入的原始法语句子传入编码器,解码器生成对应的译文输出。

Encoder

用于语言翻译的循环网络的简单示意

  • 法语输入句子逐词传入编码器,解码器按同样顺序生成词嵌入,这使训练过程较慢。
  • 当前词的隐藏状态依赖前序词的隐藏状态,无论算力多强,都无法并行计算。
  • 当网络过长时,序列到序列(seq2seq)网络容易出现梯度爆炸,从而表现不佳。
  • 为缓解梯度消失问题,人们提出了另一类循环网络——长短期记忆(LSTM),但它们比序列模型更慢。

如果有一种模型既能保留循环网络的优势,又能实现并行计算,那不是更好吗?

这正是 Transformer 大显身手之处。

NLP 中的 Transformers 是什么?

Transformer 是 Google Brain 于 2017 年在著名论文“Attention is all you need”中提出的一种简单却强大的神经网络架构。它以注意力机制为基础,而非像循环网络那样依赖顺序计算。

Transformer 的主要组成部分有哪些?

与循环网络类似,Transformer 也由两个主要模块组成:编码器与解码器,每个模块都包含自注意力机制。Transformer 的初版曾采用 RNN/LSTM 的编码器—解码器架构,后来被自注意力与前馈网络所取代。

下文对 Transformer 各模块的关键组件作一概述。

components of transformers

Transformer 的总体架构(作者改编)

输入句子的预处理阶段

该阶段包括两步:(1)为输入句子生成词嵌入;(2)为句中每个词计算其位置向量。对于源句(进入编码器前)与目标句(进入解码器前),计算过程相同。

输入数据的嵌入

在生成输入数据的嵌入之前,先对文本进行分词,然后为每个词各自创建嵌入,此时不考虑它们在句中的相互关系。

位置编码

分词会丢失输入句子中原有的关系信息。位置编码通过为每个词生成上下文向量,尝试恢复这种原本的周期性结构。

编码器模块

完成前述步骤后,我们为每个词得到两个向量:(1)词嵌入;(2)其上下文向量。将二者相加得到每个词的单一向量,并将其传入编码器。

多头注意力

如前所述,我们一度丢失了词与词之间的关系。注意力层的目标是捕捉输入句子中不同词之间的上下文关系。此步骤会为每个词生成一个注意力向量。

位置前馈网络(FFN)

此时,对每个注意力向量应用前馈神经网络,将其转换为解码器中下一层多头注意力所期望的格式。

解码器模块

解码器由三层组成:带掩码的多头注意力、多头注意力,以及位置前馈网络。后两层与编码器中的相同。

在训练阶段,解码器发挥作用,并接收两类主要输入:(1)待翻译输入句子的注意力向量;(2)英文的目标译文句子。

那么,带掩码的多头注意力层负责什么?

在生成下一个英文单词时,网络被允许使用所有法语词语的信息。然而,对于目标序列(英文译文)中的某个给定词,网络只能访问其之前的词。如果让后续词可见,网络就会“作弊”,而无需努力学习。带掩码的多头注意力层正是在此发挥作用:它将那些后续词屏蔽为零,使注意力网络无法使用它们。

带掩码的多头注意力层的输出会继续流经其余层,通过生成概率得分来预测下一个词。

该架构之所以成功,原因包括:

  • 各层的总计算复杂度低于 RNN。
  • 彻底消除了对循环的依赖,允许序列并行化;而 RNN 需要按顺序输入。
  • RNN 难以高效学习长距离依赖,因为网络中前向与后向信号路径过长。自注意力缩短了该路径,从而改进了学习过程。

NLP 中的迁移学习

从零开始训练诸如 Transformer 这类深度神经网络并不容易,可能面临以下挑战:

  • 为目标问题获取足量数据耗时费力
  • 获得用于训练深度网络所需的 GPU 等算力资源成本高昂

采用迁移学习的好处很多,例如缩短训练时间、加速新模型的训练过程、压缩项目交付周期。

设想从零开始构建一个将曼丁哥语翻译成沃洛夫语的模型,这两者都是低资源语言。收集相关数据代价不菲。与其克服重重困难,不如复用预训练的深度神经网络,作为新模型训练的起点。

此类模型已在海量语料上完成训练并由他人(自然人、组织等)发布,在如法译英等翻译任务上表现出色。

如果您是 NLP 新手,可以参考这门Python 自然语言处理入门课程获取解决实际问题所需的基础技能。

但“复用深度神经网络”具体指什么?

即选择与您的使用场景相近的预训练模型,准备好目标任务的输入—输出配对数据,并用您的数据对预训练模型的顶层进行再训练。

Transformer 的出现催生了多种前沿的迁移学习模型,例如:

  • BERT(Bidirectional Encoder Representations from Transformers)由 Google 研究者于 2018 年提出,有助于解决诸如命名实体识别、情感分析、问答、文本摘要等常见任务。可在本 NLP 教程中阅读更多 BERT 相关内容。
  • GPT-3(Generative Pre-Training-3),由 OpenAI 研究者提出,是一种多层 Transformer,主要用于生成各类文本。GPT 模型能够对给定问题生成类人文本回复。这篇精彩文章可帮助您更深入了解 GPT-3 的独特之处、底层技术、风险与局限。

Hugging Face Transformers 简介

Hugging Face 是由 Julien Chaumond、Clément Delangue 和 Thomas Wolf 于 2016 年创建的 AI 社区与机器学习平台。其目标是通过提供基于最先进 Transformer 架构的 20,000 多个预训练模型,让数据科学家、AI 从业者与工程师即取即用,推动 NLP 的普及。这些模型可应用于:

  • 文本(覆盖 100 多种语言),用于分类、信息抽取、问答、生成与翻译等任务。
  • 语音,用于音频分类、语音识别等任务。
  • 视觉,用于目标检测、图像分类、分割。
  • 表格数据,用于回归与分类问题。
  • 强化学习 Transformer。

Hugging Face Transformers 还提供近 2000 个数据集与分层 API,便于开发者通过约 31 个库轻松调用这些模型,其中多数为深度学习框架,如 Pytorch、Tensorflow、Jax、ONNX、Fastai、Stable-Baseline 3 等。

以下课程可帮助您分别入门使用 Pytorch 与 Tensorflow 构建深度卷积神经网络。Hugging Face Transformers 的另一组件是Pipelines。

Transformers 中的 Pipelines 是什么?

  • 它们通过 pipeline() 方法提供易用的 API,可在多种任务上直接进行推理。
  • 它们用于封装各类 NLP 任务的完整流程,如文本清洗、分词、嵌入等。

pipeline() 方法的基本用法如下:

from transformers import pipeline

# To use a default model & tokenizer for a given task(e.g. question-answering)
pipeline("<task-name>")

# To use an existing model
pipeline("<task-name>", model="<model_name>")

# To use a custom model/tokenizer
pipeline('<task-name>', model='<model name>',tokenizer='<tokenizer_name>')

Hugging Face 教程:编辑进行中…

现在,您已对 Transformer 与 Hugging Face 平台有了更清晰的认识。接下来我们将演示以下真实场景:机器翻译、零样本分类的序列分类、情感分析与问答。

关于数据集的信息

本数据集可在 Datacamp’s Dataset 获取,由 Facebook 丰富,旨在预测文章在发布前的受欢迎程度。我们的分析将基于描述字段。为演示示例,我们仅使用其中的三个样本。

下面是数据的简要说明。该数据集包含 14 列与 1428 行。

import pandas as pd
# Load the data from the path
data_path = "datacamp_workspace_export_2022-08-08 07_56_40.csv"
news_data = pd.read_csv(data_path, error_bad_lines=False)




# Show data information
news_data.info()

info dataset

机器翻译

MariamMT 是一套高效的机器翻译框架。它底层使用MarianNMT 引擎,该引擎由 Microsoft 及爱丁堡大学、波兹南亚当密茨凯维奇大学等多家学术机构以 C++ 纯实现开发。同一引擎也为Microsoft Translator 服务提供支持。

赫尔辛基大学的 NLP 团队在 Hugging Face Transformers 上开源了多种翻译模型,命名格式为 Helsinki-NLP/opus-mt-{src}-{tgt},其中 {src} 与 {tgt} 分别表示源语言与目标语言。

在我们的示例中,源语言为英语(en),目标语言为法语(fr)。

MarianMT 是这些模型之一,基于在 Opus 上收集的平行语料,用 Marian 预先训练得到。

  • 除 Transformers 外,MarianMT 还需要安装 sentencepiece:
pip install transformers sentencepiece
from transformers import MarianTokenizer, MarianMTModel



  • 选择预训练模型,获取分词器并加载预训练模型
# Get the name of the model
model_name = 'Helsinki-NLP/opus-mt-en-fr'

# Get the tokenizer
tokenizer = MarianTokenizer.from_pretrained(model_name)
# Instantiate the model
model = MarianMTModel.from_pretrained(model_name)
  • 在每条源(英文)文本前添加特殊标记 >>{tgt}<<,可使用下面的函数实现。
def format_batch_texts(language_code, batch_texts):
    formated_bach = [">>{}<< {}".format(language_code, text) for text in     

                batch_texts]
return formated_bach
  • 使用以下函数实现批量翻译逻辑(一个 batch 为待翻译文本列表)。
def perform_translation(batch_texts, model, tokenizer, language="fr"):

  # Prepare the text data into appropriate format for the model
  formated_batch_texts = format_batch_texts(language, batch_texts)
 
  # Generate translation using model
  translated = model.generate(**tokenizer(formated_batch_texts,

                                          return_tensors="pt", padding=True))

  # Convert the generated tokens indices back into text
  translated_texts = [tokenizer.decode(t, skip_special_tokens=True) for t in translated]
 
  return translated_texts
  • 对前述描述样本运行翻译
# Check the model translation from the original language (English) to French
translated_texts = perform_translation(english_texts, trans_model, trans_model_tkn)

# Create wrapper to properly format the text
from textwrap import TextWrapper
# Wrap text to 80 characters.
wrapper = TextWrapper(width=80)

for text in translated_texts:
  print("Original text: \n", text)
  print("Translation : \n", text)
  print(print(wrapper.fill(text)))
  print("")

French translation

零样本分类

在大多数情况下,训练机器学习模型需要预先知道所有候选标签/目标。也就是说,如果训练标签为科学、政治或教育,那么除非重新训练并纳入相应标签与输入数据,否则无法预测医疗标签。

零样本分类使得模型无需见过候选标签,也能在约 15 种语言上预测文本的目标标签。我们只需从模型库中直接加载该模型即可使用。

本示例的目标是对先前各条描述进行分类,判断其更偏向于科技、政治、安全还是金融。

  • 导入 pipeline 模块
from transformers import pipeline
  • 定义候选标签,即我们希望预测的类别:tech、politics、business 或 finance
candidate_labels = ["tech", "politics", "business", "finance"]
  • 定义带多语言选项的分类器
my_classifier = pipeline("zero-shot-classification",  

                           model='joeddav/xlm-roberta-large-xnli')
  • 对第一条与最后一条描述运行预测
#For the first description
prediction = my_classifier(english_texts[0], candidate_labels, multi_class = True)
pd.DataFrame(prediction).drop(["sequence"], axis=1)

Text predicted finance

文本被预测为主要关于金融

上述结果显示,该文本整体上以金融为主,占比 81%。

对于最后一条描述,得到如下结果:

#For the last description
prediction = my_classifier(english_texts[-1], candidate_labels, multi_class = True)
pd.DataFrame(prediction).drop(["sequence"], axis=1)

Text predicted tech

文本被预测为主要关于科技

上述结果显示,该文本整体上以科技为主,占比 95%。

情感分析

大多数情感分类模型需要适当训练。Hugging Face 的 pipeline 模块让我们可以通过指定在模型库中的特定模型名称,轻松运行情感分析预测。

  • 选择要执行的任务并加载相应模型。此处我们要进行情感分类,使用蒸馏后的 BERT Base 模型。
model_checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"

distil_bert_model = pipeline(task="sentiment-analysis", model=model_checkpoint)
  • 模型已就绪!让我们分析最后两条句子的情感倾向。
# Run the predictions
distil_bert_model(english_texts[1:])

model predicted text

模型以 96% 的置信度预测第一段文本为负向情感,第二段文本为 52% 置信度的正向情感。

如果您想进一步探索情感分析任务,这门 Python 情感分析课程将帮助您掌握使用 Python 构建自有情感分类器及 NLP 基础知识。

问答

设想您正在处理一份比 Apple 报告更长的文档,而您只关心其中提到的事件日期。与其通读全文寻找关键信息,不如使用 Hugging Face 的问答模型来直接给出我们关心的答案。

方法是向模型提供合适的上下文(如 Apple 的报告)以及我们想要查询的问题。

  • 从 transformers 导入问答模型类与分词器
from transformers import AutoModelForQuestionAnswering, AutoTokenizer
  • 使用模型名称与对应分词器实例化模型。
model_checkpoint = "deepset/roberta-base-squad2"

task = 'question-answering'
QA_model = pipeline(task, model=model_checkpoint, tokenizer=model_checkpoint)
  • 向模型提出问题并指定上下文。
QA_input = {
          'question': 'when is Apple hosting an event?',
          'context': english_texts[-1]
          }
  • 获取模型结果
model_response = QA_model(QA_input)
pd.DataFrame([model_response])

Apple event date

模型以 97% 的高置信度回答 Apple 的活动日期为 9 月 10 日。

结论

本文回顾了从循环网络到 Transformer 的自然语言技术演进,并介绍了 Hugging Face 如何通过其平台推动 NLP 的普及化。

如果您仍在犹豫是否使用 Transformer,我们认为现在正是尝试它们并为业务场景创造价值的好时机。

FAQ:Transformers 与 Hugging Face

什么是 Hugging Face Transformer?

Hugging Face Transformers 是一个平台,通过 API 为社区提供对最先进预训练模型的访问与使用,这些模型可从 Hugging Face Hub 获取。

什么是预训练 Transformer?

预训练 Transformer 指由某个主体(个人或机构)完成训练与验证、可作为相似任务起点使用的 Transformer 模型。

Hugging Face 是否免费?

Hugging Face 提供社区版与组织版。社区版包含免费的(有一定限制)与每月 9 美元的专业版。面向组织的方案则包括 Lab 与企业版,均为付费。

Hugging Face 使用哪些框架?

Hugging Face 为近 31 个库提供 API,其中多数为深度学习框架,如 Pytorch、Tensorflow、Jax、ONNX、fastai、Stable-Baseline 3 等。

Hugging Face 使用哪些编程语言?

部分预训练模型在多语言去噪任务上完成训练,涉及 Javascript、Python、Rust 与 Bash/Shell。此Python 自然语言处理课程可帮助您掌握完成常见文本清洗任务所需技能。

主题