FluidAudio: Appleデバイス上でCoreMLを使用して最先端の音声AIモデルをローカル実行
FluidAudioは、Apple Neural Engineを使用して、最先端の音声認識、テキスト読み上げ、話者識別、音声アクティビティ検出をすべてデバイス上で実行するためのSwift SDKです。この記事では、その機能、アーキテクチャ、およびアプリへの統合方法について説明します。
FluidAudioがApple開発者にとって重要な理由
長年にわたり、高度な音声AIをAppleアプリに統合するには、2つの選択肢がありました。音声データをクラウドAPIに送信するか(レイテンシ、プライバシー、コストの問題あり)、またはパフォーマンスの低いオンデバイスで肥大化したPyTorchモデルを実行するのに苦労するかです。FluidAudioは、推論を**Apple Neural Engine(ANE)**にオフロードする洗練されたSwift SDKを提供することで、これを変え、高速で電力効率が高く、完全にローカルな音声AIを実現します。
SDKは、最先端のオープンソースモデル(MIT/Apache 2.0ライセンス)をバンドルしており、以下を提供します。
- 自動音声認識(ASR) — バッチおよびストリーミング文字起こし
- テキスト読み上げ(TTS) — パラレルおよびストリーミング合成、音声クローン機能付き
- 話者識別 — 会話内の「誰がいつ話したか」を識別
- 音声アクティビティ検出(VAD) — 音声内の音声セグメントを検出
すべてのモデルは事前にCoreMLに変換され、ANE用に最適化されているため、CPUの使用を最小限に抑え、GPU/MPSを完全に回避します。これにより、FluidAudioはバックグラウンド処理、アンビエントコンピューティング、常時稼働のワークロードに最適です。
はじめに:インストール
FluidAudioはSwift Package Managerを介して統合します。Package.swiftに追加します。
dependencies: [
.package(url: "https://github.com/FluidInference/FluidAudio.git", from: "0.12.4"),
],
次に、ターゲットにプロダクトを追加します。
.product(name: "FluidAudio", package: "FluidAudio")
Xcodeでは、File → Add Packagesを使用し、リポジトリURLを貼り付けます。CocoaPodsもpod 'FluidAudio', '~> 0.12.4'でサポートされていますが、メンテナーはより良い統合のためにcocoapods-spmを推奨しています。
コア機能の詳細
1. 自動音声認識(ASR)
FluidAudioのASRは、NVIDIAのParakeet TDTモデルをCoreMLに変換したものを使用しています。2つのバージョンが利用可能です。
- v3: 多言語対応、25のヨーロッパ言語と日本語をサポート
- v2: 英語のみ、最高の再現率に最適化
パフォーマンス: M4 Proでは、バッチ文字起こしのリアルタイムファクターは約190倍で、1時間の音声を約19秒で処理します。ストリーミングはSlidingWindowAsrManagerを介してリアルタイムユースケースでサポートされています。
クイックスタート — バッチ文字起こし:
import FluidAudio
Task {
let models = try await AsrModels.downloadAndLoad(version: .v3)
let asrManager = AsrManager(config: .default)
try await asrManager.loadModels(models)
// `samples`は16kHzの[Float]です
let result = try await asrManager.transcribe(samples)
print("文字起こし: \(result.text)")
}
CLI相当:
swift run fluidaudiocli transcribe audio.wav
swift run fluidaudiocli transcribe audio.wav --model-version v2 # 英語のみ
2. 話者識別
FluidAudioは、それぞれ異なるトレードオフを持つ3つの話者識別パイプラインを提供します。
オフラインパイプライン(Pyannote Community-1)
録音された会議の後処理に最適。パワーセットセグメンテーション + WeSpeaker埋め込み + VBxクラスタリングを使用。高精度ですが、リアルタイム使用には適していません。
let config = OfflineDiarizerConfig()
let manager = OfflineDiarizerManager(config: config)
try await manager.prepareModels()
let samples = try AudioConverter().resampleAudioFile(path: "meeting.wav")
let result = try await manager.process(audio: samples)
for segment in result.segments {
print("\(segment.speakerId) \(segment.startTimeSeconds)s → \(segment.endTimeSeconds)s")
}
LS-EEND(ストリーミング)
CoreMLを使用したエンドツーエンドのニューラル話者識別。最大10人の話者をサポートし、100msのフレーム更新と900msの暫定プレビューを提供。これはオンライン話者識別の推奨デフォルトです。
Sortformer(ストリーミング)
NVIDIAのSortformerモデル。LS-EENDよりも優れた話者識別の安定性を提供しますが、話者は4人に制限されています。NVIDIA Open Model Licenseの下でライセンスされています。
それぞれを使用するタイミング:
- LS-EEND: ライブ話者識別のデフォルト — 高い話者容量、優れたベンチマーク
- Sortformer: 話者数よりも識別の安定性が重要な場合
- Pyannoteパイプライン: セグメンテーションとクラスタリングの段階をモジュール式に制御する必要がある場合
3. 音声アクティビティ検出(VAD)
Silero VADを搭載したFluidAudioの検出器は、オフラインセグメンテーションとストリーミングAPIの両方を提供します。オフラインモードは、256msホップごとにチャンクレベルの確率を返します。
let results = try await manager.process(samples)
for (index, chunk) in results.enumerated() {
print(String(format: "チャンク %02d: 確率=%.3f", index, chunk.probability))
}
より高レベルの統合には、設定可能な最小音声/無音時間でsegmentSpeechを使用します。
var segmentation = VadSegmentationConfig.default
segmentation.minSpeechDuration = 0.25
segmentation.minSilenceDuration = 0.4
let segments = try await manager.segmentSpeech(samples, config: segmentation)
4. テキスト読み上げ(TTS)
FluidAudioには2つのTTSバックエンドが搭載されています。
| 機能 | PocketTTS | Kokoro |
|---|---|---|
| 生成 | フレームごとの自己回帰(80ms) | パラレル(すべてのフレームを一度に) |
| ストリーミング | はい | いいえ |
| 音声クローン | はい(1~30秒のサンプル) | いいえ |
| 発音制御 | いいえ | はい(SSML、カスタム辞書) |
| 言語 | EN, DE, ES, FR, IT, PT | EN, ES, FR, HI, JA, PT, ZH, IT |
PocketTTSの例:
let manager = PocketTtsManager(language: .spanish)
try await manager.initialize()
let audioData = try await manager.synthesize(text: "Hola, mundo.")
try audioData.write(to: URL(fileURLWithPath: "out.wav"))
Kokoroの例(ANE最適化):
let manager = KokoroAneManager()
try await manager.initialize()
let samples = try await manager.synthesize(text: "Hello from FluidAudio.")
// `samples`は24 kHzモノラルFloat32 PCMです
エンタープライズ展開のための設定
FluidAudioはHuggingFaceからのモデルダウンロードを自動的に処理しますが、エンタープライズ環境ではカスタマイズが必要な場合があります。
カスタムモデルレジストリ
ローカルミラーやエアギャップ環境がある場合:
ModelRegistry.baseURL = "https://your-mirror.example.com"
プロキシ設定
企業ファイアウォールの場合:
export https_proxy=http://proxy.company.com:8080
swift run fluidaudiocli transcribe audio.wav
オフライン専用モード
バンドルされたモデルを出荷するプライバシー重視のアプリの場合:
ModelHub.offlineMode = true
let asr = try await AsrModels.load(from: bundledModelURL, configuration: config)
オフラインモードが有効な場合、ネットワークフェッチはダウンロードを試みる代わりにDownloadError.networkDisabledをスローします。
実際の影響:ショーケース
FluidAudioエコシステムは急速に成長しており、SDKを使用する数十のアプリがあります。注目すべき例は次のとおりです。
- Voice Ink: インスタントでプライベートな文字起こしのためのローカルAI
- Spokenly: リアルタイムおよびファイル文字起こしを備えたMac音声入力
- Slipbox: プライバシー第一の会議アシスタント
- Talat: AI会議メモアプリ(TechCrunchで紹介)
- BoltAI: Parakeetモデルを使用したコンテンツ作成
- Hedy: iOS、macOS、Android、Windowsで完全にオンデバイスのリアルタイム会議コーチ
これらのアプリは、FluidAudioが可能にするユースケースの幅広さを示しています。単純な音声入力から複雑な複数話者の会議分析までです。
Apple Neural Engineが重要な理由
FluidAudioがGPU/MPSではなくANEをターゲットにするという決定は意図的です。ANEは以下を提供します。
- 低消費電力: 常時稼働およびバックグラウンドワークロードに最適
- 専用ハードウェア: グラフィックスや計算タスクでGPUと競合しない
- 一貫したパフォーマンス: デバイス世代間で予測可能な推論時間
これにより、FluidAudioは特に以下に適しています。
- バックグラウンドで実行される会議の文字起こし
- バッテリー駆動デバイス上の音声制御インターフェース
- リアルタイムキャプションとアクセシビリティ機能
結論
FluidAudioは、Appleプラットフォーム上のオンデバイス音声AIにとって重要な前進です。最先端のモデルとANE最適化されたCoreML推論を組み合わせることで、以前はクラウドAPIでのみ達成可能だったパフォーマンスを提供し、データをプライベートかつローカルに保ちます。
音声入力アプリ、会議アシスタント、音声制御インターフェースのいずれを構築している場合でも、FluidAudioは最小限のコードでビルディングブロックを提供します。SDKのモジュール設計、包括的なドキュメント、活発なコミュニティにより、個人開発者とエンタープライズチームの両方がアクセスできます。
今すぐ始めましょう: GitHubリポジトリをクローンし、ドキュメントを確認し、Discordコミュニティに参加してサポートと最新情報を入手してください。