techfreakworm commited on
Commit
6ad959d
·
unverified ·
1 Parent(s): 23509d8

fix(pipeline): pass save_dir so generate_music writes a usable file path

Browse files

generate_music's audios[0]['path'] is empty string when save_dir is not
provided — only the in-memory tensor is returned. Gradio's output processing
then tried to read the empty path, resolved it against cwd, and crashed
with IsADirectoryError on the project root.

Pass save_dir=./output/ so the audio is written with the UUID filename
the AudioSaver chose. Also add a defensive tensor-fallback (soundfile.write)
in case generate_music ever returns an empty path despite save_dir being
provided.

Caught while running the live app end-to-end after the M1 GPU smoke
passed — the smoke happened to skip this code path because its mock
provided a path. The bug only surfaced with the real pipeline.

Files changed (1) hide show
  1. ace_pipeline.py +35 -2
ace_pipeline.py CHANGED
@@ -41,6 +41,7 @@ from pathlib import Path
41
 
42
  _REPO_ROOT = Path(__file__).resolve().parent
43
  _CHECKPOINTS_DIR = _REPO_ROOT / "checkpoints"
 
44
 
45
  _DEFAULT_DIT_CONFIG = "acestep-v15-xl-sft"
46
  _DEFAULT_LM_MODEL = "acestep-5Hz-lm-0.6B"
@@ -193,14 +194,46 @@ class ACEStepStudio:
193
  seeds=[int(params.get("seed", 1))],
194
  )
195
 
196
- result = generate_music(self._dit, self._llm, gen_params, gen_config)
 
 
 
 
 
 
 
 
 
 
 
197
 
198
  if not result.success:
199
  raise RuntimeError(f"ACE-Step generation failed: {result.error}")
200
  if not result.audios:
201
  raise RuntimeError("ACE-Step returned no audio outputs")
202
 
203
- return result.audios[0]["path"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
 
206
  _PIPELINE: ACEStepStudio | None = None # module-level lazy singleton
 
41
 
42
  _REPO_ROOT = Path(__file__).resolve().parent
43
  _CHECKPOINTS_DIR = _REPO_ROOT / "checkpoints"
44
+ _OUTPUT_DIR = _REPO_ROOT / "output"
45
 
46
  _DEFAULT_DIT_CONFIG = "acestep-v15-xl-sft"
47
  _DEFAULT_LM_MODEL = "acestep-5Hz-lm-0.6B"
 
194
  seeds=[int(params.get("seed", 1))],
195
  )
196
 
197
+ # generate_music only writes a file when save_dir is provided; otherwise
198
+ # result.audios[i]["path"] is empty and ["tensor"] holds the raw audio.
199
+ # Pass an explicit output dir so the path is always usable.
200
+ _OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
201
+
202
+ result = generate_music(
203
+ self._dit,
204
+ self._llm,
205
+ gen_params,
206
+ gen_config,
207
+ save_dir=str(_OUTPUT_DIR),
208
+ )
209
 
210
  if not result.success:
211
  raise RuntimeError(f"ACE-Step generation failed: {result.error}")
212
  if not result.audios:
213
  raise RuntimeError("ACE-Step returned no audio outputs")
214
 
215
+ audio = result.audios[0]
216
+ path = audio.get("path") or ""
217
+ if not path:
218
+ # generate_music returned an empty path despite save_dir being passed.
219
+ # Fall back to writing the in-memory tensor so callers always get a
220
+ # valid file path (Gradio cannot serve an empty path).
221
+ import soundfile as sf
222
+
223
+ tensor = audio.get("tensor")
224
+ if tensor is None:
225
+ raise RuntimeError("ACE-Step returned neither an audio path nor a tensor")
226
+ sample_rate = int(audio.get("sample_rate", 48000))
227
+ audio_format = advanced.get("audio_format", "wav")
228
+ fallback = _OUTPUT_DIR / f"{audio.get('key', 'fallback')}.{audio_format}"
229
+ data = tensor.detach().cpu().numpy()
230
+ # soundfile expects (frames, channels); acestep tensors are (channels, frames)
231
+ if data.ndim == 2 and data.shape[0] in (1, 2):
232
+ data = data.T
233
+ sf.write(str(fallback), data, sample_rate)
234
+ path = str(fallback)
235
+
236
+ return path
237
 
238
 
239
  _PIPELINE: ACEStepStudio | None = None # module-level lazy singleton