Transformers 文档

创建自定义架构

Hugging Face's logo
加入 Hugging Face 社区

并获得增强文档体验

开始使用

创建自定义架构

一个 AutoClass 会自动推断模型架构并下载预训练的配置和权重。通常,我们建议使用 AutoClass 来生成与检查点无关的代码。但是,想要对特定模型参数有更多控制权的用户,可以通过几个基本类创建自定义的 🤗 Transformers 模型。对于任何想要研究、训练或实验 🤗 Transformers 模型的人来说,这可能特别有用。在本指南中,我们将深入探讨如何在没有 AutoClass 的情况下创建自定义模型。了解如何

  • 加载和定制模型配置。
  • 创建模型架构。
  • 为文本创建快速和慢速分词器。
  • 为视觉任务创建图像处理器。
  • 为音频任务创建特征提取器。
  • 为多模态任务创建处理器。

配置

一个 配置 指的是模型的特定属性。每个模型配置都有不同的属性;例如,所有 NLP 模型都共用 hidden_sizenum_attention_headsnum_hidden_layersvocab_size 属性。这些属性指定了用于构建模型的注意力头或隐藏层的数量。

通过访问 DistilBertConfig 来更仔细地查看 DistilBERT,以检查它的属性。

>>> from transformers import DistilBertConfig

>>> config = DistilBertConfig()
>>> print(config)
DistilBertConfig {
  "activation": "gelu",
  "attention_dropout": 0.1,
  "dim": 768,
  "dropout": 0.1,
  "hidden_dim": 3072,
  "initializer_range": 0.02,
  "max_position_embeddings": 512,
  "model_type": "distilbert",
  "n_heads": 12,
  "n_layers": 6,
  "pad_token_id": 0,
  "qa_dropout": 0.1,
  "seq_classif_dropout": 0.2,
  "sinusoidal_pos_embds": false,
  "transformers_version": "4.16.2",
  "vocab_size": 30522
}

DistilBertConfig 显示了用于构建基本 DistilBertModel 的所有默认属性。所有属性都是可定制的,为实验提供了空间。例如,您可以定制默认模型来

  • 使用 activation 参数尝试不同的激活函数。
  • 使用 attention_dropout 参数为注意力概率设置更高的 dropout 比例。
>>> my_config = DistilBertConfig(activation="relu", attention_dropout=0.4)
>>> print(my_config)
DistilBertConfig {
  "activation": "relu",
  "attention_dropout": 0.4,
  "dim": 768,
  "dropout": 0.1,
  "hidden_dim": 3072,
  "initializer_range": 0.02,
  "max_position_embeddings": 512,
  "model_type": "distilbert",
  "n_heads": 12,
  "n_layers": 6,
  "pad_token_id": 0,
  "qa_dropout": 0.1,
  "seq_classif_dropout": 0.2,
  "sinusoidal_pos_embds": false,
  "transformers_version": "4.16.2",
  "vocab_size": 30522
}

预训练模型属性可以在 from_pretrained() 函数中修改。

>>> my_config = DistilBertConfig.from_pretrained("distilbert/distilbert-base-uncased", activation="relu", attention_dropout=0.4)

一旦您对模型配置满意,就可以使用 save_pretrained() 保存它。您的配置文件将存储在指定保存目录中的 JSON 文件中。

>>> my_config.save_pretrained(save_directory="./your_model_save_path")

要重用配置文件,请使用 from_pretrained() 加载它。

>>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/config.json")

您还可以将配置文件保存为字典,甚至只保存自定义配置属性和默认配置属性之间的差异!有关更多详细信息,请参阅 配置 文档。

模型

下一步是创建一个 模型。模型 - 也被松散地称为架构 - 定义了每一层的作用以及正在执行的操作。来自配置的属性(如 num_hidden_layers)用于定义架构。每个模型都共享基类 PreTrainedModel 和一些通用方法,例如调整输入嵌入的大小和修剪自注意力头。此外,所有模型也都属于 torch.nn.Moduletf.keras.Modelflax.linen.Module 子类。这意味着模型与它们各自框架的用法兼容。

Pytorch
隐藏 Pytorch 内容

