AI-ChatBot / app.py
gzyc's picture
Update app.py
19c5734 verified
Raw
History Blame Contribute Delete
5.82 kB
import gradio as gr
import requests
import os
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# ========== 从环境变量读取密钥 ==========
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
CEREBRAS_API_KEY = os.getenv("CEREBRAS_API_KEY")
# ========== 模型定义 ==========
LOCAL_MODELS = {
"DistilGPT2 (最快)": "distilgpt2",
"DialoGPT-small (轻量)": "microsoft/DialoGPT-small",
"DialoGPT-medium (均衡)": "microsoft/DialoGPT-medium",
}
OPENROUTER_MODELS = {
"Llama 3.3 70B (免费)": "meta-llama/llama-3.3-70b-instruct:free",
"Nemotron 3 Super (免费)": "nvidia/nemotron-3-super:free",
"Qwen3 Next 80B (免费)": "qwen/qwen3-next-80b:free",
}
CEREBRAS_MODELS = {
"Llama 3.1 8B (Cerebras)": "llama3.1-8b",
}
local_model_cache = {}
def load_local_model(model_key):
if model_key in local_model_cache:
return local_model_cache[model_key]
model_id = LOCAL_MODELS[model_key]
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
local_model_cache[model_key] = (model, tokenizer)
return model, tokenizer
def is_chinese(text):
return any('\u4e00' <= c <= '\u9fff' for c in text)
def local_predict(message, model_key):
if is_chinese(message):
return "⚠️ This model only supports English input. 请使用英文。"
model, tokenizer = load_local_model(model_key)
inputs = tokenizer.encode(message + tokenizer.eos_token, return_tensors='pt')
outputs = model.generate(
inputs,
max_new_tokens=100,
do_sample=True,
temperature=0.7,
repetition_penalty=1.2,
pad_token_id=tokenizer.eos_token_id
)
reply = tokenizer.decode(outputs[0][inputs.shape[-1]:], skip_special_tokens=True)
return reply.strip() or "I'm not sure how to respond."
def openrouter_predict(message, model_name):
if not OPENROUTER_API_KEY:
return "❌ OpenRouter API key 未设置,请在 Space Secrets 中添加 OPENROUTER_API_KEY"
headers = {
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
"HTTP-Referer": "https://your-space.hf.space",
"X-Title": "AI ChatBot",
"Content-Type": "application/json"
}
payload = {
"model": model_name,
"messages": [{"role": "user", "content": message}],
"max_tokens": 500,
"temperature": 0.7
}
try:
resp = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload, timeout=60)
if resp.status_code == 200:
return resp.json()["choices"][0]["message"]["content"]
elif resp.status_code == 402:
return "⚠️ 免费额度已用完或需启用付费模型。"
else:
return f"❌ API 错误 {resp.status_code}"
except Exception as e:
return f"❌ 请求失败: {e}"
def cerebras_predict(message, model_name):
if not CEREBRAS_API_KEY:
return "❌ Cerebras API key 未设置,请在 Space Secrets 中添加 CEREBRAS_API_KEY"
headers = {
"Authorization": f"Bearer {CEREBRAS_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": model_name,
"messages": [{"role": "user", "content": message}],
"max_tokens": 500,
"temperature": 0.7
}
try:
resp = requests.post("https://api.cerebras.ai/v1/chat/completions", headers=headers, json=payload, timeout=60)
if resp.status_code == 200:
return resp.json()["choices"][0]["message"]["content"]
else:
return f"❌ Cerebras 错误 {resp.status_code}"
except Exception as e:
return f"❌ 请求失败: {e}"
def predict(message, history, backend, model_choice):
if not message.strip():
return ""
if backend == "本地 CPU 模型 (限英文)":
return local_predict(message, model_choice)
elif backend == "OpenRouter (不限语言)":
return openrouter_predict(message, model_choice)
elif backend == "Cerebras (不限语言)":
return cerebras_predict(message, model_choice)
else:
return "未知后端"
with gr.Blocks(title="多后端 AI 聊天机器人", theme=gr.themes.Soft()) as demo:
gr.Markdown("# 🧠 多后端 AI 聊天机器人")
gr.Markdown("**本地 CPU 模型**仅限英文;**OpenRouter / Cerebras** 不限语言,且质量更高。")
with gr.Row():
backend_radio = gr.Radio(
choices=["本地 CPU 模型 (限英文)", "OpenRouter (不限语言)", "Cerebras (不限语言)"],
label="选择后端",
value="本地 CPU 模型 (限英文)"
)
model_dropdown = gr.Dropdown(
choices=list(LOCAL_MODELS.keys()),
label="模型选择",
value=list(LOCAL_MODELS.keys())[2]
)
def update_model_dropdown(backend):
if backend == "本地 CPU 模型 (限英文)":
return gr.update(choices=list(LOCAL_MODELS.keys()), value=list(LOCAL_MODELS.keys())[2], visible=True)
elif backend == "OpenRouter (不限语言)":
return gr.update(choices=list(OPENROUTER_MODELS.keys()), value=list(OPENROUTER_MODELS.keys())[0], visible=True)
else:
return gr.update(choices=list(CEREBRAS_MODELS.keys()), value=list(CEREBRAS_MODELS.keys())[0], visible=True)
backend_radio.change(fn=update_model_dropdown, inputs=backend_radio, outputs=model_dropdown)
chatbot = gr.ChatInterface(
fn=predict,
additional_inputs=[backend_radio, model_dropdown],
title=None,
description="多轮对话,自动记忆上下文。"
)
demo.launch(server_port=7860)