{"record":{"id":"60af3201dd7fc77e","repo":"microsoft/VibeVoice","slug":"segment-length-must-be-positive","errorCode":null,"errorMessage":"segment_length must be positive","messagePattern":"segment_length must be positive","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vibevoice/modular/modeling_vibevoice_asr.py","lineNumber":280,"sourceCode":"                    semantic_tokens = self.model.semantic_tokenizer.encode(speech_tensors.unsqueeze(1)).mean\n                    semantic_features = self.model.semantic_connector(semantic_tokens)\n            else:\n                # Long audio: streaming processing\n                # print(f\"Using streaming processing for long audio: {total_samples/sample_rate:.1f}s \"\n                #       f\"(segment size: {streaming_segment_duration}s)\")\n                \n                # Initialize caches for both tokenizers\n                acoustic_encoder_cache = VibeVoiceTokenizerStreamingCache()\n                semantic_encoder_cache = VibeVoiceTokenizerStreamingCache()\n                acoustic_mean_segments = []\n                semantic_mean_segments = []\n                sample_indices = torch.arange(batch_size, device=speech_tensors.device)\n                \n                # Helper function from batch_asr_sft_cache.py\n                def _iter_segments(total_length: int, segment_length: int):\n                    \"\"\"Iterate over audio segments with a given segment length.\"\"\"\n                    if segment_length <= 0:\n                        raise ValueError(\"segment_length must be positive\")\n                    for start in range(0, total_length, segment_length):\n                        end = min(start + segment_length, total_length)\n                        if end > start:\n                            yield start, end\n                \n                # Process each segment for both acoustic and semantic tokenizers\n                segments = list(_iter_segments(total_samples, segment_samples))\n                num_segments = len(segments)\n                for seg_idx, (start, end) in enumerate(segments):\n                    chunk = speech_tensors[:, start:end].contiguous()\n                    if chunk.numel() == 0:\n                        continue\n                    \n                    # Check if this is the final segment\n                    is_final = (seg_idx == num_segments - 1)\n                    \n                    # Encode chunk for acoustic tokenizer (don't sample yet)\n                    acoustic_encoder_output = self.model.acoustic_tokenizer.encode(","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/microsoft/VibeVoice/blob/94da20d98b2fa7688e9cbfaf7692ddb4954f7600/vibevoice/modular/modeling_vibevoice_asr.py#L262-L298","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a positive segment duration in seconds, e.g. streaming_segment_duration=4.0.","Validate the parameter at the call site: if duration is None or <= 0, use a sane default or skip streaming.","Check where the value originates (config/CLI) and give it a non-zero default.","Guard before calling: max(int(dur*24000), 1) only if truncation near zero is acceptable for your use case."],"exampleFix":"# before\nmodel.encode(speech, streaming_segment_duration=0)  # -> ValueError\n\n# after\nmodel.encode(speech, streaming_segment_duration=4.0)  # 4 s segments @ 24 kHz","handlingStrategy":"validation","validationCode":"SAMPLE_RATE = 24000\ndef valid_segment_samples(duration_s: float) -> int:\n    if duration_s is None or duration_s <= 0:\n        return int(4.0 * SAMPLE_RATE)  # sane default\n    n = int(duration_s * SAMPLE_RATE)\n    assert n > 0, \"segment duration too small\"\n    return n","typeGuard":"def is_positive_duration(d: object) -> bool:\n    return isinstance(d, (int, float)) and d > 0","tryCatchPattern":"try:\n    enc = model.encode(speech, streaming_segment_duration=dur)\nexcept ValueError:\n    enc = model.encode(speech, streaming_segment_duration=4.0)","preventionTips":["Never use 0 as a 'disabled' sentinel for segment duration","Pass duration in seconds against the fixed 24 kHz rate","Validate CLI/config-sourced durations before model calls"],"tags":["asr","streaming","segment-duration","valueerror","parameter-validation"],"backgroundTag":null,"analyzedSha":"94da20d98b2fa7688e9cbfaf7692ddb4954f7600","analyzedAt":"2026-08-15T04:12:07.418Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}