【前言】
目前在拥抱AI的时代,我们的单片机如何也能跟上时代的潮流,体验如何与国产大模型deepseek交谈。笔者就此做了探讨,成功的在STM32F769上对接了deepseek本地大模型,实现了无缝交流。
【程序框架】
根据本地大模型的搭建,以及STM32F769的编程,我设计了程序如下:

下面就如何实现分享如下:
一、使用ollama部署本地deepseek大模型。
如何部署deepseek大模型,网上教程非常之名,本篇不做过多分享,我在部置好后,打开本地浏览器,部署成功,如下图:

二、部署转发服务器。
由于直接跟deepseek模型对象,返回的数据包含如下信息:

而我们需要的信息,每一行数据只占用了一小部分,所以我在本地搭建了转发服务器,将服务直接转发到8000端口,其代python代码如下:
import http.server
import socketserver
import http.client
import json
import re
OLLAMA_HOST = 'localhost'
OLLAMA_PORT = 11434
MODEL_NAME = "deepseek-r1:1.5b"
class OllamaProxyHandler(http.server.SimpleHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
try:
request_json = json.loads(post_data)
request_json["model"] = MODEL_NAME
modified_post_data = json.dumps(request_json).encode('utf-8')
# 只保留必要的请求头
necessary_headers = {
'Content-Type': 'application/json',
'Content-Length': str(len(modified_post_data))
}
conn = http.client.HTTPConnection(OLLAMA_HOST, OLLAMA_PORT)
print(f"Forwarding request: {self.path}, {necessary_headers}, {modified_post_data}")
conn.request('POST', self.path, modified_post_data, necessary_headers)
response = conn.getresponse()
# 打印响应状态码和头信息
print(f"Response status: {response.status}")
print(f"Response headers: {response.getheaders()}")
self.send_response(response.status)
# 去掉分块传输编码头
headers_to_send = [
(header, value) for header, value in response.getheaders()
if header.lower() != 'transfer-encoding'
]
for header, value in headers_to_send:
self.send_header(header, value)
# 收集所有 response 字段的内容
response_content = ""
while True:
line = response.readline()
if not line:
break
try:
json_obj = json.loads(line)
print(f"Parsed JSON: {json_obj}")
# 去除 <think> 和 </think> 标签
response_text = json_obj.get('response', "")
response_text = re.sub(r'<think>|</think>', '', response_text)
# 将 \n 或 \n\n 替换为 \r\n
response_text = re.sub(r'\n+', '\r\n', response_text)
response_content += response_text
except json.JSONDecodeError:
print(f"Invalid JSON line: {line.decode('utf-8').strip()}")
continue # 忽略非 JSON 行,继续处理后续数据
# 计算内容长度
response_content_bytes = response_content.encode('utf-8')
content_length = len(response_content_bytes)
self.send_header('Content-Length', str(content_length))
self.end_headers()
# 一次性发送 response 内容给客户端
self.wfile.write(response_content_bytes)
conn.close()
except json.JSONDecodeError:
self.send_error(400, "Bad Request: Invalid JSON data")
except Exception as e:
self.send_error(500, f"Internal Server Error: {str(e)}")
PORT = 8000
with socketserver.TCPServer(("", PORT), OllamaProxyHandler) as httpd:
print(f"Serving at port {PORT}")
httpd.serve_forever()
|
【本地代码实现】
在本地中,我们向shell添加一个http的指令,本地提取指令后,转发给http_post函数,其代码如下:
然后向命令列表添加指令:
这样我就可以使用http cmd向http_post发送数据了。
【http_post】代码实现
1、首先通过shell接收到用户的命令,通过sprintf来组装到发送data中:
发送到服务器后,注册一个void handle_response(struct netconn *conn)进程进行数据接收。
其完整码源码如下:
【实现效果】
源码编译好后下载到开发,进行shell命令,输入http hello返回数据如下:
输入中文:
输入1000*100等于多少:
【总结】
STM32F769通过lwip成功的实现与AI大模型的无缝结合。
下一期,我将驱动LCD屏,将对话结果,展示在屏上。