Hugging Face来源发布时间

nemotron-halloween

或者不如说……

用 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 的工作原理

满是木刺的笑容

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

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

创建自定义动画绑定是这个制作过程中较为费力的部分之一。在反复调试将其驯服之后,我就可以导出 Audio2Face-3D 之后可以用来驱动动画的面部表情形状。角色的 SkelMesh 是在 Autodesk Maya 中构建的,然后导出到 Unreal Engine 中,在门后添加了虚拟火焰和特效。没有眼睛、没有眉毛、也不会眨眼,他是一个出奇省料的怪物。

在所有构建角色的琐碎工作进行的同时,NVIDIA 构建了 Nemotron 语音代理。本该是整个项目中最难的部分,如今却变得相当有趣、可迭代且轻松。我开箱即得了一个用于聆听、对话和语音的基础。这房子已经有了嘴巴。现在他终于可以找点东西来抱怨了。

教他坏脾气

这座房子需要一段与其性格一样暴躁的过去,于是我构思了一个背景故事:这座房子是用一艘沉没海盗船的木材建造的,被其风暴般的过往所困扰。这些航海式的抱怨如今有了缘由。这就是那艘船,转世为不动产,而且对此并不完全满意。

这场表演需要一个引导,一条从问候到道别的路径,并在途中提供糖果。首先,房子会用诸如“我忙着发牢骚呢,去烦邻居吧!”这样的话把访客打发走。但坚持会让他软化。一句“请”可以立刻突破防线,而“谢谢”则能换来一句温暖的告别。一旦访客赢得了他的好感,我希望他保持好感。没人愿意和同一扇车库门谈判两次。

这就是 Voice Agent 真正大放异彩的地方。你可以选择任何你喜欢的 LLM。因为我希望这个系统脱离电网且完全自给自足,所以我有内存和算力预算的限制。

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

在测试了十多个模型之后,我最终选择了 Bolt E4B 来提供实时对话。它是一个专为本地对话智能体和交互式角色打造的开源小型语言模型,用来描述一个会说话的车库门倒是挺贴切。我使用 4 比特量化版本(其名称中的“4GB”)作为默认响应模型, BF16 checkpoint 则可供对比使用。

如果到现在还不明显的话,我在 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 一段五只穿着服装的羊在门口的视频。它保存的分析识别出了海盗、吸血鬼、女巫、南瓜和幽灵服装。这正是我希望房子使用的视觉上下文。看来连牲畜的万圣节计划都比我 elaborate。

合成测试回放中的五只毛茸茸的不给糖就捣蛋者。服装标签来自保存的 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 流水线离线生成100多条响应,然后在演出时使用缓存。我会为交互式南瓜这样做。

资源

原始出处

Hugging Face

内容说明

原始发布及相关权利归来源方。

机器翻译 · 请以原文为准