6 Operation patterns
This chapter covers
- Recognizing areas of improvement in machine learning systems, such as job scheduling and metadata
- Preventing resource starvation and avoiding deadlocks using scheduling techniques, such as fair-share scheduling, priority scheduling, and gang scheduling
- Handling failures more effectively to reduce any negative effect on users via the metadata pattern
In chapter 5, we focused on machine learning workflows and the challenges of building them in practice. Workflow is an essential component in machine learning systems as it connects all components in the system. A machine learning workflow can be as easy as chaining data ingestion, model training, and model serving. It can also be very complex when handling real-world scenarios, requiring additional steps and performance optimizations to be part of the entire workflow.
Knowing the tradeoffs we may encounter when making design decisions to meet specific business and performance requirements is essential. I previously introduced a few established patterns commonly adopted in industry. Each pattern can be reused to build simple to complex machine learning workflows that are efficient and scalable. For example, we learned how to use the fan-in and fan-out patterns to build a system to execute complex machine learning workflows (section 5.2). This system can train multiple machine learning models and pick the most performant ones to provide good entity-tagging results. We also used synchronous and asynchronous patterns to make machine learning workflows more efficient and avoid delays due to the long-running model training steps that block other steps (section 5.3).
Since real-world distributed machine learning workflows can be extremely complex, as seen in chapter 5, a huge amount of operational work is involved to help maintain and manage the various components of the systems, such as improvements to system efficiency, observability, monitoring, deployment, etc. These operational work efforts usually require a lot of communication and collaboration between the DevOps and data science teams. For instance, the DevOps team may not have enough domain knowledge in machine learning algorithms used by the data science team to debug any encountered problems or optimize the underlying infrastructure to accelerate the machine learning workflows. For a data science team, the type of computational workload varies, depending on the team structure and the way team members collaborate. As a result, there’s no universal way for the DevOps team to handle the requests of different workloads from the data science team.
Fortunately, operational efforts and patterns can be used to greatly accelerate the end-to-end workflow. They can also reduce maintenance and communication efforts when engineering teams are collaborating with teams of data scientists or machine learning practitioners before the systems become production ready.
In this chapter, we’ll explore some of the challenges involved when performing operations on machine learning systems in practice and introduce a few commonly used patterns. For example, we’ll use scheduling techniques to prevent resource starvation and avoid deadlocks when many team members are working collaboratively in the same cluster with limited computational resources. We will also discuss the benefits of the metadata pattern, which can provide insights into the individual steps in machine learning workflows and help us handle failures more appropriately to reduce any negative effects on users.
6.1 What are operations in machine learning systems?
In this chapter, I will focus on operational techniques and patterns that are commonly seen in more than one component or step in a machine learning workflow, instead of patterns that are specific to each individual component. For example, the workflow shown in figure 6.1 includes three failed steps in the multiple model training steps that occur after data ingestion and in the multiple model serving steps that occur after the multiple model training steps. Unfortunately, each step is like a black box, and we don’t know many details about any of them yet. At this point, we only know whether they fail and whether the failures have affected the following steps. As a result, they are really hard to debug.

The operation patterns I introduce in this chapter can increase the visibility of the entire workflow to help us understand the root cause of the failures and give us some ideas on how to handle the failures properly. In addition, the increased observability may help us develop improvements in system efficiency that are beneficial to future executions of similar workflows.
What about MLOps?
We often hear about MLOps nowadays, which is a term derived from machine learning and operations. It usually means a collection of practices for managing machine learning lifecycles in production, including practices from machine learning and DevOps, to efficiently and reliably deploy and manage machine learning models in production.
MLOps usually require communication and collaboration between DevOps and data science teams. It focuses on improving the quality of production machine learning and embracing automation while maintaining business requirements. The scope of MLOps can be extremely large and varies depending on the context.
Given how large the scope of MLOps can be, depending on the context, I will only focus on a selected set of mature patterns at the time of writing. You can expect some updates to any future versions of this chapter as this field evolves.
6.3 Metadata pattern: Handle failures appropriately to minimize the negative effect on users
When building the most basic machine learning workflow that includes only data ingestion, model training, and model serving, where each component only appears once as an individual step in the workflow, everything seems pretty straightforward. Each step runs sequentially to reach completion. If any of these steps fail, we pick up where it’s left off. For example, imagine the model training step has failed to take the ingested data (e.g., lost the connection to the database where the ingested data is stored). We can retry the failed step and easily continue model training without rerunning the entire data ingestion process, as shown in figure 6.12.

