Skip to content

Commit 269f6b3

Browse files
committed
Began adding new scores
1 parent ee0d898 commit 269f6b3

2 files changed

Lines changed: 179 additions & 51 deletions

File tree

audio_separator/models-scores.json

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45778,8 +45778,23 @@
4577845778
},
4577945779
"model_bs_roformer_ep_937_sdr_10.5309.ckpt": {
4578045780
"model_name": "Roformer Model: BS-Roformer-Viperx-1053",
45781-
"track_scores": [],
45782-
"median_scores": {},
45781+
"track_scores": [
45782+
{
45783+
"track_name": "A Classic Education - NightOwl",
45784+
"scores": {
45785+
"seconds_per_minute_m3": 13.3
45786+
}
45787+
},
45788+
{
45789+
"track_name": "A Classic Education - NightOwl",
45790+
"scores": {
45791+
"seconds_per_minute_m3": 13.3
45792+
}
45793+
}
45794+
],
45795+
"median_scores": {
45796+
"seconds_per_minute_m3": 13.3
45797+
},
4578345798
"stems": [
4578445799
"no drum-bass",
4578545800
"drum-bass"
@@ -53525,5 +53540,45 @@
5352553540
"instrumental"
5352653541
],
5352753542
"target_stem": null
53543+
},
53544+
"mel_band_roformer_karaoke_gabox.ckpt": {
53545+
"model_name": "Roformer Model: MelBand Roformer | Karaoke by Gabox",
53546+
"track_scores": [
53547+
{
53548+
"track_name": "A Classic Education - NightOwl",
53549+
"scores": {
53550+
"vocals": {
53551+
"SDR": 6.88608,
53552+
"SIR": 27.7786,
53553+
"SAR": 6.37612,
53554+
"ISR": 9.25014
53555+
},
53556+
"instrumental": {
53557+
"SDR": 16.4048,
53558+
"SIR": 21.2481,
53559+
"SAR": 19.3112,
53560+
"ISR": 19.5408
53561+
},
53562+
"seconds_per_minute_m3": 17.5
53563+
}
53564+
}
53565+
],
53566+
"median_scores": {
53567+
"vocals": {
53568+
"SDR": 6.88608,
53569+
"SIR": 27.7786,
53570+
"SAR": 6.37612,
53571+
"ISR": 9.25014
53572+
},
53573+
"instrumental": {
53574+
"SDR": 16.4048,
53575+
"SIR": 21.2481,
53576+
"SAR": 19.3112,
53577+
"ISR": 19.5408
53578+
},
53579+
"seconds_per_minute_m3": 17.5
53580+
},
53581+
"stems": [],
53582+
"target_stem": null
5352853583
}
5352953584
}

tests/model-metrics/test-all-models.py

Lines changed: 122 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,49 @@ def evaluate_track(track_name, track_path, test_model, mus_db):
105105
track_duration_minutes = get_track_duration(track_path)
106106
logger.info(f"Track duration: {track_duration_minutes:.2f} minutes")
107107

108+
# Initialize variables to track processing time
109+
processing_time = 0
110+
seconds_per_minute = 0
111+
112+
# Create a basic result structure that will be returned even if evaluation fails
113+
basic_model_results = {"track_name": track_name, "scores": {}}
114+
108115
# Check if evaluation results already exist in combined file
109116
museval_results = load_combined_results()
110117
if test_model in museval_results and track_name in museval_results[test_model]:
111118
logger.info("Found existing evaluation results in combined file...")
112119
track_data = museval_results[test_model][track_name]
113120
scores = museval.TrackStore(track_name)
114121
scores.scores = track_data
122+
123+
# Try to extract existing speed metrics if available
124+
try:
125+
if isinstance(track_data, dict) and "targets" in track_data:
126+
for target in track_data["targets"]:
127+
if "metrics" in target and "seconds_per_minute_m3" in target["metrics"]:
128+
basic_model_results["scores"]["seconds_per_minute_m3"] = target["metrics"]["seconds_per_minute_m3"]
129+
break
130+
except Exception:
131+
pass # Ignore errors in extracting existing speed metrics
115132
else:
116-
# Expanded stem mapping to include "no-stem" outputs
117-
stem_mapping = {"Vocals": "vocals", "Instrumental": "instrumental", "Drums": "drums", "Bass": "bass", "Other": "other", "No Drums": "nodrums", "No Bass": "nobass", "No Other": "noother"}
133+
# Expanded stem mapping to include "no-stem" outputs and custom stem formats
134+
stem_mapping = {
135+
# Standard stems
136+
"Vocals": "vocals",
137+
"Instrumental": "instrumental",
138+
"Drums": "drums",
139+
"Bass": "bass",
140+
"Other": "other",
141+
# No-stem variants
142+
"No Drums": "nodrums",
143+
"No Bass": "nobass",
144+
"No Other": "noother",
145+
# Custom stem formats (with hyphens)
146+
"Drum-Bass": "drumbass",
147+
"No Drum-Bass": "nodrumbass",
148+
"Vocals-Other": "vocalsother",
149+
"No Vocals-Other": "novocalsother",
150+
}
118151

