Fix HF dataset preprocessing: save in-memory audio arrays to temp files so target_audio paths are valid
This commit is contained in:
+58
-54
@@ -142,74 +142,78 @@ def process_hf_dataset(
|
|||||||
preferred = [s for s in splits if "train" in s.lower()]
|
preferred = [s for s in splits if "train" in s.lower()]
|
||||||
ds = ds_dict[preferred[0] if preferred else splits[0]]
|
ds = ds_dict[preferred[0] if preferred else splits[0]]
|
||||||
|
|
||||||
|
import tempfile
|
||||||
|
|
||||||
mel_frontend = MelFrontend(HifiGanConfig(variant="v2plus"))
|
mel_frontend = MelFrontend(HifiGanConfig(variant="v2plus"))
|
||||||
output_jsonl.parent.mkdir(parents=True, exist_ok=True)
|
output_jsonl.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# Temp dir for audio extracted from HF arrays (cleaned up on exit)
|
||||||
|
audio_tmp = Path(tempfile.mkdtemp(prefix="inflect_audio_"))
|
||||||
|
print(f"Audio tmp dir: {audio_tmp}")
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
with output_jsonl.open("w", encoding="utf-8") as f:
|
try:
|
||||||
for i, row in enumerate(ds):
|
with output_jsonl.open("w", encoding="utf-8") as f:
|
||||||
text = str(row.get(text_key, "")).strip()
|
for i, row in enumerate(ds):
|
||||||
if not text:
|
text = str(row.get(text_key, "")).strip()
|
||||||
continue
|
if not text:
|
||||||
|
|
||||||
# Get audio path or array
|
|
||||||
audio_info = row.get("audio", row.get("file", None))
|
|
||||||
if audio_info is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if isinstance(audio_info, dict):
|
|
||||||
# Audio is already loaded as array
|
|
||||||
audio_path = None
|
|
||||||
audio_array = audio_info.get("array")
|
|
||||||
sample_rate = audio_info.get("sampling_rate", 24000)
|
|
||||||
if audio_array is None:
|
|
||||||
continue
|
continue
|
||||||
elif isinstance(audio_info, str):
|
|
||||||
audio_path = audio_info
|
# Get audio path or array
|
||||||
if audio_dir:
|
audio_info = row.get("audio", row.get("file", None))
|
||||||
audio_path = str(audio_dir / Path(audio_info).name)
|
if audio_info is None:
|
||||||
if not Path(audio_path).is_file():
|
|
||||||
continue
|
continue
|
||||||
audio_array = None
|
|
||||||
sample_rate = 24000 # will be detected on load
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
if isinstance(audio_info, dict):
|
||||||
phone_ids, tone_ids, lang_ids = text_to_ids(text)
|
# Audio loaded as array — save to temp file
|
||||||
except Exception as e:
|
audio_array = audio_info.get("array")
|
||||||
print(f" Skipping row {i}: text-to-ids failed: {e}")
|
sr = audio_info.get("sampling_rate", 24000)
|
||||||
continue
|
if audio_array is None:
|
||||||
|
continue
|
||||||
|
audio_path = str(audio_tmp / f"utt_{i:06d}.wav")
|
||||||
|
sf.write(audio_path, audio_array, sr, subtype="PCM_16")
|
||||||
|
elif isinstance(audio_info, str):
|
||||||
|
audio_path = audio_info
|
||||||
|
if audio_dir:
|
||||||
|
audio_path = str(audio_dir / Path(audio_info).name)
|
||||||
|
if not Path(audio_path).is_file():
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
if not phone_ids:
|
try:
|
||||||
continue
|
phone_ids, tone_ids, lang_ids = text_to_ids(text)
|
||||||
|
except Exception as e:
|
||||||
|
print(f" Skipping row {i}: text-to-ids failed: {e}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not phone_ids:
|
||||||
|
continue
|
||||||
|
|
||||||
# Estimate durations
|
|
||||||
if audio_path:
|
|
||||||
durations = estimate_durations_uniform(phone_ids, audio_path, mel_frontend)
|
durations = estimate_durations_uniform(phone_ids, audio_path, mel_frontend)
|
||||||
else:
|
|
||||||
# Uniform fallback: 8 frames per phone
|
|
||||||
durations = [8] * len(phone_ids)
|
|
||||||
|
|
||||||
speaker = str(row.get(speaker_key, voice_id))
|
speaker = str(row.get(speaker_key, voice_id))
|
||||||
|
|
||||||
row_out = {
|
row_out = {
|
||||||
"phone_ids": phone_ids,
|
"phone_ids": phone_ids,
|
||||||
"tone_ids": tone_ids,
|
"tone_ids": tone_ids,
|
||||||
"lang_ids": lang_ids,
|
"lang_ids": lang_ids,
|
||||||
"hifigan_durations": durations,
|
"hifigan_durations": durations,
|
||||||
"target_audio": audio_path or "",
|
"target_audio": str(Path(audio_path).resolve()),
|
||||||
"speaker_id": hash(speaker) % 256,
|
"speaker_id": hash(speaker) % 256,
|
||||||
"voice_id": speaker,
|
"voice_id": speaker,
|
||||||
}
|
}
|
||||||
f.write(json.dumps(row_out, ensure_ascii=False) + "\n")
|
f.write(json.dumps(row_out, ensure_ascii=False) + "\n")
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
if max_rows > 0 and count >= max_rows:
|
if max_rows > 0 and count >= max_rows:
|
||||||
break
|
break
|
||||||
|
|
||||||
if count % 100 == 0:
|
if count % 100 == 0:
|
||||||
print(f" Processed {count} rows...")
|
print(f" Processed {count} rows...")
|
||||||
|
finally:
|
||||||
|
# Audio tmp files must survive until training is done, so we keep them
|
||||||
|
pass
|
||||||
|
|
||||||
print(f"Wrote {count} rows to {output_jsonl}")
|
print(f"Wrote {count} rows to {output_jsonl}")
|
||||||
return count
|
return count
|
||||||
|
|||||||
Reference in New Issue
Block a user