newsmode
search
Меню
arrow_back Назад

More Design Patterns For Machine Learning Systems

auto_awesomeКраткое саммари

Юджин Янь делится девятью паттернами проектирования ML-систем, которые он наблюдал на практике: однократная обработка сырых данных, human-in-the-loop для сбора меток, аугментация данных, hard negative mining, переформулирование задачи, каскад, маховик данных, слой бизнес-правил и обязательная оценка перед деплоем. По каждому паттерну даны плюсы, минусы и реальные примеры из Amazon, Netflix, Meta, DoorDash, Cloudflare, Twitter, Shopify, Instagram, Stack Exchange, Uber и ChatGPT. Например, Cloudflare с помощью синтетических данных и curriculum learning снизила долю ложноположительных срабатываний классификатора вредоносных запросов примерно на 80%, а Meta при embedding-based retrieval выяснила, что оптимальное соотношение случайных и «трудных» негативов составляет 100:1. Исследования показывают, что gpt-3.5-turbo обходит работников Mechanical Turk на 4 из 5 задач аннотирования при цене менее $0.003 за метку (5% от стоимости MTurk), а gpt-4 превосходит экспертов и краудворкеров в классификации политической принадлежности пользователей Twitter. Автор также рассуждает, применимы ли эти паттерны к LLM-системам — например, слой бизнес-правил для безопасности, маховики данных для сбора фидбэка и каскады для автономных агентов.

More Design Patterns For Machine Learning Systems

Ещё паттерны проектирования для систем машинного обучения

[ machinelearning engineering production recsys ] · 20 min read

[ machinelearning engineering production recsys ] · 20 мин чтения

Design patterns are reusable, time-tested solutions to common problems in software engineering. They distill best practices and past knowledge into pragmatic advice for practitioners, and provide a shared vocabulary so we can collaborate effectively.

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

Here, I’d like to share a couple of patterns I’ve seen in machine learning systems. Some of them, such as process data once and evaluate before deploy, may seem basic to seasoned practitioners. Nonetheless, I’m including them because they’re essential, and surprisingly, not all teams adopt them. Please skip them if you’re already familiar with them.

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

(If you like this, you may also be interested in a previous post on design patterns in ML code, largely inspired by the classic Gang of Four book.)

(Если вам это интересно, возможно, понравится и предыдущий пост про паттерны проектирования в ML-коде, во многом вдохновлённый классической книгой «Банды четырёх».)

Process Raw Data Only Once: To reduce redundancy

Обрабатывать сырые данные только один раз: чтобы избежать избыточности

