当前位置: 首页 > news >正文

自然语言处理——从原理、经典模型到应用

1. 概述

自然语言处理(Natural Language Processing,NLP)是一门借助计算机技术研究人类语言的科学,是人工智能领域的一个分支,旨在让计算机理解、生成和处理人类语言。其核心任务是将非结构化的自然语言转换为机器可以理解和处理的形式,并生成符合语义和语法的语言输出。虽然该领域的发展历史不长,但是其发展迅速并且取得了许多令人印象深刻的成果。

2017 年 Google 在《Attention Is All You Need》中提出了 Transformer 结构用于序列标注,在翻译任务上超过了之前最优秀的循环神经网络模型;与此同时,Fast AI 在《Universal Language Model Fine-tuning for Text Classification》中提出了一种名为 ULMFiT 的迁移学习方法,将在大规模数据上预训练好的 LSTM 模型迁移用于文本分类,只用很少的标注数据就达到了最佳性能。这些具有开创性的工作促成了两个著名 Transformer 模型的出现:

  • GPT (the Generative Pretrained Transformer);
  • BERT (Bidirectional Encoder Representations from Transformers)。

通过将 Transformer 结构与无监督学习相结合,我们不再需要对每一个任务都从头开始训练模型,并且几乎在所有 NLP 任务上都远远超过先前的最强基准。GPT 和 BERT 被提出之后,NLP 领域出现了越来越多基于 Transformer 结构的模型。虽然新的 Transformer 模型层出不穷,它们采用不同的预训练目标在不同的数据集上进行训练,但是依然可以按模型结构将它们大致分为三类:

  • 纯 Encoder 模型:又称自编码 (auto-encoding) Transformer 模型(例如 BERT),适用于只需要理解输入语义的任务,例如句子分类、命名实体识别。在每个阶段,注意力层都可以访问到原始输入句子中的所有词语,即具有“双向 (Bi-directional)”注意力。

    纯 Encoder 模型通常通过破坏给定的句子(例如随机遮盖其中的词语),然后让模型进行重构来进行预训练,最适合处理那些需要理解整个句子语义的任务。

  • 纯 Decoder 模型:在每个阶段,对于给定的词语,注意力层只能访问句子中位于它之前的词语,即只能迭代地基于已经生成的词语来逐个预测后面的词语,因此也被称为自回归 (auto-regressive) 模型(例如 GPT)。适用于生成式任务,例如文本生成。

  • Encoder-Decoder 模型:又称 Seq2Seq (sequence-to-sequence) Transformer 模型(例如 BART、T5),适用于需要基于输入的生成式任务,例如翻译、摘要。在每个阶段,Encoder 的注意力层都可以访问初始输入句子中的所有单词,而 Decoder 的注意力层则只能访问输入中给定词语之前的词语(即已经解码生成的词语)。

在这里插入图片描述

2. 原理

2.1 分词器

因为神经网络模型不能直接处理文本,因此我们需要先将文本转换为数字,这个过程被称为编码 (Encoding),其包含两个步骤:

  • 使用分词器 (tokenizer) 将文本按词、子词、字符切分为 tokens;
  • 将所有的 token 映射到对应的 token ID。

词表就是一个映射字典,负责将 token 映射到对应的 ID(从 0 开始)。神经网络模型就是通过这些 token ID 来区分每一个 token。

根据切分粒度的不同,分词策略可以分为以下几种:

(1)按词切分 (Word-based)
在这里插入图片描述
这种策略问题是会将文本中所有出现过的独立片段都作为不同的 token,从而产生巨大的词表。而实际上很多词是相关的,例如 “dog” 和 “dogs”、“run” 和 “running”,如果给它们赋予不同的编号就无法表示出这种关联性。

当遇到不在词表中的词时,分词器会使用一个专门的 [UNK] token 来表示它是 unknown 的。显然,如果分词结果中包含很多 就意味着丢失了很多文本信息,因此一个好的分词策略,应该尽可能不出现 unknown token。

(2)按字符切分 (Character-based)
在这里插入图片描述
这种策略把文本切分为字符而不是词语,这样就只会产生一个非常小的词表,并且很少会出现词表外的 tokens。

但是从直觉上来看,字符本身并没有太大的意义,因此将文本切分为字符之后就会变得不容易理解。这也与语言有关,例如中文字符会比拉丁字符包含更多的信息,相对影响较小。此外,这种方式切分出的 tokens 会很多,例如一个由 10 个字符组成的单词就会输出 10 个 tokens,而实际上它们只是一个词。

(3)按子词切分 (Subword)
高频词直接保留,低频词被切分为更有意义的子词。例如 “annoyingly” 是一个低频词,可以切分为 “annoying” 和 “ly”,这两个子词不仅出现频率更高,而且词义也得以保留。下图展示了对 “Let’s do tokenization!“ 按子词切分的结果:
在这里插入图片描述
这种策略只用一个较小的词表就可以覆盖绝大部分文本,基本不会产生 unknown token。“tokenization” 被切分为了 “token” 和 “ization”,不仅保留了语义,而且只用两个 token 就表示了一个长词。因此现在广泛采用的是一种同时结合了按词切分和按字符切分的方式——按子词切分 (Subword tokenization)。

