跳到正文
Hugging Face Blog·· 2 小时前精选AI 评分61

用 NVIDIA Nemotron 开源模型搭建万圣节会说话的鬼屋

nemotron-halloween

AI 导读

NVIDIA 员工用 Nemotron Voice Agent 串联 Nemotron Speech ASR、Nemotron 3.5 Bolt E4B 4GB、Magpie TTS Zeroshot 和 Audio2Face-3D,在单台工作站上做出会抱怨、听到 please 就心软的万圣节互动投影 MonsterHouse。

推荐理由

作者完整拆解了用 Nemotron 语音智能体搭建万圣节互动装置的全链路,含延迟数字与双 GPU 分工,可迁移到本地实时语音角色项目。

正文 · AI 翻译

使用 NVIDIA Nemotron 开放模型打造鬼屋

更确切地说……

嘘!现在从我的草坪上滚开!

BlogThumbnail

TL;DR:MonsterHouse 是我为万圣节打造的互动投影。他会倾听“不给糖就捣蛋”的孩子们,用一艘脾气暴躁的老海盗船的声音回应,并在访客记得礼貌时变得温和。他基于 NVIDIA Nemotron Voice Agent 构建,搭配 NVIDIA Nemotron ASR、Nemotron 3.5 Bolt E4B 4GB、Magpie TTS Zeroshot 和 Audio2Face-3D,并且运行在一台工作站上。

我希望万圣节来我家拜访的孩子们能以有趣而独特的方式互动。这栋房子将负责掌控局面并分发糖果,但更多是脾气暴躁而非恐怖吓人。不知怎的,我的解决方案是给车库门装上一张嘴,并教它抱怨。

这就成了 MonsterHouse:一栋脾气暴躁的老建筑,有着海盗故事、炽烈的咧嘴笑,以及对“请”字有着可疑的软肋。NVIDIA Nemotron Voice Agent 提供对话基础。Nemotron Speech 负责聆听,Bolt E4B 是大脑,NVIDIA Magpie TTS Zeroshot 是实时语音,NVIDIA Audio2Face-3D 让木嘴开口说话。

Monster House 如何运作

满是木屑的咧嘴笑

嘴是最先做的。我想象着木质车库门板裂成参差不齐的嘴唇,每当他张开那被诅咒的嘴时,地狱的燃烧火焰便从门后照亮车道。他需要看起来古老、富有表现力,并且对访客的存在略带不满。

fireMouth一栋有很多话要说的房子的几种表情。

创建自定义动画绑定是构建过程中较为费力的部分之一。在把它折腾到服帖之后,我就可以导出 Audio2Face-3D 之后能够制作动画的面部表情形状。角色 SkelMesh 在 Autodesk Maya 中构建,然后导出到 Unreal Engine,并在门后添加了虚拟火焰和特效。没有眼睛、没有眉毛、也不眨眼,他竟是个出奇省事的怪物。

在构建角色的种种琐事进行的同时,NVIDIA 构建了 Nemotron Voice Agent。原本应该是构建中最困难的部分,现在变得相当有趣、可迭代且简单。我开箱即得一个用于聆听、对话和语音的基础。这栋房子已经有了一张嘴。现在他终于能找到可以抱怨的事情了。

教它没礼貌

这栋房子需要一个和它脾气一样暴躁的过去,所以我编了一段背景故事:这栋房子是用一艘沉没海盗船的木材建成的,被它暴风雨般的过往所萦绕。那些 nautical 抱怨现在有了理由。这就是那艘船,转世成了房地产,而且对此并不完全满意。

这场表演需要一个向导,一条从问候到告别的路径,沿途还要提供小惊喜。首先,房子会用“我正忙着抱怨呢,去烦邻居吧!”这样的话把访客打发走。但坚持会让他软化。一句“请”可能立刻突破防线,而“谢谢”则能换来温暖的告别。一旦访客赢得了他,我希望他能一直保持被赢得的状态。没人想跟同一扇车库门谈判两次。

这正是 Voice Agent 真正出彩的地方。你可以选择任何你喜欢的 LLM。因为我希望系统离线且完全自包含,所以我有内存和计算预算。

这个角色需要的不仅仅是一句“脾气暴躁”的提示词。它必须遵循主对话流程,回应访客实际说的话,跟踪遭遇状态,并为流水线的其余部分留出足够的计算资源。

在测试了十多个模型后,我选择了 Bolt E4B 来提供实时对话。它是一个开源小语言模型,专为本地对话代理和交互角色打造,这用来形容一扇会说话的车库门倒也贴切。我使用 4 位量化版本(名字里的“4GB”)作为默认响应模型,同时提供 BF16 检查点用于对比。

如果到现在还不明显的话,我在 NVIDIA 工作,因此我能在 Bolt E4B 公开发布前进行测试,并发现它是一个可靠的选择,比其他领先者——Qwen3 30B-A3B 和 Qwen 3.6 35B-A3B——占用更小。

它在 Nemotron Voice Agent 流水线中运行,把访客说的话变成下一个恰如其分的不情愿回复。

Bolt 提供了对话基础。我的提示词、应用逻辑以及在数千条经过审核的示例对话上训练的 LoRA 适配器,将它塑造成这艘特定的固执之船。

创建一个包含 5000 多轮多轮对话的数据集,意味着我可以为我感觉足够好、可以作为选项的每个模型训练 LoRA。有些训练了大约一个小时,有些花了几个小时。一个本地代理运行一切并对结果进行基准测试。那个代理和一个非常大的 LLM 最初创建并评判了数据集。这发生在夜间或我做日常工作的时候。

有了 LoRA,我会检查回复的连贯性、时机和语气,对模型和适配器进行质量、重复和速度的基准测试,然后聆听表演。房子最终应该让步,但不会变成一个欢快的礼宾员。一点抵抗是魅力的一部分。和一扇车库门无休止地争论则不是。

值得等待的声音

image两条捷径,两种输出。预写文本跳过实时对话生成,保存的音频跳过语音合成。清晰的语音驱动动画,与观众效果分开处理。

如果鬼屋抱怨得太久,就会失去威信。流水线在完整答案尚未生成之前就发布可朗读的文本,因此鬼屋可以在句子剩余部分还在传输时就开始说话。预先准备的问候语和糖果笑话覆盖了熟悉的互动场景:文本库节省了语言模型的工作量,缓存的录音则节省了语音合成。即使是古老的脾气暴躁者也能从排练中受益。

median end-of-speech-to-audio with Bolt Q4 & TTS = 1.70 seconds
median end-of-speech-to-audio cached responses = 0.72 seconds
(note: speech-end detection currently waits for 300 ms of silence )

NVIDIA Magpie TTS Zeroshot 将文本转换为女王英语。其零样本语音条件使用短参考样本而非训练过的声音;我的样本提供了脾气暴躁的海盗角色。鬼屋有七种情绪,从暴躁、威胁到愉悦、欣喜,由提示模板指定并由 LLM 提供的情绪标签决定每句话的表达方式。由于每种情绪需要不同的 3-10 秒语音样本,我在 UI 的工具选项卡上添加了一个“Sample your Voice”模块。然后我可以用我最拿手的快乐海盗或愤怒海盗声音朗读并录制一行样本文本。到了“开始”的时候,Bolt E4B 决定说什么,Magpie 则将文本转换为带有适当愉悦或绝望的语音。

流水线的下一个环节是 Audio2Face-3D 以及我在 Epic 的 Unreal Engine 中创建的 3D 角色场景。默认模型权重最适合干净、中性的男声或女声,不要太低沉,也不要太高亢(根据你的用例选择适当性别的模型)。我希望鬼屋拥有非常低沉、带有回声和腔调的恶魔般声音。在这种情况下,由于我的语音样本没有那种戏剧性的厚重感,这实际上是一个优势。Audio2Face-3D 从样本中获得干净的语音,第二个音频流添加可调节的实时人声效果,通过扬声器播放出来。

为了保持一切平稳运行,我将工作分配到两块 GPU 上:语言和语音模型流水线运行在 NVIDIA RTX PRO 6000 Blackwell Max-Q 上,Unreal Engine 图形和 Audio2Face-3D 运行在 NVIDIA RTX PRO 4000 Blackwell 上。内存不是问题,计算才是。我希望无论代理流水线在进行什么处理,动画都能保持一致的帧率。

语音、动画和效果必须同步到位。一个有说服力的怪物需要的不仅仅是快速回答;它需要听起来像是这栋建筑在抱怨。在我的情况下,确实如此。同步音频输出的调整是可用的。我发现我可以设置一次后就无需再管。(100ms 补偿 Audio2Face-3D 的缓冲)

怪物有一个控制台

在这一过程中,“让鬼屋说话”需要一个充满控件的界面。我可以试听缓存的台词、调整开场情绪、跟踪对话、更改语音处理和调整嘴部动画。选项卡涵盖对话、模型选择、录音、提示、性能监控和摄像头画面,音板(soundboard)和自定义对话字段让我可以把话塞进他嘴里。还有模型加载控件和 Unreal Engine 连接指示器,因为有时候怪物不是在生闷气。他是断开了连接。

imageMonsterHouse 控制台,带有音板、自定义台词、开场情绪和对话流程。

火焰和辉光也加入了表演。可编辑规则将视觉提示与表达绑定:实时提示随语音开始,而录制的表演可以遵循保存的时间线。我可以直接改变情绪,而无需重建场景。

实时模式运行“不给糖就捣蛋”角色。演示模式说服房子解释自己。麦克风模式让我直接通过房子说话,绕过识别、对话生成和语音合成。我干净的声音驱动嘴巴;观众听到的是处理后的版本。房子认为这是附身。我认为这是一个有用的后备方案。

下一次敲门

NVIDIA Nemotron 3 Nano Omni 是一个 VLM,为房子提供视觉上下文。作为一个可选的观察者,它解读摄像头图像并描述可见的服装,这样角色就有具体的东西可以回应。不想重新发明每一个轮子,我选择了流行的目标检测和跟踪模型 YOLO 和 ByteTrack 来计数和跟踪当前视野中的人。将这些任务分开可以让房子注意到一群人,而不需要让 Omni 叙述每一帧。

为了一个足够荒谬的测试,我给 Omni 一段五只穿着服装的羊在门口的视频。它保存的分析识别出了海盗、吸血鬼、女巫、南瓜和幽灵服装。这就是我希望房子使用的视觉上下文。显然,连牲畜的万圣节计划都比我更精心。

image合成测试回放中五只毛茸茸的“不给糖就捣蛋”者。服装标签来自保存的 Omni 分析;框和跟踪 ID 仅作示意。

这些羊是合成测试,不是成功万圣节之夜的证据。真实的车道人群、服装和夜间照明仍需测试。检测确实会触发自动问候,但我担心时髦的服装识别和恰到好处的机智回应可能需要一些后训练。由于房子没有眼睛,他称自己的访客感知为回声定位。我就让他这么说了。

还有更多事情要做:动画总是可以改进,完整的性能测试需要真实访客,糖果终有一天会自动提供。我还没有达到最初的目标,即让他运行万圣节,而我和家人一起去看附近的其他鬼怪。但这仍然是这一切的意义所在。总有一天,一个孩子会遇到一座脾气暴躁的老房子,尝试一点善意,并发现老木头也有柔软的一面。而且会分发糖果棒。

构建你自己的不合理角色

MonsterHouse 代码本身没有打包发布,但它使用的每个 NVIDIA 模型今天都可以使用,而 NVIDIA Nemotron Voice Agent 能让你完成大部分工作。这是我会遵循的路径。

  1. 从语音管道开始。 克隆 NVIDIA Nemotron Voice Agent 并运行 Generic Assistant 示例。你会得到一个级联管道,包含 Nemotron Speech ASR、一个 LLM 和 Magpie TTS,以及语音活动检测和话语结束处理,这样你的角色就知道什么时候该说话。
  2. 让 Bolt E4B 成为大脑。 Voice Agent 包含用于云、服务器和单 GPU 部署的 Bolt E4B 配置文件。你可以先在 build.nvidia.com 上试用该模型。尝试对话模式以获得简短、适合语音的回复,并禁用推理以进行更简单的交流。
  3. 赋予它个性。 从系统提示和几段相连的示例对话开始。把对话状态(例如谁已经说过“请”)保存在你的应用里,而不是让模型去记住它。当提示不够用时,训练一个 LoRA 适配器;NVIDIA NeMo AutoModel 提供了适用于 Bolt E4B 的 LoRA 配方。
  4. 赋予它声音。 Magpie TTS Multilingual 是 Voice Agent 的默认选项。若要自定义角色,Magpie TTS Zeroshot 可基于一段简短的参考样本工作。在 build.nvidia.com 上试用,并申请访问权限以便自行运行。[CONFIRM: access path and link] 仅使用你已获得许可的声音。
  5. 赋予它面孔。 NVIDIA Audio2Face-3D 可将语音转换为角色的面部动画。向它输入干净的语音,之后再添加特效。
  6. 可选:赋予它眼睛。 Voice Agent 的 Nemotron Omni Assistant Subagents 示例通过 Nemotron 3 Nano Omni 增加了实时网络摄像头理解能力。如果你需要计数,可搭配一个轻量级的人员跟踪器。

为最常见台词准备缓存响应库和预存音频,能让即使反应慢的怪物也显得迅速。事实上,如果你恰好受限于算力,完全可以做一个仅使用 Nemotron Speech ASR、一个 Python 对话路由器和全部缓存音频的 Live 版本。你可以用 Bolt E4B 和 Magpie 流水线离线生成数百条响应,然后在演出时使用缓存。我会为互动南瓜这样做。

资源

来源:Hugging Face Blog · huggingface.co