将您的自定义配置属性加载到模型中。

>>> from transformers import DistilBertModel

>>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/config.json")
>>> model = DistilBertModel(my_config)

这将创建一个具有随机值而不是预训练权重的模型。在训练之前,您还无法将此模型用于任何有用的事情。训练是一个成本高昂且耗时的过程。通常,最好使用预训练模型来更快地获得更好的结果,同时仅使用训练所需资源的一小部分。

使用 from_pretrained() 创建预训练模型。

>>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased")

当您加载预训练权重时,如果模型由 🤗 Transformers 提供,则会自动加载默认模型配置。但是,如果您愿意,您仍然可以替换一些或全部默认模型配置属性。

>>> model = DistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config)
TensorFlow
隐藏 TensorFlow 内容

将您的自定义配置属性加载到模型中。

>>> from transformers import TFDistilBertModel

>>> my_config = DistilBertConfig.from_pretrained("./your_model_save_path/my_config.json")
>>> tf_model = TFDistilBertModel(my_config)

这将创建一个具有随机值而不是预训练权重的模型。在训练之前,您还无法将此模型用于任何有用的事情。训练是一个成本高昂且耗时的过程。通常,最好使用预训练模型来更快地获得更好的结果,同时仅使用训练所需资源的一小部分。

使用 from_pretrained() 创建预训练模型。

>>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased")

当您加载预训练权重时,如果模型由 🤗 Transformers 提供,则会自动加载默认模型配置。但是,如果您愿意,您仍然可以替换一些或全部默认模型配置属性。

>>> tf_model = TFDistilBertModel.from_pretrained("distilbert/distilbert-base-uncased", config=my_config)

模型头

在这一点上,您拥有一个基础 DistilBERT 模型,它输出隐藏状态。隐藏状态被传递到模型头作为输入,以生成最终输出。 🤗 Transformers 为每个任务提供不同的模型头,只要模型支持该任务(即,您不能将 DistilBERT 用于像翻译这样的序列到序列任务)。

Pytorch
隐藏 Pytorch 内容

例如,DistilBertForSequenceClassification 是一个带有序列分类头的基础 DistilBERT 模型。序列分类头是位于池化输出顶部的线性层。

>>> from transformers import DistilBertForSequenceClassification

>>> model = DistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased")

通过切换到不同的模型头,可以轻松地将此检查点重复用于另一个任务。对于问答任务,您将使用 DistilBertForQuestionAnswering 模型头。问答头类似于序列分类头,除了它位于隐藏状态输出顶部的线性层。

>>> from transformers import DistilBertForQuestionAnswering

>>> model = DistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased")
TensorFlow
隐藏 TensorFlow 内容

例如,TFDistilBertForSequenceClassification 是一个带有序列分类头的基础 DistilBERT 模型。序列分类头是位于池化输出顶部的线性层。

>>> from transformers import TFDistilBertForSequenceClassification

>>> tf_model = TFDistilBertForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased")

通过切换到不同的模型头,可以轻松地将此检查点重复用于另一个任务。对于问答任务,您将使用 TFDistilBertForQuestionAnswering 模型头。问答头类似于序列分类头,除了它位于隐藏状态输出顶部的线性层。

>>> from transformers import TFDistilBertForQuestionAnswering

>>> tf_model = TFDistilBertForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased")

分词器

在将模型用于文本数据之前,您需要的最后一个基类是 分词器,用于将原始文本转换为张量。您可以使用 🤗 Transformers 的两种类型的分词器。

  • PreTrainedTokenizer:分词器的 Python 实现。
  • PreTrainedTokenizerFast:来自我们基于 Rust 的 🤗 Tokenizer 库的分词器。由于其 Rust 实现,这种分词器类型速度明显更快 - 特别是在批次分词期间。快速分词器还提供其他方法,例如偏移映射,它将标记映射到其原始单词或字符。

两种分词器都支持常见的操作,例如编码和解码、添加新标记以及管理特殊标记。

并非所有模型都支持快速分词器。查看此 以检查模型是否具有快速分词器支持。

如果您训练了自己的分词器,则可以从您的词汇表文件中创建一个分词器。