2.2 编码与解码

(1)文本编码

  • 分词:使用分词器按某种策略将文本切分为 tokens。
  • 映射:将 tokens 转化为对应的 token IDs。
rom transformers import AutoTokenizertokenizer = AutoTokenizer.from_pretrained("bert-base-cased")sequence = "Using a Transformer network is simple"
tokens = tokenizer.tokenize(sequence)
print(tokens)ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids)
['using', 'a', 'transform', '##er', 'network', 'is', 'simple']
[7993, 170, 13809, 23763, 2443, 1110, 3014]

还可以通过 encode() 函数将这两个步骤合并,并且 encode() 会自动添加模型需要的特殊 token,例如 BERT 分词器会分别在序列的首尾添加 [CLS] 和 [SEP]。

from transformers import AutoTokenizertokenizer = AutoTokenizer.from_pretrained("bert-base-cased")sequence = "Using a Transformer network is simple"
sequence_ids = tokenizer.encode(sequence)print(sequence_ids)
[101, 7993, 170, 13809, 23763, 2443, 1110, 3014, 102]

其中 101 和 102 分别是特殊 token 对应的 token IDs。

在实际编码文本时,最常见的是直接使用分词器进行处理,这样不仅会返回分词后的 token IDs,还包含模型需要的其他输入。

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
tokenized_text = tokenizer("Using a Transformer network is simple")

(2)文本解码
文本解码 (Decoding) 与编码相反,负责将 token IDs 转换回原来的字符串。注意,解码过程不是简单地将 token IDs 映射回 tokens,还需要合并那些被分为多个 token 的单词。

decoded_string = tokenizer.decode([7993, 170, 11303, 1200, 2443, 1110, 3014])
print(decoded_string)

3. 经典模型

3.1 NNLM 模型

2003 年,本吉奥(Bengio)提出了神经网络语言模型(Neural Network Language Model,NNLM)。可惜它生不逢时,由于神经网络在当时并不被人们看好,在之后的十年中 NNLM 模型都没有引起很大关注。直到 2013 年,随着越来越多的研究者使用深度学习模型来处理自然语言,NNLM 模型才被重新发掘,并成为使用神经网络建模语言的经典范例。NNLM 模型的思路与统计语言模型保持一致,它通过输入词语前面的 n-1 个词语来预测当前词。

具体来说,NNLM 模型首先从词表 C 中查询得到前面 n-1 个词语对应的词向量 ,然后将这些词向量拼接后输入到带有激活函数的隐藏层中,通过 Softmax 函数预测当前词语的概率。特别地,包含所有词向量的词表矩阵 C 也是模型的参数,需要通过学习获得。因此 NNLM 模型不仅能够能够根据上文预测当前词语,同时还能够给出所有词语的词向量(Word Embedding)。
在这里插入图片描述

3.2 Word2Vec 模型

真正将神经网络语言模型发扬光大的是 2013 年 Google 公司提出的 Word2Vec 模型。Word2Vec 模型提供的词向量在很长一段时间里都是自然语言处理方法的标配,即使是后来出现的 Glove 模型也难掩它的光芒。Word2Vec 的模型结构和 NNLM 基本一致,只是训练方法有所不同,分为 CBOW (Continuous Bag-of-Words) 和 Skip-gram 两种。
在这里插入图片描述
其中 CBOW 使用周围的词语 w ( t − 2 ) , w ( t − 1 ) , w ( t + 1 ) , w ( t + 2 ) w(t-2),w(t-1),w(t+1),w(t+2) w(t2),w(t1),w(t+1),w(t+2) 来预测当前词 w ( t ) w(t) w(t) ,而 Skip-gram 则正好相反,它使用当前词 w ( t ) w(t) w(t) 来预测它的周围词语。

可以看到,与严格按照统计语言模型结构设计的 NNLM 模型不同,Word2Vec 模型在结构上更加自由,训练目标也更多地是为获得词向量服务。特别是同时通过上文和下文来预测当前词语的 CBOW 训练方法打破了语言模型“只通过上文来预测当前词”的固定思维,为后续一系列神经网络语言模型的发展奠定了基础。

然而,有一片乌云一直笼罩在 Word2Vec 模型的上空——多义词问题。一词多义是语言灵活性和高效性的体现,但是 Word2Vec 模型却无法处理多义词,一个词语无论表达何种语义,Word2Vec 模型都只能提供相同的词向量,即将多义词编码到了完全相同的参数空间。

实际上在 20 世纪 90 年代初,雅让斯基(Yarowsky)就给出了一个简洁有效的解决方案——运用词语之间的互信息(Mutual Information)。具体来说,对于多义词,可以使用文本中与其同时出现的互信息最大的词语集合来表示不同的语义。例如对于“苹果”,当表示水果时,周围出现的一般就是“超市”、“香蕉”等词语;而表示“苹果公司”时,周围出现的一般就是“手机”、“平板”等词语。因此,在判断多义词究竟表达何种语义时,只需要查看哪个语义对应集合中的词语在上下文中出现的更多就可以了,即通过上下文来判断语义。
在这里插入图片描述

