Документация

Осуществимость ANE: эквивалентные преобразования и измеримая цель 10×

Дата исследования: 2026-09-20. Оборудование: M3 Max, 40-ядерный GPU, 128 ГиБ. Этот документ описывает гипотезы и математические границы, а не утверждение о новом измеренном ускорении. Отправная точка — исходные веса Laya и более быстрый рантайм MLX FP16. Инженерные эксперименты и измерения могут вытеснить приведённые ниже начальные наблюдения.

Лучший первый эксперимент — переписывание всего трансформера под фиксированную форму с channel-first раскладкой, за которым следует инспекция плана исполнения. Наиболее правдоподобная цель по порядку величины — энергия на завершённое решение, при условии, что модель сохраняет полезную задержку и точность. Изменение только настройки единиц вычислений Core ML не является достаточным свидетельством, что Neural Engine исполнял модель.

Последующие инженерные эксперименты реализовали это переписывание, а отчёт об измеренных скорости/энергии теперь фиксирует результаты. Несжатый кандидат повышает эффективность, но не достиг цели 10×. Гипотезы и исходный знаменатель ниже сохранены как запись исследования; для измеренных утверждений о производительности используйте более позднее сравнение со скомпилированным MLX.

Определите цель прежде, чем оптимизировать

Для одних и тех же входов, контрольной точки, политики точности и числа завершённых решений определите:

t = elapsed time / completed decisions
P = average measured power over that same interval
E = integrated energy / completed decisions = P × t

S = t_MLX / t_candidate                    speed gain
R = P_MLX / P_candidate                    power reduction factor
S × R = E_MLX / E_candidate                 energy efficiency gain

В этом тождестве используйте среднюю задержку по блокам, а не перцентиль задержки. Сообщайте P50 и P95 отдельно. Результат, который в 2× быстрее при пятой части мощности, — это улучшение энергии в 10×. Результат, который вдвое медленнее, требует снижения мощности в 20×, чтобы дать то же улучшение энергии в 10×. Умножение скорости на уже вычисленное улучшение энергии даёт двойной учёт прошедшего времени.

Есть два различных теста мощности:

  1. Насыщенный последовательный инференс: измерьте фактическую пропускную способность, задержку и джоули на решение. Кандидат с меньшей мощностью, но медленнее, не обязательно эффективнее.
  2. Равная предложенная нагрузка, например одинаковая частота тиков Snake: оба кандидата должны выполнить одну и ту же работу в пределах дедлайна. Сообщайте среднюю мощность, общую энергию интервала, пропуски дедлайна и завершённые решения. Более длинный сон или отбрасывание работы — не оптимизация.

Записывайте измеряемый домен мощности. Телеметрия CPU + GPU + ANE не обязательно является мощностью всей машины или батареи, и её нельзя так называть. Сообщайте сырую энергию и, если она пригодна, парную энергию за вычетом простоя. Когда нагрузка минус простой сопоставима с шумом, сохраняйте неопределённость, а не зажимайте её молча и не сообщайте огромное отношение. Держите токенизацию, копии входов, откат на CPU и постобработку внутри границы учёта конечной точки.

Начальные свидетельства и знаменатель

Текущий бенчмарк многоязычной MLX измеряет один вопрос на 91 токен при 7.870 мс P50 / 9.870 мс P95. Бенчмарк английской MLX измеряет вопрос на 93 токена при 13.334 / 13.734 мс. Это сквозные измерения predict, исключающие загрузку модели и прогрев. Новое сравнение должно заново прогнать сильнейший применимый путь MLX, включая его опциональные настройки compile и кэша промпта там, где это позволяет рабочая нагрузка; исторический eager-результат не является постоянным знаменателем.

