news 2026/3/8 15:21:08

DeepSeek-R1-Distill-Qwen-1.5B智能对话助手:基于Streamlit的Python部署实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek-R1-Distill-Qwen-1.5B智能对话助手:基于Streamlit的Python部署实战

DeepSeek-R1-Distill-Qwen-1.5B智能对话助手:基于Streamlit的Python部署实战

想不想在本地电脑上拥有一个属于自己的智能对话助手?不用联网,不用付费,完全在你的掌控之中。今天我就带你用Python和Streamlit框架,快速部署一个DeepSeek-R1-Distill-Qwen-1.5B模型的智能对话助手。

这个模型虽然只有15亿参数,但经过蒸馏优化后,在对话、问答、代码生成等任务上表现相当不错,而且对硬件要求不高,普通带GPU的电脑就能跑起来。更重要的是,我们完全用Python来实现,不需要复杂的Docker配置,也不需要折腾各种命令行工具。

如果你对Python有一定了解,想体验一下本地大模型部署的乐趣,或者想为自己的项目添加一个智能对话功能,那这篇文章就是为你准备的。我会从环境配置开始,一步步带你完成整个部署过程,最后还会教你如何优化界面和功能。

1. 环境准备:搭建你的AI开发环境

在开始之前,我们需要准备好运行环境。DeepSeek-R1-Distill-Qwen-1.5B模型虽然不大,但还是需要一些基础的AI开发环境。

1.1 系统要求和Python环境

首先确认你的电脑配置。这个模型对硬件要求相对友好:

  • 内存:至少8GB RAM,建议16GB以上
  • 存储空间:模型文件大约6-7GB,加上Python环境和依赖,建议预留15GB空间
  • GPU(可选但推荐):如果有NVIDIA GPU,速度会快很多。显存4GB以上就能跑,8GB以上体验更好
  • 操作系统:Windows、macOS、Linux都可以,我这里以Ubuntu 22.04为例,其他系统操作类似

Python版本建议使用3.8到3.11之间的版本。太老的版本可能缺少一些必要的库,太新的版本可能会有兼容性问题。你可以用下面的命令检查Python版本:

python --version # 或者 python3 --version

如果还没有安装Python,建议去Python官网下载安装。安装完成后,最好创建一个虚拟环境,这样可以避免不同项目之间的依赖冲突。

1.2 安装必要的Python库

我们需要安装几个核心的Python库。打开终端或命令行,执行以下命令:

# 创建虚拟环境(可选但推荐) python -m venv deepseek_env # 激活虚拟环境 # Windows: deepseek_env\Scripts\activate # Linux/macOS: source deepseek_env/bin/activate # 安装核心依赖 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 如果有CUDA 11.8 # 如果没有GPU或者CUDA版本不同,可以用CPU版本: # pip install torch torchvision torchaudio pip install transformers>=4.35.0 pip install streamlit>=1.28.0 pip install accelerate>=0.24.0 pip install sentencepiece>=0.1.99 # 分词器需要 pip install tiktoken>=0.5.0 # 用于token计数

这里解释一下各个库的作用:

  • torch:PyTorch深度学习框架,模型运行的基础
  • transformers:Hugging Face的模型库,提供了加载和使用各种预训练模型的接口
  • streamlit:我们用来构建Web界面的框架,非常简单易用
  • accelerate:加速库,可以优化模型加载和推理速度
  • sentencepiecetiktoken:分词相关的库,处理文本输入输出

如果你在安装过程中遇到网络问题,可以尝试使用国内的镜像源:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple torch transformers streamlit

1.3 下载模型文件

模型文件比较大,我们需要从Hugging Face下载。有两种方式可以选择:

方式一:使用transformers自动下载(推荐)

这种方式最简单,代码运行时会自动下载模型。但第一次运行时会比较慢,因为要下载6-7GB的文件。

方式二:手动下载模型文件

如果你网络不太稳定,或者想控制下载过程,可以手动下载:

# 安装git-lfs(大文件支持) # Ubuntu/Debian: sudo apt-get install git-lfs # macOS: brew install git-lfs # 初始化git-lfs git lfs install # 克隆模型仓库 git clone https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B

手动下载的好处是可以看到下载进度,而且下载一次后可以重复使用。下载完成后,记得记下模型文件的路径,后面加载模型时会用到。

2. 核心代码实现:让模型跑起来

环境准备好了,现在我们来写代码。我会把整个实现分成几个部分,这样更容易理解和调试。

2.1 模型加载模块

首先创建一个Python文件,比如叫model_loader.py,专门处理模型的加载和初始化:

import torch from transformers import AutoTokenizer, AutoModelForCausalLM import logging from typing import Optional # 设置日志 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class DeepSeekModel: """DeepSeek-R1-Distill-Qwen-1.5B模型加载和管理类""" def __init__(self, model_path: str = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B", device: Optional[str] = None): """ 初始化模型 Args: model_path: 模型路径,可以是Hugging Face模型ID或本地路径 device: 指定运行设备,如'cuda', 'cpu',为None时自动选择 """ self.model_path = model_path self.device = device if device else ('cuda' if torch.cuda.is_available() else 'cpu') self.model = None self.tokenizer = None self.is_loaded = False def load_model(self): """加载模型和分词器""" try: logger.info(f"开始加载模型,路径: {self.model_path}") logger.info(f"使用设备: {self.device}") # 加载分词器 logger.info("加载分词器...") self.tokenizer = AutoTokenizer.from_pretrained( self.model_path, trust_remote_code=True ) # 设置pad_token,避免生成时出错 if self.tokenizer.pad_token is None: self.tokenizer.pad_token = self.tokenizer.eos_token # 加载模型 logger.info("加载模型...") self.model = AutoModelForCausalLM.from_pretrained( self.model_path, torch_dtype=torch.float16 if self.device == 'cuda' else torch.float32, device_map="auto" if self.device == 'cuda' else None, trust_remote_code=True ) # 如果指定了设备但不是自动映射,移动模型到指定设备 if self.device != 'cuda' or 'auto' not in str(self.model.hf_device_map): self.model = self.model.to(self.device) self.model.eval() # 设置为评估模式 self.is_loaded = True logger.info("模型加载完成!") # 打印模型信息 total_params = sum(p.numel() for p in self.model.parameters()) logger.info(f"模型参数量: {total_params:,}") if self.device == 'cuda': logger.info(f"GPU显存使用: {torch.cuda.memory_allocated() / 1024**3:.2f} GB") except Exception as e: logger.error(f"模型加载失败: {str(e)}") raise def generate_response(self, prompt: str, max_length: int = 512, temperature: float = 0.7, top_p: float = 0.9) -> str: """ 生成回复 Args: prompt: 输入提示 max_length: 生成的最大长度 temperature: 温度参数,控制随机性 top_p: 核采样参数 Returns: 生成的回复文本 """ if not self.is_loaded: raise RuntimeError("模型未加载,请先调用load_model()") try: # 准备输入 messages = [{"role": "user", "content": prompt}] text = self.tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) # 编码输入 inputs = self.tokenizer(text, return_tensors="pt") inputs = {k: v.to(self.device) for k, v in inputs.items()} # 生成回复 with torch.no_grad(): outputs = self.model.generate( **inputs, max_new_tokens=max_length, temperature=temperature, top_p=top_p, do_sample=True, pad_token_id=self.tokenizer.pad_token_id, eos_token_id=self.tokenizer.eos_token_id, repetition_penalty=1.1 ) # 解码输出 response = self.tokenizer.decode(outputs[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True) return response.strip() except Exception as e: logger.error(f"生成回复失败: {str(e)}") return f"生成回复时出错: {str(e)}" def unload_model(self): """卸载模型,释放内存""" if self.model is not None: del self.model self.model = None if self.tokenizer is not None: del self.tokenizer self.tokenizer = None self.is_loaded = False if self.device == 'cuda': torch.cuda.empty_cache() logger.info("模型已卸载,内存已释放")

