《开源大模型食用指南》DeepSeek-7B-Chat Streamlit WebDemo 部署实战:从环境准备到多轮对话上线
【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型(MLLM)教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm
本篇技术指南以
self-llm仓库中 models/DeepSeek/03-DeepSeek-7B-chat WebDemo.md 为骨架,完整复现 DeepSeek-7B-Chat 在 AutoDL 云平台上基于 Streamlit 的 Web 对话 Demo 部署全过程,并结合仓库内 FastApi、LangChain 等配套文档与源码级实现细节进行纵深讲解。读完本篇,你将掌握:模型镜像环境的搭建与依赖版本锁定、ModelScope 模型下载、Streamlit 聊天机器人代码的结构化理解与改造,以及 Web 服务启动与本地端口映射访问的完整链路。
一、DeepSeek-7B-Chat 模型概览
DeepSeek LLM 是由深度求索研发的先进语言模型系列,其中 DeepSeek-7B-Chat 由70 亿个参数组成,是在一个包含2 万亿个英文和中文 token的庞大数据集上从零开始训练的。为了促进开源研究,DeepSeek 面向研究社区开放了 DeepSeek LLM 7B/67B Base(基座模型)和 DeepSeek LLM 7B/67B Chat(对话模型)四个版本。
在self-llm仓库中,围绕 DeepSeek-7B-Chat 构建了一条完整的「部署 → 接入 → 微调」学习链路,从 support_model.md 可以看到该系列的教程目录:
| 教程文件 | 核心内容 |
|---|---|
| 01-DeepSeek-7B-chat FastApi.md | 基于 FastAPI 提供 HTTP API 服务 |
| 02-DeepSeek-7B-chat langchain.md | 自定义 LLM 类接入 LangChain 框架 |
| 03-DeepSeek-7B-chat WebDemo.md | 基于 Streamlit 构建可视化聊天 Web 应用(本篇主题) |
| 04-DeepSeek-7B-chat Lora 微调.md | LoRA 高效参数微调 |
| 05-DeepSeek-7B-chat 4bits量化 Qlora 微调.md | 4bit 量化 + QLoRA 微调 |
其中 WebDemo 是面向终端用户最直观的一种交互形态:无需编写任何调用代码,打开浏览器即可与 7B 大模型进行自然的多轮对话,非常适合作为入门大模型部署的第一站。
二、环境准备:AutoDL 云平台镜像选择
2.1 租用 GPU 实例
在 AutoDL 平台租用一台RTX 3090 等 24G 显存的显卡机器(DeepSeek-7B-Chat 以 bf16 精度加载约占用 14~15GB 显存,24G 显存可保证模型加载后仍留有充足的推理余量)。创建实例时,镜像按以下路径选择:
PyTorch → 2.0.0 → 3.8 (ubuntu20.04) → 11.8(11.3 版本以上的都可以)说明:CUDA 选 11.3 以上版本即可,原因是本教程锁定的
transformers==4.35.2、torch2.0 系列版本对该区间 CUDA 版本均有良好的二进制兼容性。镜像创建完成后,打开 JupyterLab,在终端中完成环境配置、模型下载与 demo 运行。
2.2 依赖安装与版本锁定
进入终端后,首先升级 pip 并将 pip 源切换为清华镜像源以加速安装,随后安装固定版本的依赖包:
# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install modelscope==1.9.5 pip install transformers==4.35.2 pip install streamlit==1.24.0 pip install sentencepiece==0.1.99 pip install accelerate==0.24.1 pip install transformers_stream_generator==0.0.4各依赖在本部署链路中的作用如下:
| 依赖包 | 版本 | 作用 |
|---|---|---|
modelscope | 1.9.5 | 从 ModelScope 魔搭社区下载模型权重 |
transformers | 4.35.2 | 加载与推理模型(AutoTokenizer/AutoModelForCausalLM) |
streamlit | 1.24.0 | Web 前端框架,渲染聊天界面 |
sentencepiece | 0.1.99 | 中英双语 tokenizer 的底层分词实现 |
accelerate | 0.24.1 | 支撑device_map="auto"的设备自动分配 |
transformers_stream_generator | 0.0.4 | 流式生成依赖组件(推理加速/流式输出场景使用) |
建议严格按上述版本安装:
transformers==4.35.2对应 DeepSeek-LLM 权重发布时的适配版本,streamlit==1.24.0对应代码中st.chat_message/st.chat_input等 chat API 的稳定可用版本,版本不一致可能引发 API 签名不兼容的问题。
三、模型下载:ModelScope snapshot_download
模型权重从 ModelScope 魔搭社区下载(国内网络下速度远优于海外源)。使用modelscope中的snapshot_download函数,第一个参数为模型名称,cache_dir参数指定模型的下载路径。
在/root/autodl-tmp路径下新建download.py文件并输入以下内容(粘贴后记得保存):
import torch from modelscope import snapshot_download, AutoModel, AutoTokenizer from modelscope import GenerationConfig model_dir = snapshot_download( 'deepseek-ai/deepseek-llm-7b-chat', cache_dir='/root/autodl-tmp', revision='master' )执行下载:
python /root/autodl-tmp/download.py模型大小为 15GB 左右,下载大概需要 10~20 分钟(视网络带宽而定)。下载完成后,权重会落在/root/autodl-tmp/deepseek-ai/deepseek-llm-7b-chat目录下——这个目录就是后续代码中的mode_name_or_path模型路径。
提示:AutoDL 实例的系统盘空间有限,因此将模型下载到
/root/autodl-tmp(数据盘)是更稳妥的做法,避免因系统盘空间不足导致下载失败。
四、代码准备:编写 Streamlit 聊天机器人 chatBot.py
在/root/autodl-tmp路径下新建chatBot.py,输入以下内容(代码保留了原文档的详细注释,便于逐行理解):
# 导入所需的库 from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig import torch import streamlit as st # 在侧边栏中创建一个标题和一个链接 with st.sidebar: st.markdown("## DeepSeek LLM") "[开源大模型食用指南 self-llm](https://github.com/datawhalechina/self-llm.git)" # 创建一个滑块,用于选择最大长度,范围在0到1024之间,默认值为512 max_length = st.slider("max_length", 0, 1024, 512, step=1) # 创建一个标题和一个副标题 st.title("💬 DeepSeek Chatbot") st.caption("🚀 A streamlit chatbot powered by Self-LLM") # 定义模型路径 mode_name_or_path = '/root/autodl-tmp/deepseek-ai/deepseek-llm-7b-chat' # 定义一个函数,用于获取模型和tokenizer @st.cache_resource def get_model(): # 从预训练的模型中获取tokenizer tokenizer = AutoTokenizer.from_pretrained(mode_name_or_path, trust_remote_code=True) # 从预训练的模型中获取模型,并设置模型参数 model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, trust_remote_code=True, torch_dtype=torch.bfloat16, device_map="auto") # 从预训练的模型中获取生成配置 model.generation_config = GenerationConfig.from_pretrained(mode_name_or_path) # 设置生成配置的pad_token_id为生成配置的eos_token_id model.generation_config.pad_token_id = model.generation_config.eos_token_id # 设置模型为评估模式 model.eval() return tokenizer, model # 加载模型和tokenizer tokenizer, model = get_model() # 如果session_state中没有"messages",则创建一个包含默认消息的列表 if "messages" not in st.session_state: st.session_state["messages"] = [{"role": "assistant", "content": "有什么可以帮您的?"}] # 遍历session_state中的所有消息,并显示在聊天界面上 for msg in st.session_state.messages: st.chat_message(msg["role"]).write(msg["content"]) # 如果用户在聊天输入框中输入了内容,则执行以下操作 if prompt := st.chat_input(): # 将用户的输入添加到session_state中的messages列表中 st.session_state.messages.append({"role": "user", "content": prompt}) # 在聊天界面上显示用户的输入 st.chat_message("user").write(prompt) # 构建输入 input_tensor = tokenizer.apply_chat_template(st.session_state.messages, add_generation_prompt=True, return_tensors="pt") # 通过模型获得输出 outputs = model.generate(input_tensor.to(model.device), max_new_tokens=max_length) # 解码模型的输出,并去除特殊标记 response = tokenizer.decode(outputs[0][input_tensor.shape[1]:], skip_special_tokens=True) # 将模型的输出添加到session_state中的messages列表中 st.session_state.messages.append({"role": "assistant", "content": response}) # 在聊天界面上显示模型的输出 st.chat_message("assistant").write(response)4.1 代码结构逐段拆解
这段代码看似不长,但涵盖了 Web 交互应用的所有关键要素,可以拆解为五个逻辑模块:
① 侧边栏参数面板(L9-L13)
with st.sidebar: st.markdown("## DeepSeek LLM") "[开源大模型食用指南 self-llm](https://github.com/datawhalechina/self-llm.git)" max_length = st.slider("max_length", 0, 1024, 512, step=1)st.slider("max_length", 0, 1024, 512, step=1)创建一个最大生成长度调节滑块,范围 0~1024,默认 512。- 该值通过
st.session_state机制在每次交互(包括用户输入触发重跑)时保持,用户可在侧边栏实时调整输出长度。
② 模型懒加载 + 资源缓存(L21-L35)
@st.cache_resource def get_model(): tokenizer = AutoTokenizer.from_pretrained(mode_name_or_path, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( mode_name_or_path, trust_remote_code=True, torch_dtype=torch.bfloat16, device_map="auto" ) model.generation_config = GenerationConfig.from_pretrained(mode_name_or_path) model.generation_config.pad_token_id = model.generation_config.eos_token_id model.eval() return tokenizer, model@st.cache_resource是 Streamlit 专用于**缓存不可序列化资源(模型、数据库连接等)**的装饰器:首次请求时加载模型,后续每次页面交互直接命中缓存,避免 15GB 模型被重复加载。这里的几个加载参数值得展开说明:
trust_remote_code=True:允许执行模型仓库中随附的自定义代码(DeepSeek-LLM 通过modeling_deepseek.py等远程代码定义模型结构),必须开启;torch_dtype=torch.bfloat16:以 BF16 半精度加载权重,将 7B 模型的内存占用从约 28GB(FP32)压缩到约 14GB,同时相比 FP16 拥有更大的指数范围,训练/推理稳定性更好;device_map="auto":由accelerate自动将模型各层分配到可用设备(GPU 显存不足时自动卸载部分层到 CPU 内存),这正是 24G 单卡即可运行 7B 模型的关键机制之一;model.generation_config.pad_token_id = model.generation_config.eos_token_id:DeepSeek-7B-Chat 未定义专门的 pad token,此处将 padding 对齐到结束符,规避批量生成时的警告与潜在错误;model.eval():切换为评估模式,关闭 dropout 等训练专用层。
③ 会话历史管理(L39-L44)
if "messages" not in st.session_state: st.session_state["messages"] = [{"role": "assistant", "content": "有什么可以帮您的?"}] for msg in st.session_state.messages: st.chat_message(msg["role"]).write(msg["content"])st.session_state["messages"]以**角色(role)+ 内容(content)**的结构保存完整对话历史,并预置一条助手欢迎语;- 每次页面重跑时遍历该列表,通过
st.chat_message(role)+.write()按气泡形式渲染所有历史消息,实现多轮对话上下文保持。
④ 用户输入处理(L47-L51)
if prompt := st.chat_input(): st.session_state.messages.append({"role": "user", "content": prompt}) st.chat_message("user").write(prompt)st.chat_input()是 Streamlit 提供的聊天输入框组件;海象运算符:=使其在返回非空字符串时执行代码块,实现"输入即提交"。
⑤ 模型推理与响应回显(L53-L60)
input_tensor = tokenizer.apply_chat_template(st.session_state.messages, add_generation_prompt=True, return_tensors="pt") outputs = model.generate(input_tensor.to(model.device), max_new_tokens=max_length) response = tokenizer.decode(outputs[0][input_tensor.shape[1]:], skip_special_tokens=True) st.session_state.messages.append({"role": "assistant", "content": response}) st.chat_message("assistant").write(response)这里的核心是tokenizer.apply_chat_template:
- 它按 DeepSeek-7B-Chat 的 chat 模板将 messages 列表渲染成包含特殊 token 的完整对话输入(即
<|User|>...<|Assistant|>格式的拼接序列); add_generation_prompt=True表示在序列末尾追加助手角色的起始 token,指示模型开始生成回复;return_tensors="pt"返回 PyTorch Tensor,随后input_tensor.to(model.device)将其搬到模型所在设备。
生成与解码环节:
model.generate(..., max_new_tokens=max_length):max_new_tokens表示新增生成的 token 上限(即侧边栏滑块控制的 0~1024 值),历史 prompt 长度不计入;outputs[0][input_tensor.shape[1]:]:将生成结果切片,只保留新增生成的部分,丢弃原始输入前缀;tokenizer.decode(..., skip_special_tokens=True):解码为可读文本并剔除<|User|>、<|Assistant|>、<|endoftext|>等特殊 token;- 最后将响应追加进
st.session_state["messages"](供下一轮作为上下文)并即时渲染。
值得留意的是,这一段推理代码与仓库中 01-DeepSeek-7B-chat FastApi.md 的 API 实现、02-DeepSeek-7B-chat langchain.md 自定义 LLM 类中的
_call方法使用同一套「apply_chat_template→model.generate→ 切片解码」三段式调用链,可见它是 DeepSeek-7B-Chat 在不同服务形态间复用的通用推理范式。
五、运行 demo:启动 Streamlit 服务并访问
在终端中运行以下命令启动 Streamlit 服务:
streamlit run /root/autodl-tmp/chatBot.py --server.address 127.0.0.1 --server.port 6006参数说明:
| 参数 | 含义 |
|---|---|
streamlit run <脚本路径> | 启动 Streamlit 应用并监听 HTTP 服务 |
--server.address 127.0.0.1 | 只监听本机回环地址,服务不直接对外暴露(安全考虑) |
--server.port 6006 | 指定服务端口为 6006(与仓库其他教程的约定端口一致) |
随后按 AutoDL 平台的指引将 6006 端口映射到本地,在本地浏览器中打开http://localhost:6006/即可看到聊天界面:
启动成功后可进行的验证:
- 侧边栏拖动
max_length滑块即可控制每次回答的长度上限; - 在输入框提问并发送,模型返回回答后继续追问,可观察到模型能够引用上文(多轮上下文生效);
- 查看服务终端日志,确认无报错、推理耗时正常。
六、WebDemo 的进阶方向:从交互界面到服务化部署
完成 WebDemo 之后,如果希望将 DeepSeek-7B-Chat 以更通用的形态提供给其他系统调用,仓库提供了同一模型的两条延伸路径:
① FastAPI 服务化(详见 01-DeepSeek-7B-chat FastApi.md):以相同的模型加载与推理代码为基础,通过@app.post("/")暴露 HTTP 接口,接收prompt与max_length参数,返回response / status / time结构的 JSON;启动后可用curl -X POST "http://127.0.0.1:6006" -H 'Content-Type: application/json' -d '{"prompt": "你好"}'调用。WebDemo 侧边栏的max_length滑块与 FastAPI 接口中的max_length请求字段在语义上完全一致。
② LangChain 框架接入(详见 02-DeepSeek-7B-chat langchain.md):从langchain.llms.base.LLM继承并重写_call方法,即可让 DeepSeek-7B-Chat 以标准 LLM 组件身份参与链式应用构建:
llm = DeepSeek_LLM('/root/autodl-tmp/deepseek-ai/deepseek-llm-7b-chat') llm('你好')需要指出的是,Streamlit WebDemo 面向人工交互,FastAPI 面向程序化调用,LangChain 面向应用编排,三者共享同一份模型权重与推理范式,可依据业务场景按需组合。
七、常见问题与排查要点
基于上述部署链路,整理几个高频问题的排查思路:
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 依赖安装失败 | pip 源过慢或版本冲突 | 确认已切换清华源;严格按 2.2 节的版本号安装 |
| 模型加载时报错 | 模型未下载完整 / 路径错误 | 核对/root/autodl-tmp/deepseek-ai/deepseek-llm-7b-chat目录是否存在且权重齐全(15GB 左右) |
| 显存不足(OOM) | 未使用 bf16 或 device_map | 确认加载参数为torch_dtype=torch.bfloat16+device_map="auto";必要时降低max_length |
| 启动后本地打不开页面 | 端口未映射 / 端口被占用 | 在 AutoDL 控制台为 6006 端口添加映射;确认命令中--server.port 6006与映射端口一致 |
| 生成结果异常或出现特殊字符 | 未正确设置 pad_token_id | 确认代码包含model.generation_config.pad_token_id = model.generation_config.eos_token_id |
| 模型回答不连贯、不记得上文 | 未维护 messages 上下文 | 确认每轮都将 user/assistant 消息 append 进st.session_state["messages"]并整体传入模板 |
结语
本篇以 models/DeepSeek/03-DeepSeek-7B-chat WebDemo.md 为骨架,完成了从 AutoDL 环境搭建、依赖锁定、ModelScope 模型下载、Streamlit 多轮对话应用编写到服务启动与访问的完整闭环,并深入解析了apply_chat_template、st.cache_resource、BF16 +device_map="auto"等关键机制。这套"模型下载 → 推理封装 → Web 呈现"的模式在self-llm仓库中具有高度通用性——其他模型的 WebDemo 教程(如 DeepSeek-Coder-V2、DeepSeek-R1-Distill-Qwen)均遵循相似的部署范式。掌握本篇内容后,你便有能力将任意开源 Chat 模型快速包装为可交互的 Web 应用。
【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型(MLLM)教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考