Transformers生成结果为什么包含输入提示词
如果用 Hugging Face Transformers 调用 model.generate(),再把 outputs.sequences 整段交给 tokenizer 解码,GPT、Llama 这类 decoder-only 模型出现“结果包含输入提示词”是正常的:返回值通常是“输入 token + 新生成 token”的完整序列,不是只包含答案的字符串。真正要取回答部分,应按输入 token 数量切片后再解码。
官方地址:https://huggingface.co/docs/transformers/
- decoder-only 的生成序列从提示词开始,先切掉输入 token,再读取新增内容。
- encoder-decoder 的切片边界不同,不能把 GPT 的规则原样套到 T5 或 BART。
- 批量推理要结合 padding_side 和 attention_mask,
max_new_tokens只控制新增长度。
一、先判断模型输出是否天然包含输入
Transformers 的 generate 面向的是 token 序列。对 decoder-only 模型,模型要根据已有上下文继续预测,因此返回的序列会保留原来的 input_ids,后面再接上新 token。把这串 token 直接 decode,自然会看到提示词被再次打印。
这不是模型把提示词“重新生成”了一遍,也不表示上下文被重复注入。要区分两件事:sequences 是完整序列,应用层最终展示的文本可以只是它的后半段。Hugging Face 官方生成文档的示例也按模型类型计算输入长度,再使用 outputs.sequences[:, input_length:] 取生成部分。

| 模型形态 | 常见返回关系 | 取新增文本时关注什么 |
|---|---|---|
| decoder-only | input_ids + generated tokens | 按输入提示词 token 数切片 |
| encoder-decoder | decoder 侧生成序列 | 不能直接沿用 decoder-only 的输入长度 |
二、用输入 token 长度切出新增内容
最稳妥的做法是保留 tokenizer 的输入,不按字符长度猜边界。中文、英文和特殊 token 的分词长度都可能不同,len(prompt) 与 input_ids.shape[1] 没有一一对应关系。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "your-decoder-only-model"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
prompt = "请用一句话解释 attention_mask 的作用。"
inputs = tokenizer(prompt, return_tensors="pt")
with torch.no_grad():
# max_new_tokens 只限制新生成 token,不把提示词长度算进去。
sequences = model.generate(**inputs, max_new_tokens=48)
# decoder-only 模型的前半段是输入,按 token 数切掉而不是按字符切。
input_length = inputs["input_ids"].shape[1]
new_tokens = sequences[:, input_length:]
# 跳过 eos 等特殊 token,得到真正供页面展示的新增文本。
generated_text = tokenizer.batch_decode(new_tokens, skip_special_tokens=True)[0]
print(generated_text.strip())
这里的关键是 input_length 来自实际送入模型的 token 张量。若使用 chat template,角色标记、换行和结束标记也已经进入这段输入,不能只根据肉眼看到的用户问题计算长度。
三、批量推理时按 attention_mask 处理 padding
单条输入时用 inputs["input_ids"].shape[1] 足够;批量输入就要进一步确认 padding。不同提示词会被补齐到同一列数,右 padding 与左 padding 的布局不同。如果直接对整个 batch 使用一个固定切片位置,短提示词的结果可能把 padding 或提示词残片带进解码文本。
工程上要先统一 tokenizer 的 padding 策略。attention_mask.sum(dim=1) 可以告诉你每条样本有多少有效提示词 token,用来诊断 padding;但对 decoder-only 的 batch,生成 token 通常是在统一的补齐宽度之后追加,所以实际切片起点通常是 inputs["input_ids"].shape[1],而不是每行的有效长度。还要按模型和 tokenizer 的要求确认是否需要左 padding,不要把“能生成”当成“切片正确”。

