GLM-4V-9B Streamlit UI定制指南:添加清空历史、图片缩略图、下载日志功能
GLM-4V-9B Streamlit UI定制指南:添加清空历史、图片缩略图、下载日志功能
1. 项目概述
GLM-4V-9B是一个强大的多模态大模型,能够同时处理图像和文本输入。本项目基于Streamlit框架构建了一个用户友好的界面,让用户可以通过简单的操作与模型进行交互。
经过深度优化,这个版本解决了官方示例在特定环境下的兼容性问题,特别是PyTorch和CUDA版本的匹配问题。通过4-bit量化技术,模型现在可以在消费级显卡上流畅运行,大大降低了硬件门槛。
核心优化亮点:
- 自动检测视觉层参数类型,避免数据类型冲突导致的错误
- 修正了Prompt拼接顺序,确保模型正确理解图像和文本的关系
- 优化了显存使用,让8GB显存的显卡也能运行这个大型模型
2. 环境准备与快速部署
2.1 系统要求
在开始定制之前,确保你的系统满足以下要求:
- Python 3.8或更高版本
- 支持CUDA的NVIDIA显卡(建议8GB以上显存)
- 至少20GB的可用磁盘空间
- 稳定的网络连接(用于下载模型权重)
2.2 安装依赖
创建并激活Python虚拟环境后,安装所需依赖:
# 创建虚拟环境
python -m venv glm4v-env
source glm4v-env/bin/activate # Linux/Mac
# 或
glm4v-env\Scripts\activate # Windows
# 安装核心依赖
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install streamlit transformers accelerate bitsandbytes
pip install Pillow python-multipart
2.3 快速启动
下载项目代码后,通过以下命令启动基础版本:
streamlit run app.py --server.port 8080
启动后,在浏览器中访问 http://localhost:8080 即可看到基础界面。
3. 清空历史功能实现
3.1 为什么需要清空历史功能
在多轮对话过程中,历史记录会不断累积,可能导致以下问题:
- 占用过多内存,影响性能
- 新旧对话混杂,影响模型理解
- 隐私考虑,用户可能希望清除敏感对话内容
3.2 实现清空历史功能
在Streamlit应用中添加清空按钮非常简单。在app.py中找到会话状态管理部分,添加以下代码:
import streamlit as st
# 在侧边栏添加清空按钮
with st.sidebar:
if st.button("🗑️ 清空历史", help="清除所有对话记录"):
# 重置会话状态中的消息历史
st.session_state.messages = []
st.session_state.uploaded_images = []
st.rerun()
# 初始化消息历史
if "messages" not in st.session_state:
st.session_state.messages = []
if "uploaded_images" not in st.session_state:
st.session_state.uploaded_images = []
3.3 增强清空功能
为了更好的用户体验,我们可以添加确认对话框防止误操作:
# 添加确认对话框的清空功能
if st.sidebar.button("🗑️ 清空历史"):
# 使用对话框确认
if st.session_state.messages: # 只有有历史时才确认
confirm = st.sidebar.checkbox("确认清空所有对话历史?")
if confirm:
st.session_state.messages = []
st.session_state.uploaded_images = []
st.sidebar.success("历史记录已清空!")
st.rerun()
else:
st.sidebar.info("当前没有对话历史")
4. 图片缩略图功能实现
4.1 图片缩略图的价值
在多轮对话中,用户可能会上传多张图片。缩略图功能可以帮助:
- 快速识别已上传的图片
- 方便在不同图片间切换
- 提供视觉反馈,确认图片已正确上传
4.2 实现图片缩略图展示
在侧边栏中显示已上传图片的缩略图:
from PIL import Image
import io
# 在侧边栏显示已上传图片的缩略图
if st.session_state.uploaded_images:
st.sidebar.markdown("### 📷 已上传图片")
for i, img_data in enumerate(st.session_state.uploaded_images):
# 创建缩略图
img = Image.open(io.BytesIO(img_data))
img.thumbnail((100, 100)) # 缩放到100x100像素
# 显示缩略图和删除按钮
col1, col2 = st.sidebar.columns([3, 1])
col1.image(img, use_column_width=True)
# 添加删除单个图片的按钮
if col2.button("❌", key=f"delete_img_{i}"):
st.session_state.uploaded_images.pop(i)
st.rerun()
4.3 增强缩略图功能
添加图片预览和选择功能:
# 增强版图片缩略图组件
def image_thumbnail_gallery():
if not st.session_state.uploaded_images:
return None
st.sidebar.markdown("### 📷 图片库")
# 让用户选择当前活动的图片
image_titles = [f"图片 {i+1}" for i in range(len(st.session_state.uploaded_images))]
selected_image = st.sidebar.selectbox("选择图片", image_titles)
# 显示选中图片的预览
selected_index = image_titles.index(selected_image)
img_data = st.session_state.uploaded_images[selected_index]
img = Image.open(io.BytesIO(img_data))
st.sidebar.image(img, caption=selected_image, use_column_width=True)
return selected_index
# 在适当位置调用
current_image_index = image_thumbnail_gallery()
5. 下载日志功能实现
5.1 日志功能的重要性
下载对话日志对于以下场景非常有用:
- 保存重要的对话内容供后续参考
- 分享有趣的对话结果
- 收集用户反馈和改进模型
- 学术研究或案例分析
5.2 实现对话日志下载
添加导出对话历史的功能:
import json
from datetime import datetime
def export_conversation():
"""将对话历史导出为JSON文件"""
if not st.session_state.messages:
return None
# 构建导出数据
export_data = {
"export_date": datetime.now().isoformat(),
"model": "GLM-4V-9B",
"conversation": []
}
for msg in st.session_state.messages:
export_data["conversation"].append({
"role": msg["role"],
"content": msg["content"],
"timestamp": datetime.now().isoformat()
})
# 转换为JSON字符串
return json.dumps(export_data, ensure_ascii=False, indent=2)
# 在侧边栏添加导出按钮
if st.session_state.messages:
export_json = export_conversation()
st.sidebar.download_button(
label="💾 导出对话",
data=export_json,
file_name=f"glm4v_conversation_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
mime="application/json",
help="将当前对话导出为JSON文件"
)
5.3 多种格式导出支持
提供不同格式的导出选项:
# 支持多种导出格式
def export_conversation_multiformat(format_type="json"):
"""支持多种格式的对话导出"""
if not st.session_state.messages:
return None, ""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if format_type == "json":
data = json.dumps({
"export_date": datetime.now().isoformat(),
"conversation": st.session_state.messages
}, ensure_ascii=False, indent=2)
filename = f"glm4v_conversation_{timestamp}.json"
mime_type = "application/json"
elif format_type == "txt":
# 纯文本格式
text_content = f"GLM-4V-9B 对话导出 - {datetime.now()}\n\n"
for msg in st.session_state.messages:
role = "用户" if msg["role"] == "user" else "助手"
text_content += f"{role}: {msg['content']}\n\n"
data = text_content
filename = f"glm4v_conversation_{timestamp}.txt"
mime_type = "text/plain"
elif format_type == "md":
# Markdown格式
md_content = f"# GLM-4V-9B 对话导出\n\n*导出时间: {datetime.now()}*\n\n"
for msg in st.session_state.messages:
role = "**用户**" if msg["role"] == "user" else "**助手**"
md_content += f"{role}: {msg['content']}\n\n---\n\n"
data = md_content
filename = f"glm4v_conversation_{timestamp}.md"
mime_type = "text/markdown"
return data, filename, mime_type
# 在UI中添加格式选择
if st.session_state.messages:
st.sidebar.markdown("### 💾 导出选项")
export_format = st.sidebar.selectbox("导出格式", ["JSON", "TXT", "Markdown"])
data, filename, mime_type = export_conversation_multiformat(export_format.lower())
st.sidebar.download_button(
label=f"下载{export_format}格式",
data=data,
file_name=filename,
mime=mime_type
)
6. 完整功能集成
6.1 整合所有定制功能
将上述功能整合到主应用中,创建一个完整的定制版UI:
import streamlit as st
import torch
from PIL import Image
import io
import json
from datetime import datetime
# 页面配置
st.set_page_config(
page_title="GLM-4V-9B 增强版",
page_icon="🦅",
layout="wide",
initial_sidebar_state="expanded"
)
# 初始化会话状态
if "messages" not in st.session_state:
st.session_state.messages = []
if "uploaded_images" not in st.session_state:
st.session_state.uploaded_images = []
if "current_image_index" not in st.session_state:
st.session_state.current_image_index = 0
# 侧边栏 - 功能区域
with st.sidebar:
st.title("🦅 GLM-4V-9B 控制面板")
# 图片上传
st.markdown("### 📤 上传图片")
uploaded_file = st.file_uploader("选择图片文件", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
# 保存上传的图片
img_data = uploaded_file.read()
if img_data not in st.session_state.uploaded_images:
st.session_state.uploaded_images.append(img_data)
st.success("图片上传成功!")
# 图片缩略图库
if st.session_state.uploaded_images:
st.markdown("### 📷 图片库")
image_titles = [f"图片 {i+1}" for i in range(len(st.session_state.uploaded_images))]
selected_title = st.selectbox("选择图片", image_titles)
st.session_state.current_image_index = image_titles.index(selected_title)
# 显示选中图片的预览
img_data = st.session_state.uploaded_images[st.session_state.current_image_index]
img = Image.open(io.BytesIO(img_data))
st.image(img, use_column_width=True)
# 工具功能区
st.markdown("### 🛠️ 工具")
# 清空历史按钮
if st.button("🗑️ 清空对话历史", use_container_width=True):
if st.session_state.messages:
if st.checkbox("确认清空所有对话历史?"):
st.session_state.messages = []
st.success("历史记录已清空!")
st.rerun()
else:
st.info("当前没有对话历史")
# 导出功能
if st.session_state.messages:
st.markdown("### 💾 导出对话")
export_format = st.selectbox("格式选择", ["JSON", "TXT", "Markdown"])
# 导出逻辑(略,使用前面实现的函数)
6.2 优化用户体验
添加一些用户体验优化功能:
# 添加一些用户体验增强功能
# 1. 输入框置底并固定
def bottom_input():
st.markdown("---")
input_col, button_col = st.columns([5, 1])
with input_col:
user_input = st.text_input(
"输入你的问题...",
key="user_input",
label_visibility="collapsed"
)
with button_col:
send_button = st.button("发送", use_container_width=True)
return user_input, send_button
# 2. 对话历史自动滚动到底部
def scroll_bottom():
# 使用JavaScript实现自动滚动
js = """
<script>
function scrollToBottom() {
window.parent.document.querySelector('section.main').scrollTo(0, window.parent.document.querySelector('section.main').scrollHeight);
}
setTimeout(scrollToBottom, 100);
</script>
"""
st.components.v1.html(js, height=0)
# 3. 在适当位置调用滚动函数
if st.session_state.messages:
# 显示对话历史
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# 自动滚动到底部
scroll_bottom()
# 获取用户输入
user_input, send_button = bottom_input()
7. 总结
通过本指南,我们为GLM-4V-9B的Streamlit界面添加了三个实用功能:
清空历史功能让用户可以随时重置对话,保护隐私并释放内存。我们实现了简单的清空按钮和带确认对话框的安全清空功能,防止误操作。
图片缩略图功能大大提升了多图片对话的体验。用户可以直观地看到所有已上传图片,方便在不同图片间切换和管理。
下载日志功能提供了对话导出能力,支持JSON、纯文本和Markdown多种格式,满足不同场景下的需求。
这些定制功能不仅提升了用户体验,也展示了Streamlit框架的强大灵活性。你可以基于这些示例,继续扩展更多实用功能,如对话主题管理、个性化设置保存、或者集成其他AI服务。
记住,好的UI设计应该始终以用户需求为中心,不断迭代优化。希望本指南能为你的项目开发提供有价值的参考。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐

所有评论(0)