Существующий многоязычный экспорт Core ML измеряет 11.277 мс P50 с CPU + GPU, 78.037 мс с ALL и 81.336 мс с CPU + NE. Последний план фиксирует 1 318 операций с предпочтением CPU и ни одной операции с предпочтением NE; у 24 операций SDPA метаданные устройства неизвестны. Это не устанавливает утверждения об исполнении на NE. План перечисляет многие операции как NE-поддерживаемые, что отличается от NE-предпочитаемых. Apple описывает использование устройств в плане вычислений как ожидаемое использование устройств, поэтому даже благоприятный план следует подтверждать профилированием во время выполнения или наблюдаемой активностью NE.

Существующий регрессионный порог FP16 — 100% совпадение argmax на фикстуре, конечные детерминированные выходы и не более 0.02 абсолютного дрейфа в калиброванных вероятностях и вероятностях действий. Это проверка точности конвертации на небольшом корпусе. Она не устанавливает общую точность на задачах, компетентность в Snake или качество сжатой модели.

Эквивалентные преобразования графа

Исследование Apple по развёртыванию трансформеров мотивирует четырёхмерные активации BC1L, свёртки 1×1, разделение внимания на головы и сокращение копий раскладки. Его опубликованный пример 10× — это другая модель, устройство и базовая линия; его нельзя перенести на сравнение с MLX здесь. Относитесь к этим рекомендациям по раскладке как к кандидатам для проверки на этой ОС и чипе, а не как к полному действующему контракту поддержки оборудования.

Линейные проекции и gated MLP

Пусть X[b,l,i] — существующая активация, и определим U[b,i,0,l] = X[b,l,i]. Для линейного слоя

Y[b,l,o] = sum_i W[o,i] X[b,l,i] + bias[o]
K[o,i,0,0] = W[o,i]
Conv2D(U,K)[b,o,0,l] = Y[b,l,o]

Это меняет раскладку и представление оператора, не меняя функцию с действительными значениями. Сохраняйте эту раскладку по всему энкодеру и обоим слоям трансформера головы решений. Преобразование к ней и обратно вокруг каждого линейного слоя может стереть выигрыш. QKV может остаться одной свёрткой D → 3D; разделите её выход по каналам на Q, K и V. Аналогично сохраните существующую слитую проекцию энкодера D → 2I, разделите каналы на value и gate, примените исходный точный GELU к value, умножьте на gate и спроецируйте I → D.

Для FP16 ширина последовательности, кратная 32, также выравнивается на 64-байтовое выравнивание последней оси, описанное в исследовании Apple. Начальные формы — B=1,L=96 для короткой фикстуры API и B=3,L=64 для компактного Snake. Рекомендация кратности 32 здесь следует этой модели буфера; это не разрешение дополнять каждую рабочую нагрузку до большой произвольной длины. Snake не нуждается в 96 токенах.

Внимание и RoPE

Для каждой головы держите Q и V как (B,d,1,L) и транспонируйте K в (B,L,1,d). Вычислите:

score[b,k,0,q] = sum_c Q[b,c,0,q] K[b,k,0,c] / sqrt(d)
weight = softmax(score + additive_mask, axis=key)
out[b,c,0,q] = sum_k weight[b,k,0,q] V[b,c,0,k]

Ось ключей — это ось 1 в этом представлении. Конкатенируйте выходы голов по оси каналов. Это та же функция внимания; неверная ось softmax молча её меняет. Эталонная реализация внимания от Apple демонстрирует соответствующие две четырёхмерные свёртки. Инспектируйте сконвертированные операторы MIL: написание einsum не гарантирует нужное устройство или понижение.

Применяйте RoPE к парам каналов каждой головы до QK. Сохраняйте соглашение контрольной точки о разделении пополам, исходные позиции и theta по слоям. В этой многоязычной контрольной точке и полная, и локальная RoPE используют theta 160000. Разделение первой и второй половин всех голов, конкатенированных вместе, неверно; разделяйте внутри каждой 64-канальной головы. Зависящее от позиции вращение в общем случае нельзя свернуть в одну не зависящую от позиции матрицу весов.