# attention_mask 用来核对每条样本的有效 token 数。
valid_lengths = inputs["attention_mask"].sum(dim=1).tolist()
prompt_width = inputs["input_ids"].shape[1]
texts = []
for row, valid_length in zip(sequences, valid_lengths):
# batch 的新 token 通常从统一的补齐宽度之后开始,不能直接用 valid_length 切。
row_new_tokens = row[prompt_width:]
texts.append(tokenizer.decode(row_new_tokens, skip_special_tokens=True).strip())
如果采用左 padding,生成序列的新增部分通常仍从补齐后的统一宽度开始;如果使用自定义生成循环或手工拼接,才需要根据实际输出布局重新计算每行边界。更稳的原则是:记录输入张量、明确 padding 方向,用 attention_mask 诊断有效输入,再按返回序列的真实布局解码。
四、控制长度与模板边界
max_new_tokens 与 max_length 的语义很容易混淆。前者只限制新生成的 token 数,后者通常把输入和输出放在同一个总长度预算里。排查“输出比预期短”时,先看是否误用了 max_length;排查“提示词被带回来”时,则先看是否忘记切片。
还要留意解码动作:如果先解码完整的 sequences,再把展示字符串与 prompt 拼接一次,就会造成真正的双重重复。使用 chat template 时,建议让 tokenizer 负责组织角色标记,并把同一份 input_ids 留给切片逻辑;不要重新手写一套肉眼字符串拼接。
五、按现象快速定位
| 现象 | 优先检查 | 处理方向 |
|---|---|---|
| 输出开头完整重复 prompt | 是否直接 decode 全部 sequences | decoder-only 按 input token 长度切片 |
| 只有 batch 中部分样本重复 | padding_side、attention_mask | 按每行有效长度解码,确认左/右 padding |
| 输出突然变短 | max_length 是否包含输入长度 | 改用 max_new_tokens 并重新设预算 |
| 角色标记混进文本 | chat template 和特殊 token | 使用同一 tokenizer 解码并跳过特殊 token |
因此,这个问题的边界很清楚:先确认模型形态,再确认返回序列的 token 布局,最后检查 padding、模板和长度参数。只有在切片后仍然出现重复,才需要继续排查自定义 stopping criteria、手工拼接 prompt 或多次调用之间是否复用了旧序列。
相关问题
为什么不能按字符串长度截掉输入提示词?
分词后的 token 数与中文字符数、英文字符数并不相等,特殊 token 也会改变边界,所以应使用 input_ids 的列数或每行有效长度。
encoder-decoder 模型也会返回完整 prompt 吗?
不能直接这样判断。它的输入经过 encoder,生成序列在 decoder 侧展开,切片规则应按模型类型处理,不能套用 GPT 类模型的固定假设。
skip_special_tokens 会不会删掉正常内容?
它主要过滤 tokenizer 标记的特殊 token;如果业务需要保留角色标记或边界标记,应先确认模板约定,再决定是否跳过。
Transformers怎样只解码新生成的token
- 上一篇
- Transformers怎样只解码新生成的token
- 下一篇
- PEFT适配器检查点为什么不包含完整基础模型
-
- 科技周边 · 人工智能 | 48分钟前 | python · 人工智能 · Transformers apply_chat_template 聊天模板 chat_template 角色标签
- Transformers聊天模板与手写角色标签有什么兼容性差异
- 492浏览 收藏
-
- 科技周边 · 人工智能 | 53分钟前 | PyTorch checkpoint Accelerate 随机数状态 恢复训练
- Accelerate恢复训练时如何保存随机数状态
- 326浏览 收藏
-
- 科技周边 · 人工智能 | 54分钟前 |
- Diffusers怎样使用Generator复现同一张生成图
- 118浏览 收藏
-
- 科技周边 · 人工智能 | 55分钟前 | 模型 混合精度 优化器 分布式训练 Accelerate Accelerator.prepare
- Accelerate prepare为什么要同时接收模型与优化器
- 386浏览 收藏
-
- 科技周边 · 人工智能 | 58分钟前 | 人工智能 · Hugging Face Datasets streaming IterableDataset Dataset.shuffle shuffle buffer
- Datasets流式读取与内存数据集的shuffle有什么区别
- 130浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face Datasets map怎样同时删除旧字段
- 421浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- PEFT适配器检查点为什么不包含完整基础模型
- 301浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 解码 token Transformers generate 新生成内容
- Transformers怎样只解码新生成的token
- 461浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | python · 人工智能 · Transformers offset_mapping 原始文本 Fast tokenizer 文本偏移
- Transformers分词偏移怎样映射回原始文本片段
- 330浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | Transformers 固定长度 tokenizer 动态补齐 DataCollatorWithPadding
- Transformers批次分词时动态补齐与固定长度补齐怎么选
- 153浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 463次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 526次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 543次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 492次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 311次使用
-
- go格式“占位符”输入输出 类似python的input
- 2023-01-19 346浏览
-
- Golang如何调用Python代码详解
- 2023-01-07 235浏览
-
- HTTP 的 response 中的响应体和头部是分开发送的吗?
- 2023-01-28 387浏览
-
- B站等视频网站的弹幕用的是 websocket 还是轮询?
- 2023-02-16 447浏览
-
- Linux 下有什么命令行工具以时序显示 CPU 占用率?
- 2023-01-13 360浏览

