风的故乡 發表於 2024-1-29 00:00:00

使用 Ansible 在树莓派上部署 Mycroft AI 语音助手

<p>
        <img title="使用 Ansible 在树莓派上部署 Mycroft AI 语音助手" alt="使用 Ansible 在树莓派上部署 Mycroft AI 语音助手" border="0" height="auto" src="https://zhuji.jb51.net/uploads/img/202305/9ffe9d87b511ef792a73dcb2b6e14a3b.jpg" width="auto"></p>
<p>
        使用本文中的这些 Ansible 剧本可以帮你获得更优的 Mycroft AI 体验。</p>
<p>
        Mycroft AI 是一款虚拟助手应用程序,可以响应语音请求并完成相应的任务,比如在互联网上搜索你需要的某些信息,或者下载你喜欢的博客等等。这是一款优秀的开源软件,不同于那些收集个人数据业务的公司的同款软件,Mycroft AI 注重于保护隐私以及提供平台灵活性。</p>
<p>
        Mycroft AI 使用 python 开发,可以安装于不同的硬件平台上。家喻户晓的树莓派便是一个非常热门的运行语音助手的硬件方案(不过不是唯一的方案)。方便的是,Mycroft 为树莓派提供了 Picroft 镜像,虽然目前 Picroft 还有一些限制,比如不支持 64 位系统,不过不能阻止它成为一种优秀的解决方案。</p>
<h3 class="mume-header" id="%E6%A0%91%E8%8E%93%E6%B4%BE-4%E6%88%91%E9%80%89%E6%8B%A9%E7%9A%84%E7%9B%AE%E6%A0%87%E5%B9%B3%E5%8F%B0">
        树莓派 4,我选择的目标平台</h3>
<p>
        树莓派在 Mycroft 社区中非常受欢迎,因为其性价比高,在教育行业中有着巨大的优势,并且由于 Mycroft 提供的便捷功能以及树莓派本身易于访问的输入/输出(GPIO)引脚等,为树莓派提供了有趣的扩展可能(比如,提供 唤醒词 LED GPIO 能力)。</p>
<p>
        树莓派 4B 具有足够的 CPU 算力以及内存来平稳运行 Mycroft。我使用的是 8G 内存的树莓派4B,运行 Raspberry Pi OS Bullseye 64-bit 系统,你可以从 RaspberryPi.org 网站下载该系统镜像文件。</p>
<h3 class="mume-header" id="%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%99%E4%BB%B6%E4%BA%8B">
        自动化这件事</h3>
<p>
        构建你自己的 Mycroft AI 系统,必须要注意一些细节问题。根据我(一年以来)的初步经验,以下罗列了一些重要的技术细节点:</p>
<ul>
<li>
                音频输出(扬声器配置)</li>
        <li>
                音频输入(麦克风配置)</li>
        <li>
                麦克风质量(以购买的实际硬件为准)</li>
        <li>
                唤醒词响应(比如打招呼 “嘿,Mycroft”)</li>
        <li>
                响应延迟(比如提问 “天气怎么样”)</li>
</ul>
<p>
        这些并不是 Mycroft AI 的问题(LCTT 译注:难道软件平台就没有处理延时问题?),它们只能是你在选择硬件和配置操作时必须牢记关心的事情。树莓派本身能够运行 Mycroft AI,但有一些配置需要额外的注意下:</p>
<ul>
<li>
                CPU 调度器</li>
        <li>
                SD 卡性能</li>
        <li>
                PulseAudio 配置</li>
        <li>
                网络延迟</li>
</ul>
<p>
        我做了大量的研究和实践来解决上面列出这些令人头疼的注意点,最终我实现了我的“终极”目标 —— 最流畅的体验!</p>
<h3 class="mume-header" id="ansible-%E9%9B%AA%E4%B8%AD%E9%80%81%E7%82%AD">
        Ansible 雪中送炭</h3>
<p>
        我已经摸索出了最流畅的体验配置,但是如何确保在任何树莓派 4 板子上都能不遗漏每一个设置细节,然后达到重新部署这种流畅性体验的目标呢?</p>
