deezer/spleeter · error · NotImplementedError

Function only implemented for concat_axis equal to 0 or 1

Error message

Function only implemented for concat_axis equal to 0 or 1

What it means

spleeter's `sync_apply` (spleeter/utils/tensor.py:21) applies `func` to the concatenation of all tensors in `tensor_dict` along `concat_axis`, then splits the result back per key. The split-back slicing logic (lines 59-67) is hard-coded for rank-3 tensors using exactly two non-concat axes, so any `concat_axis` other than 0 or 1 raises this NotImplementedError at call time, before any TensorFlow op runs. It is a deliberate guard, not a bug: the function has only ever been implemented for axis 0 (batch) and 1 (default, e.g. channel/time).

Source

Thrown at spleeter/utils/tensor.py:51

    Note:
        All tensor are assumed to be the same shape.

    Parameters:
        tensor_dict (Dict[str, tf.Tensor]):
            A dictionary of tensor.
        func (Callable):
            Function to be applied to the concatenation of the tensors in
            `tensor_dict`.
        concat_axis (int):
            (Optional) The axis on which to perform the concatenation.

    Returns:
        Dict[str, tf.Tensor]:
            Processed tensors dictionary with the same name (keys) as input
            tensor_dict.
    """
    if concat_axis not in {0, 1}:
        raise NotImplementedError(
            "Function only implemented for concat_axis equal to 0 or 1"
        )
    tensor_list = list(tensor_dict.values())
    concat_tensor = tf.concat(tensor_list, concat_axis)
    processed_concat_tensor = func(concat_tensor)
    tensor_shape = tf.shape(list(tensor_dict.values())[0])
    D = tensor_shape[concat_axis]
    if concat_axis == 0:
        return {
            name: processed_concat_tensor[index * D : (index + 1) * D, :, :]
            for index, name in enumerate(tensor_dict)
        }
    return {
        name: processed_concat_tensor[:, index * D : (index + 1) * D, :]
        for index, name in enumerate(tensor_dict)
    }

View on GitHub (pinned to c8854001ac)

Solutions

  1. Change concat_axis to 0 or 1 (the only supported values); the default is 1, so most callers should simply omit the argument.
  2. If you need axis -1 semantics for a rank-3 tensor, convert to axis 1 instead (for rank-3 tensors axis -1 == axis 2, so permute axes or restructure so the concat axis is 1).
  3. For other axes or higher-rank tensors, don't use sync_apply: apply func to the concatenated tensor yourself via tf.concat + tf.split, or extend the function's slicing logic to generalize the split-back step.
  4. Validate the axis before calling: `assert concat_axis in (0, 1)` in a wrapper so the failure is caught with a clearer message in your own code.

Example fix

// before
processed = sync_apply(tensor_dict, crop_fn, concat_axis=-1)

// after
processed = sync_apply(tensor_dict, crop_fn, concat_axis=1)
Defensive patterns

Strategy: validation

Validate before calling

from spleeter.utils.tensor import sync_apply

def safe_sync_apply(tensor_dict, func, concat_axis=1):
    if concat_axis not in (0, 1):
        raise ValueError(
            f"sync_apply supports concat_axis 0 or 1 only, got {concat_axis!r}"
        )
    return sync_apply(tensor_dict, func, concat_axis=concat_axis)

Type guard

def is_supported_concat_axis(axis) -> bool:
    return isinstance(axis, int) and not isinstance(axis, bool) and axis in (0, 1)

Try / catch

try:
    processed = sync_apply(tensor_dict, func, concat_axis=axis)
except NotImplementedError as e:
    # fall back to the default supported axis
    processed = sync_apply(tensor_dict, func, concat_axis=1)

Prevention

When it happens

Trigger: Calling `spleeter.utils.tensor.sync_apply(tensor_dict, func, concat_axis=N)` with N not in {0, 1} — e.g. concat_axis=2 or -1. Note that concat_axis=-1 also raises despite being a valid tf.concat axis, because the membership check `concat_axis not in {0, 1}` is on the literal value only. Custom augmentation pipelines that call sync_apply directly (or wrap it as random_time_crop / random_time_stretch / random_pitch_shift with a non-default concat_axis) trigger it.

Common situations: Writing a custom Spleeter data augmentation step that crops/stretches along a different axis than the built-in transforms; passing -1 or 2 assuming tf.concat-style negative axis indexing is supported; copying spleeter's augmentation code into a training pipeline for higher-rank tensors (e.g. >3D spectrogram batches) where axis 0/1 slicing no longer matches; upgrading code where tensor rank changed so the previously-correct axis no longer is.

Related errors


AI-assisted analysis of deezer/spleeter@c8854001ac (2026-08-28). Data as JSON: /api/errors/3c8d40e307ce1945. Report an issue: GitHub.