3.3 ELMo 模型

为了更好地解决多义词问题,2018 年研究者提出了 ELMo 模型(Embeddings from Language Models)。与 Word2Vec 模型只能提供静态词向量不同,ELMo 模型会根据上下文动态地调整词语的词向量。

具体来说,ELMo 模型首先对语言模型进行预训练,使得模型掌握编码文本的能力;然后在实际使用时,对于输入文本中的每一个词语,都提取模型各层中对应的词向量拼接起来作为新的词向量。ELMo 模型采用双层双向 LSTM 作为编码器,从两个方向编码词语的上下文信息,相当于将编码层直接封装到了语言模型中。
在这里插入图片描述
训练完成后 ELMo 模型不仅学习到了词向量,还训练好了一个双层双向的 LSTM 编码器。对于输入文本中的词语,可以从第一层 LSTM 中得到包含句法信息的词向量,从第二层 LSTM 中得到包含语义信息的词向量,最终通过加权求和得到每一个词语最终的词向量。

但是 ELMo 模型存在两个缺陷:首先它使用 LSTM 模型作为编码器,而不是当时已经提出的编码能力更强的 Transformer 模型;其次 ELMo 模型直接通过拼接来融合双向抽取特征的做法也略显粗糙。

不久之后,将 ELMo 模型中的 LSTM 更换为 Transformer 的 GPT 模型就出现了。但是 GPT 模型再次追随了 NNLM 的脚步,只通过词语的上文进行预测,这在很大程度上限制了模型的应用场景。例如对于文本分类、阅读理解等任务,如果不把词语的下文信息也嵌入到词向量中就会白白丢掉很多信息。

3.4 BERT 模型

2018 年底随着 BERT 模型(Bidirectional Encoder Representations from Transformers)的出现,这一阶段神经网络语言模型的发展终于出现了一位集大成者,发布时 BERT 模型在 11 个任务上都取得了最好性能。

BERT 模型采用和 GPT 模型类似的两阶段框架,首先对语言模型进行预训练,然后通过微调来完成下游任务。但是,BERT 不仅像 GPT 模型一样采用 Transformer 作为编码器,而且采用了类似 ELMo 模型的双向语言模型结构。因此 BERT 模型不仅编码能力强大,而且对各种下游任务,BERT 模型都可以通过简单地改造输出部分来完成。

在这里插入图片描述
但是 BERT 模型的优点同样也是它的缺陷,由于 BERT 模型采用双向语言模型结构,因而无法直接用于生成文本。

可以看到,从 2003 年 NNLM 模型提出时的无人问津,到 2018 年底 BERT 模型横扫自然语言处理领域,神经网络语言模型的发展也经历了一波三折。在此期间,研究者一直在不断地对前人的工作进行改进,这才取得了 BERT 模型的成功。BERT 模型的出现并非一蹴而就,它不仅借鉴了 ELMo、GPT 等模型的结构与框架,而且延续了 Word2Vec 模型提出的 CBOW 训练方式的思想,可以看作是这一阶段语言模型发展的集大成者。

3.5 大语言模型

除了优化模型结构,研究者发现扩大模型规模也可以提高性能。在保持模型结构以及预训练任务基本不变的情况下,仅仅通过扩大模型规模就可以显著增强模型能力,尤其当规模达到一定程度时,模型甚至展现出了能够解决未见过复杂问题的涌现(Emergent Abilities)能力。例如 175B 规模的 GPT-3 模型只需要在输入中给出几个示例,就能通过上下文学习(In-context Learning)完成各种小样本(Few-Shot)任务,而这是 1.5B 规模的 GPT-2 模型无法做到的。

在规模扩展定律(Scaling Laws)被证明对语言模型有效之后,研究者基于 Transformer 结构不断加深模型深度,构建出了许多大语言模型。
在这里插入图片描述

一个标志性的事件是 2022 年 11 月 30 日 OpenAI 公司发布了面向普通消费者的 ChatGPT 模型(Chat Generative Pre-trained Transformer),它能够记住先前的聊天内容真正像人类一样交流,甚至能撰写诗歌、论文、文案、代码等。发布后,ChatGPT 模型引起了巨大轰动,上线短短 5 天注册用户数就超过 100 万。2023 年一月末,ChatGPT 活跃用户数量已经突破 1 亿,成为史上增长最快的消费者应用。

4. 推理部署

4.1 步骤

  • 将文本预处理为模型可以理解的格式。
  • 将预处理好的文本送入模型。
  • 对模型的预测值进行后处理,输出人类可以理解的格式。

在这里插入图片描述

(1)使用分词器进行预处理

神经网络模型无法直接处理文本,因此首先需要通过预处理环节将文本转换为模型可以理解的数字。具体地,我们会使用每个模型对应的分词器 (tokenizer) 来进行:

  • 将输入切分为词语、子词或者符号(例如标点符号),统称为 tokens;
  • 根据模型的词表将每个 token 映射到对应的 token 编号(就是一个数字);
  • 根据模型的需要,添加一些额外的输入。

