Catbot 문법 버그 수정
- •Catbot 호출명 오류는 마이크나 청취 시간만이 아니라 Vosk 문법 한계에서 비롯됐다
- •근본적인 음성인식 수정에 앞서 청취 대기 시간이 .5초에서 1.5초로 늘어났다
- •두 번째 인식기 추가로 RAM은 약 200 MB 늘고 CPU는 블록당 4.3에서 8.0 ms로 상승했다
안나 비야레알(Anna Villarreal)은 2026년 8월 1일 데스크톱 반려형 음성 비서 Catbot이 호출명을 잘못 알아들은 이유가 음성 인식기에 지어낸 단어 “Catbot”을 처리할 usable path가 없었기 때문이라고 밝혔다. 이 버그로 Catbot은 사용자의 말을 끊고, “cat bought” 같은 이름을 말한 것이라고 반박했으며, 정상 응답 대신 긴 정정 대화를 시작했다. 비야레알은 먼저 청취 창을 .5초에서 1.5초로 바꿔 Catbot이 사용자의 자연스러운 멈춤을 기다린 뒤 말하도록 했다.
하드웨어도 인식에 영향을 줬다. 비야레알은 웹캠 마이크가 방 안 소음을 함께 잡아낸 반면, 가까운 거리의 무지향성 헤드셋 마이크는 Catbot이 말을 더 안정적으로 이해하는 데 도움이 됐다고 확인했다. 다만 마이크를 바꾼 뒤에도 핵심 문제는 남았다. Catbot은 여전히 자기 이름을 거부했는데, 음성 모델이 발명된 토큰 “Catbot”을 인식하기보다 사용 가능한 문법 안에서 가능성이 높은 단어를 고르고 있었기 때문이다.
비야레알은 문제를 Vosk 모델의 runtime graph 지원에서 찾았다. 선호하던 더 큰 모델인 vosk-model-en-us-0.22는 decoding graph가 하나의 고정 파일로 미리 합성돼 있어 training graph를 무시했다. 반면 custom grammar를 지원한 모델은 vosk-model-en-us-0.22-lgraph였다. 비야레알은 이 수정이 진짜 custom command를 추가하는 방식이 아니라, decoder가 선택할 수 있는 출력을 문법으로 제한해 선택지를 안내하는 방식이라고 설명했다.
Catbot은 Kaldi를 사용하며, Kaldi는 H, C, L, G 계층으로 구성된 HCLG(음성 디코딩용 그래프)라는 finite state transducer에 맞춰 음성을 해독한다. G 계층은 문법 또는 language model로, 가능한 단어열에 비용을 부여한다. 비야레알은 총비용이 음소가 오디오 프레임과 얼마나 잘 맞는지를 뜻하는 acoustic cost와 문장이 얼마나 그럴듯한지를 뜻하는 language cost를 합친 값이라고 썼다. negative log probability가 낮을수록 좋기 때문에 decoder는 비용이 가장 낮은 단어열을 선택한다.
해당 설명에서는 “ice cream”과 “I scream”이 음향만으로는 인식을 해결할 수 없는 사례로 제시됐다. language model은 소리를 듣지 않고 단어열에 점수를 매기며, decoder는 acoustic cost와 language cost의 합을 최소화한다. 비야레알은 정렬 문제를 헬렌 켈러와 앤 설리번에 비유하며, 원시 오디오 파형과 상징적 언어 토큰 사이를 잇는 중간 인터페이스가 필요하다고 말했다. 그는 컴퓨터과학에서 이를 multimodal alignment(서로 다른 데이터 유형 연결)라고 불렀다.
버그는 Claude가 “Catbot, engage”에 대한 phrase output을 생성했을 때 뚜렷하게 드러났다. 인식기는 “kappa engage”를 conf 114.1로, “cappa engage”를 conf 112.1로 반환했다. 비야레알은 이를 vocabulary trap이라고 불렀다. “Catbot”이 G를 통과하는 경로를 갖지 못했기 때문에 decoder가 가장 가까운 발음의 대체 문구를 골랐다는 뜻이다. 임시 해결책으로 그는 Catbot이 “CB”에 반응하도록 설정했는데, 이 영어 글자들은 이미 사용 가능했기 때문이다.
코드 수정은 Catbot_voice.py에 두 번째 grammar-constrained recognizer를 추가하는 방식이었다. 이 인식기는 VOSK_DYNAMIC을 vosk-model-en-us-0.22-lgraph로 설정하고, graph/Gr.fst를 확인했으며, WAKE_NAME_FORMS, GRAMMAR_TAILS, GRAMMAR_BARE에서 phrase list를 만들었다. 또한 model.vosk_model_find_word로 phrase를 필터링하고, 관련 없는 발화가 command grammar에서 빠져나갈 수 있도록 “[unk]”를 추가했다. 문법에는 “cat bot,” “cat pot,” “cat bought,” “cat bottom,” “catfight,” “combat,” “cabot,” “kat bot,” “cap pot” 같은 변형과 “engage,” “wake up,” “go to sleep,” “stop listening,” “open terminal,” “close terminal,” “approve,” “skip” 등 명령이 포함됐다.
두 번째 인식기는 기존 인식기를 대체하지 않고 함께 실행되므로, 전체 모델은 계속 대화를 처리한다. 비야레알이 측정한 추가 비용은 RAM 약 200 MB와 대략 두 배의 decode CPU였으며, 수치는 62 ms 블록당 4.3에서 8.0 ms로 올랐다. 그는 여전히 0.13x realtime으로 실행되고 지연시간은 추가되지 않았으며, 이 조건이 깨질 경우 CATBOT_GRAMMAR=0 스위치를 사용할 수 있다고 밝혔다.