119152
# Create a temporary directory for separation files
120153
with tempfile.TemporaryDirectory() as temp_dir:
@@ -135,26 +168,41 @@ def evaluate_track(track_name, track_path, test_model, mus_db):
135168
logger.info(f"Separation completed in {processing_time:.2f} seconds")
136169
logger.info(f"Processing speed: {seconds_per_minute:.2f} seconds per minute of audio")
137170

138-
# Check which stems were actually created and pair them appropriately
139-
available_stems = {}
140-
stem_pairs = {"drums": "nodrums", "bass": "nobass", "other": "noother", "vocals": "instrumental"}
171+
# Always add the speed metric to our basic results
172+
basic_model_results["scores"]["seconds_per_minute_m3"] = round(seconds_per_minute, 1)
141173

142-
for main_stem, no_stem in stem_pairs.items():
143-
# Construct full file paths for both the isolated stem and its complement
144-
main_path = os.path.join(temp_dir, f"{main_stem}.wav")
145-
no_stem_path = os.path.join(temp_dir, f"{no_stem}.wav")
174+
# Check which stems were actually created
175+
wav_files = [f for f in os.listdir(temp_dir) if f.endswith(".wav")]
176+
logger.info(f"Found WAV files: {wav_files}")
146177

147-
# Only process this pair if both files exist
148-
if os.path.exists(main_path) and os.path.exists(no_stem_path):
149-
# Add the main stem with its path to available_stems
150-
available_stems[main_stem] = main_path # This is already using the correct musdb name
178+
# Determine if this is a standard vocal/instrumental model that can be evaluated with museval
179+
standard_model = False
180+
if len(wav_files) == 2:
181+
# Check if one of the files is named vocals.wav or instrumental.wav
182+
if "vocals.wav" in wav_files and "instrumental.wav" in wav_files:
183+
standard_model = True
184+
logger.info("Detected standard vocals/instrumental model, will run museval evaluation")
151185

152-
# For the complement stem, always use "accompaniment" as that's what museval expects
153-
available_stems["accompaniment"] = no_stem_path
186+
# If not a standard model, skip museval evaluation and just return speed metrics
187+
if not standard_model:
188+
logger.info(f"Non-standard stem configuration detected for model {test_model}, skipping museval evaluation")
154189

155-
if not available_stems:
156-
logger.info(f"No evaluatable stems found for model {test_model}, skipping evaluation")
157-
return None, None
190+
# Store the speed metric in the combined results
191+
if test_model not in museval_results:
192+
museval_results[test_model] = {}
193+
194+
# Create a minimal structure for the speed metric
195+
minimal_results = {"targets": [{"name": "speed_metrics_only", "metrics": {"seconds_per_minute_m3": round(seconds_per_minute, 1)}}]}
196+
197+
museval_results[test_model][track_name] = minimal_results
198+
save_combined_results(museval_results)
199+
200+
return None, basic_model_results
201+
202+
# For standard models, proceed with museval evaluation
203+
available_stems = {}
204+
available_stems["vocals"] = os.path.join(temp_dir, "vocals.wav")
205+
available_stems["accompaniment"] = os.path.join(temp_dir, "instrumental.wav")
158206

159207
# Get track from MUSDB
160208
track = next((t for t in mus_db if t.name == track_name), None)
@@ -171,39 +219,64 @@ def evaluate_track(track_name, track_path, test_model, mus_db):
171219

