WinstonDeng commited on
Commit
17d9154
·
verified ·
1 Parent(s): ecded4c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +181 -0
app.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import json
4
+ import httpx
5
+
6
+ # ============================================================
7
+ # API 配置
8
+ # ============================================================
9
+ STEPFUN_API_KEY = os.environ.get("STEPFUN_API_KEY", "")
10
+ STEPFUN_BASE_URL = "https://api.stepfun.com/v1"
11
+ MODEL_NAME = "step-3.5-flash"
12
+ HF_CONFIG_URL = "https://huggingface.co/stepfun-ai/Step-3.5-Flash/raw/main/config.json"
13
+ STEPFUN_LOGO = "https://huggingface.co/stepfun-ai/Step-3.5-Flash/resolve/main/stepfun.svg"
14
+
15
+ cached_config = None
16
+
17
+
18
+ def fetch_model_config():
19
+ global cached_config
20
+ try:
21
+ response = httpx.get(HF_CONFIG_URL, timeout=10.0)
22
+ if response.status_code == 200:
23
+ cached_config = response.json()
24
+ return cached_config
25
+ except Exception as e:
26
+ print(f"拉取 config.json 失败: {e}")
27
+ return cached_config
28
+
29
+
30
+ def format_messages(history, system_prompt: str, user_message: str):
31
+ """将 chatbot history 转换为 API 消息格式"""
32
+ messages = []
33
+ if system_prompt.strip():
34
+ messages.append({"role": "system", "content": system_prompt})
35
+ for user_msg, bot_msg in history:
36
+ if user_msg:
37
+ messages.append({"role": "user", "content": user_msg})
38
+ if bot_msg:
39
+ messages.append({"role": "assistant", "content": bot_msg})
40
+ messages.append({"role": "user", "content": user_message})
41
+ return messages
42
+
43
+
44
+ def chat_stream(message: str, history, system_prompt: str, max_tokens: int, temperature: float, top_p: float):
45
+ """流式聊天,返回 (reasoning, content) 生成器"""
46
+ fetch_model_config()
47
+ messages = format_messages(history, system_prompt, message)
48
+
49
+ reasoning = ""
50
+ content = ""
51
+
52
+ try:
53
+ headers = {
54
+ "Authorization": f"Bearer {STEPFUN_API_KEY}",
55
+ "Content-Type": "application/json",
56
+ }
57
+ payload = {
58
+ "model": MODEL_NAME,
59
+ "messages": messages,
60
+ "stream": True,
61
+ "max_tokens": max_tokens,
62
+ "temperature": temperature if temperature > 0 else 0.01,
63
+ "top_p": top_p,
64
+ }
65
+
66
+ with httpx.stream("POST", f"{STEPFUN_BASE_URL}/chat/completions", headers=headers, json=payload, timeout=120.0) as response:
67
+ response.raise_for_status()
68
+ for line in response.iter_lines():
69
+ if not line or not line.startswith("data: "):
70
+ continue
71
+ data_str = line[6:]
72
+ if data_str == "[DONE]":
73
+ break
74
+ try:
75
+ chunk = json.loads(data_str)
76
+ delta = chunk.get("choices", [{}])[0].get("delta", {})
77
+ if delta.get("reasoning"):
78
+ reasoning += delta["reasoning"]
79
+ yield reasoning, content
80
+ if delta.get("content"):
81
+ content += delta["content"]
82
+ yield reasoning, content
83
+ except json.JSONDecodeError:
84
+ continue
85
+ yield reasoning, content
86
+
87
+ except httpx.HTTPStatusError as e:
88
+ yield reasoning, f"❌ API 错误: {e.response.status_code}"
89
+ except Exception as e:
90
+ yield reasoning, f"❌ 错误: {str(e)}"
91
+
92
+
93
+ def create_demo():
94
+ examples = [
95
+ "请解释一下什么是机器学习?",
96
+ "帮我写一个 Python 快速排序算法",
97
+ "1000以内有多少个质数?",
98
+ "一个农夫需要把狼、羊和白菜都带过河,请问农夫该怎么办?",
99
+ ]
100
+
101
+ with gr.Blocks(title="Step-3.5-Flash", theme=gr.themes.Soft()) as demo:
102
+ gr.Markdown("# 🚀 Step-3.5-Flash")
103
+
104
+ with gr.Row():
105
+ # 左侧:思考过程 (1)
106
+ with gr.Column(scale=1, min_width=250):
107
+ gr.Markdown("### 💭 思考过程")
108
+ thinking_display = gr.Textbox(
109
+ value="等待输入...",
110
+ lines=20,
111
+ max_lines=20,
112
+ interactive=False,
113
+ show_label=False,
114
+ )
115
+
116
+ # 右侧:对话 (4)
117
+ with gr.Column(scale=4):
118
+ gr.Markdown("### 💬 对话")
119
+ chatbot = gr.Chatbot(
120
+ height=450,
121
+ show_label=False,
122
+ avatar_images=(None, STEPFUN_LOGO),
123
+ )
124
+
125
+ with gr.Row():
126
+ msg = gr.Textbox(
127
+ placeholder="输入消息...",
128
+ show_label=False,
129
+ scale=8,
130
+ container=False,
131
+ )
132
+ submit_btn = gr.Button("发送", variant="primary", scale=1)
133
+ clear_btn = gr.Button("🗑️", scale=0, min_width=50)
134
+
135
+ # 设置(折叠)
136
+ with gr.Accordion("⚙️ 设置", open=False):
137
+ with gr.Row():
138
+ system_prompt = gr.Textbox(label="系统提示词", value="你是一个有帮助的 AI 助手。", scale=2)
139
+ max_tokens = gr.Slider(256, 131072, value=4096, step=256, label="最大长度", scale=1)
140
+ temperature = gr.Slider(0.0, 1.5, value=0.7, step=0.1, label="Temperature", scale=1)
141
+ top_p = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-p", scale=1)
142
+
143
+ gr.Examples(examples, inputs=msg, label="💡 试试这些")
144
+
145
+ # 事件处理
146
+ def respond(message, history, system_prompt, max_tokens, temperature, top_p):
147
+ if not message.strip():
148
+ yield history, "", ""
149
+ return
150
+
151
+ # 添加用户消息
152
+ history = history + [[message, None]]
153
+ yield history, "", "思考中..."
154
+
155
+ reasoning = ""
156
+ content = ""
157
+
158
+ for r, c in chat_stream(message, history[:-1], system_prompt, max_tokens, temperature, top_p):
159
+ reasoning = r if r else ""
160
+ content = c if c else "▌"
161
+ history[-1][1] = content
162
+ yield history, "", reasoning
163
+
164
+ history[-1][1] = content
165
+ yield history, "", reasoning
166
+
167
+ def on_clear():
168
+ return [], "", "等待输入..."
169
+
170
+ msg.submit(respond, [msg, chatbot, system_prompt, max_tokens, temperature, top_p], [chatbot, msg, thinking_display])
171
+ submit_btn.click(respond, [msg, chatbot, system_prompt, max_tokens, temperature, top_p], [chatbot, msg, thinking_display])
172
+ clear_btn.click(on_clear, outputs=[chatbot, msg, thinking_display])
173
+ demo.load(fetch_model_config)
174
+
175
+ return demo
176
+
177
+
178
+ if __name__ == "__main__":
179
+ demo = create_demo()
180
+ demo.queue()
181
+ demo.launch(server_name="0.0.0.0", server_port=7860)