Telegram Web Link
С удовольствием прочитал The Phoenix Project.

Такой жанр по-английски обычно называют business fable, впрочем, что-то в нем есть и от производственного романа. Что-то среднее между популярными The Goal Голдратта и The Deadline ДеМарко.

Так или иначе, это история менеджера, который вычищает авгиевы конюшни IT operations в некой большой вымышленной нетехнологической компании, наступает на грабли, но благодаря deus ex machina строит дивный новый мир, соответствующий канонам devops-культуры. Половину книги протагонист тушит пожары на продакшене и пытается соорудить что-то, их предотвращающее. Окружение - классический энтерпрайз - изо всех сил этому сопротивляется.

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

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

Сколько-то интересуюсь темой self-supervised learning в компьютерном зрении. Раньше ее называли просто unsupervised, а потом стали выделять в отдельную подзадачу; на пальцах задача выглядит так: "как получить такие representations, которые улучшат качество конечной модели (например, классификации), за счет неразмеченных данных". Последние пару лет там появилось много прорывных работ (SimCLR, MoCo, BYOL, SwAV...), эксплуатирующих contrastive learning подход, а до этого исследователи в основном пытались придумать такую остроумную задачу, которой не нужна дополнительная разметка. Обзор по теме.

Рядом с этой задачей стоят попытки использовать в обучении синтетические (обычно рендеренные) данные, и чаще всего это не работает в лоб - выученные представления плохо обобщаются на реальные данные без отдельных, довольно сложных трюков (см. domain adaptaion).

И вот сегодня я впечатлился статьей, авторы которой замахнулись на некую смесь этих задач - "как эффективно предтренировывать сеть вообще без реальных данных?". TL;DR: авторы сгенерировали разнообразный датасет фракталов 🌿, учатся на них и доучиваются на основной задаче. Конечно, пока не state of the art (но и совсем не плохо) в плане метрик, зато полет мысли прекрасен.

Пишите в комментариях, какие статьи про self-supervised learning и около того, впечатлили вас в последнее время!
Главный скандал недели в околоML тусовке - это, конечно, увольнение Timnit Gebru из Google за неавторизованную публикацию статьи на тему ethical AI.

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

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

Достаточно нейтральное изложение событий можно почитать на MIT Tech Review. И отдельно отмечу этот прекрасный комментарий.
This media is not supported in your browser
VIEW IN TELEGRAM
Рубрика "Нифига себе как бывает": фреймворк для multi-animal body part position estimation. Особенно доставляют анимированные маски ползающих мух.
Задумался, каково живется в современном мире людям, далеким от технологий, и кажется, что им можно посочувствовать.

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

Указание неместного телефонного номера может поместить заказ в некий лимб - он будет висеть в статусе "в обработке" примерно вечно. Кнопки "переключить язык" на сайтах часто ведут на главную страницу, и оказывается, что нужная фича в принципе недоступна на неосновном языке. Платежи с неместных карточек могут проходить или не проходить, и узнать об их судьбе можно только вооружившись dev консолью в браузере. Типичное сообщение об ошибке выглядит как "Something went wrong; please try again".

Некоторый опыт дебаггинга помогает в этих ситуациях - можно на лету декомпозировать предполагаемый процесс, выбрать гипотезы, что именно пошло не так, и проверять их как техническими (поковыряться в браузере, изучить поведение системы с другими инпутами), так и социальными (общение с саппортом) методами. Иначе, наверное, можно было бы только сходить с ума в бессильной злобе.
Свежая работа OpenAI по генерации картинок лично меня впечатляет даже больше, чем та самая GPT-3.

Хотя, конечно, иногда результат скорее забавный, чем реалистичный.
Важный скилл, который зачастую отличает зрелых senior инженеров от зеленых щеглов, - умение мыслить в problem space, а не solution space. Разобраться в проблеме на достаточном уровне, а не пойти сразу чинить (чем попало).

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

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

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

Уже в этом году первым делом устроил суровое нагрузочное тестирование, которое показало неожиданное: новые лямбды ничем не отличаются от старых по latency и подобным метрикам. Новый деплой, новые таймауты, новый rollback. Наконец, более внимательное изучение логов показало, что таймауты и деплои никак не связаны, обновление ничего не ухудшило. Просто так совпало - примерно в то же время один из сервисов-пользователей изменил профиль нагрузки и начал иногда отправлять тяжелые (примерно в 10 раз тяжелее) запросы.
Для расширения кругозора я иногда отвечаю на Linkedin-приглашения поговорить от рекрутеров и стартаперов. В 2021 поговорил с двумя, и оба разговора получились едва ли не образцом того, что такое хорошо и что такое плохо.

