kaedeasset記事 · Notes霧走町 流氷に眠る

Win+H で声がそのまま質問になる。ゲームの側には一行も足していない

Win+H turns your voice into a question, without a single line added to the game

 D13-4-T26-play-by-voice-typing・技術・日本語入力でプレイする仕組み

画面と入力Windows voice typingdictationautomatic speech recognitionclaude自然言語処理

入力欄をクリックして Win キー+H を押し、「昨日の夜はどこにいた」と話す。それだけで、佐伯への質問になります。
声のために足したコードはありません。入力欄が、OS から見てふつうの文字入力だからです。

前の回(T25)で、入力欄は IME を自前で受けず、UE とブラウザの本物の入力欄を借りている、と書きました。
その作りの、思わぬ副産物がこれです。
Windows の音声入力は、IME と同じく、焦点のある文字欄へ文字を届ける仕組みです。
届いた文字は、キーボードで入力した日本語と区別なく照合に回ります。
ゲーム実況で、刑事として声で問い詰めながら遊べる。作者が 10 月 27 日に、UE 版とブラウザ版の両方で確かめました。

今日は、なぜそのまま動くのかと、声の文字が照合にどう効くかを書きます。

この回の位置と、前後の回#

区切り: T25〜T29 画面と入力(5 回のうち 2 回目)
先に読むとよい回: T25(入力欄の中の IME)・T12(複文を節に割る)・T10(固有名詞の辞書)
次に読む回: T27(C++ の核を三つの外側で共有する)

名前 — Windows voice typing#

正式名
Windows voice typing(Windows 11 での呼び名。Windows 10 では dictation と呼ばれていた)。技術の一般名は automatic speech recognition(ASR)
略称
ASR
日本語
音声入力、音声認識
出所
Microsoft サポートの記事 "Use voice typing to talk instead of type on your PC"。Win+H が何年のどの版から使えるかは、今日は Microsoft の文書で確かめられませんでした

Windows の音声入力とは#

Microsoft の記事によると、こういうものです。

  • ハードウェアのキーボードでは Windows キー+H、タッチキーボードではマイクのボタンで始まる
  • 使うには、インターネットへの接続と、使えるマイクと、カーソルがテキストボックスにあることが要る
  • オンラインの音声認識(Azure Speech services)で文字にする
  • 「Stop listening」のような声の命令で止められる
  • エコーキャンセルが、スピーカーから出ている音(ナレーターやアプリの再生)を抑える
  • Windows の表示言語と違う言語でも、その言語を入れれば使える

仕組みの側から見ると、TSF のテキストサービスの一つです。
TSF のテキストサービスには、キーボードの IME のほかに手書きと音声認識が入る、と Microsoft の TSF の文書は書いています。
アプリから見ると、IME で確定した文字列が入るのと同じ道を通って、文字が入ってきます。

音声認識の一般的な弱点#

音声認識の誤りは、ふつう単語誤り率(WER)で測ります。

WER = (S + D + I) / N

S は置き換え、D は落ち、I は余計に入った語の数、N は正解の語の数です。
日本語は語の境目が文字に出ないので、文字の単位で数える文字誤り率(CER)がよく使われます。

数字に出にくい弱点もあります。

  • 同音の別の字。人の名前・地名のような固有名詞で起きやすい
  • 句読点。話し言葉には句読点が無いので、付けるかどうかは認識の側の推定になる
  • 言いよどみ(「えーと」「あのー」)がそのまま文字になる
  • 数の書き方(「十時」か「10時」か)
  • オンラインの認識なら、通信の遅れと、ネットにつながらないときに使えないこと

ゲームの入力として効いてくるのは、上の三つです。

なぜゲームの側に何も足さずに動くのか#

UE 版の入力欄は、編集している間だけ、枠の位置に Slate の SEditableText を置いています(T25)。
SEditableText は、キーボードの焦点を得たときに UE の ITextInputMethodSystem へ自分を登録して有効にし、Windows の実装はその先で TSF とつながっています。
音声入力の文字は、その口から入ってきます。

ブラウザ版は、キャンバスの上に重ねた本物の <input> です。
音声入力から見れば、ブラウザのふつうのテキストボックスです。

どちらも、入った文字列は Enter で送るまで欄の中にあり、送ると核(core)へそのまま渡ります。
核は、その文字列がキーボードから来たか声から来たかを知りません。
知る必要もありません。照合が見るのは文字列だけだからです。

逆に言うと、声のための特別な口を作っていたら、こうはいきませんでした。
音声認識のライブラリを組み込み、UE とブラウザで別々に動かし、結果を照合へつなぐ。
それより、OS の入力の口を一つも塞がない方が、ずっと安上がりでした。

声の文字は、照合でどうなるか#

作者が確かめたとき、音声入力の文には句読点が付きませんでした(それでも返事は返った)。
今日は声そのものは入れず、音声入力が出しそうな文を文字で入れて、照合の中で何が変わるかを測りました。
場所は港、相手は佐伯です。

  1. 句読点が無いと、点が下がる
    「ゆうべ、何時までどこにいたんですか?」は 0.647。
    句読点を除いた「ゆうべ何時までどこにいたんですか」は 0.489。
    正規化(norm/1)のあとの文字列は同じなのに、点が違います。
    どちらも採用の線(0.33)を越え、同じ証言が返りました。

