Sakhanda Wire
NVDA $213.12 -1.05% MSFT $530.92 -0.02% GOOGL $283.33 -12.79% META $618.93 +1.05% AMZN $244.91 -3.81%
← К новостям

Представляем AnySpeechRecognizer и AnyDecisionModel: открытые модели для речи и принятия решений на платформах Apple

Представляем AnySpeechRecognizer и AnyDecisionModel: открытые модели для речи и принятия решений на платформах Apple
Опубликовано 29 октября 2026 года
Обновить на GitHub

Языковые модели умеют многое. Они пишут, суммируют, переводят и вызывают инструменты. Но это лишь малая часть того, на что способно машинное обучение.

Представьте, что клиент звонит в службу поддержки. Сначала нужно понять, что он сказал (распознавание речи). Затем нужно решить, куда его направить (принятие решения). Вы можете поручить обе задачи языковой модели, но существуют модели, созданные специально для каждой из них: они лучше, быстрее и дешевле.

В нашем обзоре AnyLanguageModel 1.0 мы рассмотрели год локальных и размещённых моделей в Swift. Теперь, когда AnyLanguageModel и swift-huggingface выпустили версии 1.x, мы применяем тот же подход к речи и принятию решений: знакомые API Swift с возможностью выбора модели.

Сегодня мы представляем два пакета:

  • AnySpeechRecognizer реализует новый API Apple для преобразования речи в текст с возможностью выбора движка распознавания, включая Parakeet от NVIDIA и Qwen3-ASR от Alibaba, работающие локально на Core ML, а также добавляет диаризацию говорящих, чтобы отслеживать, кто и когда говорит.
  • AnyDecisionModel отвечает на вопросы с ответами «да» или «нет», вопросы с вариантами ответа и вопросы со шкалой оценок, возвращая типизированные результаты и вероятности. Каждый ответ вычисляется на основе вероятностей модели, а не генерируется как текст, с использованием модели на устройстве через MLX, Core AI или llama.cpp, либо модели принятия решений от Jev или Ollama.

Оба пакета могут загружать открытые модели из Hugging Face Hub и запускать их на устройстве.

AnySpeechRecognizer

Компьютеры расшифровывают речь уже несколько десятилетий, и за последние несколько лет научились делать это очень хорошо. На платформах Apple для этого уже есть API. В macOS 26 и iOS 26 появился SpeechAnalyzer, новый API Apple для преобразования речи в текст. Вы добавляете в анализатор такие модули, как SpeechTranscriber и SpeechDetector, передаёте ему файл или поток аудиобуферов и читаете результаты из асинхронных последовательностей по мере их поступления. Компонент AssetInventory устанавливает модели, так что приложение само решает, когда выполнять загрузку.

Это хорошо спроектированный API, но за ним стоит только движок Apple. AnySpeechRecognizer сохраняет API и позволяет выбирать движок:

- import Speech
+ import AnySpeechRecognizer

Пакет повторяет интерфейсы SpeechAnalyzer, SpeechTranscriber, DictationTranscriber, SpeechDetector и AssetInventory, используя Speech framework Apple в качестве движка по умолчанию. Если ваш код использует этот общий API, достаточно изменить импорт. Чтобы использовать Parakeet, измените только способ создания транскрибатора:

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

Шаги установки ресурсов, запуска анализатора и чтения результатов остаются теми же. В README есть полный пример, а также перечислены отличия от фреймворка Apple.

Знакомство с моделями

Parakeet v3 — это Parakeet TDT 0.6B v3 от NVIDIA. Это полиглот: модель распознаёт 25 европейских языков и сама определяет, какой из них слышит, поэтому передавать локаль не нужно.

Parakeet Ultra — это дообученная версия v3 от Moondream. В большинстве наших измерений она была точнее.

Parakeet Unified — это англоязычная версия Parakeet от NVIDIA.

Все три модели Parakeet работают в собственном средстве выполнения Core ML пакета, которое поддерживает файловый и потоковый ввод, изменяемые результаты, временные метки слов и уверенность распознавания слов.

Qwen3-ASR — речевая модель Alibaba размером 0,6B и 1,7B. Она распознаёт 30 языков и 22 китайских диалекта, включая путунхуа, кантонский, японский и корейский, которые не поддерживает Parakeet. Язык определяется автоматически, но его можно задать вручную:

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

Qwen3-ASR выдаёт один итоговый результат для каждого сегмента длиной до 40 секунд, без промежуточных результатов, временных меток слов и оценки уверенности. Модель работает на GPU и медленнее Parakeet, поэтому лучше подходит для расшифровки файлов, чем для потокового ввода.

