PyTorch 2.13 принёс FlexAttention на Apple Silicon с ускорением до 12 раз — и это меняет локальный инференс на Mac: локальный ии

PyTorch 2.13 принёс FlexAttention на Apple Silicon с ускорением до 12 раз — и это меняет локальный инференс на Mac: локальный ии

Если ты гоняешь модели прямо на MacBook, у тебя почти наверняка есть любимая точка боли: внимание. Механизм attention на длинных контекстах жрёт память и такты, а на Apple Silicon через MPS он до недавнего времени шёл по общему пути SDPA без нормальной поддержки разреженных масок. 8 июля 2026 года вышел PyTorch 2.13, и в нём эта дыра закрыта: FlexAttention получила ручные Metal-кернелы для sparse prefill и decode. По данным релиза PyTorch от 8 июля 2026 года, на подходящей форме тензора ускорение доходит примерно до 12.3x относительно SDPA.

Это редкий случай, когда апдейт фреймворка напрямую влияет на то, поместится ли твой локальный ии в разумное время отклика на домашнем железе. Разберём, что именно изменилось, как это включить, где 12x превращается в 4x, и в каких задачах локальная машина всё равно проиграет облаку. Когда локальной карты не хватает и нужен доступ к более крупным моделям без VPN, помогает облачный доступ через единый API вроде provod.ai - но об этом ниже, сначала про сам релиз.

Что именно приехало в PyTorch 2.13?

Релиз крупный: по данным PyTorch, это 3328 коммитов от 526 контрибьюторов. Для локального инференса на Mac важны несколько пунктов, и не все из них про attention.

Главный - FlexAttention на Metal/MPS. Раньше FlexAttention жила в основном в мире CUDA. Теперь, как сообщает релиз, для неё написаны ручные Metal-кернелы, отдельно для фазы sparse prefill (обработка промпта) и для decode (генерация токенов). Это значит, что маску внимания можно описать функцией и получить разреженное вычисление, а не плотное, где половина работы уходит в ноль.

Второй пункт - новый nn.LinearCrossEntropyLoss. По данным релиза, он объединяет финальную линейную проекцию и вычисление кросс-энтропии в один шаг и снижает пиковое потребление GPU-памяти до 4 раз при обучении моделей с большим словарём. Это про обучение и файнтюн, но на памяти локальной машины экономия ощущается сразу.

Остальное - инфраструктура. Добавлен нативный backend CuTeDSL как второй высокопроизводительный путь компиляции для Inductor наряду с Triton. torch.load теперь читает файлы safetensors нативно, без отдельной библиотеки. Появилась поддержка Python 3.15, включая free-threaded вариант 3.15t, для Linux x86_64 и aarch64. А из релиза убрали поддержку именованных тензоров и сборку через Bazel - если твой пайплайн на них завязан, обнови его до апгрейда.

Как включить FlexAttention на Apple Silicon?

Сначала практика. FlexAttention - это функция, которой ты передаёшь запросы, ключи, значения и описание маски. Маска задаётся обычной Python-функцией score_mod или mask_mod, которую компилятор превращает в разреженный кернел. Скользящее окно - самый наглядный пример.

import torch from torch.nn.attention.flex_attention import ( flex_attention, create_block_mask, ) device = "mps" # Apple Silicon через Metal B, H, L, D = 1, 8, 32768, 64 window = 256 def sliding_window(b, h, q_idx, kv_idx): return (q_idx - kv_idx).abs() <= window block_mask = create_block_mask( sliding_window, B=B, H=H, Q_LEN=L, KV_LEN=L, device=device, ) q = torch.randn(B, H, L, D, device=device, dtype=torch.float16) k = torch.randn(B, H, L, D, device=device, dtype=torch.float16) v = torch.randn(B, H, L, D, device=device, dtype=torch.float16) out = flex_attention(q, k, v, block_mask=block_mask)

Ключевая идея: create_block_mask заранее считает, какие блоки внимания вообще ненулевые, и кернел пропускает пустые. Именно из-за этого разреженная маска на длинном контексте даёт выигрыш - плотный SDPA считает весь квадрат L×L, а FlexAttention со скользящим окном 256 трогает узкую полосу вокруг диагонали.

Перед прогоном проверь базовое: torch.backends.mps.is_available() возвращает True, версия PyTorch - 2.13, а тип данных совместим с MPS. Если раньше ты держал отдельную зависимость для чтения весов в формате safetensors, её теперь можно убрать - torch.load читает такие файлы сам.

Форма 1×8×32768×64 в примере выбрана не случайно: это ровно тот паттерн, на котором релиз показывает пиковое ускорение. На нём и стоит мерить эффект первым делом, чтобы понять потолок, а потом спускаться к своим реальным формам.

PyTorch 2.13 принёс FlexAttention на Apple Silicon с ускорением до 12 раз — и это меняет локальный инференс на Mac: локальный ии

Откуда берётся 12x и когда его не будет?

