Pular para o conteúdo principal

IA de Voz Conversacional Interrompível na Borda: Construção, Implantação e Resultados Medidos

Aviso de uso

Esta é uma implementação de referência open source, não um produto certificado. A precisão de fala foi medida apenas em RK3576 e em Orin NX (Qwen3-ASR int4).

O que esta solução faz​

Alguém se aproxima de um dispositivo e fala com ele. O dispositivo responde em voz alta; se a pessoa começar a falar de novo no meio da resposta, ele para imediatamente em vez de terminar a frase.

Feito para lugares onde uma pessoa fala com uma máquina com as mãos ocupadas: balcões de atendimento, exposições e quiosques, front-ends de voz para robôs, terminais de casa e ambientes inteligentes.

  • A fala permanece no dispositivo

    Reconhecimento (Qwen3-ASR) e síntese (Matcha-TTS) rodam no host de borda. Com um preset totalmente local, o modelo de conversação também roda ali, e o dispositivo funciona offline após a primeira inicialização.

  • Conecte o microfone e interrompa

    O reSpeaker XVF3800 faz cancelamento de eco em hardware e é detectado automaticamente via USB, incluindo hot-plug. Fale enquanto a resposta está sendo reproduzida e o dispositivo para.

  • Open source, funciona com o seu backend

    O código é aberto. A conversação passa por uma API compatível com OpenAI, então apontar para a sua própria base de conhecimento, agente ou backend de pedidos é apenas uma mudança de URL; a camada de fala permanece igual.

  • Medido em chinês e inglês

    Medido em RK3576: 1,05% de taxa de erro de caracteres em enunciados curtos em chinês, síntese a 0,204× tempo real. Hosts RK3588 e Jetson oferecem 30 idiomas.

De que hardware você precisa​

Quatro coisas no local: um array de microfones, um alto-falante e um host de voz; se o texto da conversação não puder sair do local, também uma placa aceleradora ou um host grande o bastante para um modelo 4B.

① O array de microfones deve fazer cancelamento de eco acústico (AEC) em hardware.

MicrofoneObservações
reSpeaker XVF3800reSpeaker XVF3800 USB 4-Mic Array
Array USB com AEC em hardware, supressão de ruído e beamforming
O padrão validado. Tanto os layouts de firmware de 2 canais quanto de 6 canais são reconhecidos e o canal processado é selecionado automaticamente. Outros arrays voltam a capturar o canal 1 e precisam de um teste acústico no local antes de entrar em operação.

② Um alto-falante: USB ou 3,5 mm, no mesmo dispositivo. Não silencie o microfone durante a reprodução para evitar eco; isso também desativa o barge-in.

③ O host de voz executa reconhecimento, síntese e o agente residente, e determina quais idiomas você pode oferecer:

Host de vozIdiomas que ele pode atenderQuando escolhê-lo
reComputer RK3576reComputer RK3576
NPU Rockchip, Qwen3-ASR W8A8 + Matcha
Chinês, inglêsHost de menor custo para a pilha de fala totalmente local; os dados medidos em "Desempenho e dados medidos" vêm desta placa
reComputer RK3588reComputer RK3588
NPU Rockchip, adiciona Kokoro RKNN para TTS
Todos os 30Você precisa dos 28 idiomas além de chinês e inglês, ou planeja adicionar uma placa RK1828 para conversação local depois
reComputer J3011reComputer J3011 (Orin Nano 8GB)
Qwen3-ASR int4 + Matcha na GPU
Todos os 30O host também executa outras cargas de trabalho de IA e precisa de folga na GPU. Não execute um modelo 4B local nele
reComputer J4012reComputer J4012 (Orin NX 16GB)
Fala mais Qwen3.5-4B no mesmo host
Todos os 30O texto da conversação não pode sair do local

A série reComputer R2000 também executa uma pilha de fala em CPU (sherpa-onnx, apenas inglês); ela ainda não é oferecida no configurador na página de design de referência. Ela não oferece suporte a chinês, e ASR e TTS compartilham quatro núcleos de CPU.

④ Conversação totalmente local na rota RK: adicione uma placa NPU RK1828 / RM182X PCIe a um host RK3588 para executar Qwen3-4B. A placa precisa de sua própria alimentação de 12 V, e o host precisa do driver e do nó de dispositivo. Apenas um modelo grande pode ficar residente na placa por vez.

