Apple平台新增语音与决策开放模型包

介绍 AnySpeechRecognizer 和 AnyDecisionModel:Apple 平台上的语音与决策开放模型

语言模型(LLM)通常被用于写作、总结、翻译或调用工具,但这仅是机器学习应用的一小部分。在实际场景中,例如处理客户支持电话,系统首先需要识别语音内容(语音识别),随后根据内容决定路由策略(决策)。针对这类任务,存在比通用 LLM 更高效、更快速且成本更低的专用模型。

支持Parakeet与Qwen3-ASR本地运行

在回顾 AnyLanguageModel 1.0 时,我们探讨了 Swift 中本地及托管模型一年的发展现状。随着 AnyLanguageModel 和 swift-huggingface 进入 1.x 版本,我们将这一熟悉的 Swift API 模式扩展至语音和决策领域。今日宣布推出两个新软件包:AnySpeechRecognizer 和 AnyDecisionModel。两者均支持从 Hugging Face Hub 下载开放模型并在设备端运行。

  • AnySpeechRecognizer:实现了 Apple 新的语音转文本 API,允许用户选择识别引擎。支持在 Core ML 上本地运行 NVIDIA 的 Parakeet 和阿里巴巴的 Qwen3-ASR,并新增扬声器日记功能以追踪说话人身份。
  • AnyDecisionModel:通过输出类型化结果和概率来回答是/否、多选及评分尺度问题。它直接从模型概率中提取答案而非生成文本,利用设备端的 MLX、Core AI 或 llama.cpp 运行模型。

AnySpeechRecognizer:多引擎语音识别

计算机语音转录已有数十年历史,而近年来技术进展显著。macOS 26 和 iOS 26 推出了 SpeechAnalyzer,这是 Apple 全新的语音到文本 API。开发者可通过添加语音转录器和检测器等模块,向分析器传入文件或音频缓冲区,由应用程序控制下载时机。

尽管该 API 设计精良,但其背后默认仅使用 Apple 自有引擎。AnySpeechRecognizer 保留了相同的 API 结构,但允许用户切换底层引擎:

- import Speech
+ import AnySpeechRecognizer

该软件包模拟了 SpeechAnalyzer、SpeechTranscriber、SpeechDetector 和资产库,默认引擎仍为 Apple 语音框架。若代码遵循共享 API,仅需修改导入语句即可。若要使用 Parakeet,只需更改转录器的创建方式:

let transcriber = SpeechTranscriber(
    model: ParakeetSpeechModel(variant: .v3),
    transcriptionOptions: [],
    reportingOptions: [.volatileResults],
    attributeOptions: [.audioTimeRange]
)

安装资产、运行分析器及读取结果的步骤保持不变。README 提供了完整示例并列出了与 Apple 框架的差异。

支持的模型详解

NVIDIA Parakeet TDT 0.6B v3:可识别 25 种欧洲语言,并能自动检测所听语言。Moondream 对其进行了训练后优化,在多数测量指标中准确率更高。

Parakeet Unified EN 0.6B:NVIDIA 推出的英语专用版本。

上述三种 Parakeet 模型均在包内的 Core ML 运行时上执行,支持文件输入和实时输入,提供波动结果、单词定时及置信度信息。

Qwen3-ASR:阿里巴巴的语音模型,提供 0.6B 和 1.7B 两种尺寸。支持识别 30 种语言和 22 种中文方言(包括普通话、粤语、日语和韩语)。可自动检测语言或手动指定:

let transcriber = SpeechTranscriber(
    model: QwenSpeechModel(variant: .large, language: Locale.Language(identifier: "yue")),
    transcriptionOptions: [],
    reportingOptions: [],
    attributeOptions: []
)

Qwen3-ASR 每段最长 40 秒提供一个最终结果,不支持波动结果、单词时间或置信度。由于其在 GPU 上运行速度较慢于 Parakeet,更适合文件转录而非实时输入。

如需添加其他引擎,需实现 SpeechRecognitionModel 用于配置,以及 SpeechRecognitionExecutor 用于会话管理。仓库中包含一个小型提供者示例,报告占位符文本以帮助起步。

Hugging Face Hub 上的 Core ML 模型

团队将这些模型转换为 Core ML 格式并发布在 Hub 上:

模型名称 Core ML 转换仓库 原始检查点 许可证
TDT 0.6B v3 mattt/-tdt-0.6b-v3-coreml nvidia/parakeet-tdt-0.6b-v3 Creative Commons Attribution 4.0
Ultra /ult-ultra-coreml moondream/ult-ultra Creative Commons Attribution 4.0
Unified EN 0.6B /parakeet-unified-en-0.6b-coreml nvidia/parakeet-unified-en-0.6b NVIDIA Open Model License
Qwen3-ASR 0.6B Other mattt/qwen3-asr-0.6b-coreml Qwen/Qwen3-ASR-0.6B-hf Apache 2.0
Qwen3-ASR 1.7B Other mattt/qwen3-asr-1.7b-coreml Qwen/Qwen3-ASR-1.7B-hf Apache 2.0
Streaming Sortformer 4spk v2 /sortformer-streaming-4spk-v2-coreml nvidia/diar_streaming_sortformer_4spk-v2 Creative Commons Attribution 4.0
Streaming Sortformer 4spk v2.1 /sortformer-streaming-4spk-v2.1-coreml nvidia/diar_streaming_sortformer_4spk-v2.1 NVIDIA Open Model License

每个仓库记录其源检查点和文件校验和,包将固定到特定修订版。Parakeet 仓库添加了一个用于实时输入的 8 秒编码器,这将实时分析时间缩短约三分之一,但代价是文字错误率略有上升。该仓库还包含转换工作流程,大多数遵循 FluidInference 的 mobius 脚本,并与原始模型对比验证每个转换。

下载仅在应用程序请求时发生:每个 Parakeet 模型约 600MB(加上现场编码器约 590MB),Qwen3-ASR 约 0.9 至 2.4GB,Sortformer 约 250MB。文件存储在标准的 Hugging Face 缓存中,因此沙箱外的 Mac 应用可与 Python 及其他 Hugging Face 工具共享缓存。

扬声器日记化(Speaker Diarization)

在录制对话时,确定“谁说了什么”至关重要。Apple 语音框架缺乏此模块,AnySpeechRecognizer 对此进行了补充。SpeakerDiarizer 可与 Apple 或 Parakeet 转录器并行运行,在 Core ML 上使用 NVIDIA 的 Streaming Sortformer:

let diarizer = SpeakerDiarizer(model: SortformerDiarizationModel())
if let request = try await AssetInventory.assetInstallationRequest(
    supporting: [transcriber, diarizer]
) {
    try await request.downloadAndInstall()
}
let analyzer = SpeechAnalyzer(modules: [transcriber, diarizer])

日记化器可追踪多达四个扬声器,即使他们同时说话。时间线收集结果并将每个单词归因于特定演讲者,从而按轮次打印成绩单。这超出了 Apple API 目前提供的范围。

默认使用 Sortformer v2。也可选择 v2.1 版本,NVIDIA 使用更多会议数据进行训练,在测试中准确率更高。

性能评估

在 M4 Max Mac Studio 上,使用命令行工具对 3 到 8 分钟的 LibriSpeech 文件进行了单词错误率(WER)测量:

转录器 test-clean test-other
Parakeet v3 (文件) 1.55% 2.78%
Parakeet v3 (实时) 4.73% 4.29%
Parakeet Ultra (文件) 1.66% 2.55%
Parakeet Ultra (实时) 2.65% 3.28%
Parakeet Unified (文件) 1.43% 2.19%
Parakeet Unified (实时) 1.45% 2.42%
Apple 转录器 (文件) 2.12% 3.97%

Parakeet 从文件中转录一小时音频大约需要 20 到 40 秒,实时转录则需要 1.5 到 2.5 分钟。一旦 Core ML 编译完模型,内存占用约为 100 MB。Qwen3-ASR 速度慢得多,且需要数 GB 内存。对于多人交谈的会议录音(如 AMI 数据集),所有测试引擎的单词错误率均超过 23%。

上述数据源自单台机器和少量数据集,建议用户在自有硬件和音频上进行测量。hear evaluate 命令可用于自己的文件,仓库中的 natural-speech-eval.py 工具可复现这些测量结果。目前仅在 macOS 27 上进行了测试,尚未在 iPhone 上验证。

下一步计划添加更多引擎,包括 macOS 27 和 iOS 27 上的 Core AI。

AnyDecisionModel:基于概率的结构化决策

AnyDecisionModel 的情况有所不同。没有对应的 Apple 框架可供映射,且决策模型本身并非全新概念。所谓“决策模型”,实质上是经过专门训练以做出判断的零样本分类模型。新之处在于 Swift API 的设计,旨在适应这一趋势。

