采用 Raspberry Pi 的智能语音助理应用的快速原型开发                              
Digi-Key

语音助理已经迅速成为一个重要的产品功能,这要归功于流行的基于智能语音的产品,例如 Amazon Echo 和 Google Home。虽然语音服务提供商为开发人员提供了应用程序编程接口 (API) 支持,因此他们不必成为语音识别和解析细节方面的专家,但是将音频硬件和语音处理软件相结合的要求仍然是一个重大障碍。

此外,在与每个学科相关的细节工作中,在声学设计、音频工程、基于云的服务方面没有丰富经验的项目可能会面临严重延迟。

为了解决这些问题,供应商提供了完整的语音助理开发套件,以求显著简化问题。本文将分别介绍两种此类套件,一个套件来自 XMOS,另一个套件来自 Seeed Technology,它们分别实现了基于 Amazon Alexa 语音服务 (AVS) 和谷歌助理的定制产品的快速开发。这些电路板可与 Raspberry Foundation 的 Raspberry Pi 3 (RPi 3) 电路板连接。

本文将介绍如何让每个套件投入运行,并展示每个套件如何随时利用语音助理技术。

快速 AVS 评估

Amazon 公司推出了 Alexa 智能音箱,这是一款面向家庭的产品,提供智能语音助理功能,但过去这些功能在很大程度上仅限于智能手机。对于开发人员来说,AVS API 的发布为在定制系统设计中使用相同的语音助理功能打开了大门,但其仍然需要音频硬件和软件方面的丰富专业知识。现在,随着适用于 Amazon Alexa 语音服务 (AVS) 的 XMOS xCORE VocalFusion 4-Mic 套件的推出,实施语音助理功能的最后一个难题也迎刃而解。

XMOS 套件包括一个 XVF3000 处理器基板、由四个 Infineon IM69D130 MEMS 麦克风组成的 100 mm 线性阵列、xTAG 调试器、安装套件和电缆。开发人员需要为 RPi 3 提供有源扬声器、USB 电源,以及 USB 键盘、鼠标、监视器和互联网连接。在使用安装套件将 XMOS 板和麦克风阵列连接到 RPi 3 之后,开发人员可以快速评估 Amazon Alexa 语音助理(图1)。
图 1: 开发人员使用 XMOS xCORE VocalFusion 套件开始工作,将提供的麦克风阵列板(最左侧)和 XMOS 处理器板(中间)插入 Raspberry Pi 3 板(右侧)。(图片来源: XMOS)

将 RPi 3 连接到 USB 键盘、鼠标、监视器和互联网服务之后,下一步骤是从 SD 微型卡安装 Raspbian 操作系统,在 RPi 3 上打开端子,并克隆 XMOS VocalFusion 存储库。安装操作系统和存储库之后,只需运行位于克隆的 vocalfusion-avs-setup 目录下的 auto_install.sh。

安装脚本将配置 Raspberry Pi 音频系统及其与 xCORE VocalFusion 套件的连接,并在 Raspberry Pi 上安装和配置 AVS Device SDK。这个安装过程可能需要大约两个小时完成。

安装完成后,开发人员需要执行一个简单的过程来加载他们的 Amazon 开发人员凭据,然后开始测试大量的语音命令和内置功能。此时,XMOS 套件将能够演示 Alexa 的全套功能,如定时器、闹钟和日历,以及使用 Alexa Skills 套件构建的第三方功能。

参考设计

虽然设置步骤简单,但 XMOS 套件中的硬件和软件组件的功能却非常复杂。该套件为开发人员提供了实现定制设计的全面参考设计。XMOS 套件的核心是 XMOS XVF3000-TQ128 器件,它提供了很高的处理能力(图 2)。
图 2: XMOS XVF3000-TQ128 器件集成了两个 xCORE Tile,每个 Tile 包含八个内核,以提供高性能音频处理。(图片来源: XMOS)

该器件专为并行处理任务而构建,包含两个 xCORE Tile,每个 Tile 包含八个带集成 I/O 的 32 位 xCORE 内核、256 KB 的 SRAM、8 KB 的一次性可编程(OTP)片上存储器。xTIME 调度程序管理内核,并触发来自 I/O 引脚的硬件事件的内核操作。每个内核都可以独立执行计算、信号处理或控制任务,利用了 xCORE VocalFusion 套件中的集成式 2MB 闪存,以及用于套件设置和执行的代码和数据。

