【异地访问本地DeepSeek】Flask+内网穿透,轻松实现本地DeepSeek的远程访问

devtools/2025/3/3 5:03:32/

写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除!


文章目录

  • 前言
  • 依赖
  • Flask构建本地网页访问
    • LM Studio 开启网址访问
    • DeepSeek 调用模板
    • Flask 访问本地网址
    • HTML内容
    • 本地推理
  • 内网穿透访问
  • 总结
  • 互动
  • 致谢
  • 参考
  • 往期回顾


前言

在人工智能技术日新月异的今天,DeepSeek作为一款强大的大语言模型,已经在众多领域中展现出其巨大的应用潜力。然而,对于许多用户而言,在本地服务器或者电脑部署DeepSeek,异地如何访问本地资源,成为了一个值得思考的问题。

在这里插入图片描述

本文以内网穿透技术实现公网访问,以期为相关从业者或爱好者提供有价值的参考。本地部署DeepSeek,意味着用户可以在自己的服务器上运行这一大语言模型,从而在一定程度上掌控数据的隐私性和安全性。与此同时,通过内网穿透技术,用户还能将本地部署的DeepSeek实例暴露到公网上,实现远程访问和交互。不仅提高了模型的可用性,还为跨地域、跨团队的合作提供了极大的便利。

然而,本地部署和内网穿透并非没有挑战。硬件成本、维护成本、技术门槛以及安全风险等问题,都是用户在决策过程中需要考虑的关键因素。因此,本文旨在全面分析本地部署DeepSeek并通过内网穿透实现公网访问的必要性,帮助用户权衡利弊,做出最适合自己的选择。


依赖

本地部署: 【DeepSeek本地化部署保姆级教程 】

如果需要创建新环境:conda create -n deepseek python=3.7

  • Window 11
  • Flask
  • markdown2

安装: pip install Flaskpip install markdown2

Flask构建本地网页访问

LM Studio 开启网址访问

确保加载合适的模型(GGUF),然后在开发者选项中确保开启运行,并查看对应的IP和端口,此处http://127.0.0.1:1234,这个区别于OpenAI。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

DeepSeek 调用模板

DeepSeek 调用模板:首次调用 API

python"># Please install OpenAI SDK first: `pip3 install openai`from openai import OpenAIclient = OpenAI(api_key="<DeepSeek API Key>", base_url="https://api.deepseek.com")response = client.chat.completions.create(model="deepseek-chat",messages=[{"role": "system", "content": "You are a helpful assistant"},{"role": "user", "content": "Hello"},],stream=False
)print(response.choices[0].message.content)

此处提供了OpenAI的调用方式,由于需要api_key显得比较麻烦或者需要付费,因此直接和LM Studio 的本地网址进行访问。

Flask 访问本地网址

通过上述模板构建本地的API,将Flask构建的网页 的输入框的内容传入到messages中,随后将其传入到LM Studio进行推理,将返回的结果进一步展示到Flask构建的对话框中即可。下面是app.py的逻辑:

python">from flask import Flask, request, jsonify, render_template
import markdown2
import requestsAPI_URL = "http://localhost:1234/v1/chat/completions"headers = {"Content-Type": "application/json"
}app = Flask(__name__, template_folder='templates',)
app.static_folder = 'static'
@app.route('/')
def index():return render_template("index.html")@app.route('/process', methods=['POST'])
def process():data = request.get_json()user_input = data['input']# user_input = request.form['user_input']messages = [{"role": "system", "content": "你是一个优秀的人工智能助手"},{"role": "user", "content": f"{user_input}"},]data = {"model": "DeepSeek/7B/DeepSeek-R1-Distill-Qwen-7B-Q6_K.gguf",  # 你的 DeepSeek 模型名称"messages": messages,"stream": False  # 关闭流式输出}response = requests.post(API_URL, headers=headers, json=data)if response.status_code == 200:result = response.json()else:print("请求失败:", response.status_code, response.text)# 将用户输入和脚本输出以对话形式返回conversation = [{"user": user_input},{"script": result["choices"][0]["message"]["content"]}]markdown_text = conversation[1]["script"]html_content = markdown2.markdown(markdown_text)response_message = f"DeepSeek: {html_content}"return jsonify({'message': response_message})if __name__ == '__main__':app.run(debug=False)

