zzc0208's picture
Upload 2 files
39640b5 verified
# ruff: noqa
import random
import requests
import io
import gradio as gr
import pandas as pd
from PIL import Image
from useapi import *
from utils import *
def set_interface_language(lang):
if lang == "Chinese":
return {
"title": "# LLM角色扮演竞技场:在角色扮演场景中评估LLMs的表现\n\n## 点赞❤️这个Space,下次还能找到!",
"intro": """
## 📜 规则
#### · 与两个匿名的模型(例如 Claude, Gemini, Llama )同时进行角色扮演(他们会成为一个相同的角色),投票选出更好的那个
#### · 你可以一直对话直到选出赢家(单轮对话上限是5轮)
#### · 想要开始对话,您需要先在"选择角色"中选择一个角色,之后您需要在"选择时刻"中选择一个时刻,时刻是给角色选一个场景和开场白,这样可以与角色在想要的场景中进行对话。
### [角色来自Rubii.ai, 想要和角色进行更长久的角色扮演?来Rubii.ai吧。](https://rubii.ai/)
### [在线免费语音合成以及声音克隆](https://huggingface.co/spaces/YoMioAI/Free-Zero-shot-TTS-by-GSV-Infer-Engine)
""",
"avatar_label": "角色图片",
"char_choice_label": "选择角色",
"preset_prompt_label": "选择时刻",
"refresh_button": "刷新角色列表",
"bio_label": "输入你的自设",
"bio_placeholder": "我的名字叫Rubii",
"chatbox1_label": "Model 1 的答复",
"chatbox2_label": "Model 2 的答复",
"user_input_placeholder": "在此输入对话",
"battle_button": "发送",
"score_instruction": "在获得答复后可使用以下四个按钮对本轮对话打分",
"model1win_button": "Model 1 效果更好",
"model2win_button": "Model 2 效果更好",
"tie_button": "效果一样好",
"bothbad_button": "效果都不好",
"result_placeholder": "结果: ",
"refresh_chat_button": "刷新对话",
"ranking_tab": "🏆 模型排行",
"model_name_header": "模型名称",
"contest_count_header": "参赛次数",
"win_rate_header": "模型胜率",
"random_model": "⚔️ 随机模型",
"select_language": "选择语言(语言很重要,选择语言决定了角色扮演中AI用的语言)",
"select_language2": "选择语言",
"char_choice_label": "选择角色",
"selected_char_label": "当前选择的角色",
"contant": """
## 联系我们
### [技术讨论,或有任何问题,或是对LLM角色扮演感兴趣,欢迎加入我们的Discord](https://discord.gg/DyECTyqhkC)
### 我们正在积极寻求更多模型愿意参与我们排行榜,
### 我们也在寻求合作,如果您有意的话,欢迎请联系我们。**Email:** [[email protected]](mailto:[email protected])
## 服务条款
### 用户在使用服务之前需同意以下条款:
### 该服务为研究预览版。它仅提供有限的安全措施,可能会生成冒犯性内容。不得将该服务用于任何非法、有害、暴力、种族主义或性相关的目的。请勿上传任何私人信息。该服务会收集用户的对话数据,包括文字和图像,并保留在创作共用署名(CC-BY)或类似许可证下分发这些数据的权利。
""",
}
elif lang == "English":
return {
"title": "# Roleplay LLM Arena: Benchmarking LLMs in the Roleplay Scenario\n\n## Like❤️ this Space, you can find it next time!",
"intro": """
## 📜 Rules
#### · Engage in roleplay with two anonymous models (e.g., Claude, Gemini, Llama) simultaneously, as they take on the same character. Vote for the one that performs better.
#### · You can continue the conversation until you select a winner (the maximum number of dialogue rounds per session is 5).
#### · To start the comparison, you need to first select a character in "Choose Character." Then, you need to select a "Moment" in "Choose Moment." A moment is used to set a scene and opening line for the character, allowing you to converse with the character in the desired scenario.
### [Characters are from Rubii.ai. Want to roleplay with characters for a longer time? Come to Rubii.ai.](https://rubii.ai/)
### [Online free voice synthesis and voice cloning](https://huggingface.co/spaces/YoMioAI/Free-Zero-shot-TTS-by-GSV-Infer-Engine)
""",
"avatar_label": "Character Image",
"char_choice_label": "Select Character",
"preset_prompt_label": "Select Moment",
"refresh_button": "Refresh Character List",
"bio_label": "Enter your bio",
"bio_placeholder": "My name is Rubii.",
"chatbox1_label": "Model 1's Response",
"chatbox2_label": "Model 2's Response",
"user_input_placeholder": "Enter conversation here",
"battle_button": "Send",
"score_instruction": "Use the following four buttons to score this round after receiving the response",
"model1win_button": "Model 1 is better",
"model2win_button": "Model 2 is better",
"tie_button": "Both are equally good",
"bothbad_button": "Both are bad",
"result_placeholder": "Result: ",
"refresh_chat_button": "Refresh Conversation",
"ranking_tab": "🏆 Model Ranking",
"model_name_header": "Model Name",
"contest_count_header": "Contest Count",
"win_rate_header": "Win Rate",
"random_model": "⚔️ Random Model",
"select_language": "Select a language (Language is important; the choice of language determines the language the AI will use in the roleplay)",
"select_language2": "Select a language",
"char_choice_label": "Select Character",
"selected_char_label": "Currently Selected Character",
"contant": """
## Contact Us
### [Technical discussion, or any questions, or if you are interested in LLM roleplay, welcome to join our Discord](https://discord.gg/DyECTyqhkC)
### We are actively seeking more models willing to participate in our leaderboard.
### We are also looking for collaboration opportunities. If you are interested, please contact us. **Email:** [[email protected]](mailto:[email protected]).
## Terms of Service
### Users must agree to the following terms before using the service:
### This service is a research preview. It provides limited safety measures and may generate offensive content. The service should not be used for any illegal, harmful, violent, racist, or sexually related purposes. Please do not upload any personal information. The service collects user conversation data, including text and images, and reserves the right to distribute this data under Creative Commons Attribution (CC-BY) or similar licenses.
""",
}
elif lang == "Japanese":
return {
"title": "# LLMロールプレイアリーナ:ロールプレイシナリオでのLLMのパフォーマンスを評価\n\n## Like❤️this Space!",
"intro": """
## 📜 ルール
#### · 2つの匿名モデル(例: Claude, Gemini, Llama)と同時にロールプレイを行い(彼らは同じキャラクターになります)、より良い方に投票してください。
#### · 勝者が決まるまで会話を続けることができます(1ターンあたりの会話の上限は5ターンです)。
#### · 会話を始めるには、まず「キャラクターを選択」でキャラクターを選択し、「時刻を選択」でシーンとオープニングを選択してください。これにより、キャラクターと望むシーンで会話ができます。
### [キャラクターはRubii.aiから来ています。キャラクターとのロールプレイをより長く続けたい場合は、Rubii.aiに来てください。](https://rubii.ai/)
### [オンライン無料音声合成と声のクローン](https://huggingface.co/spaces/YoMioAI/Free-Zero-shot-TTS-by-GSV-Infer-Engine)
""",
"avatar_label": "キャラクター画像",
"char_choice_label": "キャラクターを選択",
"preset_prompt_label": "時刻を選択",
"refresh_button": "キャラクターリストを更新",
"bio_label": "あなたのプロフィールを入力",
"bio_placeholder": "私の名前はRubii",
"chatbox1_label": "Model 1 の応答",
"chatbox2_label": "Model 2 の応答",
"user_input_placeholder": "ここにメッセージを入力",
"battle_button": "送信",
"score_instruction": "応答を受け取った後、以下の4つのボタンでこのターンの会話を評価できます",
"model1win_button": "Model 1 がより良い",
"model2win_button": "Model 2 がより良い",
"tie_button": "同じくらい良い",
"bothbad_button": "どちらも良くない",
"result_placeholder": "結果: ",
"refresh_chat_button": "会話を更新",
"ranking_tab": "🏆 モデルランキング",
"model_name_header": "モデル名",
"contest_count_header": "参加回数",
"win_rate_header": "モデル勝率",
"random_model": "⚔️ ランダムモデル",
"select_language": "言語を選択してください(言語は非常に重要です。選択した言語はロールプレイでAIが使用する言語を決定します)",
"select_language2": "言語を選択してください",
"char_choice_label": "キャラクターを選択",
"selected_char_label": "現在選択されているキャラクター",
"contant": """
## お問い合わせ
### [技術的な議論、またはご質問、またはLLMロールプレイに興味がある場合は、私たちのDiscordにご参加ください。](https://discord.gg/DyECTyqhkC)
### 私たちは、リーダーボードに参加したいモデルを積極的に探しています。
### 私たちはコラボレーションの機会も探しています。興味がある方は、ぜひご連絡ください。**メール:** [[email protected]](mailto:[email protected])。
## 利用規約
### サービスを利用する前に、ユーザーは以下の規約に同意する必要があります:
### 本サービスは研究プレビュー版です。限られた安全対策を提供しており、攻撃的な内容を生成する可能性があります。本サービスを違法、有害、暴力的、人種差別的、または性的な目的で使用しないでください。個人情報のアップロードは避けてください。本サービスはユーザーの会話データ(テキストおよび画像)を収集し、クリエイティブ・コモンズ・ライセンス(CC-BY)または同様のライセンスの下でこれらのデータを配布する権利を保有します。
""",
}
elif lang == "Korean":
return {
"title": "# LLM 역할 수행 경기장: 역할 수행 시나리오에서 LLM의 성능 평가\n\n## Like❤️this Space!",
"intro": """
## 📜 규칙
#### · 두 개의 익명의 모델(예: Claude, Gemini, Llama)과 동시에 역할 수행을 진행하고, 더 나은 모델을 선택하세요.
#### · 우승자를 선택할 때까지 계속 대화를 진행할 수 있습니다(최대 5라운드).
#### · 대화를 시작하려면 먼저 "캐릭터 선택"에서 캐릭터를 선택해야 하며, 그 다음 "시나리오 선택"에서 시나리오를 선택해야 합니다. 시나리오는 캐릭터에게 장면과 오프닝을 제공하여 원하는 시나리오에서 대화를 진행할 수 있게 합니다.
### [캐릭터는 Rubii.ai에서 오고 있습니다. 캐릭터와 더 긴 역할 수행을 하고 싶으신가요? Rubii.ai로 오세요.](https://rubii.ai/)
### [온라인 무료 음성 합성 및 음성 클론](https://huggingface.co/spaces/YoMioAI/Free-Zero-shot-TTS-by-GSV-Infer-Engine)
""",
"avatar_label": "캐릭터 이미지",
"char_choice_label": "캐릭터 선택",
"preset_prompt_label": "시나리오 선택",
"refresh_button": "캐릭터 목록 새로고침",
"bio_label": "자신의 설정 입력",
"bio_placeholder": "제 이름은 루비입니다.",
"chatbox1_label": "Model 1의 응답",
"chatbox2_label": "Model 2의 응답",
"user_input_placeholder": "여기에 대화 입력",
"battle_button": "보내기",
"score_instruction": "응답을 받은 후 아래 네 개의 버튼을 사용하여 이번 라운드를 평가할 수 있습니다.",
"model1win_button": "Model 1이 더 나음",
"model2win_button": "Model 2가 더 나음",
"tie_button": "똑같이 좋음",
"bothbad_button": "둘 다 별로임",
"result_placeholder": "결과: ",
"refresh_chat_button": "대화 새로고침",
"ranking_tab": "🏆 모델 순위",
"model_name_header": "모델 이름",
"contest_count_header": "참가 횟수",
"win_rate_header": "모델 승률",
"random_model": "⚔️ 랜덤 모델",
"select_language": "언어를 선택하세요 (언어는 매우 중요합니다. 선택한 언어는 역할 놀이에서 AI가 사용할 언어를 결정합니다)",
"select_language2": "언어를 선택하세요",
"char_choice_label": "캐릭터 선택",
"selected_char_label": "현재 선택된 캐릭터",
"contant": """
## 문의하기
### [기술적인 논의, 또는 문의사항, 또는 LLM 역할 수행에 관심이 있으실 경우, 우리의 Discord에 참여해 주세요.](https://discord.gg/DyECTyqhkC)
### 우리는 리더보드에 참여할 의향이 있는 모델을 적극적으로 찾고 있습니다.
### 우리는 또한 협력 기회를 모색하고 있습니다. 관심이 있으시면 연락해 주세요. **이메일:** [[email protected]](mailto:[email protected])
## 이용 약관
### 사용자는 서비스를 사용하기 전에 다음 약관에 동의해야 합니다:
### 이 서비스는 연구 미리보기 버전입니다. 제한된 안전 조치를 제공하며, 불쾌한 콘텐츠를 생성할 수 있습니다. 이 서비스를 불법적, 해롭거나, 폭력적이거나, 인종차별적이거나, 성적으로 관련된 목적으로 사용하지 마십시오. 개인 정보를 업로드하지 마십시오. 이 서비스는 사용자 대화 데이터(텍스트 및 이미지)를 수집하며, 크리에이티브 커먼즈 저작자 표시(CC-BY) 또는 유사한 라이선스 하에 이 데이터를 배포할 권리를 보유합니다.
""",
}
async def run_battle(
user_input,
chatbox1,
chatbox2,
session_id1,
session_id2,
chat_count,
bio,
preset_prompt,
selected_models,
):
if chat_count >= 5:
chatbox1 = chatbox1 + [
(
"您已经在此体验了多次模型效果了,前往 rubii.ai 继续对话吧",
"您已经在此体验了多次模型效果了,前往 rubii.ai 继续对话吧",
)
]
chatbox2 = chatbox2 + [
(
"您已经在此体验了多次模型效果了,前往 rubii.ai 继续对话吧",
"您已经在此体验了多次模型效果了,前往 rubii.ai 继续对话吧",
)
]
yield (
chatbox1,
chatbox2,
selected_models[0],
selected_models[1],
gr.update(interactive=True),
gr.update(interactive=True),
gr.update(interactive=True),
gr.update(interactive=True),
session_id1,
session_id2,
chat_count,
gr.update(interactive=False),
gr.update(value=""),
)
return
chat_count += 1
chatbox1 = chatbox1 + [(user_input, "")]
chatbox2 = chatbox2 + [(user_input, "")]
yield (
chatbox1,
chatbox2,
selected_models[0],
selected_models[1],
gr.update(interactive=True),
gr.update(interactive=True),
gr.update(interactive=True),
gr.update(interactive=True),
session_id1,
session_id2,
chat_count,
gr.update(interactive=True),
gr.update(value=""),
)
response1 = ""
response2 = ""
async for chunk in combine_streams(
user_input,
user_input,
selected_models[0],
selected_models[1],
preset_prompt["_id"],
preset_prompt["_id"],
session_id1,
session_id2,
bio,
bio,
language,
):
if "requestA_header" in chunk:
session_id1 = chunk["requestA_header"]["x-session-id"]
if "requestB_header" in chunk:
session_id2 = chunk["requestB_header"]["x-session-id"]
if "requestA" in chunk:
response1 += chunk["requestA"]
if "requestB" in chunk:
response2 += chunk["requestB"]
chatbox1 = chatbox1[:-1] + [(user_input, response1)]
chatbox2 = chatbox2[:-1] + [(user_input, response2)]
yield (
chatbox1,
chatbox2,
selected_models[0],
selected_models[1],
gr.update(interactive=True),
gr.update(interactive=True),
gr.update(interactive=True),
gr.update(interactive=True),
session_id1,
session_id2,
chat_count,
gr.update(interactive=True),
gr.update(value=""),
)
def select_winner(model1_name, model2_name, state, turn, anony, Language):
if Language == "Chinese":
if state == "Model 1":
result = f"感谢您的投票,你选择了 {state} - {model1_name} 效果更好,{model2_name} 效果更差,刷新以进行下一轮测试"
elif state == "Model 2":
result = f"感谢您的投票,你选择了 {state} - {model2_name} 效果更好,{model1_name} 效果更差,刷新以进行下一轮测试"
elif state == "tie":
result = f"感谢您的投票,你选择了 {model1_name}{model2_name} 效果都很好,刷新以进行下一轮测试"
elif state == "bothbad":
result = f"感谢您的投票,你选择了 {model1_name}{model2_name} 效果都不好,刷新以进行下一轮测试"
elif Language == "English":
if state == "Model 1":
result = f"Thank you for your vote. You chose {state} - {model1_name} performed better, {model2_name} performed worse. Refresh to proceed to the next round of testing."
elif state == "Model 2":
result = f"Thank you for your vote. You chose {state} - {model2_name} performed better, {model1_name} performed worse. Refresh to proceed to the next round of testing."
elif state == "tie":
result = f"Thank you for your vote. You selected that both {model1_name} and {model2_name} performed well. Refresh to proceed to the next round of testing."
elif state == "bothbad":
result = f"Thank you for your vote. You chose that both {model1_name} and {model2_name} performed poorly. Refresh to proceed to the next round of testing."
elif Language == "Japanese":
if state == "Model 1":
result = f"投票ありがとうございます。あなたは {state} - {model1_name} の方が良く、{model2_name} は劣っていると選びました。次のテストを行うにはリフレッシュしてください。"
elif state == "Model 2":
result = f"投票ありがとうございます。あなたは {state} - {model2_name} の方が良く、{model1_name} は劣っていると選びました。次のテストを行うにはリフレッシュしてください。"
elif state == "tie":
result = f"投票ありがとうございます。あなたは {model1_name}{model2_name} の両方が良いと選びました。次のテストを行うにはリフレッシュしてください。"
elif state == "bothbad":
result = f"投票ありがとうございます。あなたは {model1_name}{model2_name} の両方が良くないと選びました。次のテストを行うにはリフレッシュしてください。"
elif Language == "Korean":
if state == "Model 1":
result = f"투표해 주셔서 감사합니다. {state} - {model1_name} 이(가) 더 좋다고 선택하셨습니다. {model2_name} 이(가) 더 나쁩니다. 다음 테스트를 위해 새로 고침하세요."
elif state == "Model 2":
result = f"투표해 주셔서 감사합니다. {state} - {model2_name} 이(가) 더 좋다고 선택하셨습니다. {model1_name} 이(가) 더 나쁩니다. 다음 테스트를 위해 새로 고침하세요."
elif state == "tie":
result = f"투표해 주셔서 감사합니다. {model1_name} 과(와) {model2_name} 둘 다 좋다고 선택하셨습니다. 다음 테스트를 위해 새로 고침하세요."
elif state == "bothbad":
result = f"투표해 주셔서 감사합니다. {model1_name} 과(와) {model2_name} 둘 다 나쁘다고 선택하셨습니다. 다음 테스트를 위해 새로 고침하세요."
update_model_stats(model1_name, model2_name, state, turn, anony, Language)
# 返回结果并让打分按钮置灰,同时重置chat_count
return (
result,
gr.update(interactive=False),
gr.update(interactive=False),
gr.update(interactive=False),
gr.update(interactive=False),
gr.update(interactive=False),
0 # 重置chat_count为0
)
async def get_preset_prompts(char_id, language):
recommand_data = await recommand(char_id, language)
return [(item["name"], item) for item in recommand_data]
async def update_preset_prompt(char_id, language):
if not char_id:
return gr.update(), None
try:
preset_prompts = await get_preset_prompts(char_id, language)
except TypeError:
return gr.update(), None
avatar_image_url = id_to_avatar(char_id)
response = requests.get(avatar_image_url)
image = Image.open(io.BytesIO(response.content))
resized_image = image.resize((256, 256))
# 直接在这里设置 preset_prompt 的默认值为第一个选项
if preset_prompts:
preset_prompt_update = gr.update(choices=preset_prompts, value=preset_prompts[0][1])
else:
preset_prompt_update = gr.update(choices=[], value=None)
return preset_prompt_update, resized_image
def update_chat_and_avatar(moment):
opening = [(None, moment["opening"])]
selected_models = random.sample(models, 2)
while selected_models[0] == selected_models[1]:
selected_models = random.sample(models, 2)
print(selected_models)
# Resize the image
response = requests.get(moment["image_url"])
img = Image.open(io.BytesIO(response.content))
# Calculate new width to maintain aspect ratio
aspect_ratio = img.width / img.height
new_height = 720
new_width = int(new_height * aspect_ratio)
# Resize image
resized_img = img.resize((new_width, new_height))
return opening, opening, resized_img, "", "", selected_models
def refresh_data(language):
characters = recommand_character(language)
characters = [(item["name"], item["_id"]) for item in characters]
return gr.update(choices=characters)
def refresh_chat(moment):
chatbox1, chatbox2, avatar_image, session_id1, session_id2, selected_models = (
update_chat_and_avatar(moment)
)
return (
chatbox1,
chatbox2,
avatar_image,
session_id1,
session_id2,
selected_models,
gr.update(interactive=False),
gr.update(interactive=False),
gr.update(interactive=False),
gr.update(interactive=False),
gr.update(interactive=True),
gr.update(value="结果:"),
gr.update(value=0),
)
def update_language(lang):
print("update_language", lang)
text = set_interface_language(lang)
gallery_data, characters = refresh_character_gallery(lang)
return (
text["title"],
text["intro"],
None,
gr.update(label=text["char_choice_label"], value=gallery_data),
gr.update(label=text["preset_prompt_label"], choices=[], value=None),
gr.update(value=text["refresh_button"]),
gr.update(placeholder=text["bio_placeholder"], label=text["bio_label"]),
gr.update(label=text["chatbox1_label"]),
gr.update(label=text["chatbox2_label"]),
gr.update(placeholder=text["user_input_placeholder"]),
gr.update(value=text["battle_button"]),
gr.update(placeholder=text["result_placeholder"]),
gr.update(value=text["refresh_chat_button"]),
gr.update(value=text["model1win_button"]),
gr.update(value=text["model2win_button"]),
gr.update(value=text["tie_button"]),
gr.update(value=text["bothbad_button"]),
gr.update(label=text["random_model"]),
gr.update(label=text["ranking_tab"]),
gr.update(label=text["select_language"], value=lang),
text["score_instruction"],
text["contant"],
gr.update(value=lang, label=text["select_language2"]),
characters, # 更新 characters_state
gr.update(value=None), # 重置 selected_char_name
gr.update(value=None), # 重置 selected_char_id
)
def auto_i18n(request: gr.Request):
print(request.headers["Accept-Language"])
if request.headers["Accept-Language"].split(",")[0].lower().startswith("zh"):
language = "Chinese"
elif request.headers["Accept-Language"].split(",")[0].lower().startswith("en"):
language = "English"
elif request.headers["Accept-Language"].split(",")[0].lower().startswith("ja"):
language = "Japanese"
elif request.headers["Accept-Language"].split(",")[0].lower().startswith("ko"):
language = "Korean"
else:
language = "Chinese"
return language
def init_and_update(request: gr.Request):
detected_lang = auto_i18n(request)
text = set_interface_language(detected_lang)
gallery_data, characters = refresh_character_gallery(detected_lang)
return [
detected_lang,
text["title"],
text["intro"],
None,
gr.update(label=text["char_choice_label"], value=gallery_data),
gr.update(label=text["preset_prompt_label"]),
gr.update(value=text["refresh_button"]),
gr.update(placeholder=text["bio_placeholder"], label=text["bio_label"]),
gr.update(label=text["chatbox1_label"]),
gr.update(label=text["chatbox2_label"]),
gr.update(placeholder=text["user_input_placeholder"]),
gr.update(value=text["battle_button"]),
gr.update(placeholder=text["result_placeholder"]),
gr.update(value=text["refresh_chat_button"]),
gr.update(value=text["model1win_button"]),
gr.update(value=text["model2win_button"]),
gr.update(value=text["tie_button"]),
gr.update(value=text["bothbad_button"]),
gr.update(label=text["random_model"]),
gr.update(label=text["ranking_tab"]),
gr.update(label=text["select_language"], value=detected_lang),
text["score_instruction"],
text["contant"],
characters # 新增的输出
]
def passive_language_change(lang):
return gr.update(value=lang)
async def get_character_gallery(language):
characters = recommand_character(language)
return [[id_to_avatar(char['_id']), char['name']] for char in characters]
def update_character_gallery(language):
characters = get_character_gallery(language)
return gr.update(value=characters)
def refresh_character_gallery(language):
characters = recommand_character(language)
gallery_data = [[id_to_avatar(char['_id']), char['name']] for char in characters]
return gallery_data, characters
def select_character(evt: gr.SelectData, characters):
index = evt.index
print(f"Event triggered. Index: {index}")
if index >= len(characters):
return None, None
selected_char = characters[index]
selected_char_name = selected_char['name']
selected_char_id = selected_char['_id']
print(f"Selected character: {selected_char_name}, ID: {selected_char_id}")
return selected_char_name, selected_char_id
with gr.Blocks() as demo:
characters_state = gr.State(value=[])
# load 的时候就会刷新掉default_language
default_language = gr.State("Chinese")
language = "Chinese"
characters = recommand_character(language)
characters = [(item["name"], item["_id"]) for item in characters]
text = set_interface_language(default_language.value)
models = get_models()
with gr.Tab(text["random_model"]) as random_model_tab:
with gr.Column():
title = gr.Markdown(f"{text['title']}")
with gr.Column(scale=10):
intro = gr.Markdown(f"{text['intro']}")
with gr.Column(scale=1):
language = gr.Radio(
["English", "Chinese", "Japanese", "Korean"],
label=text["select_language"],
value=default_language.value,
)
with gr.Row():
with gr.Column(scale=4):
char_gallery = gr.Gallery(
label=text["char_choice_label"],
show_label=True,
elem_id="character_gallery",
columns=[5],
object_fit="contain",
height="auto",
interactive=True,
allow_preview=False
)
selected_char_name = gr.Textbox(
label=text["selected_char_label"],
interactive=False
)
selected_char_id = gr.Textbox(
visible=False
)
refresh_button = gr.Button(
text["refresh_button"], scale=1, variant="primary"
)
with gr.Column(scale=6):
preset_prompt = gr.Dropdown(
label=text["preset_prompt_label"], scale=3
)
avatar_image = gr.Image(scale=1, label=text["avatar_label"])
with gr.Row():
bio = gr.Textbox(
show_label=True,
label=text["bio_label"],
placeholder=text["bio_placeholder"]
)
with gr.Row():
chatbox1 = gr.Chatbot(label=text["chatbox1_label"])
chatbox2 = gr.Chatbot(label=text["chatbox2_label"])
with gr.Row():
user_input = gr.Textbox(
placeholder=text["user_input_placeholder"], scale=3, show_label=False
)
battle_button = gr.Button(text["battle_button"], scale=1, variant="primary")
with gr.Column():
score_instruction = gr.Markdown(f"{text['score_instruction']}")
with gr.Row():
model1win_button = gr.Button(
text["model1win_button"], variant="primary", interactive=False
)
model2win_button = gr.Button(
text["model2win_button"], variant="primary", interactive=False
)
tie_button = gr.Button(text["tie_button"], interactive=False)
bothbad_button = gr.Button(text["bothbad_button"], interactive=False)
with gr.Row():
result_output = gr.Textbox(
placeholder=text["result_placeholder"], scale=3, show_label=False
)
refresh_chat_button = gr.Button(
text["refresh_chat_button"], variant="secondary", scale=1
)
with gr.Tab(text["ranking_tab"]) as ranking_tab:
language2 = gr.Radio(
["English", "Chinese", "Japanese", "Korean"],
label=text["select_language"],
value=default_language.value,
)
gr.DataFrame(
load_dataframe,
datatype=["str", "str", "str", "str", "str"],
every=gr.Timer(10),
)
# 插入 CSS 样式,用于隐藏底部的“通过 API 使用”链接
gr.HTML("""
<style>
footer {display: none !important;}
</style>
""")
with gr.Row():
with gr.Column(scale=5):
contant = gr.Markdown(f"{text['contant']}")
with gr.Column(scale=1):
gr.Image("group.jpg")
selected_models = gr.State([])
model1_state = gr.State("")
model2_state = gr.State("")
chat_count = gr.State(0)
session_id1 = gr.State("")
session_id2 = gr.State("")
refresh_button.click(
fn=refresh_character_gallery,
inputs=[language],
outputs=[char_gallery, characters_state]
)
char_gallery.select(
fn=select_character,
inputs=[characters_state],
outputs=[selected_char_name, selected_char_id]
)
selected_char_id.change(
fn=update_preset_prompt,
inputs=[selected_char_id, language],
outputs=[preset_prompt, avatar_image],
)
refresh_chat_button.click(
fn=refresh_chat,
inputs=[preset_prompt],
outputs=[
chatbox1,
chatbox2,
avatar_image,
session_id1,
session_id2,
selected_models,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
battle_button,
result_output,
chat_count,
],
)
language.change(
fn=update_language,
inputs=language,
outputs=[
title,
intro,
avatar_image,
char_gallery,
preset_prompt,
refresh_button,
bio,
chatbox1,
chatbox2,
user_input,
battle_button,
result_output,
refresh_chat_button,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
random_model_tab,
ranking_tab,
language,
score_instruction,
contant,
language2,
characters_state, # 新增的输出
selected_char_name, # 新增的输出
selected_char_id, # 新增的输出
],
)
language2.change(
fn=passive_language_change,
inputs=language2,
outputs=language
)
char_gallery.select(
fn=select_character,
inputs=[characters_state],
outputs=[selected_char_name, selected_char_id]
)
preset_prompt.change(
fn=update_chat_and_avatar,
inputs=[preset_prompt],
outputs=[
chatbox1,
chatbox2,
avatar_image,
session_id1,
session_id2,
selected_models,
],
)
model1win_button.click(
fn=select_winner,
inputs=[
model1_state,
model2_state,
gr.State("Model 1"),
chat_count,
gr.State(True),
language,
],
outputs=[
result_output,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
battle_button,
chat_count
],
)
model2win_button.click(
fn=select_winner,
inputs=[
model1_state,
model2_state,
gr.State("Model 2"),
chat_count,
gr.State(True),
language,
],
outputs=[
result_output,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
battle_button,
chat_count
],
)
tie_button.click(
fn=select_winner,
inputs=[
model1_state,
model2_state,
gr.State("tie"),
chat_count,
gr.State(True),
language,
],
outputs=[
result_output,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
battle_button,
chat_count
],
)
bothbad_button.click(
fn=select_winner,
inputs=[
model1_state,
model2_state,
gr.State("bothbad"),
chat_count,
gr.State(True),
language,
],
outputs=[
result_output,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
battle_button,
chat_count
],
)
battle_button.click(
run_battle,
inputs=[
user_input,
chatbox1,
chatbox2,
session_id1,
session_id2,
chat_count,
bio,
preset_prompt,
selected_models,
],
outputs=[
chatbox1,
chatbox2,
model1_state,
model2_state,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
session_id1,
session_id2,
chat_count,
battle_button,
user_input,
],
)
demo.load(
init_and_update,
outputs=[
default_language,
title,
intro,
avatar_image,
char_gallery,
preset_prompt,
refresh_button,
bio,
chatbox1,
chatbox2,
user_input,
battle_button,
result_output,
refresh_chat_button,
model1win_button,
model2win_button,
tie_button,
bothbad_button,
random_model_tab,
ranking_tab,
language,
score_instruction,
contant,
characters_state # 新增的输出
],
)
if __name__ == "__main__":
demo.queue(default_concurrency_limit=8).launch(
server_name="0.0.0.0",
server_port=7860,
)