实现Django和Transformers 构建智能客服大模型(模拟订单系统)

一、环境安装准备

   #git拉取 bert-base-chinese 文件#创建 虚拟运行环境python -m venv myicrplatenv#刷新source myicrplatenv/bin/activate#python Django 集成nacospip install nacos-sdk-python#安装 Djangopip3 install Django==5.1#安装 pymysql settings.py 里面需要 # 强制用pymysql替代默认的MySQLdb pymysql.install_as_MySQLdb()pip install pymysql# 安装mongopip install djongo pymongopip install transformerspip install torch#安装Daphne: pip install daphne#项目通过 通过 daphne启动daphne icrplat.asgi:application

二、构建项目及app模块

#创建app模块
python3 manage.py startapp cs
icrplat├── README.md
├── cs
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── icrplat
│   ├── __init__.py
│   ├── __pycache__
│   ├── asgi.py
│   ├── common
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── myicrplatenv
│   ├── bin
│   ├── include
│   ├── lib
│   ├── pyvenv.cfg
│   └── share
├── nacos-data
│   └── snapshot
└── templates

三、相关代码

####################################views.py####################################@csrf_exempt
def send_message(request):if request.method == "GET":text = request.GET.get("message")# 输入验证if not text or len(text) > 512:return JsonResponse({"status": "error", "message": "无效的输入文本"})try:# 加载 BERT 模型和分词器path = "/Users/jiajiamao/soft/python/space/bert-base-chinese"model_dir = "/Users/jiajiamao/soft/python/space/csBotModel/"model_path = os.path.join(model_dir, "cs_bot_model.pth")tokenizer = BertTokenizer.from_pretrained(path)model = BertModel.from_pretrained(path)# 初始化训练类trainer = TrainModel(tokenizer, model, output_size=3)trainer.train_dataloader()# 加载训练好的模型trainer.load_model(model_path)# 调用模型进行推理predicted_label = trainer.predict(text)print(f"Predicted Label: {predicted_label}")# 根据预测结果生成回复if predicted_label == 0:response = "您的订单状态是:已发货。"elif predicted_label == 1:response = "您可以取消订单,请提供订单号。"elif predicted_label == 2:response = "请登录您的账户,提交退货申请。"else:response = "抱歉,我不明白您的问题。"return JsonResponse({"status": "success", "response": response})except Exception as e:return JsonResponse({"status": "error", "message": str(e)})else:return JsonResponse({"status": "error", "message": "无效的请求方法"})
################################CsBotModule.py################################import torch.nn as nn"""定义模型类 CsBotModel
"""
class CsBotModule(nn.Module):"""nn.Module:所有神经网络模型的基类。自定义模型需要继承 nn.Module 并实现 __init__ 和 forward 方法。@:param bert_model 预训练的 BERT 模型(例如 BertModel 或类似的 Hugging Face 模型)@:param hidden_size:BERT 模型的隐藏层大小(通常是 768 或 1024)@:param output_size:输出层的大小,表示回复的分类数量或生成回复的维度。"""def __init__(self, bert_model, hidden_size, output_size):super(CsBotModule, self).__init__()self.bert = bert_model  # 加载的 BERT 模型,用于提取输入文本的特征。self.fc = nn.Linear(hidden_size, output_size)  # 一个全连接层(线性层),将 BERT 的输出映射到最终的输出空间"""forward方法用来定义数据如何通过模型传递,最终返回分类结果@:param input_ids:输入的 token ID 序列(经过 tokenizer 处理后的输入)。@:param attention_mask:注意力掩码,用于指示哪些 token 是有效的(1)或填充的(0)。"""def forward(self, input_ids, attention_mask):# 获取BERT的输出outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)pooled_output = outputs.pooler_output  # 使用[CLS]的输出向量# 全连接层生成回复logits = self.fc(pooled_output)return logits
################################TrainModel.py################################import logging
import osimport torch
import torch.nn as nn
from torch.optim import AdamW
from cs.CsBotModule import CsBotModule"""PyTorch和Transformers库中的模块。torch是PyTorch的核心库,nn是用来构建神经网络的模块,BertTokenizer和BertModel是BERT模型和它的分词器,AdamW是用来优化模型的。
"""
class TrainModel:"""#初始化模型  创建一个 CsBotModel 的实例@:param model:预训练的 BERT 模型。@:param hidden_size=768:BERT 模型的隐藏层大小(BERT-base 的隐藏层大小为 768)。@:param output_size=tokenizer.vocab_size:输出层的大小,设置为 tokenizer 的词汇表大小,表示模型需要生成词汇表中的每个 token 的概率。"""def __init__(self, tokenizer, model,output_size):self.tokenizer = tokenizerself.model = model# self.csBotModule = CsBotModule(self.model, hidden_size=768, output_size=self.tokenizer.vocab_size)self.csBotModule = CsBotModule(self.model, hidden_size=768, output_size=output_size)"""数据预处理"""# def preprocess_data(self, dataList, max_len=512):#     input_ids = []  # input_ids:表示文本的ID序列。#     attention_masks = []  # attention_mask:表示哪些位置是真实文本,哪些位置是填充的#     labels = []  # labels:表示文本对应的类别标签#     for data in dataList:#         # TODO 对每一条文本数据,使用BERT的分词器(tokenizer)进行编码 将其转换为模型可以处理的格式#         encoded = self.tokenizer.encode_plus(#             data["text"],  # 需要编码的文本内容。#             max_length=max_len,  # 设定编码后的序列最大长度(这里为64)。如果文本长度超过这个值,会进行截断;如果不足,会用特殊符号填充。#             padding="max_length",  # 将序列填充到max_length指定的长度。#             truncation=True,  # 如果文本长度超过max_length,进行截断#             return_attention_mask=True,  # 返回注意力掩码(attention_mask),它告诉模型哪些位置是真实文本,哪些位置是填充的。#             return_tensors="pt"  # 返回PyTorch张量格式,方便后续直接用于模型训练#         )##         input_ids.append(encoded["input_ids"])  # input_ids是BERT模型输入的ID序列,代表了分词后的文本。每个词或子词被映射成一个唯一的ID。#         attention_masks.append(encoded["attention_mask"])  # attention_mask是一个二进制掩码,用来区分真实文本和填充部分。真实文本位置为1,填充位置为0。#         labels.append(data["label"])  # 将继续将每一条文本对应的标签(label)添加到labels列表中##     input_ids = torch.cat(input_ids,dim=0)  # 通过torch.cat方法将input_ids列表中的所有张量拼接成一个大的张量,适合批量输入模型。dim=0表示沿着第一维度(行)进行拼接#     attention_masks = torch.cat(attention_masks, dim=0)  # 将attention_masks列表中的所有张量拼接成一个大的张量#     labels = torch.tensor(labels)  # 将labels列表转换为一个PyTorch张量,方便后续计算损失函数##     return input_ids, attention_masks, labelsdef preprocess_data(self, dataList, max_len=512):input_ids = []attention_masks = []labels = []for data in dataList:encoded = self.tokenizer.encode_plus(data["text"],max_length=max_len,padding="max_length",truncation=True,return_attention_mask=True,return_tensors="pt")input_ids.append(encoded["input_ids"])attention_masks.append(encoded["attention_mask"])labels.append(data["label"])input_ids = torch.cat(input_ids, dim=0)attention_masks = torch.cat(attention_masks, dim=0)labels = torch.tensor(labels)return input_ids, attention_masks, labels"""训练循环将模型设置为训练模式。清空梯度。输入数据并得到模型的预测值。计算损失值。通过反向传播计算梯度。使用优化器更新模型参数。打印当前轮次和损失值。通过多次循环,模型会逐渐拟合数据,损失值也会逐渐降低,最终达到我们需要的效果。"""def train_dataloader(self):"""定义损失函数和优化器损失函数:nn.CrossEntropyLoss():交叉熵损失函数,用于分类任务或多分类生成任务。它将模型的输出(logits)与真实标签(labels)进行比较,计算损失。优化器:AdamW(chatbot_model.parameters(), lr=5e-5):使用 AdamW 优化器,学习率设置为 5e-5(BERT 模型的典型学习率)。chatbot_model.parameters():获取模型的所有可训练参数。"""criterion = nn.CrossEntropyLoss()optimizer = AdamW(self.csBotModule.parameters(), lr=5e-5)epochs = 10  # 增加训练轮数dataList = [{"text": "如何查询我的订单状态?", "label": 0},{"text": "我可以取消订单吗?", "label": 1},{"text": "如何进行退货操作?", "label": 2},{"text": "我的订单在哪里?", "label": 0},{"text": "订单支付失败了怎么办?", "label": 1},{"text": "我的订单显示已发货,但还没收到。", "label": 2}]input_ids, attention_masks, labels = self.preprocess_data(dataList, max_len=512)  # 修正参数顺序# csBotModel = self.init_model()for epoch in range(epochs):# 将模型设置为训练模式。在训练模式下,模型会启用Dropout等特性,并计算梯度用于反向传播self.csBotModule.train()# 在每一轮训练开始时,清空优化器中的梯度。这一步非常重要,因为如果不清空梯度,梯度会在每一轮中累积,导致训练结果错误optimizer.zero_grad()# 将预处理好的数据(input_ids和attention_masks)输入模型,模型会计算出预测值(outputs)。outputs = self.csBotModule(input_ids, attention_masks)# 计算模型的损失值(loss)。criterion是损失函数,这里使用的是CrossEntropyLoss(交叉熵损失),# 它用于衡量模型的预测值(outputs)与实际标签(labels)之间的差异。损失值越小,说明模型的预测越接近真实值loss = criterion(outputs, labels)# 进行反向传播,计算损失的梯度。这一步会从损失值开始,沿着模型的每一层,逐层计算各参数的梯度。loss.backward()# 根据计算出的梯度,使用优化器(这里用的是AdamW)更新模型的参数,从而让模型在下一轮训练中表现得更好。optimizer.step()logging.info((f"*********************Epoch {epoch + 1}, Loss: {loss.item()}"))# 检查目录是否存在,如果不存在则创建model_dir = "/Users/jiajiamao/soft/python/space/csBotModel/"os.makedirs(model_dir, exist_ok=True)# 保存模型model_path = os.path.join(model_dir, "cs_bot_model.pth")self.save_model(model_path)"""保存模型"""def save_model(self, path):torch.save(self.csBotModule.state_dict(), path)"""# 加载模型"""def load_model(self, path):self.csBotModule.load_state_dict(torch.load(path))self.csBotModule.eval()# 推理def predict(self, text):self.csBotModule.eval()with torch.no_grad():encoded = self.tokenizer.encode_plus(text,max_length=512,padding="max_length",truncation=True,return_attention_mask=True,return_tensors="pt")input_ids = encoded["input_ids"]attention_mask = encoded["attention_mask"]outputs = self.csBotModule(input_ids, attention_mask)_, predicted = torch.max(outputs, dim=1)return predicted.item()

