paint-brush
Программное обеспечение для геологоразведки: достижение баланса в Discoveryк@sinavski
331 чтения
331 чтения

Программное обеспечение для геологоразведки: достижение баланса в Discovery

к Oleg SInavski10m2024/03/21
Read on Terminal Reader

Слишком долго; Читать

Пост с аргументами в пользу: - избегать слишком большого количества производственных технологий во время исследования. Производство и исследования преследуют разные цели - можно использовать «технический долг» в исследованиях, поскольку большая часть кода умрет. Например, не стоит стремиться к повторному использованию кода. - но как исследователь вам все равно следует инвестировать в быстрое исследование, быстрое ветвление и чистый простой код.
featured image - Программное обеспечение для геологоразведки: достижение баланса в Discovery
Oleg SInavski HackerNoon profile picture

Я всю жизнь занимался исследованиями, поэтому знаю стереотип, что исследователи пишут уродливый код (например, см. здесь , здесь или здесь ). Но я подумал: мы можем это исправить, правда? Поэтому я несколько раз пытался разработать хорошие исследовательские рамки. Я пытался внедрить интерфейсы и создавать красивые абстракции, используя книги по разработке программного обеспечения и блоги, которые мне нравилось читать.


Но раз за разом все эти усилия оказывались напрасными. Большая часть исследовательского программного обеспечения, над которым я работал, так и не была запущена в производство (хотя некоторые из них так и поступили). Для моего психического здоровья было бы здорово, если бы кто-нибудь сказал мне простую истину: на самом деле должно произойти умирание исследовательского кода . Во-первых, исследователям не следует тратить много времени на его разработку.


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

1. Взять на себя стратегический технологический долг

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

Во время разведки многие проекты замирают. Вы должны создавать надежное решение только во время эксплуатации.

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


Но на первом этапе «исследований» вы не строите фундамент, который будет жить вечно. Фактически, если большая часть ваших усилий сохраняется, значит, вы (по определению) недостаточно исследовали.


Многие практики в этой статье являются примерами того, что обычно называют «техническим долгом». Это то, что вы получаете, если не пишете чистый, хорошо абстрактный код, пригодный для многократного использования. Всегда ли долг – это плохо? Мы предпочитаем никогда не получать кредит или ипотеку, но заимствование денег часто является хорошей стратегией в жизни. Это нормально — влезать в долги, чтобы двигаться быстро и получить прибыль позже.

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

Точно так же, не принимая технический долг, вы можете замедлить свои исследования. Хорошей новостью является то, что в большинстве случаев вам не придется возвращать долг. Большая часть вашего исследовательского кода, скорее всего, умрет в любом случае. Таким образом, в среднем вы не будете страдать от всего полученного вами технического долга.

Аргументы против повторного использования кода

Многие архитектуры программного обеспечения и методы рефакторинга специально ориентированы на улучшение возможности повторного использования кода. Повторное использование кода имеет общие недостатки . Но в производстве их перевешивают известные преимущества (см., например, этот типичный пост ). В исследовательских проектах большая часть кода обречена на забвение. Стремление к повторному использованию кода может фактически замедлить вашу работу.


Ограничение повторного использования кода — это тот тип технического долга, который можно учитывать в исследованиях. Есть несколько моделей повторного использования кода, которые я хочу обсудить: добавление ненужной зависимости, копирование кода, сохранение большого количества общего исследовательского кода, преждевременные инвестиции в дизайн.

Подумайте дважды, прежде чем импортировать что-то новое

Если вы знаете хорошо поддерживаемую библиотеку с поддержкой версий, которая ускорит вас — дерзайте! Но прежде чем принять новую зависимость, попытайтесь принять решение, стоит ли оно того. Каждый дополнительный приближает вас к аду зависимости. Это заставляет вас тратить время на изучение и устранение неполадок. Дополнительные подводные камни зависимостей смотрите в этом кратком посте .


Наверное, хорошо от чего-то зависеть, если:

  • вы уже использовали его, здесь особо нечему учиться, у него большое сообщество, хорошая документация и тесты
  • он версирован, прост в установке
  • и, наконец, вы не сможете реализовать это самостоятельно.

Но будьте осторожны с зависимостью, если:

  • вы не можете быстро разобраться, как им пользоваться, он очень новый (или очень старый) или о нем, похоже, никто не знает; нет никаких документов или тестов

  • он из вашего монорепозитория и постоянно меняется другими командами.

  • он использует множество других зависимостей и инструментов; или его просто сложно установить

  • и, наконец, вы чувствуете, что вы (или какой-нибудь LLM) можете написать этот код за несколько часов.


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