However, when the workflow gets more complicated, any failures are not trivial to handle. For example, consider the workflow from chapter 5. This workflow trains models via three model training steps that arrive at different accuracies when tagging entities. Then, a model selection step picks the top two models with at least 90% accuracy trained from the first two model training steps, which will be used in the following two separate model serving steps. The results from the two model serving steps are then aggregated via a result aggregation step to present to users.
Now let’s consider the case where the second and the third model training steps have both failed during execution (e.g., some of the workers allocated for model training are preempted). These two model training steps would have provided both the most and the least accurate model if they had finished successfully, as shown in figure 6.13.

At this point, one might think that we should rerun both steps to proceed to the model selection and model serving steps. However, in practice, since we already wasted some time training part of the models, we may not want to start everything from scratch. It would be much longer before our users can see the aggregated results from our best models. Is there a better way to handle such kinds of failures?
6.3.1 The problem
For complicated machine learning workflows, such as the one we discussed in chapter 5, where we want to train multiple models and then select the top-performing models for model serving, the decision on which strategy to use to handle failures of certain steps due to real-world requirements is not always trivial. For example, when two out of three model training steps fail due to preempted workers, we don’t want to start training those models from scratch, which greatly increases the time needed to complete the workflow. How do we handle these failures appropriately so the negative effect on users can be minimized?
6.3.2 The solution
Whenever we encounter a failure in a machine learning workflow, we should first understand the root cause (e.g., loss of network connections, lack of computational resources, etc). Knowing the root cause is important because we need to understand the nature of the failure to predict whether retrying the failed steps would help. If the failures are due to some long-lasting shortages that could very likely lead to repetitive failures when retrying, we could better utilize the computational resources to run some other tasks. Figure 6.14 illustrates the difference in the effectiveness of retrying for permanent and temporary failures. When we retry the model training step when encountering permanent failures, the retries are ineffective and lead to repetitive failures.

For example, in our case, we should first check whether the dependencies of a model training step are met, such as whether the ingested data from the previous step is still available. If the data has been persisted to a local disk to a database, we can proceed to model training. However, if the data was located in memory and lost when the model training step failed, we cannot start model training without ingesting the data again. Figure 6.15 shows the process of restarting the data ingestion step when there’s a permanent failure during model training.

Similarly, if the model training step fails due to preempted training workers or out-of-memory problems, we need to make sure we still have sufficient computational resources allocated to rerun the model training step.
However, we won’t know what information to analyze to determine the root cause unless we intentionally record it as metadata during the runtime of each step in the entire machine learning workflow. For example, for each model training step, we can record metadata on the availability of the ingested data and whether different computational resources, such as memory and CPU usage, exceeded the limit before the step failed.
Figure 6.16 is a workflow where the model training step failed. Metadata is collected every 5 minutes on memory usage (in megabytes) and the availability of the training data (yes/no) during the runtime of this step. We can notice a sudden huge memory spike from 23 MB to 200 MB after 30 minutes. In this case, we can retry this step with an increase in requested memory, and it would then successfully produce a trained model that will be used for the next model serving step.

