/ Модель

Характеристики

Лицензия
Apache 2.0
Библиотека
pytorch
Опубликована
19 авг 2026

nomo-pvad

Поиск речи в аудиоАудио → label

Потоковая модель TuyaNomo определяет с интервалом 160 мс, говорит ли в аудиопотоке заранее зарегистрированный человек.

0скачиваний за 30 дней0лайковвеса обновлены10 сен 2026

Бенчмарки

Как модель справилась с задачами пользователей ailist и что о ней публикуют открытые лидерборды

Публичные оценки

Из открытых лидербордов. Сравнивайте результаты одного теста при одинаковых условиях — отсутствие оценки не значит, что модель хуже.

В подключённых источниках результатов для этой модели пока нет.

Что умеет модель

Описание составлено по карточке модели и метаданным Hugging Face

nomo-pvad — потоковая модель TuyaNomo для обнаружения речи конкретного заранее зарегистрированного говорящего. Она принимает аудио регистрации голоса и входящий аудиопоток, затем с интервалом 160 мс оценивает вероятность того, что говорит именно целевой человек. Модель предназначена для приложений на устройстве или в облаке, которые должны реагировать только на речь зарегистрированного пользователя, в том числе при нескольких говорящих и фоновом шуме.

Модель реализована на PyTorch и объединяет обнаружение голосовой активности, различение целевого говорящего и временное моделирование. В составе архитектуры используются акустические признаки Fbank, голосовой backbone ERes2NetV2 с 13,93 млн параметров и FiLM-модуляция по вектору регистрации размерностью 192. Лицензия — Apache-2.0. README не указывает поддерживаемые языки речи; метаданные карточки содержат коды zh и en.

Порог вероятности настраивается под сценарий: более высокий порог снижает риск ложного принятия ценой большего числа пропусков. Для устойчивости потоковой работы можно применять гистерезис. Качество снижается при регистрации короче одной секунды, сжатом аудио, несовпадении условий записи и большом расстоянии до микрофона; также сложнее различать людей с похожими голосами. Модель не предназначена для аутентификации личности, обнаружения подделок голоса или скрытого наблюдения. Регистрация голосового шаблона требует информированного согласия говорящего.

Сценарии применения

  • фильтрация голосовых команд по зарегистрированному пользователю
  • обнаружение речи выбранного говорящего в многоголосом разговоре
  • голосовое управление устройством с учётом владельца
  • потоковое выделение речи целевого человека на фоне шума

Ограничения

Качество снижается при аудио регистрации короче одной секунды, сжатии с потерями, несовпадении условий записи и дальнем расположении микрофона; похожие по тембру голоса различать сложнее. Модель не предназначена для аутентификации личности, обнаружения подделок или проверки живости голоса.

Карточка модели

README от автора на Hugging Face, как он его опубликовал

Открыть на Hugging Face

nomo-pvad — Streaming Target-Speaker Detection (Inference)

Given a target speaker's enrollment audio and an incoming audio stream, nomo-pvad determines whether the target speaker is speaking, in real time, at 160 ms intervals. It supports applications that respond only to an enrolled speaker, including scenarios with multiple speakers and background noise. Inference operates on streaming audio chunks and supports on-device deployment.

  • Input: enrollment audio (used to extract a d-vector speaker embedding) and a 16 kHz audio stream to analyze
  • Output: a target-speaker probability ∈ [0, 1] for every 160 ms chunk
  • Includes inference code and sample audio, without training code. Version 1.1 (tag release-1.1).

📄 Technical report (task definition, module architecture and configuration, training settings, and measured latency and accuracy): https://tuya.com/model/doc/pvad

🎧 Online demo: https://tuya.com/model/demo/pvad

⚠️ The demo includes substantial additional engineering beyond the open-source baseline in this repository (model only, no pre/post-processing). Those additions are not included in this release.

Installation

# After cloning the repo, install dependencies:
pip install -r requirements.txt

The nomo-pvad weights (approximately 35 MB) are bundled at weights/nomo_pvad.pt, so no separate download is required for these weights. The original ERes2NetV2 speaker model is downloaded automatically on first run if it is not already available locally (see Architecture).

Command-line usage

The repository includes enrollment and test audio for a quick check. The first portion of the test clip contains the target speaker and should be classified as target speech; the later portion contains a non-target speaker and should be classified as non-target speech:

python infer.py --enroll examples/enroll.wav --test examples/test.wav --verbose

Illustrative output (excerpt; p is the target-speaker probability, followed by a timeline with 160 ms resolution):

▶ streaming detection (one frame per 160 ms) …
    0.16s  p=0.92  █ target speaker
    0.32s  p=0.90  █ target speaker
    ...
    2.72s  p=0.11  · non-target / silence
    2.88s  p=0.08  · non-target / silence

  0s          2s          4s
  ████████████████··········
  █ target speaking     · non-target / silence

Result: ✅ target speaker detected (≈ 2.4 s of target speech, 55%)

Or use your own audio:

python infer.py --enroll enroll.wav --test test.wav
# per-chunk log: --verbose ; GPU: --device cuda:0 ; threshold: --threshold 0.7

Selecting the decision threshold

process_chunk returns the target-speaker probability P(target) ∈ [0, 1]. The decision threshold defines the operating point selected for deployment and should be adjusted to the application:

ScenarioSuggested thresholdTrade-off
Speaker-based gating / false-acceptance prevention (high cost of false acceptance)0.7–0.85Lower false acceptance rate, slightly higher miss rate (the target speaker may occasionally need to repeat themselves); default 0.7
Balanced0.6Balance between recall and false acceptance rate
Multi-speaker turn-taking / high recall0.5–0.6Prioritize recall while tolerating more false acceptances

