文本复述生成:用不同表述传达相同意思

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_T5Vamsi/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_sizerepetition_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