Skip to content

Bugs in MossFormer2_SE_48K direct NumPy inference for audio longer than 20 seconds #169

Description

@f0sta1

Hello! I found several bugs in the direct NumPy/tensor-to-tensor inference path for MossFormer2_SE_48K in clearvoice/utils/decode_batch.py.

I use the official NumPy API:

audio = np.reshape(audio, [1, audio.shape[0]]).astype(np.float32)

model = ClearVoice(
    task="speech_enhancement",
    model_names=["MossFormer2_SE_48K"]
)

output = model(audio, False)

Short audio works correctly, but audio longer than one_time_decode_length (20 seconds) enters the segmented inference branch and exposes several issues.

1. Incorrect input length calculation

The input has shape [batch, samples], but the code uses:

input_len = inputs.shape[0]

For an input of shape (1, 9240399), this sets input_len to 1 instead of 9240399.

Fix:

input_len = inputs.shape[-1]

2. Incorrect indexing of the output tensor

outputs is created with shape [batch, samples]:

outputs = torch.from_numpy(np.zeros((b, t)))

but later it is indexed with three indices:

outputs[batch_idx, batch_idx, ...]

Fix:

outputs[batch_idx, ...]

This applies to both output assignments in the segmented inference loop.

3. Padded output is not trimmed to the original input length

For a 60-second, 48 kHz mono input:

Input shape:  (1, 2880000)
Output shape: (1, 3168000)

The 60-second input therefore produced 66 seconds of output.

Fix:

outputs = outputs[:, :input_len]

before the final return.

Results after the fixes

After these three fixes, a 60-second file completed successfully with the exact original output length:

INPUT duration=60.000 sample_rate=48000 samples=2880000 dtype=float32
NUMPY input_shape=(1, 2880000) dtype=float32
TIMING inference=74.087
NUMPY output_shape=(1, 2880000) dtype=float64
TIMING total=75.633

A longer file that previously caused the Python process to terminate during inference with exit code 9 and empty stderr also completed successfully after the fixes:

INPUT duration=192.508 sample_rate=48000 samples=9240399 dtype=float32
NUMPY input_shape=(1, 9240399) dtype=float32
TIMING inference=321.712
NUMPY output_shape=(1, 9240399) dtype=float64
TIMING total=323.386

Before the fixes, the same 192.508-second file failed during the direct NumPy inference call with:

Exit code: 9
stderr:

Exact diff

@@ -334,7 +334,7 @@
-    input_len = inputs.shape[0]  # Get the length of the input audio
+    input_len = inputs.shape[-1]  # Get the number of audio samples

@@ -408,10 +408,10 @@
-                        outputs[batch_idx, batch_idx, current_idx:current_idx + window - give_up_length] = output_segment[:-give_up_length]
+                        outputs[batch_idx, current_idx:current_idx + window - give_up_length] = output_segment[:-give_up_length]
                     else:
                         output_segment = output_segment[-window:]
-                        outputs[batch_idx, batch_idx, current_idx + give_up_length:current_idx + window - give_up_length] = output_segment[give_up_length:-give_up_length]
+                        outputs[batch_idx, current_idx + give_up_length:current_idx + window - give_up_length] = output_segment[give_up_length:-give_up_length]

@@ -476,6 +476,9 @@
+    # Trim padded output back to the exact original input length.
+    outputs = outputs[:, :input_len]
+
     return outputs.numpy() / MAX_WAV_VALUE

Environment

* macOS on Apple Silicon
* Python 3.11
* Model: MossFormer2_SE_48K
* Input: mono WAV, 48 kHz, float32
* API mode: direct NumPy/tensor-to-tensor inference through ClearVoice

Thank you for making ClearerVoice-Studio available. I hope these findings are useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions