基于深度学习的中文问答系统毕设:从数据预处理到Gradio演示的完整实战

发布时间:2026/9/28 11:34:33
基于深度学习的中文问答系统毕设:从数据预处理到Gradio演示的完整实战 简介这份毕业设计资源面向计算机相关专业学生与深度学习入门者提供一套基于深度学习的中文问答系统完整源码可用于课程设计、毕业设计或NLP方向的自学实践。压缩包共26个文件约16.39MB以9个Python脚本为核心涵盖编码器、注意力解码器、数据预处理与训练入口等模块另有7个txt语料与说明文件、6个xml工程配置、1个md说明文档及license等辅助文件目录结构清晰便于按模块阅读与二次开发。项目围绕自然语言处理、Transformer/BERT/RNN/LSTM等模型、分词与词向量化、损失函数与优化器选择、准确率与BLEU评估等关键环节展开读者可据此理解问答系统从数据预处理、模型搭建到训练评估的完整链路并参考配置与脚本组织方式完成自己的实验。目前已有243人学习适合希望将深度学习理论落地为可运行项目的同学参考。1. 中文问答系统毕设从深度学习模型到可演示的最小闭环很多同学拿到“基于深度学习的中文问答系统”这个题目时第一反应是打开搜索引擎找现成代码结果翻到的大多是英文 SQuAD 数据集上的 BERT 微调脚本直接拿来跑中文语料就翻车——分词对不上、数据格式不匹配、显存爆掉、推理速度慢到演示时尴尬。这个题目的核心不是“训练一个多大的模型”而是在有限算力和有限时间内搭出一条从中文原始语料到可交互问答的完整链路。它适合计算机、软件工程、大数据方向的本科或硕士毕业设计也适合想用 Python 深度学习教程里知识做实战项目的人。你需要的是能跑通、能演示、能写进论文的系统而不是一个刷榜模型。这一章先把边界划清楚输入是用户自然语言问题输出是答案片段或答案文本中间涉及数据预处理、模型选型、训练策略、服务封装四个环节缺一个都交不了差。2. 中文问答系统的数据从哪来语料选型与预处理流水线2.1 公开中文问答数据集对比与选择依据做中文问答第一个卡点不是模型是数据。英文有 SQuAD、Natural Questions中文能直接用的、规模适中、标注质量过得去的常见的有以下几个方向一是机器阅读理解类比如 CMRC 2018、DRCD、WebQA二是社区问答对类比如 NLPCC 的 KBQA 数据集三是自己爬取构建但毕设周期内不建议从零标注。选数据集的判断标准有三条是否包含答案在原文中的位置标注抽取式需要、问题类型是否覆盖事实型与推理型、数据量是否能在单卡 8G 显存内完成微调。数据集任务类型规模量级答案形式适合的模型路线CMRC 2018抽取式阅读理解约 2 万问题原文片段BERT/RoBERTa 微调DRCD抽取式阅读理解约 3 万问题原文片段BERT 微调WebQA开放域问答约 4 万问题短答案检索阅读理解NLPCC KBQA知识库问答约 1.5 万问题实体/关系语义解析或检索排序如果导师没有指定数据集我一般会选 CMRC 2018 做主线因为它格式干净、社区脚本多、论文里引用率高。想加创新点可以再叠加一个检索模块做开放域版本。2.2 从原始 JSON 到模型输入分词、截断与答案对齐拿到数据集后不能直接丢给模型。中文需要先经过分词或字级切分再映射到预训练模型的词表。以 BERT 中文版为例它用的是字级 WordPiece所以“深度学习”会被切成“深”“度”“学”“习”四个 token。这一步的坑在于答案起止位置的对齐原始数据里答案是以字符索引标注的转成 token 索引时如果直接复用会偏移一到两个位置导致训练时标签错位模型学出来全是废的。下面是一个可复现的预处理脚本核心片段用 Python 和 HuggingFace transformers 实现from transformers import BertTokenizerFast import json tokenizer BertTokenizerFast.from_pretrained(bert-base-chinese) def preprocess_example(example, max_len384, doc_stride128): # example 包含 context, question, answers tokenized tokenizer( example[question], example[context], truncationonly_second, max_lengthmax_len, stridedoc_stride, return_overflowing_tokensTrue, return_offsets_mappingTrue, paddingmax_length ) # 关键用 offset_mapping 把字符级答案映射到 token 级 offset_mapping tokenized.pop(offset_mapping) sample_map tokenized.pop(overflow_to_sample_mapping) start_positions, end_positions [], [] for i, offsets in enumerate(offset_mapping): input_ids tokenized[input_ids][i] cls_index input_ids.index(tokenizer.cls_token_id) sequence_ids tokenized.sequence_ids(i) # 找到 context 在 token 序列中的起止 span_start 0 while sequence_ids[span_start] ! 1: span_start 1 span_end len(input_ids) - 1 while sequence_ids[span_end] ! 1: span_end - 1 answer example[answers][0] start_char answer[answer_start] end_char start_char len(answer[text]) # 如果答案不在当前窗口内标为 CLS if not (offsets[span_start][0] start_char and offsets[span_end][1] end_char): start_positions.append(cls_index) end_positions.append(cls_index) else: while span_start len(offsets) and offsets[span_start][0] start_char: span_start 1 start_positions.append(span_start - 1) while offsets[span_end][1] end_char: span_end - 1 end_positions.append(span_end 1) tokenized[start_positions] start_positions tokenized[end_positions] end_positions return tokenized这段代码的逻辑说明return_offsets_mappingTrue是核心它返回每个 token 在原始字符串中的字符区间。overflow_to_sample_mapping处理长文本切窗后一个样本对应多个特征的情况。答案对齐时先判断答案是否落在当前窗口内不在就标为 CLS 位置让模型学会“无法回答”。参数方面max_len384是单卡 8G 显存下 BERT-base 的安全值doc_stride128保证切窗之间有重叠避免答案被切断。如果显存更小降到 256 和 64但召回会掉。注意中文预训练模型不要用bert-base-uncased它会把中文字符全部映射成 UNK训练 loss 根本不降。认准bert-base-chinese或hfl/chinese-roberta-wwm-ext。3. 模型选型与训练在毕设算力约束下做取舍3.1 抽取式、生成式还是检索式三条路线的成本对比中文问答系统在毕设语境下模型路线基本三条抽取式阅读理解、生成式Seq2Seq 或 LLM 微调、检索式向量匹配排序。抽取式的优点是答案一定来自原文不会胡说训练稳定BERT-base 在 CMRC 上微调三四个 epoch 就能到 70% 左右的 EM够写论文。生成式的优点是答案灵活但需要更多数据和更大模型用 T5 或 BART 中文版在毕设数据上训很容易生成重复或无关文本调参周期长。检索式适合 FAQ 场景用 Sentence-BERT 做向量召回再接一个交叉编码器精排工程量大但可解释性强。我的建议主线做抽取式加一个检索模块做开放域扩展。这样论文里有 baseline 对比有模块创新工作量也撑得起来。如果导师明确要求用 LLM那就选一个 6B 或 7B 的中文模型做 LoRA 微调但显存至少 16G训练时间按小时算要提前规划。3.2 用 HuggingFace Trainer 微调 BERT 中文问答模型选定抽取式路线后训练脚本可以用 transformers 的 Trainer 封装减少手写循环的出错概率。下面是一个可运行的训练配置from transformers import BertForQuestionAnswering, TrainingArguments, Trainer from datasets import load_dataset model BertForQuestionAnswering.from_pretrained(bert-base-chinese) dataset load_dataset(cmrc2018) # 假设已转为 HF datasets 格式 args TrainingArguments( output_dir./qa_model, evaluation_strategyepoch, learning_rate3e-5, per_device_train_batch_size8, per_device_eval_batch_size8, num_train_epochs3, weight_decay0.01, warmup_ratio0.1, logging_steps50, save_strategyepoch, load_best_model_at_endTrue, metric_for_best_modeleval_exact_match, fp16True # 显卡支持时开启 ) trainer Trainer( modelmodel, argsargs, train_datasetdataset[train], eval_datasetdataset[validation], tokenizertokenizer, data_collatordefault_data_collator ) trainer.train()逻辑说明learning_rate3e-5是 BERT 微调的经典值太大 loss 震荡太小收敛慢。per_device_train_batch_size8配合fp16True在 8G 显存上刚好跑满。warmup_ratio0.1让前 10% 步数线性升温避免初期梯度爆炸。metric_for_best_model用 EM 而不是 loss因为问答任务最终看的是答案匹配度。如果显存不够把 batch size 降到 4梯度累积设 2等效 batch 不变。训练过程中要盯两个信号训练 loss 是否稳定下降验证集 EM 是否在第二个 epoch 后还在涨。如果 loss 降但 EM 不涨大概率是过拟合或标签对齐有问题回去检查预处理脚本。3.3 推理阶段的后处理从 logits 到可读答案模型输出的是 start logits 和 end logits需要解码成文本片段。常见做法是取 start 和 end 概率最高的组合限制end start且长度不超过 30 个 token。下面是一个推理函数import torch def answer_question(question, context, model, tokenizer, max_len384): inputs tokenizer(question, context, return_tensorspt, max_lengthmax_len, truncationonly_second) with torch.no_grad(): outputs model(**inputs) start_logits outputs.start_logits end_logits outputs.end_logits start_idx torch.argmax(start_logits) end_idx torch.argmax(end_logits) if end_idx start_idx or end_idx - start_idx 30: return 无法从给定文本中找到答案 tokens inputs[input_ids][0][start_idx:end_idx1] return tokenizer.decode(tokens, skip_special_tokensTrue)参数说明max_len384要和训练时一致否则位置编码对不上。end_idx - start_idx 30是长度约束防止模型把整段话当答案。返回“无法找到”是一种兜底策略演示时比返回乱码体面得多。4. 避坑与排查中文问答系统毕设里最容易翻车的五件事4.1 现象训练 loss 正常下降但验证集 EM 始终为 0原因答案位置对齐错误。中文 tokenizer 在切分时标点、空格、数字的处理和英文不同直接用字符索引当 token 索引会整体偏移。解决用offset_mapping重新计算 start/end 位置并在预处理后随机抽 5 条样本把 token 序列 decode 回文本肉眼确认答案片段是否被正确框出。4.2 现象模型推理时显存溢出batch size 设为 1 依然 OOM原因max_length设得太大或者没有用torch.no_grad()。BERT-base 在 512 长度下单条推理约需 1.5G 显存如果忘了关闭梯度会额外占用计算图内存。解决推理时加with torch.no_grad():把max_length降到 384 或 256必要时用 ONNX Runtime 做推理加速。4.3 现象演示时输入一个问题系统返回的答案包含大量无关标点原因解码时没有跳过 special tokens或者答案边界判断太宽松。解决tokenizer.decode加skip_special_tokensTrue并在后处理里过滤掉纯标点或长度小于 2 的答案片段返回“未找到答案”。4.4 现象换一个中文预训练模型后训练直接报维度不匹配原因不同模型的词表大小不同BertForQuestionAnswering的config.vocab_size和 tokenizer 不一致。解决加载模型时用from_pretrained自动同步 config不要手动改num_labels或vocab_size。如果换 RoBERTa注意它没有 NSP 任务pooler 层输出不同但问答头不受影响。4.5 现象系统在测试集上 EM 不错但实际演示时问题稍微换个说法就答错原因模型过拟合了训练集的问题句式缺乏语义泛化。解决在训练数据里做问题改写增强比如同义词替换、语序调整或者在推理前加一个检索模块先用 Sentence-BERT 召回最相关的段落再送给阅读理解模型减少上下文噪声。5. 把模型变成可演示系统Gradio 封装与论文实验设计5.1 用 Gradio 搭一个三小时能跑通的演示界面毕设答辩时老师不会看你训练脚本只会看输入问题、点按钮、出答案。Gradio 是最省事的方案几十行代码就能把模型包成 Web 界面。下面是一个最小可用示例import gradio as gr def qa_interface(question, context): if not question or not context: return 请输入问题和上下文 return answer_question(question, context, model, tokenizer) demo gr.Interface( fnqa_interface, inputs[ gr.Textbox(label问题, placeholder例如深度学习是什么), gr.Textbox(label上下文, lines6, placeholder粘贴一段包含答案的文本) ], outputsgr.Textbox(label答案), title中文问答系统演示, description基于 BERT 的抽取式问答答案来自上下文 ) demo.launch(server_name0.0.0.0, server_port7860)逻辑说明qa_interface做输入校验避免空输入导致模型报错。server_name0.0.0.0让同一局域网内的设备都能访问答辩时用手机或另一台电脑演示更方便。如果要做开放域版本把上下文输入框换成检索模块的返回结果用户只输问题即可。5.2 论文实验部分该跑哪些对比和消融毕设论文里实验章节不能只放一个最终 EM 值。至少要有三组对比不同预训练模型BERT-base vs RoBERTa-wwm vs ERNIE、不同 max_length256/384/512、有无数据增强。消融实验可以去掉检索模块看端到端 EM 掉多少证明模块有效性。评价指标用 EM 和 F1计算脚本可以直接用官方评估代码不要自己手写容易算错。实验组模型max_len数据增强验证集 EM验证集 F1baselineBERT-base-chinese384无68.279.5换模型RoBERTa-wwm-ext384无71.482.1调长度BERT-base-chinese512无69.080.2加增强BERT-base-chinese384同义替换70.181.0这张表的结构可以直接放进论文数据根据你实际跑的结果填。注意如果换模型后 EM 提升不到 1 个点别硬吹如实写“提升有限但推理速度下降 20%”反而显得客观。5.3 一个我踩过的坑别在答辩前一天换模型我见过太多人答辩前三天觉得 BERT 不够新非要换 LLM 做生成式问答结果 LoRA 微调 loss 不收敛推理延迟高到每问一次等十秒最后演示翻车。毕设的第一目标是稳定演示第二目标才是创新。抽取式 BERT 方案虽然不新但可控、可解释、可复现论文里把数据预处理、模型对比、系统封装写清楚工作量已经足够。真想加 LLM可以放在“未来工作”里讨论或者单独做一个检索模块的对比实验不要动主线。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询