partially unsupervised
6.52K subscribers
20 photos
2 files
154 links
@arsenyinfo пишет про software engineering и machine learning
Download Telegram
Свежая работа 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$ в месяц на удаленке (фулл-тайм) с перспективой релокации в солнечный Торонто. Надоела унылая галера? Напишите ему на max@denti.ai, и за каждое удачное собеседование он угостит меня кружкой пива при встрече! 🍺
Прикручиваю к продакшену новый пайплайн на замену старому. Значит, в т.ч. нужно обновить 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) может ошибаться.

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

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

К сожалению, некоторые комментарии страдают от извечной проблемы плохих комментариев: описывают, что делает код, а не зачем/почему. Догадаться, что строка identity_loss = torch.nn.L1Loss() инициализирует L1 Loss, вполне можно без комментариев, а почему именно он - не так очевидно.
Я фанат Streamlit и часто использую его там, где многие бы ограничились Jupyter. Основные сценарии использования в чем-то похожи на Jupyter ноутбуки, но позволяют высунуть наружу не сами исходники, а только несколько контролов, которые и нужно крутить. Очень удобно для всяких демок - например, показать результат коллегам вне ML команды и дать им возможность потыкать что-то своими руками без единой строчки кода. И никакого богомерзкого JS писать не нужно!

Так вот, недавно я добрался до их коллекции компонентов и окончательно влюбился. Так, например, при помощи drawable canvas я набросал инструмент для разметки ровно в том формате, который мне был нужен, примерно за 3 минуты (т.е. взял исходники с гитхаба и дописал пять строк). Очень рекомендую!
Я по работе последние полтора года активно пользуюсь AWS (до этого - совсем поверхностно, на уровне aws s3 cp s3://bucket/my_awesome_data /tmp), но с использованием устоявшейся и местами слегка запутанной инфраструктуры. Потому казалось, что AWS - это классная махина, но порог входа для новых проектов достаточно высокий.

И вот вчера решил сделать небольшое приложение для pet-проекта: буквально пара ендпоинтов. Ну и сразу задался целью сделать модный serverless на лямбдах. В качестве фреймворка взял chalice.

Так вот, это бомба! Код пишется настолько прямолинейно, насколько возможно, никакой инфраструктурной возни. Чтобы сложить логи в Cloudwatch, нужно дописать одну строку. Тестирование не требует никаких особых приседаний. Чтобы задеплоиться, нужно вбить одну команду chalice deploy. Когда понадобилось задеплоить жирный пакет (более 50 мб зависимостей, что превышает лимит загрузки кода в лямбду напрямую), пришлось прикрутить деплоймент через CloudFormation, и это тоже заняло аж 15 минут.

Кажется, что для stateful приложений придется потратить еще на 15 минут больше, чтобы прикрутить какую-нибудь DynamoDB. Но все равно - близкий к идеальному опыт использования.
Недавно обсуждали с приятелем о том, как подходить к незнакомой ML задаче. И это повод как-то сформулировать фреймворк, которому следую я сам.

0. Собрать небольшой, но качественный датасет (или взять готовый, если задача позволяет; см. также мой старый пост)
1. Поверхностно понять продуктовую задачу и попытаться ее сформулировать в терминах ML. Например, "нужно распознавать ключевые фразы по аудио" ⇒ sound classification (disclaimer - я как раз почти ничего не знаю об этой задаче).
2. Уточнить формулировку в гугле, найти соответствующий раздел на paperswithcode, взять оттуда пяток свежих SotA статей.
3. Погуглить task name + survey для поиска обзорных статей по теме.
4. Бегло прочитать все это, опционально прочитать еще пару статей, которые часто цитируются в прочитанных.
5. Получив базовую интуицию, подытожить, что в прочитанных статьях является свистелками-перделками, а что - ядром подходов. Например, для sound classification будет логично, что перегнать звук в спектрограмму, аугментировать (pitch, mixup) и натравить CNN - это важно, а attention на последнем слое - не очень.
6. Построить бейзлайн (или с нуля, или на базе готовой реализации, найденной на paperswithcode).
7. ...
8. PROFIT

Дополнения и критика приветствуются в комментариях!
С огромным удовольствием прочитал книгу про становление и падение Silk Road (goodreads, bookmate) - крупнейшего магазина дарквеба, который начинался с торговли грибами, а на пике торговал всем подряд - от автоматического оружия до донорских органов. Это совершенно нетехническая книга, но она про технологии. Точнее, про то, как технологии меняют те аспекты жизни, о которых мы (по крайней мере я) мало думаем - например, о том как изменились цепочки поставок веществ и о том, как можно довольно долго сохранять анонимность, если она по-настоящему нужна.

Написано драматично и захватывающе, по стилю довольно сильно напоминает Bad Blood, прекрасную историю расцвета и такого же падения Theranos.
image_2021-06-29_19-54-41.png
250.8 KB
Дорогие подписчики присылают контент для рубрики "Нерды шутят". Статья, кстати, реально существует.