新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于深度学习的文本摘要自动生成:T5模型实战与避坑指南

发布时间:2026/9/29 20:09:36来源:尧图网络
基于深度学习的文本摘要自动生成:T5模型实战与避坑指南
简介面向本科毕业设计的深度学习与自然语言处理实践资源围绕Transformer模型实现文本摘要自动生成。内容完整覆盖文本数据预处理、模型搭建、训练评估与部署可见的工程链路尤其适合希望结合理论与实践完成毕业设计或NLP入门项目的高年级本科生。资源压缩包共34个文件以Python源码18个py为主覆盖模型定义、训练、测试、评估等模块辅以Shell训练与测试脚本、Docker与CI配置、词汇表及说明文档等整体仅360KB结构清晰便于本地快速运行。已有3569人学习下载热度可观。除核心Transformer模型与训练逻辑外资源还包含分词与词表构建、ROUGE/BLEU指标评估、beam search解码等关键实现并可通过Web接口交互演示训练、测试、CI等配置脚本覆盖完整工程流程方便读者对照理解从数据预处理、模型训练到部署评估的每个环节为后续开展NLP研究打下扎实基础。1. 文本摘要自动生成毕设是什么一个Seq2Seq问题别被“深度学习”四个字吓住如果你的毕设题目是“基于深度学习的文本摘要自动生成”别慌这个题目在国内NLP方向的本科毕设里出现频率很高。它要你做的事情说白了就是给模型一篇长新闻或一段长文本让它输出一句或一小段人话读得通的摘要属于自然语言处理里的生成式摘要任务。和“抽取式摘要”不同生成式摘要不是从原文里挑句子拼出来而是让模型自己组织语言所以它天然和Seq2Seq架构绑在一起——“自动生成”这四个字指的就是模型逐字把摘要“写”出来。这个方向最适合需要快速出成果、又想要完整技术栈的本科毕设数据处理、模型训练、自动评估全都得自己动手论文里可写的图表和对比实验也不愁凑不够。2. 把任务定义清楚从“给人看”到“给模型看”的数据与预处理2.1 生成式摘要的建模思路目标就是条件概率最大化摘要任务可以抽象成一个条件语言模型。给定原文序列 x(x1,x2,...,xn)我们希望模型生成摘要序列 y(y1,y2,...,ym)训练目标就是最大化条件概率 P(y|x)。在深度学习框架里这个目标通常落成交叉熵损失每一步都让模型预测的下一token概率去匹配真实摘要中的下一个token。这个建模方式和机器翻译几乎一模一样所以你会看到T5、BART这类模型在摘要上表现很好因为它们本质上就是“干翻译的架构”。本科毕设里一个常见的误区是拿到题目就开始写代码却说不清自己的模型输入输出是什么。我建议你动笔前先画一条数据流原始语料 → 清洗后的文本 → tokenizer编码 → 模型前向 → 生成解码 → 评估脚本。每一步都要能回答“这步在干什么”和“出了问题在哪看”。这不仅是给论文写流程图的素材更是你后面排查bug的地图。2.2 公开数据集怎么选中文用LCSTS英文用CNN/DailyMail毕设数据集选择直接影响训练时间和最终效果。常见做法是中文用哈尔滨工业大学的LCSTS新浪微博短文本摘要数据集英文用CNN/DailyMail。LCSTS有超过240万条微博原文-摘要对质量参差但胜在规模大、获取容易。我不建议毕设直接拿全集训时间上跑不完显存和CPU都要和你叫板。我一般会这样划分用PART I的一部分做训练PART II做验证PART III做测试。这样既保住了“大规模数据集”的噱头又让单卡训练可控。如果你导师要求用英文数据CNN/DailyMail是另一个选择但有一个隐藏缺点它的摘要基本是原文句子的高度压缩生成式模型很容易退化成“抄原文”。这样你的“自动生成”在论文里会显得很牵强。我自己的偏好是中文任务用LCSTS因为中文摘要更接近“人写的总结”模型泛化压力更大也更好写创新点。2.3 数据预处理清洗比模型更决定下限LCSTS是从微博来的数据里全是用户、#话题#、URL、表情符号和“转发微博”这种垃圾串。如果原样丢给模型第一个坑就是词表被污染生成的摘要会莫名其妙带上“某人”。我常用的清洗流程如下import re import json def clean_text(text): text re.sub(r#.*?#, , text) # 去话题标签 text re.sub(r[\w\u4e00-\u9fa5], , text) # 去用户 text re.sub(rhttp\S, , text) # 去URL text re.sub(r\[.*?\], , text) # 去微博表情 [哈哈] text re.sub(r\s, , text).strip() # 合并空白 return text def load_jsonl(path): with open(path, r, encodingutf-8) as f: for line in f: obj json.loads(line) yield clean_text(obj[content]), clean_text(obj[summarization])逻辑说明这个脚本用五个正则分别处理微博文本里的典型噪声。你可以看到我把它写成了生成器函数因为数据集几万条起步一次性全load进内存会显得很笨生成器配合后续的Dataset构建更顺。参数说明#.*?#里的.*?是非贪婪匹配防止把两个话题标签中间的内容一并删掉[\w\u4e00-\u9fa5]同时兼容英文数字用户名和中文昵称。2.4 用HuggingFace tokenizer构建训练样本清洗完文本后下一步是把它编码成模型能吃的张量。这里直接用transformers库的tokenizer是主流做法不需要手写词表。from transformers import BertTokenizerFast from datasets import Dataset tokenizer BertTokenizerFast.from_pretrained(bert-base-chinese) def encode_fn(examples): model_inputs tokenizer( examples[source], max_length512, truncationTrue, paddingmax_length, return_tensorspt ) with tokenizer.as_target_tokenizer(): labels tokenizer( examples[target], max_length128, truncationTrue, paddingmax_length ) model_inputs[labels] labels[input_ids] model_inputs[labels] [ [(l if l ! tokenizer.pad_token_id else -100) for l in label] for label in model_inputs[labels] ] return model_inputs dataset Dataset.from_list([ {source: src, target: tgt} for src, tgt in load_jsonl(train.jsonl) ]) dataset dataset.map(encode_fn, batchedTrue, remove_columns[source, target])逻辑说明as_target_tokenizer()让目标文本用和源文本不同的tokenizer配置很多Seq2Seq模型会单独处理decoder端这里用同一个tokenizer但是开了target模式保证labels的格式和模型预期一致。把pad_token_id替换成-100是关键操作因为PyTorch的CrossEntropyLoss默认忽略label等于-100的位置这样计算loss时就不会把padding位置算进去。参数说明源文本max_length取512摘要取128是因为LCSTS原文平均长度在200字左右摘要平均在50字以内这个余量足够了。padding策略选了max_length优点是batch形状固定缺点是小样本浪费算力如果你追求训练速度可以改成paddingTrue配合DataCollator动态padding。3. 模型与baseline选型为什么T5是本科毕设的最优解3.1 三个可选方案从RNN到预训练模型的对比构建模型是整个项目的核心也是最容易陷入焦虑的部分——总怕自己选的模型不够新。我按“毕设友好度”给你三个方案直接对比看怎么选。方案架构训练成本效果上限毕设适配度ALSTM Attention从零训练低CPU可跑低摘要经常语法不通高适合做“对比基线”BT5-small中文权重微调中单张3060可跑高生成质量明显可用最高推荐CBART-large / Pegasus高需要多卡或长训练更高低显存和训练时间会拖垮你方案A不是拿来当主模型的但它必须出现在你的论文里。毕设评审老师非常吃“baseline对比”这一套你从零训练一个LSTM效果差不要紧关键是有了对比T5提升多少就一目了然。方案C我劝你慎重它效果好是匿名评审的但训练一轮动辄几个小时本科毕设的时间表撑不住。方案B的T5是学术社区里最常用的Seq2Seq预训练模型它对输入输出格式统一用前缀文本控制训练和推理代码都极简中文有开箱即用的权重所以我下面的实现全部基于它。3.2 T5模型与tokenizer的细节前缀和参数都要交代用T5做摘要输入要在原文前加一个任务前缀。官方习惯是用summarize: 你也可以换成中文摘要 注意前后要保持一致训练和推理里都得加否则模型会蒙。选权重这一步有讲究我建议直接用uer/t5-small-chinese-cluecorpussmall这是UER项目发布的中文T5权重模型规模小显存压力低效果在LCSTS上够用。当然你也可以跑英文的google-t5/t5-small但处理中文文本时效果会差一截。初始化模型和tokenizer的代码很简单但下面这段藏着两个容易翻车的点from transformers import T5Tokenizer, T5ForConditionalGeneration model_name uer/t5-small-chinese-cluecorpussmall tokenizer T5Tokenizer.from_pretrained(model_name) model T5ForConditionalGeneration.from_pretrained(model_name) # 训练时要把decoder端也初始化好别只拿model直接怼 model.config.max_length 128 model.config.min_length 10 model.config.no_repeat_ngram_size 3 model.config.length_penalty 0.8 model.config.early_stopping True逻辑说明这里设置的一串config属性就是生成阶段的默认参数。max_length和min_length控制摘要长度范围no_repeat_ngram_size3禁止生成阶段出现重复的三元组这是治“复读机”症状的关键后面避坑章节还会重点说。length_penalty0.8是一个微妙的参数值小于1会让模型更喜欢短句子适合同样偏短的LCSTS摘要如果你换成长文本数据集这个值要回调到1.0或者1.2。3.3 最小可运行的生成样例先跑通再谈训练训练之前我强烈建议你先用没微调的模型生成一条摘要感受一下和最终结果的差距同时验证整套代码链路从头到尾是通的。这个“先跑一个样本”的习惯可以帮你把数据加载、模型推理、解码生成、结果打印这一串接口全部打通比一次性跑完整训练然后被几十个报错淹没高效得多。input_text summarize: 据央视新闻报道我国自主研发的深海探测器成功完成万米海试采集到大量珍贵样本相关科研人员表示这将推动深海生物研究取得重大突破。 inputs tokenizer(input_text, return_tensorspt, max_length512, truncationTrue) outputs model.generate( inputs.input_ids, max_length128, min_length10, num_beams4, do_sampleFalse, no_repeat_ngram_size3 ) print(tokenizer.decode(outputs[0], skip_special_tokensTrue))逻辑说明num_beams4表示用beam search解码每次保留4条候选路径最终挑整体概率最高的序列比贪心解码效果好一个档位。do_sampleFalse关闭随机采样保证结果可复现这也方便你后面做不同模型的对比实验。参数说明skip_special_tokensTrue会去掉pad和/s这些特殊token否则你打印出来的摘要尾巴上会带着一串pad pad看起来很业余。4. 训练配置与调参让模型在单卡上稳定收敛4.1 环境配置一台普通游戏本也能跑训练之前先解决环境。我推荐你直接用Anaconda建虚拟环境装PyTorch、transformers、datasets、rouge_score这几个包就够了。CUDA版本按你显卡驱动来一般装PyTorch官方源对应的CUDA 11.8或12.1都行如果你用的是Mac或者没有独立显卡的笔记本纯CPU训练也不是不可能只是需要把训练轮数、数据量砍掉一半并且改用T5-small这种小模型。很多同学在这个环节容易卡住常见问题是torch和CUDA版本不匹配torch.cuda.is_available()返回False别慌去PyTorch官网用命令行生成器重新装一遍就好。关于“要不要租服务器跑深度学习”我的观点是如果只是T5-small加LCSTS子集自己的3060够了不用花这个钱如果导师非要你用BART-large再考虑租卡。但你要额外承担上传数据集和调试网络环境的成本本科毕设没必要给自己加这个戏。4.2 训练参数逐项说明别把超参调成玄学我把一套亲测可用的参数组合放在下面参数说明直接看表参数取值理由learning_rate5e-5T5微调用1e-4容易震荡5e-5保守可靠batch_size83060 6GB显存下比较安全再大就OOMgradient_accumulation_steps4等效batch32梯度更稳定又不爆显存warmup_ratio0.1前10%的step让学习率从0爬升防止前期震荡weight_decay0.01常规的正则化手段不过度依赖max_epochs3LCSTS子集上3轮基本收敛多了容易过拟合max_grad_norm1.0梯度裁剪防止单batch异常拉崩训练这组参数不是拍脑袋是我拿LCSTS的3万条子集在3060上试出来的。你要注意gradient_accumulation_steps和batch_size的乘积才是真正的batch size改的时候两个一起调别只动一个。4.3 训练主循环代码手写循环才能讲清楚每一行很多教程用Trainer一把梭对毕设来说反而不好——你论文里的“训练细节”章节需要你写清楚优化器、学习率调度、梯度裁剪用Trainer虽然省事但你讲不出细节。我习惯手写一个极简训练循环工作量不大但可控性高很多from torch.utils.data import DataLoader from torch.optim import AdamW from transformers import get_scheduler optimizer AdamW(model.parameters(), lr5e-5, weight_decay0.01) num_epochs 3 total_steps len(dataloader) * num_epochs // gradient_accumulation_steps scheduler get_scheduler( linear, optimizeroptimizer, num_warmup_stepsint(total_steps * 0.1), num_training_stepstotal_steps ) model.train() global_step 0 for epoch in range(num_epochs): for batch in dataloader: batch {k: v.to(device) for k, v in batch.items() if k ! labels} labels batch.get(labels, None) outputs model(**batch, labelsbatch[labels]) loss outputs.loss / gradient_accumulation_steps loss.backward() if (global_step 1) % gradient_accumulation_steps 0: torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) optimizer.step() scheduler.step() optimizer.zero_grad() global_step 1 if global_step % 500 0: print(fepoch {epoch} step {global_step} loss {loss.item():.4f}) torch.save(model.state_dict(), fcheckpoint_step_{global_step}.pt)逻辑说明loss.backward()之后不立刻optimizer.step()而是累积gradient_accumulation_steps次再更新一次这是显存不够时的标准操作。梯度裁剪clip_grad_norm_放在step之前防止梯度爆炸把参数冲出有效区域。参数说明labels被独立取出来传进模型而batch里其他字段也要明确过滤掉不需要的键否则Tensor一起进了forward会报多余参数的错。torch.save(model.state_dict(), ...)保存的是权重文件加载时需要先model.load_state_dict()这个和HuggingFace官方格式的save_pretrained不一样如果你打算后面用from_pretrained加载就得换用model.save_pretrained()。4.4 验证与早停训练loss骗人的地方训练loss降不下来是玄学降下来了也不代表模型好。我第5章会专门讲避坑这里先说一个判断标准训练loss降到3.0左右时模型基本开始输出成句的摘要了但能不能用必须拿验证集生成几条肉眼看看。我通常的做法是每训完一个epoch随机从验证集抽5条用model.generate()生成摘要并打印和真实摘要并排看。这一步亲眼所见的效果比任何指标都直观。5. 文本摘要训练与生成的避坑指南5个让模型翻车的典型问题5.1 训练loss降不下去一直在4.5到5.0之间徘徊现象loss曲线像条水平线训了上千步毫无波动。原因最常见的是学习率太大参数在loss曲面的山谷两侧来回震荡不落底其次是数据预处理出了问题比如labels里没把pad替换成-100模型一直在预测无意义的padding tokenloss自然下不去。解决先确认data collator和loss计算逻辑。如果你是照我上面代码做的-100替换了pad那么就去调学习率。我建议从5e-5往下调直接调成2e-5重训。如果还不行取128条训练样本跑一个过拟合实验正常情况3分钟loss就该明显下降如果连小样本都过拟合不了那就是模型或代码的问题不要去怪数据。5.2 显存不够batch_size一调大就OOM现象CUDA out of memory程序直接崩掉。原因单batch过大、max_source_length过长或者没有做梯度累积的显存优化。3060这种6GB显存卡batch_size取8已经是上限有些同学T5的隐藏层本身就吃显存再叠加长序列就爆了。解决把batch_size降到4然后用gradient_accumulation_steps保持等效batch不变再把max_length从512裁剪到256LCSTS原文超过256字的比例不高丢掉信息有限。如果还想再省开启model.gradient_checkpointing_enable()用一点训练速度换显存你就能把batch_size调回8。这三点按顺序试基本能压进6GB。5.3 模型生成“复读机”一句话重复三遍现象生成的摘要里同一个词组反复出现比如“深海探测器深海探测器深海探测器完成海试”。原因解码时beam search倾向重复已经是经典难题模型在生成后期对概率的估计模糊如果训练数据里就有重复片段LCSTS微博数据里这种常见模型就学到了这种坏习惯。解决在model.generate()里加no_repeat_ngram_size3或者repetition_penalty1.2。前者的含义是禁止生成任何连续三个token组成的片段在全文重复出现后者是对重复token的概率做一个惩罚缩放。两者可以一起用但先只加no_repeat_ngram_size因为repetition_penalty尺度不好调调大了会让摘要丢掉信息。5.4 ROUGE分数挺高但生成摘要读起来像原文截断现象自动评估ROUGE-1有40多分但人工一看摘要基本就是原文前两句话拼接没有概括性。原因LCSTS这类数据集里不少摘要本身就是原文句子的压缩和改写模型学到的捷径是“从原文里摘重要片段”而不是“理解后重新表达”。这在抽取式摘要里是正常的在生成式任务里就是不合格。解决评估不能只看ROUGE加一个BERTScore或人工评估表。我建议你在论文里把ROUGE定位为“词汇重叠度的参考”把人工评分当做主要结论。另外可以从数据侧下手清洗时把那些和原文重合度超过70%的训练样本删掉强制模型去学概括。5.5 中文符号混乱模型输出全是全角半角混杂的逗号句号现象生成的摘要里经常出现“,”、“。。。”这种符号粘连甚至中文里混入英文逗号。原因LCSTS的原始文本符号不统一中文逗号和英文逗号在tokenizer词表里是两个不同的token模型会混淆它们。解决在clean_text里加一步符号统一。def normalize_punc(text): text text.replace(, ,).replace(。, .) text text.replace(, !).replace(, ?) return text如果你不想让摘要里的标点全变成半角可以反过来把英文符号统一成中文全角关键是训练集和测试集必须用同一套规则否则token分布不一致生成结果就会在两种符号之间摇摆。5.6 一个额外提醒训练和推理时input前缀不一致现象训练时代码里加了summarize: 前缀推理时代码里忘了加效果断崖式下跌。原因T5的预训练任务和微调任务共用一套参数输入格式不同会直接让模型掉回预训练模式相当于是另一个task。解决把前缀拼接写进数据预处理函数而不是训练循环里这样训练和推理共用同一个函数就从源头上避免了不一致。这个坑看似简单我在帮别人debug时至少见过三次。6. 效果验证与进阶方向ROUGE之外还能怎么把摘要做扎实先看ROUGE怎么算。这个指标虽然被诟病和人工评估相关性不够强但毕设论文里必须有它撑场面所以你得会算、会解释。推荐用rouge_score库实现稳定。下面是最小脚本from rouge_score import rouge_scorer scorer rouge_scorer.RougeScorer([rouge1, rouge2, rougeL], use_stemmerTrue) scores scorer.score(深海探测器完成万米海试并采集大量样本, 探测器完成海试并采集样本) print(scores[rouge1].fmeasure, scores[rouge2].fmeasure, scores[rougeL].fmeasure)逻辑说明rouge1看单个词的重叠rouge2看相邻词对的重叠rougeL看最长公共子序列的重叠。fmeasure是精确率和召回率的调和平均论文里报这个分就行。参数说明use_stemmerTrue会把英文单词还原成词干中文场景下作用不大保留默认即可。算完ROUGE你以为就完了不够。我习惯在每次实验末尾额外生成一个测试集的“可视化评估表”挑10条样本列出三个字段原文摘要、模型生成摘要、人工评分1-5分。这个表会成为你论文最有力的论据比任何指标都直观。进阶方向上如果你想在毕设里拉开和其他人的差距可以做两件事。第一件是做“抽取生成”的两阶段摘要先用textrank或类似算法从原文抽3句关键句把关键句拼在原文前面喂给T5。这个做法的效果提升是实打实的因为T5生成时有了更聚焦的上下文论文里也很好讲。第二件是用强化学习做指标优化用ROUGE作为奖励对模型做self-critical训练但这套方法工程量大需要两周左右的调试时间适合你中期检查完成之后有时间余量再上。最后说一个我自己的习惯每次实验结束把生成的错误样本攒成一个“bad case集”归类整理。这个集子既是调整参数的依据也是答辩时老师问“你做了什么分析”的最佳答案。3000条训练出来的模型能跑通30000条才谈得上效果这两种状态之间的差距就是踩坑踩出来的。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

