Field notes from building a fully local voice assistant (Spanish, voice cloning from a short reference + transcript). Everything below was measured on one machine, in October 2026. Where something was not measured, it says so.
🔊 Listen to Ali's voice (Chica) in Spanish, Portuguese and English on the project page or in
samples/.TL;DR
- Fish S2 Pro runs fine in real time on a 16 GB consumer GPU alongside a 12B chat model, with the Q4_K GGUF.
- First audio arrives in ~0.15–0.35 s with streaming (0.5 s through our HTTP adapter), but generation runs at only ~1.0× the audio duration (Q4 median; Q8 ~1.12×) — so you need a small playback buffer (we use 0.8 s) or you get clicks.
- audio.cpp release 0.9.1 cannot stream Fish even though its README says so. Build from source (≥ commit
b0feeff, 13 Oct 2026).- Separate win for the LLM side: warming the stable prefix of the prompt cut the per-answer prompt re-read from 3.4 s → ~1.2 s.
1. Test machine
| CPU / RAM | Ryzen 7 5800X3D / 64 GB |
| GPU | GeForce RTX 5060 Ti 16 GB (Blackwell, compute 12.0), Windows 11 Pro, normal desktop running (~2 GB of VRAM used by apps) |
| Chat model | gemma4:12b in Ollama 0.35.1 (8 GB file incl. vision projector + MTP drafter), KV cache q8_0, num_ctx 8192, batch 512 |
| TTS | Fish Audio S2 Pro GGUF via audio.cpp (CUDA), Q4_K / Q6_K / Q8_0 |
| Speech-to-text, etc. | other models resident too; not covered here |
2. Getting audio.cpp to stream Fish (the part that cost us the most time)
Symptom: with the Windows CUDA release v0.9.1 (7 Oct 2026), a server config with "mode": "streaming" for the Fish model fails at start:
audiocpp_server failed: Fish Audio S2-Pro supports offline TTS sessions
The fish_audio.md doc and README table say streaming is supported, but that landed in the source tree after 0.9.1.
(--mode streaming in audiocpp_cli fails the same way.) Offline mode works but the first sound only arrives when the whole utterance is
done — ~30 s of waiting for a 30 s answer (RTF 0.9–1.1) — useless for conversation.
Fix: build the server from source (commit b0feeff, 13 Oct 2026 or newer). Nothing needs to be installed on C::
- MSVC: Visual Studio 2022 Build Tools with the C++ workload (we had 14.44). CMake comes with it.
- CUDA without the 3 GB installer: NVIDIA publishes the toolkit as redistributable zips:
https://developer.download.nvidia.com/compute/cuda/redist/redistrib_13.3.1.jsonlists them. We downloaded the Windows-x86_64 zips forcuda_nvcc, cuda_cudart, cccl, cuda_crt, cuda_nvrtc, libnvvm, libcublas, libcufft, cuda_profiler_api, libnvjitlink, libnvfatbin, libnvptxcompiler, cuda_nvtx, cuda_cuxxfilt, libcurand, libcusparse, libcusolverand merged them into one folder (3.9 GB total — a superset; we did not try to find the minimum). Noteccclandlibnvvmhave different manifest keys than you might expect. - Build (≈ 20–25 min, ~1200 steps). The repo's script needs a PowerShell execution-policy bypass:
powershell
$env:CUDA_PATH = "D:\cuda\toolkit"; $env:CUDAToolkit_ROOT = $env:CUDA_PATH
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\build_windows.ps1 `
-Preset windows-cuda-release -Target audiocpp_server -CudaArchitectures "120a-real"
120a-real is for Blackwell cards (RTX 50xx) only — it makes the build faster but the binary will not run on other GPUs.
4. The result is a single audiocpp_server.exe, no DLLs. Copy the DLLs (ggml*.dll, cublas*.dll, cudart*.dll, …) from the
release zip's bin folder next to it. --version should print your build, and the Fish streaming config should now start.
GGUF files: Q8_0 comes from the audio.cpp GGUF repo (audio-cpp/audio.cpp-gguf); Q6_K and Q4_K are produced with the project's own
recipe — read docs/proposals/fish_audio_quantization_recipe.md in the source tree. The key point is that the small "fast acoustic
decoder" tensors must stay at original precision (--keep-type 'model_weights/fast_*=orig') and the token metadata sidecar must be
extracted from the Q8 file; naive quantization gives garbled audio. File sizes: Q8 6.3 GB, Q6 5.4 GB, Q4 4.5 GB.
3. Server config and request
server.json (voice cloning = a preset with a reference wav and its exact transcript):
{ "host": "127.0.0.1", "port": 18190, "backend": "cuda", "device": 0, "busy_timeout_ms": 600000,
"models": [{ "id": "fish", "family": "fish_audio", "task": "tts", "mode": "streaming",
"path": "D:/models/Fish-Audio-S2-Pro-GGUF/fish-audio-s2-pro-q4_k.gguf",
"model_spec_override": "D:/audiocpp/src/model_specs",
"session_options": { "fish_audio.reference_cache_slots": "4" },
"voice_presets": { "my_voice": { "voice_ref": "D:/voices/ref.wav", "reference_text": "exact transcript of ref.wav" } } }] }
(model_spec_override is what we ran with; we did not test whether a new enough binary needs it.)
Request: POST /v1/audio/speech with {"model":"fish","input":"...","voice":"my_voice","response_format":"pcm","stream_format":"sse"}.
You get SSE events; speech.audio.delta carries base64 PCM16 mono at 44.1 kHz. Closing the HTTP connection stops generation
(measured: the next request started speaking in 0.65 s after an interruption).
Our adapter (fish_tts_adapter.py, ~200 lines, standard library + numpy/scipy/requests) turns that into
"POST text → raw 24 kHz PCM16 as it is generated", and also: starts/stops audio.cpp, /sleep + /wake to free VRAM, and a Windows Job Object so
audio.cpp dies with the adapter (an orphaned server keeps ~5 GB of VRAM). Tested: first byte 0.5 s.
Two details worth copying: streaming 44.1→24 kHz with resample_poly in blocks with context on both sides (bit-identical to a one-shot
resample, verified with several chunk sizes — no seams), and a soft limiter instead of hard clipping.
4. Results
4.1 TTS alone (GPU otherwise idle), streaming
38 utterances per GGUF (2 voices × 19 texts, 2–34 s of speech). "Generation ÷ audio" > 1 means slower than real time.
| GGUF | first audio | generation time ÷ audio time (range, median) | peak VRAM incl. ~2 GB desktop |
|---|---|---|---|
| Q8_0 | 0.15–0.31 s | 0.98–1.27, median 1.12 | 8.4 GB |
| Q6_K | 0.17–0.35 s | 0.98–1.19, median 1.09 | 7.7 GB |
| Q4_K | 0.14–0.31 s | 0.85–1.08, median 1.00 | 7.0 GB |
How much start delay you need so playback never runs dry, for ~19 s answers (measured from the SSE arrival times): Q8 1.0–2.5 s, Q4 0.2–0.5 s. So Q4 is not only the smallest, it is the one that plays smoothly — on our ears (Spanish, one listener) all three sounded equally good; the listener chose Q4 for efficiency. Emotional tone came out of the text itself (punctuation, words); we did not need inline emotion tags and did not evaluate them.
4.2 Full pipeline (real LLM + real TTS, simulated sound card that counts under-runs)
Q4, short conversational answers (~8–10 s of speech each). "Cushion" = audio buffered before playback starts; "queue" = how far generation may run ahead.
| cushion / queue | audible gaps | speech tested |
|---|---|---|
| 0.5 s / 6 | 1 | 48 s |
| 0.65 s / 60 | 0 | 52 s |
| 0.8 s / 60 (our setting) | 0 / 0 / 0 | 50 + 51 + 48 s |
| 1.1 s / 60 | 0 | 52 s |
With Q6 and the small cushion, a real session logged 8 gaps in one 11 s answer — those are the "little clicks" a listener reports. Time from the request to the first sound: ~1.9–2.4 s median across those runs (≈0.7 s of that is the LLM writing its first sentence).
4.3 VRAM
gemma4:12b (≈8.5 GB dedicated) + Fish Q4 + Windows desktop: ~14.1 GB of 16 GB used (it was ~15.7 GB with the TTS we replaced).
5. Bonus: making the LLM start answering sooner (Ollama / llama.cpp, sliding-window models)
Before: every answer re-read the whole ~5 000-token prompt (3.4 s) although only the last turn had changed. With gemma4 (sliding-window
attention) llama.cpp can only reuse a cached prefix through context checkpoints, and it only creates them at the end of a request — i.e.
after the part that changes every turn, so they were never usable. (The server log shows forcing full prompt re-processing due to lack of cache data.)
What worked (Ollama 0.35.1, no environment variables needed): after each answer, once speech has finished, send one extra request containing only the
stable prefix (system prompt + conversation history, without the volatile "current context" block and without the new user message) with
num_predict: 1. The checkpoint now lands exactly where the next turn's prompt diverges.
Keep tools, num_ctx, num_batch, keep_alive identical to the real requests or the model reloads. Put everything that changes per turn (clock, retrieved
memories) after the history.
- Measured on a replayed 8-turn conversation: re-read before answering 3.4 s → ~1.2 s (warm-up itself ~0.3–0.7 s while idle); in live use 1.3–1.7 s.
- Things that did not help:
LLAMA_ARG_CHECKPOINT_MIN_SPACING_NT=256(no effect);LLAMA_ARG_SWA_FULL=1works but costs ~2.2 GB of VRAM. - Moving the user profile before the history would save another ~0.6 s, but with this 12B model it made recall of the current conversation worse (asked "what did I say her name was?" it answered from the profile: 0/6 correct vs 6/6). Check for this kind of regression if you reorder prompts.
OLLAMA_DEBUG=1made prompt reads ~7× slower in our runs (23 s vs 3 s); don't leave it on while measuring.- Not tested: newer Ollama (0.40.x) — its notes were mostly about Apple/MLX.
6. Gotchas, quickly
- Don't trust "streaming supported" in a README: grep the release for it, or just try a config with
"mode":"streaming". - Streaming gives time to first audio, not speed. If generation is ≥ 1.0× audio duration you still need a buffer.
- Kill orphaned
audiocpp_server.exeprocesses — each holds ~5 GB of VRAM. - First start after boot was slow (≈57 s, cold disk read); afterwards 10–20 s. Waking an adapter that put audio.cpp to sleep took ≈10 s.
- In PowerShell scripts blocked by policy, use
-ExecutionPolicy Bypassfor that command only. - If you run Git Bash, backslashes inside heredocs get eaten (we corrupted a Windows path in a doc that way).
7. Not measured / limits
Other languages; other voices; word-error-rate or any objective quality metric (only one human listener); behaviour while gaming or rendering at the same time;
long sessions (hours); audio.cpp versions newer than b0feeff; non-Blackwell GPUs.
8. License note
The Fish Audio S2 Pro model card restricts the weights to non-commercial use — check the current terms before building anything beyond personal use. audio.cpp, llama.cpp and Ollama have their own licenses.
Licenses
Code: MIT · text and data: CC BY 4.0 (reuse with credit, commercial use allowed) · audio samples and the Ali mascot: CC BY-NC 4.0 (non-commercial). Details in LICENSES.md.
Credits
This was a team effort:
- @andreaabcj-cmd — product direction, the hardware, every decision, and the listening tests (the only human ears behind the "sounds good" claims).
- Claude (Anthropic, via Claude Code) — engineering, measurements, research, and this write-up. All numbers come from scripts run on the machine above; raw data is in
data/. - The open-source community, whose work made it possible and whose findings we read before measuring anything (RESEARCH.md): the
audio.cpp project and its Fish quantization recipe, Fish Audio and the
fish-speechissue threads, s2.cpp and the GGUF publishers on Hugging Face, SGLang-Omni, llama.cpp (and the maintainers who documented the sliding-window checkpoint behaviour), Ollama, and everyone who posted benchmarks and bug reports.
Raw measurements: data/ · What we read first: RESEARCH.md · Example adapter: fish_tts_adapter.py.
Listen — Ali's voice, in 3 languages
This is Chica, the voice of the assistant (the Ali mascot above), generated by the exact setup in this guide: Fish S2 Pro Q4_K in audio.cpp streaming, RTX 5060 Ti. It is cloned from a short reference clip generated on the Fish Audio platform (one Spanish reference, no Portuguese or English recordings), and the same voice speaks Spanish, Portuguese and English. Automatically checked — speech recognition reads every sample back with ≥ 97% word match and the timbre stays close to the reference — but not curated by a human ear. The model weights are non-commercial; 'first audio' = time to first sound in streaming.
Spanish (the assistant's main language)
Hola, soy Ali. Corro por completo en esta computadora, sin enviar nada a internet.¡Qué buena noticia! ¡Por fin lo logramos!Portuguese
Oi, eu sou a Ali. Eu rodo inteira neste computador, sem mandar nada para a internet.Que notícia boa! Finalmente conseguimos!English
Hi, I'm Ali. I run entirely on this computer, without sending anything to the internet.What great news! We finally made it!Notas de campo de quem montou um assistente de voz 100% local (espanhol, clonagem de voz a partir de uma referência curta + transcrição). Tudo foi medido em uma única máquina, em outubro de 2026. O que não foi medido está dito como tal.
🔊 Escute a voz da Ali (Chica) em espanhol, português e inglês na página do projeto ou em
samples/.Resumo
- O Fish S2 Pro roda bem em tempo real numa GPU de consumo de 16 GB junto de um modelo de chat de 12B, usando o GGUF Q4_K.
- O primeiro áudio sai em ~0,15–0,35 s com streaming (0,5 s pelo nosso adaptador HTTP), mas a geração é só ~1,0× a duração do áudio (mediana do Q4; Q8 ~1,12×) — é preciso um pequeno colchão de reprodução (usamos 0,8 s), senão aparecem estalos.
- O audio.cpp release 0.9.1 não faz streaming com o Fish, embora o README diga que sim. Compile do código-fonte (≥ commit
b0feeff, 13/10/2026).- Ganho separado no LLM: "aquecer" o prefixo estável do prompt reduziu a releitura por resposta de 3,4 s → ~1,2 s.
1. Máquina de teste
| CPU / RAM | Ryzen 7 5800X3D / 64 GB |
| GPU | GeForce RTX 5060 Ti 16 GB (Blackwell, compute 12.0), Windows 11 Pro, desktop normal aberto (~2 GB de VRAM usados por apps) |
| Modelo de chat | gemma4:12b no Ollama 0.35.1 (arquivo de 8 GB com projetor de visão + rascunhador MTP), KV cache q8_0, num_ctx 8192, lote 512 |
| TTS | Fish Audio S2 Pro GGUF via audio.cpp (CUDA), Q4_K / Q6_K / Q8_0 |
2. Fazer o audio.cpp dar streaming no Fish (o que mais custou tempo)
Sintoma: com o release v0.9.1 do Windows CUDA (7/10/2026), uma config com "mode": "streaming" para o Fish falha ao iniciar:
audiocpp_server failed: Fish Audio S2-Pro supports offline TTS sessions
A documentação fish_audio.md e a tabela do README dizem que há streaming, mas isso entrou no código depois da 0.9.1
(audiocpp_cli --mode streaming falha igual). O modo offline funciona, mas o primeiro som só sai quando a fala inteira termina —
~30 s de espera para uma resposta de 30 s — inútil para conversa.
Solução: compilar o servidor (commit b0feeff, 13/10/2026 ou mais novo). Nada precisa ser instalado no C::
- MSVC: Build Tools do Visual Studio 2022 com o pacote C++ (usamos 14.44). O CMake vem junto.
- CUDA sem o instalador de 3 GB: a NVIDIA publica o toolkit em zips redistribuíveis; o manifesto fica em
https://developer.download.nvidia.com/compute/cuda/redist/redistrib_13.3.1.json. Baixamos os zips Windows-x86_64 decuda_nvcc, cuda_cudart, cccl, cuda_crt, cuda_nvrtc, libnvvm, libcublas, libcufft, cuda_profiler_api, libnvjitlink, libnvfatbin, libnvptxcompiler, cuda_nvtx, cuda_cuxxfilt, libcurand, libcusparse, libcusolvere juntamos tudo numa pasta (3,9 GB — um superconjunto; não procuramos o mínimo). Atenção:ccclelibnvvmtêm chaves diferentes das que você imaginaria no manifesto. - Compilar (≈ 20–25 min, ~1200 etapas). O script do repositório precisa de bypass da política de execução do PowerShell:
powershell
$env:CUDA_PATH = "D:\cuda\toolkit"; $env:CUDAToolkit_ROOT = $env:CUDA_PATH
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\build_windows.ps1 `
-Preset windows-cuda-release -Target audiocpp_server -CudaArchitectures "120a-real"
120a-real serve só para placas Blackwell (RTX 50xx): acelera a compilação, mas o binário não roda em outras GPUs.
4. O resultado é um único audiocpp_server.exe, sem DLLs. Copie as DLLs (ggml*.dll, cublas*.dll, cudart*.dll…) da pasta bin do
zip do release para junto dele. --version deve mostrar o seu build, e a config de streaming do Fish deve passar a iniciar.
Arquivos GGUF: o Q8_0 vem do repositório de GGUFs do audio.cpp (audio-cpp/audio.cpp-gguf); Q6_K e Q4_K são gerados com a receita do próprio
projeto — leia docs/proposals/fish_audio_quantization_recipe.md na árvore de código. O ponto-chave: os tensores pequenos do "decodificador
acústico rápido" precisam ficar na precisão original (--keep-type 'model_weights/fast_*=orig') e o arquivo de metadados dos tokens deve ser
extraído do Q8; quantizar "no ingênuo" gera áudio embaralhado. Tamanhos: Q8 6,3 GB, Q6 5,4 GB, Q4 4,5 GB.
3. Config do servidor e pedido
server.json (clonagem de voz = um preset com wav de referência e a transcrição exata dele):
{ "host": "127.0.0.1", "port": 18190, "backend": "cuda", "device": 0, "busy_timeout_ms": 600000,
"models": [{ "id": "fish", "family": "fish_audio", "task": "tts", "mode": "streaming",
"path": "D:/models/Fish-Audio-S2-Pro-GGUF/fish-audio-s2-pro-q4_k.gguf",
"model_spec_override": "D:/audiocpp/src/model_specs",
"session_options": { "fish_audio.reference_cache_slots": "4" },
"voice_presets": { "minha_voz": { "voice_ref": "D:/voices/ref.wav", "reference_text": "transcrição exata de ref.wav" } } }] }
(model_spec_override é o que usamos; não testamos se um binário novo o dispensa.)
Pedido: POST /v1/audio/speech com {"model":"fish","input":"...","voice":"minha_voz","response_format":"pcm","stream_format":"sse"}.
Vêm eventos SSE; speech.audio.delta traz PCM16 mono em base64 a 44,1 kHz. Fechar a conexão HTTP interrompe a geração
(medido: depois de uma interrupção, o pedido seguinte voltou a falar em 0,65 s).
Nosso adaptador (fish_tts_adapter.py, ~200 linhas, biblioteca padrão + numpy/scipy/requests) transforma isso em
"POST do texto → PCM16 cru a 24 kHz conforme é gerado", e ainda: liga/desliga o audio.cpp, /sleep + /wake para liberar VRAM, e um Job Object do Windows
para o audio.cpp morrer junto com o adaptador (um servidor órfão segura ~5 GB de VRAM). Testado: primeiro byte em 0,5 s.
Dois detalhes que valem copiar: conversão 44,1→24 kHz em streaming com resample_poly em blocos com contexto dos dois lados (idêntica bit a bit
à conversão de uma vez, verificada com vários tamanhos de bloco — sem emendas) e um limitador suave em vez de corte seco.
4. Resultados
4.1 Só o TTS (GPU livre), streaming
38 falas por GGUF (2 vozes × 19 textos, de 2 a 34 s de fala). "Geração ÷ áudio" > 1 significa mais lento que o tempo real.
| GGUF | primeiro áudio | tempo de geração ÷ tempo do áudio (faixa, mediana) | pico de VRAM com ~2 GB de desktop |
|---|---|---|---|
| Q8_0 | 0,15–0,31 s | 0,98–1,27, mediana 1,12 | 8,4 GB |
| Q6_K | 0,17–0,35 s | 0,98–1,19, mediana 1,09 | 7,7 GB |
| Q4_K | 0,14–0,31 s | 0,85–1,08, mediana 1,00 | 7,0 GB |
Atraso inicial necessário para a reprodução nunca secar, em respostas de ~19 s (medido pelos tempos de chegada do SSE): Q8 1,0–2,5 s, Q4 0,2–0,5 s. Ou seja, o Q4 não é só o menor: é o que toca mais redondo. No ouvido (espanhol, um único ouvinte) os três soaram igualmente bons; o ouvinte escolheu o Q4 por eficiência. O tom emocional saiu do próprio texto (pontuação, palavras); não precisamos de marcas de emoção inline e não as avaliamos.
4.2 Pipeline completo (LLM real + TTS real, placa de som simulada que conta falhas)
Q4, respostas curtas de conversa (~8–10 s de fala cada). "Colchão" = áudio acumulado antes de começar a tocar; "fila" = quanto a geração pode adiantar.
| colchão / fila | falhas audíveis | fala testada |
|---|---|---|
| 0,5 s / 6 | 1 | 48 s |
| 0,65 s / 60 | 0 | 52 s |
| 0,8 s / 60 (nossa config) | 0 / 0 / 0 | 50 + 51 + 48 s |
| 1,1 s / 60 | 0 | 52 s |
Com o Q6 e o colchão pequeno, uma sessão real registrou 8 falhas numa única resposta de 11 s — são os "estalinhos" que o ouvinte relatou. Tempo do pedido até o primeiro som: ~1,9–2,4 s de mediana nessas rodadas (≈0,7 s disso é o LLM escrevendo a primeira frase).
4.3 VRAM
gemma4:12b (≈8,5 GB dedicados) + Fish Q4 + desktop do Windows: ~14,1 GB dos 16 GB (eram ~15,7 GB com o TTS que substituímos).
5. Bônus: fazer o LLM começar a responder mais cedo (Ollama / llama.cpp, modelos de janela deslizante)
Antes: cada resposta relia o prompt inteiro de ~5 000 tokens (3,4 s) embora só o último turno tivesse mudado. No gemma4 (atenção de janela
deslizante) o llama.cpp só consegue reaproveitar um prefixo em cache por meio de context checkpoints, e só os cria no fim de um pedido — ou seja,
depois da parte que muda a cada turno, então nunca serviam. (O log do servidor mostra forcing full prompt re-processing due to lack of cache data.)
O que funcionou (Ollama 0.35.1, sem variável de ambiente): depois de cada resposta, quando a fala termina, mandar um pedido extra só com o prefixo
estável (prompt de sistema + histórico, sem o bloco volátil de "contexto atual" e sem a nova mensagem do usuário) com num_predict: 1.
O checkpoint passa a cair exatamente onde o prompt do próximo turno diverge.
Mantenha ferramentas, num_ctx, num_batch e keep_alive idênticos aos pedidos reais, ou o modelo recarrega. Coloque tudo que muda a cada turno
(relógio, memórias recuperadas) depois do histórico.
- Medido numa conversa de 8 turnos reproduzida: releitura antes de responder 3,4 s → ~1,2 s (o aquecimento leva ~0,3–0,7 s, com o assistente parado); no uso real 1,3–1,7 s.
- O que não ajudou:
LLAMA_ARG_CHECKPOINT_MIN_SPACING_NT=256(sem efeito);LLAMA_ARG_SWA_FULL=1funciona, mas custa ~2,2 GB de VRAM. - Pôr o perfil do usuário antes do histórico pouparia mais ~0,6 s, mas com este 12B piorou a lembrança da conversa atual (perguntado "como te disse que ela se chamava?", respondia pelo perfil: 0/6 certas contra 6/6). Teste esse tipo de regressão se reordenar prompts.
OLLAMA_DEBUG=1deixou a leitura do prompt ~7× mais lenta nas nossas rodadas (23 s contra 3 s); não deixe ligado ao medir.- Não testado: Ollama mais novo (0.40.x) — as notas dele eram sobretudo de Apple/MLX.
6. Armadilhas, em resumo
- Não confie em "streaming suportado" no README: procure no release, ou teste uma config com
"mode":"streaming". - Streaming dá tempo até o primeiro áudio, não velocidade. Se a geração é ≥ 1,0× a duração do áudio, ainda precisa de colchão.
- Mate processos
audiocpp_server.exeórfãos — cada um segura ~5 GB de VRAM. - A primeira subida depois do boot foi lenta (≈57 s, disco frio); depois 10–20 s. Acordar um adaptador que pôs o audio.cpp para dormir levou ≈10 s.
- Se a política do PowerShell bloquear scripts, use
-ExecutionPolicy Bypasssó naquele comando. - No Git Bash, barras invertidas em heredocs são comidas (corrompemos um caminho do Windows num documento assim).
7. Não medido / limites
Outros idiomas; outras vozes; taxa de erro de palavras ou qualquer métrica objetiva de qualidade (só um ouvinte humano); comportamento jogando ou renderizando ao mesmo tempo;
sessões longas (horas); versões do audio.cpp mais novas que b0feeff; GPUs que não sejam Blackwell.
8. Nota de licença
O cartão do modelo Fish Audio S2 Pro restringe os pesos a uso não comercial — confira os termos atuais antes de construir algo além de uso pessoal. audio.cpp, llama.cpp e Ollama têm licenças próprias.
Licenças
Código: MIT · texto e dados: CC BY 4.0 (reuso com crédito, uso comercial permitido) · amostras de áudio e a mascote Ali: CC BY-NC 4.0 (não comercial). Detalhes em LICENSES.md.
Créditos
Isto foi um trabalho de equipe:
- @andreaabcj-cmd — direção do produto, o hardware, todas as decisões e os testes de escuta (os únicos ouvidos humanos por trás dos "soa bem").
- Claude (Anthropic, via Claude Code) — engenharia, medições, pesquisa e este texto. Todos os números vêm de scripts rodados na máquina acima; os dados brutos estão em
data/. - A comunidade open source, cujo trabalho tornou isto possível e cujos achados lemos antes de medir qualquer coisa (RESEARCH.md): o projeto
audio.cpp e a receita de quantização do Fish, a Fish Audio e as issues do
fish-speech, o s2.cpp e quem publicou GGUFs no Hugging Face, o SGLang-Omni, o llama.cpp (e os mantenedores que documentaram o comportamento dos checkpoints de janela deslizante), o Ollama, e todos que postaram benchmarks e relatos de erro.
Medições brutas: data/ · O que lemos antes: RESEARCH.md · Adaptador de exemplo: fish_tts_adapter.py
Escute — a voz da Ali, em 3 idiomas
Esta é a Chica, a voz do assistente (a mascote Ali no topo), gerada exatamente pelo setup deste guia: Fish S2 Pro Q4_K no audio.cpp em streaming, RTX 5060 Ti. Ela é clonada de um trecho curto de referência gerado na plataforma do Fish Audio (uma referência em espanhol, sem nenhuma gravação em português ou inglês), e a mesma voz fala espanhol, português e inglês. Conferido automaticamente — o reconhecimento de fala lê de volta cada amostra com ≥ 97% de acerto e o timbre fica próximo da referência — mas não selecionado por um ouvido humano. Os pesos do modelo são de uso não comercial; 'primeiro áudio' = tempo até o primeiro som no streaming.
Espanhol (idioma principal do assistente)
Hola, soy Ali. Corro por completo en esta computadora, sin enviar nada a internet.¡Qué buena noticia! ¡Por fin lo logramos!Português
Oi, eu sou a Ali. Eu rodo inteira neste computador, sem mandar nada para a internet.Que notícia boa! Finalmente conseguimos!Inglês
Hi, I'm Ali. I run entirely on this computer, without sending anything to the internet.What great news! We finally made it!