docs: add project documentation and voice cloning notice
This commit is contained in:
160
README.md
Normal file
160
README.md
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
# 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.
|
||||||
59
VOICE_CLONING_NOTICE.md
Normal file
59
VOICE_CLONING_NOTICE.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Uso de clonagem de voz e responsabilidade
|
||||||
|
|
||||||
|
> **Minuta para revisão jurídica.** Este aviso complementa a documentação do
|
||||||
|
> projeto; não substitui contratos, termos de uso, políticas de privacidade ou
|
||||||
|
> parecer jurídico aplicáveis ao operador do serviço.
|
||||||
|
|
||||||
|
## Licença do código
|
||||||
|
|
||||||
|
O código deste repositório é disponibilizado publicamente sob a Licença Apache
|
||||||
|
2.0, incluindo uso, alteração, distribuição e exploração comercial, nos termos
|
||||||
|
do arquivo [LICENSE](LICENSE). Componentes de terceiros, modelos, pesos e
|
||||||
|
dependências podem possuir licenças e condições próprias, que devem ser
|
||||||
|
observadas pelo usuário.
|
||||||
|
|
||||||
|
## Responsabilidade por vozes, conteúdo e uso do serviço
|
||||||
|
|
||||||
|
Quem implanta, administra, integra, fornece ou utiliza este serviço
|
||||||
|
("Operador") é exclusivamente responsável por:
|
||||||
|
|
||||||
|
1. obter, registrar e manter todas as autorizações, consentimentos, licenças e
|
||||||
|
demais direitos necessários para gravar, enviar, processar, clonar,
|
||||||
|
sintetizar, reproduzir, distribuir ou explorar comercialmente qualquer voz,
|
||||||
|
áudio, texto, identidade ou outro conteúdo utilizado no serviço;
|
||||||
|
2. confirmar que a clonagem ou síntese não viola direitos de personalidade,
|
||||||
|
direitos autorais, direitos conexos, marcas, privacidade, proteção de dados,
|
||||||
|
obrigações contratuais ou qualquer lei, regulamento ou ordem aplicável;
|
||||||
|
3. informar adequadamente os titulares das vozes e os usuários finais sobre o
|
||||||
|
tratamento de dados e sobre o uso de voz sintética, quando exigido;
|
||||||
|
4. responder integralmente pela autoria, legitimidade, segurança, divulgação,
|
||||||
|
distribuição e utilização dos áudios e conteúdos gerados; e
|
||||||
|
5. manter controles técnicos e operacionais para impedir uso não autorizado,
|
||||||
|
enganoso, fraudulento ou que permita se passar por terceiro sem autorização.
|
||||||
|
|
||||||
|
É proibido usar este projeto para clonar, imitar ou representar a voz de uma
|
||||||
|
pessoa sem a autorização válida do respectivo titular ou outro fundamento
|
||||||
|
jurídico aplicável. O Operador deverá fornecer, quando solicitado pela
|
||||||
|
autoridade competente ou pelo titular, evidências das autorizações e da base
|
||||||
|
legal adotada.
|
||||||
|
|
||||||
|
## Ausência de responsabilidade da Oracle
|
||||||
|
|
||||||
|
Na máxima extensão permitida pela legislação aplicável, a Oracle Corporation e
|
||||||
|
suas afiliadas não são autoras, provedoras, controladoras, operadoras,
|
||||||
|
coparticipantes, representantes ou garantidoras das vozes, áudios, perfis de
|
||||||
|
voz, conteúdos, resultados ou serviços criados, hospedados ou disponibilizados
|
||||||
|
pelo Operador a partir deste projeto.
|
||||||
|
|
||||||
|
O Operador assume, de forma exclusiva, toda a responsabilidade por reclamações,
|
||||||
|
perdas, danos, sanções, custos e despesas decorrentes ou relacionados à coleta,
|
||||||
|
clonagem, síntese, geração, armazenamento, transmissão, publicação,
|
||||||
|
comercialização ou demais usos de vozes e conteúdos no serviço. Nada neste
|
||||||
|
repositório constitui autorização, endosso, garantia, parceria, agência,
|
||||||
|
sociedade ou coparticipação da Oracle com o Operador ou com os serviços por ele
|
||||||
|
oferecidos.
|
||||||
|
|
||||||
|
Esta seção deve ser validada e, se necessário, substituída pelo texto aprovado
|
||||||
|
pelo departamento jurídico da Oracle antes de qualquer divulgação externa ou
|
||||||
|
uso contratual. Nenhuma pessoa pode vincular a Oracle ou suas afiliadas sem
|
||||||
|
autorização expressa e por escrito.
|
||||||
54
config/voxcpm2-a10.yaml
Normal file
54
config/voxcpm2-a10.yaml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# VoxCPM2 deploy: single-stage AR pipeline with per-request state batching.
|
||||||
|
# Runs on large (H20 141GB) and small (24GB L4) cards alike: the KV cache is
|
||||||
|
# pinned to a right-sized budget instead of ballooning to fill the card.
|
||||||
|
#
|
||||||
|
# VoxCPM2-local runtime knobs are passed through hf_overrides.
|
||||||
|
async_chunk: false
|
||||||
|
dtype: bfloat16
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- stage_id: 0
|
||||||
|
custom_voice_dir: /home/opc/voxcpm-vllm-poc/runtime/voices
|
||||||
|
max_num_seqs: 2
|
||||||
|
#max_num_seqs: 8
|
||||||
|
gpu_memory_utilization: 0.9
|
||||||
|
# Right-size the KV cache instead of letting it fill gpu_memory_utilization.
|
||||||
|
# max_num_seqs(8) * max_model_len(4096) ~= 32k tokens; 6 GiB leaves headroom
|
||||||
|
# for longer live requests while keeping VoxCPM2 TTS decode batches small
|
||||||
|
# enough to avoid the high ITL observed with large admission caps.
|
||||||
|
# The remaining VRAM stays free for the VoxCPM2 diffusion side-path
|
||||||
|
# (LocDiT / AudioVAE / code2wav + batch CUDA-graph pools), which allocates
|
||||||
|
# outside vLLM's KV accounting during inference. Keeps peak ~13 GiB on any
|
||||||
|
# card and avoids per-rebase OOM tuning on small CI GPUs.
|
||||||
|
# Assumes prefix caching off and typical live decode concurrency <= ~8;
|
||||||
|
# raise this cap if either grows or enable_prefix_caching is turned on.
|
||||||
|
kv_cache_memory_bytes: 6442450944 # 6 GiB
|
||||||
|
enforce_eager: true
|
||||||
|
trust_remote_code: true
|
||||||
|
enable_prefix_caching: false
|
||||||
|
async_scheduling: true
|
||||||
|
max_num_batched_tokens: 4096
|
||||||
|
max_model_len: 4096
|
||||||
|
devices: "0"
|
||||||
|
engine_extras:
|
||||||
|
hf_overrides:
|
||||||
|
voxcpm2_runtime_config:
|
||||||
|
audio_emit_every: 1
|
||||||
|
vae_decode_every: 3
|
||||||
|
enable_batched_cfm: true
|
||||||
|
enable_batched_vae_decode: true
|
||||||
|
coalesce_audio_d2h: true
|
||||||
|
enable_loc_dit_fused_qkv: true
|
||||||
|
enable_loc_dit_fused_mlp: true
|
||||||
|
enable_loc_dit_zero_dt_cache: true
|
||||||
|
enable_loc_dit_skip_qkv_contig: true
|
||||||
|
enable_loc_dit_reduce_overhead_no_cg: true
|
||||||
|
enable_unified_decode_graph: true
|
||||||
|
unified_decode_graph_max_batch_size: 8
|
||||||
|
default_sampling_params:
|
||||||
|
temperature: 0.0
|
||||||
|
top_p: 1.0
|
||||||
|
top_k: -1
|
||||||
|
max_tokens: 4096
|
||||||
|
seed: 42
|
||||||
|
repetition_penalty: 1.0
|
||||||
Reference in New Issue
Block a user