microsoft/VibeVoice · error · ValueError
Unsupported audio type: {type(audio)}
Error message
Unsupported audio type: {type(audio)} What it means
`save_audio()` only accepts `torch.Tensor`, `np.ndarray`, or a `list` of tensors/arrays (see the Union in its signature at vibevoice/processor/vibevoice_tokenizer_processor.py:284). Any other type falls through to `raise ValueError(f"Unsupported audio type: {type(audio)}")` before any file I/O happens. It is an input-contract error raised by explicit type dispatch, not by serialization.
Source
Thrown at vibevoice/processor/vibevoice_tokenizer_processor.py:331
raise ImportError(
"soundfile is required to save audio files. "
"Install it with: pip install soundfile"
)
# Ensure audio is in the right format
if isinstance(audio, torch.Tensor):
# Convert PyTorch tensor to numpy
audio_np = audio.float().detach().cpu().numpy()
elif isinstance(audio, np.ndarray):
audio_np = audio
elif isinstance(audio, list):
# Handle list of tensors or arrays
if all(isinstance(a, torch.Tensor) for a in audio):
audio_np = [a.float().detach().cpu().numpy() for a in audio]
else:
audio_np = audio
else:
raise ValueError(f"Unsupported audio type: {type(audio)}")
saved_paths = []
# Handle based on shape or type
if isinstance(audio_np, list):
# Multiple separate audios to save
output_dir = output_path
# Ensure output directory exists
os.makedirs(output_dir, exist_ok=True)
# Save each audio
for i, audio_item in enumerate(audio_np):
audio_item = self._prepare_audio_for_save(audio_item, normalize)
file_path = os.path.join(output_dir, f"{batch_prefix}{i}.wav")
sf.write(file_path, audio_item, sampling_rate)
saved_paths.append(file_path)
View on GitHub (pinned to 94da20d98b)
Solutions
- Convert the value to a supported type before saving: wrap tuples with `list(...)`, convert non-torch arrays with `torch.as_tensor(...)` or `np.asarray(...)`.
- If you meant to load audio, use the processor's audio-loading API (or soundfile/librosa) — `save_audio` only writes.
- For mixed lists (tensors + numpy), normalize first: `[a.numpy() if isinstance(a, torch.Tensor) else a for a in audio]`.
Example fix
# before tracks = tuple(w.cpu() for w in wavs) # tuple -> ValueError processor.save_audio(tracks, "out_dir") # after tracks = [w.detach().cpu().numpy() for w in wavs] # list of arrays processor.save_audio(tracks, "out_dir")
Defensive patterns
Strategy: type-guard
Validate before calling
import torch, numpy as np
def as_saveable(audio):
if isinstance(audio, (torch.Tensor, np.ndarray)):
return audio
if isinstance(audio, (list, tuple)):
return [a.detach().cpu().numpy() if isinstance(a, torch.Tensor) else a for a in audio]
raise TypeError(f"Cannot save audio of type {type(audio)!r}")
processor.save_audio(as_saveable(wav), "out.wav") Type guard
def is_saveable_audio(audio) -> bool:
import torch
if isinstance(audio, (torch.Tensor, np.ndarray)):
return True
return isinstance(audio, (list, tuple)) and all(
isinstance(a, (torch.Tensor, np.ndarray)) for a in audio
) Try / catch
try:
processor.save_audio(wav, out)
except ValueError as e:
if "Unsupported audio type" in str(e):
wav = list(wav) if isinstance(wav, tuple) else wav
processor.save_audio(wav, out)
else:
raise Prevention
- Normalize model outputs to a torch.Tensor or numpy array at the pipeline boundary, before passing to save_audio.
- Convert tuples to lists — the API accepts only list for multi-audio.
- Remember save_audio writes; never pass a file path as the audio argument.
When it happens
Trigger: Passing a Python tuple of tensors, a generator, a string path to a wav file, a JAX/TF tensor, or a 0-d/odd object to `save_audio()`. Also passing a nested list of lists, since only a flat list of torch.Tensors is converted element-wise.
Common situations: Pipeline code that collects outputs into tuples instead of lists, feeding a model output after `.cpu()` chained onto a tuple, or handing `save_audio` a file path expecting it to read audio (it only writes).
Related errors
- soundfile is required to save audio files. Install it with:
- Sample index {sample_idx} exceeds batch size {self.batch_siz
- load_audio_bytes_use_ffmpeg requires resample=True
- Audio input is required for ASR processing
- Unexpected audio shape: {audio.shape}
AI-assisted analysis of microsoft/VibeVoice@94da20d98b (2026-08-15).
Data as JSON: /api/errors/66473767d15847d7.
Report an issue: GitHub.