查看原文
其他

WeNet 更新:支持 Endpoint 检测

彭震东 WeNet步行街 2021-07-07

Endpoint 检测是语音识别系统的重要组成部分,可以提高人机交互的效能和质量。它的任务是确定用户何时结束讲话,这对于实时长语音转写和语音搜索等交互式语音应用非常重要。

最近,WeNet 的更新则支持了 endpoint 的检测。有了 endpoint 检测,我们就可以愉快地进行实时长语音转写了。下面将从实现原理和应用方面介绍 endpoint 检测和实时长语音转写的使用。

Endpoint 原理

Endpoint 的实现主要有两种思路,一种是端到端的方式直接在声学模型中对 endpoint 进行建模;另一种是制定规则,检测到持续的静音则认为是 endpoint。

开源的语音识别工具 Kaldi[1] 中使用的就是第二种方式,制定了五条规则,只要满足其中一条则认为是检测到了 endpoint。

  1. 识别出文字之前,检测到了 5s 的静音;
  2. 识别出文字之后,检测到了 2s 的静音;
  3. 解码到概率较小的 final state,且检测到了 1s 的静音;
  4. 解码到概率较大的 final state,且检测到了 0.5s 的静音;
  5. 已经解码了 20s。

WeNet Endpoint 原理

为了满足不同场景下的 endpoint 检测,WeNet 基于 CTC 架构实现了 endpoint 检测。这种实现方法易于控制 endpoint 的超参数,并且不需要训练额外的模型。

参考 Shinji 等人的论文[2],WeNet 将连续的长 blank 标签,视为非语音区域。非语音区域满足一定的条件,即可认为是检测到了 endpoint。同时,参考 Kaldi 的 src/online2/online-endpoint.h,WeNet 制定了以下三条规则:

  1. 识别出文字之前,检测到了 5s 的静音;
  2. 识别出文字之后,检测到了 1s 的静音;
  3. 已经解码了 20s。

只要满足上述三条规则中的任意一条,WeNet 就认为检测到了 endpoint。

WeNet Endpoint 实现

WeNet 中 endpoint 检测相关代码的实现在 decoder/ctc_endpoint.h 和 decoder/ctc_endpoint.cc 中。

// 遍历每一个时间步
for (int t = 0; t < ctc_log_probs.size(0); ++t) {
  torch::Tensor logp_t = ctc_log_probs[t];
  // 获取当前时间步 blank 标签的概率
  float blank_prob = expf(logp_t[config_.blank].item<float>());
  // 解码帧数加一
  num_frames_decoded_++;
  // 判断 blank 标签的概率是否大于阈值(默认 0.8)
  if (blank_prob > config_.blank_threshold) {
    // 是,则尾部 blank 标签的帧数加一
    num_frames_trailing_blank_++;
  } else {
    // 否,则尾部 blank 标签的帧数置零
    num_frames_trailing_blank_ = 0;
  }
}
三条规则的表示如下所示,可以手动添加更多的规则或者更改规则中的时间,以满足各种不同场景下的需求。
// rule1 times out after 5000 ms of silence, even if we decoded nothing.
CtcEndpointRule rule1;
// rule2 times out after 1000 ms of silence after decoding something.
CtcEndpointRule rule2;
// rule3 times out after the utterance is 20000 ms long, regardless of
// anything else.
CtcEndpointRule rule3;

CtcEndpointConfig()
    : rule1(false50000), rule2(true10000), rule3(false020000) {}

实时长语音转写

大多数端到端语音识别方法,都假设输入的音频被适当地分割成短音频。这种假设,使得端到端语音识别系统难用于实时长语音转写。

使用 endpoint 检测,在进行实时长语音转写时,检测到 endpoint 就可以对当前候选结果进行重打分,并且重置解码状态。然后继续转写接下来的内容,重复上述过程。

使用实时长语音转写,只需要在启动客户端的时候,加上参数 --continuous_decoding=true 即可。或者直接通过 Browser/Server 在浏览器中体验实时长语音识别。新版的 Chrome 在 http 协议下可能无法调用麦克风,需要在 chrome://flags/#unsafely-treat-insecure-origin-as-secure 中添加 IP 和端口号。

方便起见,可以直接用 Chrome 打开 runtime/server/x86/web/templates/index.html,填写 WebSocket 的 IP 和端口进行识别,如下所示:

参考资料

[1] 

Kaldi: https://github.com/kaldi-asr/kaldi/blob/6260b27d146e466c7e1e5c60858e8da9fd9c78ae/src/online2/online-endpoint.h#L132-L150

[2] 

End-to-End Automatic Speech Recognition Integrated with CTC-Based Voice Activity Detection: https://arxiv.org/pdf/2002.00551.pdf



We make the Net better
长按二维码关注


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存