microsoft/VibeVoice · error · ValueError

segment_length must be positive

Error message

segment_length must be positive

What it means

In the streaming ASR path (modeling_vibevoice_asr.py), segment length is computed as int(streaming_segment_duration * 24000) and _iter_segments raises ValueError if it is <= 0. Because int() truncates, this fires when streaming_segment_duration is 0, negative, or so small that duration*24000 rounds to 0 (any value below ~4.2e-5 s).

Source

Thrown at vibevoice/modular/modeling_vibevoice_asr.py:280

                    semantic_tokens = self.model.semantic_tokenizer.encode(speech_tensors.unsqueeze(1)).mean
                    semantic_features = self.model.semantic_connector(semantic_tokens)
            else:
                # Long audio: streaming processing
                # print(f"Using streaming processing for long audio: {total_samples/sample_rate:.1f}s "
                #       f"(segment size: {streaming_segment_duration}s)")
                
                # Initialize caches for both tokenizers
                acoustic_encoder_cache = VibeVoiceTokenizerStreamingCache()
                semantic_encoder_cache = VibeVoiceTokenizerStreamingCache()
                acoustic_mean_segments = []
                semantic_mean_segments = []
                sample_indices = torch.arange(batch_size, device=speech_tensors.device)
                
                # Helper function from batch_asr_sft_cache.py
                def _iter_segments(total_length: int, segment_length: int):
                    """Iterate over audio segments with a given segment length."""
                    if segment_length <= 0:
                        raise ValueError("segment_length must be positive")
                    for start in range(0, total_length, segment_length):
                        end = min(start + segment_length, total_length)
                        if end > start:
                            yield start, end
                
                # Process each segment for both acoustic and semantic tokenizers
                segments = list(_iter_segments(total_samples, segment_samples))
                num_segments = len(segments)
                for seg_idx, (start, end) in enumerate(segments):
                    chunk = speech_tensors[:, start:end].contiguous()
                    if chunk.numel() == 0:
                        continue
                    
                    # Check if this is the final segment
                    is_final = (seg_idx == num_segments - 1)
                    
                    # Encode chunk for acoustic tokenizer (don't sample yet)
                    acoustic_encoder_output = self.model.acoustic_tokenizer.encode(

View on GitHub (pinned to 94da20d98b)

Solutions

  1. Pass a positive segment duration in seconds, e.g. streaming_segment_duration=4.0.
  2. Validate the parameter at the call site: if duration is None or <= 0, use a sane default or skip streaming.
  3. Check where the value originates (config/CLI) and give it a non-zero default.
  4. Guard before calling: max(int(dur*24000), 1) only if truncation near zero is acceptable for your use case.

Example fix

# before
model.encode(speech, streaming_segment_duration=0)  # -> ValueError

# after
model.encode(speech, streaming_segment_duration=4.0)  # 4 s segments @ 24 kHz
Defensive patterns

Strategy: validation

Validate before calling

SAMPLE_RATE = 24000
def valid_segment_samples(duration_s: float) -> int:
    if duration_s is None or duration_s <= 0:
        return int(4.0 * SAMPLE_RATE)  # sane default
    n = int(duration_s * SAMPLE_RATE)
    assert n > 0, "segment duration too small"
    return n

Type guard

def is_positive_duration(d: object) -> bool:
    return isinstance(d, (int, float)) and d > 0

Try / catch

try:
    enc = model.encode(speech, streaming_segment_duration=dur)
except ValueError:
    enc = model.encode(speech, streaming_segment_duration=4.0)

Prevention

When it happens

Trigger: Calling the streaming ASR encode with streaming_segment_duration=0.0, a negative value, or None coerced to 0; also total_samples > segment_samples being true while segment_samples == 0 (always true for positive audio) makes the streaming branch reachable with the bad value.

Common situations: Config default of 0 used as 'disabled' sentinel misread as a valid duration; unit confusion (passing seconds vs milliseconds scaled wrong); CLI flag parsed to 0 on missing argument.

Related errors


AI-assisted analysis of microsoft/VibeVoice@94da20d98b (2026-08-15). Data as JSON: /api/errors/60af3201dd7fc77e. Report an issue: GitHub.