Команды, которые арендуют Mac mini M4 в Сингапуре, Токио, Сеуле, Гонконге или на западе США, часто запускают ONNX Runtime с провайдером CoreML для пакетного скоринга. Ниже — матрица решений по числу InferenceSession, верхним границам потоков, размеру батча B, дисковому I/O и раздельным таймаутам очереди (Wq ожидание слота, Wc фаза вычисления), плюс готовые экспорты окружения и консервативный чек-лист параллелизма — без заявлений о фиксированном ускорении. Контекст по стекам Apple Silicon см. в сравнении PyTorch MPS и MLX; нативный конвейер Core ML — в заметке про mlmodelc и батч. Экономику регионов и RTT — в матрице задержки и TCO. Публичные страницы тарифов и оформления заказа доступны без входа в аккаунт до этапа оплаты.
Три типичных сбоя на удалённом M4
- Размножение сессий. Каждая
InferenceSessionдержит планы графа, веса и кэши EP в unified memory. Создавать сессию на каждый HTTP-запрос кажется дёшево, пока не столкнётесь с давлением на DRAM, артефакты ANE и очередь чтений NVMe. - Двойное бронирование потоков. Пулы intra-op в ORT, OpenMP и ядра Accelerate могут одновременно претендовать на P-ядра. Несогласованные верхние границы дают «занятый» CPU и растущий хвост p95 при том, что узел выглядит загруженным.
- Один таймер на всё. Смешение ожидания в очереди с длительностью
run()на CoreML провоцирует неверные ретраи, выталкивание горячих кэшей компилятора и ложный вывод «мало GPU», когда проблема — бэклог или сеть управления.
Матрица решений
Строки таблицы — ограничители; затем прокачивайте B и число тёплых сессий только по замерам памяти и очереди диска. Подсказки по суточной и месячной аренде качественные — сверяйте фактические цены на странице тарифов.
| Профиль | Тёплые сессии | Intra / inter потоки | Батч B | Встроенный NVMe I/O | Wq / Wc | День vs месяц (подсказка) |
|---|---|---|---|---|---|---|
| Стабильный API с прогретыми весами | 16 ГБ: одна основная; 24 ГБ: 1–2 с жёстким потолком | Старт intra 2–4, inter 1; снижайте при перегрузе OMP | Рост B до излома p95, затем шаг назад | Один prefetch; избегайте параллельных полных копий модели | Короткий Wq; Wc по p95 батча плюс запас | Помесячно при ровном QPS |
| Всплески из CI или ночного скоринга | Одна сессия на хэш модели; пересборка только при смене хэша | Inter оставьте 1, если граф не «embarrassingly parallel» | Умеренный B; стабильная задержка важнее пика RPS | Стадируйте ONNX и данные на локальный NVMe до цикла | Жёсткий Wq; широкий Wc только на профилировании | Посуточно на короткие окна |
| Общий хост нескольких арендаторов | Глобальный семафор на семейство моделей | Меньше потоков на арендатора; справедливость важнее насыщения | Малый B и admission control | Изолированные префиксы scratch; следите за записью | Оба таймаута в метриках; деградация до жёсткого обрыва | Середина месяца при необходимости SKU побольше |
Без гарантий ускорения. Поведение CoreML EP зависит от покрытия операторов, точности и маршрутизации ANE/GPU — перепрофилируйте на том же образе аренды после обновления ORT или macOS.
Экспорт переменных окружения и чек-лист параллелизма
Подходит для launchd, оболочки CI или entrypoint контейнера; значения — стартовые, подстройте по профилю.
# оболочка воркера macOS — подстроить после профилирования
export OMP_NUM_THREADS="${OMP_NUM_THREADS:-2}"
export OMP_WAIT_POLICY="${OMP_WAIT_POLICY:-PASSIVE}"
export VECLIB_MAXIMUM_THREADS="${VECLIB_MAXIMUM_THREADS:-2}"
export ORT_LOG_SEVERITY_LEVEL="${ORT_LOG_SEVERITY_LEVEL:-3}" # 0 подробно .. 4 fatal
В коде явно фиксируйте потоки через SessionOptions:
import onnxruntime as ort
so = ort.SessionOptions()
so.intra_op_num_threads = 2
so.inter_op_num_threads = 1
# providers=[('CoreMLExecutionProvider', {...}), 'CPUExecutionProvider']
Меняя опции сессии CoreML (точность, флаги «только ANE», дополнительные ключи провайдера), логируйте итоговую строку провайдеров на каждый деплой: минорные версии ORT меняют дефолты независимо от неизменных Bash-экспортов.
- Сначала ограничьте число тёплых сессий, затем увеличивайте B.
- Один «ведущий» контур OpenMP на процесс; ядра между процессами делите осознанно.
- В лог: id сессии, хэш модели, список провайдеров, wall time батча.
- При перегрузке: уменьшить B, затем скорректировать Wc, затем добавить узлы — не слепые повторы одного запроса.
- Ошибки стыковать с DLQ или подписанной сводкой вместо тихого отбрасывания.
Пять шагов до роста параллелизма
- Зафиксируйте колёсо ORT и сборку EP; сохраните вывод
pip freezeи digest образа. - Один прогрев; отдельно измерьте p50/p95 и при необходимости исключите холодный старт из SLA.
- Двоичный поиск по B; остановитесь при росте дисперсии задержки или давлении на память.
- Разведите Wq и Wc; алертируйте бэклог отдельно от медленного EP.
- Повторите бенчмарк после смены региона; меньший RTT не добавляет ядер на чипе.
Сигналы, которые стоит выгрузить в метрики
- Резидентные байты на сессию и пики во время компиляции тяжёлых графов.
- Время на элемент (длительность батча, делённая на B).
- Доля батчей у границы Wc за скользящее десятиминутное окно.
Регион узла и пакет на публичных страницах
Ставьте воркеры рядом с весами и признаками, чтобы сократить стадирование на NVMe. Сравнение узлов без логина: Сингапур, Япония, Корея, Гонконг, запад США, общий каталог заказа и индекс заметок. Состав образа и лимиты — в справочном центре.
FAQ
Оставлять CPUExecutionProvider? Часто да, как запасной путь; сравните оба маршрута на своих операторах.
Добавлять intra-op потоки? Не подразумевается линейный выигрыш — измеряйте хвосты, а не среднее.
Где описаны пакеты образа? См. разделы поддержки на pomoshch относительно toolchain.
Итог
ORT CoreML EP на арендованном M4 требует повторного использования сессий, согласованных потолков потоков, измеренного батча и раздельных таймаутов в условиях unified memory. Экспортируйте лимиты OMP и vecLib, задавайте SessionOptions в коде и заново профилируйте после смены региона или минора ORT. Slug: 2026-remote-mac-m4-onnxruntime-coreml-batch-inference-matrix.html.