Хорошо:

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

Плохо:

Харизматичный CEO небольшого стартапа из Калифорнии написал в Linkedin, кое-как назначил звонок, на котором усердно питчил продукт, хвастался вооот такими перспективами рынка AR-рекламы и неумело льстил "Arseny, we need people with great CS education as you have!". И только после этого прислал tech job description, составленный техлидом из одной гордой восточноевропейской страны; тут всплыло, что от computer vision инженера они в первую очередь ожидают глубокого знания JavaScript и браузерных API 🤦‍♂️
Не претендую на объективность, но есть ощущение, что в последние год-два академический ML-код стал значительно лучше и приблизился к production-ready качеству.

Еще недавно было нормальным или не выкладывать код к статье, или выкладывать жуткое поделие, хоть как-то запустить которое было серьезным вызовом. Эзотерические фреймворки, неуказанные зависимости, неочевидные форматы датасетов, слабовоспроизводимые результаты.

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

В общем, https://paperswithcode.com/ делает для индустрии очень много.
Из очередной статьи, критикующей переусложененный yaml, узнал про прекрасный шуточный язык программирования INTERCAL.

Некоторые фичи:
- прекрасные формулировки исключений вроде VARIABLES MAY NOT BE STORED IN WEST HYPERSPACE или I HAVE NO FILE AND I MUST SCREAM;
- свои названия для многих спецсимволов. Например, = называется half mesh, - называется worm, двойные кавычки и вовсе rabbit ears;
- вместо GOTO есть обратный оператор COMEFROM;
- операторы DO, PLEASE, or PLEASE DO взаимозаменяемы: these may be used interchangeably to improve the aesthetics of the program.
Недавно пишет мне fresh grad - бакалавр из американского универа второй лиги. Примерное содержание:

Бью челом тебе, мудрый старик!
Хочу быть
владычицей морскою крутым ML инженером и Kaggle-мастером, но математику учил плоховато - как выживать в этой сфере без крутой master's/PhD степени, будучи необразованным чурбаном самоучкой вроде тебя?

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

Но ведь видение мира с моего дивана по определению ограничено! Дорогие читатели, расскажите в комментариях, какую математику вам приходилось трогать в последнее время и насколько вы были к этому готовы?
Успешно выполнил такой план:
1. Прочитать статью, "опытным" глазом найти "неоптимальности" в архитектуре.
2. Вычистить код, заменить некоторые старые блоки модными, оптимизированными под быстрый инференс.
3. Прогнать бенчмарки на современном железе с последними версиями CUDA и torch, порадоваться своей крутизне.
4. Прогнать бенчмарки в окружении, близком к продакшену.
5. Осознать, что для этого окружения свертки 3x3 оптимизированы, а остальное - не очень.
6. Откатить все к черту.
Так как аудитория моего канала уже измеряется десятками миллионов самых умных, а иногда даже красивых читателей, неудивительно, что ко мне выстроилась очередь из рекламодателей. И первый в очереди мой старый кореш Максим.

У Максима серьезная проблема - нехватка тех самых прекрасных людей в команде. Их канадско-российскому стартапу denti.ai отчаянно нужны авторитетные ребята - например, мудрый CV engineer, который будет пилить платформу анализа стоматологических снимков.

Ожидания от человека примерно такие:
- что-то знать про object/landmark/instance detection, segmentation и прочие ML/DL/CV задачи;
- уметь находить и имплементить (на pytorch) свежие идеи из статей и собственной головы;
- уметь писать на Python так, чтобы коллеги не хотели сломать вам руки;
- сносно говорить по-английски (и шутить хотя бы по-русски);
- быть читателем канала @partially_unsupervised (обязательно!).

Макс будет рад платить такому человеку 4-6.5k$ в месяц на удаленке (фулл-тайм) с перспективой релокации в солнечный Торонто. Надоела унылая галера? Напишите ему на [email protected], и за каждое удачное собеседование он угостит меня кружкой пива при встрече! 🍺
Прикручиваю к продакшену новый пайплайн на замену старому. Значит, в т.ч. нужно обновить API в нескольких компонентах на разных стеках - Python, Scala, TypeScript. И в таком не ML-специфичном коде недостатки питона ощущаются сильнее, чем при написании ML-пайплайнов.

