microsoft/VibeVoice · error · ValueError

GroupNorm doesn't support causal evaluation.

Error message

GroupNorm doesn't support causal evaluation.

What it means

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.

Source

Thrown at vibevoice/modular/modular_vibevoice_tokenizer.py:119

    elif norm == 'spectral_norm':
        return nn.utils.spectral_norm(module)
    else:
        # We already check was in CONV_NORMALIZATION, so any other choice
        # doesn't need reparametrization.
        return module


def get_norm_module(module: nn.Module, causal: bool = False, norm: str = 'none', **norm_kwargs) -> nn.Module:
    """Return the proper normalization module. If causal is True, this will ensure the returned
    module is causal, or return an error if the normalization doesn't support causal evaluation.
    """
    assert norm in CONV_NORMALIZATIONS
    if norm == 'layer_norm':
        assert isinstance(module, nn.modules.conv._ConvNd)
        return ConvLayerNorm(module.out_channels, **norm_kwargs)
    elif norm == 'time_group_norm':
        if causal:
            raise ValueError("GroupNorm doesn't support causal evaluation.")
        assert isinstance(module, nn.modules.conv._ConvNd)
        return nn.GroupNorm(1, module.out_channels, **norm_kwargs)
    else:
        return nn.Identity()


def get_extra_padding_for_conv1d(x: torch.Tensor, kernel_size: int, stride: int,
                                padding_total: int = 0) -> int:
    """Calculate extra padding needed for convolution to have the same output length"""
    length = x.shape[-1]
    n_frames = (length - kernel_size + padding_total) / stride + 1
    ideal_length = (math.ceil(n_frames) - 1) * stride + (kernel_size - padding_total)
    return ideal_length - length


def pad1d(x: torch.Tensor, paddings: tp.Tuple[int, int], mode: str = 'zero', value: float = 0.):
    """Pad 1D input with handling for small inputs in reflect mode"""
    length = x.shape[-1]

View on GitHub (pinned to 94da20d98b)

Solutions

  1. Use a causal-compatible norm: 'layer_norm' (ConvLayerNorm) or 'none' when causal=True.
  2. Or set causal=False if the non-causal GroupNorm behavior is acceptable for your block.
  3. Check the tokenizer config's norm field before building; reject time_group_norm+causal combos early with a clear message.
  4. For streaming models, use the config presets shipped with the repo rather than hand-editing norm.

Example fix

# before
Convlayer(dim, dim, norm="time_group_norm", causal=True)  # ValueError

# after
Convlayer(dim, dim, norm="layer_norm", causal=True)  # causal-safe norm
Defensive patterns

Strategy: validation

Validate before calling

CAUSAL_NORMS = {"layer_norm", "none"}
if causal and norm not in CAUSAL_NORMS:
    raise SystemExit(f"norm={norm!r} cannot be causal; use one of {CAUSAL_NORMS}")

Type guard

def is_causal_norm(norm: str) -> bool:
    return norm in ("layer_norm", "none")

Prevention

When it happens

Trigger: 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)).

Common situations: 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.

Related errors


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