Além disso: a primeira inicialização precisa de acesso à internet e espaço livre em disco (pelo menos 25 GB em Orin NX), e a ferramenta de implantação deve conseguir alcançar o host pela rede.

Como implantar no local​

Instale primeiro o microfone e o alto-falante, depois execute o assistente de implantação.

1. Posicionando o microfone e o alto-falante​

Verifique se o microfone tem cancelamento de eco em hardware

Barge-in, detecção de turno e manter o microfone aberto durante a reprodução exigem um canal de captura com a saída do alto-falante já removida em hardware. Um microfone sem AEC em hardware causa interrupções falsas ou um loop de eco, e nenhuma configuração de software corrige isso.

  • Use o reSpeaker XVF3800 por padrão. Se você usar outro array, faça primeiro um teste acústico no local; arrays desconhecidos usam o canal 1 por padrão.
  • Faça a aceitação com o alto-falante em volume normal de ambiente. Um terminal que passa em volume baixo pode falhar em volume de operação por motivos acústicos não relacionados aos modelos.
  • O reSpeaker pode ser conectado antes da implantação ou conectado a quente depois que o agente estiver em execução. O agente seleciona o dispositivo de captura pela identidade de produto USB, ignora pseudo-entradas HDMI/DP e se recupera de desconectar/reconectar sem reiniciar o contêiner.

2. Instalando o software​

O app SenseCraft Solution implanta no host via SSH (ou localmente, se você estiver em um Jetson Orin com JetPack 6.2). As etapas por dispositivo estão no guia de implantação; o resumo são quatro etapas.


  1. Escolha um preset: cloud / compatível com OpenAI, ou totalmente local. Com um preset em nuvem, o texto da conversação vai para um endpoint externo; com um preset totalmente local, nada sai do local.
  2. Escolha o idioma da conversa: a implantação resolve (language, device) em um único perfil de fala antes de iniciar os outros serviços. Um par não suportado, como chinês em reComputer série R2000, sai com código 2 e interrompe todo o docker compose up; nada inicia pela metade.
  3. Preencha o endpoint e a persona: URL base, chave e ID do modelo para o preset em nuvem (padrões: o endpoint Qwen da região de Pequim com qwen3.5-flash), além do prompt de sistema. Você pode alternar de Always listening para Wake word required e digitar qualquer frase curta em chinês ou inglês; o detector de vocabulário aberto sherpa-onnx na imagem a compila localmente na inicialização.
  4. Verifique no dashboard: o dashboard web na porta 18000 mostra ouvindo / pensando / falando / interrompido.

Aceitação: três turnos na sala real, com volume real de alto-falante, interrompendo 0,5–1 s após cada resposta começar. Verifique se a resposta antiga para imediatamente e se o enunciado de interrupção não é perdido.

Tempo: cerca de 30 minutos para um preset em nuvem. Presets totalmente locais levam mais tempo porque a primeira inicialização baixa os arquivos de modelo; após uma inicialização online bem-sucedida, as imagens e os arquivos de modelo são armazenados em cache e o dispositivo roda offline.

Interfaces disponíveis​

O agente chama uma API de Chat Completions em streaming compatível com OpenAI. Aponte LLM_BASE_URL para o seu próprio serviço para integrar: um endpoint de RAG sobre seus documentos, um framework de agente com chamadas de ferramentas, uma camada de comando de robô, um backend de pedidos ou de tickets. A camada de fala não muda.

  • Modelo hospedado: mantenha os padrões ou substitua URL base, chave e ID do modelo. O endpoint deve suportar Chat Completions em streaming.
  • Seu próprio serviço: implemente a mesma interface. O agente envia a transcrição como o turno do usuário e faz streaming da resposta para a síntese, de modo que a primeira frase começa a tocar antes que o seu serviço termine de gerar.
  • Apenas camada de fala: para construir um agente diferente em cima, chame diretamente o WebSocket duplex e os endpoints offline abaixo.

Lista completa de portas e endpoints​

Todos os serviços usam rede em modo host, então <host> é o próprio endereço do host de voz.

