Step3 / app.py
Zenith Wang
完全重写应用:使用更稳定的Gradio 3.50.2版本和简化的代码结构
96f986b
raw
history blame
6.88 kB
import os
import io
import base64
import gradio as gr
from PIL import Image
from openai import OpenAI
# 配置
BASE_URL = "https://api.stepfun.com/v1"
DEFAULT_MODEL = "step-3" # 可选: step-3, step-r1-v-mini
def get_api_key():
"""获取API密钥"""
api_key = os.environ.get("STEPFUN_API_KEY")
if not api_key:
raise ValueError("请设置环境变量 STEPFUN_API_KEY")
return api_key
def image_to_base64(image):
"""将PIL图像转换为base64编码"""
if image is None:
return None
# 转换为RGB格式
if image.mode != 'RGB':
image = image.convert('RGB')
# 保存到字节流
buffer = io.BytesIO()
image.save(buffer, format='JPEG', quality=85)
# 编码为base64
img_str = base64.b64encode(buffer.getvalue()).decode('utf-8')
return f"data:image/jpeg;base64,{img_str}"
def chat_with_stepfun(message, image, history, model, system_prompt):
"""
处理聊天请求
Args:
message: 用户输入的文本
image: 用户上传的图片 (PIL Image)
history: 聊天历史
model: 选择的模型
system_prompt: 系统提示词
Returns:
更新后的聊天历史
"""
try:
# 获取API密钥
api_key = get_api_key()
client = OpenAI(api_key=api_key, base_url=BASE_URL)
# 构建消息列表
messages = []
# 添加系统提示
if system_prompt and system_prompt.strip():
messages.append({
"role": "system",
"content": system_prompt
})
# 添加历史对话
for user_msg, assistant_msg in history:
if user_msg:
messages.append({
"role": "user",
"content": user_msg
})
if assistant_msg:
messages.append({
"role": "assistant",
"content": assistant_msg
})
# 构建当前用户消息
current_content = []
# 添加图片
if image is not None:
img_base64 = image_to_base64(image)
current_content.append({
"type": "image_url",
"image_url": {
"url": img_base64,
"detail": "high"
}
})
# 添加文本
if message and message.strip():
current_content.append({
"type": "text",
"text": message
})
# 如果没有任何内容,返回
if not current_content:
return history
# 添加当前消息
messages.append({
"role": "user",
"content": current_content
})
# 调用API
response = client.chat.completions.create(
model=model,
messages=messages,
stream=True
)
# 处理流式响应
full_response = ""
for chunk in response:
if chunk.choices[0].delta.content:
full_response += chunk.choices[0].delta.content
# 实时更新界面
yield history + [(message, full_response)]
# 返回最终结果
yield history + [(message, full_response)]
except Exception as e:
error_msg = f"错误: {str(e)}"
yield history + [(message, error_msg)]
def clear_chat():
"""清空聊天记录"""
return None, None, []
# 创建Gradio界面
def create_interface():
with gr.Blocks(title="StepFun 多模态对话") as demo:
gr.Markdown("""
# 🚀 StepFun Step-3 多模态对话
支持图片理解和文本对话,使用StepFun API。
**使用说明:**
1. 在环境变量中设置 `STEPFUN_API_KEY`
2. 可选择上传图片进行视觉理解
3. 输入文本进行对话
""")
with gr.Row():
with gr.Column(scale=3):
# 聊天界面
chatbot = gr.Chatbot(
height=500,
bubble_full_width=False,
avatar_images=(None, None)
)
with gr.Row():
with gr.Column(scale=3):
msg = gr.Textbox(
label="输入消息",
placeholder="输入你的问题...",
lines=2
)
with gr.Column(scale=1):
img = gr.Image(
label="上传图片(可选)",
type="pil"
)
with gr.Row():
submit = gr.Button("发送", variant="primary")
clear = gr.Button("清空对话")
with gr.Column(scale=1):
# 设置面板
model = gr.Dropdown(
label="选择模型",
choices=["step-3", "step-r1-v-mini"],
value="step-3"
)
system_prompt = gr.Textbox(
label="系统提示(可选)",
placeholder="设置AI的角色或行为...",
lines=3
)
gr.Markdown("""
### 说明
- **step-3**: 标准多模态模型
- **step-r1-v-mini**: 轻量级版本
### 提示
- 支持中英文对话
- 图片支持JPG/PNG格式
- 可以询问图片内容
""")
# 事件绑定
submit.click(
fn=chat_with_stepfun,
inputs=[msg, img, chatbot, model, system_prompt],
outputs=[chatbot],
queue=True
).then(
lambda: (None, None),
outputs=[msg, img]
)
msg.submit(
fn=chat_with_stepfun,
inputs=[msg, img, chatbot, model, system_prompt],
outputs=[chatbot],
queue=True
).then(
lambda: (None, None),
outputs=[msg, img]
)
clear.click(
fn=clear_chat,
outputs=[msg, img, chatbot]
)
return demo
# 主程序
if __name__ == "__main__":
demo = create_interface()
# 获取端口
port = int(os.environ.get("PORT", 7860))
# 启动应用
demo.launch(
server_name="0.0.0.0",
server_port=port,
share=False
)