У ранніх збірках Voice Pro використовувався ONNX Runtime з офіційними експортами Qwen ASR у форматі ONNX. Це працювало, але випускати це було болісно. Ось із чим ми зіткнулися і чому зараз застосунок працює на llama.cpp з моделями, квантованими у форматі GGUF.
Проблема 1: розмір встановлення
Вийшла версія Voice Pro для Windows із ONNX Runtime + провайдером DirectML + провайдером CUDA + вагами моделі 430 MB. У Linux ситуація була подібною. Це занадто велика вимога — просити когось завантажувати інструмент для диктування, яким він ще не користувався.
Збірка GGUF — це 83 МБ у Windows. Скомпільований бінарний файл llama.cpp дуже компактний, квантована базова модель займає близько 60 МБ (порівняно з ~200 МБ у форматі fp16 ONNX), і ми не постачаємо окремі DLL-файли виконавчих провайдерів для CPU, CUDA, DirectML та Vulkan — llama.cpp обробляє всі чотири платформи одним бінарним файлом.
Проблема 2: холодний старт
ONNX Runtime з DirectML на чистій установці Windows витрачав 3–5 секунд на ініціалізацію сесії інференсу. Щоразу, коли користувач уперше натискав гарячу клавішу після перезавантаження, виникала така затримка. Це неприйнятно для інструменту диктування, де головна мета — «говорити негайно».
llama.cpp завантажує модель GGUF за ~400 мс у холодному старті на тому самому обладнанні. Ваги моделі зберігаються у вигляді memory-mapped об’єктів, немає кроку компіляції графа, не потрібно ініціалізувати wheel-пакети під час роботи.
Проблема 3: пекло пакування
ONNX Runtime постачається у вигляді Python-пакету (wheel), що означає різні wheel-пакети для кожної версії Python, ОС та архітектури CPU. Додайте прискорення від GPU, і результат множиться на версію CUDA та версію DirectML. Nuitka (наш пакувальник) продовжував включати неправильну версію. У нас були скрипти збірки з шістьма умовними розгалуженнями.
llama.cpp — це єдиний бінарний файл на C++. Його компілюють один раз для кожної платформи (Windows x64, Linux x64) та постачають у вигляді нативного виконуваного файлу, який викликає Voice Pro. Зовсім немає залежності від середовища виконання Python для інференсу — Python використовується лише як «клей».
Проблема 4: якість при малих розмірах
Проблемою квантування є втрата точності. На практиці квантована версія Qwen3-ASR 0.6B (наша базова модель) за допомогою формату Q5_K_M дає результати, які відрізняються на 0,3% від результатів повної версії у форматі fp16 ONNX у нашому внутрішньому наборі для оцінки. Формат Q4_0 значно гірший, тому ми використовуємо Q5_K_M як стандартний варіант. Користувачі, які хочуть досягти максимальної точності, можуть завантажити версію у форматі fp16 з менеджера моделей.
Чим ми пожертвували
Підтримка ASR у llama.cpp є новішою, ніж у ONNX Runtime. Деякі екзотичні архітектури моделей поки що не мають конвертерів у формат GGUF. Наразі це не має значення — Qwen3-ASR конвертується коректно — але якщо ми захочемо у майбутньому спробувати радикально іншу модель ASR, нам може знадобитися зберегти шлях через ONNX як резервний варіант.
Підсумок: встановлення у 5 разів менше, холодний запуск приблизно у 10 разів швидший, один бінарний файл для збірки замість дванадцяти. Нам варто було зробити це з першого дня.