EndpointQual implantaçãoO que transporta
ws://<host>:8621/v2v/streamtodo presetA sessão duplex: PCM de entrada, transcrição e PCM de TTS de saída, além do abort que uma interrupção dispara
POST http://<host>:8621/asrtodo presetTranscrição offline de arquivo inteiro, sem VAD e sem streaming. Os números de acurácia offline em "Desempenho e dados medidos" são medidos aqui
POST http://<host>:8621/ttstodo presetSíntese; o cabeçalho de resposta x-rtf carrega o fator de tempo real
GET http://<host>:8621/healthtodo presetProntidão; usado como healthcheck do Compose
http://<host>:18000todo presetDashboard web: estado do turno e a transcrição de cada turno
http://<host>:1828/v1, /healthpreset local RK3588 + RK1828Chat Completions compatível com OpenAI para o Qwen3-4B no dispositivo
http://<host>:8000/v1, /healthpreset local Orin NXChat Completions compatível com OpenAI para o Qwen3.5-4B no dispositivo
LLM_BASE_URL (saída)preset em nuvemQualquer endpoint compatível com OpenAI

Ambas as rotas locais expõem a mesma interface que a rota em nuvem, então a troca altera apenas LLM_BASE_URL. A menos que aponte para fora, não há broker nem componente em nuvem no caminho de dados.

Desempenho e dados medidos​


Tempos de execução e parâmetros principais​

O protocolo duplex e o Agent são os mesmos em todo host; apenas os backends que executam ASR e TTS diferem.

Host de falaBackend / modelo de ASRBackend / modelo de TTSPerfil resolvido
RK3576rk.asr — Qwen3-ASR, codificador RKNN + decodificador RKLLM, W8A8rk.tts — matcha-icefall-zh-en, acústico ORT + RKNN Vocosrk3576-default
RK3588 (zh / en)rk.asr — mesmork.tts — matcha-icefall-zh-enrk3588-default
RK3588 (outros 28)rk.asr — mesmork.tts — Kokoro v1.0 híbrido, decodificador frontal RKNN INT8 + prefixo/cauda CPU ONNXrk3588-kokoro-rknn
Orin Nano 8GB / Orin NX 16GB (zh / en)jetson.trt_edge_llm — Qwen3-ASR 0.6B, int4jetson.matcha_trt — matcha-icefall-zh-en, Vocos bf16/fp16jetson-edgellm-v091-matcha
Orin NX 16GB (outros 28)jetson.trt_edge_llm — Qwen3-ASR 0.6B, int4jetson.trt_edge_llm — Qwen3-TTS CustomVoice, int4jetson-edgellm-v091-customvoice
reComputer série R2000 (inglês)cpu.sherpa_asr — sherpa-onnx streaming zh-en, CPU int8cpu.sherpa — voz sherpa-onnx em CPU, int8rpi5-default

O preset totalmente local do Orin NX usa a imagem TensorRT-Edge-LLM v0.9.1; engines construídos para outras versões de TensorRT / JetPack não são carregados. No lado RK, os arquivos de modelo são baixados na primeira inicialização.

Matriz idioma × dispositivo. A implantação escolhe um perfil a partir de (idioma, dispositivo). Das 18 células, 15 são implantáveis e 3 não são suportadas; das células implantáveis, 5 têm medições fim a fim e nas outras 10 cada componente tem medições no dispositivo. As células não suportadas: chinês em reComputer série R2000, e os "outros 28" idiomas em RK3576 e reComputer série R2000. O chinês não faz fallback para Whisper: em todas as placas medidas, o CER de chinês do Whisper é 35–56%. O RK3576 tem apenas a voz Matcha zh-en de TTS, então consegue transcrever os outros 28 idiomas, mas não consegue sintetizar uma resposta.

Três parâmetros que afetam os resultados da implantação:

  • barge_in_min_speaking_ms 500, barge_in_min_chars 2: uma interrupção só conta depois que a resposta começou a tocar e a interrupção é mais longa que uma sílaba.
  • playback_drain_enabled true: o Agent permanece em SPEAKING até o buffer de reprodução local esvaziar. Com isso desligado, fala durante a cauda da resposta é tratada como um novo turno e a resposta antiga continua tocando.
  • Fim de turno no servidor: silero, 400 ms de silêncio + QWEN3_ASR_FRONTEND_EOU_MIN_AUDIO_S=2.5, encerrando o turno na primeira pausa natural; uma frase longa com uma pausa no meio recebe resposta apenas à sua primeira oração.

Medições da série reComputer RK3576​

Condições: Debian 12 + Rockchip BSP, perfil rk3576-default; o script de teste e o contêiner de fala rodam no mesmo dispositivo e se comunicam via 127.0.0.1:8621, então os números excluem transferência de rede.

ASR no endpoint offline (POST /asr, arquivo inteiro, sem VAD, sem streaming):