应用程序常要求语言模型做出决策,例如:“这条消息紧急吗?”、“哪个团队应处理此工单?”、“客户有多沮丧?”。通常的做法是提示 LLM 并解析生成的文本。这种方法只能给出一个答案,却无法展示分配给各个选项的概率。

以下是 Swift 中的决策示例:

import AnyDecisionModel

enum Department: String, Choosable {
    case billing, technical, sales
}

let ticket = "I was charged twice for my order, and now the app logs me out when I try to ask for a refund."

let model = MLXDecisionModel(modelID: "mlx-community/Qwen3-4B-Instruct-2507-4bit")
let session = DecisionSession(model: model, state: .text(ticket))

let urgent = try await session.probability(of: "Does this convey urgency?")
let team = try await session.choice("Which team?", from: Department.self)
let anger = try await session.score(
    "How frustrated?",
    levels: ["Calm", "Frustrated", "Very angry"]
)

urgent 是一个 Double。team 是一个 Choice<Department>,包含选定的案例、每个选项的概率及置信度值。anger 是一个 Score,包含预期级别、每个级别的概率及置信度值。由于 Department 符合 Choosable 协议,team.value 返回一个可在详尽 switch 中使用的 Department 枚举值。

如果使用过 Foundation Models 或 AnyLanguageModel,这种“模型与会话”的模式会很熟悉。DecisionSession 持有单一状态(文本或 JSON),所有问题均针对该状态。问题是独立的:答案不会成为后续问题的输入。若要同时提出多个问题,可将它们作为批次传递给 decide(_:)。

对于每个问题,MLX 后端构建一个带有每个允许答案的单令牌标签的提示词,然后从一次前向传播中读取每个标签的概率。

演示应用:Emoji Magnet

Emoji Magnet 是一款 macOS 应用,文本字段上方堆叠着 343 个 emoji。输入短语(如“你穿的东西”),匹配的 emoji 会从堆中升起;细化为“冬天穿的东西”,不再匹配的 emoji 则落下。

该应用没有内置关键词规则,一切由模型在推理时决定。当用户停止输入时,它对每个 emoji 询问一个是/否问题,例如:

Statement: a heavy winter coat fits the description "things you wear". Is this statement true?

会话状态持有该短语。演示中使用托管的 Jev 后端,在一次请求中回答所有 343 个问题,因此 emoji 在半秒内稳定下来。若无 TYPESAFE_AI_API_KEY,应用则在 Mac 上使用 MLX 后端运行 Qwen3 4B。该后端使用前缀缓存评估状态,每次前向传播回答 16 个问题。在 M4 Max 上,加载模型后每组 16 个问题耗时约 0.45 秒。遍历所有 343 个 emoji 的全流程约需 10 秒,各组结果随到达即显示。

Emoji Magnet 位于 AnyDecisionModel-Examples 仓库中。

决策头与 Clef 模型

读取下一令牌概率适用于通用语言模型,但这些模型并非专为决策训练。Cloudflare 的 Clef 模型代表了一种新方法:模型拥有训练好的决策头,将状态和类型化问题模式转化为决策,在一次前向传播中返回所有允许选项的概率。Clef-Flash 是其中的 9B 变体。

AnyDecisionModel 可在 Mac 上使用 MLX 运行 Clef-Flash:

let model = MLXHeadDecisionModel(
    modelID: "mlx-community/clef-flash-4bit",
    head: .jointSchema
)

使用相同的会话和问题,但 MLXHeadDecisionModel 从 Clef 的训练决策头读取决策,而非下一令牌概率。4-bit 模型下载大小为 6.2 GB,模型卡推荐至少 16 GB 内存的 Mac。虽然 Clef 可读图像和视频,但该后端仅接受文本和 JSON 状态。

概率校准与去偏

语言模型的原始概率往往过度自信。本地后端接受 Calibration 参数,对所有答案应用温度,并对是/否答案应用偏差。建议使用独立的数据集来拟合校准并评估结果。

此外,语言模型可能因选项在列表中的位置而产生偏好。在 MLX、Core AI 和 llama.cpp 的下一令牌后端中,启用 rotationDebiasing 以轮换提问顺序,从而消除位置偏差。

评论 0

0/500

评论需审核后展示,请文明发言

💬
还没有评论,来说两句

相关阅读