Например, без вывода типов нужно быть гораздо внимательнее в обработке ошибок: там где Scala ругнется на этапе компиляции про match is not exhaustive, в Python коде легко пропустить какую-нибудь валидацию (особенно, если сигнатура функции в духе def fn(Optional[CoolStuff])).

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

In [1]: from unittest.mock import patch
...:
...: config = {'foo': 'bar'}
...: other_config = {'foo': 42}
...:
...: class Thing:
...: def __init__(self, config):
...: self.config = config
...:
...: def __call__(self):
...: print(self.config['foo'])
...:
...: thing = Thing(config)
...: with patch('__main__.config', new=other_config):
...: thing()
...:
bar


Обойти, конечно, можно (передавать не сам конфиг, а замыкание с ним), но все равно как-то неаккуратно.

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

Хотелось сложить сотни гигабайт некритичных файлов (датасеты, не самые важные бэкапы и т.д.) так, чтобы это было просто (sync ~/data /awesome_storage) и дешево.

Первая мысль была про S3, но как-то это слишком "ентерпрайзно" для такой банальной задачи, да и априори не очень дешево ($0.023-0.025/Gb в зависимости от региона + куча подозрительных примечаний). Следующим вариантом был Digital Ocean Spaces, который в целом неплох и дает 250 Gb хранилища и 1Tb трафика за 5 баксов (дальше $0.02/Gb и $0.01/Gb соответственно), т.е. по деньгам ушел недалеко - довольно ожидаемо, все-таки это уже большая и с недавних пор публичная компания. Туда же идет Vultr (я использую их для ssh-туннелирования), который копирует Digital Ocean почти во всем, в т.ч. в прайсинге.

Приятной находкой стал BackBlaze. У этих ребят два продукта - backup решение (plug and play для нетехнарей) и S3-like хранилище с ценами сильно ниже ($0.005/Gb хранение, те же $0.01/Gb скачивание). Пользоваться легко, есть два CLI API - одно мимикрирует под S3, другое свое и чуть попроще (b2 sync origin source 🚀). Прям сейчас я туда заливаю всякое барахло с неидеальной скоростью в районе 5 Mbit/s, но кажется, что проблема скорее в моем исходящем канале.

Наконец, я наткнулся на Rclone. Это open source обертка над 50+ хранилищами, от своего FTP или SFTP до сервисов типа Dropbox и Google Drive. Вышеупомянутые S3, DO, Vultr и B2 тоже поддерживаются. Для более важных бэкапов можно, например, сделать синхронизацию между провайдерами в одну команду. Благодаря Rclone, мой терабайтный Яндекс.Диск (Яндекс дарит бывшим сотрудникам) теперь не пустует, а вовсю наполняется бэкапами.
Присылает мне Google страшное письмо с заголовком Change your compromised passwords. И дальше запугивает: Google found some of your passwords online. Anyone who finds them can access your accounts.

Я не слишком параноик, но напрягся. Выяснилось, что "утекли" пароли примерно от таких очень важных сервисов (см. скриншот).

В принципе, я готов пойти дальше и раскрыть тот факт, что на всех трех сервисах с картинки использован пароль 123123.
Если вы думали, что только неопытные секретарши из ООО "Рога и копыта" не умеют пользоваться электронной почтой и не отличают поля To, Cc и Bcc, то знайте, что и продакт менеджер из CloudFlare (такая небольшая технологическая конторка с капитализацией $22B) может ошибаться.

Отдельно иронично видеть среди получателей [email protected].
Недавно где-то на Реддите анонсировали новый агрегатор хайповых ML статей, благодаря которому вы можете еще легче находить свежие ресерчи, чтобы открывать их в новой вкладке, откладывать на потом и никогда не читать.

У этих же авторов обнаружился сервис Annotated PyTorch Paper Implementations: подборка их собственных реализаций статей с детальными комментариями. Набор статей не очень широкий, но если вам вдруг нужно погрузиться в тему, скажем, GANов или трансформеров с нуля, может быть полезно.

К сожалению, некоторые комментарии страдают от извечной проблемы плохих комментариев: описывают, что делает код, а не зачем/почему. Догадаться, что строка identity_loss = torch.nn.L1Loss() инициализирует L1 Loss, вполне можно без комментариев, а почему именно он - не так очевидно.
2025/07/03 08:50:42
Back to Top
HTML Embed Code: