跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

OpenVINO 本地部署 DeepSeek-R1 量化大模型:前端交互与后端服务

介绍基于 OpenVINO 本地部署 DeepSeek-R1 量化大模型的前端交互与后端服务实现。内容涵盖前端 HTML 页面开发、Flask 后端接口搭建及 OpenVINO GenAI 推理引擎集成。通过示例代码展示了健康检查、对话生成及模型信息获取等核心功能,并分析了 CPU 和内存的资源占用情况,为本地化运行大模型提供参考方案。

黑客帝国发布于 2026/4/6更新于 2026/7/2453 浏览
OpenVINO 本地部署 DeepSeek-R1 量化大模型:前端交互与后端服务

一、前言

基于上一章的环境准备和模型转换,本章专注于后端服务器的部署以及前端页面的启动。

整个后端服务器是依赖于 OpenVINO 的,不过只要你的设备可以使用 OpenVINO,理论上就可以使用这个后端,如果你有 intel 的独立显卡,只需要把代码中 device 更改为对应的设备即可运行在 GPU 上。

self.pipeline = ov_genai.LLMPipeline(self.model_path, device)

二、前端交互界面

chat_interface.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DeepSeek-R1 智能对话</title>
<link rel="icon" type="image/svg+xml" href="logo.svg">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: linear-gradient(135deg, #667eea ,  ); : ; : ; }
 { : ; :  auto; : white; : ; :    (,,,); : hidden; : flex; : column; : ; }
 { : ; : white; : ; : center; }
 { : ; :  ; :  solid ; : flex; : space-between; : center; : ; }
 { :  ; : ; : bold; }
 { : ; : ; }
 { : ; : ; }
 { : ; : auto; : ; : ; }
 { : ; : flex; : flex-start; }
 { : flex-end; }
 { : flex-start; }
 { : ; :  ; : ; : ; }
  { : ; : white; : ; }
  { : white; : ; :  solid ; : ; }
 { : ; : ; : ; }
 { : none; : ; : italic; :  ; :  ; }
 { : ; : white; :  solid ; }
 { : flex; : ; }
 { : ; :  ; :  solid ; : ; : none; : ; }
 { : ; }
 { :  ; : ; : white; : none; : ; : pointer; : ; : background ; }
() { : ; }
 { : ; : not-allowed; }
 { : center; : ; : ; :  ; : ; : ; : ; }




🤖 DeepSeek-R1 智能对话
基于 OpenVINO 本地部署


服务状态:检测中...
模型加载中

系统正在初始化,请稍候...
DeepSeek 正在思考中...





发送






0%
#764ba2
100%
min-height
100vh
padding
20px
.chat-container
max-width
900px
margin
0
background
border-radius
15px
box-shadow
0
10px
30px
rgba
0
0
0
0.2
overflow
display
flex-direction
height
90vh
.chat-header
background
#2d3748
color
padding
25px
text-align
.status-bar
background
#f7fafc
padding
10px
20px
border-bottom
1px
#e2e8f0
display
justify-content
align-items
font-size
14px
.status-indicator
padding
4px
12px
border-radius
12px
font-weight
.status-loading
background
#fed7d7
color
#c53030
.status-ready
background
#c6f6d5
color
#276749
.chat-messages
flex
1
overflow-y
padding
20px
background
#f7fafc
.message
margin-bottom
15px
display
align-items
.user-message
justify-content
.bot-message
justify-content
.message-bubble
max-width
70%
padding
12px
18px
border-radius
18px
line-height
1.4
.user-message
.message-bubble
background
#4299e1
color
border-bottom-right-radius
5px
.bot-message
.message-bubble
background
color
#2d3748
border
1px
#e2e8f0
border-bottom-left-radius
5px
.message-time
font-size
12px
color
#718096
margin-top
5px
.typing-indicator
display
color
#718096
font-style
margin
10px
0
padding
0
20px
.chat-input-container
padding
20px
background
border-top
2px
#e2e8f0
.chat-input
display
gap
10px
#messageInput
flex
1
padding
12px
15px
border
1px
#cbd5e0
border-radius
25px
outline
font-size
16px
#messageInput
:focus
border-color
#4299e1
#sendButton
padding
12px
25px
background
#4299e1
color
border
border-radius
25px
cursor
font-size
16px
transition
0.3s
#sendButton
:hover
:not
:disabled
background
#3182ce
#sendButton
:disabled
background
#a0aec0
cursor
.system-message
text-align
color
#718096
font-size
14px
margin
10px
0
padding
8px
background
#edf2f7
border-radius
8px
</style>
</head>
<body>
<div>
<h1>
</h1>
<p>
</p>
</div>
<div>
<span>
<span id="statusText">
</span>
</span>
<span id="modelStatus">
</span>
</div>
<div id="loadingMessage">
</div>
<div id="thinkingMessage">
</div>
<div class="chat-container">
<div class="chat-messages" id="chatMessages">
</div>
<div class="chat-input-container">
<div class="chat-input">
<input type="text" placeholder="输入您的问题..." autocomplete="off" disabled id="messageInput">
<button disabled id="sendButton">
</button>
</div>
</div>
</div>
<script>
const API_BASE = 'http://localhost:5000'; const chatMessages = document.getElementById('chatMessages'); const messageInput = document.getElementById('messageInput'); const sendButton = document.getElementById('sendButton'); const typingIndicator = document.getElementById('typingIndicator'); const statusText = document.getElementById('statusText'); const modelStatus = document.getElementById('modelStatus'); async function checkServerStatus() { try { const response = await fetch(`${API_BASE}/health`); const data = await response.json(); if (data.status === 'ready') { statusText.textContent = 'OpenVINO 服务就绪'; modelStatus.textContent = 'CPU 加速就绪'; modelStatus.className = 'status-indicator status-ready'; messageInput.disabled = false; sendButton.disabled = false; messageInput.placeholder = "输入您的问题..."; if (chatMessages.querySelector('.system-message')) { chatMessages.innerHTML = ''; addMessage('您好!我是基于 OpenVINO GenAI 优化的 AI 助手,现在运行在 CPU 上,为您提供高效的本地推理服务。', false); } return true; } else { statusText.textContent = 'OpenVINO 模型加载中...'; modelStatus.textContent = '优化中'; modelStatus.className = 'status-indicator status-loading'; messageInput.placeholder = "OpenVINO 模型优化加载中,请稍候..."; return false; } } catch (error) { statusText.textContent = 'OpenVINO 服务未连接'; modelStatus.textContent = '离线'; modelStatus.className = 'status-indicator status-loading'; messageInput.placeholder = "无法连接到 OpenVINO 服务,请检查服务器状态"; return false; } } function getCurrentTime() { return new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }); } function addMessage(content, isUser = false) { const messageDiv = document.createElement('div'); messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`; messageDiv.innerHTML = `<div>${content.replace(/\n/g, '<br>')}<div>${getCurrentTime()}</div></div>`; chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } function showTypingIndicator() { typingIndicator.style.display = 'block'; chatMessages.scrollTop = chatMessages.scrollHeight; } function hideTypingIndicator() { typingIndicator.style.display = 'none'; } async function sendMessage() { const message = messageInput.value.trim(); if (!message) return; addMessage(message, true); messageInput.value = ''; sendButton.disabled = true; showTypingIndicator(); try { const response = await fetch(`${API_BASE}/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: message, max_tokens: 512 }) }); if (!response.ok) { throw new Error(`HTTP 错误!状态码:${response.status}`); } const data = await response.json(); if (data.status === 'success') { hideTypingIndicator(); addMessage(data.response, false); } else { throw new Error(data.error || '未知错误'); } } catch (error) { hideTypingIndicator(); addMessage(`抱歉,出现了错误:${error.message}`, false); console.error('API 调用错误:', error); } finally { sendButton.disabled = false; messageInput.focus(); } } sendButton.addEventListener('click', sendMessage); messageInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { sendMessage(); } }); async function init() { const checkInterval = setInterval(async () => { const isReady = await checkServerStatus(); if (isReady) { clearInterval(checkInterval); } }, 5000); await checkServerStatus(); } window.onload = init;
</script>
</body>
</html>