<p>
        Ansible 能帮助你实现。Ansible 在设计上是幂等设计,这意味着它仅在需要时响应更改的请求。如果一切配置正确,Ansible 不会改变任何事情。这便是幂等设计的优美之处。</p>
<p>
        为了达到这一目的,我使用了两种 Ansible 场景角色工具:</p>
<ul>
<li>
                一个用于配置和调整树莓派</li>
        <li>
                一个用于安装和配置 Mycroft AI</li>
</ul>
<h3 class="mume-header" id="ansible-prepi-%E8%A7%92%E8%89%B2">
        Ansible prepi 角色</h3>
<p>
        Ansible prepi role 应用了一些配置,以便让树莓派 4B 发挥更佳的性能以及为安装 Mycroft 做前提准备。</p>
<ul>
<li>
                更新 Raspberry Pi OS 至最新版本</li>
        <li>
                添加 Debian backports 仓库</li>
        <li>
                使用 next 分支更新固件,该分支支持 5.15 版本内核以及边缘固件</li>
        <li>
                使用测试版本更新 EEPROM,该版本支持边缘功能</li>
        <li>
                设置 <code>initial_turbo</code> 用来加速启动过程</li>
        <li>
                将树莓派超频至 2GHz</li>
        <li>
                在 RAMDisck 上挂载 <code>/tmp</code>
</li>
        <li>
                优化 <code>/</code> 分区挂载选项,提升 SD 卡读/写性能</li>
        <li>
                管理 I2C、SPI、UART 接口</li>
        <li>
                设置 CPU 控制器至避免在空间内核函数之间发生上下文切换的模式,以便提升性能</li>
        <li>
                安装和配置 PulseAduio(非系统范围)</li>
        <li>
                新固件或者 EEPROM 安装后重启树莓派</li>
</ul>
<h3 class="mume-header" id="ansible-mycroft-%E8%A7%92%E8%89%B2">
        Ansible mycroft 角色</h3>
<p>
        Ansible mycroft role 基于脚本 <code>dev_setup.sh</code> 从 Github 仓库获取并安装和配置 Mycroft AI,该脚本是 Mycroft 核心团队提供。</p>
<ul>
<li>
                需要准备 Python3 环境</li>
        <li>
                系统集成环境</li>
        <li>
                额外的安装技能</li>
        <li>
                安装 Boto3、py_mplayer、pyopenssl 库</li>
        <li>
                支持 IPC 的 RAMDisck</li>
        <li>
                支持文件配置</li>
        <li>
                PulseAudio 优化</li>
        <li>
                安全的 Mycroft 消息总线 websocket</li>
</ul>
<p>
        我利用 Ansible 剧本 来协调上面两个角色的使用。</p>
<h3 class="mume-header" id="%E4%B8%AA%E4%BA%BA%E9%85%8D%E7%BD%AE%E9%9C%80%E6%B1%82">
        个人配置需求</h3>
<p>
        下面列举了一些个人配置的需求:</p>
<ul>
<li>
                能上网的树莓派 4B 板子(或者更新的板子)</li>
        <li>
                Raspberry Pi OS 64-bit</li>
        <li>
                Ansible 2.9(或者更新版本)</li>
        <li>
                可正常工作的 SSH</li>
</ul>
<p>
        推荐使用 Etcher 来烧录 Raspberry Pi OS 镜像至 SD 卡,你也可以使用你选择的镜像烧录工具。</p>
<p>
        我将树莓派超频来提升性能,不过这可能对你的硬件是一种潜在危险。在使用我的 Ansible 剧本配置之前,请先仔细阅读。你需要为你的每个配置选择负责。你将决定使用哪个固件、哪个 EEPROM。超频的话需要记得提供相应的冷却系统。</p>
<h3 class="mume-header" id="%E6%89%A7%E8%A1%8C-ansible-%E5%89%A7%E6%9C%AC">
        执行 Ansible 剧本</h3>
<p>
        第一步,使用命令从 Github 获取 Ansible 剧本:</p>
