Windowsでオフライン(ローカル)音声認識アプリを作るとき、どの音声認識APIを選ぶかで「カスタムASRモデルを使えるか」「アプリ形態(UWP/WinUI 3/Win32)」「配布と権限」が大きく変わります。この記事では Windows.Media.SpeechRecognition / System.Speech / SAPI を比較し、OEMが独自エンジンを組み込みたいケースを中心に、実務で迷いやすい論点を整理します。
結論:カスタムASRモデルが必須なら、UWP単体では完結しない
「Windows上でオフライン音声認識をしたい」だけなら選択肢は多いのですが、OEMが独自の音声認識エンジン(ASRモデル)を採用したいとなると、最初に押さえるべき結論は次のとおりです。
- Windows.Media.SpeechRecognition:認識エンジン/ASRモデルの差し替えは不可。できるのは認識結果を絞るための「認識制約(constraints)」。
- System.Speech / SAPI:エンジンを追加・選択する思想がある。独自エンジンを「SAPI互換エンジン」として提供する設計と相性が良い。
判断の近道:音声認識を「OS標準機能として借りる」のか、「自社モデルを製品価値として運用する」のかで分かれます。後者なら、アプリ種類も含めてデスクトップ前提(Win32/WinUI 3等)+独自エンジン連携で考えるのが現実的です。
Windowsの音声認識APIは大きく3系統
Windowsのローカル音声認識(ASR: Automatic Speech Recognition)でよく候補に挙がるのは、次の3つです。
- Windows.Media.SpeechRecognition:Windows Runtime(WinRT)系。UWPでの利用が中心。
- System.Speech:主に .NET Framework のデスクトップAPI(WPF/WinForms等)。SAPI(後述)を扱いやすくしたラッパー色が強い。
- Microsoft Speech API(SAPI):COMベースのAPI。OSに「認識エンジン(Recognizer)」を登録して利用する文化。
同じ「音声認識」でも、想定しているアプリモデルとカスタムのしやすさがまったく違います。特にUWPを前提にする場合は、次の点が分岐になります。
UWPで完結させたい場合に使えるAPIの現実
UWPアプリだけで完結させたい場合、音声認識として現実的に使えるのはWindows.Media.SpeechRecognitionが中心になります。System.SpeechやSAPIは、従来のデスクトップ(Win32/WPF/WinForms等)向けの設計思想であり、UWPサンドボックスの範囲でそのまま利用する前提ではありません。
そのため、要件が次のどちらに近いかで早めに割り切るのが重要です。
| 要件の方向性 | まず選ぶべき考え方 |
|---|---|
| UWPで完結、OS標準の音声認識で十分 | Windows.Media.SpeechRecognitionを使い、constraintsで認識範囲を絞る |
| 独自ASRモデルが必須、エンジンを製品価値として運用したい | UWPに縛らず、デスクトップ+独自エンジン(SDK直呼び/別プロセス/SAPI互換)で設計 |
Windows.Media.SpeechRecognition:できること・できないこと
Windows.Media.SpeechRecognition は、Windowsに組み込まれた音声認識機能をアプリから呼び出すためのWinRT APIです。UWPアプリで「OS標準の音声認識」を使う場合、基本的にこのAPIが中心になります。
できること:制約(constraints)で「認識範囲」を狭める
このAPIのカスタマイズは、主に SpeechRecognitionConstraint を使った「認識候補の絞り込み」です。代表例は次のとおりです。
- 固定フレーズ(コマンド):候補語をリスト化して認識精度と速度を上げる(例:「開始」「停止」「次へ」など)。
- 文法(Grammar):SRGS(Speech Recognition Grammar Specification)形式の文法ファイルで構造化する。
- シナリオ指定:ディクテーション/検索など用途に応じた認識モードを指定する(環境によっては挙動が変わる)。
これらは「モデルを改造する」のではなく、モデルが出せる候補をアプリが制御して、結果を絞るイメージです。オフラインでの固定コマンド認識など、スコープが明確な用途では強力です。
できないこと:認識エンジンやASRモデルの差し替え
重要なのは、Windows.Media.SpeechRecognitionでカスタム認識エンジンや自前ASRモデルを指定する仕組みは用意されていない点です。つまり、次のような要件はこのAPI単体では満たしません。
- 自社学習したDNN/Transformerモデルをエンジンとして組み込みたい
- 特定ドメインに特化したサードパーティASRを選択したい
- 推論をGPU/NPUに固定して省電力・低遅延を狙いたい(アプリ側から明示指定したい)
簡易サンプル:リスト制約でコマンド認識(UWP/WinRT系)
最短で効果が出るのは、コマンド候補を固定する方法です。
using Windows.Media.SpeechRecognition;
var recognizer = new SpeechRecognizer();
recognizer.Constraints.Add(
new SpeechRecognitionListConstraint(new[] { "開始", "停止", "次へ" }, "commands")
);
var compilation = await recognizer.CompileConstraintsAsync();
if (compilation.Status == SpeechRecognitionResultStatus.Success)
{
var result = await recognizer.RecognizeAsync();
// result.Text に認識文字列が入る
}
固定コマンドのように「言えること」が限られる場合、クラウド依存にせずとも体験を作りやすい一方、自由発話の高精度化は別アプローチ(独自エンジン等)が必要になります。
実務メモ:オフライン運用で詰まりやすいポイント
Windows標準の認識を使う場合でも、オフライン要件では次の点がボトルネックになりがちです。
- 言語・音声パック:対象言語の認識が有効でないと制約のコンパイルや認識が失敗することがある。
- マイクのプライバシー設定:ユーザー/組織ポリシーでマイクが無効化されていると動かない。
- 常時待受:連続認識を安易に常時ONにすると、バッテリー・熱・ユーザー体験に跳ね返る。
System.Speech:デスクトップ向けで「エンジン選択」がしやすい
System.Speech は、主に .NET Framework のデスクトップアプリ(WPF/WinForms等)で使われてきた音声認識APIです。内部的にはSAPI系の仕組みを使うことが多く、PCにインストールされた認識エンジン(Recognizer)を列挙して選択できるのが大きな特徴です。
System.Speechが向くケース
- Windowsデスクトップアプリで、オフラインのコマンド認識を作りたい
- SRGS文法や辞書的なルールで「言えること」を制限して精度を上げたい
- 将来的にサードパーティのSAPI互換認識エンジンを追加する可能性がある
System.Speechの注意点
- レガシー寄り:古くから使われるAPIで、最新のUI/配布モデル(WinUI 3やMSIX)とは設計思想が違う。
- アプリ形態の自由度:UWPサンドボックス内での利用は想定されておらず、基本はデスクトップアプリ前提。
- エンジン品質は「入っているRecognizer次第」:APIが高性能化してくれるわけではない。
簡易サンプル:インストール済みRecognizerの列挙(C#)
「どの認識エンジンが入っているか」をまず確認するのが、選定の第一歩です。
using System;
using System.Speech.Recognition;
class Program
{
static void Main()
{
foreach (var ri in SpeechRecognitionEngine.InstalledRecognizers())
{
Console.WriteLine($"Name: {ri.Name}");
Console.WriteLine($"Culture: {ri.Culture}");
Console.WriteLine($"Description: {ri.Description}");
Console.WriteLine("---");
}
}
}
OEMで独自エンジンを配布する場合、ここに自社Recognizerが出てくる状態(=OSに登録される状態)まで持っていけるかが、SAPI系を採るかどうかの分岐点になります。
SAPI:最も低レベルで、OEMの「エンジン組み込み」と相性が良い
SAPI(Microsoft Speech API) はCOMベースの音声関連APIで、Windowsの音声認識/音声合成で長く使われてきた枠組みです。SAPIの世界観は「アプリ」と「認識エンジン(Recognizer)」が分離されていることにあります。
つまり、SAPIクライアント(アプリ)は、OSに登録されたRecognizerを利用します。OEMが独自エンジンを用意する場合、理想形は次のどちらかです。
- SAPI互換のRecognizerとして実装・登録し、SAPI対応アプリ全般から利用できるようにする
- SAPIには寄せず、自前のASRエンジンSDKをアプリから直接呼ぶ(後述)
SAPIを採るメリット
- エンジン追加・差し替えの思想がある(設計がそれを前提にしている)
- System.Speechなど、上位APIからも利用されやすい
- OEM配布で「OSの機能として」扱いやすいケースがある
SAPIを採るデメリット
- 実装・配布の難易度が高い(COM登録、ビット数、インストーラー、アップデート設計)
- 最新DNNモデルの推論スタック(GPU/NPU最適化など)は、SAPIが提供してくれるわけではなく自前実装
- 「1アプリだけで完結」より、エコシステム(OS登録)を意識した設計が必要
3つのAPI比較表:カスタムASR・オフライン・アプリ形態
| 観点 | Windows.Media.SpeechRecognition | System.Speech | SAPI |
|---|---|---|---|
| 主な対象 | UWP/WinRT系(OS標準機能を利用) | .NET Framework系デスクトップ | Win32/COM(エンジン分離思想) |
| カスタムエンジン/モデル差し替え | 不可(制約で絞り込みのみ) | 条件付き可(SAPI互換RecognizerをOSに追加できれば利用可能) | 可(SAPI互換Recognizerとして実装・登録する設計) |
| カスタマイズ手段 | List/Grammar/TopicなどのConstraint | Grammar(SRGS)/Dictationなど | SRGS/認識コンテキスト等(低レベル) |
| オフライン適性 | OS/言語パック依存。固定コマンドは得意 | インストール済みRecognizer次第。コマンド系は適性高め | エンジン実装次第。OEM要件に合わせやすい |
| ハードウェア(CPU/GPU/NPU)指定 | アプリ側からは指定不可(OS内部に隠蔽) | 基本は指定不可(エンジン実装依存) | APIでは指定しない(エンジン側で自由に設計) |
| 配布/運用の難しさ | 比較的低い(標準機能を呼ぶだけ) | 中(フレームワーク/Recognizer要件) | 高(COM登録・エンジン配布・保守) |
OEMが独自ASRを載せるときの「現実的な設計」
「カスタムASRモデルを使いたい」=「SAPIを採る」ではありません。SAPI互換エンジンとして実装する道は強力ですが、コストも大きいからです。実務では次の3パターンで考えると整理しやすくなります。
アプリ内にASRエンジンを組み込む(SDK/ライブラリ直呼び)
最も自由度が高い方法です。自社モデル(例:ONNX化した音声モデル)やサードパーティSDKを、アプリ(または同梱のネイティブDLL)から直接呼びます。
- メリット:CPU/GPU/NPUの最適化やモデル更新を自社でコントロールできる。OS標準認識に依存しない。
- デメリット:マイク入力、VAD(無音区間検出)、ノイズ抑制、辞書、言語切替など周辺実装まで責任範囲が広がる。
UIはWinUI 3、バックエンドはネイティブ/サービス、という分離がしやすく、“モデル主導で作る”なら第一候補になります。
ASRエンジンを別プロセス(サービス)に分離する
常駐認識や複数アプリで共有したい場合は、ASRを別プロセスに分離してIPC(Named Pipe / gRPC / WebSocket等)で連携する構成が現実的です。
- メリット:UIクラッシュと推論プロセスを切り離せる。権限分離がしやすい。モデル更新も差し替えやすい。
- デメリット:設計が複雑になる(プロセス間通信、起動制御、セキュリティ、ログ収集など)。
「UWP UIを維持しつつ、裏で自前エンジンを動かす」ような折衷案にも使えますが、その場合は配布形態(MSIX、フル・トラストプロセスの扱い等)まで含めた検討が必要になります。
SAPI互換RecognizerとしてOSに登録する
OSの音声エコシステム(SAPI対応アプリ、既存資産)に乗せたいなら、この方式が最も“Windowsらしい”選択です。
- メリット:SAPI対応アプリから利用可能になり、System.Speechからも扱いやすい。
- デメリット:実装・検証・配布が重い。言語追加や辞書更新の運用も設計が必要。
OEMで「自社デバイスの標準入力として提供したい」「複数アプリから共通利用したい」なら検討価値があります。一方、「特定アプリの機能として閉じる」なら、SDK直呼びの方がトータルで軽いことが多いです。
CPU/GPU/NPU/eNPU:どこで動かせるか、どこまで指定できるか
質問で必ず挙がるのが「モデルをCPU/GPU/NPU/eNPUのどこで動かせるのか」です。ここは誤解が生まれやすいので、考え方を整理します。
Windows標準APIの範囲では「実行場所の指定」は基本できない
Windows.Media.SpeechRecognition のようにOS標準認識を呼ぶAPIは、推論の実装詳細(どのデバイスで回すか)をアプリに見せません。したがって、アプリから「GPUで回して」「NPUを使って」といった明示指定はできません。
現場では、次のように割り切るのが安全です。
- OS標準認識を使うなら、ハードウェア最適化はOS任せ。性能要件は“CPU中心でも成立する”前提で設計しておく。
- GPU/NPU前提の性能・省電力が必須なら、自前エンジン(SDK直呼び/別プロセス)で制御する。
カスタムエンジンなら、実行場所は「エンジン側の設計」で決まる
System.Speech/SAPIを使う場合も、API自体がGPU/NPUを切り替えるわけではありません。最終的には、Recognizer(エンジン実装)が何をサポートしているかがすべてです。
例えば、独自ASRを推論基盤(例:ONNX Runtime等)で構築するなら、エンジン内部で
- CPU実行(互換性重視)
- GPU実行(低遅延・高スループット)
- NPU実行(省電力・常時待受に有利な場合がある)
のような切り替え戦略を持たせることは可能です。「どのAPIを選ぶか」より「どの推論基盤でエンジンを作るか」が支配的になるため、要件定義の段階で切り分けて考えるとブレません。
既定モデルはどこで動くのか
Windows.Media.SpeechRecognitionはOS組み込み機能を利用するため、内部実装は非公開です。一般的なクライアントPCではCPUでの処理を前提に考えるケースが多く、アプリ側から実行デバイスを固定する手段は提示されていません。
System.Speech/SAPIも同様で、既定のRecognizerがどのデバイスで推論するかはエンジン実装次第です。“APIの仕様としてGPU/NPUを保証する”ものではない点は押さえておきましょう。
権限・制限:マイクとプライバシーが実務の中心
音声認識は「音声を取得する」機能なので、実務で詰まるのはAPIよりも権限(Permission)とプライバシーです。アプリモデルごとの要点をまとめます。
Windows.Media.SpeechRecognitionの利用条件(ライセンス観点)
OS組み込み機能を利用するため、一般的には追加の音声認識ライセンス購入が必要になるケースは多くありません。一方で、音声を扱う以上、利用規約・プライバシー・セキュリティの観点で守るべきことは増えます。
- ユーザーに対して、マイク利用目的・取得範囲・保存/送信の有無を明示する
- 組織利用なら、管理者ポリシー(マイク禁止、ログ禁止等)を前提に設計する
- サードパーティエンジンを組み込む場合は、そのエンジンの利用条件/再配布条件も確認する
UWP(Windows.Media.SpeechRecognition)で必要になりやすいもの
- マイク権限:Package.appxmanifestでmicrophone機能を宣言し、ユーザーの同意を得る。
- 組織ポリシー:企業環境ではマイクが禁止されていることがある。要件に「例外申請フロー」を含めると現場が楽になる。
- ストア/審査観点:音声データの扱い(保存の有無、送信の有無、同意UI)を明確にする。
デスクトップ(System.Speech / SAPI / 独自エンジン)で気にすること
- Windowsのマイクプライバシー設定:「アプリ」だけでなく「デスクトップアプリ」のマイク許可がOFFだと取得できない。
- インストール権限:SAPI互換RecognizerをOSに登録する場合、インストール時に管理者権限が必要になるケースがある(環境依存)。
- データ取り扱い:オフラインでもログや学習データとして音声を保存する設計だと、個人情報・機密情報の扱いが問題化しやすい。
オフライン要件でも「プライバシー設計」は必須
「ローカルで動くから安心」と思われがちですが、実務では次の点を明確にする必要があります。
| 確認項目 | 決めるべき内容の例 |
|---|---|
| 音声データを保存するか | 保存しない/短時間のリングバッファのみ/ユーザー操作時のみ保存 など |
| ログに何を残すか | 認識テキストのみ/信頼度スコアのみ/原音は残さない など |
| ユーザー同意の取り方 | 初回起動時に明示/機能ON時に毎回確認/設定画面でいつでも停止できる など |
| 常時待受の扱い | Push-to-talkに限定/キーワード起動(Wake word)/バッテリー時は停止 など |
アプリ種類の決め方:UWP/WinUI 3/Win32/コンソールの使い分け
「カスタムASRモデルが使えるかどうか」がアプリ種類選定の材料になる、というのはその通りです。実務では、次のように要件を分解すると迷いが減ります。
選定の軸
- UIの要件:WindowsらしいモダンUIが必要か、設定ツール程度でよいか。
- 配布方法:Microsoft Storeなのか、社内配布なのか、OEMプリインストールなのか。
- エンジンの自由度:OS標準でよいのか、独自ASRが必須か。
- 常駐・バックグラウンド:UIなし常駐が必要か、起動中のみでよいか。
アプリ形態と音声認識の相性(実務向け)
| アプリ形態 | 向くケース | 音声認識の実装方針 | 注意点 |
|---|---|---|---|
| UWP | ストア配布、サンドボックス重視、標準機能で十分 | Windows.Media.SpeechRecognition | エンジン差し替え不可。バックグラウンド常駐は設計制約が多い |
| WinUI 3(Windows App SDK) | モダンUI+デスクトップ自由度が欲しい | WinRT API利用 or 独自エンジン連携 | パッケージ有無で権限・API可用性が変わることがある |
| Win32(WPF/WinForms含む) | 既存資産、社内ツール、OEMユーティリティ | System.Speech / SAPI / 独自エンジン | UIの近代化は別途。配布・更新は自前設計になりやすい |
| コンソール/サービス | UI不要、バックエンド処理、常駐認識 | 独自エンジン(SDK/別プロセス) | マイク入力の権限・セキュリティ・ユーザー同意の設計が特に重要 |
ユースケース別おすすめパターン
最後に、よくある要件から「まずこの形で考えると早い」パターンをまとめます。
固定コマンドで操作したい(例:現場端末、業務アプリ)
- 第一候補:Windows.Media.SpeechRecognition(Constraintでコマンドを絞る)
- 次点:System.Speech(SRGS/Grammarで堅牢に)
コマンド認識は、モデルを巨大化するより「言えることを限定」した方が成功確率が上がります。誤認識に強いUI(確認ダイアログ、やり直し導線)もセットで設計しましょう。
長時間の文字起こし・専門用語が多い(例:議事録、医療/製造の点検)
- 第一候補:独自ASRエンジン(ドメイン辞書・専門語彙を取り込みやすい構成)
- 補助:UIはWinUI 3、推論は別プロセスで運用しやすく
この領域は「エンジン差し替え不可」の制約が効きやすいので、OS標準APIだけで完結させるより、最初からモデル運用(更新/評価/ログ設計)まで含めたアーキテクチャにした方が中長期で安定します。
OEMとして独自エンジンを標準搭載したい(例:特定デバイスの入力手段)
- 第一候補:独自エンジンをSDKとして提供し、Win32/WinUI 3アプリから直接利用
- エコシステム連携が必要なら:SAPI互換Recognizerとして実装・登録(コストは高い)
「OSの音声認識を置き換える」発想に寄せるほど難易度は上がります。まずは自社アプリで完結する価値を最大化し、必要に応じてSAPI互換化を検討する、という段階設計が失敗しにくいです。
失敗しがちなポイント:API選定以前の落とし穴
PoCでは動いたのに本番で崩れる原因は、API選定より運用条件にあることが多いです。
- マイク品質と環境騒音:内蔵マイク/ヘッドセット/マイクアレイで結果が激変します。ターゲット機器で評価しましょう。
- 発話の開始・終了判定:VADが甘いと無音を認識して誤爆します。Push-to-talkやUI誘導が効きます。
- 言語・方言・専門語彙:辞書や文法で吸収できるのか、モデル側が必要なのかを早めに切り分けます。
- 32bit/64bit:SAPI系はエンジン/アプリのビット数や登録が絡み、環境差分が出やすい領域です。
選定チェックリスト:迷ったらここから埋める
- カスタムASRモデルが必須か?(YesならWindows.Media単体は除外)
- オフラインで完結する範囲(言語、専門語彙、更新頻度)
- ターゲット環境(Windows 10/11、管理ポリシー、マイク利用可否)
- 配布(ストア/社内/OEM、MSIXの可否、アップデート方式)
- 運用(ログ、障害解析、モデル更新、プライバシー同意)
- 性能要件(遅延、CPU使用率、常時待受の有無、バッテリー)
まとめ
Windowsでオフライン音声認識を作るとき、Windows.Media.SpeechRecognitionは「OS標準認識を制約で使いこなす」ためのAPIであり、カスタムエンジン/ASRモデルの差し替えには対応していません。OEMとして独自モデルを採用したいなら、設計の主戦場は System.Speech / SAPI、あるいは独自エンジンSDKをデスクトップアプリから呼ぶ構成になります。
ハードウェア(CPU/GPU/NPU)まで含めて最適化したい場合も、OS標準APIに期待するより、エンジン側(推論基盤/モデル運用)で制御する方が確実です。まずはチェックリストで要件を固め、最短で検証できる構成からPoCを回していきましょう。

コメント