我们对输入文本的预处理需要与模型自身预训练时的操作完全一致,只有这样模型才可以正常地工作。注意,每个模型都有特定的预处理操作,如果对要使用的模型不熟悉,可以通过 Model Hub 查询。这里我们使用 AutoTokenizer 类和它的 from_pretrained() 函数,它可以根据指定的模型 checkpoint 名称自动从 Hugging Face 的模型库中下载并加载相应的分词器配置和词汇表。

from transformers import AutoTokenizercheckpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)raw_inputs = ["I've been waiting for a HuggingFace course my whole life.","I hate this so much!",
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
# raw_inputs:要进行分词处理的文本列表。
# padding=True:表示对输入文本进行填充操作,使所有输入序列的长度一致。填充操作通常使用特殊的填充标记(如 [PAD])来实现,以确保所有输入序列可以在同一个批次中进行处理。
# truncation=True:表示对输入文本进行截断操作。如果输入序列的长度超过了模型所能处理的最大长度,将对其进行截断,只保留前一部分。
# return_tensors="pt":表示返回 PyTorch 张量格式的输出。这样处理后的输入数据可以直接用于 PyTorch 模型的输入。
print(inputs)
{'input_ids': tensor([[  101,  1045,  1005,  2310,  2042,  3403,  2005,  1037, 17662, 12172, 2607,  2026,  2878,  2166,  1012,   102],[  101,  1045,  5223,  2023,  2061,  2172,   999,   102,     0,     0,0,     0,     0,     0,     0,     0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]])
}

输出中包含两个键 input_ids 和 attention_mask,其中 input_ids 对应分词之后的 tokens 映射到的数字编号列表,而 attention_mask 则是用来标记哪些 tokens 是被填充的(这里“1”表示是原文,“0”表示是填充字符)。

(2)将预处理好的输入送入模型
所有存储在 HuggingFace Model Hub 上的模型都可以通过 AutoModel / 特定任务类 / Model.from_pretrained() 来加载权重,参数可以是 checkpoint 的名称,也可以是本地路径(预先下载的模型目录)。

部分模型的 Hub 页面中可能会包含很多文件,以防万一,需要全都下载。

预训练模型的本体只包含基础的 Transformer 模块,对于给定的输入,它会输出一些神经元的值,称为 hidden states 或者特征 (features)。对于 NLP 模型来说,可以理解为是文本的高维语义表示。这些 hidden states 通常会被输入到其他的模型部分(称为 head),以完成特定的任务,例如送入到分类头中完成文本分类任务。
在这里插入图片描述
Transformers 包提供了一个 AutoModel 类和对应的 from_pretrained() 函数。

from transformers import AutoModelcheckpoint = "distilbert-base-uncased-finetuned-sst-2-english"
model = AutoModel.from_pretrained(checkpoint)

但是对于有些任务,我们不会使用 AutoModel 类,而是使用针对特定任务的类。例如,情感分析任务,使用的是AutoModelForSequenceClassification。

from transformers import AutoTokenizer
from transformers import AutoModelForSequenceClassificationcheckpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)raw_inputs = ["I've been waiting for a HuggingFace course my whole life.","I hate this so much!",
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
outputs = model(**inputs)
print(outputs.logits.shape)

Transformer 模块的的输出是一个维度为 (Batch size, Sequence length, Hidden size) 的三维张量,其中 Batch size 表示每次输入的样本(文本序列)数量,即每次输入多少个句子。Sequence length 表示文本序列的长度,即每个句子被分为多少个 token。Hidden size 表示每一个 token 经过模型编码后的输出向量(语义表示)的维度。可以通过属性(outputs.last_hidden_state.shape))访问,也可以通过键(outputs[“last_hidden_state”]),甚至索引访问(outputs[0])。

另外,除了使用 AutoModel 根据 checkpoint 自动加载模型以外,我们也可以直接使用模型对应的 Model 类,例如 BERT 对应的就是 BertModel:

from transformers import BertModelmodel = BertModel.from_pretrained("bert-base-cased")

(3) 对模型输出进行后处理

由于模型的输出只是一些数值,因此并不适合人类阅读。

在深度学习,特别是自然语言处理的模型中,logits 是一个非常重要的概念。logits 是模型在进行分类或者生成任务时,最后一层神经元的原始输出值,它是未经过任何归一化处理的数值。在多分类问题中,logits 向量的每个元素对应一个类别,其数值大小表示模型认为输入属于该类别的相对可能性,但这些数值并不是概率值,因为它们没有被约束在 0 到 1 之间,且所有元素之和也不一定为 1。要将他们转换为概率值,还需要让它们经过一个 SoftMax 层。

所有 Transformers 模型都会输出 logits 值,因为训练时的损失函数通常会自动结合激活函数(例如 SoftMax)与实际的损失函数(例如交叉熵 cross entropy)。

outputs = model(**inputs)
print(outputs.logits)
tensor([[-1.5607,  1.6123],[ 4.1692, -3.3464]], grad_fn=<AddmmBackward0>)
predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
print(predictions)
tensor([[4.0195e-02, 9.5980e-01],[9.9946e-01, 5.4418e-04]], grad_fn=<SoftmaxBackward0>)

最后,为了得到对应的标签,可以读取模型 config 中提供的 id2label 属性。

