VoxCPM2 Swahili β€” Full SFT

A full fine-tune of VoxCPM2 on Swahili speech data. The model was trained by FarmerlineML for the Darli AI agricultural voice assistant.

The model generates Swahili speech using a reference recording to preserve the target speaker's voice characteristics.

Training Details

Parameter Value
Base model openbmb/VoxCPM2 (2B)
Language Swahili / Kiswahili (sw)
Method Full SFTβ€”all model parameters trained
Learning rate 1e-5
Batch size 1
Gradient accumulation 16
Effective batch size 16
AudioVAE input sample rate 16 kHz
Final training step 2985

Validation Loss

Step loss/total loss/diff loss/stop
0 1.301021 0.976434 0.216392
500 0.920041 0.854645 0.043597
1000 0.904256 0.847106 0.038100
1500 0.967527 0.931794 0.023822
2000 0.899414 0.846611 0.035202
2500 0.998210 0.927028 0.047455

Dataset

Update the dataset repository ID in this model card if your Swahili training dataset uses a different Hugging Face repository.

Usage

from voxcpm import VoxCPM
import numpy as np
import soundfile as sf

model = VoxCPM.from_pretrained(
    "FarmerlineML/voxcpm2-swahili-sft",
    load_denoiser=False,
)

def trim_audio(
    wav,
    sr,
    silence_thresh=0.01,
    max_silence_secs=2.0,
):
    """Trim a long silent tail from generated audio."""
    abs_wav = np.abs(wav)
    window = int(0.05 * sr)
    n_windows = len(abs_wav) // window
    max_silent_windows = int(max_silence_secs / 0.05)

    silence_count = 0
    cut_sample = len(wav)

    for window_index in range(n_windows):
        start = window_index * window
        end = (window_index + 1) * window
        chunk = abs_wav[start:end]

        if chunk.max() < silence_thresh:
            silence_count += 1

            if silence_count >= max_silent_windows:
                cut_sample = (
                    window_index - max_silent_windows + 1
                ) * window
                break
        else:
            silence_count = 0

    padding = int(0.1 * sr)
    final_sample = min(cut_sample + padding, len(wav))

    return wav[:final_sample]

text = "Habari za asubuhi. Karibu kwenye huduma ya Farmerline."

wav = model.generate(
    text=text,
    reference_wav_path="your_swahili_speaker.wav",
    cfg_value=2.0,
    inference_timesteps=15,
    retry_badcase=False,
    max_len=max(50, len(text) * 4),
)

wav = trim_audio(wav, 48000)
sf.write("output.wav", wav, 48000)

The example sentence means: β€œGood morning. Welcome to the Farmerline service.”

Repository Structure

β”œβ”€β”€ model.safetensors          # Fine-tuned model weights
β”œβ”€β”€ audiovae.pth               # AudioVAE decoder
β”œβ”€β”€ config.json                # Model architecture configuration
β”œβ”€β”€ tokenizer.json             # Tokenizer vocabulary and rules
β”œβ”€β”€ tokenizer_config.json      # Tokenizer configuration
β”œβ”€β”€ special_tokens_map.json    # Special-token definitions
β”œβ”€β”€ training/
β”‚   β”œβ”€β”€ train.log              # Complete training log
β”‚   β”œβ”€β”€ val_loss_summary.txt   # Validation losses by checkpoint
β”‚   β”œβ”€β”€ training_state.json    # Final training state
β”‚   └── scheduler.pth          # Learning-rate scheduler state
└── tensorboard/               # TensorBoard event files

Notes

  • A reference audio recording is required during inference to anchor the generated audio to a speaker identity.
  • The reference recording should contain clean Swahili speech with minimal background noise and reverberation.
  • Use max_len=max(50, len(text) * 4) to reduce the risk of hallucinated audio after the sentence ends.
  • Trimming long silent tails after generation is recommended.
  • Generated output in this example is saved at 48 kHz.
Downloads last month
54
Safetensors
Model size
2B params
Tensor type
F32
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for FarmerlineML/voxcpm2-swahili-sft

Base model

openbmb/VoxCPM2
Finetuned
(28)
this model