这个类封装了模型加载、推理和卸载的完整流程。有几个关键点需要注意:

  1. 设备选择:代码会自动检测是否有GPU可用,优先使用GPU
  2. 内存管理:使用float16精度可以减少显存占用,生成完成后可以手动释放内存
  3. 错误处理:每个步骤都有try-catch,避免程序崩溃
  4. 聊天模板:使用tokenizer的apply_chat_template方法,确保输入格式符合模型要求

2.2 Streamlit界面开发

接下来创建主应用文件app.py,使用Streamlit构建Web界面:

import streamlit as st import time from model_loader import DeepSeekModel import sys import os # 页面配置 st.set_page_config( page_title="DeepSeek智能助手", page_icon="", layout="wide", initial_sidebar_state="expanded" ) # 自定义CSS样式 st.markdown(""" <style> .main-header { font-size: 2.5rem; color: #1E88E5; text-align: center; margin-bottom: 2rem; } .response-box { background-color: #f0f2f6; padding: 1.5rem; border-radius: 10px; margin: 1rem 0; border-left: 5px solid #1E88E5; } .user-message { background-color: #E3F2FD; padding: 1rem; border-radius: 10px; margin: 0.5rem 0; } .assistant-message { background-color: #F5F5F5; padding: 1rem; border-radius: 10px; margin: 0.5rem 0; } .stButton button { width: 100%; background-color: #1E88E5; color: white; } .stButton button:hover { background-color: #1565C0; } </style> """, unsafe_allow_html=True) # 初始化session state if 'model' not in st.session_state: st.session_state.model = None if 'messages' not in st.session_state: st.session_state.messages = [] if 'model_loaded' not in st.session_state: st.session_state.model_loaded = False def load_model_callback(): """加载模型的回调函数""" try: with st.spinner("正在加载模型,这可能需要几分钟..."): # 获取用户选择的模型路径 model_path = st.session_state.model_path_input # 初始化模型 st.session_state.model = DeepSeekModel(model_path=model_path) st.session_state.model.load_model() st.session_state.model_loaded = True st.success("模型加载成功!") time.sleep(1) st.rerun() except Exception as e: st.error(f"模型加载失败: {str(e)}") def unload_model_callback(): """卸载模型的回调函数""" if st.session_state.model and st.session_state.model_loaded: st.session_state.model.unload_model() st.session_state.model = None st.session_state.model_loaded = False st.session_state.messages = [] st.success("模型已卸载") st.rerun() def clear_chat_callback(): """清空聊天记录""" st.session_state.messages = [] st.rerun() def generate_response(): """生成回复""" if not st.session_state.model_loaded: st.warning("请先加载模型") return user_input = st.session_state.user_input if not user_input.strip(): return # 添加用户消息到历史 st.session_state.messages.append({ "role": "user", "content": user_input, "time": time.strftime("%H:%M:%S") }) # 清空输入框 st.session_state.user_input = "" # 生成回复 with st.spinner("思考中..."): try: response = st.session_state.model.generate_response( prompt=user_input, max_length=st.session_state.max_length, temperature=st.session_state.temperature, top_p=st.session_state.top_p ) # 添加助手回复到历史 st.session_state.messages.append({ "role": "assistant", "content": response, "time": time.strftime("%H:%M:%S") }) except Exception as e: st.error(f"生成回复时出错: {str(e)}") # 侧边栏 - 模型配置 with st.sidebar: st.header("⚙ 模型配置") # 模型路径输入 st.subheader("模型路径") model_path_options = { "Hugging Face在线模型": "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B", "本地模型(需手动下载)": "./DeepSeek-R1-Distill-Qwen-1.5B" } selected_option = st.selectbox( "选择模型来源", list(model_path_options.keys()), key="model_source" ) st.session_state.model_path_input = model_path_options[selected_option] # 加载/卸载按钮 col1, col2 = st.columns(2) with col1: if not st.session_state.model_loaded: if st.button(" 加载模型", key="load_btn", use_container_width=True): load_model_callback() else: if st.button("🗑 卸载模型", key="unload_btn", use_container_width=True): unload_model_callback() with col2: if st.button("🗑 清空对话", key="clear_btn", use_container_width=True): clear_chat_callback() # 参数调节 st.divider() st.subheader("生成参数") st.session_state.max_length = st.slider( "最大生成长度", min_value=64, max_value=2048, value=512, step=64, help="控制生成文本的最大长度" ) st.session_state.temperature = st.slider( "温度", min_value=0.1, max_value=2.0, value=0.7, step=0.1, help="值越高越有创意,值越低越保守" ) st.session_state.top_p = st.slider( "Top-p采样", min_value=0.1, max_value=1.0, value=0.9, step=0.05, help="控制生成多样性的参数" ) # 系统信息 st.divider() st.subheader("系统信息") if st.session_state.model_loaded: st.success(" 模型已加载") device = "GPU" if torch.cuda.is_available() else "CPU" st.info(f"运行设备: {device}") if torch.cuda.is_available(): gpu_mem = torch.cuda.memory_allocated() / 1024**3 st.info(f"GPU显存: {gpu_mem:.2f} GB") else: st.warning(" 模型未加载") # 主界面 st.markdown('<h1 class="main-header"> DeepSeek智能对话助手</h1>', unsafe_allow_html=True) # 聊天历史显示 chat_container = st.container() with chat_container: for message in st.session_state.messages: if message["role"] == "user": st.markdown(f""" <div class="user-message"> <strong>👤 你 ({message['time']}):</strong><br> {message['content']} </div> """, unsafe_allow_html=True) else: st.markdown(f""" <div class="assistant-message"> <strong> 助手 ({message['time']}):</strong><br> {message['content']} </div> """, unsafe_allow_html=True) # 输入区域 st.divider() input_col1, input_col2 = st.columns([6, 1]) with input_col1: user_input = st.text_area( "输入你的问题或指令:", height=100, key="user_input", placeholder="输入你想问的问题,然后按Ctrl+Enter发送...", label_visibility="collapsed" ) with input_col2: st.write("") # 占位 st.write("") # 占位 if st.button("发送", key="send_btn", use_container_width=True): generate_response() # 使用说明 with st.expander(" 使用说明", expanded=False): st.markdown(""" ### 快速开始指南 1. **加载模型**:在左侧边栏选择模型来源,点击"加载模型"按钮 2. **开始对话**:在下方输入框输入问题,点击"发送"或按Ctrl+Enter 3. **调节参数**:在侧边栏可以调整生成参数,获得不同的回复效果 ### 参数说明 - **最大生成长度**:控制回复的长度,太长可能影响速度 - **温度**:控制随机性,低温度更保守准确,高温度更有创意 - **Top-p采样**:控制多样性,值越小回复越集中 ### 示例问题 - 帮我写一个Python函数,计算斐波那契数列 - 解释一下什么是机器学习 - 用简单的语言说明量子计算 - 写一个关于人工智能的短故事 ### 注意事项 - 首次加载模型需要下载约6-7GB的文件,请耐心等待 - 如果使用GPU,确保显存足够(至少4GB) - 长时间使用后可以卸载模型释放内存 """) # 底部信息 st.divider() st.caption(" 提示:这是一个本地运行的AI助手,所有对话数据都保存在你的电脑上,不会上传到任何服务器。")

