WWDC Quick Look 💓 By SwiftGGTeam
Customize on-device speech recognition

Customize on-device speech recognition

元の動画を見る

ハイライト

iOS 17 の Speech フレームワークでは、開発者がカスタム語彙とテンプレートでデバイス上音声認識の言語モデルをカスタマイズでき、専門用語、人名、ドメイン固有フレーズの認識精度を向上させます。すべての処理はローカルで完了します。

主要内容

汎用语言モデルの限界

iOS 10 から、Speech フレームワークは音響モデルと言語モデルの完全なパイプラインをシンプルな API でラップしてきました。しかしこの API はすべてのアプリを同等に扱い、すべてのアプリに同じ言語モデルの使用を強います。

問題は、ドメインごとに異なる言語モデルの振る舞いが必要なことです。チェスアプリではユーザーに「Play the Albin counter gambit」のような棋譜を口述させたい。汎用语言モデルはトレーニング中に大量の音楽リクエスト(「Play the album…」)を見ているため、この文を音楽再生リクエストと誤認識します。チェス用語はトレーニングデータに登場しませんでした。

00:29

トレーニングデータの構築

iOS 17 は SFLanguageModel クラスを導入し、result builder DSL でトレーニングデータコンテナを構築します。

import Speech

// 正確なフレーズとその重みを定義
let trainingData = SFLanguageModel.CustomData {
    PhraseCount(phrase: "Albin counter gambit", count: 50)
    PhraseCount(phrase: "Queen's Gambit", count: 100)
    PhraseCount(phrase: "Winawer variation", count: 30)
}

キーポイント:

  • PhraseCount はフレーズが最終データセットに出現する回数を記述し、特定フレーズに高い重みを付与
  • システムが受け入れるデータ量には限界がある — フレーズのブーストと全体予算のバランスを取る

02:57

テンプレートでサンプルを一括生成

import Speech

// 単語クラスを定義
let pieces = ["pawn", "knight", "bishop", "rook", "queen", "king"]
let files = ["a", "b", "c", "d", "e", "f", "g", "h"]
let ranks = ["1", "2", "3", "4", "5", "6", "7", "8"]

// テンプレートで可能なすべての手順の組み合わせを生成
let chessMoves = SFLanguageModel.CustomData {
    TemplateCount(
        pattern: "\(pieces) to \(files)\(ranks)",
        count: 10000
    )
}

キーポイント:

  • TemplateCount は複数の語クラスをパターンに組み合わせ、サンプルを一括生成
  • カウントはテンプレート全体に適用 — 10000 サンプルは生成されたすべてのデータに均等配分
  • テンプレートは棋譜や医学用語の組み合わせなど、組み合わせ空間が大きいシーンに適する

03:47

カスタム発音

import Speech

// 専門用語の綴りと発音を定義
let medicalTerms = SFLanguageModel.CustomData {
    PhraseCount(
        phrase: "amoxicillin",
        pronunciation: "@.mO.k.sI."lI.nIn",
        count: 20
    )
}

キーポイント:

  • 発音は X-SAMPA 文字列形式を使用
  • 各ロケールは異なる発音記号のサブセットをサポート
  • 医学、法律など専門分野の外来語や特殊発音に適する

04:28

ランタイムトレーニングデータ

import Speech

// ユーザーデータに基づいてトレーニングデータを動的生成
func generateUserSpecificTrainingData(contacts: [Contact]) -> SFLanguageModel.CustomData {
    SFLanguageModel.CustomData {
        for contact in contacts.prefix(50) {
            PhraseCount(phrase: "call \(contact.name)", count: 10)
        }
    }
}

// データをファイルへ書き込む
try trainingData.export(to: fileURL)

キーポイント:

  • ランタイム生成データは連絡先名や通話頻度などユーザー固有情報に基づけることができる
  • プライバシーに敏感な情報は常にデバイス上に留まり、ネットワークに送信されない
  • トレーニングデータは単一ロケールにバインド。多言語シナリオでは NSLocalizedString を使用

05:09

カスタムモデルのデプロイ

import Speech