Локальное правило — двунаправленное abs(q-k) <= 64, включительно. Сохраняйте паддинг ключей и существующее правило дополненного запроса. Постоянные зависящие от позиции части можно вычислить до трассировки для фиксированных форм; изменение паддинга сэмпла всё равно должно влиять на маску ключей. Замена математического исключения конечной большой отрицательной маской — это численная аппроксимация, если она не совпадает с поведением исходной реализации в конечной точности; проверяйте состязательные и дополненные входы.

LayerNorm не взаимозаменяем с другой нормализацией

Для каждого (b,l) выполняйте приведение только по каналам:

mu = mean_c U
v = mean_c (U-mu)^2
normalized = (U-mu) / sqrt(v + epsilon)
output = normalized * gamma + beta

Сохраняйте исходный epsilon, порядок affine, дисперсию по популяции, единичную нормализацию первого слоя, точный GELU и порядок остатков. Эталонный LayerNorm от Apple использует другой порядок affine; его адаптер DistilBERT компенсирует это, преобразуя bias. Прямое копирование этого класса и загрузка state dict Laya были бы неверны при ненулевых bias. Явное выражение affine в исходном порядке также избегает деления на потенциально нулевую gamma.

Зажим активаций, переключение GELU на tanh или замена LayerNorm на RMSNorm меняет функцию. Если квадраты значений переполняются, положительное масштабирование — математически эквивалентный вариант:

normalize(x/a, epsilon/a^2) = normalize(x, epsilon), for a > 0

Накопление в конечной точности всё равно требует проверок на паритет. Приведения FP32 могут стоить копий или отката на CPU, поэтому инспектируйте план, а не молча ослабляйте численное поведение.

Перенесите неподдерживаемую работу на границы модели

Если поиск эмбеддингов, динамический сбор маркеров или хвост действий мешают непрерывному региону NE, сделайте отдельного кандидата с таким разбиением:

CPU: tokenizer → selected embedding rows → embedding LayerNorm
NE candidate: all encoder layers → type embedding addition → both heavy head layers
CPU: marker/CLS selection → small scorer → raw-probability features → action head

Только конечные точки пересекают движки. Не переносите внимание или LayerNorm каждого слоя на CPU. При многоязычных B=1,L=96 тензор эмбеддингов FP16 занимает 147 456 байт; при B=3,L=64 — 294 912 байт. Включайте эти копии и любую копию полного скрытого состояния на выходе в сквозное измерение.

Многоязычная таблица токенов содержит 196 608 000 параметров, но каждый запрос собирает только свои строки токенов. Её не нужно поставлять в подграф трансформера ANE, и её нельзя считать полным чтением таблицы на каждом предсказании. Её LayerNorm не зависит от позиции, поэтому офлайн-преднормализация строк таблицы эквивалентна в реальной арифметике. Она может изменить округление и точность хранения, что требует собственной проверки на паритет. Голова действий потребляет вероятности из сырых логитов маркеров, до температурной калибровки; восстановление её признаков из публичных калиброванных вероятностей меняет поведение контрольной точки.

Арифметические пределы для утверждения о задержке 10×

Пусть D — скрытая ширина, I — промежуточная ширина gated-энкодера, N — слои энкодера и H=2 — слои головы решений. Основное число параметров матриц на токен и плотная арифметика:

A = N(4D^2 + 3DI) + 12HD^2
F_dense(B,L) = 2BLA + 4B(N+H)L^2D

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

Контрольная точка D / I / N A Байты основной матрицы FP16 Плотная работа при B=1,L=96 Требуемая эффективная производительность для 10× ниже текущего MLX P50
Многоязычная 768 / 1152 / 22 124 452 864 248.91 МБ 24.574 GFLOP 31.23 TFLOP/s в пределах 0.787 мс
Английская / типизированная архитектура 1024 / 2624 / 28 368 312 320 736.62 МБ 71.848 GFLOP 53.89 TFLOP/s в пределах 1.333 мс, с использованием английской базовой линии