理由は、文の埋め込みの引き方です。AdvMatcher.hpp の注記です。

// 入力全体に加えて、句読点で割った各節のベクトルも引く。
// 「佐伯が古い話を認めました。当時の記録を出してください」のような前置き付きの入力で、
// 文全体だと前置きに引っ張られて話題を取り違えるため(凍結ゴールデンで実測)。

埋め込みは、正規化する前の原文と、句読点で割った節ごとに引いて、意図ごとに最大を採ります(T05・T12)。
句読点があれば「ゆうべ」と「何時までどこにいたんですか」が別の節になり、後ろの節が言い換えの辞書の文に近く出ます。
句読点が無いと、全体の 1 本だけです。

逆の例もありました。
「事件が起きた夜、あなたは何時までどこにいましたか。」は 0.662、句読点なしは 0.685。
句読点が無い方が高い。2 位との差も、句読点なしの方が開きました(0.463 → 0.368)。
句読点は効くことも効かないこともあり、どちらに出るかは文しだいです。

  1. 二つの問いが一つにつながる
    いちばん大きな違いはこれでした。

「昨日の夜はどこにいた。それと、組合長とは会いましたか。」
→ 佐伯「どちらの話を先に確かめますか。一つずつ挙げてください」

「昨日の夜はどこにいたそれと組合長とは会いましたか」
→ アリバイの証言が返る(0.737。2 位は組合長との関係の意図で 0.564)

句読点があれば、進む問いが二つ並んだ複文として節に割れ、どちらから確かめるかを尋ねます(T12)。
句読点が無いと一つの文として照合され、点の高い方の問いにだけ答えて、もう一つは黙って消えます。
声で二つまとめて聞くと、後ろの問いが聞こえなかったことになる。

  1. 言いよどみは、ほぼ効かない
    「えーと昨日の夜はどこにいたんですか」は、正規化で長音が落ちて「えと昨日の夜は…」になり、0.917 で着地しました。
    「えーっと組合長とはどういう関係なんですか」も、組合長との関係の意図に着地(0.581)。
    文字の 1〜3-gram の照合では、頭の数文字が増えても、残りの n-gram の重なりは大きく変わりません。

  2. 名前の漢字違いは効く
    佐伯に、組合長との関係を聞きます。

「戸倉さんとはどういう関係ですか」→ 1.057。佐伯「組合長とは、特に付き合いはねえ」
「とくらさんとはどういう関係ですか」→ 0.733。同じ返事
「徳良さんとはどういう関係ですか」→ 0.600。佐伯「誰のことを言っとるんだ。名前を出せ」

固有名詞の辞書(entities.json)は、組合長に「戸倉」「組合長」「とくら」「戸倉誠一」「被害者」の 5 つの別名を持っています(T10)。
ひらがなの「とくら」は別名にあるので、固有名詞の加点(+0.15)が付き、材料を挙げた問いとして通ります。
「徳良」は別名に無いので、意図には着地しても「誰のことか」を挙げていない問いとして扱われ、名前を出せ、と返されます。
音声認識が名前を別の字にしたとき、プレイヤーには「ちゃんと名前を言ったのに」と見えるはずです。

名前どおりでない所 — Windows voice typing#

名前どおりです。
Windows の音声入力をそのまま使っていて、ゲームの側に音声認識はありません。
ゲームの照合は声を知らず、文字列だけを見ています。

弱点と、採らなかった案 — Windows voice typing#

弱点です。

  • Windows だけです。macOS やスマートフォンの音声入力でもブラウザ版の <input> に文字は入るはずですが、確かめていません。
  • オンラインが要ります。ゲーム自体はネットにつながずに動きますが、声で遊ぶときだけはつながっている必要があります。
  • 句読点が無いと、上に書いたとおり、二つの問いが一つになります。声で遊ぶ人には「一つずつ聞く」と伝える方がよさそうです。
  • 名前の漢字違いは、別名を足せば通ります。ただ、音声認識がどの字を出すかは、こちらでは決められません。別名を足すほど、ほかの名前と取り違える余地も増えます。
  • 全画面のときに音声入力の小窓が出るかは、記録が無く、確かめていません。

採らなかった案です。

  • ゲームに音声認識を組み込む。オフラインで動くモデルを積めば、ネットは要らなくなります。ただ UE とブラウザで別々に積むことになり、核の決定性(同じ入力に同じ返事・T23)の外側に、もう一つ揺れる部品が増えます。
  • 声のときだけ、句読点を推定して足す。照合の前に文を割る規則がもう一つ増え、キーボードの入力と声の入力で判定が変わります。今は入れていません。
  • 音声入力の文に専用の言い換えを足す。T50 で書く予定の失敗(落ちた入力を辞書に写して率を上げる)と同じ道です。

声で聞き込めるのは、入力欄をふつうの入力欄にしておいた結果でした。
作ったのではなく、塞がなかっただけです。

検索語#

Windows voice typing Win+H
Use voice typing to talk instead of type on your PC
automatic speech recognition word error rate
Text Services Framework speech

マイクがあれば、Win キー+H で佐伯に声で聞いてみてください。『霧走町 流氷に眠る』の第一章はブラウザで、プロフィールのリンクから遊べます。

#claude #自然言語処理