InstructBLIP
概述
InstructBLIP 模型在 Wenliang Dai、Junnan Li、Dongxu Li、Anthony Meng Huat Tiong、Junqi Zhao、Weisheng Wang、Boyang Li、Pascale Fung 和 Steven Hoi 发表的论文 InstructBLIP: Towards General-purpose Vision-Language Models with Instruction Tuning 中被提出。InstructBLIP 利用 BLIP-2 架构进行视觉指令微调。
论文摘要如下:
在预训练和指令微调管道的推动下,能够解决各种语言领域任务的通用语言模型已经出现。然而,由于额外视觉输入带来的任务差异性增加,构建通用视觉语言模型极具挑战性。尽管视觉语言预训练已被广泛研究,但视觉语言指令微调仍然相对较少被探索。在本文中,我们基于预训练的 BLIP-2 模型,对视觉语言指令微调进行了系统而全面的研究。我们收集了 26 个公开可用的数据集,将其转换为指令微调格式,并将其分为两个集群,用于进行指令微调和零样本评估。此外,我们引入了指令感知视觉特征提取,这是一种至关重要的技术,使模型能够提取针对给定指令量身定制的信息特征。最终的 InstructBLIP 模型在所有 13 个保留数据集上都取得了最先进的零样本性能,大大优于 BLIP-2 和更大的 Flamingo 模型。我们的模型在针对单个下游任务进行微调时也取得了最先进的性能(例如,ScienceQA IMG 上的准确率为 90.7%)。此外,我们定性地证明了 InstructBLIP 相比于并发多模态模型的优势。
InstructBLIP 架构。摘自 原始论文。使用技巧
InstructBLIP 使用与 BLIP-2 相同的架构,但有一个细微但重要的区别:它还将文本提示(指令)馈送到 Q-Former。
InstructBlipConfig
类 transformers.InstructBlipConfig
< 源代码 >( vision_config = None qformer_config = None text_config = None num_query_tokens = 32 image_token_index = None **kwargs )
参数
- vision_config (
字典
, 可选) — 用于初始化 InstructBlipVisionConfig 的配置选项字典。 - qformer_config (
字典
, 可选) — 用于初始化 InstructBlipQFormerConfig 的配置选项字典。 - text_config (
字典
, 可选) — 用于初始化任何 PretrainedConfig 的配置选项字典。 - num_query_tokens (
整数
, 可选, 默认为 32) — 通过 Transformer 传递的查询令牌数量。 - image_token_index (
int
, 可选) — 特殊图像标记的标记索引。 - kwargs (可选) — 关键字参数的字典。
InstructBlipConfig 是用于存储 InstructBlipForConditionalGeneration 配置的配置类。它用于根据指定的参数实例化 InstructBLIP 模型,定义视觉模型、Q-Former 模型和语言模型配置。使用默认值实例化配置将产生与 InstructBLIP Salesforce/instruct-blip-flan-t5 架构类似的配置。
配置对象继承自 PretrainedConfig,可用于控制模型输出。阅读 PretrainedConfig 中的文档以获取更多信息。
示例
>>> from transformers import (
... InstructBlipVisionConfig,
... InstructBlipQFormerConfig,
... OPTConfig,
... InstructBlipConfig,
... InstructBlipForConditionalGeneration,
... )
>>> # Initializing a InstructBlipConfig with Salesforce/instruct-blip-flan-t5 style configuration
>>> configuration = InstructBlipConfig()
>>> # Initializing a InstructBlipForConditionalGeneration (with random weights) from the Salesforce/instruct-blip-flan-t5 style configuration
>>> model = InstructBlipForConditionalGeneration(configuration)
>>> # Accessing the model configuration
>>> configuration = model.config
>>> # We can also initialize a InstructBlipConfig from a InstructBlipVisionConfig, InstructBlipQFormerConfig and any PretrainedConfig
>>> # Initializing InstructBLIP vision, InstructBLIP Q-Former and language model configurations
>>> vision_config = InstructBlipVisionConfig()
>>> qformer_config = InstructBlipQFormerConfig()
>>> text_config = OPTConfig()
>>> config = InstructBlipConfig.from_text_vision_configs(vision_config, qformer_config, text_config)
from_vision_qformer_text_configs
< 源代码 >( vision_config: InstructBlipVisionConfig qformer_config: InstructBlipQFormerConfig text_config: PretrainedConfig **kwargs ) → InstructBlipConfig
从 InstructBLIP 视觉模型、Q-Former 和语言模型配置中实例化 InstructBlipConfig(或派生类)。
InstructBlipVisionConfig
类 transformers.InstructBlipVisionConfig
< 源代码 >( hidden_size = 1408 intermediate_size = 6144 num_hidden_layers = 39 num_attention_heads = 16 image_size = 224 patch_size = 14 hidden_act = 'gelu' layer_norm_eps = 1e-06 attention_dropout = 0.0 initializer_range = 1e-10 qkv_bias = True **kwargs )
参数
- hidden_size (
int
, 可选, 默认为 1408) — 编码器层和池化层的维度。 - intermediate_size (
int
, 可选, 默认为 6144) — Transformer 编码器中“中间”(即前馈)层的维度。 - num_hidden_layers (
int
, 可选, 默认为 39) — Transformer 编码器中隐藏层的数量。 - num_attention_heads (
int
,可选,默认为 16) — Transformer 编码器中每个注意力层的注意力头数量。 - image_size (
int
,可选,默认为 224) — 每个图像的大小(分辨率)。 - patch_size (
int
,可选,默认为 14) — 每个补丁的大小(分辨率)。 - hidden_act (
str
或function
,可选,默认为"gelu"
) — 编码器和池化器中的非线性激活函数(函数或字符串)。如果为字符串,则支持"gelu"
、"relu"
、"selu"
和"gelu_new"
"gelu"
。到 1e-5): 层归一化层使用的 epsilon。 - layer_norm_eps (
float
,可选,默认为 1e-06) — 层归一化层使用的 epsilon。 - attention_dropout (
float
,可选,默认为 0.0) — 注意力概率的 dropout 比率。 - initializer_range (
float
,可选,默认为 1e-10) — 用于初始化所有权重矩阵的 truncated_normal_initializer 的标准差。 - qkv_bias (
bool
,可选,默认为True
) — 是否向自注意力层中的查询和值添加偏差。
这是用于存储 InstructBlipVisionModel 配置的配置类。它用于根据指定的参数实例化 InstructBLIP 视觉编码器,定义模型架构。实例化配置默认值将产生与 InstructBLIP Salesforce/instruct-blip-flan-t5 架构类似的配置。
配置对象继承自 PretrainedConfig,可用于控制模型输出。阅读 PretrainedConfig 中的文档以获取更多信息。
示例
>>> from transformers import InstructBlipVisionConfig, InstructBlipVisionModel
>>> # Initializing a InstructBlipVisionConfig with Salesforce/instruct-blip-flan-t5 style configuration
>>> configuration = InstructBlipVisionConfig()
>>> # Initializing a InstructBlipVisionModel (with random weights) from the Salesforce/instruct-blip-flan-t5 style configuration
>>> model = InstructBlipVisionModel(configuration)
>>> # Accessing the model configuration
>>> configuration = model.config
InstructBlipQFormerConfig
类 transformers.InstructBlipQFormerConfig
< 源代码 >( vocab_size = 30522 hidden_size = 768 num_hidden_layers = 12 num_attention_heads = 12 intermediate_size = 3072 hidden_act = 'gelu' hidden_dropout_prob = 0.1 attention_probs_dropout_prob = 0.1 max_position_embeddings = 512 initializer_range = 0.02 layer_norm_eps = 1e-12 pad_token_id = 0 position_embedding_type = 'absolute' cross_attention_frequency = 2 encoder_hidden_size = 1408 **kwargs )
参数
- 词汇量 (
int
, 可选, 默认为 30522) — Q-Former 模型的词汇量。定义了调用模型时传递的inputs_ids
可以表示的不同标记的数量。 - 隐藏层大小 (
int
, 可选, 默认为 768) — 编码器层和池化层的维度。 - 隐藏层数量 (
int
, 可选, 默认为 12) — Transformer 编码器中的隐藏层数量。 - 注意力头数量 (
int
, 可选, 默认为 12) — Transformer 编码器中每个注意力层的注意力头数量。 - 中间层大小 (
int
, 可选, 默认为 3072) — Transformer 编码器中“中间”(通常称为前馈)层的维度。 - 隐藏层激活函数 (
str
或Callable
, 可选, 默认为"gelu"
) — 编码器和池化器中的非线性激活函数(函数或字符串)。如果为字符串,则支持"gelu"
、"relu"
、"silu"
和"gelu_new"
。 - 隐藏层丢弃概率 (
float
, 可选, 默认为 0.1) — 嵌入、编码器和池化器中所有全连接层的丢弃概率。 - 注意力概率丢弃概率 (
float
, 可选, 默认为 0.1) — 注意力概率的丢弃率。 - 最大位置嵌入 (
int
, 可选, 默认为 512) — 此模型可能使用的最大序列长度。通常将此设置为一个较大的值以防万一(例如,512 或 1024 或 2048)。 - pad_token_id (
int
, 可选, 默认为 0) — 用于填充序列的 Token ID。 - position_embedding_type (
str
, 可选, 默认为"absolute"
) — 位置嵌入的类型。选择"absolute"
、"relative_key"
、"relative_key_query"
之一。对于位置嵌入,请使用"absolute"
。有关"relative_key"
的更多信息,请参阅 具有相对位置表示的自注意力 (Shaw 等人)。有关"relative_key_query"
的更多信息,请参阅 使用更好的相对位置嵌入改进 Transformer 模型 (Huang 等人) 中的方法 4。 - cross_attention_frequency (
int
, 可选, 默认为 2) — 向 Transformer 层添加交叉注意力的频率。 - encoder_hidden_size (
int
, 可选, 默认为 1408) — 交叉注意力隐藏状态的隐藏大小。
这是一个配置类,用于存储 InstructBlipQFormerModel 的配置。它用于根据指定的参数实例化 InstructBLIP 查询 Transformer (Q-Former) 模型,定义模型架构。使用默认值实例化配置将产生与 InstructBLIP Salesforce/instruct-blip-flan-t5 架构类似的配置。配置对象继承自 PretrainedConfig,可用于控制模型输出。阅读 PretrainedConfig 中的文档以获取更多信息。
请注意,InstructBlipQFormerModel 与 BertLMHeadModel 非常相似,具有交错的交叉注意力。
示例
>>> from transformers import InstructBlipQFormerConfig, InstructBlipQFormerModel
>>> # Initializing a InstructBLIP Salesforce/instruct-blip-flan-t5 style configuration
>>> configuration = InstructBlipQFormerConfig()
>>> # Initializing a model (with random weights) from the Salesforce/instruct-blip-flan-t5 style configuration
>>> model = InstructBlipQFormerModel(configuration)
>>> # Accessing the model configuration
>>> configuration = model.config
InstructBlipProcessor
类 transformers.InstructBlipProcessor
< 源代码 >( image_processor tokenizer qformer_tokenizer num_query_tokens = None **kwargs )
参数
- image_processor (
BlipImageProcessor
) — BlipImageProcessor 的实例。图像处理器是必需的输入。 - tokenizer (
AutoTokenizer
) — [‘PreTrainedTokenizer`]. 的实例。分词器是必需的输入。
构建一个 InstructBLIP 处理器,它将 BLIP 图像处理器和 LLaMa/T5 分词器封装到一个处理器中。
InstructBlipProcessor 提供了 BlipImageProcessor 和 AutoTokenizer 的所有功能。有关更多信息,请参阅 __call__()
和 decode() 的文档字符串。
此方法将其所有参数转发到 PreTrainedTokenizer 的 batch_decode()。有关更多信息,请参阅此方法的文档字符串。
InstructBlipVisionModel
forward
< 源代码 > ( pixel_values: Optional = None output_attentions: Optional = None output_hidden_states: Optional = None return_dict: Optional = None interpolate_pos_encoding: bool = False ) → transformers.modeling_outputs.BaseModelOutputWithPooling 或 tuple(torch.FloatTensor)
参数
- pixel_values (
torch.FloatTensor
形状为(batch_size, num_channels, height, width)
) — 像素值。可以使用 InstructBlipProcessor 获取像素值。有关详细信息,请参阅InstructBlipProcessor.__call__()
。 - output_attentions (
bool
, 可选) — 是否返回所有注意力层的注意力张量。有关更多详细信息,请参阅返回张量中的attentions
。 - interpolate_pos_encoding (
bool
, 可选, 默认为False
) — 是否插值预训练的位置编码。
返回值
transformers.modeling_outputs.BaseModelOutputWithPooling 或 tuple(torch.FloatTensor)
transformers.modeling_outputs.BaseModelOutputWithPooling 或 torch.FloatTensor
的元组(如果传递了 return_dict=False
或当 config.return_dict=False
时),包含根据配置(<class 'transformers.models.instructblip.configuration_instructblip.InstructBlipVisionConfig'>
)和输入而变化的各种元素。
-
last_hidden_state (
torch.FloatTensor
形状为(batch_size, sequence_length, hidden_size)
) — 模型最后一层输出的隐藏状态序列。 -
pooler_output (
torch.FloatTensor
形状为(batch_size, hidden_size)
) — 序列第一个 token(分类 token)的最后一层隐藏状态,经过用于辅助预训练任务的层进一步处理后得到。例如,对于 BERT 系列模型,这会返回经过线性层和 tanh 激活函数处理后的分类 token。在预训练期间,线性层权重是从下一个句子预测(分类)目标训练得到的。 -
hidden_states (
tuple(torch.FloatTensor)
, 可选, 当传递output_hidden_states=True
或当config.output_hidden_states=True
时返回) —torch.FloatTensor
的元组(如果模型具有嵌入层,则包含嵌入层的输出 + 每层的输出)形状为(batch_size, sequence_length, hidden_size)
。模型在每一层输出处的隐藏状态,加上可选的初始嵌入输出。
-
attentions (
tuple(torch.FloatTensor)
, 可选, 当传递output_attentions=True
或当config.output_attentions=True
时返回) —torch.FloatTensor
的元组(每一层一个)形状为(batch_size, num_heads, sequence_length, sequence_length)
。注意力 softmax 之后的注意力权重,用于计算自注意力头中的加权平均值。
The InstructBlipVisionModel 正向方法,覆盖了 __call__
特殊方法。
尽管正向传递的配方需要在此函数中定义,但之后应该调用 Module
实例而不是此函数,因为前者负责运行预处理和后处理步骤,而后者则静默地忽略它们。
InstructBlipQFormerModel
InstructBLIP 中使用的查询转换器 (Q-Former)。从 BLIP-2 略微修改,因为它还将指令作为输入。
forward
< 源代码 > ( input_ids: LongTensor attention_mask: Optional = None position_ids: Optional = None query_embeds: Optional = None head_mask: Optional = None encoder_hidden_states: Optional = None encoder_attention_mask: Optional = None past_key_values: Optional = None use_cache: Optional = None output_attentions: Optional = None output_hidden_states: Optional = None return_dict: Optional = None )
encoder_hidden_states (torch.FloatTensor
形状为 (batch_size, sequence_length, hidden_size)
, 可选): 编码器最后一层输出的隐藏状态序列。如果模型配置为解码器,则在交叉注意力中使用。encoder_attention_mask (torch.FloatTensor
形状为 (batch_size, sequence_length)
, 可选): 用于避免对编码器输入的填充 token 索引执行注意力的掩码。如果模型配置为解码器,则此掩码用于交叉注意力。在 [0, 1]
中选择掩码值
- 1 表示**未被掩盖**的 token,
- 0 表示**被掩盖**的 token。past_key_values (
tuple(tuple(torch.FloatTensor))
长度为config.n_layers
,每个元组包含 4 个张量: 形状为(batch_size, num_heads, sequence_length - 1, embed_size_per_head)
): 包含注意力块的预计算键和值隐藏状态。可用于加速解码。如果使用past_key_values
,则用户可以选择仅输入形状为(batch_size, 1)
的最后一个decoder_input_ids
(没有给出其过去键值状态的那些)而不是形状为(batch_size, sequence_length)
的所有decoder_input_ids
。use_cache (bool
, 可选): 如果设置为True
,则返回past_key_values
键值状态,可用于加速解码(请参阅past_key_values
)。
InstructBlipForConditionalGeneration
类 transformers.InstructBlipForConditionalGeneration
< 源代码 >( config: InstructBlipConfig )
参数
- config (InstructBlipConfig) — 模型配置类,包含模型的所有参数。使用配置文件初始化不会加载与模型关联的权重,仅加载配置。查看 from_pretrained() 方法以加载模型权重。
用于根据图像和可选文本提示生成文本的 InstructBLIP 模型。该模型由视觉编码器、查询转换器 (Q-Former) 和语言模型组成。
可以选择向模型传递 input_ids
,作为文本提示,使语言模型继续提示。否则,语言模型将从 [BOS](序列开始)标记开始生成文本。
此模型继承自 PreTrainedModel。查看超类文档以了解库为其所有模型实现的通用方法(例如下载或保存、调整输入嵌入的大小、修剪注意力头等)。
此模型也是 PyTorch torch.nn.Module 的子类。将其用作常规 PyTorch 模块,并参考 PyTorch 文档以了解与一般用法和行为相关的所有事项。
forward
< 源代码 > ( pixel_values: FloatTensor qformer_input_ids: FloatTensor qformer_attention_mask: Optional = None input_ids: Optional = None attention_mask: Optional = None decoder_input_ids: Optional = None decoder_attention_mask: Optional = None output_attentions: Optional = None output_hidden_states: Optional = None labels: Optional = None return_dict: Optional = None interpolate_pos_encoding: bool = False ) → transformers.models.instructblip.modeling_instructblip.InstructBlipForConditionalGenerationModelOutput
或 tuple(torch.FloatTensor)
参数
- pixel_values (
torch.FloatTensor
形状为(batch_size, num_channels, height, width)
) — 像素值。可以使用 InstructBlipProcessor 获取像素值。有关详细信息,请参阅InstructBlipProcessor.__call__()
。 - qformer_input_ids (
torch.LongTensor
形状为(batch_size, sequence_length)
,可选) — 词汇表中输入序列标记的索引,用于 Q-Former。可以选择提供输入标记作为文本提示,Q-Former 模型将对其进行编码。可以使用 InstructBlipProcessor 获取索引。有关详细信息,请参阅
InstructBlipProcessor.__call__()
。 - qformer_attention_mask (
torch.Tensor
形状为(batch_size, sequence_length)
,可选) — 用于避免对填充标记索引执行注意力的掩码。掩码值选择在[0, 1]
中:- 1 表示**未掩盖**的标记,
- 0 表示**掩盖**的标记。
- input_ids (
torch.LongTensor
形状为(batch_size, sequence_length)
,可选) — 词汇表中输入序列标记的索引,用于语言模型。可以选择提供输入标记作为文本提示,语言模型可以继续生成。可以使用 InstructBlipProcessor 获取索引。有关详细信息,请参阅
InstructBlipProcessor.__call__()
。 - attention_mask (
torch.Tensor
形状为(batch_size, sequence_length)
,可选) — 用于避免对填充 token 索引执行注意力操作的掩码。掩码值选择在[0, 1]
中:- 1 表示未被掩码的 token,
- 0 表示被掩码的 token。
- decoder_input_ids (
torch.LongTensor
形状为(batch_size, target_sequence_length)
,可选) — 解码器输入序列 token 在语言模型词汇表中的索引。仅当使用编码器-解码器语言模型(如 T5)时才相关。可以使用 AutoTokenizer 获取索引。有关详细信息,请参阅 PreTrainedTokenizer.encode() 和 PreTrainedTokenizer.call()。 什么是解码器输入 ID?
- decoder_attention_mask (
torch.BoolTensor
形状为(batch_size, target_sequence_length)
,可选) — 默认行为:生成一个忽略decoder_input_ids
中填充 token 的张量。因果掩码也将默认使用。仅当使用编码器-解码器语言模型(如 T5)时才相关。
- output_attentions (
bool
,可选) — 是否返回所有注意力层的注意力张量。有关更多详细信息,请参阅返回张量中的attentions
。 - output_hidden_states (
bool
,可选) — 是否返回所有层的隐藏状态。有关更多详细信息,请参阅返回张量中的hidden_states
。 - return_dict (
bool
,可选) — 是否返回 ModelOutput 而不是普通元组。 - interpolate_pos_encoding (
bool
,可选,默认为False
) — 是否插值预训练的位置编码。 - labels (
torch.LongTensor
形状为(batch_size,)
,可选) — 用于计算语言建模损失的标签。索引应在[-100, 0, ..., config.vocab_size - 1]
中。所有设置为-100
的标签都被忽略(掩码),损失仅针对[0, ..., config.vocab_size]
中的标签计算。
返回值
transformers.models.instructblip.modeling_instructblip.InstructBlipForConditionalGenerationModelOutput
或 tuple(torch.FloatTensor)
一个 transformers.models.instructblip.modeling_instructblip.InstructBlipForConditionalGenerationModelOutput
或一个 torch.FloatTensor
的元组(如果传递了 return_dict=False
或当 config.return_dict=False
时),包含取决于配置(<class 'transformers.models.instructblip.configuration_instructblip.InstructBlipVisionConfig'>
)和输入的各种元素。
- loss (
torch.FloatTensor
,可选,当提供labels
时返回,torch.FloatTensor
形状为(1,)
) — 来自语言模型的语言建模损失。 - logits (
torch.FloatTensor
形状为(batch_size, sequence_length, config.vocab_size)
) — 语言模型语言模型头的预测分数。 - vision_outputs (
BaseModelOutputWithPooling
) — 视觉编码器的输出。 - qformer_outputs (
BaseModelOutputWithPoolingAndCrossAttentions
) — Q-Former(查询转换器)的输出。 - language_model_outputs (
CausalLMOutputWithPast
或Seq2SeqLMOutput
) — 语言模型的输出。
InstructBlipForConditionalGeneration 的前向方法覆盖了 __call__
特殊方法。
尽管正向传递的配方需要在此函数中定义,但之后应该调用 Module
实例而不是此函数,因为前者负责运行预处理和后处理步骤,而后者则静默地忽略它们。
示例
>>> from transformers import InstructBlipProcessor, InstructBlipForConditionalGeneration
>>> import torch
>>> from PIL import Image
>>> import requests
>>> model = InstructBlipForConditionalGeneration.from_pretrained("Salesforce/instructblip-vicuna-7b")
>>> processor = InstructBlipProcessor.from_pretrained("Salesforce/instructblip-vicuna-7b")
>>> device = "cuda" if torch.cuda.is_available() else "cpu"
>>> model.to(device)
>>> url = "https://raw.githubusercontent.com/salesforce/LAVIS/main/docs/_static/Confusing-Pictures.jpg"
>>> image = Image.open(requests.get(url, stream=True).raw).convert("RGB")
>>> prompt = "What is unusual about this image?"
>>> inputs = processor(images=image, text=prompt, return_tensors="pt").to(device)
>>> outputs = model.generate(
... **inputs,
... do_sample=False,
... num_beams=5,
... max_length=256,
... min_length=1,
... top_p=0.9,
... repetition_penalty=1.5,
... length_penalty=1.0,
... temperature=1,
... )
>>> generated_text = processor.batch_decode(outputs, skip_special_tokens=True)[0].strip()
>>> print(generated_text)
The unusual aspect of this image is that a man is ironing clothes on the back of a yellow SUV, which is parked in the middle of a busy city street. This is an unconventional approach to ironing clothes, as it requires the man to balance himself and his ironing equipment on top of the vehicle while navigating through traffic. Additionally, the presence of taxis and other vehicles in the scene further emphasizes the unusual nature of this situation.
生成
< 源代码 > ( pixel_values: FloatTensor qformer_input_ids: Optional = None qformer_attention_mask: Optional = None input_ids: Optional = None attention_mask: Optional = None interpolate_pos_encoding: bool = False **generate_kwargs ) → captions (列表)
参数
- pixel_values (
torch.FloatTensor
形状为 (batch_size, num_channels, height, width)) — 要处理的输入图像。 - qformer_input_ids (
torch.LongTensor
形状为 (batch_size, sequence_length),可选) — 用于馈送到 Q-Former 模块的提示序列。 - qformer_attention_mask (
torch.LongTensor
形状为 (batch_size, sequence_length),可选) — 用于避免对填充标记索引执行注意力操作的掩码。 - input_ids (
torch.LongTensor
形状为 (batch_size, sequence_length),可选) — 用于生成任务的提示序列。 - attention_mask (
torch.LongTensor
形状为 (batch_size, sequence_length),可选) — 用于避免对填充标记索引执行注意力操作的掩码。 - interpolate_pos_encoding (
bool
,可选,默认为False
) — 是否对图像嵌入的位置编码进行插值。
返回值
captions (列表)
长度为 batch_size * num_captions 的字符串列表。
重写 generate
函数,以便能够将模型用作条件生成器。