gemma-3-chat / app.py
miaoge's picture
Update app.py
7dde3dd verified
raw
history blame
9.32 kB
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
) -> Generator[str, None, None]:
"""Generate streaming responses from the model."""
if not message.strip():
yield "请输入消息。"
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
yield response
except Exception as e:
logger.error(f"Error generating response: {e}")
yield 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推出的先进开源大语言模型。
""")
# Set up event handlers
msg_and_submit = [msg, submit_btn]
submit_click = submit_btn.click(
fn=self.generate_response,
inputs=[msg, chatbot, system_msg, max_tokens, temperature, top_p],
outputs=chatbot,
api_name="chat"
)
# Submit when pressing Enter (but not when pressing Shift+Enter)
msg.submit(
fn=self.generate_response,
inputs=[msg, chatbot, system_msg, max_tokens, temperature, top_p],
outputs=chatbot,
api_name=False
)
# Clear the textbox after sending
submit_click.then(lambda: "", None, msg)
msg.submit(lambda: "", None, msg)
# Clear chat button
clear_btn.click(lambda: None, None, chatbot)
# Example button
example_btn.click(
lambda: ("介绍一下人工智能研究中最有趣的发展", []),
None,
[msg, 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()