Копипаст дает вам свободу экспериментов

Копипаст — это быстро, и иногда это лучший инструмент во время исследования.

Некоторые говорят, что « копипаст должен быть незаконным ». Но, к моему удивлению, я довольно часто приводил доводы в пользу этого. Копипаст может быть оптимальным выбором на этапе исследования.


Если вы зависите от часто используемой функции из другой части кодовой базы, вы можете забыть о ее легком изменении. Вероятно, вы кому-то что-то сломаете и вам придется потратить драгоценное время на обзоры кода и исправления. Но если вы скопируете необходимый код в свою папку, вы вольны делать с ним все, что захотите. Это имеет большое значение для исследовательских проектов, где экспериментирование является скорее нормой, чем исключением. Особенно, если вы не уверены, что изменения будут полезны всем.


Я считаю, что кодовые базы глубокого обучения больше всего подходят для копирования. Обычно объем кода, необходимый для описания модели и ее обучения, не так уж и велик. Но в то же время это может быть очень тонким и трудным для обобщения. Сценарии обучения, которыми можно делиться, имеют тенденцию разрастаться до неуправляемых размеров: например, тренер transformers Hugging Face имеет +4 тыс. строк. Интересно, что трансформеры выбрали копипасту на уровне модели. Пожалуйста, ознакомьтесь с их сообщением с обоснованием их политики «однофайловой модели». Дополнительные ресурсы о красоте копипаста смотрите в конце.


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

Поддерживать общий исследовательский код сложно

Обслуживание часто используемого общего кода требует большой работы. Взгляните на количество строк файла torch.nn.Module , сопоставленное с версией Pytorch . Вы можете видеть, что даже самые продвинутые исследовательские группы изо всех сил пытаются держать сложность под контролем.

Длина файла torch.nn.Module зависит от версии PyTorch. Это не становится проще.

Не стоит недооценивать время и ресурсы, необходимые для поддержки большого общего исследовательского кода. Чем больше используется научная библиотека, тем сложнее она становится. Это происходит быстрее, чем в обычной библиотеке, потому что каждое направление исследований имеет немного разные варианты использования. Установите очень строгие правила относительно того, что можно вернуть. В противном случае общий код станет хрупким и зарастет множеством опций, ошибочными оптимизациями и крайними случаями. Поскольку большая часть исследовательского кода вымирает, вся эта дополнительная сложность никогда больше не будет использоваться. Удаление части вашего общего кода высвободит некоторое время для проведения реальных исследований.

Проектируйте для исследования, а не для повторного использования кода

В некоторой степени это правда, что вы не хотите слишком сильно готовить свой код к будущему даже в рабочей среде. Постарайтесь реализовать максимально простое решение, соответствующее требованиям. Но в рабочем коде всегда необходимо учитывать аспекты удобства сопровождения. Например, вам обычно нужно думать об обработке ошибок, скорости, журналировании, модульности.


В исследовательском коде все это не имеет значения. Вы просто хотите как можно быстрее доказать, хорошая или плохая идея, и двигаться дальше. Так что грязная простота, которая достигается без каких-либо модулей или API, вполне нормальна!


Не тратьте драгоценное время на преждевременные инвестиции в программное обеспечение, такие как:

  • создание интерфейсов компонентов на слишком ранних стадиях проекта. Вы потратите слишком много времени, приспосабливаясь к созданным вами искусственным ограничениям.
  • оптимизация инфраструктуры обучения глубокому обучению, прежде чем переходить к решению глубокого обучения
  • использование производственных конфигураций/фабрик/систем сериализации или базовых классов. Зачастую при прототипировании их функционал не нужен.
  • чрезмерно строгие системы линтинга и проверки типов. Нет причин замедлять быстро меняющийся одноразовый исследовательский код.

2. Инвестируйте в быстрое исследование

Цель исследовательского проекта – найти новое решение. Никто не знает (по определению), как это выглядит. Это похоже на процесс оптимизации в сложной исследовательской среде с ограниченной информацией. Чтобы найти хороший минимум, нужно перепробовать множество путей, распознать хорошие и плохие пути и не застрять в локальных минимумах. Чтобы сделать все это быстро, иногда вам нужно инвестировать в программное обеспечение вместо того, чтобы брать технологические долги.

Ускорьте общие пути

Инвестируйте в ускорение общих частей ваших исследовательских проектов.

