新闻自动摘要和生成式写作并非简单的关键词拼接,而是通过序列到序列模型对新闻要素进行压缩与重组。抽取式方法保留原始句子,生成式方法则根据语义重新组织语言,两者在新闻场景中各有适用空间。本文从方法对比、模型训练和落地评估三个角度拆解自动新闻写作的技术路径。

一、抽取式与生成式摘要的核心差异
自动摘要任务的目标是把较长新闻稿件压缩成短导语或摘要。抽取式方法把原文中的句子当作候选集合,通过图排序或贪心选择等方式挑出若干最关键的句子,组成摘要。TextRank算法借鉴PageRank思想,先把句子看成图中的节点,用词汇重叠度构造边权重,再迭代计算每个句子的重要度。这种方法的优点是忠实于原文,不会引入新的事实,缺点是多条被选句子之间可能存在指代断裂或逻辑不连贯。
生成式摘要则依赖编码器把原文编码成连续向量,再由解码器逐词生成摘要。模型可以调整语序、替换表达,输出的摘要更接近人工改写。编码器通常采用Transformer结构,通过多头自注意力捕捉长距离依赖。为了减少生成过程中的事实漂移,指针生成网络允许模型在生成词和直接复制原词之间做选择,这在一定程度上缓解了未登录词和实体丢失的问题。
下面用两个代码片段说明两种方法的调用差异。抽取式实现使用sumy库的TextRank模块:
from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.text_rank import TextRank
def extractive_summary(text, count=3):
parser = PlaintextParser.from_string(text, Tokenizer("english"))
summarizer = TextRank()
result = summarizer(parser.document, count)
return [str(sentence) for sentence in result]
生成式摘要可以直接调用预训练模型,使用Hugging Face的pipeline接口:
from transformers import pipeline
def generative_summary(text, max_len=120, min_len=40):
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
output = summarizer(text, max_length=max_len, min_length=min_len)
return output[0]["summary_text"]
两个接口差异体现了方法本质:前者只做句子选择,后者完成语言再生成。在实际新闻业务中,需要根据栏目要求选择或混合两种方法。例如快讯类栏目注重事实准确,可先抽取再人工校对;深度报道栏目则可以使用生成式模型输出可读性更强的压缩导语。
二、预训练模型如何驱动新闻自动生成
新闻自动生成依赖的预训练模型通常采用序列到序列架构,例如BART、T5和PEGASUS。这些模型在预训练阶段设计了适合摘要的任务。BART通过对原文进行噪声破坏再重建,学习恢复被遮挡或打乱的内容;T5将各类自然语言处理任务统一成文本到文本格式,把摘要任务建模为输入原文、输出摘要;PEGASUS则在预训练时直接训练模型生成被遮盖的关键句,与下游摘要任务高度一致。使用中文新闻数据时,可以选择mT5或中文BART等模型继续微调。
训练数据构建是决定生成质量的关键环节。通常把新闻导语或编辑手动撰写的摘要作为标签,把正文作为输入。如果缺少人工摘要,可以用新闻标题加首段构造弱监督信号。微调时,输入长度控制在512个token左右,摘要长度则根据手机端或网页端展示需求限制在30到100个token。解码阶段可以通过温度系数、top-k和top-p采样调节多样性与稳定性。对于新闻写作,稳定性通常比多样性更重要,因此倾向使用束搜索或较低的温度参数。
以下代码展示了如何加载一个多语言序列到序列模型,并构造一个批次进行微调。实际训练时需要完整的DataLoader和优化器,这里只保留前向传播的核心逻辑:
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM model_name = "google/mt5-small" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSeq2SeqLM.from_pretrained(model_name) input_text = "今日上午,市政部门召开新闻发布会,宣布新的交通调整方案。" label_text = "交通调整方案今日发布。" inputs = tokenizer(input_text, return_tensors="pt", max_length=512, truncation=True) labels = tokenizer(label_text, return_tensors="pt", max_length=128, truncation=True) outputs = model(**inputs, labels=labels["input_ids"]) loss = outputs.loss print(loss.item())
模型训练完成后,可以在推理时加入长度控制和重复惩罚。对于突发新闻,系统可以用增量方式触发生成:当检测到新的快讯或发布会摘要时,调用模型生成一句话摘要,再通过模板组合成简讯。这样既能保证速度,又能减少从零生成的不可控风险。
三、评估指标与工程落地中的关键问题
摘要质量的评估分为自动评估和人工评估。自动指标中,ROUGE系列通过统计生成摘要与参考摘要之间的n-gram重叠来打分,ROUGE-1衡量词重叠,ROUGE-2衡量二元词组重叠,ROUGE-L考虑最长公共子序列。BLEU原本用于机器翻译,也会出现在摘要评估中,但容易忽略召回。近年来BERTScore通过上下文嵌入计算语义相似度,对改写表达更加友好。不过自动指标并不能完全反映新闻场景最看重的事实准确性,一个生成文本可能ROUGE分数很高,却把事件时间或主体搞错。
幻觉问题是生成式新闻写作必须处理的风险。模型可能在训练数据中学到统计偏差,输出原文没有出现的人名、时间或数字。解决思路包括在推理阶段引入受限解码,只允许从原文中选择实体;或者在生成后增加事实核查模块,使用信息抽取模型比对摘要中的实体、时间、地点与原文是否一致。对于来源冲突的多篇稿件,系统可以先按发布时间和来源权威度排序,再选取主事实链,避免把不同事件错误合并。
工程落地时,评估流程应当与自动写稿链路解耦。离线评估可以用ROUGE和BERTScore快速筛选模型版本,上线前再做小规模人工盲评。以下是计算ROUGE分数的简单示例:
from rouge_score import rouge_scorer scorer = rouge_scorer.RougeScorer(["rouge1", "rouge2", "rougeL"], use_stemmer=True) reference = "大风蓝色预警信号发布,阵风可达八级。" generated = "气象部门发布大风蓝色预警,阵风八级。" scores = scorer.score(reference, generated) print(scores["rougeL"].fmeasure)
在新闻生产链路中,自动摘要与生成服务通常以消息队列接入,上游推送新闻原文或结构化要素,服务返回候选摘要,然后写入稿件库等待编辑确认。对于体育比分、财经快讯等结构化数据,还可以先填充模板,再由模型润色,这样可以兼顾准确性和表达的自然度。关键是要保留人工审核通道,不能把高风险报道完全交给模型自动发布。