A key pattern when designing data pipelines is to process and aggregate raw data just once, preferably early on. This way, we can work with the processed data downstream instead of reading and computing over the raw data again and again.

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

  • Pros: Reduces redundancy and streamlines data processing jobs, making pipelines more efficient and maintainable. This reduces compute and storage costs.
  • Cons: It can be challenging to process and aggregate data in a way so it flexibly supports various use cases. And if we try to please everyone, we lose the benefits of early processing and might be better off working with the raw data.
  • Плюсы: сокращает избыточность и упорядочивает задачи обработки данных, делая пайплайны эффективнее и проще в поддержке. Это снижает расходы на вычисления и хранение. Минусы: бывает сложно обработать и агрегировать данные так, чтобы они гибко покрывали разные сценарии использования. А если пытаться угодить всем, выгода от ранней обработки теряется и проще работать с сырыми данными.

    Imagine we’re part of an e-commerce company that tracks user behavior via clickstream logs. The logs capture pages they visit, products they viewed, and actions they took (e.g., click, add-to-cart, purchase). This dataset is enormous (one object per event) and in a format not suited for analytics, such as in a Kafka queue as JSON instead of tables.

    Представьте, что мы работаем в e-commerce-компании, которая отслеживает поведение пользователей через логи кликстрима. Логи фиксируют посещённые страницы, просмотренные товары и действия (например, клик, добавление в корзину, покупку). Такой датасет огромен (один объект на каждое событие) и хранится в формате, не предназначенном для аналитики — например, в виде JSON в очереди Kafka, а не в таблицах.

    To build a dashboard for the conversion funnel, we’ll want to group logs by session and aggregate metrics on page visits, click-through rate, add-to-cart rate, conversion rate, etc. You can imagine other teams wanting to do similar analysis on this data too. Thus, instead of multiple teams building duplicate pipelines to process the raw data, we can process it once and store it in a tabular format for everyone to use. This way, we can efficiently query the processed or aggregated data for analytics and machine learning.

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

    Similarly, if we wanted to build a session-based recommender that recommends products based on a user’s in-session events, we could aggregate the data by session to get arrays of events ordered by time. This way, multiple teams can train their recommenders on these sequences instead of processing the raw logs from scratch during every training run.

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

    The natural extension of this pattern is the feature store pattern which centralizes feature computation and storage. Feature stores enable feature reuse and consistency across applications, and reduce duplicate effort, compute, and storage.

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

    Human-In-The-Loop: To collect explicit labels

    Human-In-The-Loop: чтобы собирать явные метки

    If our ML system involves supervised learning, we can’t get away with not having labels. And if we don’t have labels—such as when we’re solving a new problem—we can apply HITL to collect them. We can collect labels explicitly (e.g., annotation) or implicitly (e.g., organic clicks, purchases). This section will focus on collecting explicit labels.

    Если наша ML-система использует обучение с учителем, без меток не обойтись. А если меток нет — например, мы решаем новую задачу — можно применить HITL, чтобы их собрать. Метки можно собирать явно (например, аннотированием) или неявно (например, через органические клики и покупки). В этом разделе мы сосредоточимся на сборе явных меток.

  • Pros: Human annotators can deal with ambiguous or complex examples where heuristics or automated methods might fail. Also, collecting input from domain experts can ensure labels reflect the nuances of reality and their expertise.
  • Cons: Human annotation is expensive and takes time, making it a bottleneck.
  • Плюсы: люди-аннотаторы умеют разбираться с неоднозначными или сложными примерами, где эвристики или автоматизированные методы могут не сработать. Кроме того, привлечение экспертов гарантирует, что метки отражают нюансы реальности и их экспертный опыт. Минусы: ручное аннотирование дорого и долго, что делает его узким местом.

    One way to collect labels is to ask users directly. For example, Stack Exchange lets users flag posts as spam and then uses these labels to train spam detection models. Similarly, LinkedIn relies on users to report messages as harassment while Uber receives fraud reports when users dispute charges or file a chargeback.

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

    Flagging a post as spam, abusive, low quality, etc on Stack Exchange

    Пометка поста как спама, оскорбительного, низкокачественного и т.п. на Stack Exchange

    Another approach is to use third-party or internal annotation services. For example, DoorDash used a mix of Mechanical Turk and professional annotators to categorize menu items by cuisine style, flavor, etc. Similarly, Airbnb relied on HITL to categorize listings into various groups such as places of interest, activities, home types, and more.

    Другой подход — использовать сторонние или внутренние сервисы аннотирования. Например, DoorDash использовала комбинацию Mechanical Turk и профессиональных аннотаторов, чтобы категоризировать позиции меню по стилю кухни, вкусу и т.д. Аналогично, Airbnb опиралась на HITL, чтобы распределять объявления по различным группам: достопримечательностям, активностям, типам жилья и т.д.

    As an example of having expert annotators, Uber had internal analysts review fraud trends. These experts analyzed and identified new fraud patterns that machine learning models trained on past data might missed (i.e., false negatives), before crafting heuristics to programmatically identify them in future transactions. They also confirmed whether flagged transactions were indeed fraudulent (i.e., true positives).

    В качестве примера экспертных аннотаторов: в Uber внутренние аналитики разбирали тренды мошенничества. Эти эксперты анализировали и выявляли новые паттерны мошенничества, которые ML-модели, обученные на прошлых данных, могли пропустить (то есть false negatives), и затем формулировали эвристики для программного выявления таких случаев в будущих транзакциях. Они также подтверждали, действительно ли отмеченные транзакции были мошенническими (то есть true positives).

    That said, we may not require as much HITL in the future. Recent studies have found large language models (LLMs) to perform on par, or better than, people at labeling ground truth.

    При этом в будущем HITL может понадобиться нам в меньших объёмах. Недавние исследования показали, что большие языковые модели (LLM) справляются с разметкой ground truth наравне с людьми, а то и лучше.

    For example, a study found that gpt-3.5-turbo outperformed Mechanical Turk workers for four out of five annotation tasks (relevance, topic detection, stance detection, and frame detection) on 2,382 tweets. Furthermore, the cost was less than $0.003/annotation, making it 5% of the cost of Mechanical Turk per annotation.

    Например, исследование показало, что gpt-3.5-turbo превзошёл работников Mechanical Turk в четырёх из пяти задач аннотирования (релевантность, определение темы, определение позиции и определение фрейма) на 2 382 твитах. При этом стоимость составила менее $0.003 за аннотацию, то есть 5% от стоимости Mechanical Turk за аннотацию.

    Another study used gpt-4 to classify the political affiliation of Twitter users based on their tweets. Here, LLMs not only outperformed experts and crowdsourced workers in terms of accuracy, they also had higher inter-rater reliability. Even when the crowdsourced and expert labels were ensembled via majority vote, LLMs still performed better.

    В другом исследовании использовали gpt-4 для классификации политической принадлежности пользователей Twitter по их твитам. Здесь LLM не только превзошли экспертов и краудворкеров по точности, но и показали более высокую межоценочную согласованность. Даже когда метки краудворкеров и экспертов объединялись голосованием большинства, LLM всё равно показывали лучшие результаты.

    LLMs outperform crowdsource and expert annotators, even when the latter is ensembled

    LLM обходят краудворкеров и экспертов-аннотаторов, даже когда последних объединяют ансамблем

    Data Augmentation: To increase data size and diversity

    Аугментация данных: чтобы увеличить объём и разнообразие данных

    Data augmentation is the process of artificially increasing the size and diversity of training data by generating new examples from existing data.

    Аугментация данных — это процесс искусственного увеличения объёма и разнообразия обучающей выборки путём генерации новых примеров из существующих.

  • Pros: Valuable when ground truth data is limited, imbalanced, or lacks diversity. Data augmentation can make training data more representative and varied, thus helping to improve model generalizability and reduce overfitting.
  • Cons: Challenging to apply to tabular data (compared to image and text data). It can also be tricky to ensure that synthetic data matches the distribution of actual data.
  • Плюсы: полезна, когда ground truth ограничен, несбалансирован или однообразен. Аугментация делает обучающие данные более репрезентативными и разнообразными, что помогает улучшить обобщающую способность модели и снизить переобучение. Минусы: сложно применять к табличным данным (по сравнению с изображениями и текстом). Также бывает непросто гарантировать, что синтетические данные соответствуют распределению реальных.

    The classic example of data augmentation is in computer vision. In this PyTorch example, images are augmented through geometric transforms such as cropping, rotation, and flipping, as well as color transforms such as grayscale, blurring, and inversion. These simple transforms increase the volume and diversity of training data, improving the performance of CV models while reducing the cost of data collection and labeling.

    Классический пример аугментации данных — в компьютерном зрении. В этом примере на PyTorch изображения аугментируются геометрическими преобразованиями — обрезкой, поворотом, отражением, — а также цветовыми трансформациями вроде перевода в оттенки серого, размытия и инверсии. Эти простые преобразования увеличивают объём и разнообразие обучающих данных, повышая качество CV-моделей и снижая затраты на сбор и разметку данных.

    An example of data augmentation on text comes from DoorDash. They varied sentence order in food descriptions and randomly removed information such as menu categories. This helped simulate the variation in real-world menus where merchants don’t always have detailed descriptions or menu categories. When training their models, they used a ratio of 100 synthetic labels to 1 actual label.

    Пример аугментации данных на тексте — DoorDash. Они варьировали порядок предложений в описаниях блюд и случайным образом удаляли информацию, например категории меню. Это помогло симулировать разнообразие реальных меню, где у мерчантов не всегда есть подробные описания или категории. При обучении моделей они использовали соотношение 100 синтетических меток на 1 реальную.

    Data augmentation on text via varying sentence or word order

    Аугментация текстовых данных через изменение порядка предложений или слов

    Besides data augmentation, another way to expand the dataset is by creating synthetic data. For example, Cloudflare generated synthetic data to increase the diversity of their training data that is used to train models to classify malicious HTTP requests.

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

    To create negative samples, they generated pseudo-random strings based on a probability distribution of existing tokens in the training data. They also made it harder by adding complex tokens such as valid URIs, user agents, XML content, and even “dangerous” n-grams that frequently occur in malicious payloads. The goal was to desensitize the model to individual tokens and keywords and have it focus on the higher-level structural and semantic aspects of the payload. This reduced the false positive rate by ~80%.

    Чтобы создать негативные примеры, они генерировали псевдослучайные строки на основе распределения вероятностей существующих токенов в обучающих данных. Они также усложнили задачу, добавляя сложные токены: валидные URI, user-agent, XML-контент и даже «опасные» n-граммы, часто встречающиеся в вредоносных payload’ах. Цель была в том, чтобы десенсибилизировать модель к отдельным токенам и ключевым словам и заставить её сосредоточиться на структурных и семантических аспектах payload’а более высокого уровня. Это снизило долю ложноположительных срабатываний примерно на 80%.

    Similarly, Meta used synthetic data generators to create sensitive data such as social security numbers, credit card numbers, addresses, etc. Uber also generated synthetic data, based on their experience with and assumptions of fraud attacks, to validate their anomaly detection algorithms during automated testing of data pipelines. Libraries such as Faker makes it easy to generate fake names, addresses, phone number, and more.

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

    Hard Negative Mining: To get difficult samples

    Hard Negative Mining: чтобы получить сложные примеры

    Hard mining can be considered an extension of data augmentation where we find or generate challenging data points to train the model on. The intent is to improve model performance on these difficult cases by exposing it to more of them during training.

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

  • Pros: Often leads to improved model performance. At the very least, we can better measure how our models perform on these difficult cases.
  • Cons: Finding these hard examples can be, well, hard. It’s also not as simple as training the model solely on these hard examples too (see Meta example below).
  • Плюсы: часто ведёт к повышению качества модели. Как минимум, мы лучше измеряем, как модели справляются с этими сложными случаями. Минусы: найти такие сложные примеры бывает, что называется, сложно. Также нельзя просто обучать модель только на сложных примерах (см. пример Meta ниже).

    One approach to hard mining is to analyze model predictions for misclassified or low-confidence examples, find similar examples (e.g., nearest neighbors), and emphasize them in subsequent training. This forces the model to learn from its mistakes and improve.

    Один из подходов hard mining — анализировать предсказания модели в поиске неправильно классифицированных или низкоуверенных примеров, искать похожие примеры (например, ближайших соседей) и подчёркивать их в последующем обучении. Это заставляет модель учиться на своих ошибках и совершенствоваться.

    When Meta built embedding-based retrieval for search, they used hard mining to address the problem of easy negatives in the training data (i.e., random negatives). Easy negatives led to the model performing poorly on harder negatives. Counterintuitively, they found that models trained on hard negatives did not perform better than models trained on random negatives. This was because the hardest negatives did not reflect actual search behavior on Facebook where most documents (e.g., people, places) were relatively easy.

    Когда Meta строила embedding-based retrieval для поиска, они использовали hard mining, чтобы решить проблему слишком лёгких негативов в обучающих данных (то есть случайных негативов). Лёгкие негативы приводили к тому, что модель плохо справлялась с более сложными негативами. Парадоксально, но они обнаружили, что модели, обученные на сложных негативах, не работали лучше, чем модели, обученные на случайных. Причина была в том, что самые сложные негативы не отражали реальное поисковое поведение в Facebook, где большинство документов (люди, места) были относительно простыми.

    Through experimentation, they found that sampling hard negatives from rank 101 - 500 (in the search results) led to the best performance. Overall, blending random and hard negatives improved recall, saturating at an easy:hard ratio of 100:1. (DoorDash also had this ratio of synthetic to actual labels when training their models.)

    Экспериментально они выяснили, что сэмплирование сложных негативов с рангов 101–500 (в результатах поиска) даёт наилучшее качество. В целом, смешивание случайных и сложных негативов улучшало recall, выходя на плато при соотношении лёгких к сложным 100:1. (У DoorDash, кстати, тоже было такое соотношение синтетических меток к реальным при обучении моделей.)

    Another approach is to blend hard negatives in curriculum learning, where the training data is sorted to gradually increase sample difficulty. The model starts learning from easy samples before progressively tackling harder samples as it becomes more capable.

    Другой подход — смешивать сложные негативы в curriculum learning, где обучающие данные отсортированы так, что сложность примеров постепенно растёт. Модель начинает с лёгких примеров и постепенно переходит к более сложным по мере того, как становится способнее.

    Cloudflare adopted this approach by training their malicious payload classifier on easy synthetic data, followed by increasingly difficult synthetic data, before finally fine-tuning on real data. To make the task harder, they appended noise of varying complexity to malicious and benign samples, with the goal of making the model more robust to padding attacks. This improved the true positive rate for fuzzed content from 91% to 97.5%.

    Cloudflare использовала этот подход, обучая свой классификатор вредоносных payload’ов сначала на простых синтетических данных, затем на всё более сложных, а в финале — дообучая на реальных. Чтобы усложнить задачу, они добавляли шум разной сложности к вредоносным и безопасным примерам с целью сделать модель более устойчивой к padding-атакам. Это повысило true positive rate для зафуззенного контента с 91% до 97,5%.

    Reframing: To simplify the problem or label

    Переформулирование задачи: чтобы упростить проблему или метку

    To reframe is to make a problem easier to solve by refining the initial problem statement or transforming the target feature. For example, we might reframe a regression problem into a classification problem, and vice versa.

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

  • Pros: Can lead to large model or business metric improvements without too much effort, especially if we’re just transforming the label or using a different technique.
  • Cons: Uncommon to successfully reframe a problem. Successful examples are infrequent and it’s more art than science.
  • Плюсы: может привести к большому росту модельных или бизнес-метрик без особых усилий, особенно если мы просто трансформируем метку или применяем другую технику. Минусы: успешно переформулировать задачу удаётся нечасто. Успешные примеры редки, и это скорее искусство, чем наука.

    For Amazon’s semantic search, the team initially had a binary label: purchased or not. They then used a two part-hinge loss where \(\hat y\) is the cosine similarity between query and product embeddings, and \(y = 1\) if the product is purchased (in response to the query) and zero otherwise. The hinge loss ensured that \(\hat y > 0.9\) when \(y = 1\) and \(\hat y < 0.2\) when \(y = 0\).

    В семантическом поиске Amazon у команды изначально была бинарная метка: куплено или нет. Затем они использовали двухчастный hinge loss, где \(\hat y\) — косинусное сходство между эмбеддингами запроса и товара, а \(y = 1\), если товар был куплен (в ответ на запрос), и ноль в противном случае. Hinge loss обеспечивал, что \(\hat y > 0.9\) при \(y = 1\) и \(\hat y < 0.2\) при \(y = 0\).

    However, they found a large overlap in score distribution (left in image below) between the random negatives (red) and purchased positives (green). After some analysis, they found that this was due to products that were impressed but not purchased. Thus, they updated their target label to distinguish between products that were impressed but not purchased (grey) and random negatives (red). They also used a three-part hinge loss, where \(\hat y < 0.55\) if the product was impressed but not purchased. This improved the separation of scores between random negatives (red) and purchased positives (green).

    Однако они обнаружили большое пересечение распределений оценок (слева на картинке ниже) между случайными негативами (красный) и купленными позитивами (зелёный). После анализа выяснилось, что это связано с товарами, которые показывались, но не были куплены. Поэтому они обновили целевую метку, чтобы различать товары, которые были показаны, но не куплены (серый), и случайные негативы (красный). Они также использовали трёхчастный hinge loss, где \(\hat y < 0.55\), если товар был показан, но не куплен. Это улучшило разделение оценок между случайными негативами (красный) и купленными позитивами (зелёный).

    Score distribution with two-part (left) and three-part (right) hinge loss

    Распределение оценок при двухчастном (слева) и трёхчастном (справа) hinge loss

    Another example of reframing is Shopify’s product classifier. To simplify the problem of classifying items into a 5,000 class, hierarchical taxonomy, they converted n one-vs-all classifiers into a single binary classifier. They did this by exploding the training data to create a row for each category for each product, and then appending the category to the features. Finally, if the product-category pair is valid, it gets a label of 1, and 0 otherwise. They also considered hierarchy by giving parents of a valid category a label of 1.

    Другой пример переформулирования — классификатор товаров Shopify. Чтобы упростить задачу классификации товаров по 5 000-классовой иерархической таксономии, они преобразовали n классификаторов «один против всех» в один бинарный классификатор. Они сделали это, развернув обучающую выборку так, чтобы для каждого товара получилась строка на каждую категорию, и добавив категорию к признакам. Если пара «товар-категория» валидна, метка равна 1, иначе 0. Они также учитывали иерархию, присваивая метку 1 родителям валидной категории.

    This allowed them to train a single logistic regression model instead of \(n\) individual classifiers, reducing computation cost and keeping the system simple. Accounting for parent-child relationships also enabled them to learn from the taxonomy structure.

    Это позволило им обучить одну логистическую регрессию вместо \(n\) отдельных классификаторов, сократив вычислительные затраты и сохранив систему простой. Учёт связей «родитель-потомок» также позволил учиться на структуре таксономии.

    During inference, they start at the root level category, categorizing the product into the top-level node with the highest score. This continues by scoring the product for each of the node’s children, picking the node with the highest score, until the leaf node is reached.

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

    Categorizing products by traversing through the product taxonomy

    Категоризация товаров через обход таксономии товаров

    A final example is the reframing of recommendations from the co-occurrence problem (e.g., matrix factorization) into a sequential problem (e.g., RNNs, Transformers). One of the earliest papers to do this applied GRUs for session-level recommendations. It was motivated by the need to learn from short, session-level data due to the lack of long user histories (such as those that Amazon or Netflix has).

    Последний пример — переформулирование рекомендаций из задачи о совместной встречаемости (например, матричная факторизация) в задачу о последовательностях (например, RNN, Transformers). Одна из самых ранних работ в этом направлении применила GRU для сессионных рекомендаций. Она была мотивирована необходимостью учиться на коротких сессионных данных из-за отсутствия длинных историй пользователей (таких, как у Amazon или Netflix).

    Since then, a large portion of recsys research has shifted towards the sequential paradigm, such as Self-Attentive Sequential Recommendations, Behavior Sequence Transformer, BERT4Rec, and more. Empirically, these approaches have been more effective than co-occurrence techniques though the latter remains a competitive baseline.

    С тех пор значительная часть исследований по recsys сместилась к последовательной парадигме: Self-Attentive Sequential Recommendations, Behavior Sequence Transformer, BERT4Rec и др. Эмпирически эти подходы оказывались эффективнее техник, основанных на совместной встречаемости, хотя последние остаются конкурентоспособным базовым решением.

    Cascade: To split a problem into smaller problems

    Каскад: чтобы разбить задачу на меньшие

    The cascade pattern splits an initial problem into smaller problems that can be solved sequentially. Thus, each subsequent model or system focuses on an increasingly difficult or smaller subset of the data. This is similar to the ensemble pattern but considers order.

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

  • Pros: Allows cheaper heuristics and models to chip away at the problem upstream before the harder cases are sent downstream to costlier but more precise models. This improves overall efficiency and system performance. Also makes it easier to structure teams that can independently focus on each step of the cascade.
  • Cons: Can lead to unintended coupling or degenerate interaction effects, where downstream models may overly rely on upstream models to act in a certain way.
  • Плюсы: позволяет более дешёвым эвристикам и моделям отсеивать задачу выше по потоку, прежде чем сложные случаи попадут к более дорогим, но точным моделям ниже. Это улучшает общую эффективность и качество системы. Также упрощает структурирование команд, каждая из которых может независимо отвечать за свой шаг каскада. Минусы: может приводить к нежелательной связности или вырожденным эффектам взаимодействия, когда нижестоящие модели чрезмерно полагаются на определённое поведение вышестоящих.

    A classic example of a cascade is recommender system design, usually split into retrieval and ranking steps. Retrieval is a fast but coarse step to narrow down millions of items into hundreds of candidates. Ranking is a slower but more precise step to score the retrieval candidates. Structuring it as a cascade allows each step to optimize for different objectives—retrieval optimizes for recall and speed while ranking optimizes for precision.

    Классический пример каскада — дизайн рекомендательных систем, обычно разделённый на этапы retrieval и ranking. Retrieval — быстрый, но грубый шаг, сужающий миллионы товаров до сотен кандидатов. Ranking — более медленный, но точный шаг, оценивающий кандидатов после retrieval. Такая структура каскада позволяет каждому шагу оптимизироваться под разные цели: retrieval оптимизирует recall и скорость, а ranking — точность.

    Candidate retrieval -> ranking -> heuristics & filtering -> ads blending

    Candidate retrieval -> ranking -> эвристики и фильтрация -> подмешивание рекламы

    Twitter’s recently open-sourced recsys follows this pattern (image above). Their recsys is a cascade of (i) candidate sourcing (aka retrieval), (ii) heavy ranking, (iii) heuristics and filtering, and (iv) ads blending. Multiple components contribute to retrieval before the heavy ranker (a parallel masknet) does the ranking. Finally, business rules are layered on.

    Недавно открытая Twitter recsys следует этому паттерну (картинка выше). Их recsys — это каскад: (i) candidate sourcing (он же retrieval), (ii) heavy ranking, (iii) эвристики и фильтрация, (iv) подмешивание рекламы. В retrieval вносят вклад несколько компонентов, прежде чем тяжёлый ранкер (параллельный masknet) выполняет ранжирование. В конце поверх накладываются бизнес-правила.

    Stack Exchange also adopts a cascade pattern to identify spam. It starts with identifying users that post too often to be humanly possible. The spammer is then slapped with an HTTP 429 Error (Too Many Requests) and blocked or rate-limited.

    Stack Exchange тоже использует паттерн каскада для выявления спама. Сначала выявляются пользователи, которые публикуют посты слишком часто, чтобы это было по силам человеку. Спамеру выдаётся HTTP 429 Error (Too Many Requests), и он блокируется или ограничивается по частоте.

    Three layers of defense against spam: Post rates -> heuristics -> machine learning

    Три уровня защиты от спама: частота постов -> эвристики -> машинное обучение

    The second step in the cascade is based on heuristics. Specifically, they run posts through an “unholy amount of regular expressions” and some rules. If a post is caught, it is sent to users to check and potentially flag it as spam. If enough users flag it as spam, the post is marked as spam and the spammer is blocked, rate-limited, or prevented from posting.

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

    The final line of defense is a (machine learning?) system that identifies posts most likely to be spam. They shadow-tested it and found it to be extremely accurate, catching almost all of the blatantly obvious spam. Eventually, this system was armed to cast three automatic flags, drastically reducing the time to spam post deletion.

    Последний рубеж защиты — это (machine learning?) система, которая выявляет посты, наиболее вероятно являющиеся спамом. Они shadow-тестировали её и выяснили, что она крайне точна, отлавливая почти весь явно очевидный спам. В итоге система получила право автоматически выставлять три флага, что существенно сократило время до удаления спам-постов.

    Data Flywheel: To continuously improve & build a moat

    Маховик данных: чтобы непрерывно улучшаться и строить ров

    The data flywheel pattern revolves (pun intended) around continuously collecting data which then improves models which then improves user experience. This leads to more usage, which leads to more data to further improve models, creating a virtuous cycle.

    Паттерн маховика данных вращается (каламбур уместен) вокруг непрерывного сбора данных, который улучшает модели, которые улучшают пользовательский опыт. Это ведёт к большему использованию, что даёт больше данных для дальнейшего улучшения моделей, создавая благотворный цикл.

  • Pros: One of the few sources of long-term competitive advantage. While model architecture and system design can be copied, they’re moot without the data.
  • Cons: It can lead to a feedback loop where bias perpetuates (e.g., popularity bias in recsys) though data augmentation can alleviate this.
  • Плюсы: один из немногих источников долгосрочного конкурентного преимущества. Архитектуру модели и дизайн системы скопировать можно, но без данных они бессмысленны. Минусы: может возникнуть петля обратной связи, в которой увековечивается смещение (например, popularity bias в recsys), хотя аугментация данных может это смягчить.

    A prime example of the data flywheel is the recommendation systems at Amazon and Netflix. When users look for their next show on Netflix, their searches, clicks, previews, watch time, and ratings are logged. This data is then used to build recsys that learn from their preferences and serve personalized recommendations. As a result, users spend more time on Netflix, generating more data which further improves the recommendations.

    Яркий пример маховика данных — рекомендательные системы Amazon и Netflix. Когда пользователи ищут следующий сериал на Netflix, их поисковые запросы, клики, превью, время просмотра и оценки логируются. Эти данные затем используются для построения recsys, которые учатся на их предпочтениях и выдают персонализированные рекомендации. В результате пользователи проводят на Netflix больше времени, генерируя больше данных, которые ещё сильнее улучшают рекомендации.

    Another example is Tesla’s Autopilot. Tesla collects driving images and videos from its vehicles as a data source. From this data, they identify errors, find similar instances (e.g., nearest neighbors), and label them. These new labels are then used to retrain models which are then deployed to vehicles. Armed with the new models, the vehicles then gather more driving data, completing the data flywheel.

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

    Andrej Karpathy sharing about Telsa's data engine

    Андрей Карпатый рассказывает о Tesla data engine

    A final example is ChatGPT. It was built as a way to collect feedback directly from users:

    Последний пример — ChatGPT. Он был построен как способ собирать обратную связь непосредственно от пользователей:

    Sam Altman mentioned that one of the main reasons OpenAI built ChatGPT was so that they could get human feedback from end users back into their models. In other words, they started out as API-only, but realized that the best way to improve performance was to integrate forward over more layers of the value chain so they could get direct access to customers’ data. — Dan Shipper

    Сэм Альтман упоминал, что одной из главных причин, по которой OpenAI создала ChatGPT, было желание получать обратную связь от живых пользователей обратно в свои модели. Иными словами, они начинали как API-only, но поняли, что лучший способ улучшить качество — интегрироваться вперёд по большему количеству слоёв value chain, чтобы получить прямой доступ к данным клиентов. — Дэн Шиппер

    By building a simple chat UI and allowing users to provide feedback (thumbs up/down), OpenAI can now directly collect feedback to improve their models. GPT-4 is also integrated with Bing Search which responds with a summary of the top results. The response includes links to sources that users can browse and click on. Here, implicit user feedback (i.e., clicks on sources) also helps with improving document retrieval.

    Построив простой чат-интерфейс и позволив пользователям давать обратную связь (лайки/дизлайки), OpenAI теперь может напрямую собирать фидбэк для улучшения своих моделей. GPT-4 также интегрирован с Bing Search, который отвечает резюме топ-результатов. Ответ включает ссылки на источники, которые пользователи могут просматривать и кликать. Здесь неявная обратная связь от пользователей (то есть клики по источникам) также помогает улучшать document retrieval.

    Business Rules Layer: To augment or override outputs

    Слой бизнес-правил: чтобы дополнять или переопределять выводы

    The business rules layer allows us to incorporate domain expertise and business rules to augment or adjust the output of ML systems. I can’t recall the last time I came across a mature machine learning system that didn’t have this.

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

  • Pros: Ensures that machine learning outputs align with business requirements and constraints. This helps improve system reliability, safety, and usability.
  • Cons: If managed poorly, can lead to a byzantine web of interacting rules that override each other in unexpected ways. May also encourage the anti-pattern of adding rules to fix short-term problems without addressing the underlying issue.
  • Плюсы: гарантирует, что выводы ML соответствуют бизнес-требованиям и ограничениям. Это помогает улучшить надёжность, безопасность и удобство системы. Минусы: при плохом управлении может вылиться в византийскую паутину взаимодействующих правил, которые неожиданным образом перекрывают друг друга. Также может поощрять анти-паттерн добавления правил для решения краткосрочных проблем без устранения первопричины.

    This pattern is common in recsys. For example, when Instagram shared about their recommender infrastructure, they also shared a sample recommender where the last step performs diversification in a round-robin fashion.

    Этот паттерн распространён в recsys. Например, когда Instagram рассказывал о своей рекомендательной инфраструктуре, они также показали пример рекомендателя, где последний шаг выполняет диверсификацию по принципу round-robin.

    user .let(seed_id=user_id) .liked(max_num_to_retrieve=30) .account_nn(embedding_config=default) .posted_media(max_media_per_account=10) .filter(non_recommendable_model_threshold=0.2) .rank(ranking_model=default) .diversify_by(seed_id, method=round_robin)

    user .let(seed_id=user_id) .liked(max_num_to_retrieve=30) .account_nn(embedding_config=default) .posted_media(max_media_per_account=10) .filter(non_recommendable_model_threshold=0.2) .rank(ranking_model=default) .diversify_by(seed_id, method=round_robin)

    An example recommender for Instagram. Note the diversification step in the last line.

    Пример рекомендателя для Instagram. Обратите внимание на шаг диверсификации в последней строке.

    Similarly, Twitter uses hand-tuned weights (below) to combine the outputs of their heavy ranker via a weighted sum across predicted engagement probabilities. In addition, at the heuristic and filtering stage (after retrieval and ranking), they apply heuristics such as author diversity, negative user feedback, and Twitter verified boost.

    Аналогично, Twitter использует подобранные вручную веса (ниже), чтобы скомбинировать выходы тяжёлого ранкера через взвешенную сумму предсказанных вероятностей вовлечённости. Кроме того, на этапе эвристик и фильтрации (после retrieval и ranking) они применяют эвристики: диверсификацию авторов, негативный пользовательский фидбэк и буст для верифицированных в Twitter.

    scored_tweets_model_weight_fav: 0.5 scored_tweets_model_weight_retweet: 1.0 scored_tweets_model_weight_reply: 13.5 scored_tweets_model_weight_good_profile_click: 12.0 scored_tweets_model_weight_video_playback50: 0.005 scored_tweets_model_weight_reply_engaged_by_author: 75.0 scored_tweets_model_weight_good_click: 11.0 scored_tweets_model_weight_good_click_v2: 10.0 scored_tweets_model_weight_negative_feedback_v2: -74.0 scored_tweets_model_weight_report: -369.0

    scored_tweets_model_weight_fav: 0.5 scored_tweets_model_weight_retweet: 1.0 scored_tweets_model_weight_reply: 13.5 scored_tweets_model_weight_good_profile_click: 12.0 scored_tweets_model_weight_video_playback50: 0.005 scored_tweets_model_weight_reply_engaged_by_author: 75.0 scored_tweets_model_weight_good_click: 11.0 scored_tweets_model_weight_good_click_v2: 10.0 scored_tweets_model_weight_negative_feedback_v2: -74.0 scored_tweets_model_weight_report: -369.0

    Hand-tuned weights for various engagement probabilities on Twitter's recommender system.

    Подобранные вручную веса для различных вероятностей вовлечённости в рекомендательной системе Twitter.

    Other examples of heuristics and business rules affecting the final output include Netflix’s calibrated recommendations to match users’ historical genre distribution, and Pinterest’s use of hand-tuned weights (in the Memboost step) after retrieval and ranking.

    Другие примеры эвристик и бизнес-правил, влияющих на финальный вывод, — калиброванные рекомендации Netflix, чтобы совпадать с историческим жанровым распределением пользователя, и использование подобранных вручную весов Pinterest (в шаге Memboost) после retrieval и ranking.

    Also, if you’ve been using ChatGPT, you may have experienced its rules layer. These constraints ensure that its responses align with ethical guidelines and is safe for users. Try asking ChatGPT about a dangerous subject, or its opinion on a political figure. For the former, it declines to provide information (“I’m sorry, but I cannot provide information or assistance on creating dangerous weapons…“) while for the latter, it returns a neutral response (“As an AI language model, I don’t have personal opinions or views.”)

    Также, если вы пользовались ChatGPT, вы могли испытать на себе его слой правил. Эти ограничения гарантируют, что его ответы соответствуют этическим принципам и безопасны для пользователей. Попробуйте спросить ChatGPT об опасной теме или его мнении о политической фигуре. В первом случае он откажется предоставлять информацию («К сожалению, я не могу предоставить информацию или помощь в создании опасного оружия…»), во втором — вернёт нейтральный ответ («Как языковая модель ИИ, у меня нет личных мнений или взглядов»).

    ChatGPT declining to provide information on dangerous subjects or political views.

    ChatGPT отказывается предоставлять информацию по опасным темам или политическим взглядам.

    Evaluate before Deploy: For safety and reliability

    Оценка перед деплоем: ради безопасности и надёжности

    This pattern represents the best practice of evaluating model (e.g., evaluation metrics) and system (e.g., error rate, latency) performance before integrating it into production. Not that different from testing builds before deployment IMO—in other words, please do this.

    Этот паттерн отражает лучшую практику оценивать модель (например, по evaluation-метрикам) и систему (например, по error rate, latency) перед интеграцией в продакшен. По мне, не сильно отличается от тестирования сборок перед деплоем — иными словами, пожалуйста, делайте это.

  • Pros: Reduces the risk of poor model performance, biased predictions, or other issues that may negatively affect user experience or business objectives.
  • Cons: None that I can think of.
  • Плюсы: снижает риск плохого качества модели, смещённых предсказаний или иных проблем, которые могут негативно повлиять на пользовательский опыт или бизнес-цели. Минусы: я не могу придумать ни одного.

    To adopt this pattern, simply have a validation hold-out when (re)training models. Given the strong temporal aspect in most production systems, the validation set should typically be split by time; using a random split or cross-validation could lead to overly optimistic evaluation metrics, especially if future data leaks into the training set.

    Чтобы внедрить этот паттерн, достаточно иметь валидационный hold-out при (пере)обучении моделей. Учитывая сильный временной аспект в большинстве продакшен-систем, валидационный набор обычно стоит делить по времени; случайный сплит или кросс-валидация могут привести к завышенно оптимистичным evaluation-метрикам, особенно если будущие данные просочатся в обучающую выборку.

    Take recommendation systems as an example. We might hold out the last period of data (e.g., day, hour), refresh our models based on new data, and evaluate on the validation set via the usual metrics such as hit@k, NDCG, etc. (And then—specific to recsys—we might then train the model on the validation set too because we want to overfit.) We can also compare it against a naive baseline (e.g., popularity sort) to get a sense of the lift. If the refreshed model fails on any of the evaluation metrics, the pipeline should break and the model should not be released—better to have a stale model than a misbehaving one.

    Возьмём рекомендательные системы как пример. Мы можем отложить последний период данных (например, день, час), переобучить модели на новых данных и оценить на валидационном наборе привычными метриками вроде hit@k, NDCG и т.п. (А затем — конкретно в recsys — можем дообучить модель и на валидационном наборе, потому что хотим переобучиться.) Также можно сравнить с наивным baseline (например, сортировкой по популярности), чтобы понять прирост. Если переобученная модель проваливает любую из evaluation-метрик, пайплайн должен сломаться и модель не должна выкатываться — лучше иметь устаревшую модель, чем поломанную.

    • • •

    • • •

    Wow, thanks for sticking till the end! We discussed nine design patterns in machine learning systems. You won’t find many of these—reframing, cascade, business rules, evaluate before deploy—explicitly mentioned in papers or tech blogs. And if you enjoyed this, you might also be interested in the proxy and mediator patterns discussed previously.

    Ого, спасибо, что дочитали до конца! Мы обсудили девять паттернов проектирования в ML-системах. Многие из них — переформулирование, каскад, бизнес-правила, оценка перед деплоем — вы не часто встретите явно упомянутыми в статьях или техблогах. И если вам понравилось, возможно, вам будут интересны и паттерны proxy и mediator, разобранные ранее.

    These patterns have served me well as I design, build, and operate ML systems. Also, given the increasing viability of using LLMs in production, I wonder if these patterns are also applicable to LLM systems? Some I can think of include:

    Эти паттерны хорошо служили мне при проектировании, построении и эксплуатации ML-систем. К тому же, учитывая растущую пригодность LLM для продакшена, мне интересно: применимы ли эти паттерны к LLM-системам? Кое-что приходит на ум:

  • Having a business rules layer on LLM output for safety and reliability
  • Data flywheels to continuously collect user feedback to fine-tune models
  • Adopting the cascade pattern when building autonomous agents
  • Слой бизнес-правил поверх выхода LLM ради безопасности и надёжности. Маховики данных для непрерывного сбора пользовательской обратной связи для дообучения моделей. Применение паттерна каскада при построении автономных агентов.

    What other patterns have you seen in machine learning or LLM systems? Please share!

    Какие ещё паттерны вы встречали в системах машинного обучения или LLM? Делитесь!

    References

    Ссылки

  • How does spam protection work on Stack Exchange?
  • The technology behind fighting harassment on LinkedIn
  • Project RADAR: Intelligent Early Fraud Detection System with Humans in the Loop
  • Using a HITL to Overcome the Cold Start Problem in Menu Item Tagging
  • Building Airbnb Categories with ML and Human-in-the-Loop
  • ChatGPT Outperforms Crowd-Workers for Text-Annotation Tasks
  • ChatGPT-4 Outperforms Experts and Crowd Workers in Annotating Political Twitter Messages with Zero-Shot Learning
  • Improving the accuracy of machine learning using data augmentation & sampling
  • Scalable Data Classification for Security and Privacy
  • Embedding-based Retrieval in Facebook Search
  • Curriculum Learning: A Survey
  • Semantic Product Search
  • Categorizing Products at Scale
  • Session-based Recommendations with Recurrent Neural Networks
  • Self-Attentive Sequential Recommendation
  • Behavior Sequence Transformer for E-commerce Recommendation in Alibaba
  • BERT4Rec: Sequential Recommendation with Bidirectional Encoder Representations from Transformer
  • Twitter’s Recommendation Algorithm
  • MaskNet: Introducing Feature-Wise Multiplication to CTR Ranking Models by Instance-Guided Mask
  • Powered by AI: Instagram’s Explore recommender system
  • Calibrated Recommendations
  • Related Pins at Pinterest: The Evolution of a Real-World Recommender System
  • How does spam protection work on Stack Exchange? The technology behind fighting harassment on LinkedIn Project RADAR: Intelligent Early Fraud Detection System with Humans in the Loop Using a HITL to Overcome the Cold Start Problem in Menu Item Tagging Building Airbnb Categories with ML and Human-in-the-Loop ChatGPT Outperforms Crowd-Workers for Text-Annotation Tasks ChatGPT-4 Outperforms Experts and Crowd Workers in Annotating Political Twitter Messages with Zero-Shot Learning Improving the accuracy of machine learning using data augmentation & sampling Scalable Data Classification for Security and Privacy Embedding-based Retrieval in Facebook Search Curriculum Learning: A Survey Semantic Product Search Categorizing Products at Scale Session-based Recommendations with Recurrent Neural Networks Self-Attentive Sequential Recommendation Behavior Sequence Transformer for E-commerce Recommendation in Alibaba BERT4Rec: Sequential Recommendation with Bidirectional Encoder Representations from Transformer Twitter's Recommendation Algorithm MaskNet: Introducing Feature-Wise Multiplication to CTR Ranking Models by Instance-Guided Mask Powered by AI: Instagram's Explore recommender system Calibrated Recommendations Related Pins at Pinterest: The Evolution of a Real-World Recommender System

    OG image prompt on MidJourney: “a woman drawing a system design diagram, in the style of contrasting tones, artifacts of online culture, innovative page design, complexity theory, bold black and whites, bold color scheme, rectangular fields –ar 2:1”

    Промпт для OG-картинки в MidJourney: «a woman drawing a system design diagram, in the style of contrasting tones, artifacts of online culture, innovative page design, complexity theory, bold black and whites, bold color scheme, rectangular fields –ar 2:1»

    If you found this useful, please cite this write-up as:

    Если вам это пригодилось, пожалуйста, цитируйте эту заметку так:

    Yan, Ziyou. (Apr 2023). More Design Patterns For Machine Learning Systems. eugeneyan.com. https://eugeneyan.com/writing/more-patterns/.

    Yan, Ziyou. (Apr 2023). More Design Patterns For Machine Learning Systems. eugeneyan.com. https://eugeneyan.com/writing/more-patterns/.

    or

    или

    @article{yan2023patterns2, title = {More Design Patterns For Machine Learning Systems}, author = {Yan, Ziyou}, journal = {eugeneyan.com}, year = {2023}, month = {Apr}, url = {https://eugeneyan.com/writing/more-patterns/} }

    @article{yan2023patterns2, title = {More Design Patterns For Machine Learning Systems}, author = {Yan, Ziyou}, journal = {eugeneyan.com}, year = {2023}, month = {Apr}, url = {https://eugeneyan.com/writing/more-patterns/} }



    Join 11,800+ readers getting updates on machine learning, RecSys, LLMs, and engineering.

    К 11 800+ читателям, получающим обновления о машинном обучении, RecSys, LLM и инженерии.