Sakhanda Wire
NVDA $212.48 -1.35% MSFT $528.21 -0.53% GOOGL $282.90 -12.93% META $620.88 +1.37% AMZN $244.92 -3.80%
← До новин

Представляємо 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 від 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 Open Model License
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 Open Model License

У кожному репозиторії зазначено вихідний чекпойнт і контрольну суму кожного файлу, а пакет закріплює його за фіксованою ревізією. Репозиторії Parakeet додають 8-секундний енкодер для введення в реальному часі, що скорочує час аналізу приблизно на третину, але дещо підвищує частоту помилок у словах. У репозиторії також є процеси конвертації, більшість із яких наслідує скрипти mobius від FluidInference, а кожна конвертація перевіряється порівнянням з оригінальною моделлю.

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

Діаризація мовців

Коли ви розшифровуєте розмову, часто потрібно знати, хто що сказав. Це і є діаризація мовців, і фреймворк Speech від Apple не має для неї модуля, тому AnySpeechRecognizer додає його. SpeakerDiarizer запускає NVIDIA Streaming Sortformer на 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 = "За моє замовлення з мене списали кошти двічі, а тепер застосунок викидає мене, коли я намагаюся попросити повернення коштів."

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: "Чи передає це відчуття терміновості?")
let team = try await session.choice("Яка команда?", from: Department.self)
let anger = try await session.score(
    "Наскільки клієнт роздратований?",
    levels: ["Спокійний", "Роздратований", "Дуже сердитий"]
)

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 емодзі. Введіть фразу, наприклад «речі, які ви носите», і відповідні емодзі піднімуться з купи. Уточніть її до «речі, які ви носите взимку», і емодзі, що більше не відповідають, опустяться назад.

У застосунку немає вбудованих правил за ключовими словами; модель приймає всі рішення під час інференсу. Коли ви припиняєте вводити текст, вона ставить моделі запитання «так/ні» для кожного емодзі, наприклад:

Твердження: тепле зимове пальто відповідає опису «речі, які ви носите». Чи правильне це твердження?

Стан сеансу містить фразу. У наведеній демонстрації використовується хостований бекенд 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 або новіша.

Бекенди наступного токена позначають відповіді як «так» і «ні», від 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 і наводяться тут із зазначенням авторства та посиланням на оригінальну публікацію.

← До новин

Ще новини

Усі останні новини