ftshijt commited on
Commit
dfa3d55
·
1 Parent(s): be31546

update app.py

Browse files
Files changed (1) hide show
  1. app.py +183 -39
app.py CHANGED
@@ -1,56 +1,200 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test script to verify that VERSA is installed correctly.
4
- """
5
-
6
  import os
7
  import sys
8
  import subprocess
 
 
 
 
 
 
 
 
9
  from pathlib import Path
10
 
11
- # Check if VERSA is installed
12
  VERSA_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "versa")
13
 
14
- def check_versa():
15
- """Check if VERSA is installed and working"""
16
- print("Testing VERSA installation...")
17
-
18
  if not os.path.exists(VERSA_ROOT):
19
- print("VERSA not found.")
20
- return False
21
-
22
- # Check if the scorer.py exists
23
- scorer_path = os.path.join(VERSA_ROOT, "versa", "bin", "scorer.py")
24
- if not os.path.exists(scorer_path):
25
- print(f"VERSA scorer not found at {scorer_path}")
26
- return False
27
-
28
- # Check if the config directory exists
29
- config_dir = os.path.join(VERSA_ROOT, "egs")
30
- if not os.path.exists(config_dir):
31
- print(f"VERSA config directory not found at {config_dir}")
32
- return False
33
-
34
- # Check for available metrics
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  metrics = []
36
- for root, _, files in os.walk(config_dir):
 
 
37
  for file in files:
38
  if file.endswith('.yaml'):
39
- metrics.append(os.path.join(root, file))
 
 
 
40
 
41
- if not metrics:
42
- print("No metric configurations found in VERSA.")
43
- return False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
- print(f"Found {len(metrics)} metric configurations.")
46
- for metric in metrics[:5]: # Print first 5 metrics
47
- print(f"- {os.path.relpath(metric, config_dir)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
- if len(metrics) > 5:
50
- print(f"... and {len(metrics) - 5} more.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- print("VERSA installation looks good!")
53
- return True
54
 
 
55
  if __name__ == "__main__":
56
- check_versa()
 
 
 
 
 
 
 
1
  import os
2
  import sys
3
  import subprocess
4
+ import gradio as gr
5
+ import json
6
+ import yaml
7
+ import tempfile
8
+ import pandas as pd
9
+ import numpy as np
10
+ import matplotlib.pyplot as plt
11
+ import time
12
  from pathlib import Path
13
 
14
+ # Check if VERSA is installed, if not, clone and install it
15
  VERSA_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "versa")
16
 
17
+ def setup_versa():
18
+ """Set up VERSA and its dependencies if not already installed"""
 
 
19
  if not os.path.exists(VERSA_ROOT):
20
+ print("VERSA not found. Installing...")
21
+ # Clone VERSA repository
22
+ subprocess.run(
23
+ ["git", "clone", "https://github.com/shinjiwlab/versa.git", VERSA_ROOT],
24
+ check=True
25
+ )
26
+
27
+ # Install VERSA
28
+ subprocess.run(
29
+ ["pip", "install", "-e", VERSA_ROOT],
30
+ check=True
31
+ )
32
+
33
+ print("VERSA installed successfully!")
34
+ else:
35
+ print("VERSA already installed.")
36
+
37
+ # Install VERSA if not already installed
38
+ setup_versa()
39
+
40
+ # VERSA paths
41
+ VERSA_BIN = os.path.join(VERSA_ROOT, "versa", "bin", "scorer.py")
42
+ VERSA_CONFIG_DIR = os.path.join(VERSA_ROOT, "egs")
43
+
44
+ # Create data directory if it doesn't exist
45
+ DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
46
+ UPLOAD_DIR = os.path.join(DATA_DIR, "uploads")
47
+ RESULTS_DIR = os.path.join(DATA_DIR, "results")
48
+
49
+ for directory in [DATA_DIR, UPLOAD_DIR, RESULTS_DIR]:
50
+ os.makedirs(directory, exist_ok=True)
51
+
52
+ # Find available metric configs
53
+ def get_available_metrics():
54
+ """Get list of available metrics from VERSA config directory"""
55
  metrics = []
56
+
57
+ # Get all YAML files from the egs directory
58
+ for root, _, files in os.walk(VERSA_CONFIG_DIR):
59
  for file in files:
60
  if file.endswith('.yaml'):
61
+ path = os.path.join(root, file)
62
+ # Get relative path from VERSA_CONFIG_DIR
63
+ rel_path = os.path.relpath(path, VERSA_CONFIG_DIR)
64
+ metrics.append(rel_path)
65
 
66
+ return sorted(metrics)
67
+
68
+ # Get metric description from YAML file
69
+ def get_metric_description(metric_path):
70
+ """Get description of a metric from its YAML file"""
71
+ full_path = os.path.join(VERSA_CONFIG_DIR, metric_path)
72
+ try:
73
+ with open(full_path, 'r') as f:
74
+ config = yaml.safe_load(f)
75
+ return config.get('description', 'No description available')
76
+ except Exception as e:
77
+ return f"Could not load description: {str(e)}"
78
+
79
+ # Process audio files and run VERSA evaluation
80
+ def evaluate_audio(gt_file, pred_file, metric_config, include_timestamps=False):
81
+ """Evaluate audio files using VERSA"""
82
+ if gt_file is None or pred_file is None:
83
+ return "Please upload both ground truth and prediction audio files."
84
 
85
+ # Create temp directory for results
86
+ with tempfile.TemporaryDirectory() as temp_dir:
87
+ output_file = os.path.join(temp_dir, "result.json")
88
+
89
+ # Full path to metric config
90
+ metric_config_path = os.path.join(VERSA_CONFIG_DIR, metric_config)
91
+
92
+ # Build command
93
+ cmd = [
94
+ sys.executable, VERSA_BIN,
95
+ "--score_config", metric_config_path,
96
+ "--gt", gt_file,
97
+ "--pred", pred_file,
98
+ "--output_file", output_file
99
+ ]
100
+
101
+ if include_timestamps:
102
+ cmd.append("--include_timestamp")
103
+
104
+ # Run VERSA evaluation
105
+ try:
106
+ process = subprocess.run(
107
+ cmd,
108
+ check=True,
109
+ stdout=subprocess.PIPE,
110
+ stderr=subprocess.PIPE,
111
+ text=True
112
+ )
113
+
114
+ # Read results
115
+ if os.path.exists(output_file):
116
+ with open(output_file, 'r') as f:
117
+ results = json.load(f)
118
+
119
+ # Format results as DataFrame
120
+ if results:
121
+ results_df = pd.DataFrame(results)
122
+ return results_df, json.dumps(results, indent=2)
123
+ else:
124
+ return None, "Evaluation completed but no results were generated."
125
+ else:
126
+ return None, "Evaluation completed but no results file was generated."
127
+
128
+ except subprocess.CalledProcessError as e:
129
+ return None, f"Error running VERSA: {e.stderr}"
130
+
131
+ # Create the Gradio interface
132
+ def create_gradio_demo():
133
+ """Create the Gradio demo interface"""
134
+ available_metrics = get_available_metrics()
135
+ default_metric = "speech.yaml" if "speech.yaml" in available_metrics else available_metrics[0] if available_metrics else None
136
 
137
+ with gr.Blocks(title="VERSA Speech & Audio Evaluation Demo") as demo:
138
+ gr.Markdown("# VERSA: Versatile Evaluation of Speech and Audio")
139
+ gr.Markdown("Upload audio files to evaluate them using VERSA metrics.")
140
+
141
+ with gr.Row():
142
+ with gr.Column():
143
+ gt_audio = gr.Audio(label="Ground Truth Audio", type="filepath", sources=["upload", "microphone"])
144
+ pred_audio = gr.Audio(label="Prediction Audio", type="filepath", sources=["upload", "microphone"])
145
+
146
+ metric_dropdown = gr.Dropdown(
147
+ choices=available_metrics,
148
+ label="Evaluation Metric",
149
+ value=default_metric
150
+ )
151
+
152
+ metric_description = gr.Textbox(
153
+ label="Metric Description",
154
+ value=get_metric_description(default_metric) if default_metric else "",
155
+ interactive=False
156
+ )
157
+
158
+ include_timestamps = gr.Checkbox(
159
+ label="Include Timestamps in Results",
160
+ value=False
161
+ )
162
+
163
+ eval_button = gr.Button("Evaluate")
164
+
165
+ with gr.Column():
166
+ results_table = gr.Dataframe(label="Evaluation Results")
167
+ raw_json = gr.Code(language="json", label="Raw Results")
168
+
169
+ # Event handlers
170
+ def update_metric_description(metric_path):
171
+ return get_metric_description(metric_path)
172
+
173
+ metric_dropdown.change(
174
+ fn=update_metric_description,
175
+ inputs=[metric_dropdown],
176
+ outputs=[metric_description]
177
+ )
178
+
179
+ eval_button.click(
180
+ fn=evaluate_audio,
181
+ inputs=[gt_audio, pred_audio, metric_dropdown, include_timestamps],
182
+ outputs=[results_table, raw_json]
183
+ )
184
+
185
+ gr.Markdown("""
186
+ ## About VERSA
187
+
188
+ VERSA (Versatile Evaluation of Speech and Audio) is a toolkit dedicated to collecting evaluation metrics in speech and audio quality. It provides a comprehensive connection to cutting-edge evaluation techniques and is tightly integrated with ESPnet.
189
+
190
+ With full installation, VERSA offers over 60 metrics with 700+ metric variations based on different configurations. These metrics encompass evaluations utilizing diverse external resources, including matching and non-matching reference audio, text transcriptions, and text captions.
191
+
192
+ Learn more at [VERSA GitHub Repository](https://github.com/shinjiwlab/versa)
193
+ """)
194
 
195
+ return demo
 
196
 
197
+ # Launch the app
198
  if __name__ == "__main__":
199
+ demo = create_gradio_demo()
200
+ demo.launch()