How to Clone Your Voice Locally on a MacBook, for Free, With VoxCPM2

A step-by-step guide to local voice cloning on Apple Silicon with the open-source VoxCPM2. No API keys, no subscription, no cloud. Reference audio, style prefixes, and the normalize step nobody mentions.

Three months ago I was paying ElevenLabs $22 a month to generate voiceovers. Last week I cloned my own voice locally, for free, on an M1 MacBook, with an open-source tool called VoxCPM2. The quality isn’t identical. It was close enough that I narrated a real reel with it, and I’m not going back.

Here is exactly how I did it.

Why I stopped paying

ElevenLabs is genuinely good. Clean clones, simple interface, well-documented API. But $22 a month for a side project that generates four or five voiceovers is hard to justify when you’re funding a product yourself. Most open-source TTS gives you a robot voice, and the few good ones need a GPU. VoxCPM2 runs on CPU, works on an M1, and does real voice cloning rather than generic text-to-speech.

You give it a reference clip of your voice and some text, and it speaks the text in your voice. Everything runs on your machine. The output quality depends on three things: the length and cleanliness of your reference audio, whether you use a style prefix, and how you normalize the result. All three matter.

Step 1: Install

You need Python 3.11. I use conda to keep things isolated.

conda create -n voiceclone python=3.11 -y
conda activate voiceclone
pip install voxcpm soundfile numpy scipy

The model weights download on first run, about 5 to 8 minutes on a decent connection.

One thing that will save your fans: cap the threads, or VoxCPM grabs every core and the MacBook sounds like it’s about to take off.

export OMP_NUM_THREADS=5 MKL_NUM_THREADS=5 OPENBLAS_NUM_THREADS=5 PYTORCH_NUM_THREADS=5

With 5 threads on a 10-core M1, CPU sits around 50 to 56 percent, comfortable for background generation while you work. Set these before every generation command.

Step 2: Build the reference audio

This is the step that decides everything. Garbage in, garbage out.

You want at least 60 seconds of your voice, ideally two to three minutes. Clean audio, no music, no room echo. Mono, 16kHz. I recorded five short clips on the built-in mic (not ideal, more on that below), then merged and resampled them:

import soundfile as sf, numpy as np
from scipy.signal import resample_poly
from math import gcd

files = ['one.wav','two.wav','three.wav','four.wav','five.wav']
target_sr = 16000
chunks = []
for f in files:
    data, sr = sf.read(f)
    if data.ndim > 1:
        data = data.mean(axis=1)
    g = gcd(target_sr, sr)
    chunks.append(resample_poly(data, target_sr // g, sr // g))
sf.write('speaker.wav', np.concatenate(chunks), target_sr, subtype='PCM_16')

Mine came out to 142 seconds, enough for the model to catch tone, pacing, and cadence.

Step 3: Generate, and fix the flat delivery

voxcpm clone \
  --text "Your text here." \
  --reference-audio speaker.wav \
  --output raw.wav

The first time I ran this, the output was flat, like a voice actor reading a legal notice. The fix is a style prefix in the text itself:

--text "(warm, conversational, natural pace, expressive) Your text here."

That parenthetical tells the model how to deliver, not just what to say, and it changes the result a lot. A few other cues help: a comma gives a short pause, an ellipsis gives a longer trailing pause, and short punchy sentences force natural full stops.

Step 4: Normalize, every single time

Every raw output comes out quiet, usually 4 to 7 percent peak amplitude, barely audible without headphones. Normalize after every generation:

import soundfile as sf, numpy as np
d, sr = sf.read('raw.wav')
sf.write('final.wav', d * (0.95 / np.max(np.abs(d))), sr, subtype='PCM_16')

That lifts the peak to 95 percent, loud without distortion. Make it a reflex.

The honest limitation

The reference audio is the ceiling. I recorded on a built-in mic because my external mic wasn’t connecting, which turned out to be a charge-only USB-C cable that cost me an afternoon. You can hear the room reverb bleed into the clone. A proper lavalier or condenser in a quiet room would beat my result comfortably. If you have decent gear, your clone will be better than mine.

So the split is simple. If you’re producing client-facing audio where quality is non-negotiable, pay for ElevenLabs. If you’re a builder experimenting, or you’d just rather not spend $264 a year to speak in your own voice, this setup works. Your voice, your hardware, zero dollars.