调试阶段可以使用app.run(debug=True),确定后改为False。

HTML内容

HTML可以使用大模型直接输出,下面是一个示范的提示词:

你的任务是使用python、Flask创建一个网页,具体要求如下:
1. 网页需包含两个文本框,一个用于获取用户输入,另一个用于显示Python脚本的返回内容。
2. 输入框需固定于网页中底部并居中,并长度仅为网页宽度50%,发送键位于输入框的右侧,发送键实现将输入框的文本发送给脚本
3. 输出框以对话的形式进行展示,同时位于位于输入框的上方并居中,并长度仅为网页宽度50%,展示用户的输入和脚本的返回内容
4. 网页需要有背景图
5. 只需要一个html和app.py

需要注意,如果无法加载图片,将其放在static文件夹中,配合app.static_folder = 'static'使用
下面是不断调整后的一个html文件的内容:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Flask DeepSeek</title><style>body {margin: 0;font-family: Arial, sans-serif;background-image: url("../static/back.jpg");background-size: cover;background-position: center;display: flex;flex-direction: column;align-items: center;justify-content: center;height: 100vh;}.container {width: 55%;/*text-align: center;*/background-color: rgba(255, 255, 255, 0.8);padding: 20px;border-radius: 10px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);}.chat-box {height: 400px;overflow-y: auto;border: 1px solid #ccc;padding: 10px;margin-bottom: 10px;}.input-group {display: flex;justify-content: space-between;align-items: center;width: 100%;}.input-group input {width: calc(90% - 10px);padding: 10px;border: 1px solid #ccc;border-radius: 5px;}.input-group button {width: calc(10% - 10px);padding: 10px;border: 1px solid #ccc;border-radius: 10px;background-color: #007bff;}.input-group button:hover {background-color: #0056b3;}</style>
</head>
<body><div class="container"><div class="chat-box" id="chat-box"><!-- 聊天内容将会通过JavaScript动态添加 --></div><div class="input-group"><input type="text" id="user-input" placeholder="输入你的消息..."><button onclick="sendMessage()">发送</button></div></div><script>function appendMessage(message, isUser) {const chatBox = document.getElementById('chat-box');const messageElement = document.createElement('div');messageElement.textContent = message;messageElement.style.color = isUser ? 'blue' : 'black';messageElement.style.padding = '5px';messageElement.style.borderBottom = '1px solid #ccc';chatBox.appendChild(messageElement);chatBox.scrollTop = chatBox.scrollHeight;}function sendMessage() {const userInput = '用户:' + document.getElementById('user-input').value;if (userInput.trim() !== '') {const xhr = new XMLHttpRequest();xhr.open('POST', '/process', true);xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {const response = JSON.parse(xhr.responseText);appendMessage(userInput, true);appendMessage(response.message, false);document.getElementById('user-input').value = '';}};xhr.send(JSON.stringify({ input: userInput }));}}</script>
</body>
</html>

网页的结构如下:
在这里插入图片描述

本地推理

在输入框中输入问题后发送,获取7B模型的返回值,网址:http://127.0.0.1:5000,结果如下
在这里插入图片描述

LM Studio中的记录如下:

2025-02-28 23:04:32  [INFO] 
[LM STUDIO SERVER] Running chat completion on conversation with 2 messages.
2025-02-28 23:04:33  [INFO] 
[LM STUDIO SERVER] Accumulating tokens ... (stream = false)
2025-02-28 23:05:33  [INFO] 
[LM STUDIO SERVER] [7b] Generated prediction:  {"id": "chatcmpl-cc7tk9bfa4b9gb6mhlztg","object": "chat.completion","created": 1740755072,"model": "7b","choices": [{"index": 0,"logprobs": null,"finish_reason": "stop","message": {"role": "assistant","content": "<think>\n好,我现在要介绍重庆。首先,重庆是一个直辖市,在中国南方,连接长江和嘉陵江。地理位置优越,是长江经济带的重要城市。\n\n重庆有很多景点,比如洪崖洞、解放碑、长江索道等,这些都是游客必去的地方。还有火锅和川菜非常有名,尤其是磁器口古镇里的小吃,可以品尝到地道的重庆味道。\n\n重庆的地形多样,既有 flat 的地区,也有山和江。著名的龙舟峡和武隆喀斯特地貌吸引了不少游客。\n\n重庆是一个比较开放的城市,经济繁荣,而且语言相对通用,这对于国际交流很有帮助。\n\n交通方面,重庆有便捷的高铁、地铁和轻轨系统,方便游客出行。\n\n气候温暖湿润,四季分明,适合各种活动。\n\n最后,重庆不仅是一个旅游胜地,也是一座充满活力的城市,有很多现代化的设施和文化活动。总的来说,重庆是一个值得一游的地方。\n</think>\n\n当然!重庆是中国的一个直辖市,位于中国南方,具体位置是在重庆市,地处长江与嘉陵江之间。以下是关于重庆的一些详细介绍:\n\n### 1. **地理位置**\n   - 重庆是中国南方的交通枢纽之一,连接长江和嘉陵江。\n   - 地处长江经济带中心地带,具有重要的战略地位。\n\n### 2. **景点与文化**\n   - **洪崖洞**:以吊脚楼建筑和夜景闻名,是重庆的标志性景点。\n   - **解放碑**:重庆的商业中心之一,拥有众多店铺和商业娱乐设施。\n   - **长江索道**:横跨长江的空中交通工具,提供壮丽的景色观赏。\n   - **磁器口古镇**:以美食和传统手工艺品闻名,是品尝重庆火锅和了解当地文化的好去处。\n\n### 3. **美食**\n   - 重庆火锅是中国最著名的火锅之一,以其麻辣鲜香著称。\n   - 其他特色美食包括小面、酸辣粉、毛血旺等。\n\n### 4. **地形与气候**\n   - 重庆地形多样,既有平坦的地区,也有山脉和河流。武隆喀斯特地貌是世界自然遗产之一。\n   - 气候温暖湿润,四季分明,雨量充沛。\n\n### 5. **经济与开放**\n   - 作为直辖市,重庆在西南地区的经济发展中占有重要地位。\n   - 外贸中心之一,拥有较为自由的市场准入政策。\n\n### 6. **交通**\n   - 运输系统完善,包括高铁、地铁和轻轨,方便游客出行。\n   - 公共交通发达,覆盖范围广。\n\n### 7. **语言与文化**\n   - 汉语以外的主要少数民族有苗族、汉族、土家族等,多元文化交融显著。\n\n总的来说,重庆是一个历史悠久、风景优美且充满活力的城市。无论是自然风光、美食文化还是历史遗迹,都让人流连忘返。"}}],"usage": {"prompt_tokens": 15,"completion_tokens": 601,"total_tokens": 616},"stats": {},"system_fingerprint": "7b"
}

内网穿透访问

内网穿透工具较多,此处使用花生壳为例子。

  • 登录后,选择内网穿透
    在这里插入图片描述
  • 选择添加映射
    在这里插入图片描述
  • 填写映射信息

在这里插入图片描述

  • 查看公网网址
    在这里插入图片描述

  • 公网访问
    在这里插入图片描述

总结

总结: 为了方便本地化部署后,异地调用本地模型进行推理,可以按照以下步骤操作:

  1. 基础环境:在LM Studio官网下载并运行对应的GGUF模型,以及安装对应的python包。
  2. Flask构建网页:Flask结合LM Studio的端口和HTML构建网页,实现网页对话。
  3. 内网穿透:通过花生壳将Flask所开放的端口进行映射,实现异地访问本地的模型。

互动

  • 你觉得上述内容对你有帮助吗?`

欢迎在评论区解答上述问题,分享你的经验和疑问!

当然,也欢迎一键三连给我鼓励和支持:👍点赞 📁 关注 💬评论。


致谢

欲尽善本文,因所视短浅,怎奈所书皆是瞽言蒭议。行文至此,诚向予助与余者致以谢意。


参考

[1] DeepSeek API 文档


往期回顾


👆 DeepSeek本地化部署保姆级教程👆

👆 EfficientTrain++帮你降低网络训练的成本👆

👆 PyCharm环境下Git与Gitee联动👆

👆 Ping通但SSH连接失败的解决办法👆

👆 轻量化设计如何提高模型的推理速度👆

👆 正则化与正则剪枝👆

http://www.ppmy.cn/devtools/164098.html

相关文章

Spark技术系列(二):深入理解RDD编程模型——从原理到生产实践

Spark技术系列(二):深入理解RDD编程模型——从原理到生产实践 1. RDD设计哲学与核心定位 1.1 为什么需要RDD? MapReduce的缺陷:固定Map/Reduce阶段、中间数据频繁落盘、难以处理迭代计算RDD(Resilient Distributed Datasets)核心价值: 内存计算:中间结果缓存至内存,…

游戏引擎学习第125天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾并为今天的内容做准备。 昨天&#xff0c;当我们离开时&#xff0c;工作队列已经完成了基本的功能。这个队列虽然简单&#xff0c;但它能够执行任务&#xff0c;并且我们已经为各种操作编写了测试。字符串也能够正常推送到队…

DeepSeep开源周,第三天:DeepGEMM是啥?

Deep GEMM 是 Deepseek 开源的一个高性能矩阵乘法优化库&#xff0c;专为深度学习场景设计。矩阵乘法&#xff08;GEMM&#xff09;是深度学习模型的核心运算&#xff08;如全连接层、卷积层等&#xff09;&#xff0c;其性能直接影响训练和推理效率。Deep GEMM 通过算法优化、…

Linux下的网络通信编程

在不同主机之间&#xff0c;进行进程间的通信。 1解决主机之间硬件的互通 2.解决主机之间软件的互通. 3.IP地址&#xff1a;来区分不同的主机&#xff08;软件地址&#xff09; 4.MAC地址&#xff1a;硬件地址 5.端口号&#xff1a;区分同一主机上的不同应用进程 网络协议…

Storm实时流式计算系统(全解)——中

storm编程的基本概念-topo-spout-bolt 例如下&#xff1a; storm 编程接口-spout的结构及组件实现 storm编程案例-spout组件-实现 这是我的第一个组件&#xff08;spout组件继承BaseRichSput&#xff09;所有重写内部的三个方法&#xff0c;用于接收数据&#xff08;这里数据是…

构建神经网络之常用pandas(补充中 )

1.serials&#xff1a; pspandas.Series(dataNone, indexNone, dtypeNone, nameNone, copyFalse, fastpathFalse) 建议&#xff1a;封装一维数组就行了2.DataFrame import pandas as pd# 创建 DataFrame data {Name: [Alice, Bob, Charlie, David],Age: [25, 30, 35, 40],Ci…

Python的那些事第三十四篇:基于 Plotly 的交互式图表与仪表板设计与应用

基于 Plotly 的交互式图表与仪表板设计与应用 摘要: 本文深入探讨了 Plotly 这一强大的交互式图表和仪表板库。首先介绍了 Plotly 的背景与发展历程,随后详细阐述了其核心功能特性,包括丰富的图表类型、高度的自定义能力以及便捷的交互操作。通过实际案例分析和示例代码展示…

【Java项目】基于Spring Boot的校园闲置物品交易网站

【Java项目】基于Spring Boot的校园闲置物品交易网站 技术简介&#xff1a;采用Java技术、Spring Boot框架、MySQL数据库等实现。 系统简介&#xff1a;校园闲置物品交易网站是一个典型的管理系统&#xff0c;主要功能包括管理员&#xff1a;首页、个人中心、用户管理、商品类…