transformers 框架使用详解,bert-base-chinese

以 bert-base-chinese 模型为例,模型目录 model_name = "C:/Users/Administrator.DESKTOP-TPJL4TC/.cache/modelscope/hub/tiansz/bert-base-chinese"

bert-base-chinese 模型大小只有400多兆,参数的量级在百万级别,与现在动辄几十个G,几十亿几百亿的参数量级不在一个层次,所以 bert 的主要功能是理解语义,它的双向编码其实就是transformer论文中的自注意力的实现。既然能够理解语义,它就能实现一些延伸的能力。

1、两个句子相似度的比较。

2、实现简单的QA,即给它一段话作为context,然后根据这段话提问,它能定位到你这个问题的答案在context中的位置,然后将答案揪出来,当然,它不是generate模型,它的参数量也做不到generate,它只是简单的截取一句话作为最符合的答案。

3、命名实体识别NER

4、在NLP领域,你可以定义很多下游任务,当然要自己实现输出层的逻辑。

transformers的三大组件configuration, tokenizer和model都可以通过一致的from_pertrained()方法来实例化。

Transformers提供了三个主要的组件。

  • Configuration配置类。存储模型和分词器的参数,诸如词表大小,隐层维数,dropout rate等。配置类对深度学习框架是透明的。
  • Tokenizer分词器类。每个模型都有对应的分词器,存储token到index的映射,负责每个模型特定的序列编码解码流程,比如BPE(Byte Pair Encoding),SentencePiece等等。也可以方便地添加特殊token或者调整词表大小,如CLS、SEP等等。
  • Model模型类。提供一个基类,实现模型的计算图和编码过程,实现前向传播过程,通过一系列self-attention层直到最后一个隐藏状态层。在最后一层基础上,根据不同的应用会再做些封装,比如XXXForSequenceClassification,XXXForMaskedLM这些派生类。

Transformers的作者们还为以上组件提供了一系列Auto Classes,能够从一个短的别名(如bert-base-cased)里自动推测出来应该实例化哪种配置类、分词器类和模型类。

Transformers提供两大类的模型架构,一类用于语言生成NLG任务,比如GPT、GPT-2、Transformer-XL、XLNet和XLM,另一类主要用于语言理解任务,如Bert、DistilBert、RoBERTa、XLM.

tokenizer.encode() 方法

经过层层继承,最终的实现是在文件transformers\tokenization_utils_base.py中的 class PreTrainedTokenizerBase(SpecialTokensMixin, PushToHubMixin):

def encode(
        self,
        text: Union[TextInput, PreTokenizedInput, EncodedInput],
        text_pair: Optional[Union[TextInput, PreTokenizedInput, EncodedInput]] = None,
        add_special_tokens: bool = True,
        padding: Union[bool, str, PaddingStrategy] = False,
        truncation: Union[bool, str, TruncationStrategy] = None,
        max_length: Optional[int] = None,
        stride: int = 0,
        padding_side: Optional[bool] = None,
        return_tensors: Optional[Union[str, TensorType]] = None,
        **kwargs,
    ) -> List[int]:
        """
        Converts a string to a sequence of ids (integer), using the tokenizer and vocabulary.

        Same as doing `self.convert_tokens_to_ids(self.tokenize(text))`.

        Args:
            text (`str`, `List[str]` or `List[int]`):
                The first sequence to be encoded. This can be a string, a list of strings (tokenized string using the
                `tokenize` method) or a list of integers (tokenized string ids using the `convert_tokens_to_ids`
                method).
            text_pair (`str`, `List[str]` or `List[int]`, *optional*):
                Optional second sequence to be encoded. This can be a string, a list of strings (tokenized string using
                the `tokenize` method) or a list of integers (tokenized string ids using the `convert_tokens_to_ids`
                method).
        """
        encoded_inputs = self.encode_plus(
            text,
            text_pair=text_pair,
            add_special_tokens=add_special_tokens,
            padding=padding,
            truncation=truncation,
            max_length=max_length,
            stride=stride,
            padding_side=padding_side,
            return_tensors=return_tensors,
            **kwargs,
        )

        return encoded_inputs["input_ids"]

model.eval() 的作用:模型在默认状态下是激活了 Dropout 模块,你此时给他输入数据会导致模型参数发生变化,所以需要调用eval()方法将模型设置为评估(evaluation)模式,deactivate DropOut modules。