Чтобы добавить другой движок, реализуйте SpeechRecognitionModel для его конфигурации и SpeechRecognitionExecutor для сессии одного модуля. В README есть небольшой провайдер, возвращающий текст-заполнитель, который поможет начать работу.

Модели Core ML на Hub

Чтобы запускать эти модели в приложениях, мы преобразовали их в Core ML и опубликовали на Hub:

Модель Преобразование в Core ML Исходная контрольная точка Лицензия
Parakeet TDT 0.6B v3 mattt/parakeet-tdt-0.6b-v3-coreml nvidia/parakeet-tdt-0.6b-v3 CC BY 4.0
Parakeet Ultra mattt/parakeet-ultra-coreml moondream/parakeet-ultra CC BY 4.0
Parakeet Unified EN 0.6B mattt/parakeet-unified-en-0.6b-coreml nvidia/parakeet-unified-en-0.6b Открытая лицензия NVIDIA на модели
Qwen3-ASR 0.6B mattt/qwen3-asr-0.6b-coreml Qwen/Qwen3-ASR-0.6B-hf Apache 2.0
Qwen3-ASR 1.7B mattt/qwen3-asr-1.7b-coreml Qwen/Qwen3-ASR-1.7B-hf Apache 2.0
Streaming Sortformer 4spk v2 mattt/diar-streaming-sortformer-4spk-v2-coreml nvidia/diar_streaming_sortformer_4spk-v2 CC BY 4.0
Streaming Sortformer 4spk v2.1 mattt/diar-streaming-sortformer-4spk-v2.1-coreml nvidia/diar_streaming_sortformer_4spk-v2.1 Открытая лицензия NVIDIA на модели

В каждом репозитории указана исходная контрольная точка и контрольная сумма каждого файла, а пакет фиксирует конкретную ревизию. В репозитории Parakeet добавлен энкодер длительностью 8 секунд для потокового ввода, что примерно на треть сокращает время анализа в реальном времени, но несколько повышает частоту ошибок в словах. В репозитории также находятся рабочие процессы преобразования, большинство из которых следуют скриптам mobius от FluidInference, и каждая конверсия проверяется на соответствие исходной модели.

Загрузка выполняется только по запросу приложения: около 600 МБ для каждой модели Parakeet плюс около 590 МБ для потокового энкодера, от 0,9 до 2,4 ГБ для Qwen3-ASR и около 250 МБ для Sortformer. Файлы помещаются в стандартный кэш Hugging Face, поэтому приложение для Mac за пределами песочницы использует их совместно с Python и другими инструментами Hugging Face.

Диаризация говорящих

При расшифровке разговора часто нужно знать, кто что сказал. Это и есть диаризация говорящих, а Speech framework Apple не содержит соответствующего модуля, поэтому AnySpeechRecognizer добавляет его. SpeakerDiarizer запускает Streaming Sortformer от NVIDIA на Core ML параллельно с транскрибатором Apple или Parakeet, используя единую временную шкалу:

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])

Диаризатор отслеживает до четырёх говорящих, даже когда они говорят одновременно. Компонент SpeakerTimeline собирает результаты и связывает каждое слово с временной меткой с соответствующим говорящим, так что транскрипцию можно вывести по очереди выступления. Как и поддержка изображений в AnyLanguageModel, эта возможность выходит за рамки того, что сегодня предлагает API Apple.

По умолчанию диаризатор использует Sortformer v2. Также можно выбрать v2.1, обученную NVIDIA на большем объёме данных встреч; по нашим измерениям, на встречах она также была точнее.

Насколько хорошо это работает?

Мы измерили работу пакета с помощью его инструмента командной строки hear на Mac Studio с M4 Max под управлением macOS 27.0.1. Ниже приведены показатели ошибок в словах для файлов LibriSpeech длительностью от 3 до 8 минут:

Транскрибатор 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 минуты в потоковом режиме, используя около 100 МБ памяти после компиляции модели Core ML. Qwen3-ASR значительно медленнее и требует несколько гигабайт памяти. Встречи сложны для всех: в записях AMI, где участники говорят одновременно, частота ошибок в словах у каждого протестированного движка превышала 23%.

Эти показатели получены на одной машине и на нескольких наборах данных, поэтому измеряйте производительность на собственном оборудовании и аудио. hear evaluate работает с вашими файлами, а инструмент natural-speech-eval.py из репозитория воспроизводит эти измерения. Пока мы тестировали только macOS 27, но не iPhone.

