6

Параллелизм операторов и оптимизация компиляции

AI999第4课:现代计算底座与张量化并行演化
00:00

В EvoX — современной вычислительной основе — минимальной единицей выполнения эволюционных операторов является уже не «особь», а весьтензор популяции: такие операторы, как мутация, скрещивание и отбор, за один вызов охватывают все особи; поверх этогокомпиляция вычислительного графаорганизует последовательность операторов в оптимизируемый план выполнения, повышая эффективность вычислений при сохранении семантики алгоритма.

Параллелизм операторов и оптимизация компиляцииПакетная эволюция на уровне тензоров · Компиляция вычислительного графа оптимизирует план выполнениятензор популяции[N, D] · все особиИзмерение особей служит измерением пакетаОдин вызов охватывает все особиОдин вызовОхватывает всю популяциюВычислительный граф эволюционных операторовМутацияСкрещиваниеОтборЗависимости операторов → вычислительный графГлобальная оптимизация всего графаА не вызов готовых реализаций по отдельным операторамКомпиляцияДо компиляцииЦикл по особям · Много запусков ядерМного запусков ядер, размер пакета равен 1Слияние операторов · Генерация ядер · Переиспользование памяти · Оптимизация планированияПосле компиляцииОбъединённый вычислительный граф · Несколько эффективных ядерОдин пакетный прямой проход завершает эволюцию целого поколенияКак вычислять · Способ выполненияЧисло ядерПромежуточные тензорыСтратегии памяти и планированияОптимизация затрагивает только уровень выполнения и не изменяет правила обновления операторовЧто вычислять · Семантика алгоритмаМутацияСкрещиваниеОтборПри одинаковом случайном зерне результаты эволюции совпадают≠

Параллелизм операторов: пакетная эволюция на уровне тензоров

  • Тензорные операторы: мутация, скрещивание и отбор могут напрямую применяться к тензору популяции формы [N, D] (N — размер популяции, D — размерность переменных решения), и один вызов оператора охватывает все N особей.
  • Устранение циклов по особям: больше не нужно писать for ind in population: ind = mutate(ind) такие последовательные циклы Python/CPU, что снижает накладные расходы на частые вызовы функций и обращения к фреймворку.
  • Пакетное измерение как источник пропускной способности: когда измерение особей служит измерением пакета, операторы выполняются на устройстве в режиме массового параллелизма, и пропускная способность пакетной эволюции растёт вместе с размером популяции.

Компиляция вычислительного графа: от последовательности операторов к плану выполнения

Организовав зависимости операторов «мутация → скрещивание → отбор» ввычислительный граф, компилятор сможет выполнить глобальную оптимизацию всего графа, а не просто вызывать готовые реализации для каждого оператора по отдельности:

  • Слияние операторов: несколько поэлементных (element-wise) операций объединяются в одно ядро, что уменьшает создание промежуточных тензоров и их многократное чтение и запись.
  • Генерация ядер и планирование: для объединённого подграфа генерируются эффективные ядра, и эволюция целого поколения выполняется за меньшее число запусков kernel.
  • Переиспользование памяти: буферы для промежуточных результатов планируются заранее, что снижает дополнительные затраты на выделение видеопамяти и пересылку данных.

Эффективность изменилась, семантика — нет

Необходимо различать«как вычислять»и«что вычислять». Параллелизм операторов и оптимизация компиляции изменяют лишь способ выполнения — число ядер, размер промежуточных тензоров, стратегии памяти и планирования — но не логический смысл самих мутации, скрещивания и отбора. Уровень алгоритма по-прежнему комбинирует операторы в соответствии с эволюционной семантикой, поэтому при одинаковом случайном зерне траектория и результаты эволюции до и после оптимизации должны совпадать. Если выразить одной фразой: тензоризация решает вопрос «насколько быстро считаются пакеты», компиляция вычислительного графа — «насколько оптимально планируются ядра», а «что именно вычисляется» остаётся неизменным.

Типичные заблуждения
Ошибочно принимать «тензоризацию» за «смену эволюционного алгоритма». Тензоризация лишь применяет один и тот же оператор ко всему тензору популяции, а правила обновления отдельных особей не меняются; компиляторная оптимизация также не делает алгоритм «умнее». На что действительно стоит обращать внимание — это отсутствие регрессионной проверки после оптимизации, из-за чего различия в реализации ошибочно принимаются за улучшение алгоритма.