Это требуемые достигнутые скорости, а не заявленные пиковые характеристики ANE. Переписывание раскладки убирает накладные расходы, но не убирает эти плотные проекции. Оборудование также должно исполнять последовательную цепочку из 24 или 30 блоков внимания/MLP.

Оптимистичная потоковая модель даёт ещё один условный нижний порог:

t >= max(F / effective_compute, bytes_from_DRAM / effective_bandwidth)

M3 Max с 40 ядрами GPU специфицирован с пропускной способностью объединённой памяти 400 ГБ/с. Если каждая основная матрица FP16 извлекается из DRAM один раз на запрос, то даже полный доступ к этой пропускной способности стоит минимум 0.622 мс для многоязычной и 1.842 мс для английской. Фактический доступ к пропускной способности ANE может быть меньше, а кешированные или сжатые веса меняют предположение. Это не безусловный физический нижний предел. Это показывает, почему 10× для английской задержки особенно требовательно при несжатом потоке, и почему измерение энергии полезно даже тогда, когда задержка улучшается умеренно.

Для измеренной доли f сквозного времени, улучшенной в s раз, закон Амдала даёт S = 1 / (1-f+f/s). Даже бесконечное ускорение одного региона не может достичь 10×, если он не занимает хотя бы 90% исходной задержки. Аналогичная граница использует долю измеренной энергии, а не FLOPs, когда цель — джоули на решение. Оптимизация выбранного запроса в финальной голове убирает лишь несколько процентов арифметики модели; разреженность локального внимания также пренебрежима при L<=64, где локальное окно покрывает все позиции. Ни одна из них не даёт правдоподобного самостоятельного пути к 10×.

Сжатие и архитектурные изменения имеют разные контракты

Кандидат Та же функция контрольной точки с действительными значениями? Что он реально может изменить
Раскладка BC1L, проекции 1×1, статические позиции/маски, разделение голов Да, если уравнения и входы сохранены Планирование, локальность, разбиение компилятором, копии памяти
Разбиение конечных точек на CPU, офлайн-нормализация эмбеддингов, выбранные запросы в финальной голове Да в реальной арифметике; проверьте округление Неподдерживаемые операции, размер пакета, часть неиспользуемой работы
8/6/4-битная палетизация или квантование весов В общем нет Трафик/хранение весов и, возможно, энергия/задержка инференса
Прунинг обученных ненулевых весов или низкоранговая факторизация Нет, если только не существует алгебраически точная структура Матричная арифметика и трафик после восстановления/калибровки
Ранний выход, прунинг токенов, меньше слоёв, более узкий студент Нет Потенциально большая экономия; новая модель и контракт качества
Переиспользование скрытого состояния между произвольными вопросами Нет для этого двунаправленного энкодера Недопустимый шорткат; контекстные состояния зависят от вопроса
Кеширование идентичных ответов на весь вход Точно для попаданий в кэш Особенность рабочей нагрузки, а не скорость некешированного инференса

Текущий обзор оптимизаций от Apple указывает на палетизацию для выигрыша по памяти/задержке NE и определяет более новый путь вычислений W8A8 с A17 Pro/M4. Не экстраполируйте это ускорение нового оборудования на этот M3 Max. Руководство по производительности квантования также предупреждает, что деквантование активаций может замедлить исполнение на CPU/GPU. Сначала получите резидентную на NE базовую линию, затем проверяйте палетизацию весов от 8 бит и ниже, сохраняя чувствительные нормы/скоринг по мере необходимости.

Упаковка весов FP16 в восемь или четыре бита даёт идеальное отношение хранения весов 2× или 4× до метаданных. Это не равный множитель задержки: декомпрессия, перемещение активаций и вычисление остаются. Прунинг помогает рантайму только если выбранное представление действительно использует нули. Удаление произвольных голов/слоёв или низкоранговое усечение требует восстановления качества и не может сохранить исходную идентичность модели без оговорок.

