Why 64 probably fails on a base M1 or M2
Batch 64 works on the M4 Pro because each GPU kernel finishes quickly enough for the page to get the GPU back in time. A 7B batch-64 step there takes about 200 ms in total (4,000 tokens in 12.8 s at 64 per step), and the page still stays smooth. So the total length of a step isn't what matters. The length of each kernel inside it is, and that scales with tokens per batch times model width, divided by GPU speed.
14B prefills 2.07× slower than 7B on this machine (23.7 s vs 11.4 s cold at 4k). That is the same ratio as the M4 Pro to a base M2 with 10 GPU cores in llama.cpp's own Apple Silicon numbers. So 14B on the M4 Pro is a stand-in for 7B on a base M2 or M3, and at batch 64 it still drops 31%.
7B Q4_0 prompt processing (pp512), from the llama.cpp Apple Silicon benchmark thread (ggml-org/llama.cpp discussion #4167). The prediction is what I'd expect for 7B Q4_K_M from the proxy ratio. It hasn't been measured.
Two effects pull in opposite directions, so treat this as a prediction to test. Base MacBook Airs have 60 Hz displays, which gives twice the frame budget (Safari at 60 Hz dropped 14.5% where Brave at 120 Hz dropped 64%). A smaller GPU also renders the page itself more slowly, which leaves less headroom. ./reproduce.sh settles it on a real Air in 15 minutes.
Small fixed values cost a lot more on slow machines. Batch 32 already costs 7B 17% TTFT on the M4 Pro. A cold 4k prefill on an M1 takes 35–40 s before any penalty, so a constant small enough for the slowest machine taxes every other machine all the time.