ChatGLM3-6B本地部署全攻略从环境配置到Web界面搭建1. 引言想在自己的电脑上运行一个强大的中文对话AI吗想拥有一个完全私有的、响应速度极快的智能助手吗今天我将带你一步步完成ChatGLM3-6B的本地部署从零开始搭建一个功能完整的Web对话界面。ChatGLM3-6B是智谱AI开源的优秀中文对话模型拥有62亿参数和32K的超长上下文能力。这意味着它不仅能进行日常对话还能处理万字长文、分析复杂代码、进行多轮深度交流。更重要的是通过本地部署你的所有对话数据都留在自己的机器上无需担心隐私泄露还能享受零延迟的响应体验。本文将采用最实用的方式手把手教你完成整个部署过程。无论你是AI开发者、技术爱好者还是想在自己的项目中集成对话能力的工程师这篇指南都能帮你快速上手。我们会从环境配置开始逐步搭建Python客户端、Web界面最终实现一个完整的智能对话系统。2. 环境准备与模型下载2.1 硬件与系统要求在开始之前我们先确认一下运行ChatGLM3-6B需要什么样的环境。虽然模型本身对硬件有一定要求但通过合理的配置我们可以在多种设备上运行。最低配置要求GPU至少12GB显存如RTX 3060 12G、RTX 3080 10G内存16GB以上存储至少20GB可用空间系统Linux/Windows/macOS均可推荐Ubuntu 20.04推荐配置GPURTX 4090D24GB显存或更高内存32GB以上存储NVMe SSD50GB以上空间如果你没有足够显存的GPU也可以使用CPU运行但速度会慢很多。对于大多数用户我建议使用云服务器平台它们通常提供预配置的环境和强大的GPU资源。2.2 创建Python虚拟环境为了避免依赖冲突我们首先创建一个独立的Python环境。这里以AutoDL平台为例其他平台的操作类似。# 创建Python 3.8的虚拟环境 conda create -n chatglm3-6b python3.8 # 激活环境AutoDL平台特殊处理 source activate chatglm3-6b如果你在其他平台可以使用标准的conda激活命令conda activate chatglm3-6b2.3 安装依赖包接下来安装所有必要的Python包。为了提高下载速度我们先切换到国内的镜像源。# 升级pip到最新版本 python -m pip install --upgrade pip # 设置清华镜像源加速下载 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 安装核心依赖包 pip install fastapi0.104.1 pip install uvicorn0.24.0.post1 pip install requests2.25.1 pip install modelscope1.9.5 pip install transformers4.37.2 pip install streamlit1.24.0 pip install sentencepiece0.1.99 pip install accelerate0.24.1这里有几个关键包需要特别注意transformersHugging Face的模型加载库版本4.37.2与ChatGLM3-6B兼容性最好modelscope用于从ModelScope平台下载模型streamlit我们将用它构建轻量级Web界面accelerate加速模型加载和推理2.4 下载ChatGLM3-6B模型模型文件大约14GB下载需要一些时间。我们使用ModelScope的官方下载方式。首先创建一个下载脚本# 在/root/autodl-tmp目录下创建download.py文件 import torch from modelscope import snapshot_download, AutoModel, AutoTokenizer import os # 下载模型到指定目录 model_dir snapshot_download(ZhipuAI/chatglm3-6b, cache_dir/root/autodl-tmp, revisionmaster) print(f模型已下载到: {model_dir})运行下载命令python /root/autodl-tmp/download.py下载过程大约需要10-20分钟具体取决于你的网络速度。下载完成后你会在/root/autodl-tmp/ZhipuAI/chatglm3-6b目录下看到模型文件。小贴士如果你之前已经下载过模型可以直接指定模型路径避免重复下载。3. Python客户端快速上手3.1 基础对话客户端让我们先从最简单的Python客户端开始验证模型是否能正常工作。创建一个client_demo.py文件import os import platform from transformers import AutoTokenizer, AutoModel # 加载分词器和模型 tokenizer AutoTokenizer.from_pretrained(/root/autodl-tmp/ZhipuAI/chatglm3-6b, trust_remote_codeTrue) model AutoModel.from_pretrained(/root/autodl-tmp/ZhipuAI/chatglm3-6b, trust_remote_codeTrue).half().cuda() model model.eval() # 设置为评估模式 # 根据操作系统设置清屏命令 os_name platform.system() clear_command cls if os_name Windows else clear def build_prompt(history): 构建对话提示 prompt 欢迎使用 ChatGLM-6B 模型输入内容即可进行对话clear 清空对话历史stop 终止程序 for item in history: if item[role] user: query item[content] prompt f\n\n用户{query} elif item[role] assistant: response item[content] prompt f\n\nChatGLM-6B{response} return prompt def main(): 主对话循环 history [] print(欢迎使用 ChatGLM-6B 模型输入内容即可进行对话clear 清空对话历史stop 终止程序) while True: query input(\n用户) if query stop: break if query clear: history [] os.system(clear_command) print(欢迎使用 ChatGLM-6B 模型输入内容即可进行对话clear 清空对话历史stop 终止程序) continue # 流式输出响应 count 0 for response, history in model.stream_chat(tokenizer, query, historyhistory): count 1 if count % 8 0: # 每8次输出清屏一次 os.system(clear_command) print(build_prompt(history), flushTrue) os.system(clear_command) print(build_prompt(history), flushTrue) if __name__ __main__: main()运行这个客户端python client_demo.py你会看到类似这样的交互欢迎使用 ChatGLM-6B 模型输入内容即可进行对话clear 清空对话历史stop 终止程序 用户你好 ChatGLM-6B你好我是人工智能助手 ChatGLM3-6B很高兴见到你欢迎问我任何问题。3.2 批量处理示例除了交互式对话我们还可以批量处理多个问题。这在需要自动化处理大量查询时非常有用。# 批量处理示例 history [] print(欢迎使用 ChatGLM-6B 模型批量处理模式) queries [ 介绍一下量子力学的基本概念, Python和Java有什么区别, 写一个简单的快速排序算法 ] for query in queries: print(f\n问题{query}) response, history model.chat(tokenizer, query, historyhistory) print(f回答{response}) print(- * 50)这个示例展示了如何连续向模型提问模型会记住之前的对话历史实现真正的多轮对话。4. Web界面搭建实战4.1 使用Gradio构建界面Gradio是一个快速构建机器学习Web界面的工具特别适合演示AI模型。让我们创建一个基于Gradio的Web界面。创建web_gradio_demo.py文件from transformers import AutoModel, AutoTokenizer import gradio as gr import os # 加载模型 tokenizer AutoTokenizer.from_pretrained(/root/autodl-tmp/ZhipuAI/chatglm3-6b, trust_remote_codeTrue) model AutoModel.from_pretrained(/root/autodl-tmp/ZhipuAI/chatglm3-6b, trust_remote_codeTrue).half().cuda() model model.eval() # 配置参数 MAX_TURNS 20 # 最大对话轮数 MAX_BOXES MAX_TURNS * 2 # 界面显示的最大消息框数 def predict(query, max_length, top_p, temperature, historyNone): 处理用户输入并生成回复 if history is None: history [] # 流式生成回复 for _, history in model.stream_chat(tokenizer, query, history, max_lengthmax_length, top_ptop_p, temperaturetemperature): updates [] for item in history: if item[role] user: query item[content] updates.append(gr.update(visibleTrue, value用户 query)) elif item[role] assistant: response item[content] updates.append(gr.update(visibleTrue, valueChatGLM-6B response)) # 填充剩余的消息框 if len(updates) MAX_BOXES: updates updates [gr.Textbox(visibleFalse)] * (MAX_BOXES - len(updates)) yield [history] updates def main(): 创建Gradio界面 with gr.Blocks() as demo: state gr.State([]) # 存储对话状态 # 创建消息显示区域 text_boxes [] for i in range(MAX_BOXES): if i % 2 0: text_boxes.append(gr.Markdown(visibleFalse, label提问)) else: text_boxes.append(gr.Markdown(visibleFalse, label回复)) # 界面布局 with gr.Row(): with gr.Column(scale4): txt gr.Textbox(show_labelFalse, placeholder输入您的问题按回车发送, lines11) with gr.Column(scale1): max_length gr.Slider(0, 4096, value2048, step1.0, label最大生成长度, interactiveTrue) top_p gr.Slider(0, 1, value0.7, step0.01, labelTop P, interactiveTrue) temperature gr.Slider(0, 1, value0.95, step0.01, label温度, interactiveTrue) button gr.Button(生成) # 绑定事件 button.click(predict, [txt, max_length, top_p, temperature, state], [state] text_boxes) # 启动服务 demo.queue().launch(shareFalse, inbrowserTrue, server_port6006) if __name__ __main__: main()运行Gradio服务python web_gradio_demo.py访问http://localhost:6006就能看到完整的Web界面了。Gradio会自动生成一个美观的聊天界面支持参数调整和流式输出。4.2 使用Streamlit构建现代化界面Streamlit是另一个流行的数据应用框架它提供了更现代化的界面和更好的交互体验。让我们创建一个Streamlit版本。创建web_streamlit_demo.py文件from transformers import AutoModel, AutoTokenizer import streamlit as st from streamlit_chat import message # 页面配置 st.set_page_config( page_titleChatGLM-6B 智能对话, page_icon:robot:, layoutwide ) st.cache_resource def get_model(): 缓存模型加载避免重复加载 tokenizer AutoTokenizer.from_pretrained(/root/autodl-tmp/ZhipuAI/chatglm3-6b, trust_remote_codeTrue) model AutoModel.from_pretrained(/root/autodl-tmp/ZhipuAI/chatglm3-6b, trust_remote_codeTrue).half().cuda() model model.eval() return tokenizer, model def predict(input_text, historyNone): 处理用户输入并显示回复 tokenizer, model get_model() if history is None: history [] # 显示历史对话 with st.container(): if len(history) 0: for i, (query, response) in enumerate(history): message(query, avatar_stylebig-smile, keyf{i}_user) message(response, avatar_stylebottts, keystr(i)) # 显示当前输入 message(input_text, avatar_stylebig-smile, keyf{len(history)}_user) # 流式显示AI回复 st.write(AI正在思考...) with st.empty(): for response, history in model.stream_chat(tokenizer, input_text, history): for item in history: if item[role] user: query item[content] elif item[role] assistant: response item[content] st.write(response) return history # 创建界面 st.title( ChatGLM3-6B 智能对话系统) st.markdown(---) # 初始化会话状态 if chat_history not in st.session_state: st.session_state[chat_history] [] # 侧边栏配置 with st.sidebar: st.header(⚙️ 参数设置) max_length st.slider(最大生成长度, 100, 4096, 2048) temperature st.slider(温度, 0.0, 2.0, 0.95) top_p st.slider(Top P, 0.0, 1.0, 0.7) if st.button(清空对话历史): st.session_state[chat_history] [] st.rerun() # 主聊天区域 col1, col2 st.columns([3, 1]) with col1: container st.container() # 显示历史消息 for i, (query, response) in enumerate(st.session_state[chat_history]): message(query, avatar_stylebig-smile, keyfhist_{i}_user) message(response, avatar_stylebottts, keyfhist_{i}_assistant) with col2: st.header( 快速提问) quick_questions [ 介绍一下你自己, 写一个Python爬虫示例, 解释量子计算, 推荐学习AI的路线 ] for q in quick_questions: if st.button(q): st.session_state[current_query] q # 输入区域 with st.form(keychat_form, clear_on_submitTrue): user_input st.text_area(输入您的问题, height100, placeholder在这里输入您的问题..., keyuser_input) submit_button st.form_submit_button(label发送) if submit_button and user_input: with st.spinner(AI正在思考请稍等...): # 获取模型回复 tokenizer, model get_model() response, _ model.chat(tokenizer, user_input, historyst.session_state[chat_history], max_lengthmax_length, temperaturetemperature, top_ptop_p) # 更新对话历史 st.session_state[chat_history].append((user_input, response)) st.rerun()运行Streamlit应用streamlit run web_streamlit_demo.py --server.address 127.0.0.1 --server.port 6006Streamlit提供了更现代化的界面和更好的用户体验特别适合需要复杂交互的应用场景。5. 高级部署方案5.1 FastAPI WebSocket实时通信对于需要更高性能和生产级部署的场景我们可以使用FastAPI配合WebSocket实现实时双向通信。创建websocket_api.pyfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect from fastapi.responses import HTMLResponse from fastapi.middleware.cors import CORSMiddleware from transformers import AutoTokenizer, AutoModel import uvicorn # 加载模型 pretrained /root/autodl-tmp/ZhipuAI/chatglm3-6b tokenizer AutoTokenizer.from_pretrained(pretrained, trust_remote_codeTrue) model AutoModel.from_pretrained(pretrained, trust_remote_codeTrue).half().cuda() model model.eval() # 创建FastAPI应用 app FastAPI() # 添加CORS中间件 app.add_middleware( CORSMiddleware, allow_origins[*], allow_credentialsTrue, allow_methods[*], allow_headers[*], ) # 读取HTML页面 with open(websocket_demo.html) as f: html f.read() app.get(/) async def get(): 返回WebSocket测试页面 return HTMLResponse(html) app.websocket(/ws) async def websocket_endpoint(websocket: WebSocket): WebSocket端点处理实时对话 输入: JSON格式 {query: 问题, history: []} 输出: JSON格式 {response: 回复, history: [], status: 200} await websocket.accept() try: while True: # 接收JSON消息 json_request await websocket.receive_json() query json_request[query] history json_request[history] # 流式生成回复 for response, history in model.stream_chat(tokenizer, query, historyhistory): await websocket.send_json({ response: response, history: history, status: 202, # 表示还在生成中 }) # 生成完成 await websocket.send_json({status: 200}) except WebSocketDisconnect: print(客户端断开连接) def main(): 启动服务 uvicorn.run(f{__name__}:app, host127.0.0.1, port6006, workers1) if __name__ __main__: main()创建对应的HTML前端页面websocket_demo.html!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleChatGLM3-6B WebSocket聊天/title style body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } #chat-container { border: 1px solid #ddd; border-radius: 5px; padding: 20px; height: 400px; overflow-y: auto; margin-bottom: 20px; } .message { margin: 10px 0; padding: 10px; border-radius: 5px; } .user-message { background-color: #e3f2fd; text-align: right; } .bot-message { background-color: #f5f5f5; text-align: left; } #input-area { display: flex; gap: 10px; } #message-input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 5px; } button { padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 5px; cursor: pointer; } button:hover { background-color: #0056b3; } /style /head body h1ChatGLM3-6B WebSocket聊天/h1 div idchat-container/div div idinput-area input typetext idmessage-input placeholder输入消息... autocompleteoff button onclicksendMessage()发送/button /div script let ws new WebSocket(ws:// location.host /ws); let history []; let lastMessageElement null; // 连接状态提示 ws.onopen function() { console.log(WebSocket连接已建立); addMessage(系统, 连接成功可以开始聊天了, system); }; ws.onclose function() { console.log(WebSocket连接已关闭); addMessage(系统, 连接已断开, system); }; // 添加消息到聊天窗口 function addMessage(sender, text, type) { let chatContainer document.getElementById(chat-container); let messageDiv document.createElement(div); messageDiv.className message ${type}-message; messageDiv.innerHTML strong${sender}/strong${text}; chatContainer.appendChild(messageDiv); chatContainer.scrollTop chatContainer.scrollHeight; return messageDiv; } // 发送消息 function sendMessage() { let input document.getElementById(message-input); let message input.value.trim(); if (!message) return; // 显示用户消息 addMessage(用户, message, user); // 发送到服务器 let request { query: message, history: history }; ws.send(JSON.stringify(request)); // 清空输入框 input.value ; // 创建AI回复占位符 lastMessageElement addMessage(AI, 思考中..., bot); } // 处理回车键 document.getElementById(message-input).addEventListener(keypress, function(e) { if (e.key Enter) { sendMessage(); } }); // 接收服务器消息 ws.onmessage function(event) { let data JSON.parse(event.data); let status data.status; if (status 202) { // 流式输出中 history data.history; if (lastMessageElement) { lastMessageElement.innerHTML strongAI/strong${data.response}; } } else if (status 200) { // 输出完成 lastMessageElement null; } }; /script /body /html这个方案提供了真正的实时双向通信适合需要低延迟、高并发的生产环境。5.2 Docker容器化部署对于生产环境我们推荐使用Docker进行容器化部署确保环境一致性和可移植性。创建docker-compose.ymlversion: 3.8 services: chatglm3-api: build: . container_name: chatglm3-api restart: unless-stopped ports: - 8000:8000 environment: - MODEL_PATH/app/models/chatglm3-6b - TZAsia/Shanghai volumes: - ./models:/app/models - ./data:/app/data deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] command: sh -c python api_server.py --host 0.0.0.0 --port 8000创建DockerfileFROM nvidia/cuda:11.8.0-runtime-ubuntu20.04 # 设置环境变量 ENV DEBIAN_FRONTENDnoninteractive ENV PYTHONUNBUFFERED1 # 安装系统依赖 RUN apt-get update apt-get install -y \ python3.8 \ python3-pip \ python3.8-venv \ git \ wget \ rm -rf /var/lib/apt/lists/* # 创建应用目录 WORKDIR /app # 复制依赖文件 COPY requirements.txt . # 安装Python依赖 RUN pip3 install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 复制应用代码 COPY . . # 创建模型目录 RUN mkdir -p /app/models # 暴露端口 EXPOSE 8000 # 启动命令 CMD [python3, api_server.py, --host, 0.0.0.0, --port, 8000]创建requirements.txtfastapi0.104.1 uvicorn[standard]0.24.0.post1 transformers4.37.2 torch2.0.0 sentencepiece0.1.99 accelerate0.24.1 streamlit1.24.0 gradio3.50.2构建并运行Docker容器# 构建镜像 docker build -t chatglm3-api . # 运行容器 docker-compose up -d # 查看日志 docker logs -f chatglm3-api6. 总结与优化建议6.1 部署方案对比通过本文的介绍我们学习了多种ChatGLM3-6B的部署方式。每种方案都有其适用场景部署方式优点缺点适用场景Python客户端最简单直接无需Web服务没有图形界面交互性差快速测试、脚本调用Gradio界面快速搭建界面友好支持参数调整性能一般不适合高并发演示、原型开发Streamlit界面现代化界面交互丰富支持复杂布局资源消耗较大数据应用、管理后台FastAPIWebSocket高性能支持实时通信适合生产环境开发复杂度较高企业应用、实时系统Docker容器化环境隔离易于部署和扩展需要Docker知识生产部署、云服务6.2 性能优化建议在实际使用中你可能需要根据具体需求进行性能优化1. 模型加载优化# 使用量化减少显存占用 model AutoModel.from_pretrained(model_path, trust_remote_codeTrue, load_in_8bitTrue, # 8位量化 device_mapauto) # 自动设备映射2. 批处理推理# 批量处理多个请求 queries [问题1, 问题2, 问题3] responses [] for query in queries: response, _ model.chat(tokenizer, query) responses.append(response)3. 缓存机制from functools import lru_cache lru_cache(maxsize100) def get_cached_response(query): 缓存常见问题的回复 response, _ model.chat(tokenizer, query) return response4. 异步处理import asyncio from concurrent.futures import ThreadPoolExecutor executor ThreadPoolExecutor(max_workers4) async def async_chat(query): loop asyncio.get_event_loop() response await loop.run_in_executor( executor, lambda: model.chat(tokenizer, query)[0] ) return response6.3 常见问题解决问题1显存不足解决方案使用模型量化8bit/4bit、梯度检查点、CPU卸载代码示例# 4位量化 model AutoModel.from_pretrained(model_path, trust_remote_codeTrue, load_in_4bitTrue, device_mapauto)问题2响应速度慢解决方案启用CUDA Graph、使用更快的推理后端如vLLM、批处理请求配置示例import torch torch.backends.cudnn.benchmark True # 启用CUDA优化问题3对话历史过长解决方案实现滑动窗口、关键信息提取、历史总结def trim_history(history, max_tokens2048): 修剪对话历史保留最近的内容 total_tokens sum(len(tokenizer.encode(str(msg))) for msg in history) while total_tokens max_tokens and len(history) 1: removed history.pop(0) total_tokens - len(tokenizer.encode(str(removed))) return history6.4 下一步学习建议掌握了基础部署后你可以进一步探索模型微调在自己的数据集上微调ChatGLM3让它更擅长特定领域RAG增强结合向量数据库实现基于文档的问答系统多模态扩展集成图像理解、语音识别等能力分布式部署使用多个GPU或服务器进行分布式推理API服务化将模型封装为标准的REST API供其他应用调用ChatGLM3-6B的本地部署为你打开了一扇通往私有化AI应用的大门。无论是个人学习、企业应用还是产品开发这个强大的中文对话模型都能为你提供可靠的支持。记住最好的学习方式就是动手实践现在就开始你的AI之旅吧获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。