Есть несколько различных направлений исследований, которые вы хотите попробовать. Есть ли дизайн, библиотека или оптимизация, которая сэкономит время на большинстве путей? Вы должны быть осторожны, чтобы не переусердствовать, потому что вы не всегда знаете все идеи, которые собираетесь реализовать. Это очень индивидуально для каждого проекта, но вот несколько примеров:


  • если вы обучаете глубокие сети, инвестируйте в инфраструктуру обучения. Определите гиперпараметры, позволяющие быстро и надежно сходиться во время обучения.
  • если каждый эксперимент требует от вас использования другой модели, выясните, как можно быстро поменять их местами (например, используя простую заводскую систему или просто скопировав)
  • Если в каждом эксперименте слишком много параметров и им сложно управлять, инвестируйте в хорошую библиотеку конфигурации.

Быстро разветвляйтесь

Инвестируйте в скорость открытия новых направлений исследований. Вам нужно много разнообразных направлений, чтобы найти решение.

Исследователи должны иметь возможность быстро выдвигать новые разнообразные идеи. В начале проекта это кажется простым. Но затем постепенно становится все труднее и труднее, поскольку люди укореняются в своих любимых исследовательских путях. Для решения этой проблемы необходимы культурные и организационные изменения. Должен быть установлен процесс прекращения бесперспективных исследований, прежде чем вкладывать в них слишком много денег и эмоций. Регулярные демонстрационные дни и технические экспертные оценки могут служить эффективной стратегией для этой цели. Также важно найти баланс между людьми, которые ухватываются за новую блестящую идею и должным образом закрывают текущие проекты.


Но это статья о программном обеспечении, поэтому вот несколько приемов, которые облегчат создание новых проектов:

  • держите оценочный код отделенным от алгоритмов. Оценки обычно более стабильны, чем направления исследований.
  • Начните новый проект с чистого листа, но затем следите за тем, какие компоненты используются повторно. Модуляция и очистка — хорошая инвестиция.
  • в новом исследовательском проекте сначала внедряйте наиболее инновационный и рискованный компонент. Это позволяет выявить большинство узких мест при разработке будущего программного обеспечения.

Увеличьте соотношение сигнал/шум

Ошибки и недетерминизм могут сорвать исследовательские проекты и сделать результаты неубедительными.

Шумный код с ошибками делает результаты настолько неоднозначными и неубедительными, что весь проект становится пустой тратой времени. Хотя вам не следует переусердствовать с проектированием, вы можете легко следовать этим простым практическим правилам, чтобы избежать беспорядка в коде:


  • избегайте кода с побочными эффектами

  • по умолчанию используются функции, а не классы; а с классами предпочитайте инкапсуляцию, а не наследование.

  • минимизировать длину функций/классов/модулей; минимизировать количество операторов if

  • хорошо знать Python, но использовать простые методы. Не поддавайтесь искушению углубляться в интеллектуальные сорняки метаклассов, декораторов и функционального программирования.


С программным обеспечением, которое дает разные результаты при разных запусках, работать сложно. Если вы приняли важное, но неправильное решение, основанное на неудачном семени, вы потратите много времени на восстановление. Вот несколько советов при работе с недетерминированным программным обеспечением:


  • понять, исходит ли шум от алгоритма или от его оценки. Источники шума усложняются, и вам следует стремиться к полностью детерминированной оценке.
  • не прекращайте поиск источников случайности, пока не получите действительно воспроизводимый сценарий. Помните, что после обнаружения всех случайных начальных значений шум может исходить от данных или общих функций с побочными эффектами.
  • меняйте исходные данные и определяйте базовую дисперсию ваших результатов. Не принимайте решения на основе статистически значимых результатов.

Заключение

Изюминка взята из этого поста об исследовательском коде:


«Вы не беспокоитесь о [хорошем дизайне программного обеспечения], потому что код не имеет значения. Код — это инструмент, который дает вам ответ, который вам нужен» .


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


Было бы безумием полностью выступать против повторного использования кода. Я просто хочу отметить, что повторное использование кода должно быть хорошо сбалансированным занятием. В исследованиях доля выбрасываемого кода больше, чем в производстве. Баланс еще больше склоняется против повторного использования. Вот еще несколько отличных постов с подводными камнями повторного использования кода:


И вот еще несколько постов, в которых аргументируется практика копипаста:

Спасибо за чтение! Я чувствую, что некоторые моменты немного спорны, пожалуйста, дайте мне знать в комментариях!


Также появляется здесь .