{"record":{"id":"795558497274db71","repo":"microsoft/VibeVoice","slug":"groupnorm-doesn-t-support-causal-evaluation","errorCode":null,"errorMessage":"GroupNorm doesn't support causal evaluation.","messagePattern":"GroupNorm doesn't support causal evaluation\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vibevoice/modular/modular_vibevoice_tokenizer.py","lineNumber":119,"sourceCode":"    elif norm == 'spectral_norm':\n        return nn.utils.spectral_norm(module)\n    else:\n        # We already check was in CONV_NORMALIZATION, so any other choice\n        # doesn't need reparametrization.\n        return module\n\n\ndef get_norm_module(module: nn.Module, causal: bool = False, norm: str = 'none', **norm_kwargs) -> nn.Module:\n    \"\"\"Return the proper normalization module. If causal is True, this will ensure the returned\n    module is causal, or return an error if the normalization doesn't support causal evaluation.\n    \"\"\"\n    assert norm in CONV_NORMALIZATIONS\n    if norm == 'layer_norm':\n        assert isinstance(module, nn.modules.conv._ConvNd)\n        return ConvLayerNorm(module.out_channels, **norm_kwargs)\n    elif norm == 'time_group_norm':\n        if causal:\n            raise ValueError(\"GroupNorm doesn't support causal evaluation.\")\n        assert isinstance(module, nn.modules.conv._ConvNd)\n        return nn.GroupNorm(1, module.out_channels, **norm_kwargs)\n    else:\n        return nn.Identity()\n\n\ndef get_extra_padding_for_conv1d(x: torch.Tensor, kernel_size: int, stride: int,\n                                padding_total: int = 0) -> int:\n    \"\"\"Calculate extra padding needed for convolution to have the same output length\"\"\"\n    length = x.shape[-1]\n    n_frames = (length - kernel_size + padding_total) / stride + 1\n    ideal_length = (math.ceil(n_frames) - 1) * stride + (kernel_size - padding_total)\n    return ideal_length - length\n\n\ndef pad1d(x: torch.Tensor, paddings: tp.Tuple[int, int], mode: str = 'zero', value: float = 0.):\n    \"\"\"Pad 1D input with handling for small inputs in reflect mode\"\"\"\n    length = x.shape[-1]","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/microsoft/VibeVoice/blob/94da20d98b2fa7688e9cbfaf7692ddb4954f7600/vibevoice/modular/modular_vibevoice_tokenizer.py#L101-L137","documentation":"In the tokenizer/SEANet builder (modular_vibevoice_tokenizer.py get_norm_module), norm='time_group_norm' maps to nn.GroupNorm over the time axis, which needs future frames and therefore cannot be causal. Requesting causal=True together with that norm raises ValueError by design.","triggerScenarios":"Constructing Convlayer/SEANet encoder blocks with norm='time_group_norm' and causal=True — typically a streaming or real-time tokenizer config where causal=True is the default (kwargs.get('causal', True)).","commonSituations":"Enabling streaming/causal mode on a config originally tuned for non-causal training; hand-writing a tokenizer config that mixes time_group_norm with causal convolution; defaults flipping causal to True in the streaming code path.","solutions":["Use a causal-compatible norm: 'layer_norm' (ConvLayerNorm) or 'none' when causal=True.","Or set causal=False if the non-causal GroupNorm behavior is acceptable for your block.","Check the tokenizer config's norm field before building; reject time_group_norm+causal combos early with a clear message.","For streaming models, use the config presets shipped with the repo rather than hand-editing norm."],"exampleFix":"# before\nConvlayer(dim, dim, norm=\"time_group_norm\", causal=True)  # ValueError\n\n# after\nConvlayer(dim, dim, norm=\"layer_norm\", causal=True)  # causal-safe norm","handlingStrategy":"validation","validationCode":"CAUSAL_NORMS = {\"layer_norm\", \"none\"}\nif causal and norm not in CAUSAL_NORMS:\n    raise SystemExit(f\"norm={norm!r} cannot be causal; use one of {CAUSAL_NORMS}\")","typeGuard":"def is_causal_norm(norm: str) -> bool:\n    return norm in (\"layer_norm\", \"none\")","tryCatchPattern":null,"preventionTips":["Pair causal=True only with layer_norm or none","Don't flip causal on configs tuned for time_group_norm","Validate norm/causal combinations at config load"],"tags":["tokenizer","normalization","causal","groupnorm","valueerror"],"backgroundTag":null,"analyzedSha":"94da20d98b2fa7688e9cbfaf7692ddb4954f7600","analyzedAt":"2026-08-15T04:12:07.418Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}