Marcus719 commited on
Commit
94179db
·
verified ·
1 Parent(s): c0b1061

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -0
app.py ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from huggingface_hub import hf_hub_download
3
+ from llama_cpp import Llama
4
+ import time
5
+
6
+ # --- 1. 页面基础配置 ---
7
+ st.set_page_config(
8
+ page_title="Llama 3.2 AI Assistant",
9
+ page_icon="🤖",
10
+ layout="wide", # 使用宽屏模式
11
+ initial_sidebar_state="expanded"
12
+ )
13
+
14
+ # --- 2. 自定义 CSS (美化界面) ---
15
+ st.markdown("""
16
+ <style>
17
+ /* 隐藏 Streamlit 默认的汉堡菜单和页脚 */
18
+ #MainMenu {visibility: hidden;}
19
+ footer {visibility: hidden;}
20
+ header {visibility: hidden;}
21
+
22
+ /* 调整主容器的顶部 padding,让内容更紧凑 */
23
+ .block-container {
24
+ padding-top: 2rem;
25
+ padding-bottom: 2rem;
26
+ }
27
+
28
+ /* 美化侧边栏 */
29
+ section[data-testid="stSidebar"] {
30
+ background-color: #f7f9fc; /* 浅灰蓝背景 */
31
+ }
32
+
33
+ /* 自定义标题样式 */
34
+ .title-text {
35
+ font-family: 'Helvetica Neue', sans-serif;
36
+ font-weight: 700;
37
+ font-size: 2.5rem;
38
+ color: #1E88E5; /* 科技蓝 */
39
+ text-align: center;
40
+ margin-bottom: 20px;
41
+ }
42
+
43
+ .subtitle-text {
44
+ font-family: 'Helvetica Neue', sans-serif;
45
+ font-weight: 400;
46
+ font-size: 1.1rem;
47
+ color: #666;
48
+ text-align: center;
49
+ margin-bottom: 40px;
50
+ }
51
+ </style>
52
+ """, unsafe_allow_html=True)
53
+
54
+ # --- 3. 标题区域 ---
55
+ st.markdown('<div class="title-text">🤖 Llama 3.2-3B AI Assistant</div>', unsafe_allow_html=True)
56
+ st.markdown('<div class="subtitle-text">Powered by Marcus719/Llama-3.2-3B-changedata-Lab2-GGUF</div>', unsafe_allow_html=True)
57
+
58
+ # --- 4. 侧边栏 (控制面板) ---
59
+ with st.sidebar:
60
+ st.image("https://huggingface.co/front/assets/huggingface_logo-noborder.svg", width=50)
61
+ st.header("⚙️ 控制面板")
62
+
63
+ # 参数设置
64
+ temperature = st.slider("Temperature (创造性)", min_value=0.1, max_value=1.5, value=0.7, step=0.1, help="值越高,回答越随机;值越低,回答越严谨。")
65
+ max_tokens = st.slider("Max Tokens (最大长度)", min_value=64, max_value=2048, value=512, step=64)
66
+
67
+ st.divider()
68
+
69
+ # 系统提示词 (System Prompt)
70
+ system_prompt = st.text_area(
71
+ "系统设定 (System Prompt)",
72
+ value="You are a helpful and polite AI assistant.",
73
+ height=100
74
+ )
75
+
76
+ st.divider()
77
+
78
+ # 清除历史按钮
79
+ if st.button("🗑️ 清除对话历史", use_container_width=True):
80
+ st.session_state.messages = []
81
+ st.rerun()
82
+
83
+ st.markdown("---")
84
+ st.markdown("Optimization: **Unsloth Q4_K_M**")
85
+
86
+ # --- 5. 模型加载逻辑 ---
87
+ REPO_ID = "Marcus719/Llama-3.2-3B-changedata-Lab2-GGUF"
88
+ FILENAME = "unsloth.Q4_K_M.gguf"
89
+
90
+ @st.cache_resource
91
+ def load_model():
92
+ model_path = hf_hub_download(repo_id=REPO_ID, filename=FILENAME)
93
+ llm = Llama(
94
+ model_path=model_path,
95
+ n_ctx=4096,
96
+ n_threads=2, # HF Spaces free tier limit
97
+ verbose=False
98
+ )
99
+ return llm
100
+
101
+ try:
102
+ if "llm" not in st.session_state:
103
+ with st.spinner("🚀 正在启动 AI 引擎,请稍候..."):
104
+ st.session_state.llm = load_model()
105
+ except Exception as e:
106
+ st.error(f"模型加载失败: {e}")
107
+
108
+ # --- 6. 聊天逻辑 ---
109
+
110
+ # 初始化历史
111
+ if "messages" not in st.session_state:
112
+ st.session_state.messages = []
113
+
114
+ # 显示历史消息
115
+ for message in st.session_state.messages:
116
+ # 设置不同的头像
117
+ avatar = "🧑‍💻" if message["role"] == "user" else "🤖"
118
+ with st.chat_message(message["role"], avatar=avatar):
119
+ st.markdown(message["content"])
120
+
121
+ # 处理用户输入
122
+ if prompt := st.chat_input("在此输入您的问题..."):
123
+ # 1. 显示用户输入
124
+ st.session_state.messages.append({"role": "user", "content": prompt})
125
+ with st.chat_message("user", avatar="🧑‍💻"):
126
+ st.markdown(prompt)
127
+
128
+ # 2. 生成 AI 回复
129
+ with st.chat_message("assistant", avatar="🤖"):
130
+ message_placeholder = st.empty()
131
+ full_response = ""
132
+
133
+ # 构建带 System Prompt 的消息列表
134
+ messages_payload = [{"role": "system", "content": system_prompt}] + [
135
+ {"role": m["role"], "content": m["content"]}
136
+ for m in st.session_state.messages
137
+ ]
138
+
139
+ stream = st.session_state.llm.create_chat_completion(
140
+ messages=messages_payload,
141
+ stream=True,
142
+ max_tokens=max_tokens,
143
+ temperature=temperature
144
+ )
145
+
146
+ for chunk in stream:
147
+ if "content" in chunk["choices"][0]["delta"]:
148
+ token = chunk["choices"][0]["delta"]["content"]
149
+ full_response += token
150
+ # 模拟打字机效果,稍微平滑一点显示
151
+ message_placeholder.markdown(full_response + "▌")
152
+
153
+ message_placeholder.markdown(full_response)
154
+
155
+ # 3. 保存回复
156
+ st.session_state.messages.append({"role": "assistant", "content": full_response})