print(model.config.id2label)

4.2 pipeline

除上述之外,我们也可以使用 Transformer 库的 pipeline() 函数,它封装了预训练模型和对应的前处理和后处理环节。我们只需输入文本,就能得到预期的答案。

Transformers 库将目前的 NLP 任务归纳为几下几类:

  • 文本分类:例如情感分析、句子对关系判断等;
  • 对文本中的词语进行分类:例如词性标注 (POS)、命名实体识别 (NER) 等;
  • 文本生成:例如填充预设的模板 (prompt)、预测文本中被遮掩掉 (masked) 的词语;
  • 从文本中抽取答案:例如根据给定的问题从一段文本中抽取出对应的答案;
  • 根据输入文本生成新的句子:例如文本翻译、自动摘要等。

目前常用的 pipelines 有:

  • feature-extraction (获得文本的向量化表示)
  • fill-mask (填充被遮盖的词、片段)
  • ner(命名实体识别)
  • question-answering (自动问答)
  • sentiment-analysis (情感分析)
  • summarization (自动摘要)
  • text-generation (文本生成)
  • translation (机器翻译)
  • zero-shot-classification (零训练样本分类)

pipeline 会自动选择合适的预训练模型来完成任务。Transformers 库会在创建对象时下载并且缓存模型,只有在首次加载模型时才会下载,后续会直接调用缓存好的模型。

我们也可以指定要使用的模型。例如,对于文本生成任务,我们可以在 Model Hub 页面左边选择 Text Generation tag 查询支持的模型。

generator = pipeline("text-generation", model="distilgpt2")

4.2.1 情感分析

我们只需要输入文本,就可以得到其情感标签(积极/消极)以及对应的概率。

from transformers import pipelineclassifier = pipeline("sentiment-analysis")
result = classifier("I've been waiting for a HuggingFace course my whole life.")
print(result)
results = classifier(["I've been waiting for a HuggingFace course my whole life.", "I hate this so much!"]
)
print(results)
No model was supplied, defaulted to distilbert-base-uncased-finetuned-sst-2-english (https://huggingface.co/distilbert-base-uncased-finetuned-sst-2-english)[{'label': 'POSITIVE', 'score': 0.9598048329353333}]
[{'label': 'POSITIVE', 'score': 0.9598048329353333}, {'label': 'NEGATIVE', 'score': 0.9994558691978455}]

4.2.2 零训练样本分类

允许我们在不提供任何标注数据的情况下自定义分类标签。

from transformers import pipelineclassifier = pipeline("zero-shot-classification")
result = classifier(
"This is a course about the Transformers library",
candidate_labels=["education", "politics", "business"],
)
print(result)
No model was supplied, defaulted to facebook/bart-large-mnli (https://huggingface.co/facebook/bart-large-mnli){'sequence': 'This is a course about the Transformers library', 'labels': ['education', 'business', 'politics'], 'scores': [0.8445973992347717, 0.11197526752948761, 0.043427325785160065]}

4.2.3 文本生成

首先根据任务构建一个模板 (prompt),然后将其送入到模型中来生成后续文本。注意,由于文本生成具有随机性,因此每次运行都会得到不同的结果。这种模板被称为前缀模板 (Prefix Prompt)。

from transformers import pipelinegenerator = pipeline("text-generation")
results = generator("In this course, we will teach you how to")
print(results)
results = generator("In this course, we will teach you how to",num_return_sequences=2,max_length=50
) 
print(results)
No model was supplied, defaulted to gpt2 (https://huggingface.co/gpt2)[{'generated_text': "In this course, we will teach you how to use data and models that can be applied in any real-world, everyday situation. In most cases, the following will work better than other courses I've offered for an undergrad or student. In order"}]
[{'generated_text': 'In this course, we will teach you how to make your own unique game called "Mono" from scratch by doing a game engine, a framework and the entire process starting with your initial project. We are planning to make some basic gameplay scenarios and'}, {'generated_text': 'In this course, we will teach you how to build a modular computer, how to run it on a modern Windows machine, how to install packages, and how to debug and debug systems. We will cover virtualization and virtualization without a programmer,'}]

4.2.4 遮盖词填充

给定一段部分词语被遮盖掉 (masked) 的文本,使用预训练模型来预测能够填充这些位置的词语。也需要先构建模板然后运用模型来完善模板,称为填充模板 (Cloze Prompt)。

from transformers import pipelineunmasker = pipeline("fill-mask")
results = unmasker("This course will teach you all about <mask> models.", top_k=2)
print(results)
No model was supplied, defaulted to distilroberta-base (https://huggingface.co/distilroberta-base)[{'sequence': 'This course will teach you all about mathematical models.', 'score': 0.19619858264923096, 'token': 30412, 'token_str': ' mathematical'}, {'sequence': 'This course will teach you all about computational models.', 'score': 0.04052719101309776, 'token': 38163, 'token_str': ' computational'}]

4.2.5 命名实体识别

负责从文本中抽取出指定类型的实体,例如人物、地点、组织等。

from transformers import pipelinener = pipeline("ner", grouped_entities=True)
results = ner("My name is Sylvain and I work at Hugging Face in Brooklyn.")
print(results)
No model was supplied, defaulted to dbmdz/bert-large-cased-finetuned-conll03-english (https://huggingface.co/dbmdz/bert-large-cased-finetuned-conll03-english)[{'entity_group': 'PER', 'score': 0.9981694, 'word': 'Sylvain', 'start': 11, 'end': 18}, {'entity_group': 'ORG', 'score': 0.97960186, 'word': 'Hugging Face', 'start': 33, 'end': 45}, {'entity_group': 'LOC', 'score': 0.99321055, 'word': 'Brooklyn', 'start': 49, 'end': 57}]

模型正确地识别出了 Sylvain 是一个人物,Hugging Face 是一个组织,Brooklyn 是一个地名。

通过设置参数 grouped_entities=True,使得 pipeline 自动合并属于同一个实体的多个子词 (token),例如这里将“Hugging”和“Face”合并为一个组织实体,实际上 Sylvain 也进行了子词合并,因为分词器会将 Sylvain 切分为 S、##yl 、##va 和 ##in 四个 token。

4.2.6 自动问答

根据给定的上下文回答问题。

from transformers import pipelinequestion_answerer = pipeline("question-answering")
answer = question_answerer(question="Where do I work?",context="My name is Sylvain and I work at Hugging Face in Brooklyn",
)
print(answer)
No model was supplied, defaulted to distilbert-base-cased-distilled-squad (https://huggingface.co/distilbert-base-cased-distilled-squad){'score': 0.6949771046638489, 'start': 33, 'end': 45, 'answer': 'Hugging Face'}

这里的自动问答 pipeline 实际上是一个抽取式问答模型,即从给定的上下文中抽取答案,而不是生成答案。

根据形式的不同,自动问答 (QA) 系统可以分为三种:

  • 抽取式 QA (extractive QA):假设答案就包含在文档中,因此直接从文档中抽取答案;
  • 多选 QA (multiple-choice QA):从多个给定的选项中选择答案,相当于做阅读理解题;
  • 无约束 QA (free-form QA):直接生成答案文本,并且对答案文本格式没有任何限制。

4.2.7 自动摘要

将长文本压缩成短文本,并且还要尽可能保留原文的主要信息。

from transformers import pipelinesummarizer = pipeline("summarization")
results = summarizer("""America has changed dramatically during recent years. Not only has the number of graduates in traditional engineering disciplines such as mechanical, civil, electrical, chemical, and aeronautical engineering declined, but in most of the premier American universities engineering curricula now concentrate on and encourage largely the study of engineering science. As a result, there are declining offerings in engineering subjects dealing with infrastructure, the environment, and related issues, and greater concentration on high technology subjects, largely supporting increasingly complex scientific developments. While the latter is important, it should not be at the expense of more traditional engineering.Rapidly developing economies such as China and India, as well as other industrial countries in Europe and Asia, continue to encourage and advance the teaching of engineering. Both China and India, respectively, graduate six and eight times as many traditional engineers as does the United States. Other industrial countries at minimum maintain their output, while America suffers an increasingly serious decline in the number of engineering graduates and a lack of well-educated engineers."""
)
print(results)
No model was supplied, defaulted to sshleifer/distilbart-cnn-12-6 (https://huggingface.co/sshleifer/distilbart-cnn-12-6)[{'summary_text': ' America has changed dramatically during recent years . The number of engineering graduates in the U.S. has declined in traditional engineering disciplines such as mechanical, civil, electrical, chemical, and aeronautical engineering . Rapidly developing economies such as China and India, as well as other industrial countries in Europe and Asia, continue to encourage and advance engineering .'}]

与文本生成类似,我们也可以通过 max_length 或 min_length 参数来控制返回摘要的长度。

相关文章:

自然语言处理——从原理、经典模型到应用

1. 概述 自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是一门借助计算机技术研究人类语言的科学&#xff0c;是人工智能领域的一个分支&#xff0c;旨在让计算机理解、生成和处理人类语言。其核心任务是将非结构化的自然语言转换为机器可以…...

Ollama 运行从 ModelScope 下载的 GGUF 格式的模型

本文系统环境 Windows 10 Ollama 0.5.7 Ollama 是什么&#xff1f; Ollama 可以让你快速集成和部署本地 AI 模型。它支持各种不同的 AI 模型&#xff0c;并允许用户通过简单的 API 进行调用 Ollama 的安装 Ollama 官网 有其下载及安装方法&#xff0c;非常简便 但如果希…...

Haproxy介绍及学习

一、负载均衡(load balance)&#xff1a; 1.一种服务基于硬件设备实现的高可用反向代理技术&#xff0c;将特定的业务分担给指定的一个或者多个后端特定的服务器&#xff0c;提高了业务的并发处理能力保证业务的高可用并方便对业务后期的水平动态扩展性。 2.使用负载均衡的原因…...

【2024年华为OD机试】 (C卷,200分)- 贪心歌手(JavaScriptJava PythonC/C++)

一、问题描述 问题描述 一个歌手需要从A城前往B城参加演出&#xff0c;必须在T天内到达。途中会经过N座城市&#xff0c;且不能往回走。每两座城市之间的行程天数已知。歌手在每座城市都可以卖唱赚钱&#xff0c;但收入会随着停留天数的增加而递减。具体来说&#xff0c;第一…...

深度学习在金融风控中的应用:突破传统模型的瓶颈

深度学习在金融风控中的应用:突破传统模型的瓶颈 金融风险控制(简称“风控”)是现代金融体系中至关重要的一环,关系到金融机构的稳定性、客户的安全以及整体经济的健康运行。近年来,随着深度学习的迅猛发展,传统的风控模型正面临被颠覆的挑战,新的技术手段和思维方式正…...

LLM - 大模型 ScallingLaws 的指导模型设计与实验环境(PLM) 教程(4)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/145323420 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 Scaling Laws (缩放法则) 是大模型领域中,用于描述 模型性能(Loss) 与…...

hunyuan 混元学习

使用了5个subset,也是用了text-image和text-video进行训练的 也是进行了复杂的视频选择。同movie gen. 也进行了模型切断&#xff0c;用拉普拉斯算子找到最清晰的一帧作为训练的起始 训练了不同的模型去选择数据&#xff0c;比如用Dover去选择美观度比较好的数据&#xff0c…...

开发、科研工具汇总

一些基础教程网站 W3&#xff1a;w3school 在线教程 菜鸟&#xff1a;菜鸟教程 - 学的不仅是技术&#xff0c;更是梦想&#xff01; 开发相关参考文档 Vue2&#xff1a;Vue.js Vue3&#xff1a;Vue.js - 渐进式 JavaScript 框架 | Vue.js MDN&#xff1a;MDN Web Docs HT…...

项目部署(springboot项目)

1、安装Nginx&#xff0c;并开启 2、前端项目打包&#xff1a;npm run build:prod--->dist 3、后端项目打包&#xff1a;install--->xxx.jar 4、开放需要的端口号&#xff1a;比如我的后端项目端口号为8282&#xff0c;则需要防火墙和服务器同时开发8282端口 5、将di…...

OpenEuler学习笔记(十四):在OpenEuler上搭建.NET运行环境

一、在OpenEuler上搭建.NET运行环境 基于包管理器安装 添加Microsoft软件源&#xff1a;运行命令sudo rpm -Uvh https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm&#xff0c;将Microsoft软件源添加到系统中&#xff0c;以便后续能够从该源安装.…...

神经网络的通俗介绍

人工神经网络&#xff0c;是一种模仿人类大脑工作原理的数学模型。人类的大脑是由无数的小“工作站”组成的&#xff0c;每个工作站叫做“神经元”。这些神经元通过“电线”互相连接&#xff0c;负责接收、处理和传递信息。 一、人类大脑神经网络 人类大脑的神经网络大概长这…...

基于 AWS SageMaker 对 DeepSeek-R1-Distilled-Llama-8B 模型的精调与实践

在当今人工智能蓬勃发展的时代&#xff0c;语言模型的性能优化和定制化成为研究与应用的关键方向。本文聚焦于 AWS SageMaker 平台上对 DeepSeek-R1-Distilled-Llama-8B 模型的精调实践&#xff0c;详细探讨这一过程中的技术细节、操作步骤以及实践价值。 一、实验背景与目标 …...

如何使用DeepSeek R1

以下是如何使用DeepSeek R1的详细步骤&#xff1a; ### 一、注册DeepSeek账户 1. **访问官方网站**&#xff1a; - 打开浏览器&#xff0c;访问[chat.deepseek.com](http://chat.deepseek.com)。 2. **注册账户**&#xff1a; - 使用电子邮件、Google账户或86手机号码…...

大屏 UI 设计风格的未来趋势

在科技飞速革新的时代&#xff0c;大屏设备的应用领域不断拓展&#xff0c;从城市的智能交通指挥中心&#xff0c;到商场的互动广告大屏&#xff0c;再到家庭的超大尺寸智能电视&#xff0c;大屏已然成为信息展示与交互的关键载体。大屏 UI 设计风格也随之不断演变&#xff0c;…...

unity学习22:Application类其他功能

目录 1 是否允许后台运行 1.1 Application.runInBackground&#xff0c;显示是否允许后台运行 1.2 设置的地方 2 打开URL 2.1 Application.OpenURL("") 打开超链接 3 退出游戏 3.1 Application.Quit() 退出游戏 4 场景相关 5 返回游戏状态 6 控制游戏的行…...

51单片机入门_02_C语言基础0102

C语言基础部分可以参考我之前写的专栏C语言基础入门48篇 以及《从入门到就业C全栈班》中的C语言部分&#xff0c;本篇将会结合51单片机讲差异部分。 课程主要按照以下目录进行介绍。 文章目录 1. 进制转换2. C语言简介3. C语言中基本数据类型4. 标识符与关键字5. 变量与常量6.…...

定位的叠放次序 z-index

浮动定位和绝对定位的区别&#xff1a; 浮动只会压住它下面标准流的盒子&#xff0c;但是不会压住下面标准流盒子里面的文字&#xff0c;但是绝对定位&#xff08;固定定位&#xff09;会压住下面标准流所有的内容。...

ESP32-S3模组上跑通esp32-camera(36)

接前一篇文章:ESP32-S3模组上跑通esp32-camera(35) 一、OV5640初始化 2. 相机初始化及图像传感器配置 上一回继续对reset函数的后一段代码进行解析。为了便于理解和回顾,再次贴出reset函数源码,在components\esp32-camera\sensors\ov5640.c中,如下: static int reset…...

前端性能优化:HMR热更新和预获取加载

最近发现项目开发&#xff0c;有点加载快&#xff0c;有点却是卡机式&#xff0c;甚至刷新导致白屏情况。于是&#xff0c;我找开发和性能优化的方法&#xff0c;找到下面几种。 本文将深入探讨 预获取&#xff08;Prefetch&#xff09;、动态导入&#xff08;Dynamic Import&…...

【自学笔记】计算机网络的重点知识点-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 计算机网络重点知识点一、计算机网络概述二、网络分类三、网络性能指标四、网络协议与体系结构五、数据交换方式六、物理层与数据链路层七、网络层与运输层八、应用…...

算法基础学习——二分查找(附带Java模板)

有单调性的数列一定可以使用二分&#xff0c;没有单调性的题目也可能可以使用二分&#xff1b; &#xff08;一&#xff09;整数二分 二分的本质&#xff1a; 在某个整数区间内&#xff0c;存在某种性质使得区间内左半边的数都不满足该性质&#xff1b;而右半边的数都满足该性…...

【llm对话系统】大模型源码分析之llama模型的long context更长上下文支持

1. 引言 Llama模型的一个重要特性是支持长上下文处理。本文将深入分析Llama源码中实现长上下文的关键技术点&#xff0c;包括位置编码(position embedding)的外推方法、注意力机制的优化等。我们将通过详细的代码解析来理解其实现原理。 2. 位置编码的外推实现 2.1 旋转位置…...

单片机基础模块学习——NE555芯片

一、NE555电路图 NE555也称555定时器,本文主要利用NE555产生方波发生电路。整个电路相当于频率可调的方波发生器。 通过调整电位器的阻值,方波的频率也随之改变。 RB3在开发板的位置如下图 测量方波信号的引脚为SIGHAL,由上面的电路图可知,NE555已经构成完整的方波发生电…...

Hive:struct数据类型,内置函数(日期,字符串,类型转换,数学)

struct STRUCT&#xff08;结构体&#xff09;是一种复合数据类型&#xff0c;它允许你将多个字段组合成一个单一的值, 常用于处理嵌套数据&#xff0c;例如当你需要在一个表中存储有关另一个实体的信息时。你可以使用 STRUCT 函数来创建一个结构体。STRUCT 函数接受多个参数&…...

最优化问题 - 内点法

以下是一种循序推理的方式&#xff0c;来帮助你从基础概念出发&#xff0c;理解 内点法&#xff08;Interior-Point Method, IPM&#xff09; 是什么、为什么要用它&#xff0c;以及它是如何工作的。 1. 问题起点&#xff1a;带不等式约束的优化 假设你有一个带不等式约束的优…...

vim交换文件的工作原理

在vim中&#xff0c;交换文件是一个临时文件&#xff0c;当我们使用vim打开一个文件进行编辑&#xff08;一定得是做出了修改才会产生交换文件&#xff09;时候&#xff0c;vim就会自动创建一个交换文件&#xff0c;而之后我们对于文件的一系列修改都是在交换文件中进行的&…...

CISCO路由基础全集

第一章&#xff1a;交换机的工作原理和基本技能_交换机有操作系统吗-CSDN博客文章浏览阅读1.1k次&#xff0c;点赞24次&#xff0c;收藏24次。交换机可看成是一台特殊的计算机&#xff0c;同样有CPU、存储介质和操作系统&#xff0c;只是与计算机的稍有不同。作为数据交换设备&…...

网络直播时代的营销新策略:基于受众分析与开源AI智能名片2+1链动模式S2B2C商城小程序源码的探索

摘要&#xff1a;随着互联网技术的飞速发展&#xff0c;网络直播作为一种新兴的、极具影响力的媒体形式&#xff0c;正逐渐改变着人们的娱乐方式、消费习惯乃至社交模式。据中国互联网络信息中心数据显示&#xff0c;网络直播用户规模已达到3.25亿&#xff0c;占网民总数的45.8…...

2024年终总结——今年是蜕变的一年

2024年终总结 摘要前因转折找工作工作的成长人生的意义 摘要 2024我从国企出来&#xff0c;兜兜转转还是去了北京&#xff0c;一边是工资低、感情受挫&#xff0c;一边是压力大、项目经历少&#xff0c;让我一度找不到自己梦寐以求的工作&#xff0c;我投了一家又一家&#xff…...

AutoDL 云服务器:普通 用户 miniconda 配置

AutoDL 初始状态下只有root用户&#xff0c;miniconda 安装在root用户目录下 /// 增加普通用户 rootautodl-container-1c0641804d-5bb7040c:~/Desktop# apt updaterootautodl-container-1c0641804d-5bb7040c:~/Desktop# apt install sudorootautodl-container-1c0641804d-5…...