新技术|基于信号特征的语音编码器 Lyra Android 实践

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

1. Lyra语音编解码器介绍

机器学习现在应用的主要领域还是NLP、语音识别、图像识别等,之前谷歌推出了基于机器学习的语音编解码器Lyra。

通过语音和视频通话与他人在线联系正日益成为日常生活的一部分。实时通信框架,如WebRTC,使这成为可能,依赖于有效的压缩技术,编解码器,编码(或解码)信号传输或存储。几十年来,编解码器一直是媒体应用的重要组成部分,它使需要带宽的应用程序能够有效地传输数据,并使人们期望在任何时间、任何地点都能实现高质量的通信。

因此,开发视频和音频编解码器的一个持续的挑战是提供更高的质量,使用更少的数据,并最小化实时通信的延迟。尽管视频似乎比音频更需要带宽,但现代视频编解码器可以达到比今天使用的一些高质量语音编解码器更低的比特率。结合低比特率视频和语音编解码器,即使在低带宽网络中也能提供高质量的视频通话体验。然而,从历史上看,音频编解码器的比特率越低,语音信号就越难理解,也就越机械。此外,虽然一些人可以访问到一致的高质量、高速的网络,但这种级别的连接并不是通用的,即使是那些连接良好的地区,有时也会遇到质量差、带宽低和网络连接拥塞的情况。

为了解决这个问题,谷歌推出了Lyra,一种高质量的、非常低比特率的语音编解码器,即使在最慢的网络上也可以进行语音通信。为此,它应用了传统的编解码器技术,同时利用机器学习(ML)的先进方法,在数千小时的数据上训练模型,以创建一种压缩和传输语音信号的新方法。

2. Lyra语音编解码器原理简介

Lyra编解码器的基本结构非常简单。每40毫秒从语音中提取特征,然后压缩以3kbps的比特率传输。这些特征本身就是log mel谱图,一组数字代表不同频带的语音能量,传统上用它们来表示感知相关性,因为它们是模仿人类的听觉反应。在另一端,生成模型使用这些特征来重现语音信号。

Lyra利用新的听起来很自然的生成模型的力量来维持低比特率的参数编解码器,同时实现高质量,与当今大多数流媒体和通信平台使用的最先进的波形编解码器相当。

通过使用一种更高效的递归生成模型,一种WaveRNN变异,以较低的速率工作,但在不同的频率范围内并行生成多个信号,然后以所需的采样率将其合并为单个输出信号,从而降低了计算复杂度。这个技巧,加上64位ARM的优化,使Lyra不仅能在云服务器上运行,还能在像Pixel手机这样的中端手机上实时运行(处理延迟为100ms)。然后,生成模型在使用超过70种语言的扬声器的数千小时的语音数据上进行训练,并优化以准确重现输入音频。

image1-3484742.png

传统的参数编解码器只是简单地从语音中提取关键参数,然后用于在接收端重建信号,实现了低比特率,但通常听起来很机械和不自然。这些缺点导致了新一代高质量音频生成模型的发展,该模型不仅能够区分信号,而且还能生成全新的信号,从而彻底改变了该领域。DeepMind的WaveNet是这些生成模型中的第一个,为以后的许多模型铺平了道路。此外,WaveNetEQ,目前在Duo中使用的基于生成模型的包丢失隐藏系统,已经演示了该技术如何在真实场景中使用。

以这些模型为基础,开发了一种新模型,能够用最少的数据重建语音。Lyra利用这些新的听起来很自然的生成模型的力量来维持低比特率的参数编解码器,同时实现高质量,与当今大多数流媒体和通信平台使用的最先进的波形编解码器相当。波形编解码器的缺点是,它们通过压缩和逐样本发送信号来实现高质量,这需要更高的比特率,在大多数情况下,并不是实现自然语音的必要条件。

生成模型的一个问题是它们的计算复杂性。Lyra通过使用一种更便宜的递归生成模型避免了这个问题,这是一种WaveRNN变体,它以较低的速率工作,但在不同的频率范围内并行生成多个信号,然后在期望的采样率下将这些信号合并成单个输出信号。这个技巧使Lyra不仅能在云服务器上运行,还能实时地在中档手机上运行(处理延迟为90ms,与其他传统语音编解码器一致)。然后,生成模型在数千小时的语音数据上进行训练,并像WaveNet一样进行优化,以准确地再现输入音频。