主要实现了几个简单控件,输入条,发送按钮和状态栏,需要后端提供三个接口:

const response = await fetch(`${API_BASE}/health`);
const response = await fetch(`${API_BASE}/model_info`);
const response = await fetch(`${API_BASE}/chat`);

分别用于服务器状态检查,获取模型信息和对话。

三、后端模型服务器

OpenVINO 为生成式 AI 优化提供了推理引擎:OpenVINO GenAI。

OpenVINO GenAI 提供简洁的 API 接口,支持 Python 和 C++ 两种编程语言,安装容量不到 200MB。

以我本次使用的 DeepSeek-R1-0528-Qwen3-8B 为例,流水线使用 LLMPipeline。

后端需要用到的包:

pip install Flask Flask-CORS openvino-genai

openvino_server.py

import openvino_genai as ov_genai
from flask import Flask, request, jsonify
from flask_cors import CORS
import threading
import logging
from typing import Dict, Any
from pathlib import Path

class OpenVINOBackend:
    def __init__(self, model_path: str):
        self.model_path = model_path
        self.pipeline = None
        self.is_ready = False
        self.init_lock = threading.Lock()

    def initialize_model(self, device: str):
        with self.init_lock:
            if self.is_ready:
                return
            logger.info("正在加载 OpenVINO 模型...")
            try:
                self.pipeline = ov_genai.LLMPipeline(self.model_path, device)
                self.is_ready = True
                logger.info("OpenVINO 模型加载完成!")
            except Exception as e:
                logger.error(f"模型加载失败:{str(e)}")
                self.is_ready = False

    def generate_response(self, message: str, max_tokens: int = 512, temperature: float = 0.7, do_sample: bool = True) -> Dict[str, Any]:
        if not self.is_ready or self.pipeline is None:
            return {"status": "error", "error": "模型未就绪"}
        try:
            config = ov_genai.GenerationConfig()
            config.max_new_tokens = max_tokens
            config.temperature = temperature
            config.do_sample = do_sample
            self.pipeline.start_chat()
            response = self.pipeline.generate(message, config)
            self.pipeline.finish_chat()
            return {
                "status": "success",
                "response": response,
                "tokens_generated": len(response.split())
            }
        except Exception as e:
            return {"status": "error", "error": str(e)}

