Короткий ответ: MPS быстрее, MLX вместительнее
На Mac с 16 ГБ объединённой памяти выбор между PyTorch MPS и Apple MLX решают две цифры. MPS через Hugging Face и TRL обучает LoRA в 2,2-5,7 раза быстрее, но упирается в потолок примерно на моделях 1,5B параметров. MLX через mlx-lm медленнее, зато нативная 4-битная QLoRA позволяет дообучать 3B и почти не увеличивает расход памяти при росте контекста с 1k до 4k токенов: плюс 109 МБ.
Матрица выбора короткая. Модель до 1,5B и важна скорость итераций: PyTorch MPS. Нужна 3B или длинный контекст: Apple MLX. В планах перенос пайплайна на CUDA: MPS, потому что связка PyTorch + TRL ближе к тому, что работает на NVIDIA.
Основа разбора - опубликованное сравнение 10 контролируемых запусков SFT на Qwen 2.5 (0,5B, 1,5B и 3B) с контекстом 1k-4k токенов на реальных трейсах агентов. Это не тест редакции AI-Manual: дальше разбор чужой методики и цифр, которые можно перепроверить у себя.
Почему на Mac с 16 ГБ память решает всё
На Apple Silicon нет отдельной видеопамяти. CPU, GPU и Neural Engine работают с одним пулом, который делят macOS, фоновые приложения, браузер и само обучение. Из 16 ГБ под SFT остаётся заметно меньше, и именно остаток, а не паспортный объём, определяет, влезет модель или нет.
Расход складывается из четырёх частей: веса базовой модели, состояния оптимизатора, активации и LoRA-адаптеры. Активации растут вместе с длиной контекста и размером батча, поэтому модель, которая спокойно живёт при 1k токенов, на 4k может уронить систему в swap.
Нижнюю границу полезно прикинуть по разрядности весов. В FP16 каждый параметр занимает 2 байта: 0,5B это около 1 ГБ, 1,5B около 3 ГБ, 3B около 6 ГБ. В 4 битах те же 3B укладываются примерно в 1,5 ГБ. Дальше добавляются активации, буферы и накладные расходы аллокатора, поэтому реальный потолок всегда ниже арифметического.
Как unified memory делится между системой и обучением
Объединённая память отлично масштабируется в инференсе: на Mac Studio с MLX запускают модели на сотни миллиардов параметров. Обучение упирается в другой лимит. Кроме весов нужны активации, которые растут с длиной последовательности, и состояния оптимизатора, а система в это время продолжает требовать свою долю.
Практический итог: бюджет на SFT меньше 16 ГБ, и он не фиксирован. Открытый браузер с десятком вкладок, индексация Spotlight или обновление в фоне способны превратить рабочий запуск в падение посреди эпохи. Диспетчер памяти в такой ситуации показывает не ошибку, а активный swap.
Почему MPS упирается в потолок, а MLX - нет
Причина в разрядности весов. PyTorch MPS в FP16 держит полную копию модели, поэтому на 16 ГБ предел находится примерно на 1,5B параметров. Нативная 4-битная QLoRA в MLX хранит веса в 4 битах и разворачивает их на лету, так что модель 3B помещается там, где MPS уже не влезает.
У экономии есть цена: деквантование выполняется при каждом матричном умножении, и на прямом проходе, и на обратном. Выигрыш MLX по вместимости - прямое следствие квантования, а не какая-то отдельная магия фреймворка. И этот же механизм объясняет часть отставания по скорости.
Скорость: насколько MPS быстрее и откуда берётся разрыв
В опубликованных замерах PyTorch MPS обгоняет MLX в 2,2-5,7 раза. Разброс зависит от размера модели и длины контекста: чем крупнее модель и длиннее последовательность, тем хуже для MLX, тогда как MPS остаётся относительно стабильным, пока модель помещается в память.
Перевести это в часы просто. Если эпоха на MPS идёт час, те же шаги на MLX легко растянутся на несколько часов. Для отладки пайплайна это терпимо, для перебора гиперпараметров уже нет: за вечер вы успеете прогнать втрое-впятеро меньше конфигураций.
Что даёт отказ от квантования в MLX
Первая гипотеза обычно такая: MLX тормозит из-за 4-битных весов, которые приходится возвращать в FP16 перед каждым умножением. Гипотезу проверили: в двух из десяти запусков MLX работал без квантования. Устранение накладных расходов на деквантование сократило разрыв лишь в 1,07-1,4 раза в зависимости от размера модели, после чего осталось примерно 4,1-4,6-кратное отставание на уровне фреймворка.
Вывод неприятный для MLX. Узкое место - не квантование, а сам фреймворк: насколько он зрелый и как хорошо оптимизирован под Metal. Ускорять деквантование смысла мало, это даст проценты, а не кратный выигрыш. Основную разницу создаёт инженерия PyTorch и MPS-бэкенда.
Не портит ли 4-битная QLoRA качество: сходимость на трейсах агентов
Экономия памяти в MLX выглядит подозрительно: 4 бита на вес читаются как компромисс по качеству. В опубликованном сравнении её проверяли не на синтетике, а на реальных многоходовых трейсах агентов из датасета badlogicgames/pi-mono. Причина в том, что большинство гайдов по дообучению берут одноходовые наборы инструкций длиной 256-512 токенов, а настоящая сессия автономного агента выглядит иначе: длиннее, с вызовами инструментов и накопленной историей.
Loss на валидации на Qwen 2.5 1,5B с контекстом 2k: 0,462 у MPS против 0,478 у MLX. Разница около 0,016, то есть примерно 3,5% в относительном выражении. Для SFT на агентных трейсах разрыв небольшой, и он не подтверждает тезис «4 бита портят модель».
Осторожность нужна в другом. Цифры получены на одной конфигурации: конкретная модель, конкретная длина контекста, конкретный датасет. На 3B, на другом домене или при иной схеме квантования результат может отличаться, поэтому переносить вывод на любые задачи нельзя.
Как проводилось сравнение: методика, которую можно повторить
Дизайн описан достаточно, чтобы повторить замеры у себя. 10 контролируемых экспериментов SFT с LoRA, модели Qwen 2.5 на 0,5B, 1,5B и 3B, контекст 1k-4k токенов, датасет badlogicgames/pi-mono, логирование каждого шага в Trackio. Первый стек: PyTorch MPS плюс Hugging Face/TRL. Второй: Apple MLX плюс mlx-lm.
Оба стека на Apple Silicon ведут себя иначе, чем привычный CUDA-пайплайн. Опыт с NVIDIA сюда не переносится напрямую: другие аллокаторы, другой профиль памяти, другие узкие места. Цифры, снятые на CUDA, не стоит проецировать на Mac без перепроверки.
Чек-лист для собственного замера:
- зафиксировать модель и её разрядность;
- зафиксировать длину контекста и размер батча;
- задать число шагов и seed;
- замерять пиковое потребление памяти и время на шаг;
- логировать loss на валидации, а не только на трейне.
Практические грабли на Mac и как их обходить
Проблемы на 16 ГБ начинаются не с ошибки в коде, а с памяти. Что ломает запуск чаще всего:
- контекст, взятый «с запасом»: активации растут вместе с ним и съедают запас первыми;
- фрагментация и поведение аллокатора, из-за которых macOS начинает задыхаться прямо посреди обучения, даже когда средний расход выглядит нормально;
- слишком крупная модель под MPS: выше примерно 1,5B обучение упирается в потолок;
- недооценка времени итераций на MLX: один прогон терпим, серия уже нет.
Приёмы простые. Начинайте с 0,5B, чтобы отладить пайплайн и датасет, и только потом переходите на 1,5B или 3B. Держите контекст минимально достаточным: для агентных трейсов часто хватает 2k, а 4k берите осознанно и на MLX. Следите за swap и закрывайте фоновые приложения перед запуском. Для 3B и контекста 4k выбирайте MLX: там рост с 1k до 4k добавляет всего 109 МБ.
Критерии выбора: MPS или MLX под вашу задачу
Свести выбор помогает таблица. Она собрана по результатам того же сравнения и действует в границах 16 ГБ объединённой памяти.
| Критерий | PyTorch MPS (HF/TRL) | Apple MLX (mlx-lm) |
|---|---|---|
| Модель до 1,5B | да, FP16 | да |
| Модель 3B | нет, упирается в память | да, нативная 4-битная QLoRA |
| Контекст 1k | быстрее в 2,2-5,7 раза | медленнее |
| Контекст 4k | резко упирается в потолок памяти | рост с 1k всего +109 МБ |
| Loss на валидации (1,5B, 2k) | 0,462 | 0,478 |
| Перенос на CUDA | ближе к пайплайну NVIDIA | потребует переписывания |
Полезно не путать роли. MLX сильнее в инференсе, чем в обучении: в сводке по локальному запуску Qwen 3.8 27B MLX указан с 38,36 tok/s на Apple Silicon, тогда как Ollama с GGUF даёт 11,78 tok/s. Тормознутость в SFT не отменяет того, что для генерации этот стек остаётся основным на Mac.
Если планируете перенос на CUDA
Связка PyTorch + Hugging Face/TRL ближе к тому, что вы запустите на NVIDIA: те же библиотеки, тот же формат конфигов, знакомый цикл обучения. MLX - нативный Apple-фреймворк, и при переезде на CUDA его придётся переписывать. Если Mac для вас промежуточный этап, MPS экономит время на миграцию, даже когда MLX технически вместительнее.
Для регулярного обучения моделей крупнее 3B Mac с 16 ГБ не подходит: разумнее арендовать GPU. Сравнение RTX 5090 и M5 Ultra Mac Studio показывает расклад по памяти и экосистеме, а разбор экономики инференса на Apple Silicon помогает посчитать стоимость токена, если после обучения модель будет работать локально.
Практический вывод для 16 ГБ: держите оба стека под рукой. MPS ставьте по умолчанию для моделей до 1,5B и короткого контекста, MLX включайте, когда нужна 3B или контекст 4k. Первый же прогон на своей модели и своём датасете покажет, что ограничивает именно ваш сценарий: скорость шага или доступная память.