四、启动项目

#通过 daphne 启动应用
daphne icrplat.asgi:application

五、测试

# 涉及到的数据都是 模拟的,可以改成动态数据epochs = 10  # 增加训练轮数dataList = [{"text": "如何查询我的订单状态?", "label": 0},{"text": "我可以取消订单吗?", "label": 1},{"text": "如何进行退货操作?", "label": 2},{"text": "我的订单在哪里?", "label": 0},{"text": "订单支付失败了怎么办?", "label": 1},{"text": "我的订单显示已发货,但还没收到。", "label": 2}]
#接口传入  》》如何查询我的订单状态?》》生成结果如下

 

 

#接口传入 》》如何进行退货操作?》》生成结果如下

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/29984.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apache Kafka单节点极速部署指南:10分钟搭建开发单节点环境

Apache Kafka单节点极速部署指南:10分钟搭建开发单节点环境 Kafka简介: Apache Kafka是由LinkedIn开发并捐赠给Apache基金会的分布式流处理平台,现已成为实时数据管道和流应用领域的行业标准。它基于高吞吐、低延迟的设计理念,能够…

浅论数据库聚合:合理使用LambdaQueryWrapper和XML

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、数据库聚合替代内存计算(关键优化)二、批量处理优化四、区域特殊处理解耦五、防御性编程增强 前言 技术认知点:使用 XM…

