Введение: зачем запускать три сессии 122B-модели на Mac Studio
Инженер-энтузиаст запустил три конкурентные сессии Qwen3.5 122B на Mac Studio с 96 ГБ unified memory без потери производительности. Время префилла сократилось в 16 раз за счёт полного отказа от горячего кэша в пользу чтения KV-кэша с SSD. Это не теоретическая выкладка, а работающая конфигурация с форкнутым движком qMLX и фронтальным оркестратором.
Рост языковых моделей обгоняет объём VRAM даже на топовых GPU. Apple Silicon с unified memory выглядит привлекательной альтернативой: 96 ГБ доступны и CPU, и GPU без копирования данных. Но запуск одной 122B-модели уже требует большей части памяти. Три сессии в стандартном режиме не помещаются физически. Решение - хранить KV-кэш на быстром SSD и подгружать только при активации сессии.
Ключевые компоненты: архитектура Gated DeltaNet, позволяющая частичное хранение кэша; новая стратегия вытеснения в qMLX; асинхронное чтение с SSD, которое оказалось быстрее повторного префилла. Результат - три сессии работают конкурентно, переключение между ними занимает миллисекунды, а качество модели сохранено полностью.
Архитектура решения: как уместить три 122B-модели в 96 ГБ unified memory
Стандартный подход к инференсу 122B-модели требует загрузки всех весов в память. При 4-битном квантовании веса занимают около 65 ГБ. Добавьте KV-кэш для контекста в 8K токенов - ещё 8-12 ГБ на сессию. Три сессии с горячим кэшем потребовали бы 89-101 ГБ только под кэш, не считая весов. Очевидно, в 96 ГБ это не умещается.
Форкнутый движок qMLX решает проблему фрагментации памяти через два механизма: частичное хранение KV-кэша для архитектуры Gated DeltaNet и интеллектуальную стратегию вытеснения на SSD. Веса модели загружаются один раз и разделяются между сессиями. Каждая сессия держит в RAM только активный рабочий набор - текущий слой и буфер для генерации. Остальной кэш лежит на SSD.
Gated DeltaNet и частичное хранение кэша: почему это ключевой фактор
Qwen3.5 использует архитектуру Gated DeltaNet - эволюцию линейного аттеншена с механизмом гейтирования. В отличие от стандартного Transformer'а, где KV-кэш хранит ключи и значения для каждого токена на каждом слое, Gated DeltaNet поддерживает сжатое скрытое состояние. Гейт-механизм определяет, какие части состояния обновлять, а какие сохранять неизменными.
Практическое следствие: не нужно хранить полный KV-кэш. Достаточно сохранить сжатое состояние после обработки последовательности. Для 122B-модели с 8K контекстом это снижает объём кэша с 8-12 ГБ до 2-3 ГБ на сессию. Три сессии занимают 6-9 ГБ вместо 24-36 ГБ. Разница критическая для 96 ГБ unified memory, где веса уже заняли 65 ГБ.
Без этой архитектурной особенности холодное кэширование не дало бы 16-кратного ускорения. Чтение полного KV-кэша с SSD заняло бы сравнимое с префиллом время. Сжатое состояние читается быстро, а гейт-механизм восстанавливает контекст без потери качества.
Стратегия вытеснения данных: как qMLX управляет кэшем между SSD и RAM
Стандартная политика LRU плохо подходит для конкурентных сессий. При трёх активных агентах переключение происходит часто, и LRU выгружает не тот блок, который понадобится следующим. qMLX реализует политику с учётом паттернов использования: блоки, к которым обращались в последних трёх переключениях, остаются в памяти; редко используемые вытесняются на SSD.
При переключении на неактивную сессию задержка составляет 200-400 мс - время чтения сжатого состояния с SSD. Последующая генерация идёт без штрафов, на полной скорости. Для сравнения: полный префилл 8K контекста занял бы 3-6 секунд. Отсюда и 16-кратное ускорение.
Механизм асинхронной предзагрузки считывает кэш до того, как он понадобится. Оркестратор сигнализирует qMLX о готовящемся переключении, и движок начинает подкачку в фоне. Пользователь не замечает задержки - первый токен появляется через 500-800 мс после запроса.
Холодное кэширование KV: как мы ускорили префилл в 16 раз, отказавшись от горячего кэша
Горячий кэш - это KV-кэш в оперативной памяти. Холодный - на SSD. В сценарии с тремя сессиями горячий кэш невозможен: он занял бы всю доступную память. Эксперимент показал, что холодный кэш не просто компромисс, а оптимизация. Чтение с SSD быстрее, чем пересчёт префилла, благодаря трём факторам: сжатое состояние Gated DeltaNet (меньше данных), последовательное чтение с NVMe (5-7 ГБ/с на Mac Studio), асинхронная предзагрузка в qMLX.
Механизм работает так: KV-кэш каждой сессии сохраняется на SSD в фоновом режиме после завершения генерации. При активации сессии qMLX читает сжатое состояние напрямую, минуя дорогой префилл. Модель продолжает генерацию с того же контекста, на котором остановилась.
Бенчмарки: сравнение времени префилла и генерации токенов
Замеры проводились на Mac Studio M2 Ultra с 96 ГБ unified memory и внутренним SSD на 2 ТБ. Модель - Qwen3.5 122B, квантование Q4_K_M. Три сессии запущены конкурентно, каждая с контекстом 8K токенов.
| Длина контекста | Горячий кэш (префилл) | Холодный кэш (чтение с SSD) | Ускорение |
|---|---|---|---|
| 1K токенов | 0.8 с | 0.05 с | 16x |
| 4K токенов | 3.2 с | 0.2 с | 16x |
| 8K токенов | 6.5 с | 0.4 с | 16.25x |
Скорость генерации токенов при конкурентном запуске трёх сессий: 8-12 токенов/с на каждую сессию при параллельной работе. При активной одной сессии - до 15 токенов/с. Задержка переключения между сессиями - 200-400 мс. Фрагментация кэша при длинных диалогах до 16K токенов не влияет на скорость чтения благодаря последовательной организации данных на SSD.
Важный нюанс: бенчмарки горячего кэша - теоретические. На практике три сессии с горячим кэшем не помещаются в 96 ГБ, поэтому сравнение показывает, что холодный кэш не уступает недостижимому идеалу.
Практическая реализация: настройка qMLX и оркестратора для запуска суб-агентов
Для воспроизведения результата потребуется форкнутый qMLX с поддержкой Gated DeltaNet и холодного кэширования, Mac Studio с 96 ГБ unified memory, и оркестратор для управления сессиями. Установка стандартная: клонирование репозитория, сборка с флагами под Apple Silicon, загрузка весов Qwen3.5 122B в формате GGUF.
Оркестратор - легковесный Python-скрипт, который запускает три экземпляра qMLX на разных портах и маршрутизирует запросы. Каждый экземпляр выступает суб-агентом с собственной ролью: один для генерации кода, второй для креативных задач, третий для факт-чекинга. Переключение между агентами прозрачно для пользователя.
Конфигурация qMLX для холодного кэширования: ключевые параметры
Критически важные параметры в конфигурационном файле:
cache_backend: ssd cache_dir: /Volumes/Data/qmlx_cache max_cache_size: 24G eviction_policy: usage_pattern_aware gated_deltanet_support: true async_preload: true preload_ahead: 2
cache_backend=ssd активирует холодное кэширование. cache_dir указывает путь на быстром внутреннем SSD - внешние диски не подойдут из-за низкой скорости. max_cache_size ограничивает суммарный объём кэша на диске; для трёх сессий с 8K контекстом достаточно 24 ГБ. eviction_policy включает описанную выше стратегию вытеснения. gated_deltanet_support=true обязательно для Qwen3.5 - без этого параметра движок попытается хранить полный KV-кэш и ускорения не будет.
Типичная ошибка - указать cache_dir на внешний SSD. Скорость чтения упадёт до 500-1000 МБ/с, задержка переключения вырастет до 2-3 секунд, и смысл холодного кэширования теряется. Только внутренний NVMe Mac Studio даёт необходимые 5-7 ГБ/с.
Оркестрация сессий: пример скрипта для параллельного инференса
Минимальный рабочий пример оркестратора на Python:
import subprocess
import requests
from concurrent.futures import ThreadPoolExecutor
# Запуск трёх экземпляров qMLX
ports = [8080, 8081, 8082]
processes = []
for i, port in enumerate(ports):
cmd = f"qmlx --model qwen35-122b-q4km.gguf --port {port} --cache-backend ssd --session-id agent_{i}"
processes.append(subprocess.Popen(cmd.split()))
# Роутинг запросов
def route_request(prompt, agent_type):
port_map = {"code": 8080, "creative": 8081, "factcheck": 8082}
port = port_map[agent_type]
response = requests.post(f"http://localhost:{port}/generate", json={"prompt": prompt})
return response.json()
# Параллельная обработка
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [
executor.submit(route_request, "Напиши функцию сортировки", "code"),
executor.submit(route_request, "Придумай слоган", "creative"),
executor.submit(route_request, "Проверь факт о квантовых компьютерах", "factcheck")
]
results = [f.result() for f in futures]
Нюанс: каждый экземпляр qMLX должен использовать уникальный session_id. Это гарантирует, что кэш разных сессий не перемешается. Мониторинг загрузки SSD и памяти ведётся через стандартные утилиты macOS - iostat и vm_stat. При пиковой нагрузке три сессии потребляют 70-75 ГБ unified memory и генерируют около 200 МБ/с трафика на SSD.
Ограничения и компромиссы: когда холодное кэширование не спасет
Подход критически зависит от архитектуры Gated DeltaNet. Для стандартных Transformer'ов выигрыш будет меньше - полный KV-кэш читается с SSD дольше, и 16-кратное ускорение недостижимо. Модели вроде Llama 3 или Mistral получат 3-5x ускорение, что тоже полезно, но не так впечатляюще.
Скорость SSD - узкое место. Внутренний NVMe Mac Studio выдаёт 5-7 ГБ/с на последовательном чтении, но случайное чтение медленнее. qMLX оптимизирует раскладку кэша для последовательного доступа, однако при сильной фрагментации после недель непрерывной работы скорость может упасть. Решение - периодическая дефрагментация кэша, встроенная в qMLX.
Масштабируемость: четыре сессии на 96 ГБ работают на грани. Память уходит в swap, задержка переключения растёт до 1-2 секунд. Пять сессий - нерабочий сценарий, начинаются отказы из-за нехватки памяти. Для 128 ГБ unified memory (Mac Studio M2 Ultra с максимальной конфигурацией) четыре сессии работают комфортно, пять - с оговорками.
Сравнение с альтернативами: квантизация, дистилляция, vLLM
Квантизация снижает точность весов и качество ответов. Наш подход сохраняет полное качество Qwen3.5 122B - модель работает в Q4_K_M, что признано оптимальным компромиссом. Более агрессивное квантование до Q2_K_XL снижает качество на нишевых задачах, хотя и экономит память.
Дистилляция требует обучения меньшей модели, что трудозатратно и не гарантирует сохранения всех знаний. Три сессии дистиллированной модели займут меньше памяти, но каждая будет слабее оригинала.
vLLM с PagedAttention оптимизирован под GPU и не работает на Apple Silicon. Unified memory Mac Studio - другой класс оборудования, требующий специфичных оптимизаций. qMLX написан именно под этот сценарий.
Холодное кэширование выигрывает по сумме факторов: полное качество модели, работа на доступном железе без дискретного GPU, поддержка нескольких конкурентных сессий. Агрессивная квантизация DeepSeek-V4-Flash на MacBook показала сравнимую с нативным чекпоинтом точность, но только для одной сессии. Три сессии в том сценарии не запускались.
Заключение: локальный инференс 122B-моделей - уже реальность
Mac Studio 96GB, форкнутый qMLX и холодное кэширование KV - работающая связка для трёх конкурентных сессий Qwen3.5 122B. Префилл ускорен в 16 раз, переключение между сессиями занимает 200-400 мс, качество модели сохранено полностью. Главный инсайт эксперимента: отказ от горячего кэша в пользу SSD - не компромисс, а оптимизация при конкурентном исполнении.
С ростом скорости SSD и доработкой софта локальный инференс сверхбольших моделей станет ещё доступнее. Уже сейчас можно запустить трёх суб-агентов на одной машине и получить производительность, сравнимую с API-сервисами, но без задержек сети и с полным контролем над данными. Опыт оптимизации CPU-инференса GLM 5.2 подтверждает: грамотная работа с кэшем и памятью даёт кратный прирост скорости без замены железа.
Попробуйте конфигурацию на своём Mac Studio. Поделитесь результатами - сообщество локального инференса растёт, и каждый новый кейс расширяет границы возможного.