Transformers 4.37 中文文档(六)(2)https://developer.aliyun.com/article/1564080
生成
文本生成策略
原文:
huggingface.co/docs/transformers/v4.37.2/en/generation_strategies
文本生成对于许多 NLP 任务至关重要,例如开放式文本生成、摘要、翻译等。它还在各种混合模态应用中发挥作用,这些应用的输出是文本,如语音转文本和视觉转文本。一些可以生成文本的模型包括 GPT2、XLNet、OpenAI GPT、CTRL、TransformerXL、XLM、Bart、T5、GIT、Whisper。
查看一些使用 generate()方法为不同任务生成文本输出的示例:
- 文本摘要
- 图像标题
- 音频转录
请注意,生成方法的输入取决于模型的模态。它们由模型的预处理器类返回,例如 AutoTokenizer 或 AutoProcessor。如果模型的预处理器创建多种类型的输入,请将所有输入传递给 generate()。您可以在相应模型的文档中了解更多关于各个模型的预处理器的信息。
选择生成文本的输出标记的过程称为解码,您可以自定义generate()
方法将使用的解码策略。修改解码策略不会改变任何可训练参数的值。但是,它可能会显著影响生成输出的质量。它可以帮助减少文本中的重复,并使其更连贯。
本指南描述:
- 默认生成配置
- 常见的解码策略及其主要参数
- 在🤗 Hub 上保存和共享自定义生成配置与您的微调模型
默认文本生成配置
模型的解码策略在其生成配置中定义。在管道内使用预训练模型进行推断时,模型调用PreTrainedModel.generate()
方法,在幕后应用默认生成配置。当没有保存自定义配置与模型一起时,也会使用默认配置。
当您显式加载模型时,您可以通过model.generation_config
检查随之提供的生成配置:
>>> from transformers import AutoModelForCausalLM >>> model = AutoModelForCausalLM.from_pretrained("distilgpt2") >>> model.generation_config GenerationConfig { "bos_token_id": 50256, "eos_token_id": 50256, }
打印出model.generation_config
只显示与默认生成配置不同的值,并不列出任何默认值。
默认生成配置限制输出与输入提示的组合大小最多为 20 个标记,以避免遇到资源限制。默认解码策略是贪婪搜索,这是一种最简单的解码策略,它选择具有最高概率的标记作为下一个标记。对于许多任务和小输出大小,这种方法效果很好。然而,当用于生成较长的输出时,贪婪搜索可能会开始产生高度重复的结果。
自定义文本生成
您可以通过直接将参数及其值传递给generate
方法来覆盖任何generation_config
:
>>> my_model.generate(**inputs, num_beams=4, do_sample=True)
即使默认解码策略对您的任务大部分有效,您仍然可以微调一些内容。一些常调整的参数包括:
max_new_tokens
:要生成的标记的最大数量。换句话说,输出序列的大小,不包括提示中的标记。作为使用输出长度作为停止标准的替代方案,您可以选择在完整生成超过某个时间量时停止生成。要了解更多信息,请查看 StoppingCriteria。num_beams
:通过指定高于 1 的波束数量,您实际上是从贪婪搜索切换到波束搜索。这种策略在每个时间步评估几个假设,最终选择具有整个序列的最高概率的假设。这有一个优点,可以识别以较低概率初始标记开头的高概率序列,并且会被贪婪搜索忽略。do_sample
:如果设置为True
,此参数将启用解码策略,如多项式采样、波束搜索多项式采样、Top-K 采样和 Top-p 采样。所有这些策略从整个词汇表的概率分布中选择下一个标记,具有各种特定策略的调整。num_return_sequences
:要为每个输入返回的序列候选数。此选项仅适用于支持多个序列候选的解码策略,例如波束搜索和采样的变体。贪婪搜索和对比搜索等解码策略返回单个输出序列。
保存带有您的模型的自定义解码策略
如果您想要与特定生成配置共享您微调的模型,您可以:
- 创建一个 GenerationConfig 类实例
- 指定解码策略参数
- 使用 GenerationConfig.save_pretrained()保存您的生成配置,确保将其
config_file_name
参数留空 - 将
push_to_hub
设置为True
,将您的配置上传到模型的存储库
>>> from transformers import AutoModelForCausalLM, GenerationConfig >>> model = AutoModelForCausalLM.from_pretrained("my_account/my_model") >>> generation_config = GenerationConfig( ... max_new_tokens=50, do_sample=True, top_k=50, eos_token_id=model.config.eos_token_id ... ) >>> generation_config.save_pretrained("my_account/my_model", push_to_hub=True)
您还可以在单个目录中存储多个生成配置,利用 GenerationConfig.save_pretrained()中的config_file_name
参数。您可以稍后使用 GenerationConfig.from_pretrained()实例化它们。如果您想为单个模型存储多个生成配置(例如,一个用于采样的创意文本生成,一个用于波束搜索的摘要),则必须具有正确的 Hub 权限以向模型添加配置文件。
>>> from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, GenerationConfig >>> tokenizer = AutoTokenizer.from_pretrained("t5-small") >>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-small") >>> translation_generation_config = GenerationConfig( ... num_beams=4, ... early_stopping=True, ... decoder_start_token_id=0, ... eos_token_id=model.config.eos_token_id, ... pad_token=model.config.pad_token_id, ... ) >>> # Tip: add `push_to_hub=True` to push to the Hub >>> translation_generation_config.save_pretrained("/tmp", "translation_generation_config.json") >>> # You could then use the named generation config file to parameterize generation >>> generation_config = GenerationConfig.from_pretrained("/tmp", "translation_generation_config.json") >>> inputs = tokenizer("translate English to French: Configuration files are easy to use!", return_tensors="pt") >>> outputs = model.generate(**inputs, generation_config=generation_config) >>> print(tokenizer.batch_decode(outputs, skip_special_tokens=True)) ['Les fichiers de configuration sont faciles à utiliser!']
流式传输
generate()
支持流式传输,通过其streamer
输入。streamer
输入与具有以下方法的类的任何实例兼容:put()
和end()
。在内部,put()
用于推送新标记,end()
用于标记文本生成的结束。
流媒体类的 API 仍在开发中,可能会在未来发生变化。
实际上,您可以为各种目的制作自己的流式传输类!我们还为您准备了基本的流式传输类供您使用。例如,您可以使用 TextStreamer 类将generate()
的输出流式传输到屏幕上,每次一个词:
>>> from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer >>> tok = AutoTokenizer.from_pretrained("gpt2") >>> model = AutoModelForCausalLM.from_pretrained("gpt2") >>> inputs = tok(["An increasing sequence: one,"], return_tensors="pt") >>> streamer = TextStreamer(tok) >>> # Despite returning the usual output, the streamer will also print the generated text to stdout. >>> _ = model.generate(**inputs, streamer=streamer, max_new_tokens=20) An increasing sequence: one, two, three, four, five, six, seven, eight, nine, ten, eleven,
解码策略
某些generate()
参数的组合,最终generation_config
可以用于启用特定的解码策略。如果您对这个概念还不熟悉,我们建议阅读这篇博文,展示了常见的解码策略如何工作。
在这里,我们将展示控制解码策略的一些参数,并说明如何使用它们。
贪婪搜索
generate
默认使用贪婪搜索解码,因此您无需传递任何参数来启用它。这意味着参数num_beams
设置为 1,do_sample=False
。
>>> from transformers import AutoModelForCausalLM, AutoTokenizer >>> prompt = "I look forward to" >>> checkpoint = "distilgpt2" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> inputs = tokenizer(prompt, return_tensors="pt") >>> model = AutoModelForCausalLM.from_pretrained(checkpoint) >>> outputs = model.generate(**inputs) >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ['I look forward to seeing you all again!\n\n\n\n\n\n\n\n\n\n\n']
对比搜索
对比搜索解码策略是在 2022 年的论文A Contrastive Framework for Neural Text Generation中提出的。它展示了生成非重复但连贯的长输出的优越结果。要了解对比搜索的工作原理,请查看这篇博客文章。启用和控制对比搜索行为的两个主要参数是penalty_alpha
和top_k
:
>>> from transformers import AutoTokenizer, AutoModelForCausalLM >>> checkpoint = "gpt2-large" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> model = AutoModelForCausalLM.from_pretrained(checkpoint) >>> prompt = "Hugging Face Company is" >>> inputs = tokenizer(prompt, return_tensors="pt") >>> outputs = model.generate(**inputs, penalty_alpha=0.6, top_k=4, max_new_tokens=100) >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ['Hugging Face Company is a family owned and operated business. We pride ourselves on being the best in the business and our customer service is second to none.\n\nIf you have any questions about our products or services, feel free to contact us at any time. We look forward to hearing from you!']
多项式抽样
与总是选择具有最高概率的标记作为下一个标记的贪婪搜索相反,多项式抽样(也称为祖先抽样)根据模型给出的整个词汇表上的概率分布随机选择下一个标记。每个具有非零概率的标记都有被选择的机会,从而降低重复的风险。
要启用多项式抽样,请设置do_sample=True
和num_beams=1
。
>>> from transformers import AutoTokenizer, AutoModelForCausalLM, set_seed >>> set_seed(0) # For reproducibility >>> checkpoint = "gpt2-large" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> model = AutoModelForCausalLM.from_pretrained(checkpoint) >>> prompt = "Today was an amazing day because" >>> inputs = tokenizer(prompt, return_tensors="pt") >>> outputs = model.generate(**inputs, do_sample=True, num_beams=1, max_new_tokens=100) >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ['Today was an amazing day because when you go to the World Cup and you don\'t, or when you don\'t get invited, that\'s a terrible feeling."']
束搜索解码
与贪婪搜索不同,束搜索解码在每个时间步保留几个假设,并最终选择整个序列的总体概率最高的假设。这有助于识别以较低概率初始标记开头的高概率序列,这些序列在贪婪搜索中会被忽略。
要启用这种解码策略,请指定num_beams
(即要跟踪的假设数量)大于 1。
>>> from transformers import AutoModelForCausalLM, AutoTokenizer >>> prompt = "It is astonishing how one can" >>> checkpoint = "gpt2-medium" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> inputs = tokenizer(prompt, return_tensors="pt") >>> model = AutoModelForCausalLM.from_pretrained(checkpoint) >>> outputs = model.generate(**inputs, num_beams=5, max_new_tokens=50) >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ['It is astonishing how one can have such a profound impact on the lives of so many people in such a short period of time."\n\nHe added: "I am very proud of the work I have been able to do in the last few years.\n\n"I have']
束搜索多项式抽样
正如其名称所示,这种解码策略将束搜索与多项式抽样结合在一起。您需要指定num_beams
大于 1,并设置do_sample=True
以使用这种解码策略。
>>> from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, set_seed >>> set_seed(0) # For reproducibility >>> prompt = "translate English to German: The house is wonderful." >>> checkpoint = "t5-small" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> inputs = tokenizer(prompt, return_tensors="pt") >>> model = AutoModelForSeq2SeqLM.from_pretrained(checkpoint) >>> outputs = model.generate(**inputs, num_beams=5, do_sample=True) >>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'Das Haus ist wunderbar.'
多样束搜索解码
多样束搜索解码策略是束搜索策略的扩展,允许生成更多样化的束序列供选择。要了解其工作原理,请参考Diverse Beam Search: Decoding Diverse Solutions from Neural Sequence Models。这种方法有三个主要参数:num_beams
、num_beam_groups
和diversity_penalty
。多样性惩罚确保输出在组间是不同的,并且在每个组内使用束搜索。
>>> from transformers import AutoTokenizer, AutoModelForSeq2SeqLM >>> checkpoint = "google/pegasus-xsum" >>> prompt = ( ... "The Permaculture Design Principles are a set of universal design principles " ... "that can be applied to any location, climate and culture, and they allow us to design " ... "the most efficient and sustainable human habitation and food production systems. " ... "Permaculture is a design system that encompasses a wide variety of disciplines, such " ... "as ecology, landscape design, environmental science and energy conservation, and the " ... "Permaculture design principles are drawn from these various disciplines. Each individual " ... "design principle itself embodies a complete conceptual framework based on sound " ... "scientific principles. When we bring all these separate principles together, we can " ... "create a design system that both looks at whole systems, the parts that these systems " ... "consist of, and how those parts interact with each other to create a complex, dynamic, " ... "living system. Each design principle serves as a tool that allows us to integrate all " ... "the separate parts of a design, referred to as elements, into a functional, synergistic, " ... "whole system, where the elements harmoniously interact and work together in the most " ... "efficient way possible." ... ) >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> inputs = tokenizer(prompt, return_tensors="pt") >>> model = AutoModelForSeq2SeqLM.from_pretrained(checkpoint) >>> outputs = model.generate(**inputs, num_beams=5, num_beam_groups=5, max_new_tokens=30, diversity_penalty=1.0) >>> tokenizer.decode(outputs[0], skip_special_tokens=True) 'The Design Principles are a set of universal design principles that can be applied to any location, climate and culture, and they allow us to design the'
本指南说明了启用各种解码策略的主要参数。generate
方法还有更高级的参数,可以进一步控制generate
方法的行为。有关可用参数的完整列表,请参考 API 文档。
推测解码
推测解码(也称为辅助解码)是上述解码策略的修改版本,它使用一个助理模型(理想情况下是一个更小的模型)与相同的分词器,生成一些候选标记。然后主模型在单个前向传递中验证候选标记,从而加快解码过程。如果do_sample=True
,则使用推测解码论文中引入的重新抽样进行标记验证。
目前,只支持贪婪搜索和抽样与辅助解码,并且辅助解码不支持批量输入。要了解更多关于辅助解码的信息,请查看这篇博客文章。
要启用辅助解码,请使用一个模型设置assistant_model
参数。
>>> from transformers import AutoModelForCausalLM, AutoTokenizer >>> prompt = "Alice and Bob" >>> checkpoint = "EleutherAI/pythia-1.4b-deduped" >>> assistant_checkpoint = "EleutherAI/pythia-160m-deduped" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> inputs = tokenizer(prompt, return_tensors="pt") >>> model = AutoModelForCausalLM.from_pretrained(checkpoint) >>> assistant_model = AutoModelForCausalLM.from_pretrained(assistant_checkpoint) >>> outputs = model.generate(**inputs, assistant_model=assistant_model) >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ['Alice and Bob are sitting in a bar. Alice is drinking a beer and Bob is drinking a']
在使用辅助解码与抽样方法时,您可以使用temperature
参数来控制随机性,就像在多项式抽样中一样。然而,在辅助解码中,降低温度可能有助于提高延迟。
>>> from transformers import AutoModelForCausalLM, AutoTokenizer, set_seed >>> set_seed(42) # For reproducibility >>> prompt = "Alice and Bob" >>> checkpoint = "EleutherAI/pythia-1.4b-deduped" >>> assistant_checkpoint = "EleutherAI/pythia-160m-deduped" >>> tokenizer = AutoTokenizer.from_pretrained(checkpoint) >>> inputs = tokenizer(prompt, return_tensors="pt") >>> model = AutoModelForCausalLM.from_pretrained(checkpoint) >>> assistant_model = AutoModelForCausalLM.from_pretrained(assistant_checkpoint) >>> outputs = model.generate(**inputs, assistant_model=assistant_model, do_sample=True, temperature=0.5) >>> tokenizer.batch_decode(outputs, skip_special_tokens=True) ['Alice and Bob are going to the same party. It is a small party, in a small']
提示
使用 IDEFICS 进行图像任务
原始文本:
huggingface.co/docs/transformers/v4.37.2/en/tasks/idefics
虽然可以通过微调专门的模型来解决单个任务,但最近出现并受到欢迎的另一种方法是使用大型模型处理各种任务而无需微调。例如,大型语言模型可以处理诸如摘要、翻译、分类等 NLP 任务。这种方法不再局限于单一模态,比如文本,在本指南中,我们将说明如何使用名为 IDEFICS 的大型多模态模型解决图像文本任务。
IDEFICS 是一个基于Flamingo的开放式视觉和语言模型,Flamingo 是由 DeepMind 最初开发的最先进的视觉语言模型。该模型接受任意序列的图像和文本输入,并生成连贯的文本作为输出。它可以回答关于图像的问题,描述视觉内容,创建基于多个图像的故事等。IDEFICS 有两个变体 - 80 亿参数和90 亿参数,这两个变体都可以在🤗 Hub 上找到。对于每个变体,您还可以找到为对话使用案例调整的模型的微调指导版本。
这个模型非常灵活,可以用于各种图像和多模态任务。然而,作为一个大型模型意味着它需要大量的计算资源和基础设施。您需要决定这种方法是否比为每个单独任务微调专门的模型更适合您的用例。
在本指南中,您将学习如何:
- 加载 IDEFICS 和加载模型的量化版本
- 使用 IDEFICS 进行:
- 图像加标题
- 提示的图像加标题
- 少样本提示
- 视觉问答
- 图像分类
- 图像引导文本生成
- 批处理模式下运行推理
- 运行 IDEFICS 指导进行对话使用
在开始之前,请确保已安装所有必要的库。
pip install -q bitsandbytes sentencepiece accelerate transformers
要运行以下示例,您将需要至少 20GB 的 GPU 内存来使用模型检查点的非量化版本。
加载模型
让我们从加载模型的 90 亿参数检查点开始:
>>> checkpoint = "HuggingFaceM4/idefics-9b"
就像其他 Transformer 模型一样,您需要从检查点加载处理器和模型本身。IDEFICS 处理器将 LlamaTokenizer 和 IDEFICS 图像处理器包装成一个单一处理器,以负责为模型准备文本和图像输入。
>>> import torch >>> from transformers import IdeficsForVisionText2Text, AutoProcessor >>> processor = AutoProcessor.from_pretrained(checkpoint) >>> model = IdeficsForVisionText2Text.from_pretrained(checkpoint, torch_dtype=torch.bfloat16, device_map="auto")
将device_map
设置为"auto"
将自动确定如何以最优化的方式加载和存储模型权重,考虑到现有设备。
量化模型
如果高内存 GPU 可用性是一个问题,您可以加载模型的量化版本。要加载模型和处理器的 4 位精度版本,请将BitsAndBytesConfig
传递给from_pretrained
方法,模型将在加载时即时压缩。
>>> import torch >>> from transformers import IdeficsForVisionText2Text, AutoProcessor, BitsAndBytesConfig >>> quantization_config = BitsAndBytesConfig( ... load_in_4bit=True, ... bnb_4bit_compute_dtype=torch.float16, ... ) >>> processor = AutoProcessor.from_pretrained(checkpoint) >>> model = IdeficsForVisionText2Text.from_pretrained( ... checkpoint, ... quantization_config=quantization_config, ... device_map="auto" ... )
现在您已经以建议的方式之一加载了模型,让我们继续探索您可以使用 IDEFICS 的任务。
Transformers 4.37 中文文档(六)(4)https://developer.aliyun.com/article/1564082