医用吊塔:手术室和 ICU 天花板上那根“臂“是做什么的 2026/9/29 21:30:51

医用吊塔:手术室和 ICU 天花板上那根“臂“是做什么的

进过手术室或 ICU 的人可能会注意到:监护仪、呼吸机、输液泵并不都堆在地面上,而是集中挂在从天花板伸下来的一根可旋转的悬臂上,旁边还整齐排着氧气、负压吸引、压缩空气的接口。这套装置通常被称为医用吊塔,也有吊桥、悬臂等叫法…

阅读更多 →
Spring-AI-Alibaba 初体验:用 Streamable-http 接入 MCP Server 的配置骨架 2026/9/29 21:30:51

Spring-AI-Alibaba 初体验:用 Streamable-http 接入 MCP Server 的配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
vscode配置C/C++环境(超详细保姆级教学):从g++到调试,一次跑通 2026/9/29 21:30:51

vscode配置C/C++环境(超详细保姆级教学):从g++到调试,一次跑通

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
llamap.cpp 和 llama-index连接 2026/9/29 21:30:51

llamap.cpp 和 llama-index连接

1. 启动 llama.cpp 服务器 使用 llama.cpp 二进制文件启动一个兼容 OpenAI API 的服务器。bash./server -m /path/to/your/model.gguf --host 127.0.0.1 --port 8080 -c 40962. 在 LlamaIndex 中连接服务器 实例化 LlamaCPP 时,将 model_url 指向本地服务器地址&…

阅读更多 →
TaoToken 配置实战:用 McEval 多语言代码评测基准验证 40 种编程语言模型能力 2026/9/29 21:30:38

TaoToken 配置实战:用 McEval 多语言代码评测基准验证 40 种编程语言模型能力

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
GitHub开源项目日报 · 2026年3月18日 · 开源AI生态领跑榜单:TaoToken统一Key接入编码代理配置指南 2026/9/29 21:30:31

GitHub开源项目日报 · 2026年3月18日 · 开源AI生态领跑榜单:TaoToken统一Key接入编码代理配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