python中的 __call__方法

它的作用为:当你把对象当做函数来调用时,例如 objectA(xxx),就会被重定向到__call__方法。

在类PreTrainedTokenizerBase

def __call__(
        self,
        text: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None,
        text_pair: Optional[Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]]] = None,
        text_target: Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None,
        text_pair_target: Optional[
            Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]]
        ] = None,
        add_special_tokens: bool = True,
        padding: Union[bool, str, PaddingStrategy] = False,
        truncation: Union[bool, str, TruncationStrategy] = None,
        max_length: Optional[int] = None,
        stride: int = 0,
        is_split_into_words: bool = False,
        pad_to_multiple_of: Optional[int] = None,
        padding_side: Optional[bool] = None,
        return_tensors: Optional[Union[str, TensorType]] = None,
        return_token_type_ids: Optional[bool] = None,
        return_attention_mask: Optional[bool] = None,
        return_overflowing_tokens: bool = False,
        return_special_tokens_mask: bool = False,
        return_offsets_mapping: bool = False,
        return_length: bool = False,
        verbose: bool = True,
        **kwargs,
    ) -> BatchEncoding:
    	"""
        Main method to tokenize and prepare for the model one or several sequence(s) or one or several pair(s) of sequences.

        Args:
            text (`str`, `List[str]`, `List[List[str]]`, *optional*):
                The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings
                (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set
                `is_split_into_words=True` (to lift the ambiguity with a batch of sequences).
            text_pair (`str`, `List[str]`, `List[List[str]]`, *optional*):
                The sequence or batch of sequences to be encoded. Each sequence can be a string or a list of strings
                (pretokenized string). If the sequences are provided as list of strings (pretokenized), you must set
                `is_split_into_words=True` (to lift the ambiguity with a batch of sequences).
            text_target (`str`, `List[str]`, `List[List[str]]`, *optional*):
                The sequence or batch of sequences to be encoded as target texts. Each sequence can be a string or a
                list of strings (pretokenized string). If the sequences are provided as list of strings (pretokenized),
                you must set `is_split_into_words=True` (to lift the ambiguity with a batch of sequences).
            text_pair_target (`str`, `List[str]`, `List[List[str]]`, *optional*):
                The sequence or batch of sequences to be encoded as target texts. Each sequence can be a string or a
                list of strings (pretokenized string). If the sequences are provided as list of strings (pretokenized),
                you must set `is_split_into_words=True` (to lift the ambiguity with a batch of sequences).
        """
    	...
        ...

此时,你就看到有这样的调用

tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForQuestionAnswering.from_pretrained(model_name)

inputs = tokenizer(question, context, return_tensors="pt")
outputs = model(**inputs)

model() 实际上调用的就是 model.forward() 。

而 tokenizer() 并不是 tokenizer.decode() ,从返回值类型就能看出来。从代码上看,tokenizer() 做了一些判断,返回值为 BatchEncoding;而 tokenizer.decode() 返回值为 BatchEncoding[‘input_ids’],所以也可以

input_ids = tokenizer.encode(question, context, return_tensors="pt")
outputs = model(input_ids)

model = xxx.from_pretrained(model_name) 的问题

同一个模型,可以有不同的下游任务,网络模型包括输入层,中间隐藏层,输出层三部分。我们所说的下游任务就是指输出层,我们拿到隐藏层的最后一层的计算结果之后,就可以在输出层上做些文章以实现不同的功能,所以在实例化模型的时候会有多种方式,AutoModelForxxxx,或者 BertForxxxx,所以 model() 的输出结果就不一样,参数个数也可能不一样,这个要去看它的 forward() 方法。

多去看看代码,基本上都有说明。我们以BertForQuestionAnswering为例

from transformers import BertTokenizer, BertForQuestionAnswering
model = BertForQuestionAnswering.from_pretrained(model_name)
......
outputs = model(**inputs)

类的定义如下