IdiomaConjuntonTaxa de erro
Chinêscurto5CER 1,05%
Chinêslongo 10–20 s5CER 9,62%
Inglêscurto5WER 3,65% / CER 1,11%
Inglêslongo 10–20 s5WER 6,99% / CER 4,16%

Cada arquivo longo em inglês voltou como texto completo com múltiplas orações; os erros restantes são desvios de reconhecimento ("3:2" transcrito como "three to two"), não truncamento.

ASR em uma sessão ao vivo (/v2v/stream, padrões de fábrica ASR_MAX_NEW_TOKENS=64, ASR_FINAL_STOP_ON_PUNCT=1), avaliado em relação ao texto de referência completo:

IdiomaConjuntonTaxa de erro
Chinêscurto5CER 29,09%
Chinêslongo 10–20 s5CER 84,06%
Inglêscurto5WER 16,95% / CER 10,16%
Inglêslongo 10–20 s5WER 63,38% / CER 62,58%

A alta taxa de erro em sessão ao vivo vem da decisão de fim de turno no servidor, não de truncamento do decodificador: com ASR_MAX_NEW_TOKENS elevado para 256 e ASR_FINAL_STOP_ON_PUNCT ajustado para 0, as transcrições em ambos os idiomas são idênticas byte a byte.

TTS (POST /tts, lido do cabeçalho de resposta x-rtf, Matcha acústico ORT + RKNN Vocos, voz icefall zh-en):

IdiomanFator de tempo realFaixa
Chinês50,2040,190–0,216
Inglês50,1940,158–0,216

O áudio em inglês por frase tem duração de 2,5–4,3 s.

Latência em sessão ao vivo (modo eco, sem LLM na cadeia):

MétricaIdiomanValor
Fim da fala → primeiro frame de TTS (stop_to_tts_audio)Chinês41575 / 1624 / 1596 / 1580 ms (cerca de 1,6 s)
ASR final → primeiro frame de TTS (final_to_tts_audio)Inglês5p50 1127 ms, média 1126 ms, 1021–1232 ms
Fim da fala → ASR final (eos_to_final)Inglês5média 2837 ms

O valor medido de fim da fala → ASR final em chinês (stop_to_final) chega depois da resposta falada e não é citado.

Reproduza: docs/perf/rk3576-matrix-20260906.md e docs/known-issues/rk3576-v2v-multi-utterance-timeout.md no repositório openvoicestream; eos_to_final em inglês com asr_stream_ws_bench.py.

Medições da série reComputer J40​

MétricaValorCondições
ASR em chinêsCER 0 no conjunto golden, em streaming e offlineQwen3-ASR 0.6B int4

Degradações conhecidas​

  • Microfone sem AEC em hardware. Cada número acima foi obtido em um canal de captura com AEC em hardware. Sem isso, o microfone causa interrupções falsas ou microfonia, e nenhum valor de configuração compensa isso.
  • Pausas no meio da frase. No mesmo áudio, o endpoint offline dá CER 9,62% e a sessão ao vivo 84,06%; a diferença vem da política de tomada de turno, e o conteúdo após uma pausa no meio da frase não recebe resposta.
  • Volume de aceitação abaixo do volume de trabalho. Um terminal que passa em volume baixo pode falhar em volume de trabalho por motivos acústicos.

Próximos passos​

  • Ajustar a detecção de fim de turno no servidor para que uma pausa no meio da frase não encerre mais o turno cedo.
  • Medir latência e acurácia fim a fim para as outras 10 células implantáveis da matriz idioma × dispositivo.

Fontes de dados e assets​

  • FLEURS: o corpus de ASR para as medições do RK3576, CC BY 4.0, 5 clipes curtos e 5 longos por idioma, verificados por sha256. O TTS usou 5 frases autoescritas por idioma. A fonte para a comparação de Whisper entre dispositivos é docs/perf/whisper-cross-device-20260827.md no repositório openvoicestream.
  • Registros brutos de execução: docs/perf/rk3576-matrix-20260906.md no repositório openvoicestream; cada número de RK3576 acima mapeia para um registro lá.
  • Modelos de fala: Qwen3-ASR, Matcha-TTS (voz icefall zh-en), Kokoro v1.0, Qwen3-TTS CustomVoice e sherpa-onnx mantêm cada um seus termos de licença upstream. Verifique a licença de cada modelo que você realmente implantar antes do envio comercial.
  • Os corpora não são distribuídos com o repositório; obtenha-os separadamente.
Loading Comments...