Qwen3.8-Flash-Next на MacBook с 64 ГБ: файлы, кванты и флаги llama.cpp
Как запустить MoE на 180 млрд параметров на M4 Max или M1 Max без выгрузки на CPU: какой GGUF выбрать, как n-gram таблица разбита по шардам и точная команда llama-server.
Файлы Qwen3.8-Flash-Next в сумме весят 88 гигабайт, и модель хорошо работает на связке из трёх RTX 3090. После нескольких дней регулярного использования впечатление устойчивое: она думает меньше, чем Qwen3.8-27B, но справляется почти с любой задачей. Меньше болтовни, меньше зацикливаний и больше настоящих ответов. Для модели с 6 миллиардами активных параметров такое сочетание краткости и толковости — редкость.
Игровые GPU в стойке — это одно, но архитектурное изменение в этой модели наводит на другой вопрос. Запустится ли она на MacBook? То есть на одном ноутбуке с 64 ГБ единой памяти — на машине, которую берут с собой в самолёт и которой обычно не доверяют модель на 180 миллиардов параметров.
Два дня тестов на M4 Max и M1 Max, оба с 64 ГБ, дали ответ: да. Рассчитывайте на 25–30 токенов в секунду при декодировании и около 400 токенов в секунду на prefill, причём без всякой выгрузки на CPU.
Ключевое здесь — «без выгрузки». Серверу с тремя 3090 приходится гонять экспертов через системную RAM, а ноутбук просто загружает модель и работает. M1 Max — чип шестилетней давности из первого поколения Apple silicon, и всё равно он выдаёт примерно две трети скорости M4 Max. Этим вполне можно пользоваться.
Дальше — как всё это настроить.
Какой файл качать: не самый известный
Здесь есть ловушка. Самая популярная квантизация этой модели — GGUF от Unsloth. Для Linux-сервера это правильный файл, а для Mac — неправильный, и README самого Unsloth это признаёт, требуя на macOS 75–96 ГБ памяти.
Причина — особенность того, как графический драйвер Apple обращается с памятью. В ней стоит разобраться, потому что она объясняет всё остальное.
llama.cpp загружает модели через отображение файла в память (mmap). Операционная система выдаёт указатель, а страницы читаются по требованию. В Linux это работает полностью лениво: страницы, к которым обращаются, загружаются, а остальные могут оставаться на диске или вытесняться, когда место нужно чему-то ещё.
Metal, графический API Apple, всё усложняет. Когда llama.cpp передаёт Metal отображённый в память шард, этот шард целиком становится wired. То есть он закрепляется в RAM, гарантированно присутствует и не может быть вытеснен. В шардах Unsloth веса модели перемешаны с n-gram таблицей внутри одних и тех же файлов. Поэтому, когда Metal запрашивает один тензор весов, он заодно закрепляет гигабайты таблицы. На Mac с 64 ГБ результат — мгновенная ошибка нехватки памяти ещё до первого токена.
Напомним, что это за n-gram таблица. Это «второй картотечный шкаф» на 29 ГБ, который вообще не считает, а только служит справочником — примерно 2,7 килобайта на сгенерированный токен. При 30 токенах в секунду это около 3 МБ/с чтения — нагрузка, с которой справилась бы флешка 2012 года. Таблице никогда не нужна была быстрая память. Ей нужно только быть доступной.
Раскладка Unsloth случайно загоняет её в быструю память. В Linux размещение можно переопределить для каждого тензора, но в Metal такого контроля нет. Значит, решение должно быть структурным: положить таблицу в шард без GPU-тензоров, чтобы ничто не заставляло её закреплять.
Именно это и делают сборки AtomicChat M64. Каждый их квант перепакован так, что в шарде 2 лежит только n-gram таблица. Таблица подтягивается с SSD постранично через кеш ОС, как и задумано архитектурой, а wired становятся только настоящие вычислительные веса.
Отсюда и метка «M64». Она обозначает семейство раскладок, придуманное под Mac с 64 ГБ, — перепаковку с разделёнными шардами, — и ничего не обещает насчёт размера. Суффикс есть у всех трёх их сборок, включая 110-гигабайтную для машин со 128 ГБ. Поместится ли сборка на ваш компьютер, решает число бит на вес, а не суффикс.
Есть и вторая причина выбрать их — качество. Сборщик начинал с оригиналов в BF16, использовал собственную опубликованную матрицу важности, а затем сравнил каждую сборку с реальными выходами эталонной модели. Сырые логи KLD и эталонные логиты опубликованы — это больше прозрачности, чем дают большинство авторов квантов.
Какой квант: 3.84 или 4.27?
На Mac с 64 ГБ важны две сборки. Обе использовались как основная модель целыми днями. Замеры на M4 Max с 64 ГБ:
| Build | Decode | Prefill | Max context | Resident RAM |
|---------------------------|---------|---------|-------------|--------------|
| AD-3.84bpw-IQ4_XS-M64 | 28-32/s | ~400/s | 220,000 | 45.8 GB |
| AD-4.27bpw-Q4_K_M-M64 | ~25/s | ~350/s | 144,000 | 54.5 GB |
Компромисс необычно чистый. 4.27 даёт заметно лучшее качество: расхождение с моделью полной точности у неё меньше половины от расхождения 3.84. Взамен она стоит скорости и 8,7 ГБ драгоценной резидентной памяти — поэтому её контекст ограничен 144K, а не 220K.
Для ежедневной работы лучше 3.84, и причина одна — контекст. Окно в 220 000 токенов при 30 токенах в секунду — более приятный спутник, чем окно в 144 000 при 25. Загрузка целых кодовых баз, полных коллекций заметок и всей истории проекта — вот где размер окна чувствуется весь день, а разница в качестве проявляется лишь в пограничных случаях раз в неделю.
Выбирайте по нагрузке. Если постоянно скармливаете длинные документы — берите 3.84. Если делаете точные рассуждения на коротких входах и разница в качестве вам мешает — берите 4.27. Она влезает в 64 ГБ, но Mac становится машиной одной модели, полностью.
Имена врут. Хорошо врут, но врут.
Эта часть наделала шуму на Reddit, поэтому скажем прямо: ни «IQ4_XS», ни «Q4_K_M» в именах этих файлов не описывают, что внутри.
Сборки AtomicChat — смешанные рецепты. Разные части модели получают разные типы квантизации, а в имени файла стоит лишь ближайший стандартный тип к среднему числу бит на вес — карточка модели говорит об этом прямо. Вот что на самом деле внутри каждой сборки.
AD-3.84bpw-IQ4_XS-M64
| AD-3.84bpw-IQ4_XS-M64 | Real type | Share | Why |
|------------------------|---------------|-------|-------------------------|
| n-gram table | ~6-bit | 46% | memorized hints, cheap |
| MoE expert body | IQ1_M (1.75b) | ~40% | 512 experts, 2% active |
| dense layers, heads | Q6_K/Q8_0 | ~14% | the parts that think |
AD-4.27bpw-Q4_K_M-M64
| AD-4.27bpw-Q4_K_M-M64 | Real type | Share | bpw contribution |
|------------------------|----------------|-------|------------------|
| n-gram table | Q5_1 | 41% | 1.74 |
| ffn_gate/up experts | IQ2_S (IQ3_S*) | 29% | 1.24 |
| ffn_down experts | IQ4_NL | 24% | 1.03 |
| everything else | Q8_0 | 5% | 0.23 |
Вдобавок слои с 0 по 3 и с 40 по 47 получают более точный IQ3_S. Статистика матрицы важности показала, что энергия активаций скапливается в последних слоях, и равномерное распределение бит потратило бы их впустую на слои с 4 по 39.
Считается ли это жульничеством? Комментаторы на Reddit сказали, что да. Цифры говорят об обратном: они показывают, что откалиброванный рецепт делает ровно то, для чего задуман. По сравнению с полной моделью в BF16 сборка 4.27 выбирает тот же самый топовый токен в 89,5% случаев, а её перплексия выше всего на 2,6% (отношение 1,026). Биты не выбросили, а перераспределили. Эксперта, к которому токен обращается примерно в 2% случаев, можно сильно сжать, а плотные слои, через которые проходит каждый токен, остаются большими. Сама архитектура делает ту же ставку — здесь она просто применена уровнем ниже, к квантизации.
Команда
Сначала обновите и пересоберите llama.cpp. Поддержка архитектуры qwen4exp попала в mainline 27 августа, и всё быстро меняется:
cd ~/github_repos/llama.cpp
git pull
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j
Затем поднимите потолок памяти для GPU. На машине с 64 ГБ macOS ограничивает его примерно 48 ГБ, а настройка сбрасывается при каждой перезагрузке:
sudo sysctl iogpu.wired_limit_mb=57344
Потом запустите сервер:
llama-server \
-m /Users/andrewzhu/ai_models/Qwen3.8-Flash-Next-AD-3.84bpw-IQ4_XS-M64/Qwen3.8-Flash-Next-AD-3.84bpw-IQ4_XS-M64-00001-of-00028.gguf \
--alias Qwen3.8-Flash-Next \
--jinja \
-ngl 99 \
-c 168000 \
-fit off \
--host 0.0.0.0 --port 8083 \
--metrics \
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0 \
--reasoning-format none \
--parallel 1
Четыре детали этой команды важнее, чем кажутся.
-fit off обязателен. Автоматический подборщик памяти в llama.cpp неверно оценивает эту архитектуру и не может выделить память. Без флага сервер падает при запуске на машине с запасом памяти, и ошибка выглядит точь-в-точь как «не хватает RAM» — люди начинают мучительные поиски. На Linux-сборках флаг не требовался, а на Mac нужен.
Переопределения -ot нет. На Linux-сервере n-gram таблицу нужно закрепить за CPU — это делается регулярным выражением -ot '^per_layer_token_embd\.weight$=CPU'. Mac может это пропустить. При раскладке с разделёнными шардами таблица сама уходит на хост, потому что в её шарде нет ничего, что заставило бы Metal её закрепить. Устройство шардов уже решает ту проблему, которую решало регулярное выражение.
Флага --load-mode тоже нет, так что остаётся mmap по умолчанию. На Linux-машине со 128 ГБ можно отключить mmap и прочитать всё один раз. На Mac mmap — это и есть нужная функция. Он позволяет ОС подгружать и выгружать 39-гигабайтную таблицу с SSD по мере того, как её потребляют токены. Если его отключить, система попытается сделать резидентными все 85 ГБ, а у ноутбука только 64.
Наконец, нет -ncmoe. Конфигурации с одной 3090 нужно около 43 ГБ экспертов, припаркованных в системной RAM. На Mac вся резидентная часть, 45,8 ГБ, помещается под лимит wired-памяти в 56 ГБ, так что выгружать ничего не нужно. Единая память просто вмещает всё. Это первая машина, где ответ на вопрос «что куда?» звучит так: «всё, что важно, туда, где важно, сразу».
Старый ноутбук тоже справляется
Та же настройка работает и на M1 Max с 64 ГБ. Это первый серьёзный рывок Apple silicon, вышедший шесть лет назад, когда 64 ГБ в ноутбуке были хвастовством в спецификациях, а не требованием для инференса.
Он выдаёт примерно две трети скорости M4 Max с той же моделью, тем же файлом и теми же флагами. Один из рабочих вариантов — перенести повседневную работу на M1 Max, а M4 Max оставить с одной задачей: эта модель, всегда загруженная, отвечает со скоростью 30 токенов в секунду на соседнем столе.
Есть две оговорки, и о них стоит сказать без прикрас.
Машина занята. Пока модель загружена, давление на память остаётся высоким, так что закройте вкладки браузера и чаты: этот Mac теперь делает одно дело. Ради этого и стоит иметь два.
SSD работает. Таблица подгружается постоянно. Пропускная способность скромная, но за месяцы это даёт реальный износ, а на долгих сессиях раскручиваются вентиляторы. Положить файлы модели во внешний корпус USB4 NVMe — жест доброй воли по отношению к внутреннему накопителю.
Но взгляните на картину шире. Ноутбук, купленный для кода и монтажа видео, теперь запускает модель, которая на равных бьётся с передовыми ИИ. У модели 180 миллиардов параметров, и она живёт на железе, охлаждение которого никогда не настраивали под тензорные нагрузки. Ни дата-центра, ни кластера, ни счёта за API. Архитектура пришла к железу, а не наоборот.
Вот в чём настоящая история Qwen3.8-Flash-Next. Большие модели не стали меньше. Умным моделям стали рады.