В этом материале
Число CPU threads для prompt processing и token generation в llama.cpp нужно подбирать раздельно.
Число CPU threads для prompt processing и token generation в llama.cpp нужно подбирать раздельно. Один общий предел может подходить prefill и ухудшать decode либо наоборот. Проверяйте threads и threads-batch на фиксированной сборке, размещении весов и входах. Большая загрузка CPU не равнозначна лучшей задержке: потоки конкурируют за ядра, память и исполнение соседних процессов, поэтому полезен фазовый профиль, а не максимальное число workers.
Разделите два режима работы
В определениях аргументов threads-batch относится к batch и prompt processing, тогда как основной threads управляет другим CPU исполнением. Не считайте vCPU физическим ядром и не выводите оптимум из числа логических процессоров. Сначала сохраните реальную CPU allocation контейнера или процесса, доступные cores и ограничения среды. Если модель частично offloaded на GPU, зафиксируйте это размещение: изменение количества CPU операций способно изменить смысл всей последующей матрицы подбора и сделать результаты несопоставимыми.
Изолируйте фазовые измерения
llama-bench различает pp, tg и pg. Используйте такие наблюдения, чтобы выяснить, на какой фазе проявляется эффект настройки. Измерение общей длительности HTTP ответа включает дополнительные компоненты и не заменяет фазовый разбор. Сохраняйте длину prompt, глубину контекста и число generated tokens. Короткий decode на почти пустом контексте нельзя автоматически переносить на длинный диалог, где чтение состояния и работа с памятью имеют другую структуру и могут изменить реакцию на количество потоков.
Пример матрицы threads
Создайте строки для нескольких допустимых значений threads и столбцы для threads-batch, не превышая согласованную CPU allocation. Для каждой клетки запишите pp, tg, pg и функциональную корректность. Это план измерения без заранее заданных лучших чисел. Если настройка улучшает prompt processing и ухудшает генерацию, сохраните оба результата. Выбор зависит от доли работы в целевом workload, а не от желания показать максимальный throughput одной отдельно выбранной фазы и скрыть цену для остальных запросов.
Проверьте affinity и конкуренцию
Сохраните CPU masks или ranges, NUMA placement и соседние нагрузки, если они влияют на эксперимент. Изменение affinity одновременно с числом threads делает вывод неоднозначным. Проведите повтор исходного варианта после серии, чтобы увидеть дрейф условий. Не требуйте полной загрузки всех логических CPU как критерия успеха: насыщение памяти может наступить раньше. Если дополнительные threads увеличивают jitter, исследуйте contention и scheduling вместо предположения, что движок обязательно должен масштабироваться линейно с каждым доступным vCPU.
Зафиксируйте рабочий профиль
В релизный артефакт включите сборку, backend, offload, threads обеих фаз, affinity и контрольные входы. Отдельно укажите, какой компромисс нужен приложению: быстрый прием длинного документа или ровный decode. После изменения CPU allocation, контейнерных limits или размещения слоев повторите проверку. Полезный вывод описывает подходящую область настроек и наблюдавшиеся регрессии, а не универсальное число threads для всех моделей. Это также предотвращает ошибочное увеличение RAM как замену вычислительной или bandwidth диагностике. Результат должен позволять повторить фазовые измерения на том же узле и понять, почему выбранное сочетание соответствует конкретной смеси prompt processing и генерации, не подменяя физические ресурсы маркетинговым числом виртуальных процессоров.
Связанные материалы
Когда CPU-инференс LLM стоит проверить вместо покупки GPU; NUMA в GPU-сервере: почему расположение ресурсов имеет значение.