Как я заставил Mac расшифровывать 74-минутные звонки за 7 минут без облаков и перегрева

История оптимизации: почему Pyannote тратил 16 минут на CPU, как мы спаслись от Metal Shader Timeout на M2 Pro и почему 60 секунд на Apple Neural Engine изменили всё.

инженерный дневник одной оптимизации

У меня была простая мечта: заканчиваешь созвон в Zoom или Telegram — а через пять минут в папке проекта уже лежит выверенный Markdown с таймкодами, репликами спикеров, договоренностями и Action Items. Без облачных API за доллары в минуту, без ручной загрузки файлов и с абсолютной конфиденциальностью.

Казалось бы, бери готовую связку: Audio Hijack + Pyannote + Parakeet v3. Я запустил первый прогон на реальном 74-минутном созвоне — и тут началась реальность.

Архитектура пайплайна

Как устроен конвейер: от клика до базы знаний

74 минуты созвона → 7 минут 35 секунд локально на MacBook M2 Pro без облаков

Шаг 1
🎙️

Захват в Audio Hijack

Двухканальная стерео-запись с физической изоляцией потоков.

  • Левый канал (L): микрофон автора (Kill Right)
  • Правый канал ®: звук Zoom/Meet (Kill Left)
  • В наушники: чистый стереозвук без задержки
AAC Stereo · 64 kbps
Шаг 2 · Apple Silicon
🧠

Локальный процессинг

Параллельная обработка на ANE и Metal GPU.

Neural Engine (ANE) · 61,3 сек

FluidAudio WeSpeaker: диаризация только правого канала (собеседники). Нагрузка на CPU: 0%.

Metal GPU (MLX) · 6,4 мин

Parakeet TDT 0.6B: окно 60s с нахлестом 5s. Пик памяти всего 1,5 ГБ RAM.

Автор: 100% точность Без облачных API
Шаг 3

Автоматизация в Hazel

Постобработка, выделение задач и раскладка по проектам.

  • Склейка: таймкоды + реплики диалога в Markdown
  • LLM-анализ: Summary, договоренности и Action Items
  • Доставка: репозиторий Git, база знаний G-Brain и Telegram
0 ручных действий

Акт 1. 16 минут на CPU и парадокс тихих вентиляторов

Первая попытка показала: распознавание текста (ASR) через Parakeet на MLX летало, но диаризация (разделение на «кто говорит») шла мучительно долго. 16 минут только на то, чтобы разметить спикеров.

Самое обидное — вентиляторы на MacBook M2 Pro даже не пытались шуметь. Ноутбук оставался совершенно холодным. Оказалось, система не была перегружена: Pyannote на Python просто уныло считал спектрограммы в один поток на одном-единственном ядре CPU, пока 12 ядер, мощный графический чип и нейропроцессор Apple Neural Engine стояли без дела. Машина с огромным запасом производительности использовалась как обычный офисный калькулятор.

Поэтому мы решили перенести диаризацию на нативный стек Apple Silicon через FluidAudio (Swift + CoreML).


Акт 2. Metal Shader Timeout и спасение в Apple Neural Engine

Мы скомпилировали нативный бинарник под macOS и запустили сегментацию на GPU через Metal Performance Shaders.

Но при обработке 74-минутного файла окно оказалось слишком большим для графического шейдера — macOS убила процесс с ошибкой GPU Timeout Error (00000002:kIOGPUCommandBufferCallbackErrorTimeout).

Поэтому мы перенаправили вычисления сегментации и эмбеддингов WeSpeaker с GPU на Apple Neural Engine (ANE) флагом --compute-units ane.

Результат превзошел ожидания:


Акт 3. Золотая середина Parakeet: с 12 минут до 6

Дальше мы оптимизировали Parakeet TDT 0.6B v3. Изначально аудио нарезалось 30-секундными окнами.

Но из-за квадратичной сложности $O (L^2)$ механизма внимания в трансформере слишком частая нарезка и нахлесты перегружали память и тратили лишнее время.

Поэтому мы подобрали идеальное окно — 60 секунд с перекрытием 5 секунд. Время транскрипции упало до 6 минут 24 секунд, а пиковое потребление памяти уложилось в скромные 1,5 ГБ RAM.


Акт 4. Двухканальный студийный сплит

Оставалась последняя проблема: когда на созвоне люди перебивают друг друга, одноканальная нейросеть может запутаться, кому принадлежит реплика.

Поэтому мы настроили в Audio Hijack двухканальную стерео-запись с физической изоляцией потоков:

Настройка маршрутизации каналов в Audio Hijack

  1. Левый канал: только микрофон автора звонка (Kill Right).
  2. Правый канал: только звук собеседников из Zoom/Meet (Kill Left), при этом в наушники идет чистый стереозвук.

Скрипт автоматически определяет 2 канала: голос автора сразу получает 100% точную метку Александр, а Neural Engine диаризирует только собеседников в правом канале. Ни одного перепутывания реплик, даже если все говорят одновременно.


Итог в цифрах