<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Han Li on Medium]]></title>
        <description><![CDATA[Stories by Han Li on Medium]]></description>
        <link>https://medium.com/@hanli_57704?source=rss-b7d1ceadc933------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*dHKPvHQ6-DkdkBGvxggMow.jpeg</url>
            <title>Stories by Han Li on Medium</title>
            <link>https://medium.com/@hanli_57704?source=rss-b7d1ceadc933------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 18:37:47 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@hanli_57704/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Unveiling the Core of Instacart’s Griffin 2.0:]]></title>
            <link>https://tech.instacart.com/unveiling-the-core-of-instacarts-griffin-2-0-8ecb310c8d32?source=rss-b7d1ceadc933------2</link>
            <guid isPermaLink="false">https://medium.com/p/8ecb310c8d32</guid>
            <category><![CDATA[mlops]]></category>
            <category><![CDATA[machine-learning]]></category>
            <dc:creator><![CDATA[Han Li]]></dc:creator>
            <pubDate>Mon, 20 Nov 2023 21:41:36 GMT</pubDate>
            <atom:updated>2023-11-20T21:41:36.740Z</atom:updated>
            <content:encoded><![CDATA[<h3>Unveiling the Core of Instacart’s Griffin 2.0: A Deep Dive into the Machine Learning Training Platform</h3><p>Authors: <a href="https://www.linkedin.com/in/hanli0612/">Han Li</a>, <a href="https://www.linkedin.com/in/sahil-khanna-umd/">Sahil Khanna</a>, <a href="https://www.linkedin.com/in/jocelyndlr/">Jocelyn De La Rosa</a>, <a href="https://www.linkedin.com/in/moping-dou/">Moping Dou</a>, <a href="https://www.linkedin.com/in/sharadgupta29/">Sharad Gupta</a>, <a href="https://www.linkedin.com/in/chenyangyu/">Chenyang Yu</a> and <a href="https://www.linkedin.com/in/rajpal-paryani-48b32014/">Rajpal Paryani</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oPSfKUUbMBwvpRoHbSJD4g.png" /></figure><h3>Background</h3><p>About a year ago, we introduced the first version of Griffin, Instacart’s first ML Platform, detailing its development and support for end-to-end ML in a previous <a href="https://tech.instacart.com/griffin-how-instacarts-ml-platform-tripled-ml-applications-in-a-year-d3d4dcae3690">post</a>. In our last week announcement, we unveiled <a href="https://tech.instacart.com/introducing-griffin-2-0-instacarts-next-gen-ml-platform-b7331e73b8d7">Griffin 2.0</a>, our advanced ML Platform, shedding light on the transition from Griffin 1.0 to 2.0 for a more cohesive user experience, refined model management, distributed computation capabilities, and enhanced deployment automation. The Griffin 2.0 post provided insights into all key components of the system, including the Griffin UI, Feature Marketplace, ML Training Platform, and ML Serving Platform.</p><p>In this article, we focus on the technical details of constructing the ML Training Platform (MLTP) within Griffin 2.0. MLTP introduces innovative functionalities such as a centralized web interface, a distributed computation framework, standard ML builds, orchestration services, and a scalable metadata store, which collectively contribute to the comprehensive creation and management of training workloads at Instacart.</p><h3>Crafting Strategies</h3><p>In the development of Griffin 2.0 MLTP, our goal was to establish a unified and centralized platform where all MLEs can seamlessly create, track, and manage their training workloads. We aimed to support distributed machine learning, preparing the platform for tasks such as distributed training, batch inference, and Large Language Model (LLM) fine-tuning. Simultaneously, we wanted to address the limitations identified in Griffin 1.0, as detailed in our previous post. These considerations led us to make the following strategic design decisions:</p><ul><li><strong><em>A Singular Interface</em></strong>: Griffin 1.0 required MLEs to navigate through multiple systems for comprehensive training workload information. Griffin 2.0 brings all tools into a unified web interface, greatly simplifying the user experience and streamlining model training development.</li><li><strong><em>Centralized Unity</em></strong>: Griffin 1.0 incorporated various training backend platforms, resulting in increased maintenance overhead. Griffin 2.0 consolidates all training workloads onto a unified Kubernetes platform.</li><li><strong><em>Standard ML Runtime</em></strong>: Griffin 1.0 lacked a standardized approach for modeling frameworks and versions, leading to maintenance challenges. Griffin 2.0 introduces standard runtimes for various ML frameworks with consistent building blocks and package versions to address this concern.</li><li><strong><em>Horizontal Scalability</em></strong>: Griffin 1.0 relied on vertical scaling for accommodating increased training data and evolving model architectures. In Griffin 2.0, we adopted <a href="https://docs.ray.io/en/latest/">Ray</a> to support horizontally scalable distributed workloads<strong> </strong>without imposing excessive complexity on our MLEs.</li><li><strong><em>Metadata Store for All</em></strong>: Griffin 1.0 lacked effective model lineage information, making it challenging for users to understand and manage the complete model lifecycle. Griffin 2.0 implements a centralized metadata store to ensure thorough model lineage management throughout the lifecycle.</li></ul><h3>How It’s Built</h3><h4>System Architecture</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pL8QehR4nY4HK7ph" /><figcaption><em>Fig 1: Architecture of ML Training Platform</em></figcaption></figure><p>We’ve constructed the MLTP with the following major building blocks (Figure 1) to make it a centralized service and platform with distributed computation capabilities:</p><p><strong>Metadata Store</strong></p><p>We’ve established a series of data models to manage all aspects of the model lifecycle, including:</p><ul><li><strong><em>Model Store</em></strong>: Specifies the raw, untrained model architecture used as input for training jobs.</li><li><strong><em>Offline Feature Store</em></strong>: Contains metadata for features in our offline storage to be utilized for training.</li><li><strong><em>Workflow Run</em></strong>: It represents a specific training job request submitted to our workflow services.</li><li><strong><em>Model Registry</em></strong>: Maintains information about models generated by training jobs. This registry is used in post-training processes like evaluation, batch inference, and real-time inference.</li></ul><p><strong>API</strong> <strong>Endpoints</strong></p><p>We’ve developed an API server with accessible <strong>REST endpoints </strong>for users to interact with the Metadata Store to achieve the following:</p><ul><li>/<em>api/training/models/</em>: Create and retrieve model architecture in<strong> the Model Store</strong></li><li><em>/api/registry/models/</em>: Generate, save, and retrieve the trained model from <strong>Model Registry</strong> during post-training processes</li><li><em>/api/features/</em>: Index and retrieve offline features</li><li><em>/api/training/dataset/</em>: Generate and retrieve training dataset</li><li><em>/api/workflows</em>: Create, retrieve and terminate training jobs in <strong>Workflow Run</strong></li></ul><p><strong>Workflow Orchestrator</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*azPhq7L_CmofqmOX" /><figcaption><em>Fig 2: Workflow Orchestrator consisting of MLTP API service and ISC worker</em></figcaption></figure><p>The workflow orchestrator consists of two major components, as illustrated in Figure 2:</p><ul><li><strong><em>MLTP API service</em></strong>: The workflow APIs empower users to customize their training jobs with specifications like worker count, CPU/GPU units, memory, SSD attachment, and runtime choice, all while shielding them from the complexities of Kubernetes operations. Figure 3 shows an example of workflow creation and resource specification UI to create a Ray Cluster. When a user initiates a workflow, the MLTP API service communicates with the ISC backend worker to generate Kubernetes resources.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*x52SCLAa7JpzGsuT" /><figcaption><em>Fig 3: Workflow Service UI screenshot to specify a Ray cluster resource specification</em></figcaption></figure><ul><li><strong><em>ISC (Instacart Software Center) + Kubernetes</em></strong>: We chose Kubernetes as the orchestration platform for our training workloads. This choice allowed us to centralize the methods for launching workflows to different training backends within a single, unified platform. We collaborated closely with Instacart’s core infrastructure team who built and managed the Instacart Software Center (ISC). ISC is a suite of tools for creating, validating, and deploying software across the company. We integrated Ray and Kubernetes in ISC to enable company-wide adoption and leverage existing build &amp; deploy features. Upon receiving workflow requests from the MLTP service, the ISC worker establishes <strong>a unique Kubernetes namespace for each workflow definition</strong> to ensure resource isolation and share identical environment variables and authorization settings. Subsequently, the ISC worker generates RayCluster and RayJob Custom Resource Definitions (CRDs), initializes them, provides an endpoint for the Ray dashboard URL, monitors the status of the launched containers, and manages cluster lifespan.</li></ul><h4>Training Application</h4><p>Here’s the typical process on MLTP for creating a training job:</p><ol><li>Users begin by customizing their input, which includes tasks like organizing features and trying out different model designs. They then select a specific model from the <strong>Model Store</strong>, pick input data from the <strong>Training Dataset,</strong> and set <strong>training configurations</strong> to start a formal training job.</li><li>When they’re ready to initiate a training workload, they have the option to either access the <strong>Griffin UI</strong> or directly employ <strong>Python SDKs</strong> to send a request to the workflow services.</li><li>The workflow services create Kubernetes resources based on the user’s input. This can be a simple single-container job or a more complex multi-node Ray cluster.</li><li>After training, the results, like metrics from MLFlow and logs from Datadog, are shown visually. The model weights and other training items are then stored in the <strong>Model Registry</strong> for easy access in tasks like evaluation and inference.</li></ol><p>Our design considerations for streamlined and standardized training job creation are as follows:</p><p><strong>Unified Interface</strong></p><p>The centralized service and APIs offer a unified interface for managing the model development lifecycle:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Ck__rSxIdAU4iorr" /><figcaption><em>Fig 4: ML development lifecycle supported by a unified MLTP web interface</em></figcaption></figure><ol><li>Users can prototype by scheduling training to a Ray cluster from their laptop or Jupyter server to leverage distributed computation.</li><li>Once the model is ready for production, users can utilize the Griffin UI to create a “production” workflow definition.</li><li>Alternatively, if there’s an existing production pipeline in Airflow, they can rely on Griffin task operator and sensor operator, which integrate with Griffin workflow APIs to submit and query workflow runs.</li></ol><p>Throughout all stages of the model lifecycle, users interact with MLTP using the same API interface.</p><p><strong>Standard ML Runtimes</strong></p><p>When we surveyed training applications implemented by our users, we found the majority of code isn’t focused on model development. Those applications shared many similarities, for instance, parallel executors for feature transformations, batch inference, and distributed GPU workers for parallelizing training batches. Optimizing these components was time-consuming for MLEs, requiring them to learn various frameworks and APIs, not to mention the debugging complexity.</p><p>To simplify model development and encourage more users to adopt MLTP, we’ve developed standardized ML runtimes with structured and configurable input parameters. This solution offers predefined approaches that cover the majority of use cases for building different models at Instacart, be it decision trees or neural networks. Figure 5 shows the high-level structure of training configurations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*5obS3KVA0I_hGc5K" /><figcaption><em>Fig 5: Structure of Training Configuration Schema</em></figcaption></figure><p>Underneath, we rely on Ray APIs to implement various components of the training pipeline as shown in Figure 6. Most of these building blocks are shared across different standard runtimes for various ML frameworks. Moreover, these standard runtimes are easily scalable, allowing users to initially test in Ray local mode and then effortlessly scale the workflow in remote distributed environments.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*aYI6Zd8RqW_tEBuP" /><figcaption><em>Fig 6(a): Configurable Data Loader and Feature Transformation</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*4Be2ziIYGX-s7rKD" /><figcaption><em>Fig 6(b): Configurable Distributed Data Parallel Trainer</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*vmfpl4rEyZfH5ZjL" /><figcaption><em>Fig 6(c): Configurable Distributed Batch Inference</em></figcaption></figure><p><strong>Lineage</strong></p><p>Thanks to the centralized data storage layer, the model lineage is now much better managed. We can effortlessly trace the following lineage pairs, as illustrated in Figure 7:</p><ul><li>Model architecture — Workflow run</li><li>Training dataset — Workflow run</li><li>Workflow run — Model Registry</li><li>Workflow run — Output Metadata URLs (Datadog, MLFlow, Ray Dashboard, etc.)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GdnJmhvWgiAUyQhN" /><figcaption><em>Fig 7: Lineage of Training Lifecycle</em></figcaption></figure><p>This simplifies the training-to-post-training process for users, helps them be more productive in both experimentation and deployment and enables them to reproduce results for sharing and debugging purposes.</p><h3>Lessons Learned</h3><p>We learned a few lessons during the journey of building the next generation of ML training infrastructure:</p><ul><li><strong><em>Unified Solutions</em></strong>: To scale ourselves effectively with a growing number of ML use cases and a limited ML infra team, we opted to unify our ML training solutions. As a result, we can now offer a more consistent training job abstraction. For instance, transitioning to Kubernetes as our only orchestration platform requires a one-time migration for existing training jobs, but it enables us to provide a consistent experience between tasks and offers users additional benefits like distributed computation and enhanced metadata management.</li><li><strong><em>Balancing Flexibility and Standardization</em></strong>: We aim for our platform to be highly flexible and capable of accommodating a wide range of ML applications for model training. Simultaneously, we recognize the importance of providing standardization to cater to the majority of use cases and accelerate development velocity.</li><li><strong><em>Consider the Bigger Picture</em></strong>: In our redesign of next-gen MLTP, we didn’t just focus on training alone. We also took into account model serving and feature engineering. We collaborated closely with stakeholders from other Griffin 2.0 projects to co-design the data models of training jobs, ensuring seamless integration into the end-to-end process for easier deployment and metadata management.</li></ul><h3>Acknowledgments</h3><p>The MLTP project received support and funding from various teams such as Cloud Foundation, Build &amp; Deploy, Developers Productivity, Ads ML, Fulfillment ML and many more at Instacart. Additionally, we are immensely thankful for the guidance offered by members of our ML consulting group: Jin Zhang, Chuanwei Ruan, Aditya Subramanian, Liang Chen, Trace Levinson, and Peng Qi.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8ecb310c8d32" width="1" height="1" alt=""><hr><p><a href="https://tech.instacart.com/unveiling-the-core-of-instacarts-griffin-2-0-8ecb310c8d32">Unveiling the Core of Instacart’s Griffin 2.0:</a> was originally published in <a href="https://tech.instacart.com/">tech-at-instacart</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Distributed Machine Learning at Instacart]]></title>
            <link>https://tech.instacart.com/distributed-machine-learning-at-instacart-4b11d7569423?source=rss-b7d1ceadc933------2</link>
            <guid isPermaLink="false">https://medium.com/p/4b11d7569423</guid>
            <category><![CDATA[distributed-training]]></category>
            <category><![CDATA[distributed-computing]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[ai-infrastructure]]></category>
            <dc:creator><![CDATA[Han Li]]></dc:creator>
            <pubDate>Fri, 17 Mar 2023 18:21:00 GMT</pubDate>
            <atom:updated>2023-03-17T18:21:00.305Z</atom:updated>
            <content:encoded><![CDATA[<h4><strong>How Instacart uses distributed Machine Learning to efficiently train thousands of models in production</strong></h4><p>Author: <a href="https://medium.com/@hanli_57704">Han Li</a></p><p>At Instacart, we take pride in offering a diverse range of machine learning (ML) products that empower every aspect of our marketplace, including customers, shoppers, retailers, and brands. Along with the growth of business and ML applications, we have encountered an increasing number of use cases that require distributed ML techniques to effectively scale our ML products.</p><p>To support the emerging requests, we have designed the distributed ML system with the following key design considerations:</p><ul><li><strong>Scalability: </strong>We must be able to scale a large number of distributed ML workloads on both CPU and GPU instances with a robust system that maintains high performance and reliability.</li><li><strong>Resource Efficiency</strong>: We aim to fully utilize distributed computation resources to maximize system throughput and achieve the fastest execution at optimal cost.</li><li><strong>Diversity</strong>: The selected computation framework should be as extensible as possible to support diverse distributed ML paradigms. In addition, we should be able to handle diverse environments that are specific to different ML workloads.</li></ul><p>Our team is currently working on a variety of ML applications that utilize the power of distributed computing to efficiently solve complex problems. Some examples include:</p><ul><li><strong>Parallelizing thousands of small to mid-sized training models </strong>across distributed hosts with efficient resource utilization and reasonable queuing time.</li><li>Using <strong>data parallelism</strong> to enable deep learning models to work with large datasets more effectively.</li><li>Developing <strong>scalable batch inference</strong> capabilities with a large number of parallel jobs processing over a vast amount of data.</li></ul><p>To meet these requirements, we have chosen <a href="https://www.ray.io/">Ray</a> as the foundational computation framework for distributed ML. In this article, we will walk through the system architecture, analyze a case study, compare it with legacy systems, and demonstrate the value of Ray-based distributed ML.</p><h3>System Architecture</h3><p>We recognize that a system with a simple user experience is essential for increasing developer productivity and maximizing the impact of our distributed ML applications. Therefore, in addition to the design principles of <strong>scalability, resource efficiency</strong>, and <strong>diversity</strong>, we prioritize the following objectives to simplify the user experience:</p><ul><li><strong>Development Simplicity</strong>: We aim to simplify the development process for ML engineers by providing them with tools to test their distributed code seamlessly in a local environment and distributed environments.</li><li><strong>Maintenance Simplicity</strong>: Our objective is to offer a serverless development model that empowers our engineers to develop and run workloads without the burden of managing any services. We believe that by eliminating the need to handle service management, we can effectively improve MLE’s productivity.</li><li><strong>Seamless Integration</strong>: Our goal is to seamlessly integrate distributed ML workloads with Instacart ML Platform <a href="https://www.instacart.com/company/how-its-made/griffin-how-instacarts-ml-platform-tripled-ml-applications-in-a-year/">Griffin</a>, without creating a redundant set of MLOps tools or platforms. Rather than reinventing the wheel, we aim to enhance our existing infrastructure.</li></ul><p>We have extended our workflow orchestration tools on Griffin to provide a unified experience for running both prototyping and production workloads on Kubernetes-based distributed ML environments powered by Ray. Fig 1 illustrates the end-to-end user experience.</p><figure><img alt="Fig 1: Distributed ML Application in Development &amp; Production on Ray Cluster" src="https://cdn-images-1.medium.com/max/1024/0*D4XTbSdqCvVsFmEU" /><figcaption><em>Fig 1: Distributed ML Application in Development &amp; Production on Ray Cluster</em></figcaption></figure><p>Here are breakdowns of each component interacting with Ray distributed environment:</p><ul><li>During the development stage, users can package prototyping code snippets on their development environment and launch them on remote AWS EKS hosts through an internal launcher API that abstracts Ray Cluster access through <a href="https://docs.ray.io/en/latest/cluster/running-applications/job-submission/index.html">Ray Job API</a> (see Fig 1a).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0Xegd4fQHWs6dUPLKNb8WQ.png" /><figcaption><em>Fig 1a: Connect development environment with Ray Cluster</em></figcaption></figure><ul><li>When users are ready to automate their code in production pipelines (i.e. Airflow), they can use the same set of APIs to launch their containerized application to production Ray Clusters (see Fig 1b).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HeMju_bzl9XrCt85PJFp-Q.png" /><figcaption><em>Fig 1b: Automated containerized application running on Ray Cluster</em></figcaption></figure><ul><li>Each Ray Cluster is independently configured with Python installations and environment variables. This effectively separates the workspace environments between clusters, avoiding overhead of maintaining a monolithic python environment, which will be discussed in detail in the next section (see Fig 1c).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*E4alznmImScc5oBZ64q9dA.png" /><figcaption><em>Fig 1c: Isolated Python environments between different Ray Clusters</em></figcaption></figure><ul><li>At the application level, users need to build ML applications using Ray APIs to achieve a wide variety of distributed computation patterns, such as <a href="https://docs.ray.io/en/latest/ray-core/walkthrough.html">Ray Core APIs</a>, <a href="https://docs.ray.io/en/latest/ray-air/getting-started.html">Ray AIR</a> and <a href="https://docs.ray.io/en/latest/serve/index.html">Ray Serve</a>.</li><li>On the controller side, we use <a href="https://github.com/ray-project/kuberay">KubeRay</a> as the controller of provisioning, scaling, and deleting Ray Cluster resources on Kubernetes.</li></ul><p>Next, we will dive deep into a case study of Instacart Fulfillment ML, the very first use case of Ray-based distributed ML at Instacart, in which thousands of models need to be trained in parallel efficiently.</p><h3>Case Study: Parallel Fulfillment ML Jobs</h3><p>At Instacart, ML is applied throughout the lifecycle of fulfilling every order placed on the Instacart App (Fig 2). This includes <strong>batching</strong> multiple orders together to improve efficiency, <strong>routing</strong> to determine optimal delivery routes, <strong>ETA prediction</strong> on order arrival time, and <strong>supply/demand forecasting</strong> to prevent lost deliveries when there are not enough available shoppers, and many more. A significant number of such models are trained with data collected in a specific neighborhood, and some of those models are also sensitive to the data collected within a particular time frame, therefore it’s common practice to partition the entire national dataset based on one or multiple space/time attributes, and then launch one training job per data partition, preferably in parallel.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3EfBVSIPqWzJwQT8Qc-uTQ.png" /><figcaption><em>Fig 2: Some common scenarios of Fulfillment ML in Instacart</em></figcaption></figure><p>The most common “attribute” is the geographical location of orders, called “zones.” At Instacart, we manage thousands of unique zones to partition our national dataset. For each Fulfillment ML application, it’s typical to launch as many as <strong>thousands of parallel training jobs</strong> to cover all zones in a single model experiment.</p><h4>Previous Solutions &amp; Limitations</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*u32_Hk42Y3q271iW" /><figcaption><em>Fig 3: Our previous system of parallel zone-level model training</em></figcaption></figure><p>Our legacy solution implemented a distributed task queue service using <a href="https://docs.celeryq.dev/en/stable/">Celery</a>; Fig 3 illustrates the architectural diagram. For each unique model application (represented as <em>Model</em> in the diagram) that requires parallel training across zone 1~n, training jobs for all zones are published as tasks to the same task queue on <em>Message Broker</em>. Subsequently, a group of Celery workers subscribes to each task queue and executes the tasks inside it. The tasks are executed asynchronously, and whenever a Celery worker is free, the task at the front of the queue is removed and assigned to the free worker. Once the worker finishes, it updates the task status in the <em>Message Backend</em> and fetches the next task in the queue to execute.</p><p>As the number of ML applications requiring zone level parallel training increased over time, this type of monolithic service started to get hard to further scale due to the following reasons:</p><ul><li><strong>Inefficient resource usage: </strong>Many ML applications shared the same task queue and Celery distributed worker services. It turned out that distributed workers couldn’t get fully utilized very efficiently:<br>- Worker node had to be over-provisioned with enough resource headroom to fit all types of models. However, in Fulfillment ML, most models are quite lightweight, such as regression, classification, etc. Therefore, when a small size model was running, the worker was poorly utilized. For example, in the left-hand side graph of Fig 4, a lightweight model was running on a 16-CPU instance, with CPU utilization only around 10% to 15%.<br>- The long-running service could leave the system idle if the load was unbalanced throughout the day. For example, in the right-hand side of Fig 4, the queue was not running any tasks for over 60% of the day, leading to inefficient resource usage.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*CxaME83wuUTa0a9g" /><figcaption><em>Fig 4: Examples of low utilized service containers (left) and idle task queues (right)</em></figcaption></figure><ul><li><strong>Long queuing time</strong>: It’s very hard to achieve faster execution time without upscaling the task queue services:<br>- Low Celery worker concurrency is configured per host of task queue, because it’s not feasible to simply increase concurrency to fit all models on a monolithic service.<br>- When a task queue gets assigned with too many tasks, such as Fig 5 in which 300 to 1k+ tasks are in queue all day round, the queuing time of each task to be executed will significantly increase, slowing down the end-to-end execution time of each ML application.<br>- Therefore, the only way to speed up a busy queue is to do upscaling to add more physical hosts, which continues adding poorly utilized resources to the system.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/994/0*nZHy7TWr871LsjSO" /><figcaption><em>Fig 5: Examples of a very busy task queue hosting too many tasks</em></figcaption></figure><ul><li><strong>Difficult dependency management</strong>: It’s difficult to manage Python dependencies for all model applications running on the same queue. Upgrading a specific python package version is challenging.</li><li><strong>Maintenance burden</strong>: This system is complex to automate, and does not provide a simple approach to replicate the system in a local environment for testing purposes.</li></ul><h4>Improvements by New System</h4><p>When we started adopting Fulfillment ML workloads for our new distributed ML systems, the most significant change was the migration from long-running monolithic services to Ray-based serverless applications. Instead of all models running on the same environment, each Fulfillment ML application is launched as an independent Ray job associated with a dedicated Ray Cluster to handle all its zone level training jobs, as illustrated in Fig 6. This new design offers several advantages compared to our legacy solution:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*oL3tyRWCg9RNNxWq" /><figcaption><em>Fig 6: Architecture Overview of distributed Fulfillment ML workflows hosted on Ray Cluster</em></figcaption></figure><ul><li>With our new system, each model now has its own <strong>isolated workspace</strong> environment, enabling independent management of Python dependencies and resource usage on a per-model basis (Fig 7).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*88eFIoyBQ5CFTHQRc_nV3A.png" /><figcaption><em>Fig 7: A diagram to illustrate the idea of workspace isolation between different models</em></figcaption></figure><ul><li><strong>Long-running task queue services are now deprecated</strong>. This reduces costs on computation resources, and most importantly, it makes the infrastructure much easier to scale to host upcoming new applications.</li><li>Serverless applications offer users the ability to provision resources per Ray worker more accurately, resulting in much more <strong>efficient resource utilization</strong>. Fig 8 provides a real-world example of this improvement by comparing the before/after CPU utilization of a Fulfillment production model running 1.5k unique training tasks on the same group of hosts:<br>- In the legacy system described earlier, only a few Celery workers were configured to run on each host, resulting in CPU utilization of around <strong>10–15%</strong>.<br>- With our new Ray-based architecture, we can more accurately customize resource requirements. Through benchmarking, we found that allocating just 2 CPUs per zonal training job is sufficient. As a result, we are able to create more concurrent Ray workers on the same instance, significantly increasing CPU utilization per host to up to <strong>80%</strong>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A1vsfAsPgEFJLeOSB2gwIA.png" /><figcaption><em>Fig 8: Before(left) and after(right) CPU utilization of the same model training the same zones.</em></figcaption></figure><ul><li>Improved resource utilization contributed to <strong>faster end-to-end execution</strong>. With the same production model mentioned above running on 10 16-CPU instances, there were only 10 Celery concurrent workers in total on the legacy service while a Ray based application can launch as many as 70+ Ray workers. <strong>As a result, we are now able to greatly speed up end-to-end completion time–previously ~4 hours– to 20 minutes</strong>!</li></ul><p>We have also found that converting existing training functions into Ray distributed function calls is a relatively straightforward process. As an example, we have refactored an existing project implemented in the legacy solution to use Ray (see Fig 9). The conversion required only a few changes to existing functions or class objects to make them Ray remote executable. Additionally, we needed only a few lines of code to orchestrate the remote calls asynchronously with rate limit handling, if necessary.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*8OoA6HEVAmCUa_Yo" /><figcaption><em>Fig 9: Code example to convert an existing Forecast class object into a Ray Actor object</em></figcaption></figure><h3>Learnings &amp; Future Work</h3><p>We’ve gained valuable insights from our experience building distributed ML solutions and migrating early use cases away from legacy systems. We’ve discovered that hosting a monolithic service as the computation backend for all distributed ML applications has limitations in scalability, efficiency, and diversity, given the rapidly evolving and highly diversified nature of ML applications. For instance, by transitioning from monolithic services to standalone serverless applications for Fulfillment zone level training, we were able to significantly boost execution time, resource utilization, and development simplicity.</p><p>Although the topology of each application can be highly customized by the application owner in distributed ML, it’s essential to have unified build and launch tools on the ML platform layer. This approach enables us to support more types of distributed ML workloads in the future while ensuring our platform remains extensible.</p><p>Looking ahead, we aim to foster broader adoption of distributed ML applications across Instacart on multiple ML product lines. Our goal for 2023 is to further mature our Ray-based distributed ML solution as the unified solution running as part of Griffin. As we embark on this journey, we’re excited to see what distributed ML can help us achieve next at Instacart.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4b11d7569423" width="1" height="1" alt=""><hr><p><a href="https://tech.instacart.com/distributed-machine-learning-at-instacart-4b11d7569423">Distributed Machine Learning at Instacart</a> was originally published in <a href="https://tech.instacart.com/">tech-at-instacart</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>