// カスタム言語モデルを準備(時間のかかる処理なのでバックグラウンドで実行)
let customModelURL = try await SFLanguageModel.prepareCustomLanguageModel(
    for: fileURL,
    clientIdentifier: "com.example.chessapp",
    locale: Locale(identifier: "en_US")
)

// 認識リクエストを設定
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = true
request.customizedLanguageModel = customModelURL

// 認識を開始
let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "en_US"))!
let task = recognizer.recognitionTask(with: request) { result, error in
    if let result = result {
        print(result.bestTranscription.formattedString)
    }
}

キーポイント:

  • prepareCustomLanguageModel は顕著な遅延がある — バックグラウンドスレッドで呼び出す必要がある
  • 認識リクエストは requiresOnDeviceRecognition = true を設定しないとカスタマイズが効かない
  • すべてのカスタマイズリクエストは厳密にデバイス上で処理され、データはデバイスを離れない

06:08

詳細

音声認識の仕組み

音声認識のフローは 2 段階です。

  1. 音響モデル:オーディオデータを音素表現に変換
  2. 言語モデル:複数の候補転写から最も可能性の高い文を選択

複数の音素表現がオーディオデータに一致する場合、または単一音素が複数の転写に対応する場合、言語モデルが曖昧さを解消します。トレーニング中に接触した使用パターンに基づき、シーケンス内での単語出現確率を予測します。

00:37

データ予算とバランス

システムはトレーニングデータの総量に制限があります。PhraseCountcount パラメータは最終データセットでのフレーズの重みを決定します。高頻度フレーズに高い count、低頻度フレーズに低い count を付与。ただし全体予算に注意し、特定フレーズを過度に重視して他の重要語彙を無視しないこと。

03:30

プライバシー保護メカニズム

言語モデルカスタマイズの核心設計原則はデータがデバイスを離れないことです。

  • トレーニングデータファイルはローカルで生成・保存
  • prepareCustomLanguageModel は完全にローカルで実行
  • 認識リクエストはデバイス上で処理され、クラウドに送信されない

連絡先名、通話履歴、個人プレイリストなどプライバシーに敏感なデータに適しています。

05:33

重要ポイント

  • やること:専門分野アプリに音声入力サポートを追加

    • 価値がある理由:汎用音声認識は専門用語で精度が低い。カスタム言語モデルで医学用語、法律用語、工学用語の認識率を実用レベルに引き上げられる
    • 始め方SFLanguageModel.CustomData でドメイン高頻度フレーズを収集し、PhraseCount で重みを設定。エクスポート後 prepareCustomLanguageModel でデプロイ
  • やること:ユーザーデータに基づくパーソナライズ音声認識を実装

    • 価値がある理由:連絡先名、個人プレイリスト、よく使う連絡先は汎用モデルでカバーできない
    • 始め方:アプリ起動時に連絡先やユーザー履歴を読み取り、PhraseCount リストを生成。定期的にトレーニングデータファイルを更新
  • やること:複雑な組み合わせシナリオでテンプレートを使いトレーニングデータを生成

    • 価値がある理由:すべてのフレーズ組み合わせを手動列挙するのは非現実的。テンプレートで組み合わせ空間全体を一括カバー
    • 始め方:語クラス配列を定義し、TemplateCount でパターンに組み合わせ。適切な総サンプル数を設定して均等配分
  • やること:音声制御ゲーム向け専用認識モデルを設計

    • 価値がある理由:ゲーム指令は通常固定文法構造を持ち、テンプレートですべての可能な指令組み合わせを完全カバーできる
    • 始め方:ゲームのすべての音声制御可能操作を分析し、動作語、対象語、方位語などの語クラスを定義。テンプレートで完全指令セットを生成
  • やること:オフライン音声メモアプリを構築

    • 価値がある理由:デバイス上認識 + 言語モデルカスタマイズは完全オフライン利用を意味し、プライバシー敏感シナリオに適する
    • 始め方requiresOnDeviceRecognition = true を設定。ユーザーの過去メモ内容からトレーニングデータを生成し、常用語彙に高い認識重みを付与

関連セッション

コメント

GitHub Issues · utterances