首页/新闻资讯/正文详情

基于BERT与Django的文本相似度检测系统实战

发布时间:2026/11/5 0:42:15 来源:云帆数科 栏目:资讯中心
基于BERT与Django的文本相似度检测系统实战
简介这份资源是面向Python初学者、高校学生及毕设开发者的一套深度学习文本相似度检测系统完整项目包基于BERT模型与Django框架构建适合作为课程设计、毕业设计或Web开发练手参考。压缩包为zip格式整体约75.86MB内含项目源码、数据库脚本、说明文档、LW论文及PPT等文件覆盖后端逻辑、模型调用与数据库集成等环节便于按模块对照学习。目前已有164人学习下载说明其在同类毕设项目中具备一定参考价值。通过研读源码与文档读者可掌握BERT文本相似度计算、Django接口设计及数据库交互等关键技能并借助论文与PPT快速梳理系统架构与实现思路为后续开发或答辩积累可复用的实践经验。1. 文本相似度检测系统从 BERT 到 Django 的完整落地路径做毕设或企业原型时最常被问到的一个需求就是「判断两段文本是不是一个意思」。传统做法靠编辑距离、Jaccard 系数遇到同义替换、语序调整就翻车。这个项目用 Python BERT Django 搭了一套完整的文本相似度检测系统把深度学习模型封装成 Web 服务前端提交两段文本后端返回相似度分数和判定结果。它适合三类人正在找毕设题目的学生、想学 BERT 工程化落地的开发者、需要快速搭一个语义匹配原型的团队。资源包里包含项目源码、数据库脚本、设计文档、论文和答辩 PPT拿到手就能跑通全流程。下面按「模型怎么用 → 系统怎么搭 → 坑在哪」的顺序拆开讲。2. BERT 文本相似度检测模型选型与推理链路拆解2.1 为什么选 BERT 而不是 TF-IDF 或 Word2Vec文本相似度检测的核心是判断两段文本在语义层面是否接近。TF-IDF 只看词频两句话用词不同但意思一样时相似度直接归零。Word2Vec 能捕捉部分语义但词向量是静态的同一个词在不同语境下向量相同「苹果手机」和「苹果水果」分不开。BERT 通过 Transformer 的注意力机制让每个词的表示都跟上下文相关能真正理解句子的语义。这个项目用的是 BERT-base 的中文预训练模型输出 768 维的句向量。具体做法是把两段文本拼接后送入模型取[CLS]位置的输出接一个全连接层做二分类判断「相似」或「不相似」。也有另一种做法是分别编码两段文本用余弦相似度计算分数。项目源码里两种方式都有实现可以根据场景切换。选型上还有一个现实考量BERT-base 中文模型大约 400MB推理时单条文本在 CPU 上约 50-100msGPU 上可以压到 10ms 以内。如果对延迟不敏感、追求精度这个方案是合理的。如果要做高并发在线服务可以考虑蒸馏后的 TinyBERT 或 ALBERT体积和延迟都能降一个量级。2.2 数据预处理与模型加载的关键步骤拿到原始文本后不能直接喂给模型需要经过分词、截断、padding 三步。中文 BERT 用的是字级别分词不需要额外做分词工具。下面是项目里数据预处理的核心代码from transformers import BertTokenizer, BertForSequenceClassification import torch # 加载预训练分词器和模型 # num_labels2 表示二分类相似/不相似 tokenizer BertTokenizer.from_pretrained(bert-base-chinese) model BertForSequenceClassification.from_pretrained( bert-base-chinese, num_labels2 ) def preprocess(text_a, text_b, max_len128): 将两段文本编码为 BERT 输入格式 text_a: 第一段文本 text_b: 第二段文本 max_len: 最大序列长度超出截断 encoding tokenizer( text_a, text_b, max_lengthmax_len, paddingmax_length, truncationTrue, return_tensorspt ) return encoding # 推理示例 def predict_similarity(text_a, text_b): model.eval() encoding preprocess(text_a, text_b) with torch.no_grad(): outputs model(**encoding) logits outputs.logits probs torch.softmax(logits, dim1) # probs[0][1] 是「相似」的概率 similarity_score probs[0][1].item() return similarity_score这段代码的逻辑是tokenizer把两段文本拼成一个序列中间用[SEP]分隔开头加[CLS]。paddingmax_length保证所有输入长度一致truncationTrue防止超长文本报错。推理时用torch.no_grad()关闭梯度计算减少显存占用。softmax把 logits 转成概率值取「相似」类别的概率作为最终分数。参数方面max_len设 128 是常见做法覆盖大多数短文本场景。如果文本较长可以调到 256 或 512但显存占用和推理时间会线性增长。num_labels2是二分类如果要做多级相似度如「高度相似」「部分相似」「不相似」改成 3 即可。2.3 训练数据的构造与微调策略预训练模型直接拿来用效果有限需要在领域数据上微调。项目里用的是 LCQMC 和 STS-B 的中文部分作为训练数据格式是「句子A \t 句子B \t 标签」。标签 1 表示相似0 表示不相似。数据量建议至少 5000 对以上否则容易过拟合。微调时的关键参数学习率设 2e-5 到 5e-5batch size 设 16 或 32训练 3-5 个 epoch。学习率太大会破坏预训练权重太小则收敛慢。项目源码里用的是 AdamW 优化器带权重衰减 0.01这是 BERT 微调的标准配置。from transformers import AdamW, get_linear_schedule_with_warmup # 优化器和学习率调度器 optimizer AdamW(model.parameters(), lr2e-5, weight_decay0.01) total_steps len(train_dataloader) * 3 # 3 个 epoch scheduler get_linear_schedule_with_warmup( optimizer, num_warmup_stepsint(total_steps * 0.1), num_training_stepstotal_steps )warmup设总步数的 10%让学习率从 0 线性上升到设定值避免训练初期梯度震荡。这是 BERT 微调的常规操作不加 warmup 有时也能跑但收敛稳定性差一些。3. Django 后端集成把 BERT 模型封装成 Web 接口3.1 项目目录结构与数据库设计这个项目用的是 Django 作为 Web 框架整体目录结构如下text_similarity/ ├── manage.py ├── requirements.txt ├── similarity/ # 核心应用 │ ├── models.py # 数据库模型 │ ├── views.py # 视图函数 │ ├── urls.py # 路由配置 │ ├── bert_utils.py # BERT 推理封装 │ └── templates/ # 前端页面 ├── static/ # 静态资源 └── media/ # 上传文件存储数据库用的是 MySQL核心表有两张text_record存储每次检测的文本和结果user表存用户信息。建表 SQL 在资源包的database.sql里导入后直接可用。CREATE TABLE text_record ( id INT AUTO_INCREMENT PRIMARY KEY, text_a TEXT NOT NULL, text_b TEXT NOT NULL, similarity_score FLOAT, result_label VARCHAR(20), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, user_id INT, FOREIGN KEY (user_id) REFERENCES auth_user(id) );similarity_score存浮点分数result_label存「相似」或「不相似」的判定结果。加索引的话user_id和created_at是常用查询字段建议加上。3.2 模型加载与视图函数实现Django 启动时如果每次都重新加载 BERT 模型响应会非常慢。正确做法是在应用初始化时加载一次全局复用。项目里用的是 Django 的AppConfig.ready()方法# similarity/apps.py from django.apps import AppConfig import torch from transformers import BertTokenizer, BertForSequenceClassification class SimilarityConfig(AppConfig): default_auto_field django.db.models.BigAutoField name similarity def ready(self): # 全局加载模型只执行一次 self.tokenizer BertTokenizer.from_pretrained(bert-base-chinese) self.model BertForSequenceClassification.from_pretrained( bert-base-chinese, num_labels2 ) self.model.eval() # 有 GPU 就用 GPU self.device torch.device(cuda if torch.cuda.is_available() else cpu) self.model.to(self.device)视图函数接收前端 POST 过来的两段文本调用模型推理把结果写入数据库并返回 JSON# similarity/views.py from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.apps import apps import torch import json csrf_exempt def detect_similarity(request): if request.method ! POST: return JsonResponse({error: 仅支持 POST 请求}, status405) data json.loads(request.body) text_a data.get(text_a, ).strip() text_b data.get(text_b, ).strip() if not text_a or not text_b: return JsonResponse({error: 文本不能为空}, status400) config apps.get_app_config(similarity) encoding config.tokenizer( text_a, text_b, max_length128, paddingmax_length, truncationTrue, return_tensorspt ) encoding {k: v.to(config.device) for k, v in encoding.items()} with torch.no_grad(): outputs config.model(**encoding) probs torch.softmax(outputs.logits, dim1) score probs[0][1].item() label 相似 if score 0.5 else 不相似 return JsonResponse({ similarity_score: round(score, 4), result_label: label })这里有几个细节值得注意csrf_exempt装饰器是为了方便接口测试生产环境应该用 token 认证替代。encoding里的张量要手动搬到 GPU 上否则模型在 GPU 而输入在 CPU 会报错。阈值 0.5 是默认值实际使用时可以根据业务需求调整比如要求高精度时调到 0.7。3.3 前端交互与结果展示前端页面用 Django 模板渲染一个简单的表单提交两段文本AJAX 请求后端接口把返回的分数和判定结果展示出来。核心 JS 逻辑async function checkSimilarity() { const textA document.getElementById(textA).value; const textB document.getElementById(textB).value; if (!textA || !textB) { alert(请填写两段文本); return; } const response await fetch(/api/similarity/, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify({text_a: textA, text_b: textB}) }); const data await response.json(); document.getElementById(score).textContent data.similarity_score; document.getElementById(label).textContent data.result_label; }页面展示时相似度分数用进度条可视化会更直观。项目模板里用的是 Bootstrap 的 progress bar根据分数动态设置宽度和颜色。分数高于 0.8 显示绿色0.5 到 0.8 显示黄色低于 0.5 显示红色。4. 避坑与排查BERT Django 集成中最容易翻车的五个点4.1 模型加载超时导致 Django 启动失败现象运行python manage.py runserver时卡住不动或者报TimeoutError。原因AppConfig.ready()里加载 BERT 模型时如果本地没有缓存会从网络下载预训练权重。国内网络环境下下载 400MB 文件很容易超时。解决提前手动下载模型文件放到本地目录然后用绝对路径加载。常见做法是在 HuggingFace 镜像站下载pytorch_model.bin、config.json、vocab.txt三个文件放到pretrained/bert-base-chinese/目录下加载时把模型名改成路径model BertForSequenceClassification.from_pretrained( ./pretrained/bert-base-chinese, num_labels2 )4.2 GPU 显存不足导致推理中断现象推理时报CUDA out of memory或者服务跑一段时间后崩溃。原因BERT-base 模型本身占约 1.5GB 显存加上输入数据和中间激活值如果 batch size 设得大或者同时有多个请求并发显存很快耗尽。解决把max_len从 512 降到 128batch size 设为 1Web 服务通常单条推理并在推理后手动释放缓存torch.cuda.empty_cache()如果显存实在紧张直接用 CPU 推理虽然慢但稳定。4.3 中文编码问题导致文本乱码现象前端提交的中文文本到后端变成乱码或者数据库里存的是问号。原因Django 默认编码是 UTF-8但 MySQL 数据库如果建库时没指定字符集默认可能是 latin1。解决建库时指定CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci。Django 的settings.py里确认DATABASES配置中有OPTIONS: {charset: utf8mb4}。前端页面meta charsetUTF-8也要加上。4.4 模型推理结果每次不一样现象同样的两段文本多次请求返回的相似度分数有细微差异。原因模型没有切换到评估模式Dropout 层还在随机丢弃神经元。解决加载模型后立即调用model.eval()推理时用torch.no_grad()包裹。这两个操作缺一不可只加no_grad不加eval仍然会有随机性。4.5 数据库连接数耗尽现象服务运行一段时间后报Too many connections。原因Django 默认每个请求新建一个数据库连接请求量大时连接数暴涨。解决在settings.py里配置CONN_MAX_AGE让连接复用DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: text_similarity, CONN_MAX_AGE: 600, # 连接保持 600 秒 # ... 其他配置 } }5. 进阶技巧用 ONNX 加速推理与阈值调优模型跑通之后下一步就是优化推理速度和判定准确率。这里分享两个我实际用过的技巧。ONNX 导出与推理加速。PyTorch 模型直接推理有框架开销导出成 ONNX 格式后用onnxruntime推理CPU 上通常能快 2-3 倍。导出脚本import torch from transformers import BertTokenizer, BertForSequenceClassification model BertForSequenceClassification.from_pretrained( ./pretrained/bert-base-chinese, num_labels2 ) model.eval() dummy_input { input_ids: torch.randint(0, 1000, (1, 128)), attention_mask: torch.ones(1, 128, dtypetorch.long), token_type_ids: torch.zeros(1, 128, dtypetorch.long) } torch.onnx.export( model, (dummy_input,), bert_similarity.onnx, input_names[input_ids, attention_mask, token_type_ids], output_names[logits], dynamic_axes{ input_ids: {0: batch, 1: seq}, attention_mask: {0: batch, 1: seq}, token_type_ids: {0: batch, 1: seq} }, opset_version14 )导出后加载 ONNX 模型推理import onnxruntime as ort import numpy as np session ort.InferenceSession(bert_similarity.onnx) inputs { input_ids: encoding[input_ids].numpy(), attention_mask: encoding[attention_mask].numpy(), token_type_ids: encoding[token_type_ids].numpy() } logits session.run([logits], inputs)[0] score np.exp(logits[0][1]) / np.sum(np.exp(logits[0]))dynamic_axes让模型支持变长输入opset_version14是兼容性较好的版本。ONNX 推理不依赖 PyTorch部署时环境更轻量。阈值调优。默认 0.5 的阈值在多数场景下够用但如果你做的是「查重」类应用宁可漏判不可误判阈值应该调高到 0.7 甚至 0.8。反过来如果是「推荐相似内容」阈值可以降到 0.3 让更多结果通过。调优方法是在验证集上画 P-R 曲线找到 F1 分数最高的点。项目文档里有一节专门讲这个用的是 sklearn 的precision_recall_curve。批量推理。如果一次要检测多对文本不要循环单条推理把 batch size 设大一次性送入模型。比如一次检测 32 对速度比循环快 5-8 倍。注意max_len要统一padding 到同一长度。def batch_predict(pairs, batch_size32): results [] for i in range(0, len(pairs), batch_size): batch pairs[i:ibatch_size] texts_a [p[0] for p in batch] texts_b [p[1] for p in batch] encoding tokenizer( texts_a, texts_b, max_length128, paddingmax_length, truncationTrue, return_tensorspt ) with torch.no_grad(): outputs model(**encoding) probs torch.softmax(outputs.logits, dim1) scores probs[:, 1].tolist() results.extend(scores) return results从那以后我每次部署 BERT 模型前都强制走一遍 ONNX 导出和阈值验证确认推理速度和判定边界都符合预期再上线。这套流程帮我省了不少返工时间希望帮到你。本文还有配套的精品资源点击获取

