【新手指南】pyqt可视化远程部署deepseek7B蒸馏版模型
本地效果:(如果想做这个的本科毕设,建议美化界面。)

总结:MobaXterm远程连接autodl服务器,在MobaXterm上利用X11转发使pyqt可视化页面在自己的电脑上展现出来。
1. 官网下载MobaXterm
MobaXterm free Xserver and tabbed SSH client for Windows,我认为这个比pycharm专业版连接autodl服务器更加好用。pycharm需要考虑同步,MobaXterm不需要点那么多同步设置。在MobaXterm上操作也比autodl上的jupyterlab好操作。
2. 在autodl上租服务器
一般一个小时1.6-2r。这里注意显存大小能否支撑起模型的参数量(关于这个具体是怎么判断的,我还不会,会了再补充)我租的是4090D,建议起个早租卡,现在是晚上八点,我刚才创建新的实例租卡租不了,但是早上八点我看有富余。
镜像可以选择社区镜像,我用的是V3版本,它自带了1.5B的模型。deepseek-ai/DeepSeek-R1/DeepSeek-R1: 【一键聊天,多维研究】 DeepSeek-R1,目前位居全球大模型竞技榜前三,性能对标OpenAIo1正式版。深度求索(DeepSeek)公司在2025年1月20日发布的最新模型! - CG
3. MobaXterm连接autodl服务器
【MobaXterm】登录与连接服务器教程_mobaxterm怎么连接服务器-CSDN博客
4. 我下载了7B的模型,注意下面下载到autodl-tmp目录中。
conda activate torch_env
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --local-dir /root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B --resume-download
7B模型运行相比1.5那个应该只改了模型路径,运行后可以在终端与模型对话,输入exit退出:
文件名:deepseek_multichat-7B.py
终端运行输入:python deepseek_multichat-7B.py
import os
import json
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import unicodedata
from typing import List@torch.inference_mode()
def generate(model: AutoModelForCausalLM,input_ids: torch.Tensor,attention_mask: torch.Tensor,max_new_tokens: int,temperature: float = 1.0
) -> List[int]:"""Generate response from the model with attention_mask provided."""outputs = model.generate(input_ids=input_ids,attention_mask=attention_mask, # 提供显式 attention maskmax_new_tokens=max_new_tokens,temperature=temperature,eos_token_id=model.config.eos_token_id,pad_token_id=model.config.eos_token_id,do_sample=True,top_k=50,top_p=0.95,)return outputs[0].tolist()def clean_input(user_input):"""清理用户输入,去除不可见字符和多余的空格。"""user_input = "".join(c for c in user_input if not unicodedata.category(c).startswith("C")) # 移除控制字符return user_input.strip() # 去除首尾空格def clean_message_content(content):"""清理消息内容,去除首尾空格并过滤非法输入"""if not content or not isinstance(content, str):return ""return content.strip() # 去除首尾空格def build_prompt(messages, max_history=3):"""Build prompt for the model, limiting the history to the most recent messages."""template = "The following is a conversation with an AI assistant. The assistant is helpful, knowledgeable, and polite:\n"for msg in messages[-max_history:]:content = clean_message_content(msg["content"])if not content: # 跳过空内容continuetemplate += f"{msg['role'].capitalize()}: {content}\n"template += "Assistant: "return template.strip() # 确保返回值是字符串if __name__ == "__main__":print("Initializing DeepSeek-R1 Service...")# Configurationckpt_path = "/root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B" # 模型所在的目录config_path = "/root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B/config.json" # 配置文件路径# Load tokenizer and modeltokenizer = AutoTokenizer.from_pretrained(ckpt_path) model = AutoModelForCausalLM.from_pretrained(ckpt_path,torch_dtype=torch.bfloat16,).cuda()# Interactive sessionmessages = [] # To maintain contextwhile True:user_input = input("You: ").strip() # 去除首尾空格user_input = clean_input(user_input) # 清理不可见字符if not user_input or len(user_input.strip()) == 0: # 检查无效输入print("Invalid input. Please type something meaningful!")continueif user_input.lower() in ["exit", "quit"]:print("Exiting conversation. Goodbye!")break# Append user input to contextmessages.append({"role": "user", "content": user_input})# Limit conversation historymessages = messages[-10:] # 只保留最近 10 条对话# Build prompt and tokenizeprompt = build_prompt(messages)if not isinstance(prompt, str) or len(prompt.strip()) == 0: # 确保 prompt 非空print("Error: Prompt is empty or invalid. Skipping this turn.")continuetokenized_prompt = tokenizer(prompt, return_tensors="pt", truncation=True, padding=True)input_ids = tokenized_prompt["input_ids"].to("cuda")attention_mask = tokenized_prompt["attention_mask"].to("cuda")# Generate responsemax_new_tokens = 500 #150temperature = 0.7completion_tokens = generate(model, input_ids, attention_mask, max_new_tokens, temperature)completion = tokenizer.decode(completion_tokens[len(input_ids[0]):], # 从输入长度截取生成部分skip_special_tokens=True).split("User:")[0].strip()print(f"Assistant: {completion}")# Append assistant response to contextmessages.append({"role": "assistant", "content": completion})
5. 接下来是最让我头疼的pyqt图形化页面显示。
autodl上是不能直接运行出图形化页面的。可以解决有两种方式:第一种方法:模型利用flask打包成api接口,然后在自己电脑上访问这个接口,在自己电脑上显示出来图形化页面;第二种方法:利用X11转发功能,在autodl上运行图形化页面程序,然后在自己电脑上显示。我用的第二种方法,第一种方法是问了师兄,这个还没尝试,之后尝试了再记录。
一开始用Xlaunch不行,MobaXterm就不需要那么多配置。
如果X11 Forward 显示红叉 可以参考:MobaXterm连接服务器,通过x11 Forwarding实现图形可视化(记录个人学习过程)_mobaxterm x11-CSDN博客
最重要的应该是那个X11UseLocalhost no,我用的pyqt,不需要localhost,也设置了no
pyqt页面代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import os
import json
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import unicodedata
from typing import List# 原模型相关代码保持不变
# [此处插入原文件中的模型加载和生成相关函数,保持原样]@torch.inference_mode()
def generate(model: AutoModelForCausalLM,input_ids: torch.Tensor,attention_mask: torch.Tensor,max_new_tokens: int,temperature: float = 1.0
) -> List[int]:"""Generate response from the model with attention_mask provided."""outputs = model.generate(input_ids=input_ids,attention_mask=attention_mask, # 提供显式 attention maskmax_new_tokens=max_new_tokens,temperature=temperature,eos_token_id=model.config.eos_token_id,pad_token_id=model.config.eos_token_id,do_sample=True,top_k=50,top_p=0.95,)return outputs[0].tolist()def clean_input(user_input):"""清理用户输入,去除不可见字符和多余的空格。"""user_input = "".join(c for c in user_input if not unicodedata.category(c).startswith("C")) # 移除控制字符return user_input.strip() # 去除首尾空格def clean_message_content(content):"""清理消息内容,去除首尾空格并过滤非法输入"""if not content or not isinstance(content, str):return ""return content.strip() # 去除首尾空格def build_prompt(messages, max_history=3):"""Build prompt for the model, limiting the history to the most recent messages."""template = "The following is a conversation with an AI assistant. The assistant is helpful, knowledgeable, and polite:\n"for msg in messages[-max_history:]:content = clean_message_content(msg["content"])if not content: # 跳过空内容continuetemplate += f"{msg['role'].capitalize()}: {content}\n"template += "Assistant: "return template.strip() # 确保返回值是字符串class ChatWindow(QWidget):def __init__(self, model, tokenizer):super().__init__()self.model = modelself.tokenizer = tokenizerself.messages = []self.init_ui()def init_ui(self):self.setWindowTitle('DeepSeek Chat')self.setGeometry(300, 300, 800, 600)# 创建界面组件self.history_area = QTextEdit()self.history_area.setReadOnly(True)self.input_area = QTextEdit()self.input_area.setMaximumHeight(100)self.send_btn = QPushButton('发送')self.clear_btn = QPushButton('清空历史')# 布局设置vbox = QVBoxLayout()vbox.addWidget(self.history_area)hbox = QHBoxLayout()hbox.addWidget(self.input_area)hbox.addWidget(self.send_btn)hbox.addWidget(self.clear_btn)vbox.addLayout(hbox)self.setLayout(vbox)# 信号连接self.send_btn.clicked.connect(self.on_send)self.clear_btn.clicked.connect(self.on_clear)self.input_area.installEventFilter(self)def eventFilter(self, obj, event):if obj is self.input_area and event.type() == QEvent.KeyPress:if event.key() == Qt.Key_Return and event.modifiers() & Qt.ControlModifier:self.on_send()return Truereturn super().eventFilter(obj, event)def update_history(self, role, content):self.history_area.append(f"<b>{role.capitalize()}:</b> {content}<br>")self.history_area.verticalScrollBar().setValue(self.history_area.verticalScrollBar().maximum())def on_clear(self):self.messages = []self.history_area.clear()def on_send(self):user_input = self.input_area.toPlainText().strip()if not user_input:return# 清理输入user_input = clean_input(user_input)self.input_area.clear()self.update_history("user", user_input)# 添加到消息历史self.messages.append({"role": "user", "content": user_input})self.messages = self.messages[-10:]# 在后台线程生成回复self.worker = Worker(self.model, self.tokenizer, self.messages)self.worker.finished.connect(self.handle_response)self.worker.start()def handle_response(self, completion):self.messages.append({"role": "assistant", "content": completion})self.update_history("assistant", completion)class Worker(QThread):finished = pyqtSignal(str)def __init__(self, model, tokenizer, messages):super().__init__()self.model = modelself.tokenizer = tokenizerself.messages = messagesdef run(self):prompt = build_prompt(self.messages)tokenized_prompt = self.tokenizer(prompt, return_tensors="pt", truncation=True, padding=True)input_ids = tokenized_prompt["input_ids"].to("cuda")attention_mask = tokenized_prompt["attention_mask"].to("cuda")max_new_tokens = 500temperature = 0.7completion_tokens = generate(self.model, input_ids, attention_mask, max_new_tokens, temperature)completion = self.tokenizer.decode(completion_tokens[len(input_ids[0]):],skip_special_tokens=True).split("User:")[0].strip()self.finished.emit(completion)if __name__ == "__main__":# 初始化模型(原代码部分)print("Initializing DeepSeek-R1 Service...")ckpt_path = "/root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B"tokenizer = AutoTokenizer.from_pretrained(ckpt_path) model = AutoModelForCausalLM.from_pretrained(ckpt_path,torch_dtype=torch.bfloat16,).cuda()# 启动GUIapp = QApplication(sys.argv)window = ChatWindow(model, tokenizer)window.show()sys.exit(app.exec_())
相关文章:
【新手指南】pyqt可视化远程部署deepseek7B蒸馏版模型
本地效果:(如果想做这个的本科毕设,建议美化界面。) 总结:MobaXterm远程连接autodl服务器,在MobaXterm上利用X11转发使pyqt可视化页面在自己的电脑上展现出来。 1. 官网下载MobaXterm MobaXterm free Xse…...
大语言模型在患者交互任务中的临床使用评估框架
An evaluation framework for clinical use of large language models in patient interaction tasks An evaluation framework for clinical use of large language models in patient interaction tasks | Nature Medicine 2025.1 收到时间:2023 年 8 月 8 日 …...
DeepSeek-V3 技术报告解读
DeepSeek火了有一段时间了,春节假期因为没时间,所以关于deepseek大模型一系列的技术报告一直没看,新年开工后,抽一点时间把之前的坑补起来,关于DeepSeek-V3技术报告的解读已经有很多了,但我相信不同的人去读…...
suricata安装测试
系统版本为Ubuntu 22.04.4。 # cat /etc/issue Ubuntu 22.04.4 LTS \n \l # # uname -a Linux logging 6.8.0-49-generic #49~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Nov 6 17:42:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux添加suricata的apt库。 # add-apt-repository pp…...
Java反射简单理解
Java反射是指在运行时(runtime)能够动态地获取类的内部信息,并能直接操作类的属性和方法的一种机制。通过反射,开发者可以在运行时检查类、接口、字段和方法,并且可以调用这些方法和访问这些字段,而无需在编…...
WPS Word中英文混杂空格和行间距不一致调整方案
文章目录 问题1:在两端对齐的情况下,如何删除参考文献(英文)的空格问题2:中英文混杂行间距不一致问题问题3:设置中文为固定字体,设置西文为固定字体参考 问题1:在两端对齐的情况下&a…...
探秘沃尔什-哈达玛变换(WHT)原理
沃尔什-哈达玛变换(WHT)起源 起源与命名(20世纪早期) 数学基础:该变换的理论基础由法国数学家雅克哈达玛(Jacques Hadamard)在1893年提出,其核心是哈达玛矩阵的构造。扩展与命名&…...
优雅拼接字符串:StringJoiner 的完整指南
在Java开发中,字符串拼接是高频操作。无论是日志格式化、构建CSV数据,还是生成动态SQL,开发者常需处理分隔符、前缀和后缀的组合。传统的StringBuilder虽然灵活,但代码冗余且易出错。Java 8推出的StringJoiner类,以简洁…...
AFL++安装
学习fuzzing也几天了,今天记录AFL的安装及使用 一、实验环境 虚拟机:ubuntu20.04 当然也可以uname -a去看自己的版本号 二、AFL安装 1.先更新一下工具 sudo apt update2.安装AFL必要的一些依赖,例如编译工具(如 build-essen…...
开发者社区测试报告(功能测试+性能测试)
功能测试 测试相关用例 开发者社区功能背景 在当今数字化时代,编程已经成为一项核心技能,越来越多的人开始学习编程,以适应快速变化的科技 环境。基于这一需求,我设计开发了一个类似博客的论坛系统,专注于方便程序员…...
如何优化 VS Code 远程开发环境?高效配置与性能提升策略
相关系列文章 《新手教学系列——善用 VSCode 工作区,让开发更高效》 《新手教学系列——用 VSCode 实现高效远程开发》 《Webpack 优化全攻略:彻底解决 Vue 项目 npm run dev 的内存泄露问题》 引言 随着开发环境不断进化,VS Code 作为一款轻量级的代码编辑器,已经成为…...
【二】JavaScript能力提升---this对象
目录 this的理解 this的原理 事件绑定中的this 行内绑定 动态绑定 window定时器中的this 相信小伙伴们看完这篇文章,对于this的对象可以有一个很大的提升! this的理解 对于this指针,可以先记住以下两点: this永远指向一个…...
YC 孵化项目 Pinch:实时语音翻译视频会议平台;Mistral OCR:能处理多语言多模态复杂文档丨日报
开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。 我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 …...
OSPF报文分析
OSPF报文分析 组播地址 224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用; 224.0.1.0~238.255.255.255为用户可用的组播地址(…...
蓝桥杯刷题周计划(第二周)
目录 前言题目一题目代码题解分析 题目二题目代码题解分析 题目三题目代码题解分析 题目四题目代码题解分析 题目五题目代码题解分析 题目六题目代码题解分析 题目七题目代码题解分析 题目八题目题解分析 题目九题目代码题解分析 题目十题目代码题解分析 题目十一题目代码题解分…...
PH热榜 | 2025-03-09
1. ResumeUp 2.0 标语:聊聊,几分钟内就能帮助你打造完美的ATS简历。 介绍:告别为写完美简历而烦恼的日子吧!只需与人工智能聊天,回答几个简单的问题,就能在几分钟内生成强有力的简历,不仅能通…...
《gradio :AI demos》
《gradio :AI demos》 Folders and files Name Last commit message Last commit date parent directory .. agent_chatbot Declare exports in __all__ for type checking (#10238) 3 months ago all_demos Fix deployed Spaces (#10271) 2 months ago …...
Interop_UdsProtocolStack之数据解析器使用方法
一、背景与需求 在汽车电子领域,UDS(Unified Diagnostic Services)协议栈的响应报文解析是实现ECU诊断功能的核心环节。本文提出一种基于配置驱动的通用解析器开发方案,满足以下行业需求: 多协议兼容性:支…...
从0开始完成基于异步服务器的boost搜索引擎
文章目录 前言一、本项目涉及的技术栈和环境二、boost是什么?三、项目的相关背景四、项目的相关原理五、正排索引 vs 倒排索引 - 搜索引擎具体原理六、 编写数据去标签与数据清洗的模块 Parser6.1 下载boost的文档库6.2 去标签6.3 代码编写 七、索引模块7.1. 整体框…...
炒菜本质是 “能量(火候)与食材特性”的动态平衡
炒菜看似简单,但想要做到色香味俱全,需遵循一套清晰的逻辑链条。以下从底层逻辑到实操步骤拆解: 一、核心逻辑:控制变量,精准匹配 炒菜本质是 “能量(火候)与食材特性”的动态平衡,…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