这个Streamlit应用包含了完整的用户界面,主要特点有:

  1. 响应式设计:使用Streamlit的列布局,适应不同屏幕尺寸
  2. 美观的聊天界面:用户和助手的消息用不同颜色区分,有时间戳
  3. 完整的控制功能:可以加载/卸载模型、清空对话、调节参数
  4. 实时状态显示:显示模型加载状态、运行设备等信息
  5. 详细的帮助文档:折叠面板中包含使用说明和示例

2.3 运行和测试

现在我们可以运行这个应用了。在终端中执行:

streamlit run app.py

Streamlit会自动打开浏览器,显示我们的应用界面。第一次运行时的流程:

  1. 在侧边栏选择模型来源(建议先用在线模型测试)
  2. 点击"加载模型"按钮,等待模型下载和加载
  3. 加载完成后,在输入框输入问题
  4. 点击发送或按Ctrl+Enter,等待回复

你可以尝试问一些问题,比如:

  • "用Python写一个快速排序算法"
  • "解释一下Transformer模型的工作原理"
  • "给我讲一个关于太空探索的故事"

如果一切正常,你应该能看到模型生成的回复。第一次生成可能会比较慢,因为模型需要预热。后续的生成会快很多。

3. 功能扩展和优化

基础功能已经实现了,但我们可以做得更好。下面是一些扩展和优化的建议。

