Сегодня мне хотелось бы поделиться решением проблемы, с которой гарантированно сталкиваются владельцы современных процессоров Intel (архитектуры Alder Lake, Raptor Lake и новее) под управлением Windows 11, если они пытаются “крутить” тяжелые локальные модели (LLM) или использовать виртуализацию.
Речь пойдет о принудительной изоляции «тяжелого» софта от энергоэффективных ядер (E-cores) и полной передаче вычислений производительным ядрам (P-cores) со стороны излишне навязчивой в этом плане Windows 11.
Кратко о сути проблемы на примере моего ноутбука.
В моём ноутбуке установлен процессор Intel Core i7-13850HX. У этого процессора вполне себе отличная конфигурация: 8 производительных ядер (16 потоков) и 12 энергоэффективных ядер (12 потоков). Всего 28 логических процессоров.
По задумке Intel и Microsoft, встроенный контроллер Thread Director должен сам понимать, какую задачу и на какие ядра (логические процессоры) ему нужно отправлять, но на практике, например, тот же гибридный режим работы (CPU + GPU) локальных нейросетей буквально вводит Windows 11 в полный ступор с “раcкидыванием” процессов на ядра.
Когда я, например, запускаю тяжелую локальную модель (Qwen 72B весом 47 ГБ) в LM Studio и настраиваю частичный перенос слоев на дискретную видеокарту (в моем случае это “скромная” RTX 2000 ADA 8GB), вычисления делятся между VRAM и оперативной памятью (RAM).
В такой ситуации работа LLM делится на две очевидные фазы:
Prompt Processing (Prefill): Чтение запроса - видеокарта загружается на 100%.
Token Generation (Decoding): Потоковая генерация текста по одному токену.
В фазе генерации видеокарта считает свои слои за считанные миллисекунды, после чего простаивает и ждёт, пока процессор и RAM досчитают “остаток” модели. В это же самое время Windows “видит” это «ожидание» и то, что окно LM Studio или фоновый Python-скрипт моего “моста” потеряли фокус и следом тут же “пугается” высокого TDP на ноутбуке в такие моменты и включает для них энергосбережение (Power Throttling с “зеленым листочком” в Диспетчере задач). А потом еще и принудительно “закидывает” потоки на медленные E-ядра!
Результат становится плачевным - скорость генерации падает, кулеры ноутбука начинают работать как «качели», страшно раздражая таким своим характером работы.
Такая же история происходит и с моим портативным VirtualBox.
Гостевые OS внутри виртуалки “не знают” о делении ядер на быстрые/медленные, и когда процессы виртуалок сама хостовая OS “раскидывает” между P и E ядрами, начинаются ощутимые задержки.
Изначально я пытался решить описанную проблему стандартной командой:
powercfg /powerthrottling disable /path “путь_к_exe”
Это хорошо помогает заблокировать падение частот, но имеет три больших недостатка:
Утилита “powercfg” наотрез отказывается работать с путями на дисках, отличных от системного “C:” (а у меня Python-мост для работы с локальными моделями разворачивается на RAM-диске “W:” для максимальной скорости).
Современные приложения на фреймворке Electron (такие как LM Studio) каждый раз “плодят” дочерние процессы (Renderers, GPU, Utility), которые игнорируют настройки родительского “.exe” и всё равно “сбегают” на E-ядра почти сразу после запуска.
Настройки сбрасываются, если ваш RAM-диск пересоздается с нуля при загрузке системы.
Как же быть, подумал я, и придумал следующее. Конечно же, не без помощи тех самых моделей, которые и пытался ускорить :-)
Оказалось, что надежным способом буквально “запереть” тяжелый софт на производительных ядрах, является использование так называемой системной маски сходства процессоров (“ProcessorAffinity”).
В частности, для процессора i7-13850HX в моём ноутбуке первые 16 логических потоков (“CPU 0” - “CPU 15”) - это всегда 8 быстрых физических P-ядер с Hyper-Threading. В шестнадцатеричной системе (Hex) маска для включения первых 16 потоков выглядит как “FFFF”. Запуск процессов с этой маской чётко блокирует им доступ к медленным E-ядрам (“CPU 16” - “CPU 27”).
Теперь, разобравшись со всем этим, осталось только всё удобно автоматизировать!
Ниже представлены два независимых готовых сценария автоматизации:
Сценарий 1: Запуск ИИ-станции (LM Studio + Python на RAM-диске)
Этот бат-файл запускается двойным кликом после того, как вы вручную открыли LM Studio и подгрузили тяжелую модель. Скрипт мгновенно находит все скрытые дочерние процессы LM Studio, “зажимает” их на быстрых ядрах через PowerShell, проверяет и разворачивает виртуальное окружение на RAM-диске “W:” (в моем случае) и запускает мой Python-мост со строгой привязкой к P-cores.
ПРИМЕЧАНИЕ: Сохраняйте “.bat” файл в кодировке UTF-8 без BOM, чтобы не сломать чтение команды @echo off и избежать нечитаемого текста.
@echo off :: Включаем поддержку UTF-8 для корректного вывода текста chcp 65001 >nul title ИИ-СТАНЦИЯ: LM Studio + Python P-Cores Only mode con: cols=75 lines=14 color 0A :: Переходим на RAM-диск cd /d "W:\AI_Bridge" echo ================================================================ echo [ИИ-СТРАЖ ЗАПУЩЕН] Настройка ресурсов процессора i7-13850HX... echo ================================================================ echo. echo [1/3] Перенаправление ВСЕХ процессов LM Studio на быстрые P-ядра... :: PowerShell находит все процессы LM Studio и зажимает их на ядрах 0-15 (маска 0xFFFF) powershell -Command "Get-Process -Name 'LM Studio' -ErrorAction SilentlyContinue | Where-Object { \(_.ProcessorAffinity -ne 0xFFFF } \vert{} ForEach-Object { try {\)_.ProcessorAffinity = 0xFFFF } catch { } }" 2>nul echo [2/3] Проверка и подготовка виртуального окружения Python на RAM-диске... if not exist env ( python -m venv env call env\Scripts\activate pip install paramiko openai ) else ( call env\Scripts\activate ) echo [3/3] Запуск скрипта qwen72_mod_a_FAST_CORES.py на быстрых P-ядрах... :: Запуск интерпретатора Python строго на первых 16 потоках start "" /affinity FFFF "W:\AI_Bridge\env\Scripts\python.exe" "qwen72_mod_a_FAST_CORES.py" echo. echo ================================================================ echo Все процессы успешно запущены и изолированы от E-ядер! echo ================================================================ timeout /t 3 >nul
После выполнения этот батник закрывается сам, а Python-мост и LM Studio остаются работать исключительно на быстрых ядрах.
Сценарий 2: Фоновый «страж» для Portable-VirtualBox.
С портативным VirtualBox ситуация немного сложнее. В моём случае лаунчер “VirtualBoxPortable.exe” запускает менеджер и тут же закрывается, а сами виртуальные машины (“VirtualBoxVM.exe” или “VBoxHeadless.exe”) я часто запускаю и останавливаю в разное время в разном сочетании, и ярлыки здесь просто не помогут.
Поэтому с помощью всё того же “Иван Иваныча” был написан по заданию автономный “скрипт-часовой”. Он запускается обычным двойным кликом (так как UAC у меня отключен, права админа подхватываются сразу). Скрипт превращается в бесконечный цикл, который раз в секунду сканирует систему. Как только вы запускаете любую виртуалку, он перехватывает её процесс прямо в момент «холодного» старта (до загрузки OS) и привязывает к быстрым ядрам:
@echo off chcp 65001 >nul :: Проверка прав администратора net session >nul 2>&1 if %errorLevel% neq 0 ( powershell -Command "Start-Process -FilePath '%0' -Verb RunAs" exit /b ) title СТРАЖ ЯДЕР: VirtualBox P-Cores Only mode con: cols=65 lines=10 color 0A echo ========================================================= echo [СТРАЖ ЗАПУЩЕН] Права подтверждены. Окно можно свернуть. echo Все новые и запущенные виртуалки переводятся на P-ядра. echo ========================================================= echo. :LOOP :: Перехватываем процессы виртуалки на лету, игнорируя системные ошибки коротких потоков powershell -Command "Get-Process -Name 'VBoxHeadless', 'VirtualBoxVM' -ErrorAction SilentlyContinue | Where-Object { \(_.ProcessorAffinity -ne 0xFFFF } \vert{} ForEach-Object { try {\)_.ProcessorAffinity = 0xFFFF } catch { } }" 2>nul timeout /t 1 >nul goto LOOP
Этот батник вы просто сворачиваете в панель задач. Он потребляет 0% ресурсов процессора, но гарантирует максимальную производительность виртуализации из-за “раскидывания” всех процессов виртуалок на быстрые ядра.
Результаты эксперимента.
Их можно проверить визуально и, что называется - даже “на слух”:
В Диспетчере задач на вкладке «Сведения» (Details) при клике правой кнопкой мыши на “python.exe”, “LM Studio.exe” или “VirtualBoxVM.exe” -> «Задать сходство» (Set Affinity), легко можно увидеть, что чекбоксы автоматически и строго стоят только на “CPU 0” - “CPU 15”. Медленные же ядра остаются “пустыми” для этих процессов!
Акустический комфорт. Кулеры моего ноутбука перестали работать «рывками». Они выходят на стабильный, ровный рабочий гул, так как P-ядра больше не простаивают в ожидании потоков, застрявших на энергоэффективных ядрах.
Общая стабильность. Практически исчезли микрофризы в виртуалках, а скорость генерации токенов локальной LLM стала стабильно высокой (насколько это вообще возможно для моего ноутбука) и без просадок.
При этом все 12 медленных E-ядер (“CPU 16” - “CPU 27”) остались свободными. Windows 11 отлично это “видит” и тут же “отгружает” на них свой системный фоновый мусор (апдейты, кэш браузера и т.п.), не мешая моей работе с “тяжелым” софтом.
Надеюсь, эта методика поможет выжать максимум из ваших гибридных процессоров, но помните, что перегрев и троттлинг также всегда должны быть под Вашим чутким контролем ;-)
