Hugging Face-Transformers快速指南

这个快速指南将帮助入门,并展示如何使用pipeline()进行推理,使用AutoClass加载预训练模型和预处理器,并使用PyTorch或TensorFlow快速训练模型。

首先安装必要的库,例如transformers、datasets等,还需要安装深度学习框架,PyTorch或者TensorFlow。

Pipeline

pipeline()是使用预训练模型进行推理的最简单方法。可以将pipeline()开箱即用地用于不同模式的许多任务。下面是一些支持的任务:

任务描述Pipeline标识符
文本分类为给定的文本序列分配一个标签pipeline(task=”sentiment-analysis”)
文本生成根据给定的提示生成文本pipeline(task=”text-generation”)
命名实体识别为序列中的每个token分配一个标签(人员、组织、位置等)pipeline(task=”ner”)
问答给定上下文和一个问题,从文本中提取答案pipeline(task=“question-answering”)
填充掩码(Fill-mask)预测序列中正确的掩码标记pipeline(task=“fill-mask”)
摘要生成一系列文本或文档的摘要pipeline(task=“summarization”)
翻译将文本从一种语言翻译成另一种语言pipeline(task=“translation”)
pipeline()支持的NLP任务

首先创建一个pipeline()实例,并指定要使用它执行的任务。可以在前面提到的任何任务中使用pipeline(),要了解它支持的任务的完整列表,请查看pipeline API参考(pipeline API reference)。在本指南中,将使用pipeline()进行情感分析作为示例:

from transformers import pipeline
classifier = pipeline("sentiment-analysis")

pipeline()下载并缓存用于情感分析的默认预训练模型和分词器。现在可以在目标文本上使用分类器了:

classifier("We are very happy to show you the Transformers library.")
输出:[{'label': 'POSITIVE', 'score': 0.9998}]

如果有多个输入,将输入作为列表传递给pipeline(),返回一个字典列表:

results = classifier(["We are very happy to show you the Transformers library.", "We hope you don't hate it."])
for result in results:
    print(f"label: {result['label']}, with score: {round(result['score'], 4)}")
输出:
label: POSITIVE, with score: 0.9998
label: NEGATIVE, with score: 0.5309

pipeline()也可以遍历整个数据集,执行任何喜欢的任务。对于这个例子,选择自动语音识别任务:

import torch
from transformers import pipeline

speech_recognizer = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-960h")

加载想要迭代的音频数据集(更多细节请参阅Datasets  Quick Start)。例如,加载MInDS-14数据集:

from datasets import load_dataset, Audio

dataset = load_dataset("PolyAI/minds14", name="en-US", split="train")

需要确保数据集的采样率与facebook/wav2vec2-base-960h训练的采样率相匹配:

dataset = dataset.cast_column("audio", Audio(sampling_rate=speech_recognizer.feature_extractor.sampling_rate))

调用“audio”列时,音频文件会自动加载并重新采样。从前4个样本中提取原始波形数组,并将其作为一个列表传递给pipeline:

result = speech_recognizer(dataset[:4]["audio"])
print([d["text"] for d in result])
输出:['I WOULD LIKE TO SET UP A JOINT ACCOUNT WITH MY PARTNER HOW DO I PROCEED WITH DOING THAT', "FODING HOW I'D SET UP A JOIN TO HET WITH MY WIFE AND WHERE THE AP MIGHT BE", "I I'D LIKE TOY SET UP A JOINT ACCOUNT WITH MY PARTNER I'M NOT SEEING THE OPTION TO DO IT ON THE AP SO I CALLED IN TO GET SOME HELP CAN I JUST DO IT OVER THE PHONE WITH YOU AND GIVE YOU THE INFORMATION OR SHOULD I DO IT IN THE AP AND I'M MISSING SOMETHING UQUETTE HAD PREFERRED TO JUST DO IT OVER THE PHONE OF POSSIBLE THINGS", 'HOW DO I THURN A JOIN A COUNT']

对于输入较大的大型数据集(如语音或视觉),将需要传递一个生成器而不是列表,以将所有输入加载到内存中。查看pipeline API reference以获取更多信息。

在pipeline中使用其他模型和分词器

pipeline()可以容纳来自Hub的任何模型,因此很容易为其他用例调整pipeline()。例如,如果希望模型能够处理法语文本,则使用Hub上的tags来筛选适当的模型。上面的过滤结果返回一个针对情感分析进行微调的多语言BERT模型,可以将其用于法语文本:

model_name = "nlptown/bert-base-multilingual-uncased-sentiment"

使用AutoModelForSequenceClassificationAutoTokenizer来加载预训练模型及其相关的分词器:

from transformers import AutoTokenizer, AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
classifier = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
classifier("Nous sommes très heureux de vous présenter la bibliothèque Transformers.")
输出:[{'label': '5 stars', 'score': 0.7273}]

如果找不到适合用例的模型,需要在相关的数据上微调一个预训练的模型。可参考微调(finetuning)教程来学习如何操作。最后,在对预训练模型进行微调后,可以考虑将模型分享(sharing )在Hub上的社区。

AutoClass

在底层,AutoModelForSequenceClassification和AutoTokenizer类一起工作,为上面使用的pipeline()提供动力。AutoClass是一种快捷方式,可以从名称或路径自动检索预训练模型的体系结构。只需要为任务选择适当的AutoClass及其相关的预处理类。回到上一节的例子,使用AutoClass来复制pipeline()的结果。

AutoTokenizer

分词器(tokenizer)负责将文本预处理为数字数组,作为模型的输入。有多种规则管理分词过程,包括如何切分单词以及应该在什么级别切分单词(在tokenizer summary中了解有关分词的更多信息)。要记住的最重要的事情是,需要实例化一个具有相同模型名称的分词器,以确保使用的是与预训练模型相同的分词规则。使用AutoTokenizer加载一个分词器:

from transformers import AutoTokenizer

model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
tokenizer = AutoTokenizer.from_pretrained(model_name)
encoding = tokenizer("We are very happy to show you the Transformers library.")
print(encoding)
输出:
{'input_ids': [101, 11312, 10320, 12495, 19308, 10114, 11391, 10855, 10103, 100, 58263, 13299, 119, 102],
 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

分词器返回一个字典,其中包含:input_ids是tokens的数字表示;Attention_mask表示应该处理哪些tokens。分词器还可以接受输入列表,并对文本进行填充和截断,以返回一个长度相同的批处理:

pt_batch = tokenizer(
    ["We are very happy to show you the Transformers library.", "We hope you don't hate it."],
    padding=True,
    truncation=True,
    max_length=512,
    return_tensors="pt",
)

查看预处理(preprocess)教程了解有关tokenization的更多详细信息,以及如何使用AutoImageProcessor、 AutoFeatureExtractorAutoProcessor预处理图像、音频和多模态输入。

AutoModel

Transformers提供了一种简单统一的方法来加载预训练实例。可以像加载AutoTokenizer一样加载AutoModel。唯一的区别是为任务选择正确的AutoModel。有关AutoModel类支持的任务,请参阅task summary。对于文本(或序列)分类,应该加载AutoModelForSequenceClassification:

from transformers import AutoModelForSequenceClassification

model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
pt_model = AutoModelForSequenceClassification.from_pretrained(model_name)

现在将预处理的批量输入直接传递给模型。只需要通过添加**来解压字典:

pt_outputs = pt_model(**pt_batch)

该模型在logits属性中输出最终激活值。对logits应用softmax函数来获取概率:

from torch import nn

pt_predictions = nn.functional.softmax(pt_outputs.logits, dim=-1)
print(pt_predictions)
输出:
tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725],
        [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=<SoftmaxBackward0>)

所有Transformers模型(PyTorch或TensorFlow)在最终激活函数(如softmax)之前输出张量,因为最终激活函数通常与损失融合。模型输出是特殊的数据类,因此它们的属性在IDE中自动补全。模型的输出类似于元组或字典(可以用整数、切片或字符串进行索引),在这种情况下,None属性将被忽略。

保存模型

一旦模型进行了微调,可以使用PreTrainedModel.save_pretrained()将其与分词器一起保存:

pt_save_directory = "./pt_save_pretrained"
tokenizer.save_pretrained(pt_save_directory)
pt_model.save_pretrained(pt_save_directory)

当准备再次使用模型时,使用PreTrainedModel.from_pretrained()重新加载:

pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained")

一个特别酷的Transformers功能是能够保存模型并将其重新加载为PyTorch或TensorFlow模型。from_pt或from_tf参数可以将模型从一个框架转换为另一个框架:

from transformers import AutoModel

tokenizer = AutoTokenizer.from_pretrained(tf_save_directory)
pt_model = AutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True)

自定义模型构建

可以修改模型的配置类以更改模型的构建方式。配置指定模型的属性,如隐藏层或注意力头的数量。当从自定义配置类初始化模型时,将从头开始。模型属性是随机初始化的,在使用模型得到有意义的结果之前,需要对模型进行训练。首先导入AutoConfig,然后加载要修改的预训练模型。在AutoConfig.from_pretrained()中,可以指定要更改的属性,例如注意力头的数量:

from transformers import AutoConfig, AutoModel

my_config = AutoConfig.from_pretrained("distilbert-base-uncased", n_heads=12)
my_model = AutoModel.from_config(my_config)

Trainer——PyTorch优化的训练循环

所有模型都是标准的torch.nn.Module,因此可以在任何典型的训练循环中使用它们。虽然你可以编写自己的训练循环,但Transformers为PyTorch提供了Trainer类,其中包含基本的训练循环,并添加了额外的功能,如分布式训练、混合精度等。根据任务的不同,通常会将以下参数传递给Trainer

1、A PreTrainedModel or a torch.nn.Module

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased")

2、TrainingArguments包含可以更改的模型超参数,如学习率、批大小和要训练的epoch数量。如果不指定任何训练参数,则使用默认值:

from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir="path/to/save/folder/",
    learning_rate=2e-5,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    num_train_epochs=2,
)

3、预处理类,如分词器、图像处理器、特征提取器或处理器:

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")

4、加载数据

from datasets import load_dataset

dataset = load_dataset("rotten_tomatoes")  # doctest: +IGNORE_RESULT

5、创建一个函数对数据集进行分词,并使用map将其应用到整个数据集上:

def tokenize_dataset(dataset):
    return tokenizer(dataset["text"])
dataset = dataset.map(tokenize_dataset, batched=True)

6、使用DataCollatorWithPadding从数据集中创建一批示例:

from transformers import DataCollatorWithPadding

data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

在Trainer中使用所有这些类:

from transformers import Trainer

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
    tokenizer=tokenizer,
    data_collator=data_collator,
)  # doctest: +SKIP

调用train()开始训练:

trainer.train()

对于使用序列到序列模型的任务(如翻译或摘要),请使用Seq2SeqTrainerSeq2SeqTrainingArguments类。

可以通过继承Trainer中的方法来自定义训练循环。允许自定义特性,如损失函数、优化器和调度器(scheduler)。请查看 Trainer参考文档,了解哪些方法可以被子类化。

另一种定制训练循环的方法是使用回调(Callbacks)。您可以使用回调与其他库集成,并检查训练循环以报告进度或提前停止训练。回调不会修改训练循环本身的任何内容。如要自定义类似损失函数,需要继承Trainer

原文链接

https://huggingface.co/docs/transformers/quicktour

Open AI API连接问题

报错信息

