From e8ea59a02c9362ae78e6730ca574862f5aedd6c7 Mon Sep 17 00:00:00 2001 From: LauraGPT Date: Fri, 14 Aug 2026 07:35:21 +0000 Subject: [PATCH] fix(vad): preserve Silero ONNX CPU inputs --- funasr/models/silero_vad/model.py | 16 ++++++++-------- tests/test_silero_vad_adapter.py | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/funasr/models/silero_vad/model.py b/funasr/models/silero_vad/model.py index c5f120d46..7f90ceeda 100644 --- a/funasr/models/silero_vad/model.py +++ b/funasr/models/silero_vad/model.py @@ -26,7 +26,8 @@ class SileroVad(torch.nn.Module): '`python -m pip install "funasr[silero]"` or ' "`python -m pip install silero-vad`." ) from error - self.model = load_silero_vad(onnx=kwargs.get("silero_onnx", False)) + self.onnx = bool(kwargs.get("silero_onnx", False)) + self.model = load_silero_vad(onnx=self.onnx) self.get_speech_timestamps = get_speech_timestamps @staticmethod @@ -34,8 +35,10 @@ class SileroVad(torch.nn.Module): if not max_single_segment_time: return segments limit_ms = int(max_single_segment_time) - if limit_ms < 0: - raise ValueError("max_single_segment_time must be non-negative") + if limit_ms <= 0: + raise ValueError( + "max_single_segment_time must resolve to a positive millisecond value" + ) split = [] for start, end in segments: while end - start > limit_ms: @@ -60,11 +63,8 @@ class SileroVad(torch.nn.Module): started = time.perf_counter() results = [] for index, audio in enumerate(audio_list): - waveform = ( - torch.as_tensor(audio, dtype=torch.float32) - .flatten() - .to(self.anchor.device) - ) + device = torch.device("cpu") if self.onnx else self.anchor.device + waveform = torch.as_tensor(audio, dtype=torch.float32).flatten().to(device) timestamps = self.get_speech_timestamps( waveform, self.model, diff --git a/tests/test_silero_vad_adapter.py b/tests/test_silero_vad_adapter.py index 2effe6f49..3399e1381 100644 --- a/tests/test_silero_vad_adapter.py +++ b/tests/test_silero_vad_adapter.py @@ -72,10 +72,29 @@ class TestSileroVadAdapter(unittest.TestCase): results, _ = model.inference(data_in=[torch.zeros(16000)], key=["sample"]) self.assertEqual(results, [{"key": "sample", "value": []}]) + @patch("silero_vad.get_speech_timestamps") + @patch("silero_vad.load_silero_vad") + def test_onnx_waveform_stays_on_cpu(self, load_model, timestamps): + load_model.return_value = object() + + def timestamps_stub(waveform, model, sampling_rate, **options): + self.assertEqual(waveform.device.type, "cpu") + return [] + + timestamps.side_effect = timestamps_stub + model = SileroVad(silero_onnx=True).to("meta") + results, _ = model.inference(data_in=[torch.zeros(16000)], key=["sample"]) + self.assertEqual(results, [{"key": "sample", "value": []}]) + load_model.assert_called_once_with(onnx=True) + def test_rejects_negative_max_segment_length(self): - with self.assertRaisesRegex(ValueError, "non-negative"): + with self.assertRaisesRegex(ValueError, "positive"): SileroVad._split_long_segments([[100, 1100]], -500) + def test_rejects_sub_millisecond_max_segment_length(self): + with self.assertRaisesRegex(ValueError, "positive"): + SileroVad._split_long_segments([[100, 1100]], 0.5) + if __name__ == "__main__": unittest.main()