Telegram Web Link
Постепенное снятие карантинов порождает новый холивар: может ли компания оставаться на удаленке навсегда и оставаться продуктивной. С одной стороны кричат "все пробовали fully remote, и никто толком не смог!", с другой - тыкают примерами Gitlab, Basecamp и прочих HashiCorp.

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

P.S. Еще вспомнился такой актуальный в наше время комикc от Oatmeal.
Узнал новое для себя слово HARKing - hypothesizing after the results are known. Иными словами, подгонять задачу под ответ.

Наткнулся на это слово в отличной статье HARK Side of Deep Learning - From Grad Student Descent to Automated Machine Learning, в которой авторы критикуют современные проблемы академического ML ресерча вроде отсутствия воспроизводимости или мнимой генерализации (авторы прикручивают трюки, чтобы побить метрику на популярном датасете, но эти трюки оказываются бесполезны вне этого датасета).

---

Вообще, HARKing свойственен далеко не только академическому миру - в бизнесах этого не меньше.

Слабые маркетологи объясняют локальные успехи флуктуации своими кампаниями, плохие продакт-менеджеры репортят наверх результаты некорректно посчитанных A/B тестов, премии выдаются, почти все счастливы. Даже если босс знает словосочетание "статистическая значимость" по книжке "Статистика для успешных менеджеров", метод "сделать 20+ A/B тестов без поправки Бонферрони и найти ложноположительный результат" в целом работает.

Ну и больше всего уязвимы средние и большие нетехнологические компании: в маленьких компаниях обычно некому ездить по ушам, все слишком на поверхности, а технологические гиганты могут позволить себе построить инструментарий, который слегка защищает от слишком наглых попыток незаслуженно присвоить себе какие-то полуслучайные улучшения метрики.
Я в меру интересуюсь темой беспилотных автомобилей (с удовольствием катался и посещал тематический митап Яндекса, но за новостями не слежу). Но выступление Андрея Карпатого с последнего CVPR не мог не посмотреть - он отличный спикер, на его лекциях с CS231n выросло немало CV инженеров, включая меня.

Как и любой человек, склонный к confirmation bias, я вынес такие основные тезисы:
- маленькая R&D команда с хорошей инфраструктурой лучше, чем толпа R&D чуваков без инфраструктуры;
- если что-то можно выучить end-to-end вместо эвристик поверх сырых данных (или результатов моделей попроще), это надо делать;
- метрики - это новые юнит-тесты (при этом важно покрыть метриками все кейсы, а не выдрачивать одно число);
- алгоритм подбора новых семплов для обучения и прочий active learning важны.
Люблю хвастаться багами, которые сам же и сделал.

Недавно я обновил одну AWS Lambda функцию, которая делала инференс некой модели. И, внезапно, скорость выполнения просела вдвое.

Расследование показало, что виноват пулл реквест с рефакторингом, который состоял из кучи тестов и двух строк в основном коде. Одна из строк была довольно безобидной на вид, вроде logger.info('Click Me Load More model from {}'.format(model_weights)).

Если копнуть чуть глубже, оказалось, что конструктор модели был примерно таким:

class Model:
def __init__(self,
model_weights: Union[str, BytesIO],
...
)

Т.е. конструктор иногда принимал путь к весам, а иногда - собственно веса (потому что в случае лямбды как раз удобнее сразу прочитать веса из S3). Ну и соответственно это значение model_weights приходило в логгер, который вместо пути к файлу пытался вывести много мегабайт весов.
CTO ставит задачу Head of ML: нужно сделать так, чтобы сейлзы могли хвастаться такой-то фичей.
Head of ML немного думает и ставит задачу ML инженеру: нужно улучшить метрики такого-то классификатора.
ML инженер скребет бритую голову и ставит задачу интерну: нужно починить вот этот баг в сторонней библиотеке.
Интерн создает issue на гитхабе, мейнтейнер из Некой Гигантской Корпорации фиксит баг в течение трех дней.
Меня начала раздражать малорелевантная реклама на Youtube, и потому я полез смотреть, что там Google нахимичил в определении моих интересов. Если кто не в курсе, по этой ссылке можно найти список ваших интересов и прочих атрибутов, используемый в таргетинге.