raise error.APIConnectionError(
openai.error.APIConnectionError: Error communicating with OpenAI: HTTPSConnectionPool(host=’api.openai.com’, port=443): Max retries exceeded with url: /v1/chat/completions (Caused by ProxyError(‘Cannot connect to proxy.’, NewConnectionError(‘: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。’)))

主要原因为代理的问题,需要魔法

继续阅读Open AI API连接问题

OBS录屏并配音

录制屏幕调研

因需要录制一段屏幕视频因此做了一个小小的调研,一共使用了三种方式录制。

第一种是通过OBS进行录制。OBS的官方网站为:https://obsproject.com/,在官网上下载相对应的客户端之后便可以录制。

第二种是通过谷歌浏览器的插件。参考知乎Chrome 录屏神器!自称“最强大”的屏幕录制和注释工具!这篇文章就可以。录制的感受是清晰度相对较低。

第三种是通过PPT。新建一个空白文档,选择“插入”,再选择“屏幕录制”,然后选择需要录制的区域的步骤即可。录制好之后右击,选择“将媒体另存为”即可保存视频。PPT有个问题是出现在选择区域的相关画面都会被录制进去,比如邮件弹窗,输入法的窗口等。

继续阅读OBS录屏并配音

Linux安装配置OpenJDK1.8

下载、解压JDK

首先下载压缩包

wget https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz

然后解压

tar -zxvf openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz

配置JAVA_HOME环境变量

# 打开环境变量文件
vim .bashrc
# 子文件末尾追加
export JAVA_HOME=/home/user_name/java-se-8u41-ri
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
export PATH=${JAVA_HOME}/jre/bin:$PATH
# source一下,重新加载环境变量
source .bashrc

检查环境安装是否成功

输入:
java -version
输出:
openjdk version "1.8.0_41"
OpenJDK Runtime Environment (build 1.8.0_41-b04)
OpenJDK 64-Bit Server VM (build 25.40-b25, mixed mode)

参考

https://blog.csdn.net/linysuccess/article/details/108881251

论文笔记:Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks

前言

论文:https://arxiv.org/pdf/1908.10084.pdf

代码:https://github.com/UKPLab/sentence-transformers

摘要

BERT和RoBERTa在句子对回归任务,如语义文本相似度(STS)上取得了新的最先进的性能。然而,它需要将两个句子都输入到网络中,这会导致巨大的计算开销:使用BERT在10,000个句子的集合中找到最相似的一对,需要大约5000万次推理计算(~65小时)。BERT的构造使其不适合语义相似性搜索以及聚类等无监督任务。

论文提出sentence -BERT (SBERT),一种预训练BERT网络的修改,使用孪生和三元网络结构来得到有语义的句子嵌入,可以用余弦相似度进行比较。这将寻找最相似的一对的工作量从BERT / RoBERTa的65小时减少到SBERT的大约5秒,同时保持BERT的准确性。

在常见的STS任务和迁移学习任务上评估了SBERT和SRoBERTa,其表现优于其他最先进的句子嵌入方法。

动机

BERT使用交叉编码器:将两个句子传递给transformer网络,并预测目标值。然而,由于可能的组合太多,这种设置不适合各种对回归任务。有些任务到目前为止并不适用于BERT。这些任务包括大规模的语义相似性比较、聚类和基于语义搜索的信息检索。

解决聚类和语义搜索的一种常见方法是将每个句子映射到向量空间,使语义相似的句子接近。研究人员已经开始将单个句子输入到BERT中,并获得固定大小的句子嵌入。最常用的方法是平均BERT输出层(称为BERT嵌入)或使用第一个标记的输出([CLS]标记)。但是,这种常见做法产生了相当糟糕的句子嵌入,通常比平均GloVe嵌入更糟糕。

继续阅读论文笔记:Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks

论文笔记:Deep Short Text Classification with Knowledge Powered Attention

前言

论文:https://arxiv.org/pdf/1902.08050.pdf

代码:https://github.com/AIRobotZhang/STCKA

摘要

短文本分类是自然语言处理(NLP)中的重要任务之一。与段落或文档不同,短文本由于没有足够的上下文信息而更加模糊,这对分类提出了很大的挑战。论文通过从外部知识源检索知识来增强短文本的语义表示。将概念信息作为一种知识,并将其纳入深度神经网络。为了度量知识的重要性,引入了注意机制,并提出了基于知识驱动注意的短文本深度分类(STCKA)。利用概念对短文本(CST)的注意和概念对概念集(C-CS)的注意,从两个方面获取概念的权重。并利用概念信息对短文本进行分类。与传统方法不同的是,STCKA模型就像一个人一样,具有基于观察(即机器的训练数据)做出决策的内在能力,并且更加关注重要的知识。还针对不同的任务在四个公共数据集上进行了广泛的实验。实验结果和案例研究表明,STCKA模型优于最先进的方法,证明了知识驱动注意力的有效性。

挑战

挑战1

相对于段落或文档,短文本由于缺乏足够的上下文信息而具有更强的歧义性,这给短文本分类带来了巨大挑战。短文本分类主要可以分为显式表示和隐式表示两类。

  • 显式模型具有可解释性,便于人类理解。然而,这种显式表示通常忽略了短文本的上下文,无法捕捉深层语义信息。
  • 基于深度神经网络的隐式模型擅长捕捉短文本中的语法和语义信息。然而,它忽略了知识库中存在的isA、isPropertyOf等重要的语义关系。这些信息有助于理解短文本,特别是在处理未见过的单词时。

该文将短文本的显式和隐式表示融合到一个统一的深度神经网络模型中。在YAGO和Freebase等显式KBs的帮助下丰富了短文本的语义表示。这允许模型从短文本中没有明确声明但与分类相关的外部知识源检索知识。概念信息作为一种知识对分类是有帮助的。因此,该文利用isA关系,将短文本与知识库中的相关概念进行概念化关联。然后,将概念信息作为先验知识融入深度神经网络。

挑战2

尽管简单地将概念信息集成到深度神经网络中似乎很直观,但仍然存在两个主要问题。

  • 首先,在对短文本进行概念化时,由于实体的歧义性或KBs中的噪声,容易引入一些不恰当的概念。例如,在短文本S2:“Alice has been using Apple for 10 more years”中,从KB中获取了Apple的fruit和mobile phone两个概念。显然,fruit在这里不是一个合适的概念,这是由于Apple的模糊性造成的。
  • 其次,需要考虑概念的粒度和概念的相对重要性。例如,在短文本S3:“Bill Gates is one of the co-founders of Microsoft”中,从KB中检索了person和entrepreneur of Bill Gates的概念。虽然它们都是正确的概念,但企业家比人更具体,在这种情况下应该被赋予更大的权重。之前的工作利用网络规模的KBs来丰富短文本表示,但没有仔细解决这两个问题。

为了解决这两个问题,该文引入注意力机制,提出了基于知识驱动注意力的深度短文本分类(STCKA)。注意力机制被广泛用于获取向量的权重,在许多NLP应用中,包括机器翻译、摘要生成和问答。针对第一个问题,使用面向短文本的概念注意力(Concept towards Short Text,CST)来衡量短文本与其对应概念之间的语义相似度。该模型赋予S2中mobile phone概念较大的权重,因为它与短文本的语义相似度高于fruit概念。针对第二个问题,使用面向概念集的注意力(Concept towards Concept Set,C-CS)来探索每个概念相对于整个概念集的重要性。模型为S3中的概念企业家分配了更大的权重,这对特定的分类任务更具区分性。

引入一种软开关(soft switch)来将两个注意力权重组合为一个,并产生每个概念的最终注意力权重,该模型在不同的数据集上自适应地学习。然后对概念向量进行加权求和,得到概念表示;此外,充分利用短文本的字和词两级特征,并利用自注意力机制生成短文本表示;最后,根据短文本的表示及其相关概念对短文本进行分类。

继续阅读论文笔记:Deep Short Text Classification with Knowledge Powered Attention

项目整合管理(一)

项目整合管理包括对隶属于项目管理过程组的各种过程和项目管理活动进行识别、定义、组合、统一和协调的各个过程。项目整合管理过程包括:

制定项目章程

编写一份正式批准项目并授权项目经理在项目活动中使用组织资源的文件的过程。本过程的主要作用是,明确项目与组织战略目标之间的直接联系,确立项目的正式地位,并展示组织对项目的承诺。本过程仅开展一次或仅在项目的预定义点开展。

制定项目章程:输入、工具与技术和输出

制定项目管理计划

定义、准备和协调项目计划的所有组成部分,并把它们整合为一份综合项目管理计划的过程。本过程的主要作用是,生成一份综合文件,用于确定所有项目工作的基础及其执行方式,它仅开展一次或仅在项目的预定义点开展。

制定项目管理计划:输入、工具与技术和输出

项目管理计划是说明项目执行、监控和收尾方式的一份文件,它整合并综合了所有子管理计划和基准,以及管理项目所需的其他信息。究竟需要哪些项目管理计划组件,取决于具体项目的需求。项目管理组件包括(但不限于):

项目管理计划是用于管理项目的主要文件之一。管理项目时还会使用其他项目文件。这些其他文件不属于项目管理计划,但它们也是实现高效管理所必需的文件。

项目管理计划项目文件项目文件
1、范围管理计划1、活动属性19、质量控制测量结果
2、需求管理计划2、活动清单20、质量测量指标
3、进度管理计划3、假设日志21、质量报告
4、成本管理计划4、估算依据22、需求文件
5、质量管理计划5、变更日志23、需求跟踪矩阵
6、资源管理计划6、成本估算24、资源分解结构
7、沟通管理计划7、成本预测25、资源日历
8、风险管理计划8、持续时间估算26、资源需求
9、采购管理计划9、问题日志27、风险登记册
10、相关方参与计划10、经验教训登记册28、风险报告
11、变更管理计划11、里程碑清单29、进度数据
12、配置管理计划12、实物资源分配单30、进度预测
13、范围基准13、项目日历31、相关方登记册
14、进度基准14、项目沟通记录32、团队章程
15、成本基准15、项目进度计划33、测试与评估文件
16、绩效测量基准16、项目进度网络图
17、项目生命周期描述17、项目范围说明书
18、开发方法18、项目团队派工单
项目管理计划和项目文件

指导与管理项目工作

为实现项目目标而领导和执行项目管理计划中所确定的工作,并实施已批准变更的过程。本过程的主要作用是,对项目工作和可交付成果开展综合管理,以提高项目成功的可能性。本过程需要在整个项目期间开展。

指导与管理项目工作:输入、工具与技术和输出

管理项目知识

使用现有知识并生成新知识,以实现项目目标,并且帮助组织学习的过程。本过程的主要作用是,利用已有的组织知识来创造或改进项目成果,并且使当前项目创造的知识可用于支持组织运营和未来的项目或阶段。本过程需要在整个项目期间开展。

项目管理知识:输入、工具与技术和输出

BERT的动态量化

简介

使用HuggingFace Transformers示例(the HuggingFace Transformers examples)中的BERT模型,在BERT模型上应用动态量化。通过这一步一步的过程,演示如何将BERT转换为动态量化模型。

  • BERT (Bidirectional Embedding Representations from Transformers)是一种预训练语言表示的方法,它在许多流行的自然语言处理(NLP)任务上取得了最先进的精度结果,如问答、文本分类等。原始论文BERT
  • PyTorch 中的动态量化支持将浮点模型转换为量化模型,其中权重为静态 int8 或 float16 数据类型,激活为动态量化。当权重量化为 int8 时,激活被动态量化(每batch)为 int8。在PyTorch中,torch.quantization.quantize_dynamic API,将指定的模块替换为动态仅权重量化的版本,并输出量化模型。
  • 在通用语言理解评估基准(GLUE)中的Microsoft Research Paraphrase Corpus (MRPC) task上展示了准确性和推理性能结果。MRPC (Dolan and Brockett, 2005)是一个自动从在线新闻源中提取的句子对语料库,并配有人工标注,以判断句子对中的句子是否语义等价。由于类别是不平衡的(正样本为68%,负样本为32%),通常的做法是使用F1指标评估。MRPC是语言对分类的一个常见NLP任务,如下图所示。
继续阅读BERT的动态量化

LSTM的动态量化

简介

量化涉及将模型的权重和激活值从float转换为int,这可以使模型大小跟小和推理的速度更快,而只损失很小的精度。

使用PyTorch示例中的单词语言模型(word language model),将最简单的量化形式,动态量化(dynamic quantization)应用于基于LSTM的下一个单词预测模型。

# imports
import os
from io import open
import time
import torch
import torch.nn as nn
import torch.nn.functional as F

定义模型

按照单词语言模型示例中的模型(model)定义LSTM模型架构。

class LSTMModel(nn.Module):
    """Container module with an encoder, a recurrent module, and a decoder."""

    def __init__(self, ntoken, ninp, nhid, nlayers, dropout=0.5):
        super(LSTMModel, self).__init__()
        self.drop = nn.Dropout(dropout)
        self.encoder = nn.Embedding(ntoken, ninp)
        self.rnn = nn.LSTM(ninp, nhid, nlayers, dropout=dropout)
        self.decoder = nn.Linear(nhid, ntoken)

        self.init_weights()

        self.nhid = nhid
        self.nlayers = nlayers

    def init_weights(self):
        initrange = 0.1
        self.encoder.weight.data.uniform_(-initrange, initrange)
        self.decoder.bias.data.zero_()
        self.decoder.weight.data.uniform_(-initrange, initrange)

    def forward(self, input, hidden):
        emb = self.drop(self.encoder(input))
        output, hidden = self.rnn(emb, hidden)
        output = self.drop(output)
        decoded = self.decoder(output)
        return decoded, hidden

    def init_hidden(self, bsz):
        weight = next(self.parameters())
        return (weight.new_zeros(self.nlayers, bsz, self.nhid),
                weight.new_zeros(self.nlayers, bsz, self.nhid))
继续阅读LSTM的动态量化

PyTorch安装

创建环境

conda create -n env_name python=3.x

可以先使用conda create创建一个虚拟环境,env_name为虚拟环境的名字,3.x为python的版本,例如conda create -n pytorch python=3.8

使用conda activate pytorch激活虚拟环境,conda deactivate退出环境。

CUDA版本

首先查看cuda的版本,nvidia-smi

cuda版本为10.2

官方安装

官方网站:https://pytorch.org/get-started/locally/

在官方网站点选需求可以显示安装的命令,如:

由于没有需要的CUDA版本,因此在以前的版本中寻找https://pytorch.org/get-started/previous-versions/

例如需要安装v1.12.1版本,使用Conda,Linux 或者Windows操作系统,使用如下命令:

# CUDA 10.2
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=10.2 -c pytorch

使用上述方式安装的torch版本如下:

pytorch的后缀带有py3.8_cuda10.2_cudnn7.6.5_0;torchaudio、torchvision的后缀带有py38_cu102。选择y之后就会自动安装。

或者如果使用Wheel,Linux或者Windows操作系统,使用如下命令:

# CUDA 10.2
pip install torch==1.12.1+cu102 torchvision==0.13.1+cu102 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu102

但是官方网站安装pytorch的速度较慢,因此可以选择镜像安装。把-c pytorch表示的pytorch源,更改为国内的镜像。

镜像安装

镜像地址

清华大学:https://mirrors.tuna.tsinghua.edu.cn/

阿里云:http://mirrors.aliyun.com/

镜像地址可以参考https://blog.csdn.net/djzhao627/article/details/122999240

conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=10.2 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/linux-64/

检验

import torch
print(torch.__version__)
print(torch.version.cuda)
print(torch.backends.cudnn.version())
torch.cuda.is_available()      # cuda是否可用;
torch.cuda.device_count()      # 返回gpu数量;
torch.cuda.get_device_name(0)  # 返回gpu名字,设备索引默认从0开始;
torch.cuda.current_device()    # 返回当前设备索引