>>> from transformers import DistilBertTokenizer

>>> my_tokenizer = DistilBertTokenizer(vocab_file="my_vocab_file.txt", do_lower_case=False, padding_side="left")

重要的是要记住,自定义分词器的词汇表将与预训练模型的分词器生成的词汇表不同。如果您正在使用预训练模型,则需要使用预训练模型的词汇表,否则输入将毫无意义。使用 DistilBertTokenizer 类使用预训练模型的词汇表创建一个分词器。

>>> from transformers import DistilBertTokenizer

>>> slow_tokenizer = DistilBertTokenizer.from_pretrained("distilbert/distilbert-base-uncased")

使用 DistilBertTokenizerFast 类创建一个快速分词器。

>>> from transformers import DistilBertTokenizerFast

>>> fast_tokenizer = DistilBertTokenizerFast.from_pretrained("distilbert/distilbert-base-uncased")

默认情况下,AutoTokenizer 将尝试加载快速分词器。您可以通过在 from_pretrained 中设置 use_fast=False 来禁用此行为。

图像处理器

图像处理器处理视觉输入。它继承自基础 ImageProcessingMixin 类。

要使用,请创建一个与您所用模型相关的图像处理器。例如,如果您使用 ViT 进行图像分类,请创建一个默认的 ViTImageProcessor

>>> from transformers import ViTImageProcessor

>>> vit_extractor = ViTImageProcessor()
>>> print(vit_extractor)
ViTImageProcessor {
  "do_normalize": true,
  "do_resize": true,
  "image_processor_type": "ViTImageProcessor",
  "image_mean": [
    0.5,
    0.5,
    0.5
  ],
  "image_std": [
    0.5,
    0.5,
    0.5
  ],
  "resample": 2,
  "size": 224
}

如果您不需要任何自定义,只需使用 from_pretrained 方法加载模型的默认图像处理器参数。

修改任何 ViTImageProcessor 参数以创建您的自定义图像处理器

>>> from transformers import ViTImageProcessor

>>> my_vit_extractor = ViTImageProcessor(resample="PIL.Image.BOX", do_normalize=False, image_mean=[0.3, 0.3, 0.3])
>>> print(my_vit_extractor)
ViTImageProcessor {
  "do_normalize": false,
  "do_resize": true,
  "image_processor_type": "ViTImageProcessor",
  "image_mean": [
    0.3,
    0.3,
    0.3
  ],
  "image_std": [
    0.5,
    0.5,
    0.5
  ],
  "resample": "PIL.Image.BOX",
  "size": 224
}

主干

计算机视觉模型由主干、颈部和头部组成。主干从输入图像中提取特征,颈部组合并增强提取的特征,头部用于主要任务(例如,目标检测)。首先在模型配置中初始化一个主干,并指定您是要加载预训练权重还是加载随机初始化的权重。然后,您可以将模型配置传递给模型头部。

例如,要将 ResNet 主干加载到具有实例分割头的 MaskFormer 模型中

<hfoptions id="backbone"> <hfoption id="pretrained weights">

设置 use_pretrained_backbone=True 以加载主干的预训练 ResNet 权重。

from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation

config = MaskFormerConfig(backbone="microsoft/resnet-50", use_pretrained_backbone=True) # backbone and neck config
model = MaskFormerForInstanceSegmentation(config) # head
</hfoption> <hfoption id="random weights">

设置 use_pretrained_backbone=False 以随机初始化 ResNet 主干。

from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation

config = MaskFormerConfig(backbone="microsoft/resnet-50", use_pretrained_backbone=False) # backbone and neck config
model = MaskFormerForInstanceSegmentation(config) # head

您也可以单独加载主干配置,然后将其传递给模型配置。

from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation, ResNetConfig

backbone_config = ResNetConfig()
config = MaskFormerConfig(backbone_config=backbone_config)
model = MaskFormerForInstanceSegmentation(config)
</hfoption> </hfoptions id="timm backbone">

timm 模型使用 use_timm_backbone=TrueTimmBackboneTimmBackboneConfig 加载到模型中。

使用 use_timm_backbone=Trueuse_pretrained_backbone=True 加载主干的预训练 timm 权重。