A higher threshold makes acceptance more conservative. Streaming deployments typically also use a state machine with hysteresis, requiring N consecutive frames before changing the detection state, to reduce rapid state changes.

Library usage

from nomo_pvad import NomoPVAD, NomoPVADSession

m = NomoPVAD("weights/nomo_pvad.pt", device="cpu")   # ERes2NetV2 auto-downloads on first run
sess = NomoPVADSession(m)
sess.set_enrollment(enroll_pcm_f32_16k)          # enroll the target speaker
for chunk_f32 in stream_160ms_chunks:           # 160 ms each (2560 samples @ 16k)
    p = sess.process_chunk(chunk_f32)            # target-speaker probability [0, 1]

Repository structure

infer.py           Command-line inference example
nomo_pvad.py       Streaming inference wrapper (enrollment → per-chunk probability)
core/              Model architecture (model + eres2netv2_backbone + film + frame_adapter)
weights/           Bundled nomo_pvad.pt weights; the original ERes2NetV2 model is downloaded on first run
examples/          Sample audio (enroll.wav + test.wav)

Architecture

enroll (≥10s) ─► ERes2NetV2 full model (with pooling, frozen) ─► d-vector 192-d (L2-normalized)
                                                                   │  one-time; runtime only needs this vector
                                                                   ▼
stream ─► Fbank ─► ERes2NetV2 trunk ─► FiLM ─► proj ─► speech encoder ─► det decoder ─► chunk head ─► P(target)
 16kHz    80-d    pooling removed·8× ds  γ·(x+β) 1024→256   causal ×2        causal ×1     every 2 frames  every 160ms
ModuleConfigurationParameters
Acoustic features80-dimensional filterbank (Fbank) features, 25 ms window / 10 ms hop, dither=0, mean subtraction over the time dimension—
Speaker backboneERes2NetV2 (baseWidth=26, scale=2, expansion=2), final pooling removed; 8× temporal downsampling → 12.5 Hz (80 ms/frame), mean pooling over the frequency dimension, 1024-dimensional output13.93M
FiLM modulation192 → LayerNorm→Linear(512)→SiLU→Dropout(0.1)→Linear(2048), split into (γ̃, β), γ=1+γ̃, output γ·(x+β); final layer initialized to zero → identity mapping at the start of training1.15M
Feature projectionLayerNorm(1024) + Linear(1024→256)0.26M
Speech encoderCausalConv1d + GLU residual blocks ×2, d_model=256, kernel=71.84M
Detection decoderSame residual block ×10.92M
Chunk classification headMean pooling over every 2 backbone frames (2 × 80 ms) to produce 1 chunk → LayerNorm + Linear(256) + SiLU + Dropout + Linear(2), softmax yields the target-class probability0.07M
Total18.16M, FP16 weights: 36.6 MB

The bundled nomo_pvad.pt contains the fine-tuned backbone. The full original ERes2NetV2 (with pooling) extracts the enrollment embedding. If enrollment happens in the cloud or during provisioning, pass the precomputed 192-dimensional vector to sess.set_enrollment_emb(...). The current Python wrapper also loads the original ERes2NetV2 checkpoint during initialization, even with a precomputed embedding. For offline use, cache that model in advance or pass its local directory via eres2netv2_dir (CLI: --eres2netv2_dir); otherwise, it is downloaded automatically on first run.

Key design choices:

  • A single network integrates voice activity detection (VAD), target-speaker discrimination, and temporal modeling, producing an output every 160 ms. This avoids combining separate speaker verification, VAD, and rule-based components, simplifying deployment and supporting low-latency operation.
  • FiLM speaker conditioning: the enrollment d-vector applies an affine modulation to each frame's features instead of being concatenated at the input, preserving speaker conditioning in deeper layers. Zero initialization of the final layer makes the modulation an identity mapping at the start of training.
  • Temporal modeling with CausalConv1d + GLU residual blocks (instead of a Conformer with a look-ahead window): training and inference share the same structure, with no reliance on truncating future frames at inference time.

Intended use and limitations

  • Intended use: on-device or cloud applications that respond only to the enrolled speaker, including scenarios with multiple speakers and background noise. Voiceprint enrollment requires the speaker's informed consent.
  • Unintended use: monitoring or tracking without consent, or high-risk applications such as identity authentication. The model is not designed for spoofing countermeasures or liveness detection.
  • Limitations: performance degrades with very short enrollment audio (<1 s), lossy audio transmission (e.g. Opus), mismatched recording environments, or far-field audio. Distinguishing speakers of the same gender with similar vocal timbres is a known challenge.

License

  • Code: Apache-2.0 (see LICENSE).
  • ERes2NetV2 speaker backbone: from 3D-Speaker / ModelScope (iic/speech_eres2netv2_sv_zh-cn_16k-common), declared Apache-2.0 upstream.
    • weights/nomo_pvad.pt contains weights fine-tuned from that backbone (final pooling removed, all parameters fine-tuned for this task) — a derivative work, redistributed under Apache-2.0 with attribution here.
    • The enrollment side uses the unmodified original full model (with pooling); it is not bundled and downloads automatically from ModelScope on first run.

Как запустить

На своей GPU в ailist. Цена — по текущим предложениям провайдеров

GPU в ailist

Универсальный рантайм · pytorch

Нельзя запустить

Задача «voice-activity-detection» пока не поддерживается рантаймом.

Ревизия весов
36cf3fa

0 моделей