Transformers 文档
文本生成
并获得增强的文档体验
开始使用
文本生成
文本生成是大型语言模型(LLM)最受欢迎的应用。LLM 被训练为在给定初始文本(提示)以及自身生成的输出(长度达到预设长度或遇到序列结束(EOS)标记)的情况下,生成下一个词(token)。
在 Transformers 中,generate() API 负责文本生成,并且可用于所有具有生成能力的模型。本指南将向您展示使用 generate() 进行文本生成的基础知识以及一些常见的陷阱。
对于以下命令,请确保
transformers serve正在运行。transformers chat Qwen/Qwen2.5-0.5B-Instruct
默认生成
在开始之前,安装 bitsandbytes 来量化非常大的模型以减小内存使用量会很有帮助。
!pip install -U transformers bitsandbytes
除了基于 CUDA 的 GPU 之外,Bitsandbytes 还支持多种后端。请参阅多后端安装 指南以了解更多信息。
使用 from_pretrained() 加载 LLM,并添加以下两个参数以减少内存需求。
device_map="auto"启用 Accelerates 的 大模型推理 功能,该功能可以自动初始化模型骨架,并在所有可用设备上加载和分发模型权重,从最快的设备(GPU)开始。quantization_config是一个定义量化设置的配置对象。此示例使用 bitsandbytes 作为量化后端(有关更多可用后端,请参阅量化部分),并以4 位加载模型。
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto", quantization_config=quantization_config)对输入进行分词,并将 padding_side() 参数设置为 "left",因为 LLM 没有被训练为从填充标记继续生成。分词器会返回输入 ID 和注意力掩码。
通过将字符串列表传递给分词器,一次处理多个提示。批处理输入以提高吞吐量,同时略微增加延迟和内存。
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
model_inputs = tokenizer(["A list of colors: red, blue"], return_tensors="pt").to(model.device)将输入传递给 generate() 以生成 token,然后将生成的 token batch_decode() 回文本。
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
"A list of colors: red, blue, green, yellow, orange, purple, pink,"生成配置
所有生成设置都包含在 GenerationConfig 中。在上例中,生成设置取自 mistralai/Mistral-7B-v0.1 的 generation_config.json 文件。当模型未保存配置时,将使用默认解码策略。
通过 generation_config 属性检查配置。它仅显示与默认配置不同的值,在本例中是 bos_token_id 和 eos_token_id。
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto")
model.generation_config
GenerationConfig {
"bos_token_id": 1,
"eos_token_id": 2
}您可以通过覆盖 GenerationConfig 中的参数和值来定制 generate()。有关常用参数,请参阅下面的此部分。
# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)generate() 也可以通过外部库或自定义代码进行扩展
logits_processor参数接受自定义 LogitsProcessor 实例,用于操纵下一个 token 的概率分布;stopping_criteria参数支持自定义 StoppingCriteria 来停止文本生成;- 其他自定义生成方法可以通过
custom_generate标志加载(文档)。
有关搜索、采样和解码策略的更多信息,请参阅生成策略指南。
保存
创建一个 GenerationConfig 实例并指定您想要的解码参数。
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
)使用 save_pretrained() 保存特定的生成配置,并将 push_to_hub 参数设置为 True 以将其上传到 Hub。
generation_config.save_pretrained("my_account/my_model", push_to_hub=True)将 config_file_name 参数留空。当在一个目录中存储多个生成配置时,应使用此参数。它提供了一种指定要加载哪个生成配置的方法。您可以为单个模型创建不同的配置,以用于不同的生成任务(如使用采样进行创意文本生成、使用束搜索进行摘要)。
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, GenerationConfig
tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small")
model = AutoModelForSeq2SeqLM.from_pretrained("google-t5/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,
)
translation_generation_config.save_pretrained("/tmp", config_file_name="translation_generation_config.json", push_to_hub=True)
generation_config = GenerationConfig.from_pretrained("/tmp", config_file_name="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))常用选项
generate() 是一个功能强大且可高度定制的工具。这对于新用户来说可能令人望而生畏。本节列出了 Transformers 中大多数文本生成工具中可以定义的流行生成选项:generate()、GenerationConfig、pipelines、chat CLI 等。
| 选项名称 | 类型 | 简化描述 |
|---|---|---|
max_new_tokens | int | 控制最大生成长度。请务必定义它,因为它通常默认为一个较小的值。 |
do_sample | 布尔值 | 定义生成是采样下一个 token(True)还是贪婪地选择(False)。大多数用例应将此标志设置为 True。有关更多信息,请查看此指南。 |
temperature | 浮点数 | 下一个选定 token 的不可预测程度。高值(>0.8)适用于创意任务,低值(例如 <0.4)适用于需要“思考”的任务。需要 do_sample=True。 |
num_beams | int | 设置为 >1 时,激活束搜索算法。束搜索在输入相关任务上表现良好。有关更多信息,请查看此指南。 |
repetition_penalty | 浮点数 | 如果发现模型经常重复自身,请将其设置为 >1.0。较大的值会施加更大的惩罚。 |
eos_token_id | list[int] | 导致生成停止的 token。默认值通常很好,但您可以指定不同的 token。 |
陷阱
以下部分涵盖了文本生成过程中可能遇到的常见问题及解决方法。
输出长度
默认情况下,generate() 返回最多 20 个 token,除非在模型的 GenerationConfig 中另有指定。强烈建议手动设置生成的 token 数量,使用 max_new_tokens 参数来控制输出长度。仅解码器模型会返回初始提示和生成的 token。
model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'A sequence of numbers: 1, 2, 3, 4, 5'解码策略
默认情况下,generate() 的默认解码策略是贪婪搜索,它选择下一个最可能的 token,除非在模型的 GenerationConfig 中另有规定。虽然这种解码策略在输入相关任务(转录、翻译)上表现良好,但对于更具创意的用例(故事写作、聊天应用程序)来说并非最佳。
例如,启用 多项式采样策略以生成更多样化的输出。有关更多解码策略,请参阅生成策略指南。
model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]填充侧
如果输入的长度不同,则需要进行填充。但是 LLM 没有被训练为从填充 token 继续生成,这意味着 padding_side() 参数需要设置为输入的左侧。
model_inputs = tokenizer(
["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 33333333333'提示格式
某些模型和任务需要特定的输入提示格式,如果格式不正确,模型将返回次优输出。有关提示的更多信息,请参阅提示工程指南。
例如,聊天模型期望输入为聊天模板。您的提示应包含 role 和 content 来指示谁参与了对话。如果您尝试将提示作为单个字符串传递,模型并不总是返回预期的输出。
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")
model = AutoModelForCausalLM.from_pretrained(
"HuggingFaceH4/zephyr-7b-alpha", device_map="auto", quantization_config=BitsAndBytesConfig(load_in_4bit=True)
)prompt = """How many cats does it take to change a light bulb? Reply as a pirate."""
model_inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
input_length = model_inputs.input_ids.shape[1]
generated_ids = model.generate(**model_inputs, max_new_tokens=50)
print(tokenizer.batch_decode(generated_ids[:, input_length:], skip_special_tokens=True)[0])
"Aye, matey! 'Tis a simple task for a cat with a keen eye and nimble paws. First, the cat will climb up the ladder, carefully avoiding the rickety rungs. Then, with"资源
请看下面的更多特定和专业的文本生成库。
- Optimum:Transformers 的一个扩展,专注于在特定硬件设备上优化训练和推理
- Outlines:一个用于约束文本生成的库(例如,生成 JSON 文件)。
- SynCode:一个用于无上下文语法引导生成的库(JSON、SQL、Python)。
- Text Generation Inference:一个生产级的 LLM 服务器。
- Text generation web UI:一个用于文本生成的 Gradio Web UI。
- logits-processor-zoo:用于控制文本生成的附加 logits 处理器。