@add_start_docstrings(
    """
    Bert Model with a span classification head on top for extractive question-answering tasks like SQuAD (a linear
    layers on top of the hidden-states output to compute `span start logits` and `span end logits`).
    """,
    BERT_START_DOCSTRING,
)
class BertForQuestionAnswering(BertPreTrainedModel):
    def __init__(self, config):
        ......

    def forward(
        self,
        input_ids: Optional[torch.Tensor] = None,
        attention_mask: Optional[torch.Tensor] = None,
        token_type_ids: Optional[torch.Tensor] = None,
        position_ids: Optional[torch.Tensor] = None,
        head_mask: Optional[torch.Tensor] = None,
        inputs_embeds: Optional[torch.Tensor] = None,
        start_positions: Optional[torch.Tensor] = None,
        end_positions: Optional[torch.Tensor] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
    ) -> Union[Tuple[torch.Tensor], QuestionAnsweringModelOutput]:

从说明就知道此类提供question-answering任务,它的返回值是 Tuple[torch.Tensor] 或者 QuestionAnsweringModelOutput,通过传入的参数 return_dict 来决定返回值类型,默认就是返回Tuple[torch.Tensor] ,它只包含两个值 (sequence_output, pooled_output)

再比如

from transformers import BertTokenizer, AutoModel
model = AutoModel.from_pretrained(model_name)
print(type(model)) # <class 'transformers.models.bert.modeling_bert.BertModel'>

类的定义如下

@add_start_docstrings(
    "The bare Bert Model transformer outputting raw hidden-states without any specific head on top.",
    BERT_START_DOCSTRING,
)
class BertModel(BertPreTrainedModel):
    """

    The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of
    cross-attention is added between the self-attention layers, following the architecture described in [Attention is
    all you need](https://arxiv.org/abs/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit,
    Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin.

    To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set
    to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and
    `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass.
    """

    _no_split_modules = ["BertEmbeddings", "BertLayer"]

    def __init__(self, config, add_pooling_layer=True):
        ......

    def forward(
        self,
        input_ids: Optional[torch.Tensor] = None,
        attention_mask: Optional[torch.Tensor] = None,
        token_type_ids: Optional[torch.Tensor] = None,
        position_ids: Optional[torch.Tensor] = None,
        head_mask: Optional[torch.Tensor] = None,
        inputs_embeds: Optional[torch.Tensor] = None,
        encoder_hidden_states: Optional[torch.Tensor] = None,
        encoder_attention_mask: Optional[torch.Tensor] = None,
        past_key_values: Optional[List[torch.FloatTensor]] = None,
        use_cache: Optional[bool] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
    ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]:

从说明就知道此类只能作为encoder和decoder用,其返回值为 Tuple[torch.Tensor] 或者 BaseModelOutputWithPoolingAndCrossAttentions

@dataclass 的说明

@dataclass
class QuestionAnsweringModelOutput(ModelOutput):
    """
    Base class for outputs of question answering models.

    Args:
        loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
            Total span extraction loss is the sum of a Cross-Entropy for the start and end positions.
        start_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length)`):
            Span-start scores (before SoftMax).
        end_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length)`):
            Span-end scores (before SoftMax).
        hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
            Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, +
            one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`.

            Hidden-states of the model at the output of each layer plus the optional initial embedding outputs.
        attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):
            Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
            sequence_length)`.

            Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
            heads.
    """

    loss: Optional[torch.FloatTensor] = None
    start_logits: torch.FloatTensor = None
    end_logits: torch.FloatTensor = None
    hidden_states: Optional[Tuple[torch.FloatTensor, ...]] = None
    attentions: Optional[Tuple[torch.FloatTensor, ...]] = None

此装饰器的作用相当于定义了一系列的类的属性

def __init__(self, 
    loss: Optional[torch.FloatTensor] = None
    start_logits: torch.FloatTensor = None
    end_logits: torch.FloatTensor = None
    hidden_states: Optional[Tuple[torch.FloatTensor, ...]] = None
    attentions: Optional[Tuple[torch.FloatTensor, ...]] = None
):

@classmethod 的说明

@classmethod
def from_pretrained(
    cls,
    pretrained_model_name_or_path: Union[str, os.PathLike],
    *init_inputs,
    cache_dir: Optional[Union[str, os.PathLike]] = None,
    force_download: bool = False,
    local_files_only: bool = False,
    token: Optional[Union[str, bool]] = None,
    revision: str = "main",
    trust_remote_code=False,
    **kwargs,
):
    ......
    ......