3. Lyra与传统音频编解码器对比

Lyra的目标是传统低比特率音频编解码器的替代品。目前,免费开源编解码器Opus是基于webbrtc的VOIP应用程序中最广泛使用的编解码器,音频为32kbps,通常获得透明的语音质量,即与原始语音无区别。然而,虽然Opus可以在带宽限制更大的环境下使用,低至6kbps,但此时音频的质量已经下降的很明显。其他编解码器(Speex、MELP、AMR)能够以与Lyra相当的比特率运行,但每一种都存在音频质量问题,码率越低,声音越机械越不够平滑。

目前,Lyra的设计工作速率为3kbps,听力测试表明,在该比特率下,Lyra的性能优于任何其他编解码器,并优于Opus的8kbps,因此实现了60%以上的带宽削减。当带宽条件不足以满足高比特率和现有的低比特率编解码器不能提供足够的质量时,可以使用Lyra。

Clean Speech对比:

原始音频 Opus@6kbps Lyra@3kbps
image-20211006101149184-3486311.png image-20211006101244909-3486367.png image-20211006101314845-3486396.png
链接: pan.baidu.com/s/1q7bQQFBO… 提取码: yscj 链接: pan.baidu.com/s/1bmA9Im68… 提取码: nt3a 链接: pan.baidu.com/s/1KQXr2UY9… 提取码: 5qsi

Noisy Environment:

原始音频 Opus@6kbps Lyra@3kbps Speex@3kbps
image-20211006103528630-3487729.png image-20211006103513282-3487714.png image-20211006103450029-3487691.png image-20211006103429300-3487670.png
链接: pan.baidu.com/s/1hIv_tn8Y… 提取码: dwf8 链接: pan.baidu.com/s/1S9TVaJpB… 提取码: 9qzi 链接: pan.baidu.com/s/1q-WhbNQp… 提取码: 23p7 链接: pan.baidu.com/s/16D7UzOZO… 提取码: ah7e

4.Android平台使用Lyra编解码器

4.1 安装bazel

官网教程:docs.bazel.build/versions/ma…

export BAZEL_VERSION=4.2.1

curl -fLO "https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-installer-darwin-x86_64.sh"

./bazel-${BAZEL_VERSION}-installer-darwin-x86_64.sh --user
Bazel installer
---------------

Bazel is bundled with software licensed under the GPLv2 with Classpath exception.
You can find the sources next to the installer on our release page:
   https://github.com/bazelbuild/bazel/releases

# Binary package at HEAD (@02ad3e3bc69)
   - [Commit](https://github.com/bazelbuild/bazel/commit/02ad3e3bc69)
Uncompressing.......

Bazel is now installed!

Make sure you have "/Users/qingkouwei/bin" in your path.

For bash completion, add the following line to your :
  source /Users/shenjunwei/.bazel/bin/bazel-complete.bash

For fish qingkouwei completion, link this file into your
/Users/shenjunwei/.config/fish/completions/ directory:
  ln -s /Users/qingkouwei/.bazel/bin/bazel.fish /Users/qingkouwei/.config/fish/completions/bazel.fish

See http://bazel.build/docs/getting-started.html to start a new project!
复制代码

链接bazel.fish:ln -s /Users/qingkouwei/.bazel/bin/bazel.fish /Users/qingkouwei/.config/fish/completions/bazel.fish

配置环境变量:export PATH=/Users/qingkouwei/bin:$PATH

4.2 下载sdk

 sdkmanager  --sdk_root=$HOME/android/sdk --list
 sdkmanager  --sdk_root=$HOME/android/sdk --install  "platforms;android-30" "build-tools;30.0.0" "ndk;21.4.7075529"
 
复制代码

配置ANDROID_HOME与ANDROID_NDK_HOME

4.3 执行编译命令

执行 bazel build android_example:lyra_android_example --config=android_arm64 --copt=-DBENCHMARK

4.4 常见错误处理

4.4.1 报错一

ERROR: Error fetching repository: /Users/qingkouwei/fruits-plans/verimillionorange/lyra/WORKSPACE:118:23: Bazel requires Android build tools version 30.0.0 or newer, 29.0.3 was provided
ERROR: Analysis of target '//android_example:lyra_android_example' failed; build aborted: Bazel requires Android build tools version 30.0.0 or newer, 29.0.3 was provided
INFO: Elapsed time: 0.198s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded, 0 targets configured)
复制代码

修改/Users/qingkouwei/fruits-plans/verimillionorange/lyra/WORKSPACE:118配置为30,30.0.0

4.4.2 报错二

WARNING: /private/var/tmp/_bazel_qingkouwei/2ddc2e20128c69264bf5fbb324e74851/external/com_google_audio_dsp/third_party/fft2d/BUILD:3:11: in linkstatic attribute of cc_library rule @com_google_audio_dsp//third_party/fft2d:fft2d: setting 'linkstatic=1' is recommended if there are no object files
INFO: Analyzed target //android_example:lyra_android_example (110 packages loaded, 9000 targets configured).
INFO: Found 1 target...
ERROR: /private/var/tmp/_bazel_qingkouwei/2ddc2e20128c69264bf5fbb324e74851/external/com_google_glog/BUILD.bazel:7:13: Compiling src/logging.cc failed: (Exit 1): clang failed: error executing command external/androidndk/ndk/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -gcc-toolchain external/androidndk/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64 -target ... (remaining 71 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
external/com_google_glog/src/logging.cc:798:35: error: use of undeclared identifier 'prefix_len'
                        message + prefix_len);
                                  ^
1 error generated.
Target //android_example:lyra_android_example failed to build
复制代码

修改/private/var/tmp/_bazel_qingkouwei/2ddc2e20128c69264bf5fbb324e74851/external/com_google_glog/src/logging.cc #793,注释掉+ prefix_len

4.4.3 错误三

WARNING: /private/var/tmp/_bazel_qingkouwei/2ddc2e20128c69264bf5fbb324e74851/external/com_google_audio_dsp/third_party/fft2d/BUILD:3:11: in linkstatic attribute of cc_library rule @com_google_audio_dsp//third_party/fft2d:fft2d: setting 'linkstatic=1' is recommended if there are no object files
INFO: Analyzed target //android_example:lyra_android_example (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: /Users/qingkouwei/fruits-plans/verimillionorange/lyra/android_example/BUILD:40:15: Linking _nativedeps/84_7_0_0_2_3e5289b33307c3130dbcc205157825ab5877f28ecd3298c4ac55dc581b7024b0.so failed: (Exit 1): clang failed: error executing command external/androidndk/ndk/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -shared -o ... (remaining 112 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
external/androidndk/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld: cannot find Foundation: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Target //android_example:lyra_android_example failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 236.159s, Critical Path: 52.52s
INFO: 371 processes: 28 internal, 303 darwin-sandbox, 40 worker.
FAILED: Build did NOT complete successfully
复制代码

bazel-lyra/external/com_google_absl/absl/time/internal/cctz/BUILD.bazel

26行到38行

#config_setting(
#    name = "osx",
#    constraint_values = [
#        "@bazel_tools//platforms:osx",
#    ],
#)

#config_setting(
#    name = "ios",
#    constraint_values = [
#        "@bazel_tools//platforms:ios",
#    ],
#)
复制代码

78到85

#    linkopts = select({
#        ":osx": [
#            "-framework Foundation",
#        ],
#        ":ios": [
#            "-framework Foundation",
#        ],
#        "//conditions:default": [],
#    }),
复制代码

bazel-lyra/external/com_google_absl/absl/BUILD.bazel 31行到43行

#config_setting(
#    name = "osx",
#    constraint_values = [
#        "@bazel_tools//platforms:osx",
#    ],
#)

#config_setting(
#    name = "ios",
#    constraint_values = [
#        "@bazel_tools//platforms:ios",
#    ],
#)
复制代码

5. Android平台Lyra演示效果

下面是Lyra官方demo的中文效果,demo点击按钮录音编码,再次点击解码播放:

www.bilibili.com/video/BV15Q…

6. 总结

Lyra为我们提供了一种基于特征存储的编解码器实现思路,目标是保证质量基础上大大降低音频码率。目前还不是很完善:

  1. 数据训练方式未开源,Lyra支持了70种语音,对中文的支持基于开源数据集,不能保证编码质量;
  2. 包含了模型数据,包体积大;

虽然目前Lyra还有一些缺点离商用有些距离,但是它是一种思路一种指导思想,相信离我们实际使用会越来越近。


欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边,抽奖详情见活动文章

猜你喜欢

转载自juejin.im/post/7018094258519293966