161 lines
3.9 KiB
Markdown
161 lines
3.9 KiB
Markdown
# VoxCPM2 + vLLM-Omni
|
|
|
|
PoC para servir o modelo `openbmb/VoxCPM2` com vLLM-Omni, usando GPU NVIDIA e Podman.
|
|
|
|
O serviço expõe uma API compatível com OpenAI em `POST /v1/audio/speech` e oferece:
|
|
|
|
- Síntese de voz em WAV;
|
|
- Streaming de áudio PCM `s16le`, mono, 48 kHz;
|
|
- Perfis de voz pré-calculados;
|
|
- Criação de novos perfis de voz em um container temporário.
|
|
|
|
> Use somente áudios de referência com consentimento explícito e documentado.
|
|
|
|
## Pré-requisitos
|
|
|
|
No host:
|
|
|
|
- Oracle Linux 9 ou outra distribuição Linux compatível;
|
|
- GPU NVIDIA compatível (a PoC foi validada em OCI `VM.GPU.A10.1`);
|
|
- Driver NVIDIA funcional;
|
|
- Podman e NVIDIA Container Toolkit/CDI configurados;
|
|
- Acesso à internet no primeiro build e primeiro boot.
|
|
|
|
Valide a GPU no host:
|
|
|
|
```bash
|
|
nvidia-smi -L
|
|
```
|
|
|
|
Valide o acesso à GPU pelo Podman:
|
|
|
|
```bash
|
|
podman run --rm \
|
|
--device nvidia.com/gpu=all \
|
|
--security-opt label=disable \
|
|
ubuntu \
|
|
nvidia-smi -L
|
|
```
|
|
|
|
## Build
|
|
|
|
```bash
|
|
git clone <URL_DO_REPOSITORIO>
|
|
cd voxcpm-vllm-omni
|
|
|
|
mkdir -p runtime/hf-cache runtime/voices
|
|
|
|
podman build --pull=newer \
|
|
-t voxcpm-omni:0.28.0-1 \
|
|
-f Containerfile .
|
|
```
|
|
|
|
## Executar o servidor
|
|
|
|
Para acesso apenas local:
|
|
|
|
```bash
|
|
podman run -d \
|
|
--name voxcpm-omni \
|
|
--restart=always \
|
|
--device nvidia.com/gpu=all \
|
|
--security-opt label=disable \
|
|
--ipc=host \
|
|
-p 127.0.0.1:8000:8000 \
|
|
-v "$PWD/runtime/hf-cache:/root/.cache/huggingface" \
|
|
-v "$PWD/runtime/voices:/opt/voices:ro" \
|
|
voxcpm-omni:0.28.0-1
|
|
```
|
|
|
|
No primeiro boot, o modelo será baixado para `runtime/hf-cache/`.
|
|
|
|
```bash
|
|
podman logs -f voxcpm-omni
|
|
curl http://127.0.0.1:8000/v1/models
|
|
curl http://127.0.0.1:8000/v1/audio/voices
|
|
```
|
|
|
|
## Gerar WAV
|
|
|
|
```bash
|
|
curl -sS -X POST http://127.0.0.1:8000/v1/audio/speech \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"model": "openbmb/VoxCPM2",
|
|
"input": "Olá. Este é um teste de síntese de voz.",
|
|
"voice": "default",
|
|
"response_format": "wav"
|
|
}' \
|
|
--output teste.wav
|
|
```
|
|
|
|
Para usar uma voz pre-processada, substitua `default` pelo nome do perfil, por exemplo `carbonera`.
|
|
|
|
## Streaming PCM
|
|
|
|
```bash
|
|
curl --no-buffer -sS -X POST http://127.0.0.1:8000/v1/audio/speech \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"model": "openbmb/VoxCPM2",
|
|
"input": "Olá. Este é um teste de streaming.",
|
|
"voice": "default",
|
|
"stream": true,
|
|
"stream_format": "audio",
|
|
"response_format": "pcm"
|
|
}' \
|
|
--output resposta.pcm
|
|
```
|
|
|
|
Formato retornado: PCM `s16le`, mono, 48 kHz.
|
|
|
|
## Criar uma voz pre-processada
|
|
|
|
Os arquivos de referência não devem ir para o Git.
|
|
|
|
Com o serviço parado:
|
|
|
|
```bash
|
|
podman stop voxcpm-omni
|
|
|
|
PROMPT_TEXT="$(tr '\n' ' ' < "$PWD/reference-audio/nome-da-voz.txt")"
|
|
|
|
podman run --rm \
|
|
--device nvidia.com/gpu=all \
|
|
--security-opt label=disable \
|
|
--ipc=host \
|
|
-v "$PWD/runtime/hf-cache:/root/.cache/huggingface" \
|
|
-v "$PWD/runtime/voices:/opt/voices" \
|
|
-v "$PWD/reference-audio/nome-da-voz.wav:/opt/input/voz.wav:ro" \
|
|
voxcpm-omni:0.28.0-1 \
|
|
python /opt/vllm-omni/examples/online_serving/text_to_speech/voxcpm2/precompute_custom_voice.py \
|
|
--model openbmb/VoxCPM2 \
|
|
--voice-name nome-da-voz \
|
|
--ref-audio /opt/input/voz.wav \
|
|
--prompt-text "$PROMPT_TEXT" \
|
|
--mode ref_continuation \
|
|
--output-dir /opt/voices \
|
|
--device cuda
|
|
|
|
podman start voxcpm-omni
|
|
```
|
|
|
|
Confira a nova voz:
|
|
|
|
```bash
|
|
curl http://127.0.0.1:8000/v1/audio/voices
|
|
```
|
|
|
|
## Dados persistentes
|
|
|
|
```text
|
|
runtime/hf-cache/ Pesos baixados do modelo
|
|
runtime/voices/ Perfis .safetensors e manifesto das vozes
|
|
```
|
|
|
|
Esses diretórios não são versionados no Git. Para migrar vozes aprovadas entre hosts, copie `runtime/voices/` por um canal seguro.
|
|
|
|
## Segurança
|
|
|
|
Não exponha a porta 8000 diretamente à internet sem controles adicionais. Para acesso remoto, restrinja firewall e NSG/Security List da OCI ao IP ou à rede autorizada e use um proxy reverso com TLS e autenticação.
|