Skip to content

Commit ef46055

Browse files
committed
fix: respect explicit VAD silence threshold
1 parent b78e636 commit ef46055

5 files changed

Lines changed: 94 additions & 2 deletions

File tree

docs/vllm_guide.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ cd /path/to/FunASR && pip install -e .
4545

4646
**Hardware**: GPU ≥ 8 GB VRAM, CUDA ≥ 11.8. 16 GB+ recommended.
4747

48+
Install a PyTorch/torchaudio/vLLM combination that matches your NVIDIA driver and
49+
CUDA runtime. Do not blindly keep the newest wheel if it was built for a newer
50+
CUDA runtime than your driver supports; PyTorch can fail during CUDA
51+
initialization with `The NVIDIA driver on your system is too old` before FunASR
52+
starts. If that happens, reinstall compatible PyTorch, torchaudio, and vLLM
53+
wheels for the CUDA version reported by `nvidia-smi`, or update the NVIDIA
54+
driver first.
55+
4856
---
4957

5058
## 2. vLLM Engine Architecture

docs/vllm_guide_zh.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ cd /path/to/FunASR && pip install -e .
4444

4545
**硬件**:GPU ≥ 8GB VRAM,CUDA ≥ 11.8。推荐 16GB+。
4646

47+
请根据 NVIDIA 驱动和 `nvidia-smi` 显示的 CUDA 版本选择匹配的
48+
PyTorch/torchaudio/vLLM 组合,不要无条件保留 pip 拉到的最新 wheel。若
49+
vLLM 或 PyTorch wheel 依赖的 CUDA runtime 高于当前驱动支持范围,可能在
50+
FunASR 启动前就报 `The NVIDIA driver on your system is too old`。遇到该错误时,
51+
优先重装与当前驱动/CUDA 匹配的 PyTorch、torchaudio、vLLM wheel,或先升级
52+
NVIDIA 驱动。
53+
4754
---
4855

4956
## 2. vLLM 推理引擎架构

docs/vllm_guide_zh_v2.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ cd /path/to/FunASR && pip install -e .
4545

4646
**硬件**:GPU ≥ 8GB VRAM,CUDA ≥ 11.8。推荐 16GB+。
4747

48+
请根据 NVIDIA 驱动和 `nvidia-smi` 显示的 CUDA 版本选择匹配的
49+
PyTorch/torchaudio/vLLM 组合,不要无条件保留 pip 拉到的最新 wheel。若
50+
vLLM 或 PyTorch wheel 依赖的 CUDA runtime 高于当前驱动支持范围,可能在
51+
FunASR 启动前就报 `The NVIDIA driver on your system is too old`。遇到该错误时,
52+
优先重装与当前驱动/CUDA 匹配的 PyTorch、torchaudio、vLLM wheel,或先升级
53+
NVIDIA 驱动。
54+
4855
---
4956

5057
## 2. vLLM 推理引擎架构

funasr/models/fsmn_vad_streaming/model.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -938,8 +938,10 @@ def inference(
938938
n = int(len(audio_sample) // chunk_stride_samples + int(_is_final))
939939
m = int(len(audio_sample) % chunk_stride_samples * (1 - int(_is_final)))
940940
segments = []
941-
# Dynamic silence threshold
942-
dynamic_silence = kwargs.get("dynamic_silence", True)
941+
# Keep explicit fixed-threshold requests from being overwritten by the dynamic schedule.
942+
dynamic_silence = kwargs.get(
943+
"dynamic_silence", kwargs.get("max_end_silence_time") is None
944+
)
943945
silence_schedule = kwargs.get("silence_schedule", DEFAULT_SILENCE_SCHEDULE)
944946
speech_to_sil_ms = self.vad_opts.speech_to_sil_time_thres
945947
accumulated_ms = cache.get("_dynamic_accumulated_ms", 0)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import unittest
2+
from types import SimpleNamespace
3+
from unittest.mock import patch
4+
5+
import torch
6+
7+
from funasr.models.fsmn_vad_streaming import model as vad_model
8+
9+
10+
class TestFsmnVadDynamicSilence(unittest.TestCase):
11+
def _run_inference(self, **kwargs):
12+
vad = vad_model.FsmnVADStreaming.__new__(vad_model.FsmnVADStreaming)
13+
vad.vad_opts = SimpleNamespace(speech_to_sil_time_thres=100)
14+
vad.forward = lambda **batch: []
15+
16+
cache = {
17+
"frontend": {},
18+
"prev_samples": torch.empty(0),
19+
"encoder": {},
20+
"stats": SimpleNamespace(
21+
vad_state_machine=vad_model.VadStateMachine.kVadInStateInSpeechSegment,
22+
max_end_sil_frame_cnt_thresh=200,
23+
speech_noise_thres=0.6,
24+
),
25+
}
26+
frontend = SimpleNamespace(fs=16000, frame_shift=10, lfr_n=1)
27+
28+
def fake_extract_fbank(*args, **kwargs):
29+
cache["frontend"]["waveforms"] = torch.zeros(1, 16000)
30+
return torch.zeros(1, 1, 80), torch.tensor([100])
31+
32+
with (
33+
patch.object(
34+
vad_model,
35+
"load_audio_text_image_video",
36+
return_value=[torch.zeros(16000)],
37+
),
38+
patch.object(vad_model, "extract_fbank", side_effect=fake_extract_fbank),
39+
):
40+
vad_model.FsmnVADStreaming.inference(
41+
vad,
42+
torch.zeros(16000),
43+
frontend=frontend,
44+
cache=cache,
45+
key=["utt"],
46+
chunk_size=1000,
47+
is_final=False,
48+
device="cpu",
49+
**kwargs,
50+
)
51+
52+
return cache
53+
54+
def test_explicit_max_end_silence_time_keeps_fixed_threshold_by_default(self):
55+
cache = self._run_inference(max_end_silence_time=300)
56+
57+
self.assertEqual(cache["stats"].max_end_sil_frame_cnt_thresh, 200)
58+
self.assertNotIn("_dynamic_accumulated_ms", cache)
59+
60+
def test_explicit_dynamic_silence_still_enables_schedule(self):
61+
cache = self._run_inference(max_end_silence_time=300, dynamic_silence=True)
62+
63+
self.assertEqual(cache["stats"].max_end_sil_frame_cnt_thresh, 1900)
64+
self.assertEqual(cache["_dynamic_accumulated_ms"], 1000)
65+
66+
67+
if __name__ == "__main__":
68+
unittest.main()

0 commit comments

Comments
 (0)