import gradio as gr import os import logging from huggingface_hub import InferenceClient from typing import List, Tuple, Generator, Dict, Any, Optional # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) class ChatConfig: """Configuration settings for the chat application.""" MODEL = "google/gemma-3-27b-it" DEFAULT_SYSTEM_MSG = "You are a super intelligent and useful Chatbot." DEFAULT_MAX_TOKENS = 512 DEFAULT_TEMP = 0.3 DEFAULT_TOP_P = 0.95 HF_TOKEN = os.environ.get("HF_TOKEN", None) # Get token from environment variable class ChatApp: """Main chat application class.""" def __init__(self): """Initialize the chat application.""" try: self.client = InferenceClient( ChatConfig.MODEL, token=ChatConfig.HF_TOKEN ) logger.info(f"Successfully initialized InferenceClient for {ChatConfig.MODEL}") except Exception as e: logger.error(f"Failed to initialize InferenceClient: {e}") raise def generate_response( self, message: str, history: List[Tuple[str, str]], system_message: str = ChatConfig.DEFAULT_SYSTEM_MSG, max_tokens: int = ChatConfig.DEFAULT_MAX_TOKENS, temperature: float = ChatConfig.DEFAULT_TEMP, top_p: float = ChatConfig.DEFAULT_TOP_P ) -> str: """Generate responses from the model.""" if not message.strip(): return "请输入消息。" messages = [{"role": "system", "content": system_message}] # Add conversation history for user_msg, bot_msg in history: if user_msg: messages.append({"role": "user", "content": user_msg}) if bot_msg: messages.append({"role": "assistant", "content": bot_msg}) # Add the current message messages.append({"role": "user", "content": message}) try: response = "" for chunk in self.client.chat_completion( messages, max_tokens=max_tokens, stream=True, temperature=temperature, top_p=top_p, ): token = chunk.choices[0].delta.content or "" response += token return response except Exception as e: logger.error(f"Error generating response: {e}") return f"抱歉,发生了错误: {str(e)}" def create_interface(self) -> gr.Blocks: """Create and configure the chat interface.""" # Custom CSS for a modern look custom_css = """ .chatbot .message { border-radius: 12px; margin: 8px; padding: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.12); } .chatbot .user-message { background-color: #e3f2fd; border-left: 4px solid #2196F3; } .chatbot .bot-message { background-color: #f5f5f5; border-left: 4px solid #9e9e9e; } .gr-button { border-radius: 8px; padding: 8px 16px; transition: all 0.3s ease; } .gr-button:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.15); } .container { max-width: 900px; margin: 0 auto; } """ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as interface: gr.Markdown("# 喵哥Google-Gemma-3尝鲜版") gr.Markdown("与Google Gemma 3 27B模型互动,可自定义参数。") with gr.Row(): with gr.Column(scale=4): chatbot = gr.Chatbot( label="Gemma Chat", avatar_images=("./user.png", "./botge.png"), height=500, show_copy_button=True, elem_classes="chatbox" ) with gr.Row(): with gr.Column(scale=8): msg = gr.Textbox( show_label=False, placeholder="在这里输入您的消息...", container=False, lines=2 ) with gr.Column(scale=1, min_width=70): submit_btn = gr.Button("发送", variant="primary") with gr.Row(): clear_btn = gr.Button("清空对话", variant="secondary") example_btn = gr.Button("加载示例", variant="secondary") with gr.Column(scale=2): with gr.Accordion("聊天设置", open=True): system_msg = gr.Textbox( value=ChatConfig.DEFAULT_SYSTEM_MSG, label="系统提示词", lines=3, placeholder="输入系统提示词..." ) with gr.Accordion("高级参数", open=False): max_tokens = gr.Slider( minimum=1, maximum=8192, value=ChatConfig.DEFAULT_MAX_TOKENS, step=1, label="最大标记数", info="控制回复长度" ) temperature = gr.Slider( minimum=0.1, maximum=1.0, value=ChatConfig.DEFAULT_TEMP, step=0.1, label="温度", info="控制随机性" ) top_p = gr.Slider( minimum=0.1, maximum=1.0, value=ChatConfig.DEFAULT_TOP_P, step=0.05, label="Top-P", info="控制多样性" ) with gr.Accordion("示例问题", open=False): gr.Examples( examples=[ ["讲一讲人工智能的最新进展"], ["写一个关于机器人发现情感的短篇故事"], ["向10岁的孩子解释量子计算"] ], inputs=msg ) with gr.Accordion("模型信息", open=False): gr.Markdown(f""" - **模型**: {ChatConfig.MODEL} - **提供商**: Hugging Face - **描述**: Gemma 3是Google推出的先进开源大语言模型。 """) # Define chatbot functions with correct input/output format def add_text(history, text): history = history + [(text, None)] return history, "" def bot_response(history, system_message, max_tokens, temperature, top_p): if history and history[-1][1] is None: user_message = history[-1][0] # Remove the last incomplete message pair history_for_model = history[:-1] # Generate response bot_message = self.generate_response( user_message, history_for_model, system_message, max_tokens, temperature, top_p ) # Update the history with the complete message pair history[-1] = (user_message, bot_message) return history def load_example(): return [("介绍一下人工智能研究中最有趣的发展", None)] # Set up event handlers submit_click = submit_btn.click( add_text, [chatbot, msg], [chatbot, msg], queue=False ).then( bot_response, [chatbot, system_msg, max_tokens, temperature, top_p], chatbot ) # Submit when pressing Enter msg.submit( add_text, [chatbot, msg], [chatbot, msg], queue=False ).then( bot_response, [chatbot, system_msg, max_tokens, temperature, top_p], chatbot ) # Clear chat button clear_btn.click(lambda: [], None, chatbot) # Example button example_btn.click(load_example, None, chatbot) return interface def main(): """Main function to launch the application.""" try: app = ChatApp() interface = app.create_interface() interface.launch( server_name="0.0.0.0", server_port=7860, share=False, show_api=False, debug=True, show_error=True ) except Exception as e: logger.critical(f"Failed to launch application: {e}") print(f"错误: {e}") if __name__ == "__main__": main()