Catbotの文法バグ修正
- •Catbotの起動名バグは、マイクや待機時間だけでなくVoskの文法制約に原因があった
- •待機停止は.5秒から1.5秒へ変更され、より深い音声認識修正の前段となった
- •第2認識器の追加でRAMは約200 MB増え、CPUはブロック当たり4.3から8.0 msに上昇した
アンナ・ビジャレアル(Anna Villarreal)はAugust 1, 2026、デスクトップペット型音声アシスタントCatbotが起動名を聞き違えた原因について、音声認識器に造語「Catbot」を扱う有効な経路がなかったと報告した。このバグによりCatbotは発話を遮り、「cat bought」などの名前を言っていると反論し、通常応答ではなく長い訂正対話を始めた。ビジャレアルはまず、自然な間を待ってからCatbotが話すよう、待機時間を.5秒から1.5秒に変えた。
ハードウェアも認識に影響した。ビジャレアルは、ウェブカメラのマイクが室内雑音を拾う一方、近距離の無指向性ヘッドセットマイクではCatbotが発話をより安定して理解すると確認した。マイク変更後も中心的な失敗は残った。音声モデルが造語トークン「Catbot」を認識するのではなく、利用可能な文法内のあり得る語を選んでいたため、Catbotは自分の名前を拒んでいた。
ビジャレアルは原因を、Voskモデルの実行時グラフ対応にたどった。望ましい大型モデルvosk-model-en-us-0.22は、復号グラフが1つの固定ファイルに事前合成されているため、訓練グラフを無視した。カスタム文法に対応したモデルはvosk-model-en-us-0.22-lgraphだった。ビジャレアルはこの修正を、真のカスタムコマンド追加ではなく、文法によってデコーダーが選べる出力候補を制限する方法だと説明した。
CatbotはKaldiを使い、H、C、L、G層から作られる有限状態トランスデューサーHCLG(音声復号用グラフ)に照らして音声を復号する。G層は文法または言語モデルで、あり得る単語列にコストを割り当てる。ビジャレアルによれば、総コストは音素が音声フレームにどれだけ合うかを示す音響コストと、文がどれだけ起こりやすいかを示す言語コストを組み合わせたものだ。負の対数確率は低いほど良く、デコーダーは最小コストの系列を選ぶ。
記事では、音響だけでは認識を解けない例として「ice cream」と「I scream」が挙げられた。言語モデルは音を聞くのではなく単語列を採点し、デコーダーは音響コストと言語コストの合計を最小化する。ビジャレアルはアラインメント問題をヘレン・ケラーとアン・サリバンになぞらえ、生の音声波形と記号的な言語トークンをつなぐ中間インターフェースが必要だと述べた。コンピューターサイエンス上の呼び名は、マルチモーダル・アラインメント(異なるデータ型を橋渡しすること)だとした。
Claudeが「Catbot, engage」のフレーズ出力を生成したとき、バグは明確に現れた。認識器はconf 114.1で「kappa engage」、conf 112.1で「cappa engage」を返した。ビジャレアルはこれを語彙の罠と呼んだ。「Catbot」がGを通る経路を持たないため、デコーダーが利用可能な中で最も音の近いフレーズを選んだからだ。一時的な回避策として、英語の文字として既に利用可能だった「CB」にCatbotが反応するよう設定した。
コード修正では、Catbot_voice.pyに第2の文法制約付き認識器を追加した。認識器はVOSK_DYNAMICをvosk-model-en-us-0.22-lgraphに設定し、graph/Gr.fstを確認し、WAKE_NAME_FORMS、GRAMMAR_TAILS、GRAMMAR_BAREからフレーズリストを作り、model.vosk_model_find_wordでフレーズを絞り込み、無関係な発話がコマンド文法から逃げられるよう「[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」などのコマンドが含まれた。
第2認識器はメイン認識器を置き換えず、並行して動くため、会話は引き続きフルモデルが処理する。ビジャレアルの測定では、追加コストはRAM約200 MB、復号CPUは約2倍で、62 msブロック当たり4.3から8.0 msに増えた。それでも0.13x realtimeで動作し、遅延は増えなかったという。その前提が崩れた場合の切り替えとして、CATBOT_GRAMMAR=0も用意された。