172220
# Evaluate using museval
173221
logger.info(f"Evaluating stems: {list(estimates.keys())}")
174-
scores = museval.eval_mus_track(track, estimates, output_dir=temp_dir, mode="v4")
175-
176-
# Update the combined results file with the new evaluation
177-
if test_model not in museval_results:
178-
museval_results[test_model] = {}
179-
museval_results[test_model][track_name] = scores.scores
180-
save_combined_results(museval_results)
181-
182-
# Calculate aggregate scores for available stems
183-
results_store = museval.EvalStore()
184-
results_store.add_track(scores.df)
185-
methods = museval.MethodStore()
186-
methods.add_evalstore(results_store, name=test_model)
187-
agg_scores = methods.agg_frames_tracks_scores()
188-
189-
# Return the aggregate scores in a structured format with 6 significant figures
190-
model_results = {"track_name": track_name, "scores": {}}
191-
192-
for stem in ["vocals", "drums", "bass", "other", "accompaniment"]:
193-
try:
194-
stem_scores = {metric: float(f"{agg_scores.loc[(test_model, stem, metric)]:.6g}") for metric in ["SDR", "SIR", "SAR", "ISR"]}
195-
# Rename 'accompaniment' to 'instrumental' in the output
196-
output_stem = "instrumental" if stem == "accompaniment" else stem
197-
model_results["scores"][output_stem] = stem_scores
198-
except KeyError:
199-
continue
222+
try:
223+
scores = museval.eval_mus_track(track, estimates, output_dir=temp_dir, mode="v4")
224+
225+
# Add the speed metric to the scores
226+
if not hasattr(scores, "speed_metric_added"):
227+
for target in scores.scores["targets"]:
228+
if "metrics" not in target:
229+
target["metrics"] = {}
230+
target["metrics"]["seconds_per_minute_m3"] = round(seconds_per_minute, 1)
231+
scores.speed_metric_added = True
232+
233+
# Update the combined results file with the new evaluation
234+
if test_model not in museval_results:
235+
museval_results[test_model] = {}
236+
museval_results[test_model][track_name] = scores.scores
237+
save_combined_results(museval_results)
238+
except Exception as e:
239+
logger.error(f"Error during museval evaluation: {str(e)}")
240+
logger.exception("Evaluation exception details:")
241+
# Return basic results with just the speed metric
242+
return None, basic_model_results
200243

201-
# Add the seconds_per_minute_m3 metric if it was calculated
202-
if "processing_time" in locals() and track_duration_minutes > 0:
203-
seconds_per_minute = processing_time / track_duration_minutes
204-
model_results["scores"]["seconds_per_minute_m3"] = round(seconds_per_minute, 1)
244+
try:
245+
# Only process museval results if we have them
246+
if "scores" in locals() and scores is not None:
247+
# Calculate aggregate scores for available stems
248+
results_store = museval.EvalStore()
249+
results_store.add_track(scores.df)
250+
methods = museval.MethodStore()
251+
methods.add_evalstore(results_store, name=test_model)
252+
agg_scores = methods.agg_frames_tracks_scores()
253+
254+
# Return the aggregate scores in a structured format with 6 significant figures
255+
model_results = {"track_name": track_name, "scores": {}}
256+
257+
for stem in ["vocals", "drums", "bass", "other", "accompaniment"]:
258+
try:
259+
stem_scores = {metric: float(f"{agg_scores.loc[(test_model, stem, metric)]:.6g}") for metric in ["SDR", "SIR", "SAR", "ISR"]}
260+
# Rename 'accompaniment' to 'instrumental' in the output
261+
output_stem = "instrumental" if stem == "accompaniment" else stem
262+
model_results["scores"][output_stem] = stem_scores
263+
except KeyError:
264+
continue
265+
266+
# Add the seconds_per_minute_m3 metric if it was calculated
267+
if processing_time > 0 and track_duration_minutes > 0:
268+
model_results["scores"]["seconds_per_minute_m3"] = round(seconds_per_minute, 1)
269+
270+
return scores, model_results if model_results["scores"] else basic_model_results
271+
else:
272+
# If we don't have scores, just return the basic results with speed metrics
273+
return None, basic_model_results
205274

206-
return scores, model_results if model_results["scores"] else None
275+
except Exception as e:
276+
logger.error(f"Error processing evaluation results: {str(e)}")
277+
logger.exception("Results processing exception details:")
278+
# Return basic results with just the speed metric
279+
return None, basic_model_results
207280

208281

209282
def convert_decimal_to_float(obj):

0 commit comments

Comments
 (0)