相关推荐

大模型产品经理的核心能力与实战方法论
大模型产品经理的核心能力与实战方法论

1. 大模型产品经理的角色定位与核心挑战 去年夏天,我和团队在推进一个金融行业智能客服项目时,深刻体会到大模型产品经理与传统产品经理的差异。当GPT-3.5的对话效果突然出现波动时,我们花了三天时间才定位到是数据预处理环节的标注标准不一致… · 2026/11/5 2:51:19

IEEE33节点辐射网潮流计算:MATLAB前推回代法实现与DG接入分析
IEEE33节点辐射网潮流计算:MATLAB前推回代法实现与DG接入分析

简介:这份资源面向电力系统分析与MATLAB编程的学习者,聚焦IEEE33节点辐射状配电网,用前推回代法完成潮流计算。辐射网结构简单却贴近教学与研究场景,适合电气工程专业学生、科研入门者以及需要复现潮流算法的工程师,用… · 2026/11/5 0:06:18

RollingGo酒店系统MCP接入:API Key与OAuth 2.0选型实战指南
RollingGo酒店系统MCP接入:API Key与OAuth 2.0选型实战指南

1. 项目概述:为什么酒店系统要接入MCP?RollingGo不是个玩具,是真正在跑订单的生产环境RollingGo酒店系统接入MCP(Model Context Protocol)这件事,最近在技术群里被反复提起,但很多人其实没搞清一… · 2026/11/4 23:59:09

