From ad31cac0f6c592cbd1f5c707fba678beb1de197d Mon Sep 17 00:00:00 2001 From: Michael Treadgold Date: Thu, 18 Jun 2026 20:21:10 +1200 Subject: [PATCH] Fix HF dataset preprocessing: save in-memory audio arrays to temp files so target_audio paths are valid --- preprocess_dataset.py | 112 ++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 54 deletions(-) diff --git a/preprocess_dataset.py b/preprocess_dataset.py index 558b4a4..3d72fd7 100644 --- a/preprocess_dataset.py +++ b/preprocess_dataset.py @@ -142,74 +142,78 @@ def process_hf_dataset( preferred = [s for s in splits if "train" in s.lower()] ds = ds_dict[preferred[0] if preferred else splits[0]] + import tempfile + mel_frontend = MelFrontend(HifiGanConfig(variant="v2plus")) 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 - with output_jsonl.open("w", encoding="utf-8") as f: - for i, row in enumerate(ds): - text = str(row.get(text_key, "")).strip() - if not text: - continue - - # 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: + try: + with output_jsonl.open("w", encoding="utf-8") as f: + for i, row in enumerate(ds): + text = str(row.get(text_key, "")).strip() + if not text: continue - 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(): + + # Get audio path or array + audio_info = row.get("audio", row.get("file", None)) + if audio_info is None: continue - audio_array = None - sample_rate = 24000 # will be detected on load - else: - continue - try: - 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 isinstance(audio_info, dict): + # Audio loaded as array — save to temp file + audio_array = audio_info.get("array") + sr = audio_info.get("sampling_rate", 24000) + 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: - continue + try: + 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) - 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 = { - "phone_ids": phone_ids, - "tone_ids": tone_ids, - "lang_ids": lang_ids, - "hifigan_durations": durations, - "target_audio": audio_path or "", - "speaker_id": hash(speaker) % 256, - "voice_id": speaker, - } - f.write(json.dumps(row_out, ensure_ascii=False) + "\n") - count += 1 + row_out = { + "phone_ids": phone_ids, + "tone_ids": tone_ids, + "lang_ids": lang_ids, + "hifigan_durations": durations, + "target_audio": str(Path(audio_path).resolve()), + "speaker_id": hash(speaker) % 256, + "voice_id": speaker, + } + f.write(json.dumps(row_out, ensure_ascii=False) + "\n") + count += 1 - if max_rows > 0 and count >= max_rows: - break + if max_rows > 0 and count >= max_rows: + break - if count % 100 == 0: - print(f" Processed {count} rows...") + if count % 100 == 0: + 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}") return count