Далее мы хотели бы добавить другие движки, включая Core AI в macOS 27 и iOS 27.

AnyDecisionModel

С AnyDecisionModel всё иначе. Здесь нет фреймворка Apple, на который можно было бы опереться, и модели принятия решений, строго говоря, не являются чем-то новым.

Это модель принятия решений только в том случае, если она родом из французского региона Дезисьон; в противном случае это просто классификация с нулевым обучением в блестящей упаковке.

Новыми являются название, большое количество шумихи и появление моделей, обученных принимать решения. Мы считаем, что за этим будущее, поэтому хотели создать готовый к ним API Swift.

Приложения часто поручают языковым моделям принимать решения. Срочно ли это сообщение? Какая команда должна обработать эту заявку? Насколько раздражён этот клиент? Обычно языковой модели предлагают запрос, а затем разбирают сгенерированный ею текст. Это даёт один ответ, но не показывает вероятности, присвоенные альтернативным вариантам.

Вот как выглядит принятие решения в 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 является значением Department, которое можно использовать в полном switch.

Если вы работали с Foundation Models или AnyLanguageModel, шаблон «модель и сессия» покажется знакомым. DecisionSession хранит одно состояние — текстовое или JSON, и каждый вопрос относится к этому состоянию. Вопросы независимы: ответ никогда не становится входными данными для последующего вопроса. Чтобы задать несколько вопросов одновременно, передайте их в decide(_:) одним пакетом.

Для каждого вопроса бэкенд MLX создаёт запрос с однозначным токеном-меткой для каждого разрешённого ответа, а затем считывает вероятность каждой метки за один прямой проход.

Попробуйте: Emoji Magnet

Emoji Magnet — приложение для macOS с текстовым полем над кучей из 343 эмодзи. Введите фразу, например «то, что вы носите», и подходящие эмодзи поднимутся из кучи. Уточните запрос до «то, что вы носите зимой», и эмодзи, которые больше не подходят, опустятся обратно.

В приложении нет встроенных правил по ключевым словам; модель принимает все решения во время вывода. Когда вы перестаёте печатать, приложение задаёт модели по одному вопросу «да» или «нет» для каждого эмодзи, например:

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

Состояние сессии содержит фразу. В приведённой демонстрации используется размещённый бэкенд Jev, который отвечает на все 343 вопроса одним запросом, поэтому эмодзи выстраиваются примерно за полсекунды для каждой фразы. Без TYPESAFE_AI_API_KEY приложение запускает Qwen3 4B на вашем Mac с бэкендом MLX. Этот бэкенд использует кэширование префикса, чтобы один раз вычислить состояние, а затем обрабатывает по 16 вопросов за прямой проход. На M4 Max группа из 16 вопросов занимает около 0,45 секунды после загрузки модели. Полный проход по всем 343 эмодзи занимает около 10 секунд, а результаты каждой группы появляются сразу после их получения.

Emoji Magnet находится в репозитории AnyDecisionModel-Examples.

Головки принятия решений и Clef

Считывание вероятностей следующего токена работает с языковыми моделями общего назначения, но эти модели не обучались принимать решения. Модели Clef от Cloudflare показывают более новый подход: модель с обученной головкой принятия решений, которая преобразует состояние и схему типизированных вопросов в решения, возвращая вероятности всех разрешённых вариантов по всем вопросам за один прямой проход. Clef-Flash — вариант на 9B.

AnyDecisionModel запускает Clef-Flash на Mac с помощью MLX:

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

Вы используете те же сессии и вопросы, но MLXHeadDecisionModel считывает каждое решение из обученной головки решений Clef, а не из вероятностей следующего токена. 4-битная модель занимает 6,2 ГБ, а в карточке модели рекомендуется Mac минимум с 16 ГБ памяти. Clef умеет обрабатывать изображения и видео, но этот бэкенд принимает только текстовые и JSON-состояния.

Калибровка и проверка вероятностей

Необработанные вероятности языковых моделей часто бывают чрезмерно уверенными. Локальные бэкенды принимают объект Calibration, который применяет температуру к каждому ответу и смещение к ответам «да» или «нет». Для настройки калибровки и оценки результатов используйте разные наборы данных.

Языковые модели также могут предпочитать вариант из-за его положения в списке. В бэкендах следующего токена MLX, Core AI и llama.cpp включите rotationDebiasing, чтобы задать вопрос с вариантами по одному разу для каждой перестановки вариантов и усреднить вероятности. Это требует одной оценки запроса для каждой перестановки.