此方法是类的方法,不需要实例化就能访问,且第一个参数是类(cls),而不是对象(self)。此方法可以访问类属性和cls的方法,而不能访问self的方法。

with torch.no_grad() 的作用

torch.no_grad()是PyTorch中的一个上下文管理器(context manager),用于指定在其内部的代码块中不进行梯度计算。当你不需要计算梯度时,可以使用该上下文管理器来提高代码的执行效率,尤其是在推断(inference)阶段和梯度裁剪(grad clip)阶段的时候。不需要进行梯度计算和反向传播,只需要进行前向传播计算。,从而提高计算效率并节省内存。with torch.no_grad()常见于eval()验证集和测试集中。另外,This context manager is thread local; it will not affect computation in other threads.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV基础02_图像预处理

图像预处理 在计算机视觉和图像处理领域&#xff0c;图像预处理是一个重要的步骤&#xff0c;它能够提高后续处理&#xff08;如特征提取、目标检测等&#xff09;的准确性和效率。 OpenCV 提供了许多图像预处理的函数和方法&#xff0c;一些常见的图像预处理操作&#xff1a…

ctf文件上传题小总结与记录

解题思路&#xff1a;先看中间件&#xff0c;文件上传点&#xff08;字典扫描&#xff0c;会员中心&#xff09;&#xff0c;绕过/验证&#xff08;黑名单&#xff0c;白名单&#xff09;&#xff0c;解析漏洞&#xff0c;cms&#xff0c;编辑器&#xff0c;最新cve 文件上传漏…

安全成为大模型的核心;大模型安全的途径:大模型对齐

目录 安全成为大模型的核心 大模型安全的途径:大模型对齐 人类反馈强化学习(RLHF) 直接偏好优化(DPO) 安全成为大模型的核心 大模型安全的途径:大模型对齐 大模型对齐技术(Alignment Techniques for Large Language Models)是确保大规模语言模型(例如GPT-4)的输…

基于知识引导提示的因果概念提取(论文复现)

基于知识引导提示的因果概念提取(论文复现) 本文所涉及所有资源均在传知代码平台可获取 文章目录 基于知识引导提示的因果概念提取(论文复现)论文概述论文方法提示构造器获取典型概念集聚类典型概念构建训练数据训练主题分类器概念提取器输入构造指针网络置信度评分训练损失…

Rust的enum枚举的强大用法

在Rust中&#xff0c;enum&#xff08;枚举&#xff09;是一种非常强大的类型&#xff0c;它可以包含多个变体&#xff08;variants&#xff09;&#xff0c;每个变体可以是不同的类型&#xff0c;包括复杂类型。这使得enum在Rust中不仅用于表示简单的状态或选项集合&#xff0…

vue常用的修饰符有哪些

1、修饰符是什么 在Vue 中&#xff0c;修饰符处理了许多 DOM 事件的细节&#xff0c;让我们不再需要花大量的时间去处理这些烦恼的事情&#xff0c;而能有更多的精力专注于程序的逻辑处理 vue中修饰符分为以下五种 汇总修饰符说明表单lazy光标离开标签的时候&#xff0c;才会…

【创建型】单例模式

单例模式使用的场景&#xff1a;需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即&#xff1a;重量级对象)&#xff0c;但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等) 1. 饿汉式&#xff08;静态常量&#xf…

如何在Linux命令行中使用GhatGPT

2、验明正身&#xff0c;证明我的所在地是国内 3、第一次提问 4、第二次提问 5、问他一首古诗 6、话不多说&#xff0c;现在来展示他的安装过程 7、输入GitHub的网址 https://github.com/aandrew-me/tgpt 8、详情页向下翻 9、到终端输入 下列命令&#xff0c;等待安装&#x…

《机器人SLAM导航核心技术与实战》第1季:第10章_其他SLAM系统

视频讲解 【第1季】10.第10章_其他SLAM系统-视频讲解 【第1季】10.1.第10章_其他SLAM系统_RTABMAP算法 【第1季】10.2.第10章_其他SLAM系统_VINS算法 【第1季】10.3.第10章_其他SLAM系统_机器学习与SLAM 第1季&#xff1a;第10章_其他SLAM系统 先 导 课 第 1 季 &#xff…

比较36个结构的迭代次数