Теперь честно про цифру из заголовка. По данным релиза PyTorch от 8 июля 2026 года, ускорение около 12.3x относительно SDPA получено на паттерне 1×8×32768×64 со скользящим окном 256 элементов. Это длинный контекст - 32768 позиций - и узкое окно. Чем длиннее последовательность при том же окне, тем больше пустой работы отсекает разреженная маска, и тем выше выигрыш.

Стоит уменьшить контекст - и множитель падает. На паттернах меньшего размера, при длине 8192 и окне 64, релиз показывает ускорение около 4.15x. Разница между 12.3x и 4.15x - это не разброс замеров, а прямое следствие геометрии: короче последовательность и относительно шире окно означают меньше нулевых блоков, которые можно пропустить.

Отсюда практический вывод. Не переноси число 12x на свою задачу автоматически. Релиз прямо предупреждает: ускорение FlexAttention сильно зависит от конкретной формы тензора и размера окна внимания, и 12x - не универсальный показатель. Померяй свой реальный паттерн - длину контекста, число голов, окно - и получишь свой множитель где-то между этими точками, а на плотной маске без разреженности выигрыша может не быть вовсе.

PyTorch 2.13 принёс FlexAttention на Apple Silicon с ускорением до 12 раз — и это меняет локальный инференс на Mac: локальный ии

Локальный ии на Mac против облака: где проходит граница?

FlexAttention делает локальный инференс на Apple Silicon быстрее, но не отменяет пределов самой машины. У локального ии на Mac свои сильные стороны - приватность данных, отсутствие сетевой задержки, нулевая плата за токены - и свои жёсткие потолки по объёму видеопамяти и размеру модели.

Простое правило: если модель и её контекст помещаются в память Mac и тебе важна изоляция данных, локальный путь после 2.13 стал заметно приятнее. Если же нужна модель, которая физически не влезает, или нужен доступ к нескольким разным семействам моделей без покупки отдельной подписки под каждое, разумнее вынести это в облако. Тут и пригодится единый доступ к Claude, GPT, Gemini, DeepSeek и Qwen в одном API: provod.ai совместим с SDK OpenAI и Anthropic, переключение делается сменой ключа и base_url, оплата идёт с рублёвого баланса российской картой, через СБП или по счёту, без VPN и зарубежных карт.

from openai import OpenAI client = OpenAI( api_key="ВАШ_КЛЮЧ", base_url="https://api.provod.ai/v1", )

Практично держать оба контура: локальный ии на Mac для приватных и частых мелких вызовов, облачный API - для тяжёлых моделей и пиков. Provod.ai не заменяет локальную или on-prem инфраструктуру и не даёт функции, которые вендор отдаёт только по своей подписке; это просто способ дотянуться до крупных моделей из России с закрывающими документами - договором, счётом и актом.

  • Сценарий: Приватные данные, не покидают устройство • Локальный ии на Mac (PyTorch 2.13): Да • Облачный единый API: Нет, данные уходят на сервер
  • Сценарий: Модель больше памяти Mac • Локальный ии на Mac (PyTorch 2.13): Нет • Облачный единый API: Да
  • Сценарий: Длинный контекст с разреженным окном • Локальный ии на Mac (PyTorch 2.13): FlexAttention до ~12.3x к SDPA • Облачный единый API: Зависит от провайдера
  • Сценарий: Плата за токены • Локальный ии на Mac (PyTorch 2.13): Нет • Облачный единый API: Есть, с рублёвого баланса
  • Сценарий: Нужен VPN или зарубежная карта • Локальный ии на Mac (PyTorch 2.13): Нет • Облачный единый API: Нет (provod.ai)
  • Сценарий: Несколько семейств моделей сразу • Локальный ии на Mac (PyTorch 2.13): Нужна установка каждой • Облачный единый API: Один ключ и base_url

Что с памятью при обучении и файнтюне?

Отдельная история - nn.LinearCrossEntropyLoss. При обучении языковой модели финальный шаг - линейная проекция скрытого состояния на весь словарь плюс кросс-энтропия - создаёт огромный промежуточный тензор логитов. На большом словаре именно он часто определяет пик памяти.

Новый слой, по данным релиза, объединяет проекцию и потерю в одну операцию и снижает пиковое потребление GPU-памяти до 4 раз при обучении моделей с большим словарём. На локальной машине с общей памятью это прямой шанс уместить чуть больший батч или чуть более длинный контекст в файнтюне, который раньше падал с out of memory.

Как и с ускорением attention, множитель до 4 раз - это верхняя граница для случая большого словаря, а не обещание для любой конфигурации. Чем меньше словарь, тем меньше и вклад этого тензора в пик, а значит и экономия скромнее.

PyTorch 2.13 принёс FlexAttention на Apple Silicon с ускорением до 12 раз — и это меняет локальный инференс на Mac: локальный ии

