Когда «медленная 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 внутри гостя не умел использовать этот путь правильно.

⚠ Частое заблуждение
Многие считают, что медленный LLM-инференс в VM — это фундаментальное ограничение гипервизора. На самом деле проблема зачастую в том, что фреймворк выбирает неправильные вычислительные ядра GPU — и это поправимо на уровне программного шима.

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 VMVM + шимBare-metalПрирост (VM→шим)
Prompt Processing (tok/s)4324 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 VMVM + шимУлучшение
Prompt Processing (tok/s)71,66515,76+7,2×
Token Generation (tok/s)3,4149,67+14,6×
💡 Практический вывод
Для модели Gemma 4 12B — реального рабочего инструмента разработчика — разница между стандартной VM и VM с шимом означает переход от «почти непригодного» (3,4 tok/s) к «вполне рабочему» (49,7 tok/s) режиму генерации.

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).

ℹ Архитектура Cua
Cua состоит из нескольких слоёв: Lume (VM-управление), Cua Drivers (нативный контроль рабочего стола в фоне), Cua Bench (оценка и обучение моделей) и Cua SDK (Python API для агентов). Шим Metal встроен в слой Lume.

Как запустить 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."
📝 Проверка Metal в VM
Чтобы убедиться, что llama.cpp действительно использует Metal, а не CPU, проверьте вывод при запуске: должна появиться строка вида 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)macOSVirtualization.framework vGPUPP: ~98%, TG: ~72%Низкая
Vulkan→Metal ремотингLinuxvirtio-gpu / libkrunTG: ~80%Средняя
CPU (Q4_0_4_4 ARM)Linux / macOSNEON-ускоренный CPU~40-60% vs GPUНизкая
Bare-metalmacOS (хост)Metal напрямую100%Нет

Почему это важно: агенты, CI и privacy-first инфраструктура

По мере того как AI-инференс смещается от централизованных облачных GPU к гетерогенным edge-архитектурам, Apple Silicon становится значимой силой. Используя унифицированную память и нативный Metal, проект llama.cpp переопределяет возможное для LLM-инференса без зависимости от дорогостоящих GPU.

Вот три сценария, где разблокированный Metal в macOS VM меняет игру:

  1. AI-агенты computer-use — агент работает в изолированной VM, управляет рабочим столом и при этом запускает LLM локально с GPU-скоростью. Именно это и строит Cua.

  2. CI/CD с LLM-оценкой — прогон тестов качества модели прямо в пайплайне на Apple Silicon runner, без отправки данных в облако.

  3. 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 — ваши бенчмарки помогут расширить картину.

Ресурсы: