Если вам нужно за вечер сделать себе утилиту, которая берёт аудиофайл и отдаёт нормальную текстовую расшифровку, причём локально на Маке и без отправки звука куда-то в облако, то на Apple Silicon правильный выбор — это mlx-whisper на модели large-v3, а не faster-whisper, потому что mlx-whisper крутится нативно на Metal и работает в 3-5 раз быстрее при том же качестве распознавания. Вот это и есть короткий ответ, а дальше я расскажу как я к нему пришёл, что чуть не утащило проект в фича-крип и почему я сознательно разошёлся со стеком соседнего проекта.
Началось всё с простого вопроса самому себе, ну то есть к Claude Code, который у меня и пишет код: можно ли быстро щас навайбкодить что то что позволит мне загрузить аудиофайл и получить его транскрипцию. Мне реально часто нужно было загнать какую-нибудь запись в текст, и каждый раз дёргать сторонние сервисы или гонять голый скрипт в терминале мне надоело, хотелось чтобы это был отдельный нормальный проект со своим лицом, а не очередная папка со скриптом, который я через месяц забуду как запускать.
Почему вообще отдельный проект, а не скрипт
Тут сразу вылез первый соблазн — а не сделать ли по-быстрому, голым питоном, без интерфейса. И я сам себе это отрезал командой ассистенту: делай уж тогда ux ui нормальный куда я файл гружу. Потому что я уже знаю эту ловушку, когда ты делаешь утилиту на коленке, а потом сам же ей не пользуешься, потому что лень вспоминать как её дёргать и какие флаги передавать. Если я хочу чтобы вещь жила и реально экономила мне время, у неё должно быть место куда мышкой притащить файл и кнопка, а не команда которую надо помнить.
Так что инфру нового проекта я поднял сразу по своему шаблону для новых штук, чтобы не настраивать каждый раз каркас с нуля. Назвал проект Slysh, что в общем-то говорит само за себя, и пошёл разбираться с самой интересной частью — какой движок распознавания брать.
Стек JustStep уже был, но я от него ушёл
Самое смешное, что готовое решение у меня под рукой уже лежало. В соседнем проекте, JustStep, локальный транскриптор уже использовался, и крутился он на базовой модели whisper — base, она быстрая и нетребовательная, но и точность у неё соответствующая, на сложном или тихом аудио начинает фантазировать и глотать слова (про эти галлюцинации Whisper на русской речи у меня был отдельный разбор). Казалось бы, бери готовое и не выдумывай, переиспользование — это же хорошо, об этом везде пишут.
Но я хотел качество. Мне расшифровка нужна не чтобы примерно понять о чём речь, а чтобы потом с этим текстом работать всерьёз, и тут base просто не вывозит. Поэтому решение было такое — медленнее, зато точнее, то есть берём large-v3, большую модель, которая распознаёт заметно чище, и сознательно платим за это скоростью. Минус очевидный: разойдёмся со стеком JustStep, два проекта теперь делают одно и то же по-разному. И вот тут я сам себе сказал прямо — да похуй же, разные проекты. Это на самом деле важный момент, потому что есть такая ловушка соло-разработчика, когда ты пытаешься всё держать на одном стеке ради красоты архитектуры, а по факту проекты живут своей жизнью, у них разные требования, и насиловать новый проект под старые решения только ради единообразия — это путь к тому что ни тот ни другой нормально не работает.
Где faster-whisper, а где mlx-whisper
А вот теперь главный технический выбор, ради которого и стоило городить отдельный пост. large-v3 — модель тяжёлая, и если запускать её в лоб, расшифровка длинного файла превращается в долгое ожидание. Стандартный ответ комьюнити тут — faster-whisper, это переписанная под CTranslate2 реализация, которая на видеокартах NVIDIA реально летает и стала де-факто стандартом, и в другом проекте я как раз поднимал faster-whisper локально на CPU, так что с ним я уже повозился.
Но у меня нет NVIDIA. У меня Mac на Apple-чипе серии M, и вся эта история про CUDA мимо меня, faster-whisper на маке хоть и работает, но без той самой ускоряющей магии, ради которой его берут. Зато у Apple есть свой фреймворк — MLX, заточенный под их железо и работающий нативно на Metal, на встроенном GPU. И под него есть mlx-whisper. Так вот, на large-v3 mlx-whisper на моём железе оказался в 3-5 раз быстрее, чем faster-whisper, и это при том же качестве — модель-то одна и та же, large-v3, просто крутится она через родной для Mac движок, а не через прослойку которая на этом железе ничего не ускоряет.
Вывод из этого простой, и его стоит держать в голове, когда читаете очередной гайд по локальному распознаванию: совет «бери faster-whisper» по умолчанию верный только если у вас зелёная видеокарта. На Apple Silicon дефолт другой, и слепо копировать чужой стек тут как раз и значит потерять то самое ускорение в несколько раз, ради которого вся возня и затевалась. Железо диктует выбор инструмента, а не наоборот.
Что я сознательно НЕ стал делать
Когда вещь начинает работать, всегда подкатывает желание навесить ещё. У меня сразу зачесалось — а давай прикрутим запись системного звука, чтобы можно было прямо со звонка или с любого видео в браузере хватать аудио и сразу расшифровывать, на Маке это делается через виртуальное устройство BlackHole, которое заворачивает системный звук во вход. Идея кайфовая, я не спорю.
И я её отложил. Это типичный фича-крип — штука, которая звучит круто, удваивает сложность проекта и при этом не нужна мне для основной задачи прямо сейчас, потому что в девяти случаях из десяти у меня уже есть готовый аудиофайл, который надо просто загнать в текст. Поэтому первая версия умеет ровно одно: аплоад файла и расшифровка. BlackHole, перехват системного звука, всякие потоковые штуки — это потом, если реально упрусь в потолок, а не потому что было прикольно. Меньше всего хочется чтобы простая утилита на вечер превратилась в недоделанный комбайн который я бросил на середине.
Что в итоге собралось
По мелочи добавили прогресс-индикатор, потому что large-v3 на длинном файле думает не мгновенно, и без обратной связи непонятно завис процесс или работает, а это бесит. Расшифровки складываются в отдельную папку внутри проекта, чтобы всё было в одном месте и не растекалось по системе. Вот собственно и весь MVP — загрузил файл, видишь прогресс, получил текст, текст лежит где надо.
Что я вынес из этого вечера. Первое и главное — на Apple Silicon для локальной транскрипции mlx-whisper с large-v3 это разумный выбор по умолчанию, а faster-whisper оставьте тем у кого NVIDIA. Дальше — переиспользование готового решения из соседнего проекта вовсе не самоцель, и иногда правильно осознанно разойтись со своим же стеком, если у нового проекта другие приоритеты. И самое тупое и самое работающее, что я повторю в сотый раз — резать фича-крип на старте, делать одну вещь которая реально нужна, а красивые хотелки складывать в backlog. Весь этот разбор, к слову, написала нейросеть под моим управлением — я только оркестрировал и принимал решения, какой движок, какую модель и что выкинуть из первой версии, а это в вайбкодинге как раз и есть основная работа. Тыкать в кнопки умеет и ИИ, а вот решать что именно делать и от чего отказаться — пока всё ещё на мне.