【C++设计模式】第四篇:建造者模式(Builder)

注意:复现代码时,确保 VS2022 使用 C17/20 标准以支持现代特性。 分步骤构造复杂对象,实现灵活装配 1. 模式定义与用途 核心目标:将复杂对象的构建过程分离,使得同样的构建步骤可以创建不同的表示形式。 常见场景&am…

uploadlabs经验总结

目录 一、基础上传漏洞(太过简单目前环境不可能存在) 1、抓包然后改后缀进行绕过 2、抓包然后改上传文件类型进行绕过 3、改后缀大小写绕过,以及收尾加空格,加::$DATA,加点等等 4、黑名单不完整绕过,复习后缀绕过&…

若依ry-vue分离板(完整版)前后端部署

目录 1.目标 2.准备工作 3.源码下载 4.整理前后端目录 5.先部署后端 (1)导入数据库 (2)改代码数据库配置 (3)运行redis (4)运行执行文件 (5)后端启…

重构谷粒商城09:人人开源框架的快速入门

谷粒商城09——人人开源框架的快速入门 前言:这个系列将使用最前沿的cursor作为辅助编程工具,来快速开发一些基础的编程项目。目的是为了在真实项目中,帮助初级程序员快速进阶,以最快的速度,效率,快速进阶…

Linux | Vim 鼠标不能右键粘贴、跨系统复制粘贴