除了 XVF3000-TQ128 器件之外,XMOS 处理器基板还需要少量的附加组件(图 3)。除了基本的缓冲器和针座连接外,基板还包括 Cirrus Logic CS43L21 数模转换器(DAC),用于为外部扬声器生成输出音频。最后,底板还引出了 XVF3000-TQ128 器件 I2C 端口,以及经过音频优化的 I2S 数字音频接口。
图 3: XMOS 套件的基板包括 XVF3000-TQ128 器件、DAC、缓冲器,以及用于连接 Raspberry Pi 3 板和外部扬声器的针座。(图片来源: XMOS)

该套件的整体功能分为两个部分:XMOS 板上的音频处理、RPi 3 上的高级语音处理服务(图 4)。RPi 的 Broadcom 四核处理器运行软件,该软件用于分析音频流,进行唤醒词识别,并且处理与 Amazon AVS 的交互。
图 4: XMOS VocalFusion 套件将基板和 Raspberry Pi 3 板上的 Alexa 功能分开,前者用于音频信号处理,后者用于语音识别和更高级别的 Alexa 服务。(图片来源: XMOS)

软件安装过程配置这些子系统并加载所需的软件包,包括 Sensory 的独立于扬声器的唤醒词引擎,以及 AVS 客户端软件等。

AVS 提供了一系列与高级功能(如语音识别、音频回放和音量控制)相关的接口。操作通过来自 AVS 的消息(指令)和来自客户端的消息(事件)进行。例如,为了响应某些条件,AVS 可能会向客户端发送指示,指示客户端应播放音频、设置闹钟或打开灯光。相反,来自客户端的事件可通知 AVS 发生了某些事件,例如来自用户的新语音请求。

开发人员可以使用 AVS 器件软件开发套件 (SDK) API 和 C++ 软件库来扩展其 XMOS 套件或 XMOS 定制设计的功能。AVS Device SDK 通过一系列单独的 C++ 类和对象,提取出低级别操作,如音频输入处理、通信和 AVS 指令管理,开发人员可以使用或扩展它们,用于定制应用程序(图 5)。
图 5: Amazon AVS Device SDK 将 AVS 的广泛功能组织为单独的功能区域,每个功能区域都有自己的接口和库。(图片来源: AWS)

包含在 AVS Device SDK 中的完整样例应用程序展示了关键设计模式,包括创建设备客户端和唤醒词交互管理器(列表 1)除了全套的样例服务例程之外,该应用还显示了主程序如何只需要实例化样例应用程序对象 sampleApplication,并使用一个简单的命令来启动它: sampleApplication->run().
  1. /*
  2.      * Creating the DefaultClient - this component serves as an out-of-box default object that instantiates and "glues"
  3.      * together all the modules.
  4.      */
  5.     std::shared_ptr<alexaClientSDK::defaultClient::DefaultClient> client =
  6.         alexaClientSDK::defaultClient::DefaultClient::create(
  7.             m_speakMediaPlayer,
  8.             m_audioMediaPlayer,
  9.             m_alertsMediaPlayer,
  10.             speakSpeaker,
  11.             audioSpeaker,
  12.             alertsSpeaker,
  13.             audioFactory,
  14.             authDelegate,
  15.             alertStorage,
  16.             settingsStorage,
  17.             {userInterfaceManager},
  18.             {connectionObserver, userInterfaceManager});
  19. . . .
  20.     // If wake word is enabled, then creating the interaction manager with a wake word audio provider.
  21.     auto interactionManager = std::make_shared<alexaClientSDK::sampleApp::InteractionManager>(
  22.         client,
  23.         micWrapper,
  24.         userInterfaceManager,
  25.         holdToTalkAudioProvider,
  26.         tapToTalkAudioProvider,
  27.         wakeWordAudioProvider);
  28. . . .
  29.     client->addAlexaDialogStateObserver(interactionManager);
  30.     // Creating the input observer.
  31.     m_userInputManager = alexaClientSDK::sampleApp::UserInputManager::create(interactionManager);
  32. . . .
  33. void SampleApplication::run() {
  34.     m_userInputManager->run();
  35. }
列表 1: 开发人员可以使用 AVS Device SDK C++ 样例应用程序来扩展设备 AVS 客户端,AVS Device

SDK C++ 样例应用程序演示了用于创建 AVS 客户端、唤醒词交互管理器和用户输入管理器等的关键设计模式。(列表来源: AWS)

Google 助理快速原型

XMOS 套件可加快 Amazon Alexa 原型的开发速度,Seeed Technology 的 Google AIY 语音套件 可帮助开发人员使用 Google Assistant 构建原型。与 XMOS AVS 套件相同,Seeed Google AIY 语音套件可与 Raspberry Pi 3 板配合使用来构建原型,并提供必要的组件(图 6)。
图 6: 开发人员可将 Raspberry Pi 3 与 Seeed Technology 的 Google AIY 语音套件配合使用(它提供了构建原型所需的组件),从而快速创建 Google 助理应用。(图片来源: Google)

