rupayanism

setup 21reel 482026-09-10comment VOICE

ElevenLabs $100, your GPU 6 cents? The exact VoiceStudio setup

VoiceStudio synthesizes speech on an AMD Radeon RX 7700 XT at 3.77x real time, about six cents a million characters.

The result

I ran VoiceStudio 0.5.2 with the OmniVoice engine on an AMD Radeon RX 7700 XT.

The input was exactly 1,000 characters. Five clean runs took 15.767, 15.816, 15.855, 15.905 and 15.928 seconds. The median was 15.855 seconds.

Each run produced 59.79 seconds of speech, so the system generated audio at 3.77x real time.

The six cent figure is electricity only. It assumes the GPU is already owned. One million characters occupies this card for about 4.4 hours.

The cost math

Average total GPU power during the measured run was 146.6 W.

146.6 W × 15.855 seconds ÷ 3,600
= 0.6457 Wh per 1,000 characters

0.6457 Wh × 1,000
= 0.646 kWh per 1,000,000 characters

0.646 kWh × ₹8 per kWh
= ₹5.17, roughly $0.06

ElevenLabs publishes a v3 API price of $0.10 per 1,000 characters. That is $100 per million characters before taxes. ElevenLabs API pricing

This comparison is marginal cost against a managed service. It does not price the GPU, setup time, maintenance, the first 2.4GB weight download or the 41.8GB Docker image.

The setup I used

  • Fedora Linux
  • AMD Radeon RX 7700 XT, gfx1101, 12GB VRAM
  • VoiceStudio 0.5.2
  • OmniVoice
  • VoiceStudio's dedicated ROCm container
  • Local OpenAI compatible endpoint at http://127.0.0.1:3900/v1/audio/speech

AMD trap: the default CUDA container can fall back to CPU on AMD without making the mistake obvious. Use the dedicated ROCm image and verify the selected device before timing anything. VoiceStudio Docker instructions

The health response printed device: cuda, but this was still AMD. PyTorch ROCm uses the CUDA device name through HIP. The actual proof was the Radeon card name and gfx1101 in the ROCm output.

The exact 1,000 character input

Every local text to speech project publishes a hardware table, and almost none of them publish a measurement. The table tells you what the machine needs. It does not tell you how long the machine takes, and those are different questions. This paragraph answers the second one. It is a fixed block of ordinary English prose, with no unusual names, no digits, and no punctuation a synthesiser would have to guess at, so the only thing changing between runs is the machine underneath. Wall clock time is recorded from the moment the request is made to the moment the audio file is complete on disk. Peak video memory is sampled throughout. The real time factor is the wall clock time divided by the duration of the audio produced, so a figure below one means the machine speaks faster than a person could. The cost comparison divides the measured seconds by the published per character price of the hosted alternative, the only number in here that somebody else has supplied. This block is the baseline.

The request

Save the text above as benchmark_script_1000.txt. Confirm it is still exactly 1,000 characters before every run.

export VOICE_API_KEY='replace-with-your-local-key'
export VOICE_URL='http://127.0.0.1:3900'
TEXT="$(cat benchmark_script_1000.txt)"

[ "${#TEXT}" -eq 1000 ] || {
  echo "Expected 1,000 characters, got ${#TEXT}"
  exit 1
}

python3 -c '
import json
text = open("benchmark_script_1000.txt").read()
assert len(text) == 1000
json.dump(
    {
        "model": "tts-1",
        "voice": "alloy",
        "input": text,
        "response_format": "wav",
    },
    open("payload.json", "w"),
)
'

curl -fsS "$VOICE_URL/v1/audio/speech"   -H "Authorization: Bearer $VOICE_API_KEY"   -H "Content-Type: application/json"   --data @payload.json   --output result.wav

ffprobe -v error -select_streams a:0   -show_entries stream=duration -of csv=p=0 result.wav

Run one warm request first and throw its timing away. Mine took 535.47 seconds because it downloaded about 2.4GB of weights. Then run at least three clean passes and report the median.

Do not play the file just to prove it contains speech. You can inspect it with ffmpeg -af astats and confirm that it is not flat or silent.

The watermark catch

Every output from my run carried a detectable VoiceStudio watermark. I sent one generated WAV back to VoiceStudio's /watermark/detect endpoint.

{
  "is_watermarked": true,
  "confidence": 1.0,
  "is_omnivoice": true,
  "source": "VoiceStudio"
}

That matters if you plan to ship the audio commercially.

What I would test on your machine

Send me your GPU model and your electricity tariff. I will tell you which number in the calculation changes and whether this test is worth running there.

If you want more measured local AI tests, The Rabbit Hole is free to join. The course library is free; optional Premium adds weekly office hours.

if you run it, tell me

the rabbit hole

It's free to join, and the course library is free too. Ask there and I answer in the open, so the next person with the same question finds it. There's an optional paid Premium tier for weekly office hours.

join the rabbit hole

Post in there what you ran it on and what you got, or reply to the DM. I read every one.