Comfy-Org/ComfyUI · error · ValueError
SeedVR2 upsample expected {self.channels} channels, got {hid
Error message
SeedVR2 upsample expected {self.channels} channels, got {hidden_states.shape[1]}. What it means
SeedVR2VaeUpsample first projects with a 1x1 conv sized for exactly self.channels inputs, then pixel-shuffles. If the incoming hidden_states channel count differs from the block's configured channels, the projection would fail with a confusing shape error, so the block pre-checks and raises with both numbers. In a correctly built VAE this never fires; it indicates a config mismatch or a manually mis-wired block graph.
Source
Thrown at comfy/ldm/seedvr/vae.py:712
self.spatial_up = spatial_up
self.temporal_ratio = 2 if temporal_up else 1
self.spatial_ratio = 2 if spatial_up else 1
upscale_ratio = (self.spatial_ratio**2) * self.temporal_ratio
self.upscale_conv = ops.Conv3d(
self.channels, self.channels * upscale_ratio, kernel_size=1, padding=0
)
self.conv = conv
def forward(
self,
hidden_states: torch.FloatTensor,
memory_state=None,
memory_cache=None,
) -> torch.FloatTensor:
if hidden_states.shape[1] != self.channels:
raise ValueError(f"SeedVR2 upsample expected {self.channels} channels, got {hidden_states.shape[1]}.")
hidden_states = self.upscale_conv(hidden_states)
b, channels, f, h, w = hidden_states.shape
c = channels // (self.spatial_ratio * self.spatial_ratio * self.temporal_ratio)
hidden_states = hidden_states.view(b, self.spatial_ratio, self.spatial_ratio, self.temporal_ratio, c, f, h, w)
hidden_states = hidden_states.permute(0, 4, 5, 3, 6, 1, 7, 2).reshape(
b,
c,
f * self.temporal_ratio,
h * self.spatial_ratio,
w * self.spatial_ratio,
)
if self.temporal_up and memory_state != MemoryState.ACTIVE:
hidden_states = remove_head(hidden_states)
hidden_states = self.conv(hidden_states, memory_state=memory_state, memory_cache=memory_cache)
View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Make the upsample's channels equal the preceding block's output channels in the VAE config.
- Diff your VAE config against the official SeedVR2 VAE config for channel progression.
- If porting weights, verify each block's expected channel count from the state dict shapes and fix the config accordingly.
- Avoid manually inserting upsample blocks; use the standard encoder/decoder builders.
Defensive patterns
Strategy: validation
Validate before calling
def validate_upsample_input(block, hidden_states):
if hidden_states.shape[1] != block.channels:
raise ValueError(f"block expects {block.channels} channels, got {hidden_states.shape[1]}; fix VAE config")
return hidden_states Type guard
def channels_match_block(x, block) -> bool:
return x.dim() >= 2 and x.shape[1] == block.channels Prevention
- Keep VAE configs canonical — derive channel transitions programmatically from block_out_channels.
- After any config edit, run a 1-frame dummy tensor through the VAE to catch wiring errors.
- Validate checkpoint weight shapes against block channels before loading.
When it happens
Trigger: Instantiating SeedVR2VaeUpsample with one channel count but feeding it a tensor from a block with a different count; editing block_out_channels inconsistently; inserting/removing a block in the encoder/decoder without updating channels.
Common situations: Hand-modified VAE configs where in_channels of the upsample does not match the previous block's out_channels; conversion scripts that miscalculate channel transitions when porting checkpoints.
Related errors
- SeedVR2 downsample expected {self.channels} channels, got {h
- SeedVR2 encoder only supports DownEncoderBlock3D, got {down_
- Unknown normalization type: {norm_type}
- Unknown activation type: {activation_type}
- Block with {block_type=} is not supported.
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/8896cba3ead947ec.
Report an issue: GitHub.