3.1 添加流式输出

当前的实现是等待整个回复生成完成后才显示,对于长文本来说体验不够好。我们可以改成流式输出,像ChatGPT那样一个字一个字地显示:

def generate_response_stream(prompt: str, max_length: int = 512, temperature: float = 0.7, top_p: float = 0.9): """流式生成回复""" if not st.session_state.model_loaded: yield "请先加载模型" return try: # 准备输入 messages = [{"role": "user", "content": prompt}] text = st.session_state.model.tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) # 编码输入 inputs = st.session_state.model.tokenizer(text, return_tensors="pt") inputs = {k: v.to(st.session_state.model.device) for k, v in inputs.items()} # 流式生成 with torch.no_grad(): generated_tokens = [] for token in st.session_state.model.model.generate( **inputs, max_new_tokens=max_length, temperature=temperature, top_p=top_p, do_sample=True, pad_token_id=st.session_state.model.tokenizer.pad_token_id, eos_token_id=st.session_state.model.tokenizer.eos_token_id, repetition_penalty=1.1, streamer=None # 可以自定义streamer ): generated_tokens.append(token) # 解码当前所有token current_text = st.session_state.model.tokenizer.decode( generated_tokens, skip_special_tokens=True ) yield current_text except Exception as e: yield f"生成回复时出错: {str(e)}"

然后在界面中,我们可以创建一个专门显示流式输出的区域:

# 在生成回复的函数中修改 response_placeholder = st.empty() full_response = "" for chunk in generate_response_stream(user_input): full_response += chunk response_placeholder.markdown(f""" <div class="assistant-message"> <strong> 助手:</strong><br> {full_response} </div> """, unsafe_allow_html=True) time.sleep(0.01) # 稍微延迟,让显示更平滑

3.2 添加对话历史管理

当前的对话历史只保存在session state中,页面刷新就会丢失。我们可以添加保存和加载功能:

import json from datetime import datetime def save_chat_history(filename=None): """保存聊天历史到文件""" if not filename: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"chat_history_{timestamp}.json" history = { "model": st.session_state.model_path_input, "timestamp": datetime.now().isoformat(), "messages": st.session_state.messages } with open(filename, 'w', encoding='utf-8') as f: json.dump(history, f, ensure_ascii=False, indent=2) return filename def load_chat_history(file): """从文件加载聊天历史""" try: with open(file, 'r', encoding='utf-8') as f: history = json.load(f) st.session_state.messages = history.get("messages", []) st.success(f"聊天历史已加载: {file}") st.rerun() except Exception as e: st.error(f"加载失败: {str(e)}")

然后在侧边栏添加相应的按钮:

# 在侧边栏添加 st.divider() st.subheader("聊天历史") col1, col2 = st.columns(2) with col1: if st.button("💾 保存对话", use_container_width=True): filename = save_chat_history() st.success(f"已保存到: {filename}") with col2: uploaded_file = st.file_uploader(" 加载历史", type=['json'], label_visibility="collapsed") if uploaded_file is not None: # 保存上传的文件到临时位置 temp_path = f"temp_{uploaded_file.name}" with open(temp_path, 'wb') as f: f.write(uploaded_file.getbuffer()) load_chat_history(temp_path) os.remove(temp_path) # 清理临时文件

3.3 添加模型性能监控

为了了解模型的运行状况,我们可以添加一些监控功能:

import psutil import GPUtil def get_system_info(): """获取系统信息""" info = {} # CPU和内存信息 info['cpu_percent'] = psutil.cpu_percent() info['memory_percent'] = psutil.virtual_memory().percent info['memory_used_gb'] = psutil.virtual_memory().used / 1024**3 # GPU信息(如果有) try: gpus = GPUtil.getGPUs() if gpus: gpu = gpus[0] info['gpu_name'] = gpu.name info['gpu_load'] = gpu.load * 100 info['gpu_memory_used'] = gpu.memoryUsed info['gpu_memory_total'] = gpu.memoryTotal info['gpu_memory_percent'] = gpu.memoryUtil * 100 except: info['gpu_name'] = "未检测到GPU" # 模型信息 if st.session_state.model_loaded and st.session_state.model.model: info['model_device'] = str(st.session_state.model.device) if torch.cuda.is_available(): info['cuda_memory_allocated'] = torch.cuda.memory_allocated() / 1024**3 info['cuda_memory_reserved'] = torch.cuda.memory_reserved() / 1024**3 return info # 在侧边栏显示监控信息 if st.session_state.model_loaded: st.divider() st.subheader(" 系统监控") if st.button("刷新监控", key="refresh_monitor"): st.rerun() info = get_system_info() # 创建两列显示 col1, col2 = st.columns(2) with col1: st.metric("CPU使用率", f"{info['cpu_percent']:.1f}%") st.metric("内存使用", f"{info['memory_used_gb']:.1f} GB", f"{info['memory_percent']:.1f}%") with col2: if 'gpu_name' in info and info['gpu_name'] != "未检测到GPU": st.metric("GPU负载", f"{info['gpu_load']:.1f}%") st.metric("GPU显存", f"{info['gpu_memory_used']:.1f}/{info['gpu_memory_total']} GB", f"{info['gpu_memory_percent']:.1f}%")

3.4 添加预设提示词模板

为了让用户更方便地使用,我们可以添加一些预设的提示词模板:

PRESET_PROMPTS = { "代码生成": { "Python排序算法": "用Python实现一个快速排序算法,并添加详细的注释说明每一步的作用。", "网页爬虫": "写一个Python爬虫,用于爬取新闻网站的头条新闻,要求使用requests和BeautifulSoup。", "数据处理": "用pandas写一个数据清洗函数,处理缺失值、重复值和异常值。" }, "学习助手": { "机器学习解释": "用简单的语言解释什么是机器学习,并举一个生活中的例子。", "神经网络基础": "解释神经网络的基本原理,适合初学者理解。", "编程概念": "解释什么是递归,并给出一个简单的例子。" }, "创意写作": { "故事开头": "写一个关于人工智能获得自我意识的故事开头,要吸引人。", "产品描述": "为一个智能咖啡机写一段吸引人的产品描述。", "邮件写作": "写一封给客户的感谢邮件,语气要专业且友好。" } } # 在侧边栏添加预设提示词 st.divider() st.subheader(" 预设提示词") category = st.selectbox("选择类别", list(PRESET_PROMPTS.keys())) if category: prompt_name = st.selectbox("选择提示词", list(PRESET_PROMPTS[category].keys())) if st.button("使用此提示词", use_container_width=True): selected_prompt = PRESET_PROMPTS[category][prompt_name] st.session_state.user_input = selected_prompt st.rerun()

4. 部署和分享

完成开发后,你可能想分享给其他人使用,或者部署到服务器上。这里有几个选项:

4.1 本地分享

Streamlit支持在局域网内分享应用:

streamlit run app.py --server.port 8501 --server.address 0.0.0.0

这样同一局域网内的其他设备就可以通过你的IP地址和端口访问应用了。

4.2 打包为可执行文件

使用PyInstaller可以将应用打包为独立的可执行文件:

pip install pyinstaller # 创建打包脚本 echo ' import streamlit.web.cli as stcli import sys if __name__ == "__main__": sys.argv = ["streamlit", "run", "app.py", "--server.port=8501"] sys.exit(stcli.main()) ' > run_app.py # 打包 pyinstaller --onefile --add-data "model_loader.py:." run_app.py