(A,B)---6*30*2---(0,1)(1,0) 让A是结构1&#xff0c;让B全是0。收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值&#xff0c;得到28080.98 做一个同样的网络(A,B)---6*30*2---(0,1)(1,0)&#xff0c;让A分是结构1-12&#xff0c;B全是0&#xff0c;用结构1的收敛权重做…

8. 数据结构——邻接表、邻接矩阵的基本操作

一、邻接表 1. 内容 2. 实现代码(直接可以复制使用) //邻接表的相关操作 #include<bits/stdc.h> #define MVnum 100 #define OK 1 #define ERROR -1 using namespace std;typedef int Status; typedef char VerTexType; //假设顶点的数据类型为char typedef int ArcT…

Kafka 基础入门

文章内容是学习过程中的知识总结&#xff0c;如有纰漏&#xff0c;欢迎指正 文章目录 前言 1. 核心概念 1.1 Producer 1.2 broker 1.3 consumer 1.4 zookeeper 1.5 controller 1.6 Cluster 2. 逻辑组件 2.1 Topic 2.2 Partition 2.3 Replication 2.4 leader & follower 3. …

qt QDialog详解

1、概述 QDialog是Qt框架中用于创建对话框的类&#xff0c;它继承自QWidget。QDialog提供了一个模态或非模态的对话框&#xff0c;用于与用户进行交互。模态对话框会阻塞其他窗口的输入&#xff0c;直到用户关闭该对话框&#xff1b;而非模态对话框则允许用户同时与多个窗口进…

从0开始学PHP面向对象内容之(类,对象,构造/析构函数)

上期我们讲了面向对象的一些基本信息&#xff0c;这期让我们详细的了解一下 一、面向对象—类 1、PHP类的定义语法&#xff1a; <?php class className {var $var1;var $var2 "constant string";function classfunc ($arg1, $arg2) {[..]}[..] } ?>2、解…

双向链表及如何使用GLib的GList实现双向链表

双向链表是一种比单向链表更为灵活的数据结构&#xff0c;与单向链表相比可以有更多的应用场景&#xff0c;本文讨论双向链表的基本概念及实现方法&#xff0c;并着重介绍使用GLib的GList实现单向链表的方法及步骤&#xff0c;本文给出了多个实际范例源代码&#xff0c;旨在帮助…

一键搞定表格文件管理与转换,轻松将XLS格式的表格文件转换为TXT格式的文本文档,办公软件是提高工作效率的方法

在办公的海洋里&#xff0c;表格文件如同繁星点点&#xff0c;而XLS格式更是其中的璀璨明珠。但有时候&#xff0c;我们需要将这些明珠的光芒以另一种形式展现——比如&#xff0c;转换成TXT格式的文本文档。这时&#xff0c;首助编辑高手软件就像一位魔法师&#xff0c;轻轻一…

初始Docker

概述&#xff1a; 容器&#xff0c;作为云原生技术的重要组成部分&#xff0c;与虚拟机一样&#xff0c;均属于虚拟化技术的范畴。然而&#xff0c;容器技术以其独特的优势&#xff0c;在虚拟化领域中脱颖而出。与虚拟机不同&#xff0c;容器能够摆脱操作系统的束缚&#xff0…

TikTok如何用邮箱注册?用哪种邮箱比较好?

要在TikTok上创建一个账号&#xff0c;首先需要进行注册&#xff0c;这是一个简单但至关重要的步骤。在本篇文章中&#xff0c;我们将详细介绍如何用邮箱注册TikTok的整个过程&#xff0c;包括每个步骤的细节和注意事项。此外&#xff0c;我们还将讨论选择哪种邮箱比较好&#…

输电线路绝缘子缺陷分割系统:轻松训练模式

输电线路绝缘子缺陷分割系统源码&#xff06;数据集分享 [yolov8-seg&#xff06;yolov8-seg-C2f-MSBlock等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global Al …

flink 自定义kudu connector中使用Metrics计数平均吞吐量,并推送到自定义kafkaReporter

文章目录 前言1. Registering metrics2. Metrics 的类型2.1 counter2.2 Gauge2.3 Histogram2.4 meter 3. 指标划分3.1 指标所属的范围3.2 默认所属 4. 自定义kudu connector中使用Metrics4.1 sink算子继承RichFunction4.2 注册指标4.3 计数逻辑4.4 自定义Reporter&#xff0c;推…