除了 Seeed Voice HAT 扩展板(图 6 中的 1)、麦克风板 (2) 和扬声器 (4) 之外,套件还包括纸板外壳 (8) 和内部框架 (9),以及一些基本组件,包括支座 (3)、电缆(6 和 7)和按钮 (5)。

开发人员首先将 RPi 3、扬声器电线、麦克风电缆连接到语音 HAT,然后组装套件。与 AVS 套件不同,Google 套件提供了一个简单的外壳和内部框架,用于固定电路板组件和扬声器(图 7)。
图 7: Seeed Google AIY 语音套件包括一个内部纸板框架,开发人员将其折叠成为电路板组件的载体。(图片来源: Seeed Technology)

框架安装在支撑按钮和麦克风阵列的外壳内,完成装配(图 8)。
图 8: 除了固定内部框架和扬声器之外,Seey Google AIY 语音套件的外壳还包括按钮和麦克风(看起来像外壳顶部的两个孔)。(图片来源: Seeed Technology)

下载语音套件镜像并将其载入 SD 卡中后,只需将 SD 卡插入 RPi 并打开电路板电源,即可调出套件。经过短暂的初始化过程以确认每个组件正常工作之后,开发人员需要激活 Google Cloud 端的服务。为此,请设置工作沙箱区域并启用 Google 助理 API,以创建和下载身份验证凭据。

最后,开发人员需要在 RPi 3 上打开一个终端控制台并执行 Python 脚本 assistant_library_demo.py,以便在套件上启动 Google 助理。此时,开发人员可以毫不费力地使用完整的 Google 助理功能。

定制 Google 助理器件

使用 Seeed Google AIY 语音套件进行自定义开发,可以充分利用 Raspberry Pi 的灵活性。Seeed Voice HAT 引出了多个已经为典型 IO 功能配置的 RPi 3 GPIO(图 9)。
图 9: 开发人员可以使用 Seeed Voice HAT 扩展板上引出的 I/O 端口,快速扩展 Seeed Google AIY 语音套件的硬件功能。(图片来源: Raspberry Pi)

在软件方面,开发人员可以使用 Google 的语音套件 API 软件,轻松扩展套件的基准功能。除了支持软件和实用程序之外,该软件包还包含样例应用程序软件,演示了通过 Google Cloud Speech API 和 Google Assistant SDK 实施语音服务的多种方法。

云语音服务与智能助理方法截然不同,它提供了语音识别功能,将实现特定语音启动操作的任务留给了程序员。对于只需要语音输入功能的设计,该服务提供了一个简单的解决方案。开发人员只需将音频传递到云语音服务,即可将语音转换为文本,并返回识别的文本,如语音套件 API 中包含的样例 Python 脚本所示(列表 2)。
  1. . . .
  2. import aiy.audio
  3. import aiy.cloudspeech
  4. import aiy.voicehat
  5. def main():
  6.     recognizer = aiy.cloudspeech.get_recognizer()
  7.     recognizer.expect_phrase('turn off the light')
  8.     recognizer.expect_phrase('turn on the light')
  9.     recognizer.expect_phrase('blink')
  10.     button = aiy.voicehat.get_button()
  11.     led = aiy.voicehat.get_led()
  12.     aiy.audio.get_recorder().start()
  13.     while True:
  14.         print('Press the button and speak')
  15.         button.wait_for_press()
  16.         print('Listening...')
  17.         text = recognizer.recognize()
  18.         if not text:
  19.             print('Sorry, I did not hear you.')
  20.         else:
  21.             print('You said "', text, '"')
  22.             if 'turn on the light' in text:
  23.                 led.set_state(aiy.voicehat.LED.ON)
  24.             elif 'turn off the light' in text:
  25.                 led.set_state(aiy.voicehat.LED.OFF)
  26.             elif 'blink' in text:
  27.                 led.set_state(aiy.voicehat.LED.BLINK)
  28.             elif 'goodbye' in text:
  29.                 break
  30. if __name__ == '__main__':
  31.     main()
列表 2: 在 Google 语音套件 API 提供的软件例程中,样例程序的这个片段演示了如何使用 Google Cloud Speech 服务,将语音转换为文本,并将实现任何语音指导操作的任务留给了程序员。(列表来源: Google)

对于需要 Google 助理的更广泛功能的开发人员,Google Assistant SDK 提供了两个实施选项: Google Assistant Library 和 Google Assistant Service。

基于 Python 的 Google Assistant Library 提供了一种在原型中快速实施 Google Assistant 的入门方法,例如在 Seeed 语音套件中。使用这种方法,原型可以即时利用基本的 Google 助理服务,包括音频捕获、对话管理和定时器。

与 Cloud Speech 方法相反,Google Assistant Library 通过将每个对话处理为一系列与对话和发声状态相关的事件来管理对话。语音识别完成后,实例化的助理对象将提供事件对象,其中包括了适当的处理结果。如另一个 Google 样例脚本所示,开发人员使用特征事件处理设计模式和一系列的 if/else 语句来处理预期的事件结果(列表 3)。
  1. . . .
  2. import aiy.assistant.auth_helpers
  3. import aiy.audio
  4. import aiy.voicehat
  5. from google.assistant.library import Assistant
  6. from google.assistant.library.event import EventType
  7. def power_off_pi():
  8.     aiy.audio.say('Good bye!')
  9.     subprocess.call('sudo shutdown now', shell=True)
  10. def reboot_pi():
  11.     aiy.audio.say('See you in a bit!')
  12.     subprocess.call('sudo reboot', shell=True)
  13. def say_ip():
  14.     ip_address = subprocess.check_output("hostname -I | cut -d' ' -f1", shell=True)
  15.     aiy.audio.say('My IP address is %s' % ip_address.decode('utf-8'))
  16. def process_event(assistant, event):
  17.     status_ui = aiy.voicehat.get_status_ui()
  18.     if event.type == EventType.ON_START_FINISHED:
  19.         status_ui.status('ready')
  20.         if sys.stdout.isatty():
  21.             print('Say "OK, Google" then speak, or press Ctrl+C to quit...')
  22.     elif event.type == EventType.ON_CONVERSATION_TURN_STARTED:
  23.         status_ui.status('listening')
  24.     elif event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED and event.args:
  25.         print('You said:', event.args['text'])
  26.         text = event.args['text'].lower()
  27.         if text == 'power off':
  28.             assistant.stop_conversation()
  29.             power_off_pi()
  30.         elif text == 'reboot':
  31.             assistant.stop_conversation()
  32.             reboot_pi()
  33.         elif text == 'ip address':
  34.             assistant.stop_conversation()
  35.             say_ip()
  36.     elif event.type == EventType.ON_END_OF_UTTERANCE:
  37.         status_ui.status('thinking')
  38.     elif event.type == EventType.ON_CONVERSATION_TURN_FINISHED:
  39.         status_ui.status('ready')
  40. def main():
  41.     credentials = aiy.assistant.auth_helpers.get_assistant_credentials()
  42.     with Assistant(credentials) as assistant:
  43.         for event in assistant.start():
  44.             process_event(assistant, event)
  45. if __name__ == '__main__':
  46.     main()
列表 3: 如 Google Voice 套件中的样例所示,使用 Google Assistant Library 的应用程序中的主循环启动一个助理对象,然后生成一系列事件,由开发人员的代码处理。(图片来源: Google)

对于要求更高的定制需求,开发人员可以转向使用 Google Assistant Service(以前称为 Google Assistant gRPC API)提供的全套接口。Google Assistant Service 基于 Google RPC(gRPC),让开发人员能够将音频查询传送到云端,处理识别的语音文本,并且处理相应的响应。为了实现定制功能,开发人员可以使用各种编程语言(包括 C++、Node.js 和 Java)来访问 Google Assistant Service API。

在将 Google Assistant SDK 用于自己的设计时,设计人员可以使用 Google 的器件匹配功能,实现特定于硬件的功能。作为器件设置的一部分,开发人员提供关于定制器件的信息,包括功能和特性,称为特质。对于涉及到定制器件的用户语音请求,服务会识别器件的有效特质,并为器件生成适当的响应(图 10)。开发人员只需在器件的事件处理程序中包括与器件特质相关的对应代码(例如列表 3 中的 def power_off_pi())。
图 10: Google Assistant SDK 使用自动语音识别 (ASR) 和自然语言处理 (NLP) 服务,将用户请求与特定设备进行匹配,并发出与定制设备及其认可特质一致的响应。(图片来源: Google)

总结

过去,智能语音助理在很大程度上是主流开发人员无法实现的。随着两个现成套件的推出,开发人员可以在定制设计中快速实施 Amazon Alexa 和 Google 助理。每个套件都允许开发人员在基本原型中快速调用相应的智能助理,或者使用定制的硬件和软件来扩展设计。