Transformers 文档

文本生成

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

文本生成

文本生成是大型语言模型(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.1generation_config.json 文件。当模型未保存配置时,将使用默认解码策略。

通过 generation_config 属性检查配置。它仅显示与默认配置不同的值,在本例中是 bos_token_ideos_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() 也可以通过外部库或自定义代码进行扩展

  1. logits_processor 参数接受自定义 LogitsProcessor 实例,用于操纵下一个 token 的概率分布;
  2. stopping_criteria 参数支持自定义 StoppingCriteria 来停止文本生成;
  3. 其他自定义生成方法可以通过 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()GenerationConfigpipelineschat 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)
默认长度
max_new_tokens
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'

提示格式

某些模型和任务需要特定的输入提示格式,如果格式不正确,模型将返回次优输出。有关提示的更多信息,请参阅提示工程指南。

例如,聊天模型期望输入为聊天模板。您的提示应包含 rolecontent 来指示谁参与了对话。如果您尝试将提示作为单个字符串传递,模型并不总是返回预期的输出。

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 处理器。
在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.