<pre class="prettyprint linenums prettyprinted">
</pre>
<ol class="linenums">
<li class="L0">
                <code><span class="pln">$ </span><span class="kwd">git</span><span class="pln"> </span><span class="kwd">clone</span><span class="pln"> https</span><span class="pun">:</span><span class="com">//github.com/smartgic/ansible-playbooks-mycroft.git</span></code>
</li>
</ol>
<p>
        源码中,<code>requirements.yml</code> 文件中提供了该剧本的依赖角色列表,必须从 Ansible Galaxy 中检索这些依赖。</p>
<pre class="prettyprint linenums prettyprinted">
</pre>
<ol class="linenums">
<li class="L0">
                <code><span class="pln">$ </span><span class="kwd">cd</span><span class="pln"> ansible</span><span class="pun">-</span><span class="pln">playbooks</span><span class="pun">-</span><span class="pln">mycroft</span></code>
</li>
        <li class="L1">
                <code><span class="pln">$ ansible</span><span class="pun">-</span><span class="pln">galaxy install </span><span class="pun">-</span><span class="pln">r requirements</span><span class="pun">.</span><span class="pln">yml</span></code>
</li>
        <li class="L2">
                <code><span class="typ">Starting</span><span class="pln"> galaxy role install process</span></code>
</li>
        <li class="L3">
                <code><span class="pun">-</span><span class="pln"> downloading role </span><span class="str">'mycroft'</span><span class="pun">,</span><span class="pln"> owned by smartgic</span></code>
</li>
        <li class="L4">
                <code><span class="pun">-</span><span class="pln"> downloading role </span><span class="kwd">from</span><span class="pln"> https</span><span class="pun">:</span><span class="com">//github.com/smartgic/ansible-role-mycroft/archive/main.tar.gz</span></code>
</li>
        <li class="L5">
                <code><span class="pun">-</span><span class="pln"> extracting smartgic</span><span class="pun">.</span><span class="pln">mycroft to </span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">goldyfruit</span><span class="pun">/.</span><span class="pln">ansible</span><span class="pun">/</span><span class="pln">roles</span><span class="pun">/</span><span class="pln">smartgic</span><span class="pun">.</span><span class="pln">mycroft</span></code>
</li>
        <li class="L6">
                <code><span class="pun">-</span><span class="pln"> smartgic</span><span class="pun">.</span><span class="pln">mycroft </span><span class="pun">(</span><span class="pln">main</span><span class="pun">)</span><span class="pln"> was installed successfully</span></code>
</li>
        <li class="L7">
                <code><span class="pun">-</span><span class="pln"> downloading role </span><span class="str">'prepi'</span><span class="pun">,</span><span class="pln"> owned by smartgic</span></code>
</li>
        <li class="L8">
                <code><span class="pun">-</span><span class="pln"> downloading role </span><span class="kwd">from</span><span class="pln"> https</span><span class="pun">:</span><span class="com">//github.com/smartgic/ansible-role-prepi/archive/main.tar.gz</span></code>
</li>
        <li class="L9">
                <code><span class="pun">-</span><span class="pln"> extracting smartgic</span><span class="pun">.</span><span class="pln">prepi to </span><span class="pun">/</span><span class="pln">home</span><span class="pun">/</span><span class="pln">goldyfruit</span><span class="pun">/.</span><span class="pln">ansible</span><span class="pun">/</span><span class="pln">roles</span><span class="pun">/</span><span class="pln">smartgic</span><span class="pun">.</span><span class="pln">prepi</span></code>
</li>
        <li class="L0">
                <code><span class="pun">-</span><span class="pln"> smartgic</span><span class="pun">.</span><span class="pln">prepi </span><span class="pun">(</span><span class="pln">main</span><span class="pun">)</span><span class="pln"> was installed successfully</span></code>
</li>
</ol>
<p>
        第二步,编辑仓库中的 Ansible 清单,设置需要管理的主机。</p>
<pre class="prettyprint linenums prettyprinted">
</pre>
<ol class="linenums">
<li class="L0">
                <code><span class="pun">[</span><span class="pln">rpi</span><span class="pun">]</span></code>
