Song generation appears to hang before output, likely during or after the audio saving phase. This could be due to:
- Codec compatibility issues
- WAV format problems
- torchaudio backend issues in WSL
- Tensor shape/dtype incompatibilities
- Audio library conflicts
CFM Sampling → VAE Decoding → Rearrange → Normalize → torchaudio.save()
↓
[int16, shape=(channels, samples)]
↓
output_fixed.wav
output = rearrange(output, "b d n -> d (b n)")- Expected output from VAE: [batch=1, channels=2, samples=N]
- After rearrange: [channels=2, samples=N]
- Issue: If batch > 1, this could create very large tensors
torchaudio.save(output_path, generated_song, sample_rate=44100)- torchaudio uses backend (libsndfile or FFmpeg)
- WAV saving can hang if:
- Tensor dtype is incompatible (should be float32 or int16)
- Shape is wrong (should be [channels, samples])
- Backend is not available in WSL
normalized = normalized.clamp(-1, 1).mul(32767).to(torch.int16)- Converting to int16 for WAV saving
- Issue: int16 range is -32768 to 32767, multiplying by 32767 might overflow
- torchaudio might use FFmpeg which could hang
- No GUI available, might block on resource allocation
- Slow disk I/O in WSL
# Should verify:
- Tensor dtype: float32 or int16
- Tensor shape: [channels, samples]
- Tensor values: -1 to 1 (float) or -32768 to 32767 (int16)
- Tensor size: reasonable (95s @ 44100Hz = ~4.2M samples)# torchaudio backends:
- libsndfile: native WAV support
- sox: audio effects
- ffmpeg: codec support# Verify:
- Output directory exists and is writable
- Sufficient disk space
- File permissionsCause: WAV encoding in WSL with FFmpeg backend might be slow or hang
Solution: Use numpy/scipy for WAV saving instead
import scipy.io.wavfile as wavfile
wavfile.write(output_path, 44100, audio_np)Cause: Audio might be wrong dtype for saving
Solution: Explicitly ensure float32 before saving
audio_float = generated_song.to(torch.float32)
# Normalize to -1 to 1 range
audio_float = audio_float / 32768.0
torchaudio.save(output_path, audio_float, sample_rate=44100)Cause: Shape might be [samples, channels] instead of [channels, samples]
Solution: Verify and transpose if needed
if audio.shape[0] > audio.shape[1]:
audio = audio.T # Transpose if neededCause: Large int16 tensor holding memory, slow disk write
Solution: Write in chunks or use memory mapping
def validate_audio_tensor(audio, expected_shape_dim=2):
"""Validate audio tensor before saving"""
# Check dtype
if audio.dtype not in [torch.float32, torch.int16]:
raise ValueError(f"Invalid dtype: {audio.dtype}")
# Check shape
if audio.dim() != expected_shape_dim:
raise ValueError(f"Invalid shape dims: {audio.dim()}")
# Check size
if audio.shape[0] > audio.shape[1]: # More channels than samples
return audio.T
return audiodef save_audio_scipy(audio, output_path, sample_rate=44100):
"""Save audio using scipy instead of torchaudio"""
import scipy.io.wavfile as wavfile
# Convert to numpy
audio_np = audio.cpu().numpy()
# Ensure int16 range
if audio_np.dtype == np.float32:
audio_np = (audio_np * 32767).astype(np.int16)
# Transpose if needed
if audio_np.shape[0] > audio_np.shape[1]:
audio_np = audio_np.T
# Write
wavfile.write(output_path, sample_rate, audio_np)import signal
def timeout_handler(signum, frame):
raise TimeoutError("Audio saving timed out after 60 seconds")
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(60) # 60 second timeout
try:
torchaudio.save(output_path, generated_song, sample_rate=44100)
finally:
signal.alarm(0) # Cancel alarmdef save_audio_robust(audio, output_path, sample_rate=44100):
"""Save audio with fallback methods"""
# Method 1: Try torchaudio (fastest)
try:
print("Attempting save with torchaudio...")
torchaudio.save(output_path, audio, sample_rate=sample_rate)
print("✓ Successfully saved with torchaudio")
return True
except Exception as e:
print(f"⚠ torchaudio failed: {e}")
# Method 2: Try scipy
try:
print("Attempting save with scipy...")
import scipy.io.wavfile as wavfile
audio_np = audio.cpu().numpy()
if audio_np.dtype == np.float32:
audio_np = (audio_np * 32767).astype(np.int16)
wavfile.write(output_path, sample_rate, audio_np)
print("✓ Successfully saved with scipy")
return True
except Exception as e:
print(f"⚠ scipy failed: {e}")
# Method 3: Try soundfile
try:
print("Attempting save with soundfile...")
import soundfile as sf
audio_np = audio.cpu().numpy()
sf.write(output_path, audio_np.T, sample_rate)
print("✓ Successfully saved with soundfile")
return True
except Exception as e:
print(f"⚠ soundfile failed: {e}")
raise RuntimeError("All save methods failed")- Validate tensor shape before saving
- Check dtype compatibility
- Print audio statistics for debugging
- Set 60-second timeout on save operation
- Provide clear error if timeout occurs
- Allow user to interrupt
- Try torchaudio first
- Fall back to scipy if needed
- Fall back to soundfile as last resort
- Verify each save method works
- Check output file integrity
- Verify audio playback
torchaudio - already installed
scipy - audio.io.wavfile for WAV
soundfile - advanced audio I/O
numpy - array operations
python -c "import scipy; print(scipy.__version__)"
python -c "import soundfile; print(soundfile.__version__)"
python -c "import numpy; print(numpy.__version__)"# Generate dummy audio tensor
audio = torch.randn(2, 4410000).to(torch.int16) # 100 seconds, 44.1kHz
# Try saving
save_audio_robust(audio, "test_output.wav", 44100)
# Verify file
print(f"File size: {os.path.getsize('test_output.wav')} bytes")python -c "import torchaudio; print(torchaudio.list_audio_backends())"python infer/infer.py \
--lrc-path output/test.lrc \
--ref-prompt "pop song" \
--audio-length 95 \
--output-dir output- Generation hangs during audio saving
- No output file created
- Process appears frozen
- No clear error message
- Audio saves successfully in <5 seconds
- Output file created and valid
- Clear progress messages
- Works even if preferred backend unavailable
| Codec | Format | torchaudio | scipy | soundfile | WSL |
|---|---|---|---|---|---|
| PCM | WAV | ✓ | ✓ | ✓ | ✓ |
| FLAC | FLAC | ✓ | ✗ | ✓ | ✓ |
| MP3 | MP3 | ✓ | ✗ | ✗ | ? |
| OGG | OGG | ✓ | ✗ | ✓ | ? |
Recommendation: Use WAV with PCM codec for maximum compatibility
Root Cause: Likely torchaudio.save() hanging due to backend issues in WSL
Solution: Implement robust multi-method audio saving with fallbacks
Expected Result: Audio saves reliably in <5 seconds regardless of backend
- Implement save_audio_robust() function
- Add audio tensor validation
- Add timeout protection
- Test each backend
- Update infer.py to use new saving method