衡岳动力刹车片源头厂家 乘用车制动片选型指南与适用场景解析
衡岳动力刹车片源头厂家 乘用车制动片选型指南与适用场景解析

制动系统是汽车安全的核心屏障,而刹车片作为制动系统中直接产生摩擦力的关键部件,其品质直接决定制动效果与行车安全。很多车主和采购人员往往只关注刹车片的摩擦材料本身,却忽视了消音片、弹簧卡、卡簧、报警线、铆钉等附属配件的重要性。事… · 2026/11/5 11:09:34

江苏热复机销售厂家,热压辊表面划伤怎么消
江苏热复机销售厂家,热压辊表面划伤怎么消

江苏热复机销售厂家,热压辊表面划伤怎么消?这是很多复合车间设备管理员在搜索的问题。热压辊是热复机(热覆复合机)上直接接触材料的部件,辊面一旦划伤,压出来的复合布面就会出现周期性压痕、局部虚粘,严重时整批货都要返查。下面… · 2026/11/5 11:09:34

降低ai率的提示词5条拿来就用,改完朱雀AI率还高就免费降AI 1000字
降低ai率的提示词5条拿来就用,改完朱雀AI率还高就免费降AI 1000字

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

雪球动态 | 雪球数智受邀参加 SILA-Matter 技术培训,深度解析量产难题与 OBIS 方案
雪球动态 | 雪球数智受邀参加 SILA-Matter 技术培训,深度解析量产难题与 OBIS 方案

近日,由上海浦东智能照明联合会(SILA)与连接标准联盟中国成员组(CMGC)联合举办的 Matter 技术应用工程师培训活动圆满举行。行业内众多深耕智能家居、智能照明、物联网领域的企业代表齐聚现场,围绕 Matter … · 2026/11/5 11:05:29

工业测温方案解析:ADS122U04与STM32F042K6的UART高精度RTD采集设计
工业测温方案解析:ADS122U04与STM32F042K6的UART高精度RTD采集设计

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

STM32L031+ADS122U04:UART接口24位ADC实现PT100高精度温度采集
STM32L031+ADS122U04:UART接口24位ADC实现PT100高精度温度采集

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

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

多智能体协作系统架构设计与实践优化
多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39

大模型系统性入门实战指南:从原理到部署微调的全链路路线
大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39

鸿蒙文件系统沙箱机制解析与开发实践
鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码