Stability-AI/generative-models · error · ValueError

input has {x.ndim} dims but target_dims is {target_dims}, wh

Error message

input has {x.ndim} dims but target_dims is {target_dims}, which is less

What it means

append_dims adds trailing singleton dimensions to a tensor until it reaches target_dims. This ValueError is raised when the tensor already has MORE dimensions than target_dims (dims_to_append is negative), meaning the caller passed a mismatched rank — appending cannot remove dims, so it fails loudly rather than silently reshaping.

Source

Thrown at sgm/util.py:196

def get_obj_from_str(string, reload=False, invalidate_cache=True):
    module, cls = string.rsplit(".", 1)
    if invalidate_cache:
        importlib.invalidate_caches()
    if reload:
        module_imp = importlib.import_module(module)
        importlib.reload(module_imp)
    return getattr(importlib.import_module(module, package=None), cls)


def append_zero(x):
    return torch.cat([x, x.new_zeros([1])])


def append_dims(x, target_dims):
    """Appends dimensions to the end of a tensor until it has target_dims dimensions."""
    dims_to_append = target_dims - x.ndim
    if dims_to_append < 0:
        raise ValueError(
            f"input has {x.ndim} dims but target_dims is {target_dims}, which is less"
        )
    return x[(...,) + (None,) * dims_to_append]


def load_model_from_config(config, ckpt, verbose=True, freeze=True):
    print(f"Loading model from {ckpt}")
    if ckpt.endswith("ckpt"):
        pl_sd = torch.load(ckpt, map_location="cpu")
        if "global_step" in pl_sd:
            print(f"Global Step: {pl_sd['global_step']}")
        sd = pl_sd["state_dict"]
    elif ckpt.endswith("safetensors"):
        sd = load_safetensors(ckpt)
    else:
        raise NotImplementedError

    model = instantiate_from_config(config.model)

View on GitHub (pinned to e8cd657656)

Solutions

  1. Increase target_dims to at least x.ndim (e.g. 5 for video tensors)
  2. Check x.ndim before calling and squeeze unintended dims with x.squeeze(dim) if a dim was added accidentally
  3. If you need to match a reference tensor's rank, use target_dims=x.dim() of the tensor you are broadcasting against

Example fix

// before
noise = append_dims(noise, 4)  # noise is 5D video latent
// after
noise = append_dims(noise, 5)  # match video latent rank
Defensive patterns

Strategy: validation

Validate before calling

def safe_append_dims(x, target_dims):
    assert x.ndim <= target_dims, f"x has {x.ndim} dims, target_dims={target_dims} too small"
    return append_dims(x, target_dims)

Type guard

def fits_target_dims(x: torch.Tensor, target_dims: int) -> bool:
    return x.ndim <= target_dims

Try / catch

try:
    out = append_dims(x, target_dims)
except ValueError as e:
    logger.error("rank mismatch: %s (x.ndim=%d, target=%d)", e, x.ndim, target_dims)
    raise

Prevention

When it happens

Trigger: Calling sgm.util.append_dims(x, target_dims) where x.ndim > target_dims, e.g. append_dims on a 5D video tensor with target_dims=4, or reusing a target_dims constant tuned for 2D images on higher-rank inputs.

Common situations: Sampler/model code (do_img2img, forward, __call__, _forward, sampler_step, ancestral_euler_step) shaping noise or timesteps: switching between image (4D) and video (5D) models without updating target_dims, or accidentally passing an already-broadcast tensor with an extra batch/time dim.

Related errors


AI-assisted analysis of Stability-AI/generative-models@e8cd657656 (2026-08-29). Data as JSON: /api/errors/06de5397d15f45fd. Report an issue: GitHub.