注:本文为 “ Vim 中鼠标右键粘贴、跨系统复制粘贴问题解决方案” 相关文章合辑。 未整理去重。 Linux 入门:vim 鼠标不能右键粘贴、跨系统复制粘贴 foryouslgme 发布时间 2016 - 09 - 28 10:24:16 Vim基础 命令模式(command-mode)插入模式(insert-m…

【JavaWeb】Web基础概念

文章目录 1、服务器与客户端2、服务器端应用程序3、请求和响应4、项目的逻辑构成5、架构5.1 概念5.2 发展演变历程单一架构分布式架构 5.3 单一架构技术体系 6、本阶段技术体系 1、服务器与客户端 ①线下的服务器与客户端 ②线上的服务器与客户端 2、服务器端应用程序 我…

基于云的内容中台核心优势是什么?

弹性云架构赋能资源整合 现代企业通过弹性云架构实现多源数据资源的深度整合,其动态扩展能力可自动适配业务流量波动。基于分布式存储与容器化部署,系统能够无缝对接CRM、ERP等企业软件集成,实现跨平台数据实时同步。值得注意的是&#xff0…

数据库基础练习1

目录 1.创建数据库和表 2.插入数据 创建一个数据库,在数据库种创建一张叫heros的表,在表中插入几个四大名著的角色: 1.创建数据库和表 #创建表 CREATE DATABASE db_test;#查看创建的数据库 show databases; #使用db_test数据库 USE db_te…

亲测解决笔记本触摸板使用不了Touchpad not working

这个问题可以通过FnFxx来解决,笔记本键盘上Fxx会有一个触摸板图标。如果不行应该玉藻设置中关了,打开即可。 解决办法 在蓝牙,触摸板里打开即可。 Turn it on in settings。

Vue23Web 基礎性拉滿的面試題(2025版)還沒更新完...

Vue2&3 基礎性1. 關於Vue2和Vue3生命週期的差別2. Vue2&3組件之間傳參不同點Vue2 傳遞與接收Vue3 傳遞與接收 (使用script setup語法糖)Vue3 傳遞與接收 (不使用script setup語法糖) 3. Vue2&3 keep-alive 組件Vue2 keep-aliveVue3 keep-alive 進階性爲什麽POST請求…

动态ip和静态ip适用于哪个场景?有何区别

在数字化浪潮席卷全球的今天,IP地址作为网络世界的“门牌号”,其重要性不言而喻。然而,面对动态IP与静态IP这两种截然不同的IP分配方式,许多用户往往感到困惑:它们究竟有何区别?又分别适用于哪些场景呢&…

深度学习模型Transformer核心组件—自注意力机制

第一章:人工智能之不同数据类型及其特点梳理 第二章:自然语言处理(NLP):文本向量化从文字到数字的原理 第三章:循环神经网络RNN:理解 RNN的工作机制与应用场景(附代码) 第四章:循环神经网络RNN、LSTM以及GR…

FreeRTOS 源码结构解析与 STM32 HAL 库移植实践(任务创建、删除篇)

1. FreeRTOS源码结构介绍 1.1 下载源码 ​ 点击官网地址,选择 FreeRTOS 202212.01非 LTS 版本(非长期支持版),因为这个版本有着最全的历程和更多型号处理器支持。 1.2 文件夹结构介绍 ​ 下载后主文件 FreeRTOSv202212.01 下包…

【uniapp】图片添加canvas水印

目录 需求&背景实现地理位置添加水印 ios补充 需求&背景 需求:拍照后给图片添加水印, 水印包含经纬度、用户信息、公司logo等信息。 效果图: 方案:使用canvas添加水印。 具体实现:上传图片组件是项目里现有的&#xff…

基于Windows11的DockerDesktop安装和布署方法简介

基于Windows11的DockerDesktop安装和布署方法简介 一、下载安装Docker docker 下载地址 https://www.docker.com/ Download Docker Desktop 选择Download for Winodws AMD64下载Docker Desktop Installer.exe 双点击 Docker Desktop Installer.exe 进行安装 测试Docker安装是…

AI自习室渐兴:人工智能赋能教育新场景的深度剖析

在数字化浪潮席卷全球的今天,教育领域也迎来了前所未有的变革。近年来,AI自习室作为人工智能技术与传统教育融合的产物,在河北等多地悄然兴起,成为学生们的新宠。这一新兴的学习场所,不仅引发了社会的广泛关注&#xf…

Android中AIDL和HIDL的区别

在Android中,AIDL(Android Interface Definition Language) 和 HIDL(HAL Interface Definition Language) 是两种用于定义跨进程通信接口的语言。AIDL 是 Android 系统最早支持的 IPC(进程间通信&#xff0…

从0开始的操作系统手搓教程23:构建输入子系统——实现键盘驱动1——热身驱动

目录 所以,键盘是如何工作的 说一说我们的8042 输出缓冲区寄存器 状态寄存器 控制寄存器 动手! 注册中断 简单整个键盘驱动 Reference ScanCode Table 我们下一步就是准备进一步完善我们系统的交互性。基于这个,我们想到的第一个可以…