diff --git a/examples/industrial_data_pretraining/fun_asr_nano/docs/realtime_demo.md b/examples/industrial_data_pretraining/fun_asr_nano/docs/realtime_demo.md index 4a8e0e258..44b477ffb 100644 --- a/examples/industrial_data_pretraining/fun_asr_nano/docs/realtime_demo.md +++ b/examples/industrial_data_pretraining/fun_asr_nano/docs/realtime_demo.md @@ -34,6 +34,64 @@ └──────────────────────────┘ ``` +## 推理逻辑 + +### 核心设计 + +服务**不是**将全部音频累积后一次性解码,而是基于 VAD 端点检测**逐段解码**: + +``` +音频流 ──→ StreamingVAD (60ms chunk) ──→ 检测到端点 ──→ _decode_segment (vLLM) + │ │ + │ ▼ + │ locked_sentences (文字锁定) + │ │ + │ ▼ + │ SPK assign (说话人分配) + │ + └──→ 未结束 ──→ decode partial (vLLM, 每0.48s) + │ + ▼ + partial text (实时预览,会被覆盖) +``` + +### 两条推理路径 + +| 路径 | 触发条件 | 推理范围 | 输出 | +|------|---------|---------|------| +| **确认段解码** | VAD 检测到静音端点 | 该段完整音频 | 锁定到 sentences,永不改变 | +| **Partial 预览** | 每 0.48s + 新音频 ≥ 960ms | 当前说话中的全部音频 | 临时文字,随时覆盖 | + +### 动态 VAD 阈值 + +为避免切碎短句或堆积过长段,静音阈值根据当前段已累积时长动态调整: + +| 累积时长 | 需要静音 | 效果 | +|---------|---------|------| +| ≤ 5s | 2.0s | 短句不切碎 | +| 5-10s | 1.5s | 正常分句 | +| 10-15s | 1.0s | 开始收紧 | +| 15-30s | 0.8s | 较快切分 | +| 30-45s | 0.4s | 防止过长 | +| > 45s | 0.1s | 强制切分 | + +### STOP 时的最终处理 + +1. 将剩余音频喂给 VAD(`is_final=True`),收集最后的确认段 +2. 如果仍在说话中,强制结束并解码当前段 +3. 对所有 `sentences` 运行 SPK `finalize()`(全局重聚类,修正说话人 ID) +4. 返回 `is_final: true` 的完整结果 + +### 与 FunASRNanoStreamingVLLM 的区别 + +| | WebSocket 服务 (`serve_realtime_ws.py`) | SDK 流式 (`FunASRNanoStreamingVLLM`) | +|---|---|---| +| 分句方式 | VAD 自然端点 | 固定 720ms chunk | +| 推理粒度 | 每个 VAD 段整体解码 | 累积重编码全部音频 | +| 准确率 | 更高(完整语义段) | 较低(前 3s 噪声多) | +| 适用场景 | 生产环境实时服务 | SDK 级流式展示 | + + ## 快速部署 ### 环境要求