Spaces:
Runtime error
Runtime error
| 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 | |
| ) |