In practice, for complex workflows like in figure 6.13, even when we know all the dependencies of model training steps are met (e.g., we have enough computational resources and a good database connection to access the data source), we should also think about whether we want to handle the failures and how we’d like to handle them. We’ve spent a lot of time on the training steps already, but now, the steps have suddenly failed, and we’ve lost all the progress. In other words, we don’t want to start re-training all the models from scratch, which may add considerable time before we can deliver the aggregated results from our best models to users. Is there a better way to handle this without a huge effect on our user experience?
In addition to the metadata we’ve recorded for each of the model training steps, we could save more useful metadata that can be used to figure out whether it’s worth rerunning all the model training steps. For example, the model accuracy over time indicates whether the model is being trained effectively.
Model accuracy that remains steady or even decreases (from 30% to 27%, as shown in figure 6.17) may indicate that the model already converges and continuing training would no longer improve model accuracy. In this example, even though two model training steps fail, it’s not necessary to retry the third model training step from scratch since it would lead to a model that converges fast but with low accuracy. Another example of metadata that can be potentially useful is the percentage of completed model training (e.g., if we’ve iterated through all the requested number of batches and epochs, the completion is 100%).

Once we have this additional metadata about model training steps, we can tell how well each started model training step progresses. For example, for the workflow in figure 6.18, we could potentially conclude ahead of time that the third model training step was progressing very slowly (only 1% of completion every 30 minutes) due to a smaller amount of allocated computational resources or more complex model architecture. We know that it’s highly likely that, given the limited time, we end up with a model with low accuracy. As a result, we can disregard this model training step in favor of allocating more computational resources to the other model training steps with more potential, which leads to more accurate models faster.

Recording these metadata may help us derive more insights specific to each of the failed steps in the end-to-end machine learning workflow. We can then decide on a strategy to handle the failed steps appropriately to avoid wasting computational resources and minimize the effect on existing users. The metadata patterns provide great visibility into our machine learning pipelines. They can also be used to search, filter, and analyze the artifacts produced in each step in the future if we run a lot of pipelines on a regular basis. For example, we might want to know which models are performant or which datasets contribute the most to those models based on the historical training metrics.
6.3.3 Discussion
With the help of the metadata pattern, we can gain additional insights into the individual steps in machine learning workflows. Then, if any fail, we can respond based on what’s beneficial to our users and thus reduce any negative effect due to the step failures.
One common type of metadata is the various network performance (http://mng.bz/D4lR) metrics while the model is being trained (e.g., bandwidth, throughput, latency). This type of information is very useful for detecting when certain workers experience poor network performance that blocks the entire training process. We can take down slow workers and start new workers to continue training, assuming the underlying machine learning frameworks support elastic scheduling and fault-tolerance (see chapter 3). For example, in figure 6.19, based on the metadata, the worker on the right-hand side has extremely high latency (10 times the latency of the other workers), which slows down the entire model training process. Ideally, this worker would be taken down and restarted.

One additional benefit of introducing the metadata pattern to our machine learning workflows is to use the metadata recorded to establish relationships between the individual steps or across different workflows. For example, modern model management tools can use the recorded metadata to help users build the lineage of the trained models and visualize what individual steps/factors contributed to the model artifacts.
6.3.4 Exercises
If the training step failed due to the loss of training data source, what should we do?
What type of metadata can be collected if we look at individual workers or parameter servers?
6.4 Answers to exercises
Section 6.2
No, we can apply this scheduling strategy at each level of abstraction, such as processes, users, groups, etc.
No, some machine learning frameworks support elastic scheduling, which allows distributed model training jobs to start with any number of workers available without waiting for all the requested workers to be ready for communication. In this case, gang scheduling is not suitable.
Section 6.3
We should rerun data ingestion before retrying the model training step since this failure is permanent, and simply retrying would lead to repetitive failures.
Various network performance metrics while the model is being trained (e.g., bandwidth, throughput, and latency). This type of information is very useful when we want to detect when workers experience poor network performance that blocks the entire training process.
Summary
There are different areas of improvement related to operations in machine learning systems, such as job scheduling and metadata.
Various scheduling patterns, such as fair-share scheduling, priority scheduling, and gang scheduling, can be used to prevent resource starvation and avoid deadlocks.
We can collect metadata to gain insights from machine learning workflows and handle failures more appropriately to reduce any negative effects on users.