</li>
        <li class="L1">
                <code><span class="pln">rpi4b01 ansible_host</span><span class="pun">=</span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">1.97</span><span class="pln"> ansible_user</span><span class="pun">=</span><span class="pln">pi</span></code>
</li>
</ol>
<p>
        <code></code> 代表组,无需更改。该组有一个主机 <code>rpi4b01</code>,其 IP 地址为 <code>192.168.1.97</code>, 并创建 <code>pi</code> 作为 Linux(Raspberry Pi OS)上的默认用户。</p>
<p>
        现在比较棘手的部分到了:你希望每个选项怎么配置?这取决于你自己,下面是我的首选配置,供你参考:</p>
<pre class="prettyprint linenums prettyprinted">
</pre>
<ol class="linenums">
<li class="L0">
                <code><span class="com">#</span><span class="pln"> </span><span class="kwd">file</span><span class="pun">:</span><span class="pln"> install</span><span class="pun">-</span><span class="pln">custom</span><span class="pun">.</span><span class="pln">yml</span></code>
</li>
        <li class="L1">
                <code><span class="pun">-</span><span class="pln"> hosts</span><span class="pun">:</span><span class="pln"> rpi</span></code>
</li>
        <li class="L2">
                <code><span class="pln">gather_facts</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">yes</span></code>
</li>
        <li class="L3">
                <code><span class="pln">become</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">yes</span></code>
</li>
        <li class="L4">
                 </li>
        <li class="L5">
                <code><span class="pln">pre_tasks</span><span class="pun">:</span></code>
</li>
        <li class="L6">
                <code><span class="pun">-</span><span class="pln"> name</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Install</span><span class="pln"> </span><span class="typ">Python</span><span class="pln"> </span><span class="lit">3.x</span><span class="pln"> </span><span class="typ">Ansible</span><span class="pln"> requirement</span></code>
</li>
        <li class="L7">
                <code><span class="pln">raw</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">apt-get</span><span class="pln"> install </span><span class="pun">-</span><span class="pln">y python3</span></code>
</li>
        <li class="L8">
                <code><span class="pln">changed_when</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">no</span></code>
</li>
        <li class="L9">
                <code><span class="pln">tags</span><span class="pun">:</span></code>
</li>
        <li class="L0">
                <code><span class="pun">-</span><span class="pln"> always</span></code>
</li>
        <li class="L1">
                 </li>
        <li class="L2">
                <code><span class="pln">vars</span><span class="pun">:</span></code>
</li>
        <li class="L3">
                <code><span class="com">#</span><span class="pln"> PREPI</span></code>
</li>
        <li class="L4">
                <code><span class="pln">prepi_pi_user</span><span class="pun">:</span><span class="pln"> pi</span></code>
</li>
        <li class="L5">
                <code><span class="pln">prepi_hostname</span><span class="pun">:</span><span class="pln"> mylovelypi</span></code>
</li>
        <li class="L6">
                <code><span class="pln">prepi_firmware_update</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">yes</span></code>
</li>
        <li class="L7">
                <code><span class="pln">prepi_overclock</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">yes</span></code>
</li>
        <li class="L8">
                <code><span class="pln">prepi_force_turbo</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">yes</span></code>
</li>
        <li class="L9">
                <code><span class="pln">prepi_cpu_freq</span><span class="pun">:</span><span class="pln"> </span><span class="lit">2000</span></code>
</li>
        <li class="L0">
                <code><span class="pln">prepi_pulseaudio_daemon</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">yes</span></code>
</li>
        <li class="L1">
                 </li>
        <li class="L2">
                <code><span class="com">#</span><span class="pln"> MYCROFT</span></code>
</li>
        <li class="L3">
                <code><span class="pln">mycroft_branch</span><span class="pun">:</span><span class="pln"> dev</span></code>
</li>
        <li class="L4">
                <code><span class="pln">mycroft_user</span><span class="pun">:</span><span class="pln"> </span><span class="str">"{{ prepi_pi_user }}"</span></code>
</li>
        <li class="L5">
                <code><span class="pln">mycroft_skills_update_interval</span><span class="pun">:</span><span class="pln"> </span><span class="lit">2.0</span></code>
</li>
        <li class="L6">
                <code><span class="pln">mycroft_recording_timeout_with_silence</span><span class="pun">:</span><span class="pln"> </span><span class="lit">3.0</span></code>
</li>
        <li class="L7">
                <code><span class="pln">mycroft_enclosure_name</span><span class="pun">:</span><span class="pln"> picroft</span></code>
</li>
        <li class="L8">
                <code><span class="pln">mycroft_extra_skills</span><span class="pun">:</span></code>
</li>
        <li class="L9">
                <code><span class="pun">-</span><span class="pln"> https</span><span class="pun">:</span><span class="com">//github.com/smartgic/mycroft-finished-booting-skill.git</span></code>
</li>
        <li class="L0">
                 </li>
        <li class="L1">
                <code><span class="pln">tasks</span><span class="pun">:</span></code>
</li>
        <li class="L2">
                <code><span class="pun">-</span><span class="pln"> import_role</span><span class="pun">:</span></code>
</li>
        <li class="L3">
                <code><span class="pln">name</span><span class="pun">:</span><span class="pln"> smartgic</span><span class="pun">.</span><span class="pln">prepi</span></code>
</li>
        <li class="L4">
                 </li>
        <li class="L5">
                <code><span class="pun">-</span><span class="pln"> import_role</span><span class="pun">:</span></code>
</li>
        <li class="L6">
                <code><span class="pln">name</span><span class="pun">:</span><span class="pln"> smartgic</span><span class="pun">.</span><span class="pln">mycroft</span></code>
</li>
</ol>
<p>
        上面的配置内容需要保存在文件里(比如,<code>install-custom.yml</code>)。</p>
<p>
        现在关键步骤:运行你新创建的剧本。</p>
<pre class="prettyprint linenums prettyprinted">
</pre>
<ol class="linenums">
<li class="L0">
                <code><span class="pln">$ ansible</span><span class="pun">-</span><span class="pln">playbook </span><span class="pun">-</span><span class="pln">i inventory install</span><span class="pun">-</span><span class="pln">custom</span><span class="pun">.</span><span class="pln">yml </span><span class="pun">-</span><span class="pln">k</span></code>
</li>
</ol>
<p>
        <code>-k</code> 选项只有在不需要 SSH 密钥的时候才使用。在命令执行期间,树莓派可能会重启若干次。Ansible 剧本会自动处理这个问题,不必担心。</p>
<p>
        Ansible 配置完成后,你可以看到一条祝贺消息,提示你下一步需要做什么。</p>
<p>
        <img title="使用 Ansible 在树莓派上部署 Mycroft AI 语音助手" alt="使用 Ansible 在树莓派上部署 Mycroft AI 语音助手" border="0" height="auto" src="https://zhuji.jb51.net/uploads/img/202305/6cade04b3b0cd8870652f5ca96158bb7.jpg" width="auto"></p>
<p class="article_img_desc">
        <em>Congratulations message (Gaëtan Trellu, CC BY-SA 4.0)</em></p>
<h3 class="mume-header" id="ansible-%E8%AE%A9%E5%AE%9A%E5%88%B6-mycroft-%E5%8F%98%E5%BE%97%E6%9B%B4%E5%AE%B9%E6%98%93">
        Ansible 让定制 Mycroft 变得更容易</h3>
<p>
        这些 Ansible 剧本是我开始使用 Mycroft AI 后学到的经验教训。它们帮助我在任何一个地方都能构建、重构、定制、拷贝我的安装,并保持一致,这让我很省心!</p>
<p>
        读完此文,你有何意见、问题或疑虑?欢迎在 Twitter上 @goldyfruit上和我交流,或者访问 Mycroft 频道 搜寻答案。</p>
<p>
        原文链接:https://linux.cn/article-14102-1.html</p>
頁: [1]
查看完整版本: 使用 Ansible 在树莓派上部署 Mycroft AI 语音助手