文本复述生成:用不同表述传达相同意思
FreeGuideOnline
最新
2026-06-23
bash pip install transformers torch sentencepiece
- `transformers`:Hugging Face的模型库,提供预训练模型接口。
- `torch`:深度学习框架。
- `sentencepiece`:T5使用的分词器依赖。
### 第一步:加载预训练模型和分词器
我们选择`t5-small`作为起点,它在速度和质量之间取得了平衡。如果你有更高需求,可以替换为`t5-base`或`t5-large`。
```python
from transformers import T5Tokenizer, T5ForConditionalGeneration
model_name = "t5-small"
tokenizer = T5Tokenizer.from_pretrained(model_name)
model = T5ForConditionalGeneration.from_pretrained(model_name)
第二步:构造带任务前缀的输入
T5模型要求输入带有任务前缀。对于复述,通常使用 "paraphrase: " 作为前缀。这样做能激活模型在预训练阶段学习到的复述能力。
def generate_paraphrase(text, num_return_sequences=1, max_length=128):
# 添加任务前缀
input_text = "paraphrase: " + text + " </s>"
# 编码输入
inputs = tokenizer.encode(input_text, return_tensors="pt", max_length=512, truncation=True)
# 生成输出
outputs = model.generate(
inputs,
max_length=max_length,
num_beams=5, # 使用束搜索提高质量
num_return_sequences=num_return_sequences,
early_stopping=True,
temperature=0.7, # 控制随机性
)
# 解码并返回结果
paraphrases = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
return paraphrases
参数解析:
num_beams:束搜索的宽度,越大结果可能越好但速度越慢。temperature:大于1.0增加多样性,小于1.0让输出更保守。early_stopping:当所有束都完成生成时停止,节省计算。
第三步:测试基本效果
original = "Learning to code opens up many career opportunities."
results = generate_paraphrase(original, num_return_sequences=3)
for i, para in enumerate(results):
print(f"复述{i+1}: {para}")
你可能得到的输出示例:
- 复述1: "coding skills can lead to many job opportunities."
- 复述2: "many career opportunities become available when you learn to program."
- 复述3: "there are many employment opportunities that come from learning how to code."
可见模型已经能够进行词汇替换和语序调整。
第四步:提升多样性与控制度
原始T5模型有时会生成与原句高度重合的复述。我们可以通过以下技巧增加表达多样性:
1. 使用更大、专门的模型
Hugging Face上有很多专门在复述数据集上微调过的T5变体,例如 prithivida/parrot_paraphraser_on_T5 或 Vamsi/T5_Paraphrase_Paws。只需将模型名替换即可获得更优效果。
model_name = "Vamsi/T5_Paraphrase_Paws"
这类模型通常已经将paraphrase:前缀内化,可以直接使用。
2. 约束解码——避免原句照搬
我们可以通过惩罚重复ngram来强制生成新词。
outputs = model.generate(
inputs,
max_length=max_length,
num_beams=10,
num_return_sequences=num_return_sequences,
no_repeat_ngram_size=2, # 禁止重复任意2-gram
repetition_penalty=1.5, # 更严厉的重复惩罚
top_k=50, # 仅从概率最高的50个词中采样
top_p=0.95, # 核采样
do_sample=True, # 开启采样模式以增加随机性
)
调整no_repeat_ngram_size和repetition_penalty可以显著减少重叠。
3. 后处理过滤
生成多个候选后,过滤掉与原文相似度过高的结果。可以使用BLEU、METEOR或基于嵌入的余弦相似度作为过滤标准。例如,要求BLEU值在0.2到0.7之间,避免太低(意义偏离)或太高(缺乏改写)。
from nltk.translate.bleu_score import sentence_bleu
def filter_by_bleu(original, candidates, low=0.2, high=0.7):
ref = original.split()
filtered = []
for c in candidates:
bleu = sentence_bleu([ref], c.split())
if low < bleu < high:
filtered.append(c)
return filtered