Pendrokar commited on
Commit
fecb668
·
2 Parent(s): 51adc6d 41bd317

Merge branch 'main_sync'

Browse files
Files changed (7) hide show
  1. README.md +14 -0
  2. app/config.py +12 -2
  3. app/leaderboard.py +19 -16
  4. app/models.py +31 -0
  5. app/ui.py +3 -0
  6. app/ui_leaderboard.py +2 -2
  7. app/ui_vote.py +3 -1
README.md CHANGED
@@ -34,3 +34,17 @@ sdk_version: 5.13.0
34
 
35
  [Saved votes dataset](https://huggingface.co/datasets/Pendrokar/TTS_Arena)
36
  [TTS tracker dataset](https://huggingface.co/datasets/Pendrokar/open_tts_tracker)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  [Saved votes dataset](https://huggingface.co/datasets/Pendrokar/TTS_Arena)
36
  [TTS tracker dataset](https://huggingface.co/datasets/Pendrokar/open_tts_tracker)
37
+
38
+ # TTS Arena
39
+
40
+ The codebase for TTS Arena v2.
41
+
42
+ The TTS Arena is a Gradio app with several components. Please refer to the `app` directory for more information.
43
+
44
+ ## Running the app
45
+
46
+ ```bash
47
+ RUNNING_LOCALLY=1 python app.py
48
+ ```
49
+
50
+ You must set the `RUNNING_LOCALLY` environment variable to `1` when running the app locally. This prevents it from syncing with the database
app/config.py CHANGED
@@ -1,5 +1,11 @@
1
  import os
2
 
 
 
 
 
 
 
3
  # NOTE: Configure models in `models.py`
4
 
5
  #########################
@@ -18,7 +24,7 @@ DB_PATH = f"/data/{DB_NAME}" if os.path.isdir("/data") else DB_NAME # If /data a
18
  ROUTER_ID = "Pendrokar/xVASynth-TTS" # You should use a router space to route TTS models to avoid exposing your API keys!
19
  # ROUTER_ID = "TTS-AGI/tts-router" # You should use a router space to route TTS models to avoid exposing your API keys!
20
 
21
- SYNC_DB = True # Sync DB to HF dataset?
22
  DB_DATASET_ID = os.getenv('DATASET_ID') # HF dataset ID, can be None if not syncing
23
 
24
  SPACE_ID = os.getenv('SPACE_ID') # Don't change this! It detects if we're running in a HF Space
@@ -48,4 +54,8 @@ CITATION_TEXT = """@misc{tts-arena,
48
  year = 2024,
49
  publisher = {Hugging Face},
50
  howpublished = "\\url{https://huggingface.co/spaces/TTS-AGI/TTS-Arena}"
51
- }"""
 
 
 
 
 
1
  import os
2
 
3
+ RUNNING_LOCALLY = os.getenv('RUNNING_LOCALLY', '0').lower() in ('true', '1', 't')
4
+ if RUNNING_LOCALLY:
5
+ print("Running locally, not syncing DB to HF dataset")
6
+ else:
7
+ print("Running in HF Space, syncing DB to HF dataset")
8
+
9
  # NOTE: Configure models in `models.py`
10
 
11
  #########################
 
24
  ROUTER_ID = "Pendrokar/xVASynth-TTS" # You should use a router space to route TTS models to avoid exposing your API keys!
25
  # ROUTER_ID = "TTS-AGI/tts-router" # You should use a router space to route TTS models to avoid exposing your API keys!
26
 
27
+ SYNC_DB = not RUNNING_LOCALLY # Sync DB to HF dataset?
28
  DB_DATASET_ID = os.getenv('DATASET_ID') # HF dataset ID, can be None if not syncing
29
 
30
  SPACE_ID = os.getenv('SPACE_ID') # Don't change this! It detects if we're running in a HF Space
 
54
  year = 2024,
55
  publisher = {Hugging Face},
56
  howpublished = "\\url{https://huggingface.co/spaces/TTS-AGI/TTS-Arena}"
57
+ }"""
58
+
59
+ #- 2025/01/21: New leaderboard UI released with enhanced UI and improved performance.
60
+ NEWS = """
61
+ """
app/leaderboard.py CHANGED
@@ -21,27 +21,30 @@ def get_leaderboard(reveal_prelim = False):
21
  df['name'] = df['name'].replace(model_names)
22
  for i in range(len(df)):
23
  df.loc[i, "name"] = make_link_to_space(df['name'][i], True)
 
 
24
  df['votes'] = df['upvote'] + df['downvote']
 
25
  # df['score'] = round((df['upvote'] / df['votes']) * 100, 2) # Percentage score
26
 
27
  ## ELO SCORE
28
- df['score'] = 1200
29
- df['score_diff'] = ""
30
  for i in range(len(df)):
31
  for j in range(len(df)):
32
  if i != j:
33
  try:
34
- expected_a = 1 / (1 + 10 ** ((df['score'].iloc[j] - df['score'].iloc[i]) / 400))
35
- expected_b = 1 / (1 + 10 ** ((df['score'].iloc[i] - df['score'].iloc[j]) / 400))
36
  actual_a = df['upvote'].iloc[i] / df['votes'].iloc[i] if df['votes'].iloc[i] > 0 else 0.5
37
  actual_b = df['upvote'].iloc[j] / df['votes'].iloc[j] if df['votes'].iloc[j] > 0 else 0.5
38
- df.at[i, 'score'] += round(32 * (actual_a - expected_a))
39
- df.at[j, 'score'] += round(32 * (actual_b - expected_b))
40
  except Exception as e:
41
  print(f"Error in ELO calculation for rows {i} and {j}: {str(e)}")
42
  continue
43
- df['score'] = round(df['score'])
44
- df['score_diff'] = df['score']
45
 
46
  if (
47
  reveal_prelim == False
@@ -51,18 +54,18 @@ def get_leaderboard(reveal_prelim = False):
51
 
52
  if (reveal_prelim == False):
53
  for i in range(len(df)):
54
- score_diff = (df['score'].iloc[i] - leaderboard_df['score'].iloc[i])
55
- if (score_diff == 0):
56
  continue
57
- if (score_diff > 0):
58
  plus = '<em style="color: green; font-family: monospace">+'
59
  else:
60
  plus = '<em style="color: red; font-family: monospace">'
61
 
62
- df.at[i, 'score_diff'] = str(df['score'].iloc[i]) + plus + str(score_diff) +'</em>'
63
 
64
- ## ELO SCORE
65
- df = df.sort_values(by='score', ascending=False)
66
  # medals
67
  def assign_medal(rank, assign):
68
  rank = str(rank + 1)
@@ -86,6 +89,6 @@ def get_leaderboard(reveal_prelim = False):
86
  ):
87
  top_five.append(orig_name)
88
 
89
- df['score'] = df['score_diff']
90
- df = df[['order', 'name', 'score', 'votes']]
91
  return df
 
21
  df['name'] = df['name'].replace(model_names)
22
  for i in range(len(df)):
23
  df.loc[i, "name"] = make_link_to_space(df['name'][i], True)
24
+
25
+ # Calculate total votes and win rate
26
  df['votes'] = df['upvote'] + df['downvote']
27
+ df['win_rate'] = (df['upvote'] / df['votes'] * 100).round(1)
28
  # df['score'] = round((df['upvote'] / df['votes']) * 100, 2) # Percentage score
29
 
30
  ## ELO SCORE
31
+ df['elo'] = 1200
32
+ df['elo_diff'] = ""
33
  for i in range(len(df)):
34
  for j in range(len(df)):
35
  if i != j:
36
  try:
37
+ expected_a = 1 / (1 + 10 ** ((df['elo'].iloc[j] - df['elo'].iloc[i]) / 400))
38
+ expected_b = 1 / (1 + 10 ** ((df['elo'].iloc[i] - df['elo'].iloc[j]) / 400))
39
  actual_a = df['upvote'].iloc[i] / df['votes'].iloc[i] if df['votes'].iloc[i] > 0 else 0.5
40
  actual_b = df['upvote'].iloc[j] / df['votes'].iloc[j] if df['votes'].iloc[j] > 0 else 0.5
41
+ df.at[i, 'elo'] += round(32 * (actual_a - expected_a))
42
+ df.at[j, 'elo'] += round(32 * (actual_b - expected_b))
43
  except Exception as e:
44
  print(f"Error in ELO calculation for rows {i} and {j}: {str(e)}")
45
  continue
46
+ df['elo'] = round(df['elo'])
47
+ df['elo_diff'] = df['elo']
48
 
49
  if (
50
  reveal_prelim == False
 
54
 
55
  if (reveal_prelim == False):
56
  for i in range(len(df)):
57
+ elo_diff = (df['elo'].iloc[i] - leaderboard_df['elo'].iloc[i])
58
+ if (elo_diff == 0):
59
  continue
60
+ if (elo_diff > 0):
61
  plus = '<em style="color: green; font-family: monospace">+'
62
  else:
63
  plus = '<em style="color: red; font-family: monospace">'
64
 
65
+ df.at[i, 'elo_diff'] = str(df['elo'].iloc[i]) + plus + str(elo_diff) +'</em>'
66
 
67
+ ## ELO score
68
+ df = df.sort_values(by='elo', ascending=False)
69
  # medals
70
  def assign_medal(rank, assign):
71
  rank = str(rank + 1)
 
89
  ):
90
  top_five.append(orig_name)
91
 
92
+ df['elo'] = df['elo_diff']
93
+ df = df[['order', 'name', 'elo', 'votes', 'win_rate']]
94
  return df
app/models.py CHANGED
@@ -513,6 +513,37 @@ model_names = {
513
  'metavoice': 'MetaVoice-1B',
514
  }
515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  def make_link_to_space(model_name, for_leaderboard=False):
517
  # create a anchor link if a HF space
518
  style = 'text-decoration: underline;text-decoration-style: dotted;'
 
513
  'metavoice': 'MetaVoice-1B',
514
  }
515
 
516
+ model_links = {
517
+ 'ElevenLabs': 'https://elevenlabs.io/',
518
+ 'Play.HT 2.0': 'https://play.ht/',
519
+ 'Play.HT 3.0 Mini': 'https://play.ht/',
520
+ 'XTTSv2': 'https://huggingface.co/coqui/XTTS-v2',
521
+ 'MeloTTS': 'https://github.com/myshell-ai/MeloTTS',
522
+ 'StyleTTS 2': 'https://github.com/yl4579/StyleTTS2',
523
+ 'Parler TTS Large': 'https://github.com/huggingface/parler-tts',
524
+ 'Parler TTS': 'https://github.com/huggingface/parler-tts',
525
+ 'Fish Speech v1.5': 'https://github.com/fishaudio/fish-speech',
526
+ 'Fish Speech v1.4': 'https://github.com/fishaudio/fish-speech',
527
+ 'GPT-SoVITS': 'https://github.com/RVC-Boss/GPT-SoVITS',
528
+ 'WhisperSpeech': 'https://github.com/WhisperSpeech/WhisperSpeech',
529
+ 'VoiceCraft 2.0': 'https://github.com/jasonppy/VoiceCraft',
530
+ 'PlayDialog': 'https://play.ht/',
531
+ 'Kokoro v0.19': 'https://huggingface.co/hexgrad/Kokoro-82M',
532
+ 'CosyVoice 2.0': 'https://github.com/FunAudioLLM/CosyVoice',
533
+ 'MetaVoice': 'https://github.com/metavoiceio/metavoice-src',
534
+ 'OpenVoice': 'https://github.com/myshell-ai/OpenVoice',
535
+ 'OpenVoice V2': 'https://github.com/myshell-ai/OpenVoice',
536
+ 'Pheme': 'https://github.com/PolyAI-LDN/pheme',
537
+ 'Vokan TTS': 'https://huggingface.co/ShoukanLabs/Vokan',
538
+ }
539
+
540
+ closed_source = [
541
+ 'ElevenLabs',
542
+ 'Play.HT 2.0',
543
+ 'Play.HT 3.0 Mini',
544
+ 'PlayDialog',
545
+ ]
546
+
547
  def make_link_to_space(model_name, for_leaderboard=False):
548
  # create a anchor link if a HF space
549
  style = 'text-decoration: underline;text-decoration-style: dotted;'
app/ui.py CHANGED
@@ -37,6 +37,9 @@ head_js += open("app/cookie.js").read()
37
  head_js += '</script>'
38
 
39
  with gr.Blocks() as about:
 
 
 
40
  gr.Markdown(ABOUT)
41
 
42
  with gr.Blocks(
 
37
  head_js += '</script>'
38
 
39
  with gr.Blocks() as about:
40
+ with gr.Row():
41
+ with gr.Accordion("News", open=False):
42
+ gr.Markdown(NEWS)
43
  gr.Markdown(ABOUT)
44
 
45
  with gr.Blocks(
app/ui_leaderboard.py CHANGED
@@ -9,8 +9,8 @@ with gr.Blocks() as leaderboard:
9
  interactive=False,
10
  min_width=0,
11
  wrap=False,
12
- column_widths=[30, 200, 50, 50],
13
- datatype=["str", "html", "html", "number"]
14
  )
15
  reloadbtn = gr.Button("Refresh")
16
  with gr.Row():
 
9
  interactive=False,
10
  min_width=0,
11
  wrap=False,
12
+ column_widths=[30, 200, 50, 50, 50],
13
+ datatype=["str", "html", "html", "html", "number"]
14
  )
15
  reloadbtn = gr.Button("Refresh")
16
  with gr.Row():
app/ui_vote.py CHANGED
@@ -54,6 +54,7 @@ with gr.Blocks() as vote:
54
  show_label=False,
55
  show_download_button=False,
56
  show_share_button=False,
 
57
  # waveform_options={'waveform_progress_color': '#EF4444'},
58
  # var(--color-red-500)'}); gradio only accepts HEX and CSS color
59
  )
@@ -76,6 +77,7 @@ with gr.Blocks() as vote:
76
  show_download_button=False,
77
  show_share_button=False,
78
  waveform_options={'waveform_progress_color': '#3C82F6'},
 
79
  # var(--secondary-500)'}); gradio only accepts HEX and CSS color
80
  )
81
  bbetter = gr.Button(
@@ -161,7 +163,7 @@ with gr.Blocks() as vote:
161
  .then(
162
  None,
163
  inputs=[bplayed if autoplay else True],
164
- js="(b) => b ? 0 : document.querySelector('.row .gap+.gap button.play-pause-button[aria-label=Play]').click()",
165
  )
166
  # autoplay if unplayed
167
  aud2\
 
54
  show_label=False,
55
  show_download_button=False,
56
  show_share_button=False,
57
+ elem_id="vote-a-audio",
58
  # waveform_options={'waveform_progress_color': '#EF4444'},
59
  # var(--color-red-500)'}); gradio only accepts HEX and CSS color
60
  )
 
77
  show_download_button=False,
78
  show_share_button=False,
79
  waveform_options={'waveform_progress_color': '#3C82F6'},
80
+ elem_id="vote-b-audio",
81
  # var(--secondary-500)'}); gradio only accepts HEX and CSS color
82
  )
83
  bbetter = gr.Button(
 
163
  .then(
164
  None,
165
  inputs=[bplayed if autoplay else True],
166
+ js="(b) => b ? 0 : document.getElementById('vote-b-audio')?.querySelector('button.play-pause-button')?.click()",
167
  )
168
  # autoplay if unplayed
169
  aud2\