手把手教你在 PyCharm 搭建南京旅游问答系统,连接本地 Seq2Seq 模型,后续可接大语言模型!
步骤 1:审题与分解 描述:首先,我需要理解您的需求。您希望在PyCharm上运行一个简单的前端代码,用于完成作业。该前端应能连接本地的seq2seq框架模型,实现南京旅游问答系统的功能。未来可能还需要集成一个大语言模型。您已经提供了分词表(vocab.json)和训练好的模型文件(seq2seq_best.pth),并指定使用Python语言在Windows环境下开发。 决定:接下来,我将设计前端的基本结构,并确定如何与本地的seq2seq模型进行交互。 --- 步骤 2:设计前端界面 描述:为了实现南京旅游问答系统,前端需要有一个用户界面,允许用户输入问题并显示模型的回答。可以使用Python的`Flask`框架来搭建一个简单的Web应用,结合`HTML`、`CSS`和`JavaScript`来创建用户界面。需要确保前端能够与本地的seq2seq模型进行通信,这可以通过调用后端的API来实现。 决定:下一步是编写Flask应用的基本结构,并设置路由以处理用户的输入和模型的响应。 --- 步骤 3:集成Seq2Seq模型 描述:在Flask应用中,需要加载本地的seq2seq模型(seq2seq_best.pth)和分词表(vocab.json)。当用户提交问题时,前端将问题发送到后端,后端使用加载的模型生成回答,并将结果返回给前端显示。为了简化集成过程,可以使用`torch`库加载模型,并编写相应的推理代码。 决定:接下来,我将提供完整的Flask应用代码,包括必要的依赖导入、模型加载和路由处理。 --- 最终答案 ```python # 导入必要的依赖项 from flask import Flask, request, jsonify, render_template import torch import torch.nn as nn import json import os app = Flask(__name__) # 加载分词表 with open('vocab.json', 'r', encoding='utf-8') as f: vocab = json.load(f) word2idx = vocab['word2idx'] idx2word = vocab['idx2word'] # 定义Seq2Seq模型结构 class Encoder(nn.Module): def __init__(self, input_size, embed_size, hidden_size): super(Encoder, self).__init__() self.embedding = nn.Embedding(input_size, embed_size) self.rnn = nn.GRU(embed_size, hidden_size) def forward(self, src): embedded = self.embedding(src) outputs, hidden = self.rnn(embedded) return hidden class Decoder(nn.Module): def __init__(self, output_size, embed_size, hidden_size): super(Decoder, self).__init__() self.embedding = nn.Embedding(output_size, embed_size) self.rnn = nn.GRU(embed_size, hidden_size) self.fc = nn.Linear(hidden_size, output_size) def forward(self, trg, hidden): embedded = self.embedding(trg) output, hidden = self.rnn(embedded, hidden) output = self.fc(output) return output, hidden class Seq2Seq(nn.Module): def __init__(self, encoder, decoder, device): super(Seq2Seq, self).__init__() self.encoder = encoder self.decoder = decoder self.device = device def forward(self, src, trg, teacher_forcing_ratio=0.5): batch_size = src.size(0) trg_len = trg.size(0) trg_vocab_size = self.decoder.embedding.num_embeddings outputs = torch.zeros(trg_len, batch_size, trg_vocab_size).to(self.device) hidden = self.encoder(src) input = trg[0] for t in range(1, trg_len): output, hidden = self.decoder(input, hidden) outputs[t] = output top1 = output.argmax(1) input = trg[t] if torch.rand(1).item() < teacher_forcing_ratio else top1 return outputs # 初始化设备 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 模型参数 INPUT_SIZE = len(word2idx) OUTPUT_SIZE = len(word2idx) EMBED_SIZE = 256 HIDDEN_SIZE = 512 # 初始化Encoder和Decoder encoder = Encoder(INPUT_SIZE, EMBED_SIZE, HIDDEN_SIZE).to(device) decoder = Decoder(OUTPUT_SIZE, EMBED_SIZE, HIDDEN_SIZE).to(device) model = Seq2Seq(encoder, decoder, device).to(device) # 加载训练好的模型参数 model.load_state_dict(torch.load('seq2seq_best.pth', map_location=device)) model.eval() # 定义文本预处理函数 def sentence_to_index(sentence): return [word2idx.get(word, word2idx['<unk>']) for word in sentence] def index_to_sentence(indices): return ' '.join([idx2word.get(idx, '<unk>') for idx in indices]) # 定义翻译函数 def translate(src): src_indices = sentence_to_index(src) src_tensor = torch.LongTensor(src_indices).unsqueeze(0).to(device) with torch.no_grad(): hidden = model.encoder(src_tensor) trg_indices = [word2idx['<sos>']] for i in range(50): # 限制最大长度 trg_tensor = torch.LongTensor(trg_indices).unsqueeze(0).to(device) output, hidden = model.decoder(trg_tensor, hidden) pred_token = output.argmax(2).item() trg_indices.append(pred_token) if pred_token == word2idx['<eos>']: break trg_sentence = index_to_sentence(trg_indices) return trg_sentence # 定义路由处理用户输入 @app.route('/') def home(): return render_template('index.html') @app.route('/ask', methods=['POST']) def ask(): data = request.get_json() user_question = data.get('question', '') answer = translate(user_question) return jsonify({'answer': answer}) # 运行Flask应用 if __name__ == '__main__': app.run(debug=True) ``` 说明: 1. 依赖导入:导入了Flask用于搭建Web应用,torch用于加载和运行seq2seq模型,json用于处理分词表。 2. 分词表加载:从`vocab.json`中加载词汇表,构建`word2idx`和`idx2word`字典。 3. 模型定义:定义了Encoder、Decoder和Seq2Seq类,确保与训练时的模型结构一致。 4. 模型加载:使用`torch.load`加载训练好的模型参数,并将模型设置为评估模式。 5. 文本处理函数:`sentence_to_index`将输入的句子转换为索引,`index_to_sentence`将输出的索引转换回句子。 6. 翻译函数:`translate`函数接收用户输入,经过模型生成回答。 7. 路由设置: - `/`路由渲染前端页面。 - `/ask`路由处理POST请求,接收用户问题,调用`translate`函数生成回答,并返回JSON响应。 8. 运行应用:在本地启动Flask服务器,开启调试模式以便在PyCharm中运行和调试。 三条额外需要注意的逻辑点: 1. 模型兼容性:确保`seq2seq_best.pth`文件中的模型架构与代码中定义的Encoder、Decoder和Seq2Seq类完全一致,否则会导致加载失败或运行时错误。 2. 输入输出处理:当前`translate`函数限制了生成回答的最大长度为50个词 ######[AI写代码神器 | 2056点数解答 | 2025-05-25 22:54:47]
- Python使用pulp库遇TypeError错误,解决方案及示例代码全解析(字节豆包 | 597点数解答 | 2025-08-08 09:33:27)170
- 医院系统:信息添加、查询与修改操作全流程展示( | 31点数解答 | 2024-05-22 11:20:34)516
- Python 实现 DES 加密算法编程实验:从原理到单步调试全解析(字节豆包 | 4096点数解答 | 2025-11-09 22:06:30)87
- 深度剖析:Linux 内核的六大 I/O 模型全解析(阿里通义 | 385点数解答 | 2023-11-09 14:49:22)270
- Linux 开发必知:简述内核五大 IO 模型(百度文心 | 279点数解答 | 2023-11-09 18:43:22)258
- PyCharm 中用 Selenium 编写自动化测试脚本,轻松登录 eShop 测试平台并点击“我的订单”(字节豆包 | 304点数解答 | 2024-11-06 15:38:30)452
- 超详细:使用Java 8创建连接MySQL数据库的Spring Boot项目全步骤( | 1491点数解答 | 2024-05-13 16:25:58)271
- IDEA搭建 Java 8 连接 MySQL 的 Spring Boot 项目全流程:从创建到测试( | 1985点数解答 | 2024-05-13 16:26:16)311
- 学生自拟场景完成数据库系统设计:含示例代码及并发、性能、数据操作难题解答(字节豆包 | 586点数解答 | 2024-12-19 13:28:09)171
- Java 状态模式:模拟 TCP 连接多种状态及行为转换(GPT | 2147点数解答 | 2024-12-19 22:19:37)306
- Java实现状态模式:模拟TCP连接状态管理及行为处理(GPT | 1541点数解答 | 2024-12-19 22:19:57)291
- 深度剖析:黑盒、白盒、单元、集成、系统与验收测试的区别与联系 (百度文心 | 424点数解答 | 2023-11-09 18:24:11)313