NVIDIA 员工用 Nemotron 全家桶打造会说话的万圣节怪兽屋 MonsterHouse
nemotron-halloween
NVIDIA 员工为万圣节打造互动投影装置 MonsterHouse,由 Nemotron Speech ASR 负责听、Nemotron 3.5 Bolt E4B 4GB 负责对话。
用 NVIDIA Nemotron 开放模型打造鬼屋
或者应该说……
哇!都给我离开我的草坪!
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 的工作原理
- 倾听:NVIDIA Nemotron Speech ASR 将访客的语音转换为文本。[已确认:
nemotron-speech-streaming-en-0.6b.q8_0.gguf]- 思考:NVIDIA Nemotron 3.5 Bolt E4B 4GB 是一款面向对话智能体的开放小语言模型,负责撰写每一条回复。一个 LoRA 适配器提供个性。
- 说话:NVIDIA Magpie TTS Zeroshot 根据角色的简短参考样本为每条回复配音。
- 动画:NVIDIA Audio2Face-3D 将清晰的语音转换为 Unreal Engine 5 中的嘴部动画。
- 观看:NVIDIA Nemotron 3 Nano Omni 描述服装,同时 YOLO 和 ByteTrack 对访客进行计数和追踪。
- 运行:NVIDIA Nemotron Voice Agent 在一台配备 NVIDIA RTX PRO 6000 Blackwell Max-Q 和 NVIDIA RTX PRO 4000 Blackwell 的工作站上协调一切。
满是木刺的笑容
嘴巴最先完成。我设想车库门的木板裂开成锯齿状的嘴唇,每当他张开那张被诅咒的嘴时,地狱之火就会从门后照亮车道。他需要看起来古老、富有表现力,并且对访客的存在隐隐感到不悦。
创建自定义动画绑定是整个构建过程中比较费力的部分之一。在将它反复折腾屈服之后,我才能导出 Audio2Face-3D 之后可以用来制作动画的面部表情形状。角色 SkelMesh 在 Autodesk Maya 中构建,然后导出到 Unreal Engine,并在门后添加了虚拟火焰和特效。没有眼睛,没有眉毛,也不会眨眼,他是一个惊人地 economical 的怪物。
在我忙于构建角色这些琐碎事务的同时,NVIDIA 构建了 Nemotron Voice Agent。原本应该是构建中最难的部分,现在变得相当有趣、可迭代且轻松。我开箱即得了一个倾听、对话和语音的基础。房子已经有了嘴。现在他终于可以找到可以抱怨的东西了。
教坏了习惯
这座房子需要一个和它的性格一样古怪的过往,于是我编了一段背景故事:房子是用一艘沉没海盗船的木材建造的,被它动荡的过去所萦绕。那些航海式的抱怨如今有了解释。这就是那艘船,转世成了不动产,而且对此颇为不满。
这场表演需要一个引导,一条从问候到道别的路径,沿途还要不断给点甜头。首先,房子会用“我忙着发牢骚呢,去烦邻居吧!”这样的话把访客打发走。但坚持会慢慢磨软他的态度。一句“请”可以立刻打动他,一句“谢谢”则能换来热情的告别。一旦访客赢得了他的好感,我希望他能一直保持好感。没人想跟同一个车库门谈判两次。
这正是 Voice Agent 真正大放异彩的地方。你可以选择任何你喜欢的 LLM。因为我希望整个系统离网运行、完全自给自足,所以内存和算力预算都很有限。
这个角色需要的可不仅仅是一句“要暴躁”的提示词。它必须遵循一条主对话流程,回应访客实际说的话,跟踪每次会话的状态,还要给流水线的其余部分留出足够的算力。
在测试了十几个模型之后,我选中了 Bolt E4B 来提供实时对话。它是一个开源小语言模型,专为本地对话智能体和交互式角色打造——这用来形容一扇会说话的车库门也算贴切。我使用 4-bit 量化版本(名字里的“4GB”)作为默认响应模型,同时也提供 BF16 检查点 供对比。
如果到现在还不明显的话,我在 NVIDIA 工作,因此在 Bolt E4B 公开发布之前我就能够测试它,发现它是一个可靠的选择,比其他领先者 Qwen3 30B-A3B 和 Qwen 3.6 35B-A3B 占用资源更少。
它在 Nemotron Voice Agent 流水线内运行,把访客说的话转化为下一句恰到好处的不情愿回复。
Bolt 提供了对话基础。我的提示词、应用逻辑以及在数千条经过审阅的示例对话上训练的 LoRA 适配器,把它塑造成了这艘特别固执的船。
创建一个包含 5000 多条多轮对话的数据集,意味着我可以为每个我觉得够格成为候选的模型训练 LoRA。有的训练大约花一个小时,有的要花几个小时。一个本地智能体负责运行所有流程并对结果进行基准测试。这个数据集最初也是由该智能体和一个超大规模 LLM 共同创建和评判的。这些工作都在夜里或我白天上班的时候进行。
装好 LoRA 之后,我会检查回复的连贯性、时机和语气,对模型和适配器的质量、重复度和速度做基准测试,然后亲耳听一遍表演。房子最终应该会让步,但不能变成一个热情洋溢的门房。一点抗拒正是魅力所在。而跟一扇车库门无休止地争论就不是了。
值得等待的声音
两条捷径,两种输出。已撰写的文本可跳过新生成的对话,已保存的音频可跳过合成。干净的语音独立于观众音效来驱动动画。
鬼屋如果抱怨得太慢,就会失去威慑力。该流水线在完整答案尚未生成完毕时就释放可朗读的文本,让房子可以在句子其余部分还在生成时就开始说话。预先准备的问候语和糖果笑话可以应对熟悉的场景:文本库节省了语言模型的工作量,缓存的录音节省了语音合成。即使是年迈的老古板也能从排练中受益。
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 上,带 Audio2Face-3D 的 Unreal Engine 图形运行在 NVIDIA RTX PRO 4000 Blackwell 上。内存不是问题,算力才是。我希望无论智能体流水线在处理什么,动画都能保持稳定的帧率。
语音、动画和特效必须同时到位。一个令人信服的怪物不仅需要快速回答,还需要听起来仿佛这抱怨本来就属于这座建筑。在我的例子里,确实如此。音频同步播放可进行微调。我发现设置好之后就可以不用再管了。(100ms 可补偿 Audio2Face-3D 的缓冲)
怪物有一张控制台
在这个过程中的某个时候,“让房子说话”需要一套满是控件的界面。我可以试听缓存的台词,调整开场情绪,跟踪对话,更改语音处理效果并调整嘴部动画。各个标签页涵盖对话、模型选择、录音、提示词、性能监控和摄像头画面,还有一个音效板和自定义对话输入框,让我可以替他说出想说的话。还有模型加载控件和 Unreal Engine 连接指示器,因为有时候怪物不是在生闷气——他是断线了。
MonsterHouse 控制台,包含音效板、自定义台词、开场情绪和对话流程。
火焰和光芒也加入了演出。可编辑的规则将视觉线索与台词播报绑定:实时线索随语音启动,而预先录制的表演则可以按照保存的时间轴进行。我可以在不重建场景的情况下指挥情绪变化。
实时模式运行这个“不给糖就捣蛋”角色。演示模式说服这座房子自己解释。麦克风模式让我直接通过房子说话,绕过语音识别、对话生成和语音合成。我干净的声音驱动嘴巴;观众听到的是处理过的版本。房子认为这是附身,我认为这是一个实用的后备方案。
下一次敲门声
NVIDIA Nemotron 3 Nano Omni 是一个视觉语言模型(VLM),为房子提供视觉上下文。作为一个可选的观察者,它解读摄像头图像并描述可见的服装,让角色有具体的东西可以做出反应。我并不想重复发明每一个轮子,所以选择了流行的目标检测与跟踪模型 YOLO 和 ByteTrack 来计数和跟踪当前视野中的人。把这些工作分开,房子就能注意到一群人,而不必让 Omni 逐帧解说。
为了进行一次足够荒诞的测试,我给了 Omni 一段五只穿着服装的绵羊站在门口的视频。它保存的分析识别出了海盗、吸血鬼、女巫、南瓜和幽灵的装扮。这正是我希望房子使用的视觉上下文。显然,连牲畜的万圣节计划都比我精心。
合成测试回放中的五只毛茸茸的“不给糖就捣蛋”者。服装标签来自 Omni 保存的分析;边框和跟踪 ID 仅供示意。
绵羊是合成测试,并不是万圣节之夜成功举办的证据。真实的车道人群、服装和夜间照明仍需测试。检测确实会触发自动问候,但我担心识别流行服装并给出恰到好处的机智回应可能需要一些后训练。由于房子没有眼睛,他把对访客的感知称为回声定位。这一条我由他了。
还有很多事要做:动画永远可以改进,完整的性能测试需要真实的访客,糖果终有一天会自动发放。我还没有达成最初的目标——让他独自运行万圣节,而我和家人出门去看 neighborhood 里其他的幽灵。但这仍然是一切的意义所在。总有一天,会有一个孩子遇到一座脾气暴躁的老房子,试着表现出一点善意,然后发现这老木头也有柔软的一面。而且会分发巧克力棒。
构建你自己的不理性角色
MonsterHouse 代码本身并未打包发布,但它使用的每一个 NVIDIA 模型现在都可用,而 NVIDIA Nemotron Voice Agent 能让你走完大部分路程。这就是我会遵循的路径。
- 从语音管线开始。克隆 NVIDIA Nemotron Voice Agent 并运行 Generic Assistant 示例。你会得到一个包含 Nemotron Speech ASR、一个 LLM 和 Magpie TTS 的级联管线,还有语音活动检测和话语结束处理,让你的角色知道何时该说话。
- 让 Bolt E4B 成为大脑。Voice Agent 包含适用于云端、服务器和单 GPU 部署的 Bolt E4B 配置。你可以先在 build.nvidia.com 上试用该模型。试试会话模式以获得简短、适合语音的回复,并在较简单的交互中禁用推理。
- 给它一个性格。从系统提示词和几段连贯的示例对话开始。把对话状态(比如谁已经说过“请”)保存在你的应用程序中,而不是让模型记住。当提示词不够用时,训练一个 LoRA 适配器;NVIDIA NeMo AutoModel 提供了针对 Bolt E4B 的 LoRA 配方。
- 给它一个声音。Magpie TTS Multilingual 是 Voice Agent 的默认选项。对于自定义角色,Magpie TTS Zeroshot 只需一段简短的参考样本即可工作。在 build.nvidia.com 上试用,并申请访问权限以便自行运行。[待确认:访问路径和链接] 只使用你有权使用的声音。
- 给它一张脸。NVIDIA Audio2Face-3D 可将语音转换为角色的面部动画。给它输入干净的语音,之后再添加效果。
- 可选:给它一双眼睛。Voice Agent 的 Nemotron Omni Assistant Subagents 示例通过 Nemotron 3 Nano Omni 增加了实时网络摄像头理解能力。如果需要人数统计,可以搭配一个轻量级的人员跟踪器。
缓存响应库和为最常用的台词预先保存的音频,能让即使反应迟缓的怪物也显得反应迅速。事实上,如果你恰好受限于算力,完全可以做一个只用 Nemotron Speech ASR 加一个 Python 对话路由器、全部使用缓存音频的 Live 版本。你可以用 Bolt E4B 和 Magpie 流水线离线生成数百条回复,然后在表演时使用缓存。我会为我的互动南瓜这样做。
资源
来源: Hugging Face Blog · huggingface.co

