Problem
Original text:
「還有就是最新的蘋果內建的語音辨識也要拿進來比較吧」
— Source: 2026-07-31 與 Claude 的對話(承 #110 的 backend 擴充討論)
bestASR 定位是 Apple Silicon-first 的本機 ASR 比較器,目前 6 個 backend(whisperkit / whisper.cpp / fluid-parakeet / fluid-paraformer / fluid-sensevoice / mlx-audio)全部是第三方——唯獨缺了每台 Mac 都自帶、零安裝零下載的那個:Apple 自己的 Speech framework。
這個缺口在比較意義上不小:Apple 內建 ASR 是所有其他 backend 的天然對照基線(使用者已經有了,不裝任何東西就能用)。沒有它,grid 回答不了「花力氣裝 WhisperKit / Parakeet 到底比系統內建好多少」這個最實際的問題。
Type
feature
Expected
把 Apple 內建語音辨識接成第七個 backend,納入既有的 benchmark 矩陣(bestasr benchmark / release sweep / bench leaderboard)。
已查證的事實(本機 SDK introspection,非記憶)
環境:macOS 27.0 / Xcode 26.6,SDK MacOSX.sdk。以下取自
Speech.framework/.../arm64e-apple-macos.swiftinterface 與 ObjC headers:
新 API(macOS 26 起,即使用者說的「最新版」)
| 型別 |
宣告 |
availability |
SpeechAnalyzer |
final public actor SpeechAnalyzer : Sendable |
@available(macOS 26.0, iOS 26.0, visionOS 26.0, tvOS 26.0, *) |
SpeechTranscriber |
final public class SpeechTranscriber : SpeechModule, LocaleDependentSpeechModule |
macOS 26.0+ |
DictationTranscriber |
final public class DictationTranscriber : SpeechModule, LocaleDependentSpeechModule |
macOS 26.0+(tvOS unavailable) |
相關面:SpeechDetector、AssetInventory、AnalyzerInput、ContentHint、
SpeechModels、ModelRetention、SensitivityLevel、TranscriptionOption。
三件對 bestASR 直接相關的能力,SDK 已確認存在
- Locale 可查詢(決定 en/ja/zh 語料能不能測):
SpeechTranscriber.supportedLocales(static var ... { get async })、
installedLocales、reservedLocales。
- 模型資產要下載(跟 WhisperKit / Parakeet 同樣有 cold-start 成本):
AssetInventory.assetInstallationRequest(supporting modules:) async throws -> AssetInstallationRequest?
→ AssetInstallationRequest.downloadAndInstall() async throws(含
ProgressReporting);另有 reserve(locale:) / release(reservedLocale:)。
- 時間戳 + 信心值都有(對得上 bestASR 的 segment / confidence 需求):
audioTimeRange(CoreMedia.CMTimeRange)、transcriptionConfidence
(ConfidenceAttribute)。
舊 API:SFSpeechRecognizer(ObjC,headers 仍在 SDK)——
grep API_DEPRECATED 於 SFSpeechRecognizer.h 無命中,尚未標記 deprecated。
⚠️ 雲端 vs 端上:舊 API 預設走網路(condition 污染風險)
「Apple 有沒有免費雲端 API」的查證結果——沒有一般意義的公開雲端 ASR endpoint
(不像 OpenAI / Google 那種拿 key 就能打的服務);但舊 API 內建一條 server-backed
路徑,且預設啟用:
| 事實(逐字取自 SDK headers) |
出處 |
@property (nonatomic) BOOL requiresOnDeviceRecognition API_AVAILABLE(ios(13), macos(10.15)); — 預設 false |
SFSpeechRecognitionRequest.h:65 |
「Set this property to true to prevent an SFSpeechRecognitionRequest from sending audio over the network. However, on-device requests won't be as accurate.」 |
SFSpeechRecognitionRequest.h(doc comment) |
「If supportsOnDeviceRecognition is false, the SFSpeechRecognizer requires a network in order to recognize speech.」 |
SFSpeechRecognizer.h:162 |
新 API 則是純端上:對整份 Speech.swiftinterface grep
onDevice|server|cloud|network|remote → 零命中,SpeechAnalyzer /
SpeechTranscriber 不提供 server 選項。
對本 issue 的直接後果:
- 走新 API → 純端上,與其他 6 個 backend 同 condition,可直接排進同一個 ranking。
- 走舊 API → 必須顯式設
requiresOnDeviceRecognition = true,否則量到的是
Apple 伺服器的成績。把雲端數字混進「本機 ASR 比較」的 leaderboard 是
condition 污染(同 common-ocr-toolchain-freshness 例外 2 的紀律:不同 condition
的 row 不可排同一個 ranking)。Apple 自陳 on-device「won't be as accurate」,
代表這兩條路徑的成績本來就不同,更不能混。
- 若之後真要量雲端路徑,它是另一個 condition(需獨立標記,甚至獨立 backend id),
不是同一個 backend 的另一組數字。
未查證、留給 diagnose:server-backed 路徑的免費額度 / 時長上限 / throttling
(Apple 歷來對此有限制,但本次 SDK introspection 看不到,需查官方文檔或實測)。
Actual
BackendID enum(Sources/BestASRKit/Models/DataModels.swift:9)與
ModelGrid backend 常數(ModelGrid.swift:12-17)都沒有 Apple 項;
Sources/BestASRKit/Engines/ 下無對應 engine。
Impact
需要在 diagnose 階段決定的事(不在此處預判)
- 接哪一個 API? 新
SpeechAnalyzer + SpeechTranscriber(macOS 26+,純端上、
condition 乾淨)/ 舊 SFSpeechRecognizer(可跑到現行 deployment target,但必須
強制 requiresOnDeviceRecognition = true,見上方雲端警示)/ 兩者都接當成兩個
backend row(新舊對照本身就有比較價值)。
傾向:優先新 API——純端上不需額外把關,且是使用者說的「最新版」。
- Deployment target 衝突怎麼處理(關鍵約束):
Package.swift 目前是
platforms: [.macOS(.v14)],而新 API 要 macOS 26。選項:@available(macOS 26, *)
gating + isAvailable() 在舊系統回 false(與既有 Engine protocol 的
「Availability detection is graceful,never throws」契約天然吻合)、或抬高整包
deployment target(影響所有使用者,代價大)。
- en / ja / zh 三語料是否都支援——需 runtime 查
supportedLocales,不能從文件假設。
- ModelGrid row 怎麼表達:Apple 沒有一般意義的 model size / quantization 軸,
grid schema(family / size / quantization)要怎麼填才誠實。
- 模型下載計入哪裡:
AssetInventory 的 download 成本要不要算進 warmup,
與其他 backend 的 cold-start 量測如何可比。
時機
P2。與 #110(FluidAudio 0.15.5 + Parakeet Unified/TDT-ja 納入評估)同屬
「擴充比較矩陣」這條線,但互相獨立:本 issue 零新依賴、不受 #110 的 pin bump
阻擋,可平行進行。
Source: surfaced during 2026-07-31 conversation following the #110 decomposition
discussion;API 事實由本機 SDK introspection 查證(xcrun --show-sdk-path →
Speech.framework swiftinterface + headers),非模型記憶。
Current Status
- Phase: diagnosed
- Last update: 2026-07-31
Problem
bestASR 定位是 Apple Silicon-first 的本機 ASR 比較器,目前 6 個 backend(
whisperkit/whisper.cpp/fluid-parakeet/fluid-paraformer/fluid-sensevoice/mlx-audio)全部是第三方——唯獨缺了每台 Mac 都自帶、零安裝零下載的那個:Apple 自己的 Speech framework。這個缺口在比較意義上不小:Apple 內建 ASR 是所有其他 backend 的天然對照基線(使用者已經有了,不裝任何東西就能用)。沒有它,grid 回答不了「花力氣裝 WhisperKit / Parakeet 到底比系統內建好多少」這個最實際的問題。
Type
feature
Expected
把 Apple 內建語音辨識接成第七個 backend,納入既有的 benchmark 矩陣(
bestasr benchmark/ release sweep / bench leaderboard)。已查證的事實(本機 SDK introspection,非記憶)
環境:macOS 27.0 / Xcode 26.6,SDK
MacOSX.sdk。以下取自Speech.framework/.../arm64e-apple-macos.swiftinterface與 ObjC headers:新 API(macOS 26 起,即使用者說的「最新版」)
SpeechAnalyzerfinal public actor SpeechAnalyzer : Sendable@available(macOS 26.0, iOS 26.0, visionOS 26.0, tvOS 26.0, *)SpeechTranscriberfinal public class SpeechTranscriber : SpeechModule, LocaleDependentSpeechModulemacOS 26.0+DictationTranscriberfinal public class DictationTranscriber : SpeechModule, LocaleDependentSpeechModulemacOS 26.0+(tvOS unavailable)相關面:
SpeechDetector、AssetInventory、AnalyzerInput、ContentHint、SpeechModels、ModelRetention、SensitivityLevel、TranscriptionOption。三件對 bestASR 直接相關的能力,SDK 已確認存在
SpeechTranscriber.supportedLocales(static var ... { get async })、installedLocales、reservedLocales。AssetInventory.assetInstallationRequest(supporting modules:) async throws -> AssetInstallationRequest?→
AssetInstallationRequest.downloadAndInstall() async throws(含ProgressReporting);另有reserve(locale:)/release(reservedLocale:)。audioTimeRange(CoreMedia.CMTimeRange)、transcriptionConfidence(
ConfidenceAttribute)。舊 API:
SFSpeechRecognizer(ObjC,headers 仍在 SDK)——grep API_DEPRECATED於SFSpeechRecognizer.h無命中,尚未標記 deprecated。「Apple 有沒有免費雲端 API」的查證結果——沒有一般意義的公開雲端 ASR endpoint
(不像 OpenAI / Google 那種拿 key 就能打的服務);但舊 API 內建一條 server-backed
路徑,且預設啟用:
@property (nonatomic) BOOL requiresOnDeviceRecognition API_AVAILABLE(ios(13), macos(10.15));— 預設falseSFSpeechRecognitionRequest.h:65trueto prevent anSFSpeechRecognitionRequestfrom sending audio over the network. However, on-device requests won't be as accurate.」SFSpeechRecognitionRequest.h(doc comment)supportsOnDeviceRecognitionisfalse, theSFSpeechRecognizerrequires a network in order to recognize speech.」SFSpeechRecognizer.h:162新 API 則是純端上:對整份
Speech.swiftinterfacegreponDevice|server|cloud|network|remote→ 零命中,SpeechAnalyzer/SpeechTranscriber不提供 server 選項。對本 issue 的直接後果:
requiresOnDeviceRecognition = true,否則量到的是Apple 伺服器的成績。把雲端數字混進「本機 ASR 比較」的 leaderboard 是
condition 污染(同
common-ocr-toolchain-freshness例外 2 的紀律:不同 condition的 row 不可排同一個 ranking)。Apple 自陳 on-device「won't be as accurate」,
代表這兩條路徑的成績本來就不同,更不能混。
不是同一個 backend 的另一組數字。
未查證、留給 diagnose:server-backed 路徑的免費額度 / 時長上限 / throttling
(Apple 歷來對此有限制,但本次 SDK introspection 看不到,需查官方文檔或實測)。
Actual
BackendIDenum(Sources/BestASRKit/Models/DataModels.swift:9)與ModelGridbackend 常數(ModelGrid.swift:12-17)都沒有 Apple 項;Sources/BestASRKit/Engines/下無對應 engine。Impact
Sources/BestASRKit/Engines/一個 engine(Engineprotocol 只要id/isAvailable()/transcribeRaw(),見Engines/Engine.swift:61)、BackendID新 case、ModelGridrows、ModelRegistry記憶體估計、測試。bestasr benchmark/ release sweep(measureASR:release 全矩陣 deterministic sweep(pin 版本下每個模型的表現快照) #109)/ benchleaderboard;量測 row 會帶 measurement schema 增 run_kind / decode-determinism provenance 欄位(follow-up from #109 verify) #111 剛加的
run_kind/decode_deterministicprovenance(Apple 不消費
--decode-deterministic→ 依 measurement schema 增 run_kind / decode-determinism provenance 欄位(follow-up from #109 verify) #111 的誠實三態記null)。需要在 diagnose 階段決定的事(不在此處預判)
SpeechAnalyzer+SpeechTranscriber(macOS 26+,純端上、condition 乾淨)/ 舊
SFSpeechRecognizer(可跑到現行 deployment target,但必須強制
requiresOnDeviceRecognition = true,見上方雲端警示)/ 兩者都接當成兩個backend row(新舊對照本身就有比較價值)。
傾向:優先新 API——純端上不需額外把關,且是使用者說的「最新版」。
Package.swift目前是platforms: [.macOS(.v14)],而新 API 要 macOS 26。選項:@available(macOS 26, *)gating +
isAvailable()在舊系統回false(與既有Engineprotocol 的「Availability detection is graceful,never throws」契約天然吻合)、或抬高整包
deployment target(影響所有使用者,代價大)。
supportedLocales,不能從文件假設。grid schema(
family/size/quantization)要怎麼填才誠實。AssetInventory的 download 成本要不要算進 warmup,與其他 backend 的 cold-start 量測如何可比。
時機
P2。與 #110(FluidAudio 0.15.5 + Parakeet Unified/TDT-ja 納入評估)同屬
「擴充比較矩陣」這條線,但互相獨立:本 issue 零新依賴、不受 #110 的 pin bump
阻擋,可平行進行。
Source: surfaced during 2026-07-31 conversation following the #110 decomposition
discussion;API 事實由本機 SDK introspection 查證(
xcrun --show-sdk-path→Speech.frameworkswiftinterface + headers),非模型記憶。Current Status