from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation

config = MaskFormerConfig(backbone="resnet50", use_pretrained_backbone=True, use_timm_backbone=True) # backbone and neck config
model = MaskFormerForInstanceSegmentation(config) # head

设置 use_timm_backbone=Trueuse_pretrained_backbone=False 加载随机初始化的 timm 主干。

from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation

config = MaskFormerConfig(backbone="resnet50", use_pretrained_backbone=False, use_timm_backbone=True) # backbone and neck config
model = MaskFormerForInstanceSegmentation(config) # head

您也可以加载主干配置并使用它来创建 TimmBackbone 或将其传递给模型配置。Timm 主干默认加载预训练权重。设置 use_pretrained_backbone=False 以加载随机初始化的权重。

from transformers import TimmBackboneConfig, TimmBackbone

backbone_config = TimmBackboneConfig("resnet50", use_pretrained_backbone=False)

# Create a backbone class
backbone = TimmBackbone(config=backbone_config)

# Create a model with a timm backbone
from transformers import MaskFormerConfig, MaskFormerForInstanceSegmentation

config = MaskFormerConfig(backbone_config=backbone_config)
model = MaskFormerForInstanceSegmentation(config)

特征提取器

特征提取器处理音频输入。它继承自基础 FeatureExtractionMixin 类,也可能继承自 SequenceFeatureExtractor 类以处理音频输入。

要使用,请创建一个与您所用模型相关的特征提取器。例如,如果您使用 Wav2Vec2 进行音频分类,请创建一个默认的 Wav2Vec2FeatureExtractor

>>> from transformers import Wav2Vec2FeatureExtractor

>>> w2v2_extractor = Wav2Vec2FeatureExtractor()
>>> print(w2v2_extractor)
Wav2Vec2FeatureExtractor {
  "do_normalize": true,
  "feature_extractor_type": "Wav2Vec2FeatureExtractor",
  "feature_size": 1,
  "padding_side": "right",
  "padding_value": 0.0,
  "return_attention_mask": false,
  "sampling_rate": 16000
}

如果您不需要任何自定义,只需使用 from_pretrained 方法加载模型的默认特征提取器参数。

修改任何 Wav2Vec2FeatureExtractor 参数以创建您的自定义特征提取器

>>> from transformers import Wav2Vec2FeatureExtractor

>>> w2v2_extractor = Wav2Vec2FeatureExtractor(sampling_rate=8000, do_normalize=False)
>>> print(w2v2_extractor)
Wav2Vec2FeatureExtractor {
  "do_normalize": false,
  "feature_extractor_type": "Wav2Vec2FeatureExtractor",
  "feature_size": 1,
  "padding_side": "right",
  "padding_value": 0.0,
  "return_attention_mask": false,
  "sampling_rate": 8000
}

处理器

对于支持多模态任务的模型,🤗 Transformers 提供了一个处理器类,它方便地将处理类(如特征提取器和分词器)包装到一个对象中。例如,让我们使用 Wav2Vec2Processor 进行自动语音识别任务 (ASR)。ASR 将音频转录为文本,因此您需要一个特征提取器和一个分词器。

创建一个特征提取器来处理音频输入

>>> from transformers import Wav2Vec2FeatureExtractor

>>> feature_extractor = Wav2Vec2FeatureExtractor(padding_value=1.0, do_normalize=True)

创建一个分词器来处理文本输入

>>> from transformers import Wav2Vec2CTCTokenizer

>>> tokenizer = Wav2Vec2CTCTokenizer(vocab_file="my_vocab_file.txt")

将特征提取器和分词器组合到 Wav2Vec2Processor

>>> from transformers import Wav2Vec2Processor

>>> processor = Wav2Vec2Processor(feature_extractor=feature_extractor, tokenizer=tokenizer)

有了两个基本类 - 配置和模型 - 以及一个额外的预处理类(分词器、图像处理器、特征提取器或处理器),您可以创建 🤗 Transformers 支持的任何模型。这些基础类都是可配置的,允许您使用您想要的特定属性。您可以轻松地设置一个模型进行训练,或者修改现有的预训练模型以进行微调。

< > 在 GitHub 上更新