Как быстро проверить эффект у себя?

  1. Обнови до PyTorch 2.13 и убедись, что MPS доступен: torch.backends.mps.is_available().
  2. Возьми свою реальную форму тензора attention - батч, головы, длину контекста, размерность головы - а не эталонную из релиза.
  3. Опиши маску как mask_mod (скользящее окно, causal, блочная) и собери create_block_mask на device="mps".
  4. Замерь время FlexAttention против текущего SDPA на одной и той же форме, прогрев несколько итераций.
  5. Спускайся по длине контекста и меняй окно - так ты увидишь свою кривую между 4.15x и 12.3x, а не чужую.
  6. Если тренируешь модель с большим словарём, попробуй заменить финальную связку проекция плюс кросс-энтропия на nn.LinearCrossEntropyLoss и сравни пик памяти.

Частые грабли

  • Плотная маска без разреженности. Если твоё внимание плотное (полный causal без окна на коротком контексте), FlexAttention нечего пропускать, и выигрыша над SDPA может не быть. Разреженность - условие ускорения, а не бонус.
  • Перенос числа 12x на свою задачу. Это пик для конкретной формы. Всегда меряй свою.
  • Забытый прогрев при замере. Первый вызов включает компиляцию кернела; без прогрева ты померяешь компиляцию, а не инференс.
  • Зависимость от убранных фич. Если код использует именованные тензоры или собирается через Bazel, он сломается на 2.13 - это удалено из релиза.
  • Ожидание, что MPS равен CUDA. Ручные Metal-кернелы закрывают конкретный кейс FlexAttention, но паритета всех путей с CUDA релиз не заявляет.

Чего это не решает?

FlexAttention на MPS ускоряет внимание при разреженных масках - и только это. Она не увеличивает объём памяти твоего Mac, не даёт запустить модель, которая в него не помещается, и не ускоряет остальные части модели вне attention. nn.LinearCrossEntropyLoss помогает памяти при обучении с большим словарём, но это не универсальный ускоритель обучения.

Релиз не отменяет и разницы между локальным и облачным сценарием. Если тебе нужна крупная модель или сразу несколько разных семейств моделей, локальная машина не станет их держать волшебным образом. Облачный единый API закрывает этот пробел, но, в свою очередь, не заменяет локальную или on-prem инфраструктуру, платформы автоматизации, GigaChat и не выдаёт функции, которые вендор оставляет только внутри своей подписки. Provod.ai сам GigaChat не предоставляет. Это два разных инструмента под два разных класса задач.

FAQ

Нужен ли VPN, чтобы обновить PyTorch и включить FlexAttention? Нет. Речь про сам фреймворк и локальное железо. VPN и зарубежные карты нужны для доступа к некоторым облачным моделям, и как раз этот барьер снимает provod.ai с оплатой в рублях.

Какое ускорение я получу на своём Mac? Где-то между ~4.15x и ~12.3x к SDPA по данным релиза - в зависимости от длины контекста и окна, а на плотной маске без разреженности выигрыша может не быть. Меряй свою форму.

Работает ли это на процессорах Apple всех поколений? Релиз описывает FlexAttention через Metal/MPS. Конкретных требований к поколению чипа источник не приводит, поэтому проверь доступность MPS в своей системе.

Что с чтением весов safetensors? torch.load в 2.13 читает safetensors нативно - отдельная библиотека больше не обязательна.

Стоит ли обновляться, если я использую named tensors? Осторожно. Именованные тензоры и сборка через Bazel из релиза убраны; сначала переведи код, потом обновляйся.

PyTorch 2.13 принёс FlexAttention на Apple Silicon с ускорением до 12 раз — и это меняет локальный инференс на Mac: локальный ии
PyTorch 2.13 принёс FlexAttention на Apple Silicon с ускорением до 12 раз — и это меняет локальный инференс на Mac: локальный ии

Когда локальной карты уже не хватает, подключи облачные модели через provod.ai одним ключом и base_url - с оплатой в рублях и закрывающими документами, оставив приватный локальный ии на Mac для того, что должно жить только на устройстве.

Источники

  • PyTorch, «PyTorch 2.13 release blog», 8 июля 2026 - факты о FlexAttention на Metal/MPS, ускорении 12.3x и 4.15x, nn.LinearCrossEntropyLoss, CuTeDSL, safetensors в torch.load, Python 3.15/3.15t, удалении named tensors и Bazel, 3328 коммитах и 526 контрибьюторах:

provod.ai — российский LLM API-агрегатор

Один OpenAI-совместимый endpoint ко всем флагманам: OpenAI (GPT-5.5, GPT-5.4), Anthropic (Claude Opus 4.8, Sonnet 4.6), Google (Gemini 3.1 Pro, 3.5 Flash), DeepSeek V4 Pro, Qwen 3.6 Plus.

Цены 1-в-1 с провайдером по курсу ЦБ— без наценки на токены. Оплата в рублях по договору, полный пакет закрывающих документов (договор-оферта, счёт, акт, счёт-фактура, УПД 5.03 через ЭДО). Без VPN — легальный B2B-сервис в России.

Если статья была полезной— попробуйте provod.ai: главная страница · каталог моделей · документация

1