打包后的文件可以在没有Python环境的电脑上运行,但模型文件需要单独提供。

4.3 部署到云服务器

如果你有云服务器,可以部署为长期运行的服务:

  1. 安装依赖:在服务器上安装Python和依赖库
  2. 下载模型:提前下载好模型文件
  3. 使用进程管理:使用systemd或supervisor管理进程
  4. 配置反向代理:使用Nginx作为反向代理,支持HTTPS

创建一个systemd服务文件:

# /etc/systemd/system/deepseek-assistant.service [Unit] Description=DeepSeek Assistant After=network.target [Service] Type=simple User=ubuntu WorkingDirectory=/path/to/your/app Environment="PATH=/home/ubuntu/deepseek_env/bin" ExecStart=/home/ubuntu/deepseek_env/bin/streamlit run app.py --server.port 8501 Restart=always [Install] WantedBy=multi-user.target

然后启动服务:

sudo systemctl daemon-reload sudo systemctl enable deepseek-assistant sudo systemctl start deepseek-assistant

5. 总结

通过这篇文章,我们完成了一个完整的DeepSeek-R1-Distill-Qwen-1.5B智能对话助手的本地部署。从环境准备到模型加载,从界面开发到功能扩展,我们一步步实现了这个项目。

这个项目的亮点在于它的完整性和实用性。你不仅学到了如何加载和使用大语言模型,还掌握了用Streamlit构建Web应用的方法。更重要的是,这个应用是完全可用的,你可以根据自己的需求进行修改和扩展。

实际使用下来,这个1.5B的蒸馏模型在大多数日常对话和编程任务上表现不错,响应速度也很快。虽然它可能无法处理特别复杂或专业的问题,但对于学习和日常使用来说已经足够了。

如果你在部署过程中遇到问题,或者想进一步优化,可以考虑以下几个方面:首先是模型性能,可以尝试量化技术来减少内存占用;其次是用户体验,可以添加更多交互功能;最后是部署方案,可以考虑容器化部署以便更好地管理依赖。

希望这个项目能帮助你更好地理解大模型部署的流程,也期待看到你基于这个框架开发出更有趣的应用。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/3 9:39:16

3DS硬件检测与设备分析实用指南

3DS硬件检测与设备分析实用指南 【免费下载链接】3DSident PSPident clone for 3DS 项目地址: https://gitcode.com/gh_mirrors/3d/3DSident 引言&#xff1a;为什么3DS设备信息检测至关重要&#xff1f; 当你面对一台3DS设备&#xff0c;无论是购买二手主机、进行系统…

作者头像 李华
网站建设 2026/3/5 18:51:29

PDF-Parser-1.0企业级应用:合同管理系统集成方案

PDF-Parser-1.0企业级应用&#xff1a;合同管理系统集成方案 1. 为什么合同管理需要PDF-Parser-1.0 在法务、采购、HR和销售部门&#xff0c;每天要处理成百上千份合同——采购协议、劳动合同、服务条款、保密协议、租赁合同……这些文件90%以上以PDF格式存在&#xff0c;且结…

作者头像 李华
网站建设 2026/3/7 7:30:33

3步打造研发效率工具:从重复操作到自动化处理的转型实践

3步打造研发效率工具&#xff1a;从重复操作到自动化处理的转型实践 【免费下载链接】zteOnu 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 问题发现&#xff1a;研发流程中的效率陷阱 在软件项目开发的日常工作中&#xff0c;研发团队常常面临这样的困境&…

作者头像 李华
网站建设 2026/3/4 9:52:24

OFA-VE新手指南:轻松掌握赛博风视觉蕴含分析

OFA-VE新手指南&#xff1a;轻松掌握赛博风视觉蕴含分析 获取更多AI镜像 想探索更多AI镜像和应用场景&#xff1f;访问 CSDN星图镜像广场&#xff0c;提供丰富的预置镜像&#xff0c;覆盖大模型推理、图像生成、视频生成、模型微调等多个领域&#xff0c;支持一键部署。 1. 什么…

作者头像 李华