Для границы ошибки логитов на вход ||z'-z||_infinity <= delta достаточный сертификат argmax — top1(z)-top2(z) > 2delta. При одинаковой положительной температуре калибровки T граница Липшица бесконечной нормы softmax даёт ||p'-p||_infinity <= delta/(2T). Это полезные диагностики на оценённых входах, а не глобальный сертификат для квантования. Сохраняйте отдельные срезы оценки с малым запасом и многоязычные; насыщенные примеры могут скрывать большие ошибки логитов.

Три эксперимента и критерии приёмки

  1. Эквивалентный граф NE с фиксированной формой. Экспортируйте многоязычный B=1,L=96,K=4 и Snake B=3,L=64,K=4 с проекциями BC1L, корректным RoPE по головам, явным вниманием и исходными LayerNorm/GELU. Сравните входные массивы и выходы отдельных слоёв с исходным графом. Инспектируйте, какие основные проекции и блоки внимания предпочитают NE, затем проверьте фактическую активность NE во время выполнения. Одного подсчёта поддерживаемых операций недостаточно для успеха. Заново прогоните соответствующую оптимизированную базовую линию MLX в чередующихся блоках.
  2. Один непрерывный островок трансформера. Если первый граф фрагментируется, перенесите эмбеддинги и небольшой финальный хвост на границы CPU. Сравните это с кандидатом на полном графе при одном и том же измерении мощности. Сохраняйте кандидата, только если полные предсказания улучшают задержку или энергию сверх наблюдаемой вариации от прогона к прогону. Включайте все копии; быстрый изолированный энкодер недостаточен.
  3. Сжатие с фокусом на энергию после того, как размещение работает. Отберите 8-битную палетизацию, затем 6/4-битную как отдельные приближённые варианты. Прогоните неизменённый шлюз фикстуры, отложенные задачи choice/score/noul, многоязычные входы, близкие ничьи и траектории Snake. Публикуйте точность, дрейф вероятности и калибровку вместе с производительностью. Агрессивное сжатие или дистилляция относятся к отдельно названной модели, если они меняют обученное поведение.

Перед утверждением о запуске используйте одни и те же хеши контрольной точки/входа и чередующийся порядок базовая линия/кандидат; исключайте холодную компиляцию, но сообщайте о ней отдельно. Используйте не менее пяти устойчивых блоков на финалиста и сохраняйте сырые задержки, завершённые вызовы и выборки мощности. Требуйте исходного согласия на фикстуре и существующих допусков вероятности, не ослабляя их, чтобы пройти кандидата, плюс стабильные конечные выходы и ограниченную память. Измеряйте длинные входы и входы на границе форм отдельно от коротких демо с фиксированной формой.

Объявляйте 10× только тогда, когда соответствующее отношение скорости, равной нагрузки или энергии составляет хотя бы десять с неопределённостью, поддерживающей утверждение, при соблюдении заявленных пределов задержки и качества задачи. Если нижняя граница неопределённости не достигает десяти, сообщите измеренное отношение. Меньший выигрыш по энергии с подтверждённым исполнением на NE остаётся полезным свидетельством; это не результат на порядок величины.

Происхождение документации

Использован требуемый рабочий процесс CLI Context7: Core ML Tools разрешён в /apple/coremltools, затем запрошены понижение операторов/раскладки трансформера и поведение сжатия NE (всего три команды). Проверены исследовательская статья Apple, эталонные исходники, текущая документация по оптимизации Core ML, документация по плану вычислений и спецификация устройства по ссылкам выше. Уравнения модели, числа параметров и начальные измерения выведены из этого репозитория и его родственного проекта MLX. Эта исследовательская ветка не запускала конкурирующий бенчмарк GPU/ANE.