def create_app(backend: OpenVINOBackend) -> Flask:
    app = Flask(__name__)
    CORS(app)

    @app.route('/health', methods=['GET'])
    def health_check():
        return jsonify({
            "status": "ready" if backend.is_ready else "loading",
            "backend": "openvino_genai",
            "device": "CPU"
        })

    @app.route('/chat', methods=['POST'])
    def chat_endpoint():
        data = request.json
        if not data or 'message' not in data:
            return jsonify({"status": "error", "error": "缺少 message 参数"})
        message = data['message']
        max_tokens = min(max(int(data.get('max_tokens', 512)), 1), 2048)
        result = backend.generate_response(message, max_tokens)
        return jsonify(result)

    @app.route('/model_info', methods=['GET'])
    def model_info():
        return jsonify({
            "backend": "openvino_genai",
            "status": "ready" if backend.is_ready else "loading",
            "device": "CPU",
            "optimization": "int4_quantization"
        })
    return app

def initialize_backend(backend: OpenVINOBackend, device: str='CPU'):
    def init_task():
        backend.initialize_model(device)
    thread = threading.Thread(target=init_task, daemon=True)
    thread.start()

def main(model_path: str = "./converted_ov_model"):
    logging.basicConfig(
        level=logging.INFO,
        format='-- %(levelname)s - %(message)s',
        force=True
    )
    global logger
    logger = logging.getLogger(__name__)
    logger.info("Starting OpenVINO GenAI server...")
    p = Path(model_path)
    if not p.exists():
        logger.error(f"路径不存在:{model_path}")
        return
    if not p.is_dir():
        logger.error(f"请传入模型文件夹:{model_path}")
        return
    backend = OpenVINOBackend(model_path)
    app = create_app(backend)
    initialize_backend(backend, "CPU")
    logger.info(f"启动 OpenVINO GenAI 服务器,模型路径:{model_path}...")
    app.run(host='0.0.0.0', port=5000, debug=False)

if __name__ == '__main__':
    path = "./DeepSeek-R1-0528-Qwen3-8B_openvino_int4"
    main(path)

为了启动方便,我将模型路径写进了 py 文件,读者可以根据自身情况改为从命令行传参。后端也是主要实现三个接口,以及模型的初始化和推理。

为了适配长期运行环境,启用了 logger 和局域网服务器,并且关闭了 Flask 的 debug,防止 Werkzeug 的自动重载机制(reloader),出现一些莫名的情况。

四、资源占用

启动后端服务是不占用资源的,开始对话以后才会明显占用 CPU 和内存。

可以看到,OpenVINO 优化以及 INT4 量化后的 DeepSeek-R1-0528-Qwen3-8B,内存占用约 10G,CPU 也在可接受范围,每次推理大约需要 40 秒。

根据缩略图情况,启动后内存不会释放,直到后端服务器关闭。目前对话是单次输入输出,也就是每次对话只会有一次请求和回复,因此消息没有逐字生成的效果,未来有机会再继续优化,并且现在有字符上线限制,主要是因为我的设备性能有限,如果能将逐字显示完成,使用体验应该可以流畅很多。

目录

  1. 一、前言
  2. 二、前端交互界面
  3. chat_interface.html
  4. 三、后端模型服务器
  5. openvino_server.py
  6. 四、资源占用
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • TWIST2 全身 VR 遥操控制:基于视觉观测预测人形机器人关节位置
  • DataX 二进制与源码部署及 DataX-Web 可视化平台搭建
  • 奥迪 A6/A7 CarPlay 激活与 8511 地图安装指南
  • Ubuntu 22.04 基于 ROS2 Humble 搭建 PX4 无人机仿真环境
  • 结构化的力量:ChatGPT 如何实现高效信息管理
  • AES CCM 算法的 FPGA/Verilog 实现
  • ChatGPT、Gemini 及 Spotify 教育版身份验证自动化方案
  • phpStudy 下载与安装教程
  • Java volatile 关键字详解:原理、场景与误区
  • OpenViking 部署与应用:字节跳动开源 AI 代理上下文数据库
  • AI 时代内存需求暴涨背后的能源隐私与绿色技术解析
  • GitHub Copilot 接入 Figma MCP 实现设计稿转前端代码
  • VibeThinker-1.5B-APP:小模型在编程与数学推理中的优势与部署
  • AI 技能 UI UX Pro Max 驱动的现代前端 UI 工作流
  • ComfyUI 云服务器部署实战与优化指南
  • 使用 UI UX Pro Max 构建现代前端 UI 工作流
  • Linux 基础入门:常用命令与系统管理指南
  • JavaScript 语言特性与常见误解分析
  • CosyVoice 安装 openai-whisper 报错:ModuleNotFoundError: No module named 'pkg_resources'
  • Python 爬虫实战:爬取国家统计局公开数据

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online