File size: 5,757 Bytes
ab76d2a 57cac61 034dd7d ab76d2a 476eb45 ab76d2a 476eb45 57cac61 034dd7d 476eb45 ab76d2a ce45729 ab76d2a 57cac61 ce45729 57cac61 ff147bb ab76d2a ce45729 57cac61 ab76d2a 034dd7d 45e2ada 2b717f1 41ad8f7 6768a50 1f1385b 6768a50 1f1385b 41ad8f7 45e2ada 41ad8f7 6768a50 c5dc144 41ad8f7 2b717f1 41ad8f7 f0643ac 034dd7d 41ad8f7 417d37b 41ad8f7 417d37b 41ad8f7 417d37b 45e2ada 417d37b 6cd0f07 476eb45 41ad8f7 810081f 6768a50 810081f 6768a50 810081f 6768a50 034dd7d 476eb45 810081f 476eb45 41ad8f7 fac1a49 41ad8f7 6768a50 810081f 6768a50 c5dc144 fac1a49 41ad8f7 6768a50 810081f 6768a50 476eb45 fac1a49 034dd7d 6768a50 a236245 c5dc144 034dd7d 6768a50 a236245 476eb45 fac1a49 810081f fac1a49 476eb45 034dd7d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# coding: utf-8
# Author: Du Mingzhe (dumingzhex@gmail.com)
# Date: 2025-12-21
import os
import json
import random
import datetime
import gradio as gr
import pandas as pd
from pathlib import Path
from huggingface_hub import CommitScheduler
from huggingface_hub import InferenceClient
HF_TOKEN = os.getenv("HF_TOKEN")
# Model configuration - these should match the models launched by launch_models.py
MODELS = {
"Local-Model-00500": "http://localhost:9000/v1",
"Local-Model-01000": "http://localhost:9001/v1",
"Local-Model-01500": "http://localhost:9002/v1",
"Local-Model-02000": "http://localhost:9003/v1",
"Local-Model-02500": "http://localhost:9004/v1",
"Local-Model-03000": "http://localhost:9005/v1",
"Local-Model-03500": "http://localhost:9006/v1",
}
DATA_DIR = Path("logs")
DATA_DIR.mkdir(exist_ok=True)
FEEDBACK_FILE = DATA_DIR / "feedback.jsonl"
scheduler = CommitScheduler(
repo_id="Elfsong/arena_feedback",
repo_type="dataset",
folder_path=DATA_DIR,
every=5, # Sync every 5 minutes
)
def save_feedback(model_name, history, feedback_data: gr.LikeData):
new_entry = {
"timestamp": datetime.datetime.now().isoformat(),
"model_name": model_name,
"message_index": feedback_data.index,
"vote": feedback_data.value,
"is_liked": feedback_data.liked,
"conversation": history
}
with open(FEEDBACK_FILE, "a", encoding="utf-8") as f:
f.write(json.dumps(new_entry, ensure_ascii=False) + "\n")
print(f"Feedback logged for {model_name}")
def bot_response(user_message, history, model_name, system_message, thinking_mode, max_tokens, temperature, top_p, seed_val):
if not user_message or user_message.strip() == "":
yield history, ""
return
token = HF_TOKEN
if model_name.startswith("Local-"):
local_endpoint = MODELS.get(model_name)
client = InferenceClient(base_url=local_endpoint, token="vllm-token")
else:
client = InferenceClient(token=token, model=model_name)
history.append({"role": "user", "content": user_message})
history.append({"role": "assistant", "content": ""})
api_messages = [{"role": "system", "content": system_message + "/set think" if thinking_mode else "/set nothink"}] + history[:-1]
try:
stream = client.chat_completion(
api_messages,
max_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
model=model_name,
seed=seed_val,
)
response_text = ""
for chunk in stream:
if not chunk.choices or len(chunk.choices) == 0:
continue
token_content = chunk.choices[0].delta.content
if token_content is not None:
response_text += token_content
history[-1]["content"] = response_text
# Continuously yield update UI, while keeping input box unavailable to prevent double clicks
yield history, gr.update(interactive=False)
except Exception as e:
# If error, display error message in assistant dialog
history[-1]["content"] = f"**Error:** {str(e)}"
# --- Final Yield: Restore input box availability and clear content ---
yield history, gr.update(value="", interactive=True)
with gr.Blocks() as demo:
with gr.Sidebar():
gr.Markdown("## Configuration")
# gr.LoginButton()
system_msg = gr.Textbox(value="You are a helpful assistant.", label="System Prompt")
thinking_mode = gr.Checkbox(value=False, label="Thinking Mode")
max_t = gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max Tokens")
temp = gr.Slider(minimum=0.0, maximum=2.0, value=0.0, step=0.05, label="Temperature")
top_p_val = gr.Slider(minimum=0.0, maximum=1.0, value=1.0, step=0.05, label="Top-p")
seed_val = gr.Slider(minimum=-1, maximum=4294967295, value=random.randint(0, 4294967295), step=1, label="Seed")
gr.Markdown("# ⚔️ Chatbot Arena")
with gr.Row():
# --- Model A ---
with gr.Column():
model_a_name = gr.Dropdown(list(MODELS.keys()), label="Model A", value=list(MODELS.keys())[0])
chatbot_a = gr.Chatbot(label="Model A Output")
msg_a = gr.Textbox(placeholder="Send message to Model A...", label="Model A Input")
btn_a = gr.Button("Send to Model A")
# --- Model B ---
with gr.Column():
model_b_name = gr.Dropdown(list(MODELS.keys()), label="Model B", value=list(MODELS.keys())[-1])
chatbot_b = gr.Chatbot(label="Model B Output")
msg_b = gr.Textbox(placeholder="Send message to Model B...", label="Model B Input")
btn_b = gr.Button("Send to Model B")
# --- Bind Events ---
a_inputs = [msg_a, chatbot_a, model_a_name, system_msg, thinking_mode, max_t, temp, top_p_val, seed_val]
msg_a.submit(bot_response, a_inputs, [chatbot_a, msg_a])
btn_a.click(bot_response, a_inputs, [chatbot_a, msg_a])
chatbot_a.like(save_feedback, [model_a_name, chatbot_a], None)
b_inputs = [msg_b, chatbot_b, model_b_name, system_msg, thinking_mode, max_t, temp, top_p_val, seed_val]
msg_b.submit(bot_response, b_inputs, [chatbot_b, msg_b])
btn_b.click(bot_response, b_inputs, [chatbot_b, msg_b])
chatbot_b.like(save_feedback, [model_b_name, chatbot_b], None)
def clear_chats():
return [], []
gr.Button("🗑️ Clear Chats").click(
fn=clear_chats,
inputs=None,
outputs=[chatbot_a, chatbot_b]
)
if __name__ == "__main__":
demo.launch(share=True)
|