Каждый локальный выбор и оценка также включают значение уверенности, основанное на энтропии вероятностей. Оно измеряет концентрацию вероятностей, а не правильность ответа, поэтому прежде чем выбирать порог, проверьте частоту ошибок на собственных данных. Диагностика бэкендов следующего токена показывает, какую долю вероятности модель присвоила разрешённым ответам. Низкое значение означает, что большая часть вероятности была отнесена к другим вариантам.

Бэкенды

AnyDecisionModel имеет шесть бэкендов:

  • MLX запускает небольшую языковую модель на Apple silicon с помощью mlx-swift-lm и загружает её с Hub.
  • Головки решений MLX запускают модель с собственной обученной головкой решений, например Clef.
  • Core AI делает то же, что и MLX, но с моделью Core AI на macOS 27 и iOS 27.
  • llama.cpp считывает решения из локальной модели GGUF через llama.swift.
  • Jev обращается к Jev от TypeSafe через System One API или к любому серверу, который его реализует, например к Kev.
  • Ollama обращается к модели принятия решений System One на локальном сервере Ollama или в облаке Ollama. Требуется Ollama версии 0.35.0 или новее, а для облачных моделей — версии 0.40.5 или новее.

Бэкенды следующего токена обозначают ответы «yes» и «no», буквами от A до Z или цифрами от 0 до 9, поэтому вопрос с вариантами может содержать не более 26 вариантов, а оценка — не более 10 уровней. У головок решений такого ограничения нет.

Как и AnyLanguageModel, пакет использует возможности пакетов Swift. Без них пакет не имеет сторонних зависимостей. Вы получаете основные типы, а также бэкенды Jev и Ollama, которые также собираются в Linux. Для локальных бэкендов включите возможность MLX, CoreAI или Llama.

Начало работы

Для обоих пакетов требуется Swift 6.2 или новее, а также macOS 26 или iOS 26 или новее. Среда выполнения Parakeet и Sortformer, а также бэкенд MLX требуют Apple silicon. Задачи сборки MLX в AnyDecisionModel используют Xcode со Swift 6.4 или новее и набор инструментов Metal; для Core AI требуются Xcode 27 и среда выполнения ОС 27.

Добавьте пакеты в свой Package.swift:

dependencies: [
    .package(url: "https://github.com/mattt/AnySpeechRecognizer", from: "0.1.0"),
    .package(
        url: "https://github.com/mattt/AnyDecisionModel",
        from: "0.6.0",
        traits: ["MLX"]
    ),
]

Пока возможность CoreAI в AnyDecisionModel нельзя использовать вместе с AnySpeechRecognizer, поскольку coreai-kit 0.7.3 требует swift-huggingface версии ниже 1.0, а AnySpeechRecognizer требует версию 1.x.

В каждом README есть дополнительные примеры и подробности о требованиях и бэкендах. AnySpeechRecognizer также включает инструмент командной строки hear, который расшифровывает локальные файлы, определяет говорящих и оценивает результаты. Для каждой команды hear требуется --backend apple, --backend parakeet или --backend qwen; перед анализом выполните hear prepare с теми же параметрами бэкенда и модели, чтобы установить необходимые ресурсы.

Попробуйте пакеты в своих приложениях и расскажите нам, что работает, а что нет. Мы приветствуем сообщения об ошибках и запросы на включение изменений в обоих репозиториях.

Ссылки

Спасибо NVIDIA за Parakeet, Sortformer и NeMo, Moondream за Parakeet Ultra, FluidInference, чьи проекты FluidAudio и mobius задокументировали соглашения, которым следуют среда выполнения Parakeet и преобразования в Core ML, Cloudflare за Clef, а также всем, кто внёс вклад в AnyLanguageModel, чьи шаблоны используют оба пакета.

Модели, упомянутые в этой статье 10

Сообщество

Загружайте изображения, аудио и видео, перетаскивая их в текстовое поле, вставляя или нажимая здесь.
Нажмите или вставьте сюда, чтобы загрузить изображения

· Зарегистрируйтесь или войдите, чтобы оставить комментарий

Модели, упомянутые в этой статье 10

Переведено автоматически с английского. Оригинал статьи — по ссылке ниже.

Впервые опубликовано изданием Hugging Face

Читать оригинал на Hugging Face ↗

Текст и изображения принадлежат Hugging Face и приводятся здесь с указанием авторства и ссылкой на оригинальную публикацию.

← К новостям

Ещё новости

Все последние новости