라기보다는...
요약: MonsterHouse는 제가 할로윈을 위해 제작한 인터랙티브 프로젝션입니다. 이 시스템은 트릭 오어 트리트(trick-or-treat)를 하는 사람들의 말을 듣고, 심술궂은 옛 해적선의 목소리로 답하며, 방문객들이 예의를 갖추면 부드러워집니다. 이는 NVIDIA Nemotron Voice Agent와 NVIDIA Nemotron ASR, Nemotron 3.5 Bolt E4B 4GB, Magpie TTS Zeroshot, Audio2Face-3D 등을 기반으로 하며 단일 워크스테이션에서 구동됩니다.
저는 할로윈에 저희 집에 방문하는 아이들이 재미있고 독특하게 상호작용하기를 바랐습니다. 원래 집이 간식(treats)을 나눠주는 역할을 맡았는데, 무섭기보다는 심술궂은 분위기가 되었습니다. 어떻게든 제가 찾은 해결책은 차고 문에 입을 달아주고 불평하는 법을 가르치는 것이었습니다.
그것이 바로 MonsterHouse가 되었습니다. 해적 이야기가 담긴 심술궂은 옛 건물로, 불같은 미소와 '부탁합니다(please)'라는 말에 대한 수상한 약점을 가지고 있습니다. NVIDIA Nemotron Voice Agent가 대화의 기반을 제공합니다. Nemotron Speech는 듣기 역할을 하고, Bolt E4B가 두뇌 역할을 하며, NVIDIA Magpie TTS Zeroshot이 실시간 목소리를 내고, NVIDIA Audio2Face-3D가 나무 입을 움직이게 합니다.
듣기 (Listening): NVIDIA Nemotron Speech ASR은 방문객의 음성을 텍스트로 변환합니다. [CONFIRMED:nemotron-speech-streaming-en-0.6b.q8_0.gguf]
사고 (Thinking): 대화형 에이전트를 위한 오픈 소스 경량 언어 모델인 NVIDIA Nemotron 3.5 Bolt E4B 4GB가 각 답변을 작성합니다. LoRA adapter는 개성을 공급합니다.
말하기 (Speaking): NVIDIA Magpie TTS Zeroshot은 캐릭터의 짧은 참고 샘플로부터 각 답변의 목소리를 생성합니다.
애니메이션 (Animating): NVIDIA Audio2Face-3D는 깨끗한 음성을 Unreal Engine 5에서 입 애니메이션으로 변환합니다.
보기 (Seeing): NVIDIA Nemotron 3 Nano Omni가 의상을 설명하는 동안, YOLO와 ByteTrack은 방문객을 계산하고 추적합니다.
구동하기 (Running it): NVIDIA Nemotron Voice Agent는 하나의 워크스테이션에서 NVIDIA RTX PRO 6000 Blackwell Max-Q 및 NVIDIA RTX PRO 4000 Blackwell을 사용하여 모든 것을 조정합니다.
입은 가장 먼저 나왔습니다. 저는 나무 차고 문 판자들이 톱니 모양의 입술로 갈라지고, 그가 저주받은 입을 열 때마다 지옥의 불길이 안뜰을 비추는 모습을 상상했습니다. 그는 고대적이고 표현력이 풍부하며 방문객들의 존재에 대해 약간 불쾌해하는 것처럼 보여야 했습니다.
fireMouth
할 말이 많은 집에서 포착한 몇 가지 표정들.
맞춤 애니메이션 리그(custom animation rig)를 제작하는 것은 빌드 과정 중 가장 노동 집약적인 부분 중 하나였습니다. 이 부분을 힘들게 완성한 후, Audio2Face-3D가 나중에 애니메이션화할 수 있는 얼굴 표정 모양들을 내보낼 수 있었습니다. 캐릭터 SkelMesh는 Autodesk Maya에서 구축된 다음 Unreal Engine으로 내보내졌고, 그곳에서 문 뒤에 가상 불과 효과들이 추가되었습니다. 눈도, 눈썹도, 깜빡임도 없는 그는 놀라울 정도로 효율적인 괴물입니다.
캐릭터를 만드는 복잡한 과정이 진행되는 동안, NVIDIA는 Nemotron Voice Agent를 구축했습니다. 빌드의 가장 어려운 부분이라고 여겨졌던 것이 이제는 꽤 재미있고, 반복적이며, 쉬운 일이 되었습니다. 저는 듣기, 대화, 음성에 대한 기초를 즉시 사용할 수 있는 형태로 갖추게 되었습니다. 집은 이미 입을 가지고 있었습니다. 이제 그는 마침내 불평할 거리를 찾을 수 있게 된 것입니다.
이 집은 그 성격만큼이나 심술궂은 과거가 필요했기 때문에, 저는 이 집이 폭풍우 치던 과거에 갇힌 침몰한 해적선의 목재로 지어졌다는 배경 이야기를 고안했습니다. 이제 항해와 관련된 불평에는 이유가 생겼습니다. 이곳은 부동산으로 환생했지만 완전히 만족하지 못한 배였습니다.
퍼포먼스에는 인사부터 작별까지, 그 과정에서 간식을 제공하는 안내자, 즉 경로가 필요했습니다. 처음에는 집이 “나 지금 투덜거리는 게 바쁘니까, 이웃들에게 가서 괴롭히지 마!” 같은 말로 손님들을 물리칠 것입니다. 하지만 끈기가 그를 지치게 할 것이었습니다. “부탁합니다(Please)”라는 말이 즉시 돌파구를 만들 수 있었고, “감사합니다(thank you)”는 따뜻한 작별 인사를 안겨주었습니다. 일단 방문객이 그를 사로잡으면, 저는 그가 계속 그렇게 남아있기를 바랐습니다. 아무도 같은 차고 문과 두 번이나 협상하고 싶어 하지 않습니다.
여기서 Voice Agent가 진가를 발휘합니다. 원하는 어떤 LLM이든 선택할 수 있습니다. 시스템을 오프그리드(off-grid)로 완전히 독립적으로 구축하고 싶었기 때문에, 저는 메모리와 컴퓨팅 예산에 제약이 있었습니다.
캐릭터는 단순히 “퉁명스럽게 행동하라”는 프롬프트 이상의 것이 필요했습니다. 방문객들이 실제로 말한 내용을 따라야 하고, 마스터 대화 흐름(master conversation flow)을 따르며, 만남 상태(encounter state)를 추적하고, 나머지 파이프라인에 충분한 컴퓨팅 자원을 남겨두어야 했습니다.
12개 이상의 모델을 테스트한 끝에 저는 실시간 대화를 제공하기 위해 Bolt E4B를 선택했습니다. 이 모델은 로컬 대화 에이전트 및 인터랙티브 캐릭터를 위해 특별히 설계된 오픈 소형 언어 모델(open small language model)이며, 말하는 차고 문이라고 비유할 수 있습니다. 저는 기본 응답 모델로 4비트 양자화 버전(이름에 있는 “4GB”)을 사용하며, 비교용으로 BF16 체크포인트도 사용할 수 있습니다.
지금까지 명확하지 않다면 말씀드리겠습니다만, 저는 NVIDIA에서 근무하고 있으며 이 덕분에 Bolt E4B가 공개되기 전에 테스트할 수 있었고, 다른 선두 주자들인 Qwen3 30B-A3B 및 Qwen 3.6 35B-A3B보다 작은 크기(smaller footprint)를 가진 견고한 선택지임을 발견했습니다.
이 모델은 Nemotron Voice Agent 파이프라인 내에서 작동하여, 방문객들이 말하는 내용을 다음으로 적절하게 마지못해 하는 답변으로 변환합니다.
Bolt가 대화의 기반을 제공합니다. 저의 프롬프트, 애플리케이션 로직, 그리고 수천 개의 검토된 예시 대화로 훈련된 LoRA 어댑터가 이 모델을 특정하고 고집스러운 형태로 만듭니다.
5000개 이상의 다중 턴(multi-turn) 대화 데이터셋을 구축함으로써, 저는 옵션으로 삼고 싶은 각 모델에 대한 LoRA를 훈련할 수 있었습니다. 일부는 훈련하는 데 약 한 시간이 걸렸고, 일부는 몇 시간씩 걸렸습니다. 로컬 에이전트가 모든 것을 실행하고 결과를 벤치마킹했습니다. 처음에 이 데이터셋은 그 에이전트와 매우 큰 LLM에 의해 생성되고 평가되었습니다. 이는 밤이나 제가 본업을 하는 동안 이루어졌습니다.
LoRA를 적용한 후에는 답변의 연속성(continuity), 타이밍, 톤을 확인하고, 모델과 어댑터들을 품질, 반복성, 속도 측면에서 벤치마킹하며, 마지막으로 성능을 청취합니다. 이 집은 결국 무너져야 하지만, 활기찬 컨시어지처럼 변해서는 안 됩니다. 약간의 저항감이야말로 매력의 일부입니다. 차고 문과의 끝없는 논쟁은 아닙니다.
image
두 개의 단축키, 두 개의 출력물. 작성된 텍스트(Authored text)는 새로운 대화 생성을 건너뛰고, 저장된 오디오(saved audio)는 합성 과정을 건너뜁니다. 깨끗한 음성(Clean speech)은 청중 효과와 별개로 애니메이션을 구동합니다.
유령의 집이 불평하는 데 너무 오랜 시간이 걸리면 권위를 잃습니다. 이 파이프라인은 전체 답변이 끝나기 전에 말할 수 있는 텍스트를 방출하므로, 나머지 문장이 아직 진행 중일 때도 집이 말을 시작할 수 있습니다. 준비된 인사말과 사탕 농담은 익숙한 만남을 다룹니다. 텍스트 은행(text bank)은 언어 모델(language-model)의 작업을 절약하고, 캐시된 녹음(cached recordings)은 음성 합성(speech synthesis)을 절약합니다. 심지어 고대의 불평꾼조차도 연습하는 것이 이롭습니다.
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은 텍스트를 영국식 영어로 변환합니다. 이 모델의 zero-shot 음성 컨디셔닝(zero-shot voice conditioning)은 학습된 목소리 대신 짧은 참조 샘플을 사용하며, 저는 여기에 불평하는 해적 캐릭터를 공급했습니다. 집에는 짜증나고 위협적인 분위기부터 즐겁고 황홀한 분위기까지 일곱 가지 기분(moods)이 있으며, 프롬프트 템플릿에 의해 결정되고 LLM이 제공하는 감정 태그(emotion tags)는 각 대사가 어떻게 전달될지 선택합니다. 각 감정은 서로 다른 3~10초 길이의 음성 샘플을 필요로 하기 때문에, 저는 UI의 도구 탭에 “Sample your Voice” 블록을 추가했습니다. 이를 통해 가장 행복한 해적 목소리나 화난 해적 목소리로 샘플 텍스트를 읽고 녹음할 수 있었습니다. ‘시작’할 시간이 되면, Bolt E4B가 무엇을 말할지 결정하고, Magpie는 그 텍스트를 적절한 기쁨이나 절망감을 담은 음성으로 변환합니다.
다음으로 소개할 것은 Audio2Face-3D와 제가 Epic의 Unreal Engine에서 만든 3D 캐릭터 장면입니다. 기본 모델 가중치(default model weights)는 너무 깊지도, 너무 높지도 않은 깨끗하고 중립적인 남성 또는 여성 목소리와 가장 잘 작동합니다 (사용 사례에 맞는 성별화된 모델을 선택하세요). 저는 집이 에코와 챔버가 있는 매우 깊고 악마적인 목소리를 갖기를 원했습니다. 이 경우, 제 음성 샘플에는 그러한 연극적인 무게감(theatrical heft)이 없기 때문에 오히려 장점입니다. Audio2Face-3D는 샘플에서 깨끗한 음성을 얻고, 두 번째 오디오 스트림은 스피커로 재생되는 조정 가능한 실시간 보컬 효과를 추가합니다.
모든 것이 원활하게 작동하도록 하기 위해 작업을 두 개의 GPU에 분할했습니다. 언어 및 음성 모델 파이프라인은 NVIDIA RTX PRO 6000 Blackwell Max-Q에서 실행되고, Audio2Face-3D를 사용한 Unreal Engine 그래픽은 NVIDIA RTX PRO 4000 Blackwell에서 실행됩니다. 메모리가 문제가 아니라 컴퓨팅(compute)이 문제입니다. 에이전트 파이프라인이 어떤 처리를 하든 애니메이션을 일관된 프레임 속도(frame rate)로 유지하고 싶습니다.
음성, 애니메이션, 효과는 함께 전달되어야 합니다. 설득력 있는 괴물은 단순히 빠른 답변 이상의 것이 필요합니다. 그 불만이 건물 자체에 속한 것처럼 들려야 합니다. 제 경우, 실제로 그렇습니다. 오디오 전달을 동기화하는 조정(tweaks)이 가능합니다. 저는 이것들을 설정해두고 잊어버릴 수 있다는 것을 알게 되었습니다. (100ms는 Audio2Face-3D 버퍼링을 보상합니다.)
어느 순간에 이르러 “집이 말하게 만들기”는 제어 장치가 가득한 인터페이스를 필요로 했습니다. 저는 캐시된 대사를 청음하고, 시작 분위기를 조정하며, 대화를 따라가고, 음성 처리를 변경하고, 입 애니메이션을 미세 조정할 수 있습니다. 탭에는 대화, 모델 선택, 녹음, 프롬프트(prompts), 성능 모니터링 및 카메라 피드가 포함되어 있으며, 사운드보드와 사용자 지정 대화 필드는 제가 그의 입에 말을 넣을 수 있게 해줍니다. 또한 모델 로딩 제어 장치와 Unreal Engine 연결 표시기(indicator)도 있는데, 왜냐하면 때로는 괴물이 우울한 것이 아니라 연결이 끊어졌기 때문입니다.
image
사운드보드, 사용자 지정 대사, 시작 분위기 및 대화 흐름이 있는 MonsterHouse 제어 데스크.
불과 빛이 연출에 합류했습니다. 편집 가능한 규칙은 시각적 단서와 전달을 연결합니다. 라이브 큐(live cues)는 음성으로 시작하며, 녹화된 공연은 저장된 타임라인을 따를 수 있습니다. 저는 장면을 재구축할 필요 없이 분위기 변화를 지시할 수 있습니다.
라이브 모드(Live mode)는 트릭 오어 트리트 캐릭터를 구동합니다. 데모 모드(Demo mode)는 집이 스스로 설명하도록 설득합니다. 마이크로폰 모드(Microphone mode)를 사용하면 인식, 대화 생성, 음성 합성 과정을 우회하여 집을 통해 직접 말할 수 있습니다. 제 깨끗한 목소리가 입을 움직이고; 청중은 처리된 버전을 듣습니다. 집은 이것을 빙의로 간주합니다. 저는 유용한 대체 기능으로 간주합니다.
NVIDIA Nemotron 3 Nano Omni는 집에 시각적 맥락을 제공하는 VLM(Visual Language Model)입니다. 선택적인 관찰자로서, 이 모델은 카메라 이미지를 해석하고 보이는 의상을 설명하여 캐릭터가 반응할 구체적인 무언가를 갖게 합니다. 모든 것을 재발명하려는 것이 아니었기에, 저는 현재 시야에 있는 사람들을 계산하고 추적하기 위해 인기 있는 객체 탐지 및 추적 모델인 YOLO와 ByteTrack을 선택했습니다. 이 작업들을 분리함으로써 집은 Omni에게 매 프레임을 서술하도록 요청하지 않고도 그룹을 알아차릴 수 있습니다.
적절하게 터무니없는 테스트를 위해, 저는 Omni에게 문 앞에 있는 의상을 입은 다섯 마리의 양 영상을 제공했습니다. 저장된 분석 결과는 해적, 뱀파이어, 마녀, 호박, 유령 복장을 식별했습니다. 이것이 바로 제가 집이 사용하기를 원하는 시각적 맥락입니다. 분명히 가축조차 저보다 더 정교한 할로윈 계획을 가지고 있는 것 같습니다.
image
합성 테스트 리플레이에서 매우 털이 많은 트릭 오어 트리트 참가자 다섯 명. 의상 라벨은 저장된 Omni 분석에서 가져왔으며; 박스와 추적 ID는 예시용입니다.
양들은 성공적인 할로윈 밤의 증거가 아닌 합성 테스트입니다. 실제 진입로 그룹, 의상, 야간 조명은 여전히 테스트가 필요합니다. 탐지 기능은 자동 인사말을 트리거하지만, 저는 트렌디한 의상 식별과 적절하게 재치 있는 응답에는 추가 훈련이 필요할까 봐 우려됩니다. 집에 눈이 없기 때문에, 그는 방문객 인식을 반향정위(echolocation)라고 부릅니다. 이 점은 제가 그에게 맡기고 있습니다.
할 것은 더 많습니다. 애니메이션은 항상 개선될 수 있고, 완전한 성능 테스트를 위해서는 실제 방문객이 필요하며, 사탕은 언젠가 자동으로 제공될 것입니다. 저는 아직 그를 남겨두고 가족과 함께 이웃의 다른 괴물들을 보러 떠나는 동안 할로윈을 운영하게 하는 원래 목표에 도달하지 못했습니다. 하지만 그것이 바로 이 모든 것의 요점입니다. 언젠가 아이가 심술궂은 낡은 집을 만나 작은 친절을 베풀고, 그 오래된 목재에 약점이 있다는 것을 발견하게 될 것입니다. 그리고 사탕 바를 나눠줄 것입니다.
MonsterHouse 코드 자체는 배포용으로 패키징되지는 않았지만, 그것이 사용하는 모든 NVIDIA 모델은 오늘날 이용 가능하며, NVIDIA Nemotron Voice Agent가 대부분의 과정을 해결해 줍니다. 이것이 제가 따를 경로입니다.