---
license: apache-2.0
tags:
  - audio.cpp
  - gguf
  - speech-separation
base_model: alibabasglab/MossFormer2_SS_16K
---

# MossFormer2 GGUF

Use this model with [audio.cpp](https://github.com/0xShug0/audio.cpp).
It separates a mixture into two 16 kHz mono speaker tracks. F32 retains the
original tensors; F16 reduces file size while keeping small affine and
positional tensors in F32. F32 remains the default.

Source weights: [alibabasglab/MossFormer2_SS_16K](https://huggingface.co/alibabasglab/MossFormer2_SS_16K).
Reference implementation: [ClearerVoice-Studio at 6b3774d](https://github.com/modelscope/ClearerVoice-Studio/tree/6b3774dc79c46ae8bed2a4fa5f706f0ac8c75c61).
The GGUF includes the configuration and audio.cpp model spec.

## Usage

```bash
audiocpp_cli --task sep --family mossformer2 \
  --model /path/to/mossformer2-ss-16k-f32.gguf \
  --backend cuda --audio mixture.wav --out-dir separated --log
```

Outputs: `speaker_1.wav` and `speaker_2.wav`.
See [model options and conversion instructions](https://github.com/0xShug0/audio.cpp/blob/main/docs/models/mossformer2.md).

The default is two-second windows with a 1.5-second hop, following the upstream
NumPy inference interface. Speaker numbers are output lanes, not persistent
identities: upstream does not match speakers across windows. Use
`--request-option audio_chunk_duration_sec=0` for whole-file processing, at the
cost of memory growth with input length. Neither setting guarantees clean
separation of arbitrary recordings or mixtures with more than two speakers.

## Controlled Parity

Parity checks are separate from performance measurements. Both implementations
use original F32 weights; CUDA parity runs use `NVIDIA_TF32_OVERRIDE=0`.
The reference is ClearVoice's NumPy interface, without its file-loader audio
normalization. C++ float32 WAV output avoids PCM clipping during comparison.

| Check | C++ vs Python waveform cosine |
| --- | ---: |
| CUDA: default, whole-file, and one-second windows | > 0.9999999999999 |
| CUDA: 120-second windowed input | > 0.9999999999999 |
| Vulkan: the same three settings | > 0.99999995 |
| CPU: two-second unnormalized network output | > 0.9999999999999 |

Returning to the default window after changing graph sizes produces
byte-identical WAVs on CUDA and Vulkan. CPU layout cleanup retains equivalent
audio; it is not claimed to be byte-identical to Python.

## Warm Performance

RTX 5090, Ryzen 9 7900X, eight CPU threads, PyTorch 2.11.0+cu128, original F32
weights. No TF32 override or other precision controls are used for performance.
Both implementations use two-second windows, a 1.5-second hop, and output RMS
normalization. A short request warms the model before the reported request.
C++ uses a Debug, multi-backend build with logging enabled.

The CUDA input is a 120-second stress fixture made by concatenating and repeating
two official mixtures, not a continuous real-world meeting. The CPU input is
the official 4.4085625-second mixture. Times exclude model loading and file
writing. Memory is sampled process peak during the request sequence, not just
framework tensor allocations; sampling interval is 50 ms.

| Backend / input | Implementation | Warm time | RTF | Peak VRAM | Peak RSS |
| --- | --- | ---: | ---: | ---: | ---: |
| CUDA / 120 s | Python | 4.293 s | 0.03577 | 1,132 MiB | 1,860 MiB |
| CUDA / 120 s | C++ | 2.752 s | 0.02293 | 1,058 MiB | 672 MiB |
| CPU / 4.409 s | Python | 10.992 s | 2.493 | 0 | 1,607 MiB |
| CPU / 4.409 s | C++ | 11.344 s | 2.573 | 0 | 702 MiB |

These are individual warmed measurements, not statistical confidence intervals.
C++ is faster on the measured CUDA workload; the measured CPU request remains
slightly slower than Python.

## F16 and Continuous Dialogue

A separate CUDA comparison used a continuous 167.333-second two-speaker
conversation generated by VibeVoice 1.5B, rather than repeated short mixtures.
RTX 5090, eight threads, Debug build, logging enabled, default separation windows
and normalization, no precision overrides. Each session ran a short warmup,
the conversation, then the same short request. Peak VRAM was sampled per process
every 20 ms. Both packages produced byte-identical short outputs before and after
the long request. Python was not rerun for this comparison.

| C++ package | Warm time | RTF | Peak VRAM | File size |
| --- | ---: | ---: | ---: | ---: |
| F32 | 3.788 s | 0.02263 | 1,058 MiB | 212.79 MiB |
| F16 | 3.759 s | 0.02246 | 970 MiB | 106.89 MiB |

F16 reduces measured peak VRAM by 8.3%; the small timing difference does not
establish a speedup. Against C++ F32, worst waveform cosine on the official
mixture (chunked and whole-file) was 0.999999828, with maximum RMSE 0.00005633.
Conversation track cosines were 0.999975265 and 0.999688800. This measures dtype
drift, not separation accuracy against isolated source recordings.
F16 was retained over BF16 because it was more accurate; BF16 is not packaged.