macOS VM + llama.cpp: в 16× быстрее на Apple Silicon
Как команда Cua разогнала LLM-инференс внутри macOS VM до 98% скорости bare-metal с помощью шима Metal и llama.cpp.
Когда «медленная VM» — это просто неправильно настроенный Metal
Представьте: вы запускаете llama.cpp внутри macOS-виртуальной машины на M1 Ultra, ожидаете хоть какое-то GPU-ускорение — и получаете 432 токена в секунду при обработке промпта. Кажется, неплохо? Только вот на bare-metal тот же чип выдаёт тысячи токенов. Виноват не гипервизор, не память и не квантизация — виновата пара строк в коде, из-за которых llama.cpp выбирает не те Metal-ядра внутри гостевой ОС.
Именно эту проблему вскрыла и решила команда проекта Cua. Результат — на M1 Ultra TinyLlama 1.1B в llama.cpp обрабатывает промпты в 11,08× быстрее, а генерирует токены в 16,36× быстрее по сравнению со стандартной VM без патча. И это не теория: обработка промптов достигла 98% от результата bare-metal.
Разберём, как устроена проблема, что именно изменилось и почему это важно для всех, кто строит локальные AI-агенты или CI/CD-пайплайны на Apple Silicon.
Почему GPU в macOS VM — это исторически боль
Apple Silicon Mac с macOS всегда имел серьёзное ограничение: GPU нельзя было использовать в контейнерах или виртуальных машинах. Это делало VM-среды пригодными только для CPU-нагрузок.
GPU Apple Silicon нельзя напрямую «пробросить» в Linux VM как PCI-устройство, поскольку macOS нуждается в нём для отображения. Вместо этого применяется паравиртуализация: гостевая ОС получает виртуальное GPU-устройство через virtio-gpu, что позволяет разделять память и командные потоки между гостем и хостом.
Для macOS-гостя ситуация иная: Apple’s Virtualization.framework предоставляет виртуальный GPU напрямую гостевой macOS. Но до недавнего времени llama.cpp внутри гостя не умел использовать этот путь правильно.
CUDA долго доминировала в GPU-ускоренном инференсе, но Metal значительно повзрослел во всех крупных фреймворках. Ollama, llama.cpp и собственный фреймворк Apple MLX воспринимают Metal как первоклассный бэкенд.
Анатомия прорыва: шим, который разблокировал Metal
Команда Cua обнаружила, что виртуальный GPU от Apple Virtualization.framework физически существует и работает — но llama.cpp внутри гостя получал от него ложный ответ на вопрос о поддерживаемых возможностях, и поэтому откатывался на медленный путь исполнения.
Шим разблокирует Metal-возможности на существующем виртуальном GPU-пути Apple. Это не хак ядра и не нарушение границ виртуализации — лишь корректный ответ на capability probe, который llama.cpp отправляет при старте.
Тестовая конфигурация
Тест проводился на Apple M1 Ultra с 48-ядерным GPU и macOS 26.6.1. Гостевой системой была публичная Tahoe Cua image (macOS 26.5.2, 8 vCPU, 16 GiB) под управлением Lume 0.5.1. Во всех трёх прогонах использовался официальный релиз llama.cpp b10167 и одна и та же модель TinyLlama 1.1B Chat Q4_K_M.
graph TD
A["llama.cpp запускается в macOS VM"] --> B["Capability probe к виртуальному GPU"]
B --> C{"Стандартная VM"}
B --> D{"VM + Metal шим"}
C --> E["Получает: Metal ограничен"]
D --> F["Получает: Metal доступен"]
E --> G["Медленный путь: 432 tok/s PP"]
F --> H["Быстрый путь: 4787 tok/s PP"]
H --> I["≈98% от bare-metal"]
На тестовой машине два точечных изменения возможностей подняли обработку промптов TinyLlama с 432 до 4787 токенов в секунду.
Бенчмарки: TinyLlama и Gemma 4 12B
TinyLlama 1.1B (Q4_K_M)
| Метрика | Stock VM | VM + шим | Bare-metal | Прирост (VM→шим) |
|---|---|---|---|---|
| Prompt Processing (tok/s) | 432 | 4 787 | ~4 880 | +11,08× |
| Token Generation (tok/s) | ~3,5 | ~57 | ~79 | +16,36× |
| PP как % от bare-metal | ~9% | 98% | 100% | — |
Обработка промптов практически достигла результата хоста. Генерация достигла 72,06% скорости хоста — измеримый разрыв VM всё ещё остаётся.
Gemma 4 12B (QAT Q4_0, 6.98 GB)
Также была протестирована официальная Gemma 4 12B instruction-tuned QAT Q4_0 GGUF от Google — модель, которую разработчики реально используют сегодня.
С Gemma 4 12B обработка промптов выросла с 71,66 до 515,76 токенов в секунду, а генерация — с 3,41 до 49,67 при той же нагрузке на существующем GPU-мосте Apple.
| Метрика | Stock VM | VM + шим | Улучшение |
|---|---|---|---|
| Prompt Processing (tok/s) | 71,66 | 515,76 | +7,2× |
| Token Generation (tok/s) | 3,41 | 49,67 | +14,6× |
Lume и Cua: инфраструктура, которая это сделала возможным
Lume — это VM-фронтенд, который использовался в тестах, тогда как виртуальный GPU обеспечивает Apple Virtualization.framework.
Lume — это лёгкий CLI и локальный API-сервер для создания, запуска и управления macOS и Linux VM с близкой к native производительностью на Apple Silicon с использованием Apple’s Virtualization.Framework.
Проект был открыт в феврале 2025 года после того, как авторы столкнулись с ограничениями существующих инструментов виртуализации на Apple Silicon. Никакого GUI, никаких сложных стеков — только единственный бинарник для запуска macOS или Linux VM через CLI или API.
Установка занимает одну команду:
# Установить Lume
/bin/bash -c "$(curl -fsSL https://cua.ai/lume/install.sh)"
# Скачать образ macOS Tahoe
curl -L "$(lume ipsw | tail -n 1)" -o ~/Downloads/macos-tahoe.ipsw
# Создать и запустить VM
lume create macos-tahoe --ipsw ~/Downloads/macos-tahoe.ipsw --unattended tahoe
lume run macos-tahoe
Встроенные пресеты sequoia и tahoe создают пользователя lume, включают SSH, настраивают автологин и отключают сон и блокировку экрана. Учётные данные по умолчанию: lume / lume.
Cua — это open-source инфраструктура для Computer-Use агентов: сэндбоксы, SDK и бенчмарки для обучения и оценки AI-агентов, управляющих полноценными рабочими столами (macOS, Linux, Windows).
Как запустить llama.cpp с Metal внутри macOS VM
После установки Lume и создания macOS VM выполните следующие шаги внутри гостевой ОС:
# Внутри macOS VM (SSH: ssh lume@<vm-ip>)
# 1. Установить зависимости
brew install cmake
# 2. Клонировать llama.cpp
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
# 3. Собрать с Metal-бэкендом (включён по умолчанию на macOS)
cmake -B build -DGGML_METAL=ON
cmake --build build --config Release -j$(sysctl -n hw.logicalcpu)
# 4. Скачать модель (пример: TinyLlama Q4_K_M)
curl -L -o tinyllama.gguf \
https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF/resolve/main/tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf
# 5. Запустить инференс с GPU-оффлоадом всех слоёв
./build/bin/llama-cli \
-m tinyllama.gguf \
-ngl 99 \
-p "Привет! Расскажи мне о Metal API."
ggml_metal_init: GPU name: Apple M1 Ultra. Если видите только CPU-строки — шим не активен.На Apple Silicon llama.cpp использует Metal для GPU-оффлоадинга и способен выдавать 50–100+ токенов в секунду на M3/M4 Mac с хорошими моделями. С шимом эти цифры становятся достижимы и внутри macOS VM.
Ограничения и честная картина
Важно понимать, что шим не делает VM эквивалентом bare-metal во всём:
Это всё ещё VM. Существующие ограничения рендеринга и виртуализации Virtualization.framework остаются в силе.
- Генерация токенов достигает около 72% от bare-metal — разрыв существует
- Обработка промптов практически выравнивается с железом (98%)
- Результаты зависят от конкретного чипа, версии гостевой ОС и характера нагрузки
Cua выпустила эту работу как research release под пермиссивной лицензией, чтобы другие могли воспроизвести результаты и помочь определить, какие чипы Apple Silicon, версии macOS и Metal-нагрузки выигрывают от этого подхода.
«Консервативные ответы гостя скрывали удивительно способный GPU-путь. Два точечных изменения переместили TinyLlama prompt processing с 432 до 4787 токенов в секунду».
Сравнение подходов к GPU-ускорению в VM на Apple Silicon
| Подход | Гостевая ОС | Механизм | Скорость vs bare-metal | Сложность |
|---|---|---|---|---|
| Metal шим (Cua) | macOS | Virtualization.framework vGPU | PP: ~98%, TG: ~72% | Низкая |
| Vulkan→Metal ремотинг | Linux | virtio-gpu / libkrun | TG: ~80% | Средняя |
| CPU (Q4_0_4_4 ARM) | Linux / macOS | NEON-ускоренный CPU | ~40-60% vs GPU | Низкая |
| Bare-metal | macOS (хост) | Metal напрямую | 100% | Нет |
Почему это важно: агенты, CI и privacy-first инфраструктура
По мере того как AI-инференс смещается от централизованных облачных GPU к гетерогенным edge-архитектурам, Apple Silicon становится значимой силой. Используя унифицированную память и нативный Metal, проект llama.cpp переопределяет возможное для LLM-инференса без зависимости от дорогостоящих GPU.
Вот три сценария, где разблокированный Metal в macOS VM меняет игру:
AI-агенты computer-use — агент работает в изолированной VM, управляет рабочим столом и при этом запускает LLM локально с GPU-скоростью. Именно это и строит Cua.
CI/CD с LLM-оценкой — прогон тестов качества модели прямо в пайплайне на Apple Silicon runner, без отправки данных в облако.
Privacy-first разработка — полная изоляция гостевой ОС + локальный инференс + никаких API-ключей. Никакого интернета не требуется: полная приватность, работа в любом месте.
Унифицированная архитектура памяти Apple Silicon предлагает до 192 ГБ общей памяти CPU/GPU и пропускную способность памяти 400+ ГБ/с, что делает Mac-устройства привлекательными для локального запуска больших языковых моделей.
Заключение
Исследование команды Cua демонстрирует: барьер между «медленной VM» и «практичным локальным LLM» оказался не архитектурным, а программным. Два точечных изменения в capability probe разблокировали Metal-путь, который всё это время существовал в Virtualization.framework, но не использовался.
Для разработчика это означает:
- macOS VM больше не компромисс для LLM-нагрузок — prompt processing достигает 98% от bare-metal
- Lume + Cua — готовая, открытая инфраструктура для воспроизведения этих результатов
- Gemma 4 12B внутри VM переходит из категории «слишком медленно» (3,4 tok/s) в «вполне рабочий» режим (49,7 tok/s)
Проект открыт под пермиссивной лицензией, и команда приглашает тестировать шим на разных поколениях Apple Silicon. Если у вас есть M2, M3 или M4 — ваши бенчмарки помогут расширить картину.
Ресурсы:
- trycua/cua на GitHub — весь код, шим и бенчмарки
- Исходный пост в блоге Cua — сырые логи и методология
- llama.cpp — основной фреймворк инференса