PyTorch 2.13 on Apple Silicon: FlexAttention is up to 12x faster than SDPA

PyTorch 2.13 brings FlexAttention to Apple Silicon (MPS) with up to 12x speedups over SDPA on sparse attention patterns.

Read time
11 min
Word count
1.6K
Sections
11
FAQs
8
Share
Glowing processor chip on a dark studio surface with blue light trails
PyTorch 2.13 brings FlexAttention to Apple Silicon.
On this page · 11 sections
  1. What actually shipped in PyTorch 2.13
  2. Why attention was the weak spot on a Mac
  3. What FlexAttention is, in one paragraph
  4. How to use it on Apple Silicon
  5. What "up to 12x" really means
  6. When to reach for it, and when not to
  7. Sharp edges to expect
  8. India-specific considerations
  9. FAQ
  10. How eCorpIT can help
  11. References

Summary. PyTorch 2.13, released around July 11, 2026, brings FlexAttention to Apple Silicon through the Metal (MPS) backend, with hand-written Metal kernels for the sparse prefill and decode paths and up to 12x speedups over scaled dot-product attention (SDPA) on sparse patterns. The release landed 3,328 commits from 526 contributors since PyTorch 2.12, with a live Q&A scheduled for July 22, 2026. For anyone running models on a Mac, this closes a gap that used to push custom attention work onto NVIDIA hardware. A Mac with 546 GB/s of memory bandwidth (M4 Max, 2026) already generates roughly 60 tokens per second on Llama 3.1 8B at 4-bit, the newer M5 Max pushes that to about 614 GB/s (near 12% more), and a machine around $1,799 can hold a 33B model in unified memory. FlexAttention makes the attention step on that hardware programmable without writing Metal by hand.

If you build or fine-tune transformers on a MacBook or a Mac Studio, this is the most useful line item in the PyTorch 2.13 release. It is not a headline model or a new training recipe. It is a kernel change that quietly removes a reason to keep a separate NVIDIA box around for experimentation.

What actually shipped in PyTorch 2.13

FlexAttention on MPS is the change most Mac developers will feel first, but it arrived alongside a few other performance items worth knowing before you upgrade.

Feature What it does Who it helps
FlexAttention on Metal (MPS) Hand-written Metal kernels for sparse prefill and decode, including grouped-query attention and captured buffers, up to 12x over SDPA on sparse patterns Anyone training or serving attention models on Apple Silicon
CuTeDSL Inductor backend A second high-performance code path alongside Triton for key GPU operations, with faster compilation Kernel authors and heavy torch.compile users on CUDA
nn.LinearCrossEntropyLoss Fuses the final projection and the loss into one operation, cutting peak GPU memory by up to 4x for large-vocabulary language-model training Teams pretraining or fine-tuning LLMs
Deterministic FlexAttention backward (CUDA) A reproducible gradient path for FlexAttention Research reproducibility and debugging
Scale of the release 3,328 commits from 526 contributors since 2.12 Context for how much changed

The Apple Silicon piece matters because the Metal path now covers both phases of inference. The release blog describes hand-written Metal kernels for the sparse prefill and the decode path, with support for grouped-query attention (GQA) and captured buffers. That combination is what real decoder-only models need, not just a toy causal mask.

Why attention was the weak spot on a Mac

Attention is the part of a transformer that scales badly. A dense attention mask over a sequence of length N holds N by N entries, so memory and compute grow with the square of the context. Fused kernels such as FlashAttention solved this on NVIDIA GPUs by never materialising the full score matrix. On Apple Silicon, that class of fused kernel was thin on the ground, so many people fell back to SDPA with a dense mask, or wrote a bespoke Metal kernel for the one pattern they needed.

The FlexAttention authors framed the underlying tension well. In the original FlexAttention announcement, Team PyTorch (Driss Guessous, Yanbo Liang, Joy Dong, and Horace He at Meta) wrote that fused attention "has come with a loss of flexibility, as you can no longer try out a new attention variant by writing a few PyTorch operators. You often need to write a new custom kernel." That is the exact problem Mac users hit: you either accepted slow generic attention, or you signed up to maintain Metal by hand.

Two numbers explain why the fix is worth caring about. Apple Silicon inference is memory-bandwidth bound, so raw bandwidth largely sets your token rate. An M4 Max runs at 546 GB/s and generates roughly 60 tokens per second on Llama 3.1 8B at 4-bit quantisation, according to Apple Silicon LLM benchmarks. Cut wasted work in the attention step and you get closer to that bandwidth ceiling instead of leaving it on the table.

What FlexAttention is, in one paragraph

FlexAttention is a single API that lets you express a custom attention pattern as plain Python and have torch.compile turn it into a fused kernel. You supply two small callables. A mask_mod(b, h, q_idx, kv_idx) returns a boolean for whether a query position may attend to a key position. A score_mod adjusts the raw attention score before the softmax, which is how biases such as ALiBi or soft-capping are expressed. The compiler traces these functions, infers the block-sparsity pattern, and generates a kernel that does not materialise the full mask. The FlexAttention documentation and the MLSys 2025 paper cover the programming model in full.

The practical win is that one API covers many variants. Causal masking, document or block masking for packed sequences, sliding-window attention, PagedAttention, and additive biases all become a few lines instead of a new kernel each.

How to use it on Apple Silicon

Install PyTorch 2.13 and confirm the MPS backend is available. FlexAttention lives in torch.nn.attention.flex_attention.


            import torch
from torch.nn.attention.flex_attention import flex_attention, create_block_mask

device = "mps" if torch.backends.mps.is_available() else "cpu"

# A causal mask expressed as a predicate, not a materialised NxN tensor.
def causal(b, h, q_idx, kv_idx):
    return q_idx >= kv_idx

block_mask = create_block_mask(causal, B=None, H=None, Q_LEN=4096, KV_LEN=4096, device=device)

q = torch.randn(1, 16, 4096, 128, device=device, dtype=torch.float16)
k = torch.randn(1, 16, 4096, 128, device=device, dtype=torch.float16)
v = torch.randn(1, 16, 4096, 128, device=device, dtype=torch.float16)

# Compile once, then call in the hot path.
flex = torch.compile(flex_attention)
out = flex(q, k, v, block_mask=block_mask)
          

The create_block_mask helper builds a block-sparse representation: a query and key block is treated as sparse only if every position inside it is masked. That block view is what lets the kernel skip whole regions instead of checking element by element, and it is where the speedup on sparse patterns comes from.

A score bias looks like this. ALiBi, which penalises attention to distant tokens, is a two-line score_mod:


            def alibi(score, b, h, q_idx, kv_idx):
    bias = (q_idx - kv_idx) * get_slope(h)   # per-head slope
    return score - bias

out = flex(q, k, v, score_mod=alibi)
          

Two habits keep this fast. Compile the call once and reuse it, because tracing on every forward pass throws away the benefit. And build the BlockMask once per shape and cache it, since the mask does not change between steps for a fixed sequence layout.

What "up to 12x" really means

The 12x figure in the PyTorch 2.13 notes is a ceiling on sparse patterns, not a blanket speedup. The more of the attention matrix your mask removes, the more work the block-sparse kernel skips, and the larger the gap over SDPA with a dense mask. A long sequence with document masking, where most cross-document pairs are masked out, sits near the top of that range. A short, fully dense causal attention over 512 tokens will see little to no gain, because there is almost nothing to skip.

So the honest read is: FlexAttention on MPS helps most when your attention is both long and sparse. That covers packed training batches, retrieval-augmented prompts with many chunks, and sliding-window decoders. It does less for short-context, dense workloads, where SDPA is already close to optimal.

Remember the hardware ceiling underneath all of this. On a memory-bandwidth-bound Mac, the attention kernel is one term in the budget. An M4 Max at 546 GB/s and about 60 tokens per second on Llama 3.1 8B is limited as much by bandwidth as by the kernel, per ML Journey's Apple Silicon benchmarks. FlexAttention removes waste; it does not raise the bandwidth wall.

When to reach for it, and when not to

Scenario on Apple Silicon Recommended approach Why
Standard causal LM, short context SDPA Already close to optimal; nothing to skip
Long context with document or block masking FlexAttention (MPS) Skips masked blocks, up to 12x on sparse patterns
Custom score bias (ALiBi, soft-capping) FlexAttention score_mod Expresses the bias with no custom kernel
One fixed pattern, maximum control Hand-written Metal kernel Full control, at a higher maintenance cost
MLX-first project MLX attention Stays inside the MLX stack you already use

The decision is mostly about sparsity and maintenance. If your pattern is standard and dense, SDPA is fine. If it is custom or sparse and you do not want to own a Metal kernel, FlexAttention is the reason to be on 2.13.

Sharp edges to expect

FlexAttention is powerful, and it has edges. Block sizes matter: the block-sparse machinery assumes block-aligned shapes, and unusual block sizes have historically caused correctness and performance surprises, which the FlexAttention docs and open issues discuss. Compile time is real, so a cold torch.compile adds latency to the first call; warm it up before you benchmark. And not every mask benefits, so measure your own pattern rather than trusting the 12x headline. A quick A/B against SDPA on your real sequence length and mask is the only number that matters for your model.

For production serving specifically, treat the Mac as a development and low-concurrency target. A single-user Mac is excellent for building and testing attention variants; multi-user serving at scale still points to GPU servers, a tradeoff we cover in our guide to running local LLMs versus cloud inference for mobile apps and in the cost of self-hosting versus API inference.

India-specific considerations

For teams in India weighing local Mac development against renting cloud GPUs, the maths is about capital versus running cost. A Mac around $1,799, roughly ₹1.5 lakh at mid-2026 rates, holds a 33B-class model in unified memory and needs no per-hour GPU bill, which suits a small team iterating on attention code all day. Cloud GPUs win for bursty multi-user serving where you pay only for the hours you use.

There is a data-protection angle too. Running inference on-device keeps prompts and user data off third-party APIs, which supports the data-minimisation expectations under the Digital Personal Data Protection Act 2023. For product teams handling personal data, an on-device path built and tested on Apple Silicon can be a cleaner privacy story than routing every request to a hosted model, a theme we develop in our note on choosing between on-device and cloud AI and in the guide to Apple's on-device foundation models for Swift developers.

FAQ

How eCorpIT can help

eCorpIT is a Gurugram-based, senior-led engineering organisation (founded 2021, CMMI Level 5, MSME certified) that builds and ships AI features on Apple Silicon and in the cloud. We help teams decide where inference should run, port attention and model code to the MPS backend, and design on-device paths that keep user data local and aligned with DPDP requirements. If you are weighing a Mac-based development setup against cloud GPUs, or need help moving a model to production, talk to our team about your workload. You can also read how we approach private LLM deployment in India and iOS and Swift application development.

References

  1. PyTorch 2.13 release blog - PyTorch
  1. PyTorch 2.13.0 release notes - GitHub
  1. FlexAttention: the flexibility of PyTorch with the performance of FlashAttention - PyTorch
  1. torch.nn.attention.flex_attention documentation - PyTorch
  1. Flex Attention: a programming model for generating optimized attention kernels - MLSys 2025
  1. PyTorch FlexAttention: custom attention patterns in production - Spheron
  1. Apple Silicon LLM benchmarks: tokens per second by model and chip - LLMCheck
  1. Best Mac for local AI 2026: Apple Silicon chips ranked - Local AI Master
  1. Apple Silicon for LLMs: M3 vs M4 Max vs M4 Ultra benchmarks - ML Journey
  1. Local LLMs on Apple Silicon Mac 2026 guide - SitePoint
  1. LM Studio on M4 Max: verified MLX performance data - Markaicode

_Last updated: July 18, 2026._

Frequently asked

Quick answers.

01 What is FlexAttention in PyTorch 2.13?
FlexAttention is an API that expresses a custom attention pattern as two small Python callables, a mask predicate and a score modifier, which torch.compile fuses into a kernel. PyTorch 2.13 adds hand-written Metal kernels so it runs on Apple Silicon (MPS) with up to 12x speedups over SDPA on sparse patterns.
02 How much faster is FlexAttention on Apple Silicon?
The release cites up to 12x over scaled dot-product attention on sparse patterns. That is a ceiling, not a guarantee. The gain grows as your mask removes more of the attention matrix, so long, sparse workloads benefit most, while short dense causal attention over a few hundred tokens sees little change.
03 Do I need an NVIDIA GPU to use FlexAttention now?
No. Before PyTorch 2.13, fused attention variants effectively required NVIDIA hardware or a bespoke Metal kernel. The 2.13 Metal path covers sparse prefill and decode, including grouped-query attention, so you can build and run custom attention on a Mac using the MPS backend without leaving PyTorch.
04 When should I keep using SDPA instead?
Use SDPA for standard, dense, short-context attention, where there is almost nothing for a block-sparse kernel to skip. FlexAttention pays off when attention is both long and sparse, such as document masking for packed batches, sliding-window decoders, or retrieval prompts with many masked cross-chunk pairs.
05 What tokens-per-second can I expect on a Mac?
Speed is bandwidth-bound. An M4 Max at 546 GB/s runs roughly 60 tokens per second on Llama 3.1 8B at 4-bit, and 70B models land near 14 to 20 tokens per second on a Mac Studio M4 Max, per 2026 benchmarks. FlexAttention reduces wasted attention work but does not change the bandwidth ceiling.
06 Does FlexAttention change my model's accuracy?
No, when used correctly it computes the same attention your mask and score modifier define, just faster. The risk is not accuracy drift but correctness bugs around unusual block sizes or edge-case masks. Validate your specific pattern against a dense reference before trusting it in training or serving.
07 Is a Mac enough for production LLM serving?
For single-user or low-concurrency workloads, yes. Apple Silicon is strong for development and on-device inference thanks to unified memory. Multi-user serving at scale still favours GPU servers with higher throughput, so most teams develop attention code on a Mac and serve heavy traffic elsewhere.
08 How do I upgrade safely to PyTorch 2.13?
Install PyTorch 2.13, confirm torch.backends.mps.is_available() returns true, and run your existing tests first. Then A/B your real attention pattern against SDPA on your true sequence length, warming torch.compile before timing. Adopt FlexAttention only where the measured speedup is real for your workload.

About the author

Manu Shukla

Founder & Director

Founder of eCorpIT. Hands-on engineer leading senior-only delivery for AI apps, custom software, and cloud systems for global clients.

Subscribe

One engineering note a week. No fluff, no spam.

Senior-architect playbooks on AI agents, mobile apps, cloud, security, data, and marketing — delivered every Wednesday.

Past the reading

Read enough. Let's build something.

A senior architect responds in 24 working hours with scope, indicative cost, and a timeline. NDA before any technical conversation.