И тут мне пришла в голову идея сравнить два профиля: у меня есть относительно новый (меньше года) аккаунт, под которым я залогинен в "рабочем" браузере, а есть основной, под которым я делаю все остальное последние много лет. Из занятных различий:

- Age. На работе мне 18-44, а вне работы - гораздо точнее, 25-34 (на самом деле мне 31);
- Education status. На работе у меня как будто "Bachelor's Degree", а вне работы - Advanced Degree (на самом деле меня отчислили со второго курса). Кажется, это сигнал, что можно быть поамбициознее в работе!
- Marital status. "Старый" аккаунт все еще считает, что я married, а новый - что я in a relationship (как будто старый аккаунт давно не пересчитывал фичи!)
- Rental status. Оба аккаунта сходятся в том, что я renter, т.е. мою квартиру в Минске как будто недвижимостью назвать сложно :(
- Относительно узкие профессиональные интересы типа Machine Learning and Artificial Intelligence и Distributed & Cloud Computing есть в основном аккаунте, но отсутствуют в рабочем. Наверное, это следствие того, что я стал реже гуглить всякое типа deep learning for dummies.

Оба аккаунта ожидаемо достаточно хорошо поняли, что я работаю в Technology Industry, интересуюсь компьютерами, нон-фикшеном, экономикой, видеоиграми и жратвой.

В общем, рекомендую покопаться, довольно забавно. А причину нерелевантной рекламы я так и не нашел :(
Извините, это пост затрагивает две чрезмерно захайпованные темы - политику и COVID-19. Хотя вообще он про анализ данных.

Некий председатель комитета по здравоохранению сегодня сказал дословно следующее:
Начиная с 21−22 августа, регистрируем рост заболеваемости COVID-19. Инкубационный период у коронавирусной инфекции в среднем две недели. Во второй декаде августа в городе стали проходить массовые акции. А любые массовые мероприятия способствуют распространению коронавируса — не соблюдается социальное дистанцирование.

Оставим за скобками вопрос, есть ли политическая компонента в его высказывании, и применим здравый смысл и базовое понимание статистики.

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

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

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

Хватит гадать, пойдем читать интернет. Запрос "covid-19 incubation period distribution" приводит нас к такой картинке с плотностью вероятности. Очевидно, что по всем исследования среднее такого распределения не может находиться в районе 14 дней. А для тех, кто сомневается в своей способности читать графики, можно найти прямое пояснение от ВОЗ:

The incubation period of COVID-19, which is the time between exposure to the virus and symptom onset, is on average 5-6 days, but can be as long as 14 days.

Q.E.D. Вышеупомянутый чиновник не только не знает важные факты по своей специальности, но и не замечает, как его слова не выдерживают проверку здравым смыслом.

И когда кто-то говорит, что уметь в анализ данных - обязательно для всех белых воротничков современности, обычно имеется в виду способность совершать такие упражнения в уме и валидировать все вокруг, а не какое-нибудь сакральное академическое знание о том, чем оценка максимального правдоподобия отличается от оценки апостериорного максимума. 🤓
Почему в software engineering так сложно с оценками сроков? Потому что зачастую практически невозможно на глазок оценить глубины кроличьей норы, если речь идет о чем-то сложнее перекраски кнопки на лендинге.

Вот небольшой пример. Есть сервис на питоне, в котором некоторые запросы начали тормозить. Хочется найти эти запросы, для этого - добавить в логи какой-то request_id.

Но в мире асинхронного питона нельзя просто хранить какой-то id на уровне треде, т.к. тред может переключаться между запросами в процессе await, нужно использовать ContextVars. Чтобы прикрутить ContextVars, нужен Python 3.7+, нужно обновиться. В процессе обновления выясняется, что некоторая старая версия библиотеки официально не поддерживает новый питон, нужно собрать ее руками. Методом проб и ошибок находим коммит, с которого собиралась старая версия для старого питона, собираем для нового питона - результаты не сходятся, тесты падают!

Для начала нужно собрать минимальный воспроизводимый пример (в моем случае получился Dockerfile на 50 строк и примерно столько же Python-кода). Разбираем билд и видим, что библиотеке нужен с десяток shared зависимостей, для которых не всегда указаны версии. Можно найти какие-то древние логи на CI-сервере, который собирал библиотеку для старого питона, и из них достать какие-то куски информации. Их не хватает, и версии приходится перебирать бинарным поиском. Версии подобраны, они конфликтуют друг с другом, и склеить их вместе можно только странным перебором apt install ... && apt remove ... && apt install.

На все эти развлечения ушло уже три дня, и я не могу сказать, что приблизился к заветным request_id. А ведь сторонний наблюдатель с навыками эффективного менеджера вполне мог бы возмутиться: "че там делать вообще? завел переменную и клади в лог, делов-то".
Рубрика "Бесполезные находки": оказывается, существует unicode-символ "Больше или равно или меньше или равно" ⋚.

Единственное (да и то сугубо умозрительное) применение, которое могу придумать - показывать, что между объектами может существовать отношение сравнения.
partially unsupervised
Почему в software engineering так сложно с оценками сроков? Потому что зачастую практически невозможно на глазок оценить глубины кроличьей норы, если речь идет о чем-то сложнее перекраски кнопки на лендинге. Вот небольшой пример. Есть сервис на питоне, в…
Иронично, что даже в этом примере кроличья нора в итоге оказалась ощутимо глубже, чем я думал.

Сервис, над которым я работаю, не просто асинхронный, но местами еще и многопоточный: тяжелые операции живут в отдельных тредах. Их как раз и хочется трейсить больше всего. Соответственно, вдобавок нужно прокидывать request_id внутрь этих тредов, обновлять там логгеры, и, конечно, нужно реализовать все это в общем виде (больше замыканий богу замыканий!).

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

Кажется, что распределение плохого кода бимодально.

Одна мода - натурально говнокод, написанный недалекими программистами. Это ребята, которые не умеют в абстрактное мышление, постоянно копипастят, не знают базовые алгоритмы, не могут осилить более сложные фичи языка, чем if и for. Так вот, если их бить монадами по ебалу заставлять писать композиции функций поверх иммутабельных коллекций вместо беспорядочного ковыряния глобального стейта, зачастую их код становится лучше. (И тут я вспоминаю, как некий map-reduce фреймворк в Яндексе выпрямлял мои собственные руки).

Вторая мода - код, написанный слишком умными и самоуверенными ребятами. Это инженеры на переднем краю, которые с удовольствием используют все возможные возможностей языка, паттерны и хитроумные алгоритмические оптимизации. Это те, кому может не хватать фичей даже в Scala. Проблема в том, что даже они сами не всегда могут понять, что они накреативили через пару месяцев вдалеке от репозитория, а сторонние наблюдатели тем более страдают от необходимости поддерживать такой код, где каждая вторая функция вызывает вопрос "А это вообще легально?". Ну и конечно, таким умникам функциональное программирование не изменит стиль написания кода - они и так знают эту парадигму. Так что спасение от таких умников - не функциональщина, а скорее прокрустово ложе Golang-а.
Бывший коллега когда-то сформулировал такой критерий: работать нужно так, чтобы раз в год собиралось достаточно интересного опыта, чтобы нестыдно выступить на какой-нибудь отраслевой конференции, похвастаться достижениями, рассказать про грабли и так далее. Собственно выступать необязательно (и лень, и NDA никто не отменял), это внутренний критерий. А если рассказывать было бы не о чем, это хороший повод задуматься, не занимаюсь ли я херней.

Так вот, я периодически ныл пацанам, что за последний год не сделал ничего технически интересного. Никакого тебе state of the art, обмазывание старых моделей новыми эвристиками, кругом самоповтор. Но недавно осознал, что вообще-то кое в чем я поднатаскался: just make it work. Собирать древние версии библиотек в окружениях, совершенно не поддерживаемых с точки мейнтейнеров этих библиотек, по кускам наводить порядок, обеспечивая вопроизводимость с точностью до 1e-5, манкипатчами дебажить мистические баги, воспроизводимые только в продакшене...

Последний баг, с которым я возился, был связан с многопоточностью: некая операция запускается в отдельном треде. Расследование показало, что там она на уровне библиотек пытается раскидать свои сабфункции по новым тредам, а каждая сабфункция внутри дергает низкоуровневые OpenBLAS API, которые - сюрприз-сюрприз - в неявном виде тоже могут использовать многопоточность. Иными словами, на море на океане есть остров, на том острове дуб стоит, под дубом сундук зарыт, в сундуке — заяц, в зайце — утка, в утке — яйцо, в яйце игла — смерть Кощея микросервиса.

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

Концепцию изобрели в 2014, примерно в 2017 начали появляться впечатляющие картинки о перекраске яблок в апельсины, а лошадей в зебр, но до реального использования все еще было далековато. Год-два назад на гитхабе стали появляться репозитории, которые иногда можно было запустить и сколько-то воспроизвести. Сейчас там уже есть не только отдельные пайплайны, но и более или менее зрелые библиотеки (пример, еще пример).

В академическом мире начали появляться работы, в которых GAN - не самоцель, а один из винтиков для другой задачи (например, мне очень понравилось это применение super-resolution сети для повышения робастности в классификации). Т.е. подход становится частью повседневного набора инструментов.

Что важнее, GANы более или менее поехали в прод, и не только в узкоспециализированных стартапах. Из относительно простых примеров - DeepHD Яндекса, которому примерно два года. Сложно сказать, как давно GANы появились в эффектах Snapchat, но явно не меньше года. Наконец, относительно свежий релиз платформы для видеозвонков от NVidia (кстати, они собирают и развивают прям серьезную экспертизу в этой нише, что неудивительно: с одной стороны, массовое распространение ганов может стать еще одним драйвером роста для видеокарт, с другой - у них есть ресурсы для экспериментов).

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

Если этот пост вызвал у вас fear of missing out, посмотрите на эту специализацию. Сам я, конечно, ее еще не прошел, но syllabus выглядит неплохо.
Я закончил прошлый пост фразой про fear of missing out, а на этих выходных FOMO накрыл и меня, и захотелось слегка разобраться, в чем суть трансформеров, почему про них все говорят и действительно ли они значимы за пределами мира NLP (TL;DR - скорее да).

Если вам тоже любопытно потратить пару-тройку часов на ознакомление, очень рекомендую два выступления Григория Сапунова: https://www.youtube.com/watch?v=KZ9NXYcXVBY и https://www.youtube.com/watch?v=7e4LxIVENZA. Они очень обзорные - от самой идеи трансформера до свежих трюков по разным направлениям, все обильно приправлено ссылками. В общем, хорошая точка входа.
Опубликовал на Хабре статью по мотивам своего последнего выступления на Дата Фесте. Это обзор, цель которого - слегка сориентировать всех тех людей, которые регулярно задают вопросы вида "как в 2020 делают наложение маски на лица в видео?"
Талеб в "Черном лебеде" много ворчит о том, что система годовых - недостаточно отложенных - премий закладывает неправильные стимулы. Топ-менеджер банка может какое-то время массово выдавать ипотечные кредиты с отсрочкой платежа неплатежеспособным бомжам, и пару лет получать жирные бонусы за рост. Потом банк разорится, его спасут субсидиями за деньги налогоплательщиков, но бонус останется при менеджере.

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

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

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

See also: почему героизм в инженерных организациях - это не ок.
2025/07/04 06:25:59
Back to Top
HTML Embed Code: