Почему генетические алгоритмы не заменили инженера

Рассуждая об эволюции, трудно отделаться от чувства профессиональной зависти. Перед нами идеальный, абсолютно всеядный оптимизатор. Он не решает уравнения, не отлаживает модули, не читает документацию. Ему не требуется разбираться ни в физике, ни в химии, ни в механике. Время, изменчивость и естественный отбор делают всё сами. И когда этот метод применяют в инженерии, он создает вещи, которые ставят специалистов в тупик.
В 2006 году NASA запустило на орбиту три микроспутника миссии ST5. На каждом стояла антенна связи, форму которой предложил генетический алгоритм. На вид — причудливо скрученная металлическая загогулина, похожая на помятую канцелярскую скрепку. Ни один радиоинженер в здравом уме не стал бы проектировать такое; конструкция нарушала все привычные представления о симметрии. Но сигнал этот уродец ловил безупречно, по ключевым параметрам обойдя классические антенны, рассчитанные людьми. Эволюция нащупала сложнейшую геометрию, до которой человеческий мозг не додумался бы никогда.
А за десять лет до этого британский исследователь Адриан Томпсон поручил эволюционному поиску построить кремниевый микрочип для тривиальной задачи: отличать сигнал частотой в один килогерц от десяти килогерц. Без тактового генератора, без внешних таймеров и счётчиков. В распоряжении алгоритма была лишь сотня логических ячеек, переключающихся за считаные наносекунды, на пять порядков быстрее входного сигнала. Программа подобрала работающую схему из тридцати двух ячеек. При этом пять из них вообще не были соединены проводниками с выходом: предложенное генетическим алгоритмом устройство задействовало паразитную ёмкость дорожек, помехи по питанию и наводки кристалла, заставив цифровые транзисторы работать как единый аналоговый резонатор. Ни автор эксперимента, ни инженеры компании‑производителя не смогли до конца понять принцип её работы. Но она работала.
Казалось бы — вот он, святой Грааль проектирования. Зачем годами учить людей в университетах, биться над строгими доказательствами и проектировать продуманную архитектуру, если можно просто задать метрику, запустить перебор вариантов и получить решение, лежащее за пределами самого буйного воображения? Почему за семьдесят лет развития компьютерных наук мы так и не доверили ему проектирование ракетных двигателей, ядерных реакторов, операционных систем? Почему этот всемогущий метод, создавший наш собственный мозг, в реальной инженерии так и остался экзотическим курьёзом для пары десятков узких задач? Ответ прячется в его фундаментальных ограничениях. Ограничениях, которые обходятся природе в сотни миллионов лет топтания на месте, а любой коммерческий проект прикончили бы в первый же релиз.
У дикой природы есть один фундаментальный недостаток — у неё нет черновиков и лабораторий, всё должно работать здесь и сейчас. Каждая строчка генетического кода обязана собирать жизнеспособную особь. Если особь не проходит тест на выживание, ветка с её кодом удаляется навсегда. Именно поэтому эволюция — непревзойдённый мастер импровизаций и генерации техдолга. Всё живое вокруг нас — это работающий, но чудовищно запутанный код, развивавшийся миллиарды лет без единого рефакторинга. Знаменитый гортанный нерв жирафа делает нелепую четырёхметровую петлю от мозга вниз, огибает аорту возле самого сердца и поднимается обратно к горлу только потому, что у природы не было окна техобслуживания, чтобы временно отсоединить этот чёртов провод и перепроложить его по кратчайшему пути. Это бред собачий, сказал бы любой инженер. Да чёрт с ней, с эффективностью, ответила бы эволюция. Главное, что все предки этого жирафа, вплоть до рыб, прекрасно жили с этой дурацкой петлёй и оставляли потомство.
Это человек может создать отдельную экспериментальную ветку, где ничего не собирается, или тесты дружно горят красным, и работать над ней. Это человек может принять решение остановить старый проверенный конвейер, терпеть убытки, избавиться от морально устаревших станков, собрав новую линию с нуля. Это мы соглашаемся потерпеть, потому что способны видеть цель. А у эволюции цели нет, она близорука, словно слабый шахматист, видящий только следующий ход.
Эволюционный поиск умеет двигаться строго в одну сторону: вверх по локальному градиенту приспособленности. Чтобы достичь сияющего инженерного оптимума на горизонте, часто нужно сначала спуститься в глубокое ущелье — временно ухудшить систему, разобрать старые узлы, пережить этап сбоящего прототипа. А для естественного отбора любой шажок вниз означает падение метрики. Говоря по‑простому: ты оказался хуже своих родителей — родился слабым, не добежал, не успел спрятаться, не нашёл пропитания, не смог найти пару. Эволюционный поиск застревает на первом попавшемся холмике приспособленности и будет до бесконечности воспроизводить найденное работающее решение, потому что небольшие изменения делают его только хуже. Это то, что математики называют локальным максимумом, а биологи — адаптивной долиной.
Вылезти из застойного болота самоповторов можно лишь одним способом — с помощью сложной мутации, множества изменений одним махом. Призрачный шанс, что выйдет что‑то путное, но если выйдет, это будет качественный скачок, революция. Проблема лишь в том, что удачная комбинация может выпасть раз за миллиард лет или не выпасть вовсе. В разработке этот барьер называют «breaking change» — «ломающее изменение». Это ситуация, когда выигрыш виден только тогда, когда согласованно переписана большая часть или даже вся система целиком.
Представьте себе монолитное приложение, в котором системная функция вызывается в десятках тысяч мест. Можно ли просто взять и поменять её логику, скажем, заставить её делать нечто совершенно другое? Конечно, нет. При первом же вызове такой функции приложение упадёт с критической ошибкой. Придётся просмотреть все фрагменты кода, вызывающие её, и переписать их. Заменить все вызовы в коде одновременно эволюция не сможет, потому что вероятность получить сразу тысячи требуемых мутаций за одно поколение равна нулю. А усидчивый кодер запросто.
Представьте, что ДНК — это исходный код, а белки — среда исполнения. Генетический код устроен как таблица опкодов, где трёхбуквенные сочетания нуклеотидов, кодоны, процессор клетки переводит в строительные блоки, аминокислоты. Три буквы UCG значат «поставь сюда деталь А». Три буквы UUG — «поставь деталь Б». Этот код появился у общего предка всего живого и стал универсальным для всей современной биосферы, от инфузории до человека. И эволюция не смеет трогать его, как слово «Referer» в протоколе HTTP, написанное с ошибкой, с одной 'r'. Улучшишь, исправишь, и все веб‑сайты мира станут недоступными.
В 2019 году биологи из Кембриджа проделали именно это с бактерией E. coli. Они вручную заменили два сериновых кодона и стоп‑кодон во всех генах клетки, аккуратно переписав их на синонимы. Для этого потребовалось внести 18 214 изменений. Ни одна живая клетка в природе не перенесла бы такой операции. Геном синтезировали по частям, тестировали модули на стендах и потом обновили весь код разом. А в 2023 году команда из Гарварда переназначила измененные кодоны на другую аминокислоту, а старые клеточные декодеры удалила.
И получилось то, о чём десятилетиями мечтали фантасты: «биоблокада», делающая организм неуязвимым к заражению. Любой вирус, по сути, вредоносный скрипт. Он подсовывает свой код клетке и рассчитывает, что её компилятор выполнит его инструкции по стандартной таблице опкодов. Но в перекодированной бактерии стандартной таблицы больше нет. И вместо реплицирования вируса считывается абракадабра. Вирус не может воспроизвести себя и погибает. На эту модифицированную бактерию натравливали коктейль из 12 агрессивных бактериофагов, включая самые продвинутые, несущие свою тРНК, и она отбила все атаки. Человек спроектировал и сделал то, что эволюция не смогла сделать за четыре миллиарда лет, потому что все это время бездумно бросала кубики мутаций, ожидая тысячи нужных изменений за один релиз.
Ровно тот же барьер согласованных правок держит эволюцию за горло и в анатомии. Попробуйте представить анатомически безупречное существо, физически возможное на Земле, но которое эволюция не создаст ни при каких обстоятельствах.
Не напрягайтесь: это классический Пегас, благородный конь о четырёх ногах, у которого из спины растут два могучих орлиных крыла. Физика против шестиконечного коня? Ни капли. Наоборот, в биомеханике шесть точек опоры считаются идеалом. Насекомые сотни миллионов лет бегают устойчивой триподной походкой, робототехники обожают шестиногих шагающих роботов за их фантастическую проходимость. Две пары конечностей уже есть, надо лишь добавить третью на той же элементной базе, что сложного?
Но на Земле никогда не появится ни Пегас, ни шестиногий волк. Все наземные позвоночные планеты, от лягушки до синего кита и нас с вами, потомки одной‑единственной древней лопастепёрой рыбы, которая около 370 миллионов лет назад вылезла на сушу. У этой рыбы было две пары плавников: грудные и брюшные. И всё. С тех пор эволюция крутит и вертит эту четырёхконечную конструкцию. Она может удлинить лапы жирафу, может уменьшить их змее или киту, может слить пальцы в одно копыто лошади или расплющить их в ласт тюленя. Но она не умеет менять топологию. Каждый раз, когда виду нужно было подняться в небо, чтобы выжить, эволюции приходилось трансформировать передние лапы. Птерозавры пожертвовали ими, превратив их в крылья. Летучие мыши натянули перепонку между пальцами. Хочешь летать? Заплати передними конечностями.
Никаких «четыре ноги и ещё два крыла в подарок» эволюция предложить не может. Потому что это требует согласованных изменений всей архитектуры тела за один релиз. Это добавить палец на лапу ничего не стоит. Достаточно слегка сдвинуть концентрацию пары сигнальных белков в зародыше. Это примитивный патч, простой, как покрутить ручку громкости. А вот третья пара конечностей потребует нечто большего, чем просто мутация одного гена или даже нескольких. Да, бывают аварии в развитии эмбриона, рождаются телята или лягушки с лишней парой конечностей. Но эта пара всегда является болтающимся бесполезным придатком.
А чтобы третья пара ног или крылья полноценно заработали, эволюция должна была бы одновременно спроектировать в скелете третий костный пояс с суставными впадинами, врезать его в позвоночник, нарастить новые мышечные корсеты, проложить магистральные нервные стволы, и самое главное, выделить под них новые вычислительные сегменты в спинном мозге, переразметив моторную кору. Для эволюции трансформация четырёхконечного существа в шестиконечное находится за гранью возможного. Ни один промежуточный шаг не даёт эволюционного преимущества, а полусформированный костный нарост на спине, зачаток крыльев, является уродующей мутацией, делающей переходное существо инвалидом.
В теле Пегаса нужно согласованно изменить тысячи параметров скелета, мышц и мозга. Это человеку подобная задача по плечу, он может спроектировать, протестировать и собрать новую конструкцию. А эволюция, вынужденная бросать каждый промежуточный экземпляр в бой, навечно заперта в анатомии той древней рыбы, что бегала в поисках пропитания по мелководьям на четырёх мощных плавниках.
Казалось бы, все эти препятствия: избегание ухудшений, барьер согласованных изменений и невозможность остановить живой прод на техобслуживание — лишь проблемы физического мира. В симуляции мы от этого освобождены! Запустите перебор вариантов, крутите миллионы поколений в секунду, отсекайте неудачников без всякой жалости. Почему же этот метод не стал нашим главным инструментом проектирования?
Первые грабли эволюционного алгоритма — циничный закон Гудхарта, доведённый до абсолюта: когда метрика становится целью, она перестаёт быть хорошей метрикой. Если инженера начнут оценивать по количеству закрытых задач, он начнет их множить. Если оценивать труд писателя по количеству слов, он завалит издательство нейрослопом. В машинном обучении это называют обманом функции вознаграждения. Эволюционный алгоритм оптимизирует не то, что вы имели в виду, а строго то, что вы буквально записали в коде проверки, он будет рваться к максимальному баллу любой ценой, игнорируя логику и здравый смысл.
Классический пример — инструмент GenProg, созданный для автоматического исправления багов с помощью генетического программирования. Вы скармливаете упавший модуль, подсовываете юнит‑тесты и ждёте, пока мутации в синтаксическом дереве починят код. Инструмент бодро шуршит вариантами и торжественно выдаёт коммит с зелёными тестами... внутри которого функция сортировки заменена на возврат пустого массива. Почему? Да потому что в тестах проверялось, отсортирован ли выходной список. Пустой список отсортирован? Формально контракт соблюдён, оценка максимальна, а то, что функция уничтожает данные, ну так это инструменту никто не запрещал.
В физических симуляторах подобное читерство выглядит ещё комичнее. Когда алгоритму поручили научить трёхмерное существо бегать с максимальной скоростью, он даже не пытался подобрать кинематический цикл суставов. Он отрастил существу длинное нелепое тело и просто валил его плашмя на землю. Дистанция покрыта за долю секунды, скорость центра масс максимальна, распишитесь в получении спринтера. А если физический движок имел баги, алгоритм обнаруживал их и ловко их эксплуатировал: накапливал бесконечную кинетическую энергию, катапультировал себя в стратосферу.
Помните ту самую «наэволюченную» схему Томпсона? Ведь там программа тоже не набрела на новую теорию схемотехники, а всего лишь воспользовалась «багами» среды: приспособилась к паразитной ёмкости конкретной партии чипов, наводкам от соседних дорожек, температуре воздуха в лаборатории. Прогрели схему, и она перестала работать.
Вторые грабли — генетическое вырождение, или преждевременная сходимость. В живой природе разнообразие поддерживается триллионами особей, нехваткой ресурсов, локальными особенностями, переменчивым климатом, конкуренцией и кооперацией с другими видами, болезнями и паразитами. В виртуальной среде размер популяции упирается в память и процессор: десятки, сотни, тысячи экземпляров. Стоит одной случайной мутации построить хоть сколько‑нибудь работающий суррогат решения, как её оценка подскакивает выше средней, алгоритм мгновенно объявляет её фаворитом и начинает скрещивать со всеми особями подряд. Через десяток‑другой поколений весь пул генов состоит из близких родственников этого случайного выскочки. Разнообразие падает в ноль, все особи топчутся на одном и том же холмике, любые новые мутации делают результат только хуже, и виртуальная эволюция намертво застревает в локальном максимуме.
Не спасает и скрещивание, перехваленный кроссовер. В теории ГА «берите лучшее от мамы и папы» подаётся как волшебная палочка. И оно действительно творит чудеса, пока параметры слабо связаны. Можно взять удачный профиль крыла у одной модели, а хвостового оперения у другой, и за одно поколение собрать выигрышную комбинацию. Но этот приём не работает с монолитными системами. Если взять половину «генов» от дизеля и половину от электромотора, получим нефункциональную химеру. В сложных системах всё сцеплено со всем, случайное разрезание и склейка двух работающих программ почти со стопроцентной вероятностью разрушают их внутреннюю логику и логические связи.
Третьи грабли — отсутствие дешёвой оценочной функции. Антенна NASA стала реальностью ровно потому, что уравнения Максвелла считаются быстро. Но попробуйте вырастить эволюционным путём что‑то, для чего нет строгой физической формулы: интерфейс мобильного приложения, панель управления автомобилем, форму кресла, дизайн сайта. Как выразить в уравнениях, насколько пользователю удобно дотягиваться большим пальцем до кнопки перевода средств или насколько очевидно выглядит инструкция для получения баланса? По какой формуле рассчитать, вызывает ли бирюзовая гамма основного окна подсознательное доверие к банку или выглядит дешманской безвкусицей? Единственный инструмент оценки здесь — пользователь из плоти и крови. А это значит, что на каждом шаге отбора вам нужна живая фокус‑группа. Там, где оценку нельзя свести к формуле или физическому симулятору, эволюционный алгоритм теряет своё преимущество.
Но даже если вам повезло, и формулу можно посчитать за миллисекунды, на сцену выходит проклятие размерности. Антенна NASA имела всего десяток параметров. У схемы Томпсона была сотня ячеек. Пока переменных немного, перебор ещё способен нащупать удачную их комбинацию. Но стоит системе усложниться, и объём пространства решений становится астрономическим. Именно поэтому нейросети никто не обучает генетическими алгоритмами. Градиентный спуск, при всей его механистичности, имеет математический компас: он рассчитывает вектор коррекции даже в пространстве из ста миллиардов параметров. У эволюционного поиска такого компаса нет. В многомерной бездне он обречён беспомощно тестировать все направления сразу.
Неужели исследователи за сорок лет не пытались эти грабли обойти? Конечно, пытались. Против вырождения изобрели «островные модели»: популяцию разбивают на изолированные группы, которые эволюционируют отдельно и лишь изредка обмениваются особями. Против застревания в тупиках придумали алгоритмы, которые вообще игнорируют цель и награждают решения просто за новизну поведения. Против дороговизны симуляторов обучали нейросетевые модели, аппроксимирующие физику.
Все эти хитроумные подпорки позволяют залатать несколько очевидных недостатков, но они бессильны против природы самого метода. Сколько ни подпирай симуляцию костылями, у слепого перебора остаётся неустранимый дефект — проблема атрибуции заслуг. Оценочная функция выдаёт одно‑единственное число на всю особь целиком. Если виртуальная особь набрала высокий балл, алгоритм понятия не имеет, какой её признак обеспечил успех, а какой был балластом, проехавшим на чужом горбу к успеху. У блока сравнения, решающего, какую особь списать, а какая передаст гены следующему поколению, нет понимания причинно‑следственных связей, он сравнивает только итоговую оценку. Помните, как спросил Купер из «Интерстеллара» директора школы: «Чтобы сшить тебе брюки, нужно знать три числа, а тебе, чтобы определить судьбу моего сына, достаточно одного?»
И чтобы заставить генетический алгоритм работать на сложной задаче, инженеру приходится обвешивать его гирляндой из эвристик: вручную размечать пространство признаков для «новизны», калибровать штрафы за сложность, обучать сторонние модели, дописывать километры проверочных контрактов. Обещание эволюционного поиска звучало пленительно: «Забудьте про уравнения и теорию, алгоритм всё найдёт за вас». Но чем сложнее система, тем больше математики и ручного контроля приходится вливать в инструмент, чтобы он не утонул в собственных галлюцинациях и трюках. Чуда не произошло: эволюционный поиск эффективен ровно до тех пор, пока задача тривиальна. А там, где начинается настоящая сложность и противоречия реального мира, наша модель эволюции без костылей забредает в тупики.
И вот тут возникает закономерный вопрос: а за счёт чего выигрываем мы? Ведь человеческий мозг — дитя того самого долгого слепого отбора, который мы тут нещадно критикуем. Почему же наши инженерные решения способны перешагивать через пропасти, перед которыми естественный отбор застревает на миллиарды лет? Знаю, соблазнительно списать всё на «развитый интеллект» и «способность представлять себе будущее». Это метафизическая чепуха. Ни один инженер, конструирующий новую ракету, не видит будущего. Любой сложный новаторский проект полон ошибок, переделок и сорванных дедлайнов. Разница между плодами нашего труда и результатами естественного отбора лежит совсем не в этом.
У эволюции нет теории: она не знакома с типовыми алгоритмами, уравнениями Максвелла и теорией аэродинамики. Чтобы понять, сломается ли от нагрузки кость толщиной в палец в туше взрослого слона, отбор должен сначала вырастить тысячи генетически искалеченных слонов. Эволюция строит наугад, безмозглым перебором всех вариантов, вслепую ощупывая законы природы мучениями и смертями своих творений, живых существ.
Человек делает ровно противоположное: он строит абстрактную модель мира. Инженер, проектирующий мост, не тестирует триллионы случайных конструкций, он изучает сопромат и одним уравнением отсекает девяносто девять процентов заведомо нежизнеспособных вариантов. Как сказал философ Карл Поппер, «главное преимущество человека в том, что наши теории гибнут вместо нас». Мы можем сотни раз разбить виртуальный самолёт в уравнениях и симуляциях, похоронить десятки неудачных концепций за один вечер, не губя никого, чтобы собрать финальный вариант, который полетит.
А второе наше отличие от дикой природы становится заметно в тот момент, когда решение найдено. У сложных многоклеточных организмов нет механизма горизонтального переноса генов. Эволюция запирает находки в изолированных ветвях, и каждая ветвь вынуждена изобретать всё с нуля. Глаз возникал независимо в десятках разных типов: моллюски растили свой глаз, позвоночные свой, насекомые свой. Птица не может «подсмотреть», как работает эхолокация у летучей мыши и прикрутить её себе. Человеческая цивилизация устроена иначе. Многие вещи изобретались единственный раз в истории и становились всеобщим достоянием. То, на что слепая эволюция тратит невообразимо много времени, учёный исследует, инженер тестирует, и назавтра они делятся готовым решением со всей планетой. И именно поэтому метод слепого перебора обречён уступить место осознанному проектированию. Ну, или «разумному замыслу», как говорят креационисты, только нашему, человеческому.
Но в чём на самом деле заключается это «осознанное проектирование»? Парадокс в том, что человеческая инженерия победила природу вовсе не потому, что научилась строить более сложные или более эффективные конструкции. Наоборот: в слепой оптимизации «здесь и сейчас» эволюция часто превосходит любой наш конструкт, порождая фантастически эффективные, но намертво спаянные монолиты, где всё завязано на всё. Смысл человеческого подхода заключался в другом — в добровольном самоограничении. Мы вовремя поняли, что нам придётся жить с тем, что мы создаём: эксплуатировать, чинить, дорабатывать, передавать следующим поколениям. И поэтому мы сознательно отказывались от максимальной локальной эффективности ради трёх скучных вещей: модульности, предсказуемости и ремонтопригодности.
Мы пишем архитектурно избыточный, но читаемый и расширяемый код, с тестами и интерфейсами. Человек победил слепую эволюцию ровно в тот момент, когда отказался называть проектированием то, логику чего он не может объяснить. Кажется, в этом споре поставлена точка: эволюционные алгоритмы заняли свою узкую нишу вспомогательных оптимизаторов и дальше не пошли, потому что ни один вменяемый инженер не допустит к критическим процессам систему, которая всего лишь подогнала коэффициенты под функцию оценки. Осталось только понять, почему сегодня, глядя, как модель на сотни миллиардов параметров выдаёт почти безупречный код, мы так легко соглашаемся верить, что внутри неё зародился разум, а не хитроумный эксплойт, который просто научился угадывать, за какой ответ ему сейчас поставят высший балл.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.