Esc
Keyboard shortcuts
?Show this help ⌘KSearch tToggle dark/light theme nOpen notes j / kScroll down / up bBack to top /Focus search EscClose panels
All Courses
GenAI System Design
ENRUUZ
Notes
Current chapter
0 chars
Highlight color
Chapter 1

Introduction and Overview

~46 min read

This book is designed to help machine learning (ML) engineers and data scientists succeed in ML system design interviews, with a focus on generative AI (GenAI). It complements the earlier book, “ML System Design Interview” [1], which covers conventional yet fundamental topics, such as search and recommendation systems. This book, however, explores GenAI applications and the unique challenges of designing such systems. It’s also intended to serve as a guide for those who want to understand how GenAI is applied in practical scenarios.

This chapter explores two key topics. First, it provides an overview of GenAI, delving into its fundamental concepts and applications. Then, it introduces a comprehensive framework for building ML systems, which is essential for real-world applications and interview preparation. This framework will serve as the foundation for developing popular GenAI systems in the following chapters.

Let’s dive in.

GenAI overview

What are AI and ML?

AI is a branch of computer science focused on creating systems that can perform tasks that typically require human intelligence, such as reasoning, planning, and problem-solving. ML is a subset of AI that uses algorithms to learn from data rather than relying on predefined rules. These algorithms analyze data, identify patterns, and make predictions or generate new content based on the learned patterns. Applications such as recommendation systems, fraud detection, autonomous vehicles, and chatbots are generally powered by ML models.

ML models generally fall into two categories:

  • Discriminative
  • Generative
Image represents a nested Venn diagram illustrating the relationship between Artificial Intelligence (AI), Machine Learning (ML), and two types of ML models: Discriminative and Generative.  The outermost, largest oval is labeled 'Artificial Intelligence,' encompassing a slightly smaller, gray-filled oval labeled 'Machine Learning.' Within the 'Machine Learning' oval are two smaller, non-overlapping ovals: one light red labeled 'Discriminative' and one light green labeled 'Generative.'  The arrangement shows that both Discriminative and Generative models are subsets of Machine Learning, which in turn is a subset of Artificial Intelligence.  No information flows between the components; the diagram solely depicts a hierarchical classification of concepts.
Figure 1: The relationship between AI and ML
Discriminative

Discriminative models classify data by learning the differences between classes based on input features. Formally, they learn the conditional probabilities, P(Y|X), where Y represents the target variable and X represents the input features.

Discriminative models can be used for both classification, where the goal is to determine the class to which an input belongs, and regression, where the goal is to predict a continuous value. For example, in fraud detection, a discriminative model might classify transactions as either legitimate or fraudulent by analyzing features such as transaction amount and purchase history. Similarly, in movie recommendations, a model predicts a user's rating for a movie based on the user’s historical interactions.

Common algorithms for developing discriminative models include:

  • Logistic regression: A linear model that predicts the probability of a binary outcome based on input features.
  • Support vector machines (SVMs): SVMs find the hyperplanes that best separate classes in the feature space. They can be extended to learn non-linear boundaries using kernel functions [2].
  • Decision trees: These models and their variations, such as random forests, recursively split the data into subgroups based on the target variable.
  • K-nearest neighbors (KNN): A non-parametric method that classifies a sample based on the majority label among its nearest neighbors in the feature space.
  • Neural networks: These models consist of layers of interconnected neurons. They use weighted inputs, activation functions, and backpropagation to learn and approximate complex functions for tasks such as classification and regression.

While these algorithms can predict a target variable from input features, most of them lack the capability to learn the underlying data distribution needed to generate new data instances. For that, we turn to generative models.

Generative models

Generative models aim to understand and replicate the underlying distribution of data. Formally, they model the distribution P(X) when focusing solely on the input data (e.g., image generation), or the joint probability distribution P(X, Y) when considering both the input data and the target variable (e.g., text-to-image generation). This allows them to generate new data instances by sampling from these learned distributions.

Unlike discriminative models, which focus on distinguishing data instances, generative models can create new instances of data that closely resemble the original. For instance, a generative model trained on images of human faces can generate entirely new faces. These models are applied in various tasks such as text generation, image generation, and speech synthesis.

Generative algorithms can be divided into two categories: classical and modern. Classical algorithms are good at learning patterns from structured data. However, they can struggle to learn from more complex or unstructured data. Common classical generative algorithms include:

  • Naive Bayes: A probabilistic model based on Bayes' theorem [3].
  • Gaussian mixture models (GMMs): GMMs [4] represent data as a mixture of Gaussian distributions.
  • Hidden Markov models (HMMs): HMMs [5] model the joint probability of observed sequences and the hidden states generating those sequences.
  • Boltzmann machines: Energy-based models used for feature learning or dimensionality reduction [6].

On the other hand, modern generative algorithms learn from complex data distributions and are well suited for tasks such as generating realistic images and producing accurate textual outputs in response to queries. Common modern generative algorithms include:

  • Variational autoencoders (VAEs): A type of autoencoder that models the distribution of data by encoding it to a latent space and then reconstructing the original data using a decoder.
  • Generative adversarial networks (GANs): A class of neural networks in which a generator and discriminator are trained simultaneously. The generator creates realistic data, and the discriminator tries to distinguish between real and generated data.
  • Diffusion models: Models that learn complex data distributions through a reverse diffusion process. They are commonly used for image and video generation.
  • Autoregressive models: Models that generate data by predicting each element in a sequence based on the preceding elements. They are commonly used in text generation and time series forecasting.

Discriminative and generative models are used for different purposes. Discriminative models are typically used when the goal is to classify or predict; generative models are used to generate new samples. Figure 2 shows popular tasks powered by generative and discriminative models.

Image represents a hierarchical tree diagram categorizing machine learning (ML)-powered tasks.  The top-level node is 'ML-powered Tasks,' branching into two main categories: 'Discriminative' and 'Generative.'  The 'Discriminative' branch further subdivides into four tasks: 'Image Segmentation,' 'Recommendation Sys...', 'Object Detection,' and 'Sentiment Analysis,' which are arranged vertically, with 'Named Entity Recog...' positioned below them.  The 'Generative' branch similarly splits into four tasks: 'Chatbots,' 'Summarization,' 'Image Captioning,' and 'Text-to-Video,' arranged vertically, with 'Text-to-Image,' 'Face Generation,' and 'Audio Synthesis' positioned below them.  The arrangement visually depicts the relationship between the overarching ML tasks and their specific sub-categories, illustrating how discriminative and generative models are used in various applications.  Some task names are abbreviated, suggesting a potential continuation of the list.
Figure 2: Popular ML-powered tasks

What is GenAI and why is it gaining popularity?

GenAI involves using modern generative algorithms to train models capable of producing new data samples such as images, videos, text, and audio.

GenAI has gained a lot of popularity recently for two main reasons. First, these models can perform various tasks across different domains such as generating text, creating realistic images, and composing music. This multitasking capability makes them valuable across industries, from creative arts and entertainment to healthcare and software development.

Second, GenAI applications significantly enhance productivity. For instance, in content creation, these models can generate drafts, suggest improvements, or even produce final outputs, saving considerable time and resources. Another example is the use of large language models (LLMs) such as ChatGPT [7], which can assist in tasks like answering complex questions and engaging in meaningful conversations. In a recent report by McKinsey [8], GenAI is predicted to “enable labor productivity growth of 0.1 to 0.6 percent annually through 2040.”

Why GenAI is becoming so powerful?

GenAI models have recently demonstrated impressive capability and are becoming very powerful. Three key factors driving this advancement are:

  • Data
  • Model capacity
  • Compute
Data

An ML model's effectiveness depends on its training data. For example, if a model has not been trained on extensive medical data, it might struggle to diagnose diseases accurately. Improving a model for a specific task requires large datasets with labels, but collecting this data can be challenging and expensive.

One key driver behind the success of GenAI is self-supervised learning. Unlike classical models that typically work well when trained on labeled data, GenAI models can learn from unlabeled data. This approach lets them use vast datasets from the internet without the need for costly and time-consuming labeling processes.

Image represents a data architecture diagram comparing two types of data sources.  The left side, labeled 'Internet data for chatb...', shows three large, vertically oriented cylinders representing different sources of internet data: 'Books,' 'GitHub,' and 'Social Media Posts.'  An ellipsis (...) indicates that this is a representative sample, implying more data sources exist. These cylinders are visually similar, suggesting a uniform data structure or processing method. The right side, labeled 'Curated data for dis...', depicts a smaller, double-layered cylinder representing 'Medical images' on top of 'Labels.' This structure suggests a dataset where medical images are paired with corresponding labels, implying a structured and annotated dataset, unlike the less structured nature of the internet data on the left.  The dashed lines around each section visually separate the two data types, highlighting the contrast between the large, diverse internet data and the smaller, curated medical image dataset.
Figure 3: Data scale comparison between training a chatbot and disease diagnosis

Because of easy access to very large datasets from the internet, modern GenAI models can be trained on massive datasets, sometimes exceeding billions of text documents or images. For example, Meta’s Llama 3 model [9] was trained on 15 trillion tokens—roughly 50 terabytes of data; Google’s Flamingo model [10] was trained on 1.8 billion (image, text) pairs. Being trained on this massive amount of data helps these models learn complex patterns and nuances, resulting in high-quality outputs.

Model capacity

Another key factor in the effectiveness of ML models is their capacity to learn. Model capacity is measured in two ways:

  • Number of parameters
  • FLOP count
Number of parameters

Parameters are the values within a model that are learned during the training process. The number of parameters is a key indicator of a model's capacity to learn from data.

A model with more parameters generally has a greater capacity to learn the complex patterns and relationships that exist within the data. This often translates to better performance, assuming the model has been trained on a large dataset. Table 1 shows five popular models and their number of parameters.

Model NameParameters
Google’s PaLM [11]540B
OpenAI’s GPT-3 [12]175B
Google’s Flamingo [10]80B
Meta’s Llama 3 [9]405B
Google’s Imagen [13]2B

Table 1: Popular GenAI models and their number of parameters

FLOP count

FLOP (Floating Point Operations) measures the computational complexity of a model by counting the floating-point operations required to complete a forward pass. This includes basic arithmetic operations like addition, multiplication, and others that happen as data moves through the model's layers.

To better understand FLOP count, let’s walk through a simple example.

Image represents a graphical depiction of a weighted directed graph, possibly illustrating a neural network layer or a similar system.  Four circular nodes labeled `$n_1$`, `$n_2$`, `$n_3$`, and `$n_4$` represent input features or neurons.  These nodes are connected to two other circular nodes labeled `$out_...$` (with ellipses suggesting further similar nodes might exist).  Thick black lines indicate strong connections, while thinner gray lines represent weaker connections.  The connections are directed, flowing from the input nodes (`$n_i$`) to the output nodes (`$out_...$`). A dashed box to the right of the output nodes contains a formula `$out_1 = n_1\times w_{1}\{1\}...$` and subsequent lines showing similar formulas for `$n_2$`, `$n_3$`, and `$n_4$`, each suggesting a weighted sum calculation where `w` represents weights associated with the connections.  The ellipses in the formulas and the `$out_...$` labels indicate that the pattern continues beyond what's explicitly shown, implying a potentially larger network.  The overall structure suggests a weighted summation of inputs to produce outputs, characteristic of a simple neural network layer or a similar data processing model.
Figure 4: A simple fully connected layer and arithmetic calculations for a single output neuron

Consider a fully connected layer with 4 input neurons and 3 output neurons. Each output neuron is computed by multiplying the input neurons with their corresponding weight and summing them up. This results in 4 multiplications and 3 additions for each output neuron, as shown in Figure 4. Therefore, total FLOPs are 3 (4+3)=21.

While the number of parameters measures a model's size, FLOP indicates the number of arithmetic computations and provides insight into the model's computational complexity. Although a model with more parameters often has a higher FLOP count, this isn’t always the case. The architecture plays a crucial role—dense layers typically require more FLOPs than sparse connections, even if the parameter count is the same. Understanding this distinction is crucial when optimizing a model, as it requires balancing both parameters and FLOPs. Understanding these distinctions helps us design models that are both accurate and computationally efficient.

Compute

As models increase in capacity, their performance tends to improve, but training these large models requires enormous amounts of computational resources. The compute required during model training is often measured in FLOP, representing the total number of operations performed. For example, Google's PaLM-2 model was trained using 1022 FLOPs [14].

Compute power is typically provided by hardware like CPUs, GPUs (Graphics Processing Units), and TPUs (Tensor Processing Units). Nvidia, for instance, offers advanced GPUs such as the H100, A100, and A10, each with different costs and processing capabilities. The performance of these machines is often measured in FLOP/S (Floating Point Operations Per Second). For example, Nvidia's H100 can deliver up to 60 teraflops per second (60 TFLOP/S) [15].

Training advanced GenAI models is expensive, requiring thousands of GPUs over weeks-long periods. To grasp the computational demands for models such as PaLM-2, let's calculate the required number of H100 GPUs. Assuming the H100 has a peak performance of 60 TFLOP/S, it can complete approximately 5.18 EFLOPs per day. Given that PaLM-2 required 1022 FLOPs, it would take around 5.5 years for a single H100 GPU to complete the necessary computations. Therefore, the cost of training large models is extremely high, often exceeding tens of millions of dollars. For example, Sam Altman, OpenAI’s CEO, has stated that the cost of training GPT-4 was more than $100 million [16].

Training a model with billions of parameters (e.g., GPT-4, Llama 3) was not possible just a few years ago. The shift in capability has been mainly due to hardware advancements, particularly with specialized chips like GPUs and TPUs, designed for deep learning tasks. Distributed training has also been crucial, allowing the workload to be shared across hundreds, or even thousands, of machines in parallel. This significantly speeds up the process, making it feasible to train very large models on huge datasets. These infrastructure improvements and training techniques have made it possible to train GenAI models at unprecedented scales.

Scaling law

Within the constraints of a compute budget (measured in FLOPs), what is the optimal combination of model size and training data (measured by the number of tokens) that yields the lowest loss? This is the fundamental question researchers aim to answer through scaling laws.

In 2020, OpenAI researchers conducted extensive LLM training experiments, exploring various factors such as model sizes (N), dataset sizes (D), computational resources (C), model architectures, and context lengths [17]. Their findings revealed two key insights. First, the impact of scaling on model performance is significantly more pronounced than the influence of architectural variations. Second, as model size, dataset size, or computational resources are increased, there is a corresponding and predictable improvement in performance, which follows a power-law trend.

Image represents a tripartite graph showing the relationship between compute, dataset size, and model parameters on the test loss of a machine learning model.  The leftmost graph plots test loss (y-axis) against compute (x-axis, in 17-days units, non-embedding), showing numerous light-blue lines representing individual model runs and a bold orange dashed line representing a fitted power law,  `L = C<sub>min</sub>/(2.3 ⋅ 10<sup>8</sup>)<sup>-0.350</sup>`. The middle graph plots test loss against dataset size (x-axis, in tokens), showing a fitted line with the equation `L = (D/5.4 ⋅ 10<sup>13</sup>)<sup>0.005</sup>`. The rightmost graph plots test loss against the number of model parameters (x-axis, non-embedding), showing a fitted line with the equation `L = (N/8.8 ⋅ 10<sup>11</sup>)<sup>-0.005</sup>`.  All three graphs use a logarithmic scale for the x-axis and a linear scale for the y-axis, illustrating a power-law relationship between the resources (compute, data, parameters) and the resulting test loss.  The graphs suggest that increasing any of these resources leads to a decrease in test loss.
Figure 5: OpenAI’s scaling law (Credit: [17])

In 2022, DeepMind researchers extended this understanding by highlighting that many existing LLMs were undertrained, meaning the models were not large enough for the amount of data on which they were trained [18]. They found that the amount of data should scale linearly with model size to achieve optimal performance.

With the recent release of GPT o1 [19], researchers have begun to speculate about the existence of a scaling law during inference, as well [20].

GenAI risks and limitations

GenAI has evolved quickly, driving advancements across many industries by creating realistic text, images, and videos. However, it also brings critical risks and limitations that need careful consideration. Addressing these issues is key to ensuring responsible and sustainable development. Common challenges include:

  • Ethical concerns: Issues relating to bias, intellectual property (IP), misinformation, and misuse of generated content can have harmful societal impacts.
  • Environmental impact: The high computational power required to train large models contributes to substantial energy consumption and carbon emissions.
  • Model limitations: GenAI models often lack true understanding, leading to inaccuracies and limitations in complex reasoning tasks, and hallucination.
  • Security risks: There are threats posed by the use of GenAI to create deepfakes used for blackmail, political manipulation, automated phishing attacks, and adversarial exploits that manipulate model outputs in critical systems such as healthcare and finance.

Each of these areas represents a significant challenge in the development of GenAI applications. Addressing these risks requires a multidisciplinary approach involving not just technical solutions but also ethical frameworks, legal regulations, and societal awareness.

A framework for ML system design interviews

Many engineers think of ML algorithms—for instance, autoregressive Transformers or diffusion models—as the entirety of an ML system. However, building and deploying GenAI systems involves much more than just training a model. These systems are complex, with components such as data pipelines to handle and preprocess large datasets, evaluation mechanisms to assess output quality and safety, infrastructure to deliver AI-generated content at scale, and monitoring to ensure consistent performance over time.

In an ML system design interview, particularly those focused on GenAI, you’ll often face open-ended questions. For example, you might be asked to design a chatbot for customer service or an AI-powered image-editing tool for creatives. There isn’t a single "correct" answer. The interviewer is interested in how you approach complex problems, your understanding of GenAI concepts, your system design process, and the reasoning behind your design choices.

To succeed in a GenAI system design interview, it is crucial to follow a structured framework. Disorganized responses can obscure your thought process and reduce clarity. This book introduces a framework to guide you through GenAI system design challenges. The framework includes the following key steps:

  • Clarifying requirements
  • Framing the problem as an ML task
  • Data preparation
  • Model development
  • Evaluation
  • Overall ML system design
  • Deployment and monitoring
Image represents a flowchart depicting the stages of a machine learning (ML) project.  The flowchart consists of seven rectangular boxes connected by arrows indicating a sequential workflow. The first box, labeled 'Clarifying Re...', represents the initial problem clarification and requirements gathering phase. This is followed by 'Framing the...', which denotes the problem framing and definition stage.  Next, 'Data Prepara...' signifies data preparation and preprocessing.  The prepared data then flows into 'Model...', representing the model selection, training, and optimization phase. The output of the model building stage feeds into 'Evaluation', where the model's performance is assessed.  The results of the evaluation are then used to inform the 'Overall ML...' stage, encompassing the overall ML pipeline assessment and refinement. Finally, the process concludes with 'Deployment...', indicating the deployment of the finalized model into a production environment.  The text 'Text is not SVG - cannot display' appears below the 'Model...' box, indicating a potential issue with the image rendering of that specific box.
Figure 6: ML system design steps

Let's dive into each step to examine the key considerations and talking points when designing a GenAI system.

Clarifying Requirements

When you start to develop an ML system to solve a particular task, you often have minimal information to begin with. Similarly, in interviews, ML system design questions are often vague, providing minimal details. For instance, an interview might ask you to "design an image generation system." The first step is to ask clarifying questions. But what questions should you ask?

Your questions should help in understanding the problem space and the specific goals the system needs to achieve. They fall into two types:

  • Functional requirements
  • Non-functional requirements

Functional requirements

Functional requirements describe what the system should do—the core capabilities of the system. For example, “generate an image and customize its style based on the user’s prompt” is a functional requirement for a text-to-image system. In the context of designing a GenAI system, functional requirements are crucial because they shape the high-level architecture of the system. They guide the development of essential components and functionalities that the system needs to deliver to meet user needs.

Non-functional requirements

Non-functional requirements focus on how the system performs, not what it does. These include performance metrics such as latency and throughput, along with considerations for fairness, security, and scalability. In an image generation system, for example, non-functional requirements might define the acceptable speed for generating images and the quality standards they must meet. While these requirements are usually advanced topics in GenAI system design and may not significantly alter the initial architecture, it's crucial to identify and understand them early, as they will often shape the later stages of design, especially during performance tuning and system improvements.

Here are some questions to help you get started:

  • Business objective: What is the primary goal of this system? What specific purpose will it serve? For example, when designing an image captioning system, it’s essential to know if it will be used for generating detailed product descriptions on an e-commerce platform or for suggesting short captions for photos on social media.
  • System features: What features should the system support that might influence the ML design? For instance, when designing an image generation system, it’s important to know if users can provide feedback or rate the generated images, as these interactions could enhance the model. Similarly, when designing an LLM, it’s crucial to know which languages should be supported.
  • Data: What are the data sources? How large is the dataset? Is the data labeled? These questions are crucial because the quality and quantity of the data might influence the design.
  • Constraints: What are the available computational resources? Will the system be cloud-based or designed to run on local devices?
  • System scale: How many users are expected to use the system? How many images need to be generated, and what is the expected growth in demand? These questions are important to clarify because a system designed to generate images for a small group of users will not require the same level of scalability as one expected to serve millions of users.
  • Performance: How quickly should the content be generated? Is real-time generation required? Is there a higher priority on content quality or generation speed?

This list isn't comprehensive, but it provides a good starting point. Other topics, such as privacy, ethics, and data security, can also be important.

By the end of this step, you should be aligned with the interviewer on the system's scope and requirements. It's generally a good idea to clarify these details to ensure you're addressing the interviewer's expectations.

Framing the problem as an ML task

If an interviewer asks you to design a feature that automatically summarizes emails for users, you have a problem to solve. But you can't simply ask AI to summarize emails. Instead, you need to frame the problem so that AI techniques can address it. Framing a problem as an ML task is a key step in designing ML systems, as doing this shapes the rest of your design.

When tackling a problem, you first need to determine whether machine learning is even necessary. However, with GenAI systems, you can typically assume ML will be required since it's the main tool for developing these systems.

The following two steps are useful for framing your problem as an ML task:

  • Specify the system’s input and output
  • Choose a suitable ML approach

Specify the system’s input and output

To frame the problem, you first define the system's input and output. This involves identifying the input data modality (text, image, audio, video) and the expected output. For instance, in a chatbot system, the input is the user's text query, and the output is the system's response.

Image represents a simplified system diagram illustrating a user interaction with a chatbot.  The diagram shows a left-to-right flow.  On the left, the user input 'where bill gat...' is depicted, indicating a partial query likely seeking information about Bill Gates' birthplace.  A solid arrow points from this input to a rectangular box representing the 'Chatbot,' which is colored light orange with a golden-yellow border.  This box signifies the core processing unit of the system.  Another solid arrow extends from the 'Chatbot' box to the right, leading to the output 'Bill Gates was born in Seat...', which is an incomplete response, suggesting the chatbot's answer is still being generated or truncated in the visualization.  The text 'Text is not SVG - cannot display' is present below the Chatbot box, indicating a technical limitation in rendering the image.
Figure 7: Input and output of a chatbot

Choose a suitable ML approach

After defining the input and output of the system, the next step is to choose the most suitable ML approach. This involves identifying key components of your system and selecting an algorithm that aligns with the specific needs of the problem. As illustrated in Figure 8, there are numerous ML algorithms to choose from, each with its own strengths and weaknesses. It is crucial to compare them, discuss the trade-offs, and choose the one that is most suitable for your task.

Image represents a hierarchical tree diagram categorizing machine learning (ML) algorithms.  The top-level node is 'ML Algorithms,' branching into two main categories: 'Discriminative' (in orange) and 'Generative' (in light green).  The 'Discriminative' category further divides into 'Classification' and 'Regression,' each with subcategories.  'Classification' includes 'Logistic...', 'Decision...', 'Neural Network...', 'SVM,' and 'k-Nearest...', while 'Regression' contains 'Linear...', 'Decision...', 'k-Nearest...', and 'Neural Network...'. The 'Generative' category branches into four data modalities: 'Text...', 'Image...', 'Audio...', and 'Video...'.  Each modality then shows various generative models. 'Text...' includes 'RNNs...' and 'Transformers'. 'Image...' uses 'VAE,' 'GANs,' and 'Diffusion Mod...'. 'Audio...' employs 'VAE' and 'Autoregressive...', and 'Video...' utilizes 'Diffusion Mode...' and 'Autoregressive...'.  Additionally, there are further subcategories under 'Diffusion Mod...' and 'Autoregressive...' for both image and video, including 'Autoregressive...' and 'Flow-based...' under 'Diffusion Mod...'.  The dashed lines around some groups suggest a possible grouping of related algorithms within each category.  The ellipses (...) indicate further potential subcategories or algorithms not explicitly listed.
Figure 8: Common ML algorithms

There are different ways to select an appropriate ML algorithm, and the criteria for selection vary from application to application. The following steps can help you narrow down your options when choosing the most suitable algorithm:

  • Discriminative vs. generative: First, determine whether the problem requires a discriminative or generative model. This can be easily determined based on the system's output. For example, in an object detection problem, where the output is the class of the input image, the task is discriminative. In contrast, designing a chatbot that produces text as output is a generative task. Figure 9: Step one for choosing a suitable ML approach
  • Identify the task type: Next, identify the specific task type to further narrow the choice of algorithms. The two most common tasks for discriminative models are classification and regression. Generative models commonly undertake tasks such as text, image, audio, and video generation. The system’s output can help identify the task type. For instance, an image captioning system generates text, making it a text generation task; a face generation system produces images, making it an image generation task; an object detection system that outputs an object class is a classification task. Figure 10: Step two for choosing a suitable ML approach
  • Choose a suitable algorithm: Finally, select an algorithm that is most suitable based on the requirements. Consider factors such as the ability to handle different input modalities, efficiency, and quality expectations. For example, in a text-to-image system, the algorithm must process text as input and generate an image as output; therefore, VAEs or GANs might not be ideal despite their abilities to generate images. This step is the ideal time to evaluate the various options and discuss their trade-offs. This step is the ideal time to evaluate various options and discuss their trade-offs.

In the upcoming chapters, we will examine various ML approaches used in popular GenAI applications.

Talking points

  • What are the system's inputs and outputs based on the requirements?
  • Which data modalities (text, image, audio, video) does the model need to understand and process? How will the model handle different modalities?
  • Should a single model handle all input modalities, or is it more effective to use multiple models for different modalities? What are the benefits and drawbacks of using a unified model versus specialized models for each modality?
  • Which generative algorithm (e.g., diffusion models, VAEs, GANs) is best suited for the task at hand, and why? What are the specific trade-offs between different algorithms in terms of quality, efficiency, and ease of use?
  • What are the performance, stability, and resource implications of choosing one algorithm over another?
  • Is the chosen approach scalable and flexible enough to accommodate future changes or additions to the system's capabilities? How easily can the system adapt if new input modalities or outputs are introduced later?

Data Preparation

ML models learn directly from data; therefore, high-quality data is crucial for effective training. This section explains different data types and key considerations when preparing them for ML models.

Data types

In ML, data is generally categorized into two types: structured and unstructured.

Image represents a hierarchical classification of data.  At the top, a single box labeled 'Data' serves as the root node.  This node branches into two main categories: 'Structured' and 'Unstructured.' The 'Structured' category further subdivides into three types: 'Categorical,' 'Numerical,' and 'Ordinal.'  The 'Numerical' category then branches down into two more specific types: 'Discrete' and 'Continuous.' The 'Unstructured' category branches into four types: 'Video,' 'Image,' 'Text,' and 'Audio.'  Arrows indicate the hierarchical relationships, showing how each data type is a subset of the node above it.  The entire diagram visually depicts the different forms data can take, ranging from the most general 'Data' category to the most specific types like 'Discrete' numerical data or 'Audio' unstructured data.
Figure 11: Data categories

Structured data: This type of data can be organized into tables with rows and columns, for example, a database or spreadsheet. Financial records and customer data are examples of structured data. Structured data can be further divided into the following categories:

  • Categorical data: Data that represent distinct groups or categories (e.g., gender or color).
  • Numerical data: Data that represent measurable quantities (e.g., number of items sold, house price).
  • Ordinal data: Data with a predetermined order (e.g., satisfaction ratings).

Unstructured data: Unstructured data refers to data with no underlying data schema or structure, such as text, images, videos, audio files, or a combination of them. For example, social media posts or emails are examples of unstructured data.

Traditional ML models are typically trained on structured data. In contrast, models that power GenAI applications primarily deal with unstructured data like images, text, and videos. As a result, the focus of data preparation differs significantly between traditional models handling structured data and generative models working with unstructured data. Let’s explore each in more detail.

Data preparation in traditional ML

Preparing structured data for traditional models typically involves two key steps: data engineering and feature engineering.

Image represents a data processing pipeline.  On the left, three vertically stacked cylinders labeled 'Data sources' depict multiple input data sources.  A single arrow points right, indicating data flow from these sources into a dashed-line box. Inside this box are two adjacent rectangular blocks. The first block, labeled 'Data...', represents a data ingestion or pre-processing stage. An arrow connects this block to the second block, labeled 'Feature Engineeri...', signifying the flow of data into a feature engineering stage.  Finally, an arrow extends from the 'Feature Engineeri...' block to a single cylinder on the right, labeled 'Prepared features,' representing the output of the pipeline—a database of prepared features ready for further processing or model training.  The dashed-line box encompasses the 'Data...' and 'Feature Engineeri...' blocks, suggesting these stages are part of a unified processing unit.
Figure 12: Data preparation process for structured data
Data Engineering

Data engineering involves building and maintaining systems for collecting, storing, retrieving, and processing data. A core component of this is ETL (Extract, Transform, Load) [21], which refers to the process of extracting data from various sources, transforming it into a usable format, and loading it into a data warehouse or other storage system. Data engineering ensures that data is clean, reliable, and accessible.

Feature Engineering

Feature engineering involves selecting and extracting predictive features from raw data and transforming them into a format usable by ML models. This process often utilizes feature stores, such as Tecton [22] or Amazon SageMaker [23], which offer a centralized platform for managing and serving features at scale.

Selecting the right features is crucial when developing and training ML models. It’s important to choose features that provide the most information. The feature engineering process requires subject matter expertise and is highly task-specific. It includes techniques such as handling missing values, representing categorical features, and bucketing.

Since this book focuses on GenAI, we concentrate primarily on data preparation specific to GenAI models. For a deeper dive into data engineering and feature engineering techniques, refer to [24].

Data preparation in GenAI

When preparing unstructured data for generative models, the focus shifts from feature engineering to collecting vast amounts of data; ensuring the data is of high quality and safe; and utilizing tools to store and retrieve the data efficiently and at scale.

Image represents a data processing pipeline. On the left, a group of icons labeled 'Various...' depicts diverse data sources: a globe (representing web data), an email, documents, a mobile phone, a laptop, a book, and social media icons (representing data from various social media platforms) and a database icon.  A solid arrow points from these icons to a rectangular box labeled 'Data...', indicating data ingestion from these sources. This box then connects via a solid arrow to a cluster of four vertically stacked cylindrical database icons labeled 'Collected...', representing the initial storage of the raw data.  Another solid arrow leads from the 'Collected...' databases to a second rectangular box labeled 'Data...', suggesting a data processing or transformation step. Finally, a solid arrow connects this second box to a pair of cylindrical database icons labeled 'Clean data,' representing the final storage of the processed and cleaned data.  Dashed lines enclose the 'Data...' boxes and the 'Collected...' databases, visually grouping these components as a processing unit.
Figure 13: Data preparation process in GenAI

Let’s examine the following key steps in data preparation:

  • Data collection
  • Data cleaning
  • Data efficiency
Data collection

Advanced GenAI models have billions of parameters that enable them to learn and generalize from data. Due to their size, these models require vast amount of training data to capture complex patterns. For instance, Llama 3 was trained on 15 trillion tokens from various internet sources—equivalent to 50 terabytes of data. To put this into perspective, a person reading nonstop at the typical rate of 250 words per minute would take around 85,000 years to read that amount of text. The data collection process gathers large datasets by scraping text from different sources (e.g., websites, social media, and forums).

As models grow larger, there's a trend toward enhancing training datasets with AI-generated content. This involves using existing models to create synthetic data, which is then used to train another GenAI model.

Image represents a data processing pipeline for generating synthetic data.  On the left, a gray box labeled 'Real data' contains icons representing various data sources: a globe (website), an email, documents, a mobile phone, a laptop, a notebook, and social media icons (Instagram, Facebook, Twitter).  A database icon is also included within this box. An arrow points from this box to a rectangular processing block labeled 'Data...', indicating the input of real data. This block is enclosed in a dashed box, suggesting a processing stage.  The output of this block flows to another 'Data...' block, also within the dashed box, implying further processing.  From this second block, an arrow leads to a pair of database cylinders labeled 'Clean data,' representing the cleaned and processed real data.  Separately, a cloud-shaped box labeled 'GenAl...' (presumably a generative AI model) sends data to a cluster of database cylinders labeled 'Synthetic data,' indicating the generation of synthetic data from the model.  Finally, a vertical line connects the 'Real data' box to the 'Synthetic data' box, suggesting that the real data might also be used to train or influence the GenAI model in generating synthetic data.  The top of the diagram shows a cluster of database cylinders labeled 'Collected...', representing the initial collection of raw data.
Figure 14: Augmenting training data with AI-generated data

Training GenAI models with AI-generated content has several pros and cons.

Pros:
  • Improving data diversity: AI-generated content adds variety to existing data, thus enhancing the model's ability to generalize, especially when the original data is limited or imbalanced.
  • Scalability: As demand for data grows, AI-generated content provides a scalable way to create large datasets that are difficult to gather manually.
Cons:
  • Quality concerns: The quality of synthetic data depends on the original model. Poor-quality data can lead to the spread of biases or errors.
  • Representation issues: The synthetic data might not represent the original data well. Ensuring the synthetic data is diverse and representative can be challenging.
  • Real-world distribution gaps: AI-generated data may not fully capture the complexity of real-world scenarios, thereby risking the omission of important details.

Using AI-generated data to train GenAI models is a rapidly evolving area of research. New techniques are constantly being developed to improve the quality and relevance of synthetic data. For more information, refer to [25].

Data cleaning

Very large datasets from the internet are often noisy, and they may contain low-quality or inappropriate content. We must clean the data carefully to avoid introducing biases, misinformation, or harmful material into the model, which can affect its performance. In addition, it is crucial to have data that is representative. This requires removing duplicate content and ensuring it is diverse and balanced.

Image represents a data cleaning pipeline depicted as a flowchart.  A dashed-line rectangle encloses four vertically stacked, equally sized boxes representing sequential stages of data processing: 'Harm Detection...', 'Low-Quality...', 'Deduplication', and 'NSFW...'.  These boxes imply filters or checks for harmful content, low-quality data, duplicate entries, and Not Safe For Work (NSFW) material, respectively.  Below this rectangle, a separate box labeled 'Data Cleaning' is shown.  Dashed lines connect the top rectangle to the 'Data Cleaning' box, indicating that the output from each of the four filtering stages feeds into the data cleaning process.  The ellipses (...) after each label in the top rectangle suggest that the names are truncated and represent broader categories of checks. The overall structure illustrates a multi-stage data preprocessing pipeline where data is sequentially filtered and cleaned before further processing.
Figure 15: Common data cleaning steps

Throughout this book, we will explore key data-cleaning techniques including filtering harmful content, detecting NSFW (Not Safe For Work), assigning quality scores, and removing duplicates.

Data efficiency

Managing large datasets requires efficient tools and techniques for storage and retrieval. Let's look at each in detail.

Efficient storage

Storing massive amounts of data with traditional tools can be expensive and slow. Distributed storage systems such as Hadoop Distributed File System (HDFS) [26] and Amazon S3 [27] are built to store massive amounts of data across multiple machines. These systems are particularly suited for managing large volumes of unstructured data. In addition, columnar storage formats such as Parquet [28] and ORC [29] are ideal for structured data or unstructured data that has been converted to structured form. These formats, optimized for analytics, offer better compression and faster query performance.

Efficient retrieval

Training an ML model requires fast data retrieval. Common techniques to retrieve data efficiently from large datasets include:

  • Sharding: Splitting data across multiple devices allows parallel access and speeds up retrieval and processing.
  • Indexing: Technologies such as Apache Lucene [30] or Elasticsearch [31] are used to index data, making it easy and quick to locate specific pieces of information.
  • Pre-loading or caching: Frequently accessed data is pre-loaded into memory to reduce I/O delays during retrieval.

Talking points

  • Data sources: What data is available, and where do you collect it from? How diverse are they? How large is the dataset?
  • Data sensitivity: How sensitive is the data (e.g., personal, financial, medical)? Is anonymization necessary to protect sensitive information?
  • Bias: Are there inherent biases in the data (e.g., demographic, geographical)? How do you detect and mitigate these biases to ensure fair representation?
  • Data quality: How do you filter low-quality, irrelevant, or noisy data? Are there any outliers or anomalies in the dataset? How do you handle them?
  • Inappropriate data: Are there inappropriate, harmful, or NSFW content in the dataset? What processes are in place to detect and remove such data?
  • Data preprocessing: How is the data represented in a format the model can understand? If using text data, how is it tokenized and transformed into numerical format (e.g., embeddings)? If dealing with multimodal data (e.g., images, text, audio), how do you preprocess them for the model to consume?

Model development

Model development is a critical step in building ML systems. It involves selecting the appropriate architecture, training the model, and finally, generating new data from the trained model. Let’s dive into each of these components in more detail.

Model architecture

In this step, you should talk about the architecture of the model in detail. There might be several viable architectures for different ML algorithms. For instance, diffusion models can be built using either the U-Net or DiT architectures. In an interview, it’s important to explore different architectural options and weigh their advantages and disadvantages.

Once an architecture is selected, it’s helpful to analyze its specific layers and examine how the input is transformed into the output. For example, in a U-Net architecture, the output should be the same size as the input image; therefore, reviewing the layers to ensure they meet this requirement is beneficial.

Image represents a U-Net architecture for image processing.  The diagram shows an input 'Image' represented as a 64x64 tensor, which is fed into a series of processing blocks.  The first set of blocks, labeled 'Downsampling block...', consists of multiple repeating units, each containing a Conv2D layer, Batch Normalization, ReLU activation, MaxPooling, and Cross-Attention layers (indicated by '...'). These blocks progressively reduce the spatial dimensions of the input.  The output of the downsampling blocks is then passed through a central 'U-Net' section.  Following the U-Net, an 'Upsampling block...' section mirrors the downsampling process but uses transposed convolutions (Transposed..) instead of MaxPooling to increase the spatial dimensions.  Each upsampling unit also includes Batch Normalization, ReLU activation, and Cross-Attention layers.  The final output is a 'Predicted...' 64x64 tensor.  The 'D' blocks represent the downsampling path, and the 'U' blocks represent the upsampling path.  The connections between blocks are unidirectional, indicating the flow of information from input to output.
Figure 16: U-Net architecture

You might be asked follow-up questions and have to modify the architecture to support a new feature. For example, in an image generation model, you might need to modify the architecture to let users control the style of generated images. Similarly, in a text-to-video model, you might be asked to control the direction of motion (e.g., left to right) during generation. These features could require adding or modifying components in the architecture to integrate style vectors or motion information.

Let’s dive into a real example—the Transformer’s self-attention—to show what it means to discuss architecture in an interview.

Transformer’s self-attention architecture

Transformers are a cornerstone of modern GenAI, especially in natural language processing and image generation. Since their introduction in 2017 [32], they have rapidly taken over the AI community, becoming the dominant architecture for a wide range of tasks across natural language processing (NLP) [33] [12], computer vision [34], and even multimodal learning [35] [36].

At the core of Transformers is the attention mechanism. Initially introduced in the context of machine translation [37], the attention mechanism has become a fundamental component of various neural network architectures, particularly in the Transformer model. It addresses the limitations of traditional sequence models such as RNNs and LSTMs by enabling the model to more effectively capture long-range dependencies and contextual information.

Self-attention, also known as scaled dot-product attention, is the most common form of the attention mechanism used in modern models. It enables each element in the input sequence to focus on every other element. This is done by converting the input embeddings for each token into three vectors: the query (QQQ), key (KKK), and value (VVV) vectors. These vectors are computed using learnable weight matrices WQW_QWQ​, WKW_KWK​, and WVW_VWV​:

where XXX represents the input sequence of embeddings.

The attention scores are computed by taking the dot product of the query vector, QQQ, with all the key vectors, KKK, followed by a scaling operation and a softmax function. This can be represented as:

Here, dKd_KdK​ is the dimension of the key vectors, and the scaling factor 1dK\frac{1}{\sqrt{d_K}}dK​​1​ is used to prevent the dot-product values from becoming too large, which could result in extremely small gradients during backpropagation. The softmax function is applied to ensure that the attention scores are normalized, summing to 1. This produces a weighted sum of the value vectors, VVV, where the weights are determined by the relevance of each input token as indicated by the attention scores.

Image represents a simplified diagram of the core computation within a self-attention mechanism, a crucial component of many transformer-based models.  The diagram shows a vertical stack of processing blocks. At the bottom, 'Q', 'K', and 'V' represent the query, key, and value matrices, respectively, which are inputs to the system.  These feed into a 'MatMul' (matrix multiplication) block, whose output then flows upwards to a 'Scale' block. The output of 'Scale' is passed to a 'Mask (opt.)' block, which applies a masking operation (optional, as indicated by '(opt.)').  This masked output is then fed into a 'SoftMax' block, which normalizes the values. Finally, the output of 'SoftMax' is input to another 'MatMul' block, resulting in the final output.  A direct connection from the initial 'V' input bypasses the lower 'MatMul' and feeds directly into the upper 'MatMul', indicating a direct contribution of the value matrix to the final output.  The arrows indicate the direction of data flow between the blocks.
Figure 17: Scaled dot-product attention (Credit: [32])
Multi-Head Attention

To capture different types of relationships and contextual dependencies, the self-attention mechanism is often extended to multi-head attention. Instead of computing a single set of QQQ, KKK, and VVV vectors, the input is projected into multiple sets, or “heads,” each with its own learnable weight matrices:

where each attention head is computed independently as:

The results of the different heads are concatenated and then linearly transformed using the output weight matrix, WO. This allows the model to jointly attend to information from different representation subspaces and capture richer dependencies.

Image represents a simplified diagram of the Scaled Dot-Product Attention mechanism, a core component of Transformer networks.  The diagram shows three input vectors, labeled 'V', 'K', and 'Q' (likely representing Value, Key, and Query), each feeding into a separate 'Linear' transformation layer.  The outputs of these linear layers are then fed into a central 'Scaled Dot-Product Attention' block, depicted as a larger, shaded rectangle.  This block computes the attention weights based on the interactions between Q, K, and V. The output of the attention block is then passed through a 'Concat' operation (represented by a yellow rectangle), which combines the results. Finally, this concatenated output is fed into another 'Linear' layer, producing the final output, indicated by an upward-pointing arrow.  The 'h' label next to the output of the attention block suggests this represents the attention-weighted output vector.  The multiple stacked 'Scaled Dot-Product Attention' blocks imply that this process might be repeated multiple times (multi-head attention).  The arrows indicate the flow of data between the components, showing the sequential and parallel processing steps within the attention mechanism.
Figure 18: Multi-head attention (Credit: [32])

There is no one-size-fits-all architecture for every problem. Interviewers want to assess your understanding of different ML architectures, their strengths and weaknesses, and your ability to choose the right one based on specific requirements and constraints. In this book, we introduce various Transformer-based models through GenAI applications and explain their necessity.

Model training

Model training is the process of adjusting the model’s parameters (weights) to produce the desired output. Key aspects to discuss during model training include:

  • Training methodology
  • Training data
  • ML objective and loss function
  • Task-specific challenges and mitigations

Let’s examine each in more detail.

Training methodology

Each model follows a distinct training process suited to its architecture and purpose. For example, diffusion models gradually denoise data to generate high-quality samples from noise. In contrast, GANs rely on adversarial training, where a generator and a discriminator compete to improve over time.

Many models also undergo multi-stage training for better performance. LLMs, for instance, typically follow three stages: pretraining on large datasets to learn general patterns; supervised finetuning to adapt to the specific task; and an alignment stage to ensure outputs align with human values or intended behaviors. This approach helps models perform well across various applications.

Having an in-depth understanding of these training methodologies for different GenAI applications is crucial, especially when discussing them in an interview.

Training data

Understanding the training data is essential for successful model development. The data used can vary across different GenAI applications and may also differ in multi-stage training approaches. For instance, when training an LLM, publicly available datasets such as Common Crawl [38] might be used during the pretraining stage, while expert-annotated, carefully curated data would be used for the alignment stage.

It's important to discuss the datasets, including how they are sourced, why they are valuable for model training, and an estimate of their size for effective training.

ML objective and loss function

ML objective is the goal of the ML task during training. For example, in an LLM, it might be to accurately predict the next token (e.g., next-token prediction). In contrast, in VAE, the ML objective is to reconstruct the original image.

Image represents a generative model training pipeline.  The diagram shows three cylindrical database icons labeled 'Training data' on the left, representing the input dataset.  A solid arrow points right from the training data to a rectangular box labeled 'Model,' indicating the flow of data into the model for training.  The model processes the training data and generates output data, represented by three more cylindrical database icons labeled 'Generated data' on the right. A solid arrow connects the 'Model' box to the 'Generated data,' showing the output flow.  A dashed line connects the top of the 'Generated data' and 'Training data' icons, looping back to the top of the 'Training data' icons, labeled 'loss,' illustrating the feedback loop used to adjust the model's parameters based on the difference between the generated data and the desired output (implicitly defined within the training data).  The overall flow depicts a cyclical process of training a generative model using a dataset, generating new data, measuring the loss, and iteratively improving the model's performance.
Figure 19: Loss computation between training data and generated data

The loss function measures how closely the model’s predictions align with the desired outcomes. It guides the optimization process, where the goal is to minimize this loss. Choosing the right loss function is crucial during model training, as it quantifies prediction errors and helps the optimization algorithm adjust the model’s parameters to improve performance.

Designing a new loss function can be complex. In most cases, you’ll select one from existing options based on how you've framed the problem. Sometimes, minor adjustments to the loss function are required to tailor it to the specific task. We will explore several loss functions in later chapters.

Task-specific challenges and mitigations

Different tasks come with their own challenges that need specific solutions. For example, training large video generation models is very resource-heavy because it requires a lot of computing power and large amounts of data. This means it might not be feasible to train a video generation model without proper optimization techniques. This might include parallelization techniques [39][40][41], mixed precision training [42], and latent diffusion models [43]. These approaches help scale video generation models while keeping resource use and costs manageable. While we will cover task-specific challenges and mitigations in future chapters, we’ll now briefly examine efficiency and optimization techniques that apply to all large-scale model training.

Three of the most common techniques for training large-scale models are:

  • Gradient checkpointing
  • Mixed precision training
  • Distributed training
Gradient checkpointing

Gradient checkpointing [44] is a technique to reduce memory usage during model training by saving only a selected subset of activations. During the backward pass, the missing activations are recomputed. This reduces memory usage significantly, which is particularly useful for training large models with limited GPU memory.

Mixed precision training

Mixed precision training is a technique that uses both 16-bit (half-precision) and 32-bit (single-precision) floating point numbers to speed up model training and reduce memory usage. It maintains the accuracy of training while improving efficiency by performing most calculations at lower precision; crucial operations are performed at higher precision when needed.

Automatic mixed precision (AMP) [45] is a specific implementation of mixed precision training provided by frameworks such as PyTorch and TensorFlow. AMP automatically handles the transition between half and single precision, optimizing where to use each precision type and applying scaling techniques to maintain numerical stability during training.

Distributed training

As models grow in size and complexity, training on a single machine becomes infeasible. Distributed training techniques enable efficient training of large models by utilizing multiple machines or devices in parallel.

Image represents a hierarchical tree diagram illustrating different types of parallelism in a system.  The top-level node is 'Parallelism,' branching into three main categories: 'Data,' 'Model,' and 'Hybrid.'  The 'Data' parallelism is a leaf node, representing a single type of parallelism. The 'Model' parallelism further branches into two sub-categories: 'Tensor' and 'Pipeline.'  'Tensor' parallelism then splits into two lower-level types: 'Column-wise' and 'Row-wise.'  The 'Pipeline' parallelism is a leaf node. Finally, 'Hybrid' parallelism is also a leaf node, representing a distinct type of parallelism.  The arrows indicate the hierarchical relationship and the flow of information, showing how each type of parallelism is a sub-type or a variation of the higher-level categories.
Figure 20: Parallelism techniques for distributed training

Common parallelism techniques are:

  • Data parallelism
  • Model parallelism
  • Hybrid parallelism
Data parallelism

In data parallelism, the dataset is split across multiple devices (e.g., GPU), each of which holds a full copy of the model and processes a portion of the data in parallel. Each device trains on its subset of data, and the parameter server coordinates the updating and distributing of model parameters across all devices. This approach is helpful when the dataset is large, as processing the data in parallel is efficient and speeds up training.

Image represents a distributed training system for a machine learning model.  The system features a central 'Parameter Server' at the top, which communicates bidirectionally with multiple instances of 'Model A,' each residing on a separate GPU (GPU 0, GPU 1, ..., GPU N).  Each Model A instance is depicted as a cloud symbol within a box labeled with its corresponding GPU number.  Below each GPU, a database-like cylinder represents local data storage for that GPU.  All the GPUs draw data from a shared 'Dataset' represented by a cluster of cylinders at the bottom.  Arrows indicate the flow of information: the Parameter Server sends model parameters to each Model A instance, receives updated parameters back, and the GPUs receive data from the shared Dataset.  The ellipses ('...') indicate that the depicted structure repeats for an unspecified number of GPUs.
Figure 21: Data parallelism

There are two primary methods for updating model parameters across the devices:

  • Synchronous: In this approach, all devices complete their computations and send gradients to the parameter server. The parameter server waits until it has received gradients from every device, and then it aggregates and updates the model before sending the updated parameters back to all devices. This ensures consistency, as the devices always work with the same version of the model. However, it can be slower because updating has to wait for the slowest device.
  • Asynchronous: With asynchronous updating, each device sends its gradients to the parameter server as soon as it finishes processing its portion of data, and the parameter server updates the model immediately upon receiving gradients from any device and sends the new parameters to all devices. This approach can be faster since the devices are working independently, but it can lead to inconsistency as devices might be working with slightly different versions of the model at any given time.

To learn more about data parallelism, refer to [39].

Model parallelism

In model parallelism, a single model is split across multiple devices, and each device is responsible for computing only a portion of the model's operations. This approach is helpful when the model is too large to fit into the memory of a single device.

Model parallelism can be further divided into types:

  • Pipeline parallelism (inter-layer)
  • Tensor parallelism (intra-layer)

Pipeline parallelism (PP): In PP, the model layers are split across multiple devices, and computations are performed in a pipelined manner. In the forward pass, each device forwards the intermediate activation to the next device in the pipeline, while in the backward pass, it sends the input tensor's gradient back to the preceding device.

Image represents a model parallel training setup across three GPUs (GPU 0, GPU 1, and GPU 2).  Each GPU is depicted as a box containing multiple vertical rectangles labeled 'Layer...', representing different layers of a neural network model.  The GPUs are interconnected; data flows between them in both 'forward' and 'backward' directions.  The 'forward' pass involves data moving from GPU 0 to GPU 1, then to GPU 2, representing the sequential processing of layers during inference or training.  The 'backward' pass shows the flow of gradients during backpropagation, moving from GPU 2 to GPU 1 and then to GPU 0.  At the bottom, a larger box labeled 'Model' contains several 'Layer...' rectangles, indicating the complete model is distributed across the GPUs.  Arrows connect the 'Model' box to each GPU, suggesting that each GPU processes a subset of the model's layers.  The ellipses (...) indicate that the number of layers on each GPU and in the model itself can extend beyond what's explicitly shown.
Figure 22: Splitting model layers across devices

PP is particularly useful when dealing with very deep models, as it allows multiple devices to work concurrently, reducing idle time and improving training efficiency. To learn more about PP, refer to [40] [41].

Tensor parallelism (TP): In TP, operations within a single layer of the model are split across multiple devices. Each device handles a portion of the computations for that layer, and the outputs are combined before moving to the next layer. For example, in a large matrix multiplication operation, different parts of the matrix can be processed in parallel across multiple devices. This can be done using both column-wise and row-wise splitting. For more information, refer to [46].

Image represents a comparison of two approaches to matrix multiplication within a neural network layer, specifically illustrating the concept of tensor parallelism.  The left side depicts 'No tensor parallelism,' showing a single computation where a matrix 'A' is multiplied by a weight matrix 'W' to produce a resulting matrix 'B'.  This is represented by three boxes labeled 'A', 'W' (in orange), and 'B', connected by 'x' and '=' symbols indicating multiplication and equality.  This entire operation is enclosed in a dashed line. Below, a simplified representation shows the input tensor 'A' flowing into a 'Layer...' box (representing the neural network layer) and producing an output tensor 'B'. The right side shows 'Tensor parallelism,' where the weight matrix 'W' is split into two parts, 'W1' and 'W2' (both orange), each processed by a separate GPU (GPU 0 and GPU 1 respectively).  On each GPU, matrix 'A' is multiplied by its assigned weight portion ('W1' or 'W2') resulting in intermediate matrices 'B1' and 'B2'.  These intermediate results are then combined to form the final output matrix 'B'.  Similar to the left side, a simplified representation below shows the input tensor 'A' flowing into a 'Layer...' box, producing the output tensor 'B'. The dashed lines on both sides group related components.  The key difference is the distribution of the weight matrix across multiple GPUs in the right-hand diagram, showcasing how tensor parallelism improves efficiency by distributing the computational load.
Figure 23: TP splitting tensor to chunks

TP is particularly useful when a single layer is too large to fit in memory. It helps in reducing memory usage by distributing the computational load across multiple devices. If you are interested to learn more about TP and its variants (e.g., sequence parallelism), refer to [47][48].

Hybrid parallelism

Hybrid parallelism combines data and model parallelism to train large models more efficiently across multiple devices. This approach reduces memory usage by distributing both the model and data across devices. It also enables scaling to a larger number of devices, making it possible to train very large models that traditional parallelism methods cannot handle.

In addition to hybrid parallelism, techniques like ZeRO (Zero Redundancy Optimizer) [49] from Microsoft and FSDP (Fully Sharded Data Parallel) [50] from Meta further optimize resource utilization and communication efficiency. These methods reduce redundancy in memory and computation across devices, enabling more efficient training of massive models.

The techniques discussed in this section are essential components of modern ML system design and are widely used in practice. By combining parallelism techniques such as FSDP, memory-saving methods such as gradient checkpointing, and optimizations such as AMP, we can efficiently scale the training of large, complex models. A solid understanding of these techniques, and knowing when to apply them, is critical for building scalable and efficient AI systems. While this overview only touches on the basics, it is not the central focus of this book. For those interested in a more detailed exploration of distributed training, refer to the provided references.

Model sampling

After training a model, the next step is sampling, which involves generating new data or outputs from the trained generative model. Various sampling methods exist for different GenAI applications. For example, in LLMs, methods such as greedy search, beam search [51], and top-k sampling [52] each have their strengths and weaknesses. Beam search, for instance, tends to produce coherent and relevant text, but it may limit diversity.

Image represents a data flow diagram showing a trained model (represented as a cloud with the text 'Trained...') distributing data to three different sample files.  A single, thick, black arrow originates from the 'Trained...' cloud and branches into three separate arrows, each pointing to a document-shaped box representing a sample file.  These sample files are vertically stacked and visually differentiated by color: the top file is light green, the middle file is light orange, and the bottom file is light blue. Each file box contains the text 'Sample...' indicating that they contain sample data.  The ellipsis ('...') between the orange and blue files suggests that there may be more files than are explicitly shown. The overall diagram illustrates the process of a trained model generating or distributing data to multiple sample outputs.
Figure 24: Sampling new data from a trained model

In an interview, it is crucial to discuss various sampling methods in depth, their pros and cons, and to choose the one that suits the system you are designing.

Talking points

  • ​​Model architectures: What are the plausible model architectures for the chosen ML algorithm? What are the pros and cons of each? What are the specific layers in an architecture and why?
  • Training methodology: What is the training methodology? How does the training process work (e.g., diffusion process, adversarial training)?
  • Training data: Where is the training data sourced from? How large is the dataset? Do you use different data for various training stages (e.g., pretraining vs finetuning)?
  • ML objectives: What are the plausible ML objectives for the task? What are the pros and cons of each objective, and how do they impact model performance?
  • Loss functions: What is the loss function that aligns with the chosen ML objective? Do you use a single loss function or multiple ones? If multiple, how do you combine them to optimize the training process? What is the purpose of each loss function?
  • Training challenges and mitigations: What are typical training challenges specific to the chosen ML algorithm? How can these challenges be mitigated to ensure effective training?
  • Training efficiency: What are the main techniques to improve training efficiency? How does distributed training work, and what benefits does it bring? How does AMP enhance training speed and efficiency? How does data, tensor, and pipeline parallelism work?
  • Sampling: How do different sampling methods (e.g., top-k, top-p) work? What are the pros and cons of each? How does the sampling process work? How do they affect the quality and creativity of the model's output? What methods can you use to make the sampling process faster without compromising quality?

Evaluation

After developing a model, the next critical step is evaluation. This involves using various metrics to assess the performance of the ML model. In this section, we will explore two evaluation methods: offline and online evaluation.

Offline Evaluation

Offline evaluation is the process of assessing the performance of a model or system using pre-collected data without deploying it in a real-time environment. This approach is critical to ensure the model is effective before it is used by the users.

Offline evaluation differs between discriminative and generative models. The goal of discriminative models is to make predictions on an evaluation set; the evaluation compares those predictions to the ground truth. Traditional metrics such as accuracy, precision, and recall are used to quantify how well the model performs based on these comparisons. Table 2 lists common metrics for different discriminative tasks, which are thoroughly explored in [1].

TaskMetrics
ClassificationPrecision, Recall, F1 score, Accuracy, Confusion matrix
RegressionMSE, MAE, RMSE
RankingPrecision@k, Recall@k, MRR, mAP, nDCG

Table 2: Popular metrics in discriminative tasks

In generative models, evaluation is more complex. Instead of comparing predictions to a fixed ground truth, these models generate new content, such as text or images. Assessing this content often requires subjective or human-in-the-loop methods to gauge how well it aligns with human expectations or benchmarks. Table 3 shows commonly used metrics for different generative tasks.

TaskMetrics
Text GenerationPerplexity, BLEU, METEOR, ROUGE, CIDEr
Image GenerationFID, IS, KID, SWD, PPL, LPIPS
Text-to-VideoFVD, CLIPScore, FID, LPIPS, KID

Table 3: Popular metrics in generative tasks

In interviews, it's essential to assess the generated content from multiple angles. For example, in a text-to-image generation model, it's important to ensure the generated image is both high-quality and that it aligns with the given text prompt. Similarly, in a chatbot, the model’s capability should be measured across different tasks such as mathematics, common-sense reasoning, and code generation. Throughout this book, we take a deep dive into the offline evaluation of various GenAI applications and explore most metrics listed in Table 3.

Online Evaluation

The online evaluation assesses how the model performs in production (i.e., after deployment). Different metrics aligned with business objectives are used to evaluate the model's impact.

In practice, companies typically monitor multiple online metrics. During an interview, you should focus on selecting the most critical ones to gauge the system's impact. Unlike offline metrics, choosing online metrics is more subjective and often involves input from product owners and stakeholders. This step helps the interviewer assess your business sense. It is beneficial to articulate clearly your reasoning and thought process when selecting specific metrics. Table 4 lists some metrics commonly used in online evaluation.

MetricDescription
Click-Through Rate (CTR)Percentage of users who click on content or suggestions.
Conversion RatePercentage of users who complete a desired action (e.g., purchase, subscription) after interacting with the system.
Latency (Inference time)Time taken by the model to generate content.
Engagement RateMeasure of user interaction, such as time spent engaging with the system.
Revenue Per UserAverage revenue generated per user.
Churn RatePercentage of users who stop using the system over a given period.
User SatisfactionDirect feedback from users on their experience with AI-generated content.
User RetentionPercentage of users who continue to use the system over a specific period.
Completion RatePercentage of tasks (e.g., text completions, image generations) successfully completed by the model.

Table 4: Common metrics for online evaluation

Talking points

Here are some key talking points for the evaluation stage:

  • Offline metrics: Which offline metrics best evaluate the quality and accuracy of the generative model? How do these metrics measure the diversity, realism, and coherence of generated outputs?
  • Online metrics: Which metrics are crucial for assessing the effectiveness of the generative model in a live production environment? How do these metrics align with the business goals, such as enhancing user creativity, boosting engagement, or driving product innovation?
  • Bias: Generative models may unintentionally reflect societal biases in relation to sensitive attributes such as gender or race. How can you evaluate the model’s bias?
  • Robustness and security: How resilient is the generative model to adversarial attacks such as intentionally misleading inputs designed to exploit model weaknesses?
  • Human evaluation: For generative models, especially in creative fields (e.g., text generation, image synthesis), human feedback is vital. How can human reviewers complement automatic evaluation? What methods (surveys, A/B testing, expert reviews) will best assess the model’s performance? How can you mitigate the effects of subjectivity among different reviewers?

Overall ML system design

The next step of the framework is to propose an overall design for the GenAI system. These systems involve more than just training a model; they require multiple pipelines and components working together seamlessly. For instance, in a chatbot, beyond the core model, other components are needed to ensure safety, for example, filtering out harmful content. Similarly, for a video generation system, additional models may be needed to upscale video resolution to the desired quality. At this stage, it's crucial to integrate all components essential for the system to function as intended. We will explore several components commonly used along with the generative model throughout this book.

Talking points

  • System components: What are the different components of the system? What are the roles of each component—such as the core model, preprocessing, content filtering, post-processing, and any necessary upscaling or quality enhancement models?
  • Safety mechanisms: How are safety and content moderation incorporated into the system? For instance, how does the system ensure that generated content is safe and appropriate for users? Describe components such as NSFW filters and harmful.
  • User feedback and continuous learning: How does the system incorporate user feedback to continuously improve model performance? Discuss the feedback loop mechanisms that allow for finetuning the model. What systems are in place for retraining models with updated data to improve accuracy and relevance over time?
  • Scalability: How does the system scale as demand increases? What cloud or hardware resources are utilized, and how is resource allocation managed efficiently? How do components such as load balancers, distributed inference, and model parallelism contribute to system scalability?
  • Security considerations: How does the system ensure user privacy, especially when dealing with sensitive data or generating personalized content? What security protocols are implemented to protect against adversarial attacks, model tampering, or data leakage?
  • Bias: Generative models may unintentionally reflect societal biases with respect to sensitive attributes like gender or race. Discuss strategies such as bias-detection algorithms, fairness auditing, and filtering of biased outputs. Additionally, how would you address ethical concerns if users attempt to misuse the generative model to produce harmful, biased, or inappropriate content?
  • Robustness and security: How resilient is the generative model to adversarial attacks, such as intentionally misleading inputs designed to exploit model weaknesses? For example, can attackers generate harmful or nonsensical outputs? In production, how can we ensure that the model isn’t being manipulated for malicious purposes, such as creating deepfakes, misinformation, or inappropriate content?

Deployment and monitoring

The final step is to deploy it to production and serve millions of users. Once the system is deployed, it can fail for many reasons. Monitoring refers to the task of tracking, measuring, and logging different metrics to detect system failures when they occur, so they can be fixed as quickly as possible. However, since this topic is broad and not specific to GenAI or any particular task, we won’t go into detail in this book. We encourage readers to refer to [53] or the “ML System Design Interview” book [1] for a deeper exploration.

Summary

In this chapter, we provided an overview of GenAI and introduced a framework for approaching a GenAI system design interview. While some details are specific to GenAI, many concepts apply broadly across AI system design. We focus on aspects unique to GenAI, avoiding general topics common to all AI systems such as deployment, infrastructure, and monitoring.

Finally, not every engineer is expected to be an expert in all areas of the GenAI life cycle. Different roles and companies may emphasize various aspects, such as infrastructure, monitoring, or LLM development. This framework helps candidates to understand the expectations and adjust their answers accordingly based on the interview's focus.

Now that you understand these fundamentals, we’re ready to tackle some of the most common GenAI system design interview questions.

References

[1] Machine Learning System Design Interview. https://www.aliaminian.com/books. [2] Support Vector Machines. https://scikit-learn.org/stable/modules/svm.html. [3] Bayes’ theorem. https://en.wikipedia.org/wiki/Bayes%27_theorem. [4] Gaussian mixture models. https://scikit-learn.org/1.5/modules/mixture.html. [5] Hidden Markov model. https://en.wikipedia.org/wiki/Hidden_Markov_model. [6] Boltzmann machine. https://en.wikipedia.org/wiki/Boltzmann_machine. [7] OpenAI’s ChatGPT. https://openai.com/index/chatgpt/. [8] Economic Potential of Generative AI. https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier. [9] The Llama 3 Herd of Models. https://arxiv.org/abs/2407.21783. [10] Flamingo: a Visual Language Model for Few-Shot Learning. https://arxiv.org/abs/2204.14198. [11] PaLM: Scaling Language Modeling with Pathways. https://arxiv.org/abs/2204.02311. [12] Language Models are Few-Shot Learners. https://arxiv.org/abs/2005.14165. [13] Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding. https://arxiv.org/abs/2205.11487. [14] PaLM2 Technical Report. https://arxiv.org/abs/2305.10403. [15] H100 Tensor Core GPU. https://www.nvidia.com/en-us/data-center/h100/. [16] GPT-4 training cost. www.wired.com/story/openai-ceo-sam-altman-the-age-of-giant-ai-models-is-already-over/. [17] Scaling Laws for Neural Language Models. https://arxiv.org/abs/2001.08361. [18] Training Compute-Optimal Large Language Models. https://arxiv.org/abs/2203.15556. [19] Introducing OpenAI o1. https://openai.com/index/introducing-openai-o1-preview/. [20] Large Language Monkeys: Scaling Inference Compute with Repeated Sampling. https://arxiv.org/abs/2407.21787. [21] ETL. https://aws.amazon.com/what-is/etl/. [22] Tecton. https://www.tecton.ai/feature-store/. [23] Amazon SageMaker. https://aws.amazon.com/sagemaker/. [24] ML System Design Interview. https://www.amazon.com/gp/product/1736049127/. [25] Comprehensive Exploration of Synthetic Data Generation: A Survey. https://arxiv.org/abs/2401.02524. [26] HDFS Architecture Guide. https://hadoop.apache.org/docs/r1.2.1/hdfs_design.html. [27] Amazon S3. https://aws.amazon.com/s3/. [28] Apache Parquet. https://parquet.apache.org/. [29] Apache ORC. https://orc.apache.org/docs/. [30] Apache Lucene. https://lucene.apache.org/. [31] Elasticsearch. https://www.elastic.co/elasticsearch. [32] Attention Is All You Need. https://arxiv.org/abs/1706.03762. [33] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. https://arxiv.org/abs/1810.04805. [34] An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale. https://arxiv.org/abs/2010.11929. [35] Learning Transferable Visual Models From Natural Language Supervision. https://arxiv.org/abs/2103.00020. [36] Zero-Shot Text-to-Image Generation. https://arxiv.org/abs/2102.12092. [37] Neural Machine Translation by Jointly Learning to Align and Translate. https://arxiv.org/abs/1409.0473. [38] Common Crawl. https://commoncrawl.org/. [39] Data Parallelism. https://en.wikipedia.org/wiki/Data_parallelism. [40] Model Parallelism. https://huggingface.co/docs/transformers/v4.15.0/en/parallelism. [41] Pipeline Parallelism. https://pytorch.org/docs/stable/distributed.pipelining.html. [42] Mixed Precision Training. https://arxiv.org/abs/1710.03740. [43] High-Resolution Image Synthesis with Latent Diffusion Models. https://arxiv.org/abs/2112.10752. [44] Training Deep Nets with Sublinear Memory Cost. https://arxiv.org/abs/1604.06174. [45] Automatic Mixed Precision. https://pytorch.org/tutorials/recipes/recipes/amp_recipe.html. [46] Model parallelism. https://huggingface.co/docs/transformers/v4.17.0/en/parallelism. [47] Paradigms of Parallelism. https://colossalai.org/docs/concepts/paradigms_of_parallelism/. [48] Tensor Parallelism tutorial. https://pytorch.org/tutorials/intermediate/TP_tutorial.html. [49] ZeRO: Memory Optimizations Toward Training Trillion Parameter Models. https://arxiv.org/abs/1910.02054. [50] Introducing PyTorch Fully Sharded Data Parallel (FSDP) API. https://pytorch.org/blog/introducing-pytorch-fully-sharded-data-parallel-api/. [51] Beam search. https://en.wikipedia.org/wiki/Beam_search. [52] Top-k sampling. https://docs.cohere.com/docs/controlling-generation-with-top-k-top-p. [53] Model monitoring for ML in production. https://www.evidentlyai.com/ml-in-production/model-monitoring.

Chapter 2

Gmail Smart Compose

~37 min read

Introduction

Gmail's Smart Compose feature [1] assists users by suggesting the next few words as they write an email. This chapter explores this feature and examines the Transformer architecture that powers most generative systems.

Image represents a Gmail compose window showing an email being drafted.  The window's title bar displays 'Taco Tuesdays' and close ('X') buttons. Below, the 'To' field shows 'Ethan Clarke' as the recipient.  A 'Cc Bcc' field is also visible, though empty. The 'Subject' line reads 'Taco Tuesdays.' The email body begins with 'Hey Ethan!' followed by 'What's up? Haven't seen you for a whil...'  A small, rectangular 'tab' button is present at the end of this line. A curved, reddish-brown arrow originates from near the 'tab' button and points to the text 'Suggested words' outside the email window, indicating that the 'tab' button likely triggers a suggestion of words to complete the sentence, providing contextual word completion or auto-suggestions based on the existing text.  The Gmail logo is visible in the top left corner.
Figure 1: Gmail's Smart Compose feature

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: Different users might have different writing styles. Is the system expected to make personalized suggestions? Interviewer: For simplicity, let's not include personalization.

Candidate: Should the system suggest the next few words only when it is confident in its prediction? Interviewer: Yes.

Candidate: The email dataset must be sufficiently large to train a model. Do we know the approximate size of the data? Interviewer: Assume our dataset consists of around one billion email messages.

Candidate: There are different parts of data to utilize when making suggestions. For example, a user's past emails or the subject of the current email. To keep it simple, can I only utilize the email's body as the context? Interviewer: Good point. In practice, though, we use more than what the user has typed in the current email. Let's start by using the body of the email. If we have more time, we can expand the context to include other relevant information.

Candidate: What languages should the system support? Interviewer: Let's begin with English.

Candidate: Do we need to ensure the system is not biased? Interviewer: This is an important requirement for this system. The system should not make biased assumptions in providing its suggestions.

Candidate: How many active users does Gmail have? Is the computing cost a concern in this feature? Interviewer: Gmail has about 1.8 billion users, and a single user can send as many as 500 emails in a day. We do care about the computing costs, but let's focus on developing the system first. We can optimize for efficiency in future iterations.

Candidate: Should the system make real-time suggestions? Interviewer: Yes. The expected latency should be imperceptible; something around 100 milliseconds should be fine.

Frame the Problem as an ML Task

In this section, we frame the Smart Compose feature as an ML task. This requires us to understand the system's inputs and outputs and choose a suitable ML approach for learning the task.

Specifying the system's input and output

The input to the model is a sequence of words typed by the user. The output is a continuation of that sequence. The model generates the words that the user is likely to type next.

Image represents a simple data flow diagram illustrating the functionality of a 'Smart Compose System.'  The diagram shows an input string, 'Hi John! I hope,'  connected via a solid black arrow to a light-orange, rounded-rectangle box labeled 'Smart Compose System.' This box represents the system's processing unit.  Another solid black arrow extends from the 'Smart Compose System' box to an output string, 'you are doing well!'  The arrows indicate the direction of data flow, showing that the input string is processed by the Smart Compose System, resulting in the output string.  A small text note at the bottom of the 'Smart Compose System' box reads 'Text is not SVG - cannot display,' indicating that the box's visual representation is not an SVG image.
Figure 2: Input and output of the Smart Compose system

Choosing a suitable ML approach

Smart Compose generates textual content, so we categorize it as a text generation task. Various ML architectures are designed to process sequential data, which is essential for text generation. Two popular architectures are recurrent neural networks (RNNs) [2] and Transformers [3].

Transformers provide several advantages over RNNs, with two main benefits being:

  • Parallelism: In an RNN, computations from one time step are carried forward and used in the next, creating a time-dependent chain of operations. Transformers, on the other hand, can process all input tokens simultaneously through their self-attention mechanism.
  • Better handling of long sequences: Transformers use self-attention mechanisms to focus on any part of a sequence, regardless of distance. In contrast, RNNs, struggle with long-range dependencies because of their sequential structure and the vanishing gradient problem.

Due to these advantages, Transformers have shown outstanding performance in text generation tasks and are, thus, used in most generative systems nowadays. Therefore, we chose Transformers to build the Smart Compose feature.

FeatureRNN (GRU [4], LSTM [5])Transformer
ArchitectureSimpleComplex
Training efficiencyInefficient due to sequential processingEfficient due to parallel processing
EffectivenessLow as it struggles with long sequencesHigh as it handles long sequences
ScalabilityLimited scalabilityHighly scalable
ApplicationsSimple tasks such as time series modelingComplex tasks such as language completion or translation

Table 1: Comparison of RNN and Transformer architectures

While Transformers are more parallelizable due to their lack of strict sequential dependencies, their self-attention mechanism has a computational complexity of O(n2)O(n^2)O(n2), where nnn is the sequence length. This complexity arises because the self-attention mechanism requires the calculation of attention scores between every pair of tokens in the sequence. Various techniques are introduced to reduce the complexity of attention. To learn more, refer to Group Attention [6] and Flash Attention [7].

Data Preparation

During the data preparation step, we convert raw data into the format expected by the ML model. First, let's briefly review the available data.

Two sources of data are available for training our model: general data and email data. General data includes publicly available text from sources such as books, websites, and social media posts. This data is important for training language models because it contains diverse vocabulary, syntax, and contexts.

Image represents a digitized page displaying two vertically-aligned columns of text.  Each column contains a poem, seemingly from the same source, with line numbers ('6' and '9') marking the end of the first and second stanzas respectively in each column. The left column's poem focuses on the fleeting nature of summer's beauty and the enduring sweetness that remains even in winter. The right column's poem uses musical metaphors to explore the themes of loneliness and the importance of connection, contrasting the solitary life with the vibrant fullness of a family.  The poems are presented in a serif typeface, typical of older printed works, with consistent line spacing and justification. No URLs or parameters are visible; the only additional elements are the line numbers, which serve as visual separators within the poems. The two columns are presented side-by-side without any explicit visual connection beyond their shared page layout.  The text flows vertically within each column, with each line representing a verse in the respective poem.
Figure 3: Example of general data from Shakespeare

The email data, as specified in the requirements, consists of one billion email messages. This data is crucial for the model to learn email writing styles and common phrases used in emails. Table 2 shows a simplified example of email data. In practice, more metadata is stored for each email message.

Email IDSenderRecipientSubjectBody
4953[email protected][email protected]Catchup?Hey Mike, let's catch up this Sat. …
9356[email protected][email protected]Project DeadlineHi TA, I hope you are well. I am writing to you to …

Table 2: Example of email data

Raw text in both general data and email data is often noisy and inconsistent, which can degrade the model performance. Additionally, ML models require data to be in a numerical format. For these reasons, raw text has to be prepared using the following two key steps:

  • Text cleaning and normalization
  • Text tokenization and token indexing

Text cleaning and normalization

Text cleaning

Text cleaning removes unnecessary or irrelevant information. Common methods include:

  • Remove non-English text: Use language identification [8] methods such as [9] to identify and remove non-English text from general and email data.
  • Remove confidential information: Emails may contain confidential information such as phone and credit card numbers. These details must be removed to prevent the model from learning or exposing them later. We replace personal names, URLs, email addresses, and phone numbers with placeholder characters. For example, replace "[email protected]" with "##@gmail.com."
  • Remove irrelevant characters or symbols: Remove unnecessary or irrelevant characters and symbols that do not contribute to the meaning. For example, symbols such as "©," "™," or emojis are removed, as they do not typically change the meaning of text.
  • Remove duplicated data: Duplicate data refers to identical text from different sources that appear multiple times in the dataset. We remove duplicates to prevent the model from becoming biased and skewing the model's learning process.

Text normalization

Text normalization transforms text into a consistent format. For example, it converts different ways of writing a phone number—such as "(123) 456-7890," "123.456.7890," and "123-456-7890"—into a standard format, for example, "1234567890." Text normalization ensures consistency and reduces complexity in text data.

Next, we convert the raw text into a sequence of numbers through text tokenization and token indexing.

Text tokenization and token indexing

Text tokenization followed by token indexing converts the raw text into a format the Transformer model expects: a sequence of numbers.

Image represents a data processing pipeline illustrating text tokenization.  The pipeline begins with a dashed-line box labeled 'Raw text' containing the text string 'Hi I am Emilie'.  A solid arrow points from this box to a light green rounded-rectangle labeled 'Text Tokenization...'. This rectangle represents the process of converting raw text into numerical tokens.  Another solid arrow extends from the 'Text Tokenization...' block to a sequence of four adjacent boxes, each containing a number (3, 7, 11, 29). This final sequence is labeled 'Sequence of indices,' indicating that the numbers represent the indices or positions of the tokens in a vocabulary or embedding space.  The overall flow shows how raw text is transformed into a numerical representation suitable for machine learning models, where each number corresponds to a specific word or sub-word unit from the input text.
Figure 4: Converting raw text to a sequence of numbers

Let's examine each step in more detail.

Text tokenization

Text tokenization is the process of splitting text into smaller units called tokens. Figure 5 shows how OpenAI's GPT-4 tokenizes the sentence "Let's go to NYC".1

Image represents a simple flowchart illustrating the process of tokenization in natural language processing.  At the top, a rectangular box contains the input phrase 'Let's go to NYC'. A downward arrow connects this box to a second box labeled 'Tokenization,' indicating that the input phrase will undergo this process.  From the 'Tokenization' box, another downward arrow points to a horizontal arrangement of five smaller rectangular boxes. Each of these smaller boxes contains a single token from the input phrase: 'Let,' ''s,' 'go,' 'to,' and 'NYC.'  The arrangement visually demonstrates how the 'Tokenization' process breaks down the input sentence into its individual constituent words and punctuation marks, effectively separating the input string into its fundamental units.
Figure 5: Example of GPT-4 tokenization

Tokenization can be performed at different levels. For example, "Hello world" can be split into ["Hello", "world"] or ["H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]. Generally, tokenization algorithms are divided into three categories:

  • Character-level tokenization
  • Word-level tokenization
  • Subword-level tokenization

Understanding each tokenization category and its pros and cons is crucial in most ML interviews. Let's delve into them.

Character-level tokenization

Character-level tokenization breaks text down into a set of characters. It is simple to implement, but difficult for the model to learn meaningful representations for each token. For example, it's harder to learn a meaningful representation for the letter "g" than for the word "go," because "go" has a clear meaning, whereas "g" does not. Because of this, character-level tokenization often results in a loss of performance.

Image represents a flowchart illustrating character-level tokenization.  At the top, a rectangular box contains the text 'Let's go!'. A downward arrow connects this box to the text 'Character-level tokenization,' indicating the process's starting point.  Below this, a series of nine rectangular boxes, resembling keyboard keys, are arranged horizontally. Each box contains a single character from the input string 'Let's go!', representing the individual tokens resulting from the character-level tokenization. The order of characters in the boxes mirrors the order in the input string: L, e, t, ', s,  g, o, !.  The arrow from 'Character-level tokenization' points to this row of character boxes, showing the output of the process.  A small text at the bottom indicates that the image is not an SVG and cannot be fully displayed.
Figure 6: Example of character-level tokenization
Word-level tokenization

Word-level tokenization breaks text into individual words. While there are different algorithms for word-level tokenization, a simple algorithm is to split the text using its whitespaces.

Image represents a simple data processing pipeline illustrating word-level tokenization.  A rectangular box at the top contains the input text string 'Let's go!'. A downward-pointing arrow connects this input box to a text label 'Word-level tokenization,' indicating a processing step.  This processing step outputs two rectangular boxes placed side-by-side, each containing a single token from the input string: 'Let's' in the left box and 'go!' in the right box.  The text 'Text is not SVG - cannot display' below the output boxes suggests that the image is a simplified representation and that a more detailed visualization of the tokenization process might be available in a richer format like SVG. The overall flow depicts the transformation of a single input string into individual word tokens.
Figure 7: Example of word-level tokenization

The advantage of word-level tokenization is that it is simpler for the model to learn meaningful representations for each token. However, the main disadvantage of word-level tokenization is that it typically leads to a very large vocabulary size. For example, Transformer-XL [10] uses a word-level tokenizer, resulting in a vocabulary of 267,735 tokens. A large vocabulary size is problematic because the model has to learn representations for hundreds of thousands of tokens. This makes the training time-consuming and, therefore, more costly to train than character-level tokenization.

Let's examine subword-level tokenization which offers a balance between word-level and character-level tokenization.

Subword-level tokenization

Subword-level tokenization splits text into smaller units called subwords. It is based on the principle that a frequently used word should not be split into smaller subwords, but a rare word should be split into smaller meaningful subwords. For example, "unhappily" might be considered a rare word and thus be split into "unhappy" and "ly." Both "unhappy" and "ly" are more frequently used in text data, making it easier for the model to learn a meaningful representation for each.

Image represents a simple illustration of subword-level tokenization.  A top rectangular box contains the input phrase 'Let's go!'. A downward-pointing arrow connects this box to the text 'Subword-level tokenization,' indicating a process is applied.  Another downward-pointing arrow leads from 'Subword-level tokenization' to four smaller, rectangular boxes arranged horizontally. Each smaller box represents a token resulting from the tokenization process: 'Let,' ''s,' 'go,' and '!'.  The arrangement shows the input phrase being broken down into its constituent subword units, demonstrating how subword tokenization works by splitting words and contractions into smaller meaningful units.
Figure 8: Example of subword-level tokenization

While subword-level tokenization can be complex to implement, it has several benefits. First, it leads to a manageable vocabulary size, thus reducing the cost of the model learning representations for each subword. Second, subword-level tokenization allows the model to represent unfamiliar words by decomposing them into known subwords.

Table 3 below compares the characteristics of the three tokenization categories.

CharacteristicsCharacter-levelWord-levelSubword-level
GranularityIndividual charactersIndividual wordsSubwords
Vocabulary sizeSmallLargeModerate
Algorithm complexitySimpleSimpleComplex
Handling unseen wordsDecomposes unseen words into charactersCannot easily handle unseen wordsDecomposes unseen words into known subwords
Vocabulary size~100~300,000+~50,000–150,000
PerformancePoor performanceHigh performance but not practicalHigh performance and practical

Table 3: Comparison between different tokenization categories

Which tokenization is suitable for the Smart Compose feature?

Most state-of-the-art language models use subword-level tokenization algorithms such as Byte-Pair Encoding (BPE) [11] and SentencePiece [12]. These algorithms are more efficient and can effectively handle multiple languages. For example, OpenAI's GPT-4 uses a variant of BPE [13], and Google's Gemini uses SentencePiece [14].

Given the effectiveness of subword-level tokenization, we use it as the text tokenizer for the Smart Compose feature. We rely on popular Python libraries such as Tiktoken [13] by OpenAI or SentencePiece [15] by Google to perform text tokenization. These libraries are implemented reliably and they support various tokenization algorithms.

In Chapter 3, we will dive into BPE and explore its algorithms. To learn more about subword-level tokenization algorithms, refer to [16].

Token indexing

Token indexing is the process of converting textual tokens into integer numbers.

To prepare for token indexing, the tokenization algorithm first builds a vocabulary—a collection of all unique tokens—from the training text data and then stores it in a table. Figure 9 shows examples of vocabularies for different tokenization categories. The order and ID values are chosen arbitrarily for demonstration purposes.

Image represents three tables illustrating different vocabulary levels used in natural language processing.  The first table, labeled 'Character-level Vocabulary,' maps individual characters (e.g., 'a', 'b', 'A', 'B', '!', '<SPACE>') to unique numerical IDs (0, 1, 26, 27, 57, 105 respectively).  The second table, 'Word-level...', shows a mapping of whole words (e.g., 'a', 'about', 'after', 'all', 'also', 'zebra', '!') to IDs (0, 1, 2, 3, 4, 270030, 270131 respectively). The third table, 'Subword-level Vocabulary,' presents a mapping of subword units and special tokens (e.g., 'the', 'of', 'home', '##ing', '##ed', '##able', '<EOS>', '<SPACE>') to IDs (0, 1, 2, 50252, 50253, 50254, 50255, 50256 respectively).  Each table demonstrates a different granularity of tokenization, with character-level being the finest and subword-level offering a balance between character and word-level representations, often handling out-of-vocabulary words more effectively.  The ellipses (...) indicate that the tables are truncated and contain more entries than shown.
Figure 9: Examples of different vocabularies

Once the tokenization algorithm has built the vocabulary, we can convert any token into a number and any number back into a token. Figure 10 shows token indexing using the GPT-4 vocabulary [17].

Image represents a process of tokenization and numerical ID assignment within a GPT-4 vocabulary.  The left side shows a flowchart.  A rectangular box labeled 'Let's go!' is at the top, pointing downwards to a row of four boxes representing the individual tokens: 'Let,' ''s,' 'go,' and '!'.  An arrow then points from the 'go' token to another row of four boxes, each containing a numerical ID: 10267, 596, 733, and 0.  These IDs correspond to the tokens above them. The right side displays a table labeled 'GPT-4 Vocabulary,' with two columns: 'Token' and 'ID.'  This table shows a partial list of tokens and their corresponding numerical IDs, including the tokens and IDs from the flowchart, illustrating the mapping between text tokens and their numerical representations used internally by the GPT-4 model.  The ellipses (...) indicate that the table contains more entries than are shown.
Figure 10: Example of token indexing

To summarize the data preparation step, we first clean and normalize the text data to ensure high-quality, consistent text in our training data. Next, we use a subword-level tokenization algorithm such as BPE to tokenize the text into textual tokens (subwords) and then replace each token with its numerical index. These steps ensure our training data is now represented in a numerical format that the ML model can use.

Model Development

The Smart Compose feature is a text generation task in which a Transformer model predicts how email sentences are likely to be completed. In this section, we explore the details of the Transformer architecture, training strategies, and sampling methods to develop the text generation model.

Architecture

The Transformer architecture, introduced in the paper "Attention Is All You Need" [3], is designed to process sequences. This makes it ideal for tasks that require understanding a text and the relationships between its words. For example, in the Smart Compose feature, the model processes the sequence of words already entered by the user so it can suggest the next words.

Transformers have three primary variations:

  • Encoder-only
  • Decoder-only
  • Encoder-decoder

Each variation has minor architectural differences that make them suitable for specific tasks. Let's briefly explore each variation and its applications.

Encoder-only

An encoder-only Transformer is used for tasks that require understanding the overall meaning of a text. It processes the input sequence as a whole and makes predictions about it. For instance, in a sentiment analysis task, an encoder-only Transformer predicts the sentiment of the input sentence.

Image represents a simplified diagram of a sentiment analysis system.  The bottom component, enclosed in a dashed-line box, represents the input text: 'This product is very good'.  An arrow points upward from this input text to a larger, light-green, rectangular box labeled 'Encoder-only Transformer,' indicating that the input text is processed by this transformer model.  The transformer likely encodes the input text into a numerical representation suitable for sentiment analysis.  Finally, another upward-pointing arrow connects the output of the 'Encoder-only Transformer' to a small, square box labeled 'Sentiment: 1,' signifying that the model has assigned a sentiment score of '1' (presumably positive, given the input text) to the input sentence. The overall flow demonstrates the process of inputting text, transforming it using an encoder-only transformer, and generating a numerical sentiment score as output.
Figure 11: Encoder-only Transformer for sentiment analysis

Encoder-only Transformers are commonly used for tasks such as sentence classification and named entity recognition, which focus on understanding the input rather than generating new content. Google's BERT [18] is a well-known example of an encoder-only Transformer. However, these models are not typically used to generate new sequences. Decoder-only Transformers, on the other, are specifically designed for that purpose.

Decoder-only

A decoder-only Transformer processes the input sequence and generates a new sequence iteratively.

Image represents a simplified architectural diagram focusing on a decoder-only Transformer model.  The central element is a rectangular box with a peach/light-orange fill and a gold border, clearly labeled 'Decoder-only Transformer.' This box represents the core of the generative AI system. Above and below this central box are dashed-line rectangles, representing unspecified input and output components respectively.  No arrows or explicit connections are shown between these components and the decoder-only Transformer, implying a general flow of information:  unspecified input feeds into the decoder-only Transformer, which then produces an unspecified output.  The lack of detail in the input and output boxes suggests a focus on the core Transformer architecture itself, rather than the specifics of data ingestion or post-processing.
Figure 12: Decoder-only Transformer for text completion

Decoder-only Transformers are widely used in generative tasks including text generation, where the model generates a sequence one token at a time based on the previously generated tokens. Most large language models (LLMs), such as OpenAI's GPT-4 [19], Meta's LLaMA [20], and Google's Gemini [14], are based on a decoder-only Transformer.

Encoder-decoder

The encoder-decoder architecture utilizes both encoder-only and decoder-only Transformers. An encoder component processes the input sequence and a decoder uses that processed information to generate the output sequence.

Image represents a simplified diagram of a machine translation system.  A light-green rectangle labeled 'Encoder-only...' represents an encoder component of a neural machine translation model, which takes as input an English sentence 'I am graduating' enclosed in a dashed-line box labeled 'English:'.  An arrow indicates the flow of information from the English sentence to the encoder.  A light-orange rectangle labeled 'Decoder-only...' represents a decoder component, receiving the output from the encoder.  An arrow shows the data flow from the encoder to the decoder. Finally, an arrow points from the decoder to a dashed-line box labeled 'Japanese:' containing the Japanese translation '私は卒業します'. This illustrates the translation process: the encoder processes the English input, and the decoder generates the Japanese output.
Figure 13: Encoder-decoder Transformer used for language translation

An encoder-decoder Transformer is particularly suited for tasks where the output is a transformation of the input. For example, in a language translation task, the input sentence in one language is transformed into an equivalent sentence in another language. We'll examine this architecture in Chapter 3.

Figure 14 below shows commonly used models that employ different variations of Transformers.

Image represents a classification of different transformer-based language models based on their architecture.  The diagram starts with a central node labeled 'Transformer,' branching into three main architectural types: 'Encoder-only,' 'Decoder-only,' and 'Encoder-decoder.'  The 'Encoder-only' branch connects to 'Meta's RoBERTa' and 'Google's BERT.' The 'Decoder-only' branch connects to 'OpenAI's GPT,' 'Anthropic's Claude,' 'Meta's LLaMA,' 'xAI's Grok,' and 'Google's Gemini.' Finally, the 'Encoder-decoder' branch connects to 'Meta's BART' and 'Google's T5.'  Each line represents a specific language model, indicating its architectural classification within the broader transformer family.  The arrangement visually demonstrates the relationships between different models and their underlying architectural designs.
Figure 14: Popular models for each variation of Transformers

Which Transformer variation is suitable for the Smart Compose feature?

The choice between encoder-only, decoder-only, and encoder-decoder Transformer models depends on whether the nature of the task is generation or understanding. Smart Compose is a text generation task that aims to complete a partially written text. Therefore, a decoder-only Transformer is ideal for this task due to its ability to generate text based on a given sequence.

ML system design interviews typically focus on high-level concepts and component interactions rather than architectural details. We'll provide a brief overview of the Transformer architecture without going too deep. For a deeper understanding of Transformer architectures, refer to [21] and [22].

A decoder-only Transformer consists of the following components:

  • Text embedding
  • Positional encoding
  • Transformer
  • Prediction head

Text embedding

The text embedding component converts each token ID into a fixed-length vector called an "embedding." Embeddings are typically stored in a table, as shown in Figure 15, and learned during the training process.

Image represents a process of token embedding.  On the left is a vocabulary table with two columns: 'Token' and 'ID'.  The 'Token' column lists example words or symbols (!, ', go, etc.), while the 'ID' column assigns a unique numerical identifier to each token (0, 1, 733, etc.).  This table is labeled 'Vocabulary'.  To the right is an 'Embedding table...', which is a matrix containing numerical values (e.g., 0.25, 0.10, 0.75, etc.). Curved arrows connect the vocabulary table to the embedding table.  Specifically, an arrow labeled 'Token 0 embedding' connects the ID '0' from the vocabulary table to the first row of the embedding table, indicating that the embedding for token '!' (ID 0) is the vector [0.25, 0.10, 0.75]. Similarly, an arrow labeled 'Token 1 embedding' connects the ID '1' to the second row of the embedding table, showing the embedding for token ''' (ID 1) as the vector [0.18, -0.9, 0.34].  The embedding table represents a vector representation of each token from the vocabulary, where each row corresponds to a unique token ID and contains its embedding vector.
Figure 15: Embedding table representing tokens

The text embedding is crucial in a decoder-only Transformer. Let's understand why.

During data preparation, we tokenized the text and converted tokens to IDs. However, there are two significant limitations in how the text is represented:

  • Sparsity: The vocabulary typically includes tens of thousands of token IDs. Representing these IDs using one-hot encoding results in sparse, high-dimensional data, which is inefficient.
  • Lack of semantic information: Token IDs are arbitrary and do not capture any relationships between words. For example, the words "happy" and "joyful" might be close in meaning, but their token IDs may not reflect this similarity.

The text embedding component addresses both of these limitations by converting token IDs into learned embeddings. Since the embeddings are dense vectors in a lower-dimensional space, sparsity is no longer a concern.

In addition, since the embeddings are learned during model training, they capture semantic meanings. For example, the embeddings for "happy" and "joyful" will be closer together in the embedding space than those for "happy" and "sad," as shown in Figure 16.

Image represents a two-dimensional scatter plot with axes labeled X1 and X2.  The plot displays various words categorized into two distinct clusters.  The first cluster, encircled in red, is positioned towards the lower left and contains the words 'Sad' and 'Angry.' The second cluster, also encircled in red, is located towards the upper right and includes the words 'Joyful' and 'Happy.'  The remaining words—'Orange,' 'Apple,' 'Strawb...' (presumably 'Strawberry'), 'Cat,' 'Dog,' 'Car,' 'Bicycle,' and 'Bus'—are scattered across the plot, not clearly belonging to either cluster, suggesting they represent a different dimension or category not directly related to the emotional states represented by the clustered words.  There are no explicit connections or information flow lines drawn between the words; their positions relative to each other and the axes implicitly suggest a relationship based on an unspecified underlying data set.
Figure 16: Word embedding similarities (visualized in 2D for simplicity)

Positional encoding

Transformers do not inherently consider the order of input tokens. If we look at the formula for attention, am, n=exp(qmknd)j=1Nexp(qmknd),

we see that it is permutation-invariant, meaning the attention mechanism doesn't account for token positions in the sequence. For instance, the Transformer cannot differentiate between "initialize the variable, then use it" and "use the variable, then initialize it." This impacts the model's ability to understand or generate coherent text.

To overcome this limitation, positional encoding provides the Transformer with position information for each token in the input sequence. Without positional encoding, the model treats the input sequence as a bag of words, which is problematic. With positional encoding, each token's position is encoded using a positional encoding function, pi=f(i), where f(⋅)f(⋅)f(⋅) is the positional encoding function and iii is the position of the token. This allows the model to distinguish between use the variable, then initialize it'' and initialize the variable, then use it."

Image represents a simplified diagram of a transformer model processing the input text 'I am home'.  The bottom layer shows the input text, which is tokenized into three tokens: 'I', 'am', and 'home'. Each token is represented by its corresponding token ID (40, 1097, and 2162 respectively). These IDs are then mapped to their respective token embeddings, which are represented as 3x3 matrices of numerical values (e.g., for 'I': 0.2, 0.5, -0.6; 0.9, -0.1, 0.9).  These embeddings are further augmented with positional embeddings (indicated by  `$e_.:.token i embedding` and `$p_.:.position i embeddi...`), which provide information about the token's position in the sequence. The combined token and positional embeddings are then fed into the transformer layers (represented by three stacked orange rectangles), which process the information. The output of the transformer (not explicitly shown) would be the model's representation of the input sentence.  Arrows indicate the flow of information from the input text through tokenization, embedding, and into the transformer.
Figure 17: Adding positional information to the Transformer's input sequence

Positional encoding can be achieved through two common methods:

  • Fixed positional encoding
  • Learned positional encoding
Fixed positional encoding

This method uses a fixed function to map a position (an integer) to a fixed-size vector. The original Transformer paper introduced the sine-cosine function at different frequencies as its positional encoding function.

Image represents a slide or a section of a document explaining sine-cosine positional encoding.  The top line displays the title 'Sine-cosine positional encoding'. Below this title, a partially shown mathematical equation is presented:  `$\begin{align*} PE_{(pos, 2i)} &= ...` This equation fragment suggests a formula for calculating positional encoding (PE), where `pos` likely represents the position of a token in a sequence, and `2i` likely indexes a dimension within the encoding vector. The ellipsis (...) indicates that the equation continues beyond what's shown.  The equation is written using LaTeX mathematical notation, implying a technical or academic context. The bottom line indicates that the underlying text is not an SVG image, explaining why a visual representation of the equation might be missing.  There are no other components, connections, or information flows depicted in the image beyond the title and the partial equation.
Figure 18: Sine-cosine positional encoding formula

Figure 19 illustrates an example of sine-cosine positional encoding, showing vector representations for four different positions. For simplicity, this example uses a vector dimension of four. In practice, this dimensionality typically matches that of the token embeddings so they can be added together (see Figure 17).

Image represents a table-like structure displaying the results of a sine and cosine calculation across multiple iterations.  The structure is organized into four columns and four rows. Each row represents a different iteration, indicated by the changing subscript in the variable names `$P_{ij}`. The first row initializes two variables, `$P_{00}` and `$P_{02}` to 0, and `$P_{01}` and `$P_{03}` to 1.0. Subsequent rows calculate the sine and cosine of increasing integer values (1, 2, 3...).  Specifically, columns 1 and 3 calculate the sine of the iteration number (e.g., `$P_{10} = sin(1...)`, `$P_{20} = sin(2...)`), while columns 2 and 4 calculate the cosine (e.g., `$P_{11} = cos(1...)`, `$P_{21} = cos(2...)`). The numerical results of these calculations are displayed in each cell, showing the computed sine and cosine values for each iteration.  The ellipses (...) in the formulas suggest that the actual calculations might involve more complex expressions than just `sin(x)` and `cos(x)`.  The `$p_...` prefix before each row seems to be a common identifier for the entire set of calculations.
Figure 19: Example of sine-cosine positional encoding

Let's take a look at the pros and cons of fixed positional encoding.

Pros:
  • Efficiency: Fixed encodings do not add extra trainable parameters to the model. This makes them computationally more efficient.
  • Support for long sequences: Fixed methods can map any position into a representation. This flexibility allows the model to handle longer sequences beyond the model's training data.
Cons:
  • Predefined limits: Some fixed encoding methods require a predefined maximum position, thus limiting their applicability to sequences below that maximum.
  • Suboptimal performance: In certain tasks, fixed encodings may not capture the positional relationships as effectively as learned methods. This can lead to suboptimal performance.
Learned positional encoding

In this method, the positional representations are learned during the training process. Specifically, a weight matrix P∈RN×dP \in \mathbb{R}^{N \times d}P∈RN×d is initialized, where NNN is the maximum sequence length and ddd is the dimensionality of the embeddings. This matrix PPP is treated as a trainable parameter, and it is optimized alongside the model's other parameters.

The image represents a completely blank or empty space.  There are no visible components, no arrangement, no connections, and no information flow of any kind.  The image is simply a solid black rectangle, devoid of any diagrams, text, labels, URLs, parameters, or any other visual elements.
Figure 20: Trainable matrix representing positional encodings

Learned positional encoding has the following pros and cons.

Pros:
  • Optimal performance: Since the embeddings are learned based on the training data, learned positional encoding can lead to optimal position representation for the specific task.
Cons:
  • Inefficiency: Requires additional parameters to be learned during the training, which can increase the training time and computational cost.
  • Lack of generalization: Learned embeddings may overfit to specific sequence lengths seen during training. If the model mainly sees sequences of a certain length during training, it may not effectively represent other positions. This affects the model's ability to generalize across diverse positions.

In summary, the choice between learned and fixed positional encodings depends on the constraints of the task, including the expected variability in sequence lengths. Some papers, including the original Transformer paper, employ fixed positional encoding due to its efficiency and better generalization. Following that, we employ fixed positional encoding, such as sine-cosine encoding, to train the Smart Compose feature.

Transformer

The Transformer component takes a sequence of embeddings as input and transforms them into an updated sequence of embeddings.

Image represents a diagram of a transformer-based architecture, likely used in a natural language processing (NLP) model.  The diagram shows an input sequence represented by three vertical rectangles labeled 'Input sequ...', each representing a sequence element. These feed upwards into two stacked transformer blocks, each containing a 'Multi-head...' layer (represented by an orange rectangle) followed by a 'Feed Forward' layer (represented by a light blue rectangle).  The 'Multi-head...' layers likely represent multi-head attention mechanisms, and the 'Feed Forward' layers represent fully connected feed-forward networks.  Arrows indicate the flow of information between layers.  The output of the second transformer block, also represented by three vertical rectangles labeled 'Output...', is shown at the top, indicating the processed sequence.  The dashed lines enclose each transformer block, highlighting their modular structure.  The text 'Transformer...' is placed to the left of each transformer block, indicating that the entire block represents a single transformer unit.
Figure 21: A simplified Transformer structure

The Transformer architecture consists of a stack of blocks. Each block contains the following:

  • Multi-head attention: This layer updates each embedding by using the attention mechanism. The attention mechanism captures the relationships in the sequence by allowing each embedding to attend to its preceding embeddings. Due to the nature of its mechanism, multi-head attention is commonly known as self-attention, a term we'll use throughout the rest of this book.
  • Feed forward: This layer applies two linear transformations, with a ReLU activation in between, to each embedding in the sequence independently.

Transformer architecture includes details such as residual connections, layer normalization, and dropout layers. For a deep understanding of these components, refer to the paper "Attention Is All You Need" [3] and [21].

Prediction head

The prediction head—the final component in a decoder-only Transformer—translates the Transformer's output into probabilities for every token in the vocabulary (Figure 22). These probabilities are used to choose the most likely next token.

Image represents a diagram illustrating the process of text generation in a language model.  At the bottom, the input text 'How are' is fed into a 'Text Embedding' layer, which converts the words into numerical representations. These embeddings are then passed through a 'Positional Encoding' layer, adding information about the word order.  The output of this layer is fed into a 'Transformer' layer, the core of the model, which processes the encoded text to understand its meaning and context. The Transformer's output is then passed to a 'Prediction Head,' which predicts the probability of the next word.  The diagram shows a sequence of predicted words with associated probabilities: 'you' (0.94 probability) and 'zebra' (0.01 probability), with '<EOS>' (end of sequence) and 'able' (0.04 probability) appearing earlier in the sequence. A curved arrow points from the 'you' prediction to the text '94% probability fo...', indicating that the model assigns a high probability to 'you' as the next word in the sequence.  The entire architecture is a bottom-up flow, with information moving from the input text through the layers to the prediction head, which then outputs the predicted words and their probabilities.
Figure 22: Prediction head output probabilities

Training

Training adjusts the decoder-only Transformer's parameters using email data. Once the training process is complete, the model can suggest likely completions.

However, directly training the model on a task-specific dataset, such as email data, is not a good strategy. This direct training has several challenges:

  • Lack of large training data: Task-specific datasets are usually limited in size. This limitation can hinder the model's ability to learn effectively.
  • Risk of overfitting: When a model is trained on a task-specific dataset, it runs a high risk of overfitting. Overfitting occurs when a model memorizes the training data to the extent that it cannot generalize to unseen data.
  • Expensive and lengthy training: Training a large model from scratch requires significant computational resources and time. This is because the model has to learn different aspects of language, which is a complex and resource-intensive process.

To address the above issues, a two-stage training strategy is commonly employed: pretraining, followed by finetuning. In the pretraining stage, the model is trained on a large amount of general data to learn the structure of the language. In the finetuning stage, the pretrained model is then finetuned on data specific to the task at hand (e.g., email completion).

This two-stage strategy harnesses a form of transfer learning, as the general knowledge gained during the pretraining stage is transferred to the finetuning stage. This transfer is beneficial because the model doesn't have to start from scratch when learning a new task. Instead, it adjusts its pretrained weights, which is more efficient.

Image represents a two-stage machine learning model training pipeline.  Two cylindrical database icons, labeled 'General...' and 'Email...', represent the source data for the model.  Arrows indicate data flow.  'General...' data feeds into a rectangular box labeled '1. Pretraining,' which then outputs to a cloud-shaped box labeled 'Base...'.  Similarly, 'Email...' data feeds into a rectangular box labeled '2. Finetuning.'  A connection from the 'Pretraining' box to the 'Finetuning' box shows that the output of the pretraining stage is used as input for the finetuning stage.  Finally, the 'Finetuning' stage outputs to a cloud-shaped box labeled 'Final...', representing the final trained model.  The 'Base...' and 'Final...' labels suggest that these represent intermediate and final model versions, respectively.
Figure 23: Two-stage training strategy

Let's take a closer look at each stage and examine the necessary training data, ML objectives, and loss functions for each.

. Pretraining

Pretraining involves training a model on a large volume of general text data. This data is usually diverse, covering a wide range of topics and language structures. The purpose of pretraining is to develop a model capable of understanding natural language, including syntax, common knowledge, and language structures.

Pretraining data

The pretraining data for this stage usually consists of a large volume of general text data from various sources on the web, such as web pages, books, and social media. For example, Common Crawl [23] is a publicly available dataset collected by crawling a large number of web pages on the Internet. It contains petabytes of data that have been regularly collected since 2008.

ML objective and loss function

An ML objective refers to the formalized goal that a training process aims to achieve. In the case of text generation, the most commonly used ML objective is "next-token prediction." In this ML objective, the model is tasked with predicting the next token given a sequence of previous tokens. For example, in the sentence "I hope you are __," the model should predict a high probability for "well" as the next token.

Image represents a simplified illustration of a language model's prediction process.  A peach-colored rectangular box labeled 'Model' receives input from four smaller boxes containing the words 'I,' 'hope,' 'you,' and 'are.'  Arrows indicate the flow of information from these input words into the model. The model outputs a vertical column of numbers representing probabilities (0.02, 0.11, 0.86, 0.00, 0.01), which are then mapped to a bar chart titled 'Token probabilities.' This chart displays the probability distribution for four potential next words: '<EOS>' (end of sentence), 'able,' 'well,' and 'zebra.'  The bar for 'well' is significantly taller than the others, indicating an 86% probability, while 'able' has a 2% probability, and '<EOS>' and 'zebra' have much lower probabilities. A curved arrow connects the model's probability output to the bar chart, visually demonstrating how the model's numerical probabilities are translated into a probability distribution over possible next tokens.
Figure 24: Probability distribution in next-token prediction

Next-token prediction is well suited for text generation tasks because, after the training process, the model can construct sentences incrementally. For example, given the input “I ordered food because I,” the model might predict was'' as the next word. Subsequently, this process repeats with the new sequence I ordered food because I was,'' leading to the next prediction, perhaps, ``hungry.'' This iterative process continues until the model predicts “⟨\langle⟨EOS⟩\rangle⟩,” a special token that indicates the end of the sequence. Figure 25 shows the incremental process of generating text using next-token prediction.

Image represents a sequence of autoregressive language models generating a sentence.  Each numbered section (1, 2, 3, and implied continuation) depicts a model's processing step.  A rectangular box labeled 'Model' (peach-colored with a gold outline) represents the core language model.  Below the 'Model' box are smaller, dashed-line boxes containing individual words ('How,' 'are,' 'you,' 'doing') which serve as input tokens to the model.  Arrows indicate the flow of information:  the model processes the input tokens and generates a new word as output, shown as a single word in a box above the 'Model' box.  Section 1 shows the model receiving 'How' as input and generating 'are' as output. Section 2 shows the model receiving 'How' and 'are' as input and generating 'you' as output. Section 3 shows the model receiving 'How,' 'are,' and 'you' as input and generating 'doing' as output.  The ellipsis (...) indicates that this process continues, with the model progressively generating the sentence word by word, using previously generated words as additional input in subsequent steps.
Figure 25: Incremental generation of text

To optimize the model for correctly predicting the next token, we define a loss function to guide the training process. Cross-entropy loss [24] is a commonly used loss function for the next-token prediction objective. This loss function measures the differences between the predicted probabilities and the correct token. This loss allows the optimizer to update the model's parameters to produce more accurate probabilities in the future.

Image represents a simplified model of a machine learning process, specifically focusing on the prediction and loss calculation.  At the bottom, two input tokens, 'How' and 'are,' feed into a 'Model' (represented as a peach-colored rectangle). The model processes these inputs and outputs a vector of predicted probabilities ('Predicted p...') represented as a column of five numbers: 0.02, 0.11, 0.86, 0.00, and 0.01.  These probabilities correspond to different possible outputs or classes. Simultaneously, a 'Correct...' vector (a column of five 0s and a single 1) represents the ground truth or actual target values.  A 'loss' arrow connects the predicted and correct vectors, indicating that a loss function compares these two vectors to quantify the difference between the model's prediction and the correct answer. This loss value is then used to adjust the model's parameters in subsequent training iterations (not shown in the image).
Figure 26: Loss calculation

In practice, the model processes all token lengths within a sequence in parallel. This allows it to compute the loss for each token position simultaneously. Parallelizing this step speeds up training by handling multiple tokens at once, instead of sequentially.

Image represents a diagram illustrating the training process of a decoder-only Transformer model for text generation.  At the bottom, an 'Input sentence,' 'How are you?', feeds into the model.  The model processes this sentence, represented by the tokens '<BOS>', 'How', 'are', 'you', and '?'. These tokens are input to a horizontally oriented, orange-filled box labeled 'Decoder-only Transformer.'  The transformer processes each token individually, and outputs a set of predicted probability distributions, visually represented as vertically stacked boxes labeled 'Predicted pro...'.  These predictions are compared to the 'Correct tokens' ('How', 'are', 'you', '?', '<EOS>'), also represented as vertically stacked boxes. The difference between the predicted and correct tokens is calculated as a 'loss' for each token, represented by arrows pointing upwards from the predicted tokens to the corresponding correct tokens.  These individual losses are then used to update the weights of the Decoder-only Transformer during the training process, aiming to minimize the difference between predicted and correct token distributions.  The '<BOS>' token represents the beginning of the sentence, and '<EOS>' represents the end of the sentence.
Figure 27: Parallelizing loss computations over different lengths

. Finetuning

Finetuning involves adapting the base model from the pretraining stage to a specific task such as email completion. This stage focuses on making the model proficient at a particular task by training it on a smaller, task-specific dataset. During finetuning, the model retains its language understanding from the pretraining stage but adapts to the nuances of the task.

Finetuning data

We use a dataset of approximately one billion email conversations, as specified in the requirements section. This data includes various email formats, both formal and informal tones, and specific vocabularies that are more common in email conversations.

ML objective and loss function

In the finetuning stage, both the ML objective and loss function remain unchanged. The ML objective is next-token prediction, and the cross-entropy loss function guides the training process. The only difference from the pretraining stage is that the loss is calculated based on email data, focusing on predicting the next token in an email context.

Image represents a simplified system for generating email content.  At the bottom is a rectangular box labeled 'Partial email body' containing the text 'Hi Alex, I hope you a...', representing a fragment of an email's body text. An upward arrow connects this box to a larger, horizontally oriented, light orange box labeled 'Model,' indicating that this partial email body serves as input to the model.  A second upward arrow connects the 'Model' box to a smaller, rectangular box labeled 'work,' suggesting that the model's output is used for work-related tasks. The overall flow depicts a process where a partial email body is fed into a model, which then generates a complete email (implied by the connection to 'work').  The arrangement visually emphasizes the model as the central component processing the input and producing output for a specific task.
Figure 28: Example of email completion

However, relying on the email's body as the sole input is not very effective, because it is not always possible to predict the next token this way. Imagine a user who wants to reply to an email from John. When the user types "Dear," the model should, ideally, suggest "John." However, if that information is not provided as input, the model cannot predict "John" as the likely next token.

To address this limitation, we include more information in the input. For example, we can use the email's subject, the recipient, and previous emails, if available. This adds depth to the context and helps the model make more relevant predictions.

Image represents a simplified architecture diagram of a model, likely a machine learning model used for email processing or generation.  A large, horizontally oriented, light orange rectangle labeled 'Model' sits at the top, representing the core model itself.  Below it are five smaller, vertically oriented, white rectangles, each connected to the 'Model' rectangle via upward-pointing arrows, indicating data flow into the model. These rectangles represent input features to the model: two are labeled 'Email...', suggesting email content as input; one is labeled 'Sender...', indicating sender information as input; one is labeled 'Recipien...', likely representing recipient information; and the last is labeled 'Previous...', possibly representing previous email interactions or context.  The arrows show that the model receives these five types of data as input for processing or prediction.
Figure 29: Providing more context as the input for improved model predictions

Combining various inputs

In traditional ML, the model's architecture typically depends on the type of data it processes. This requires customized preprocessing and feature engineering for different data types like text, images, or tables.

In the era of GenAI, however, the model architecture is often decoupled from the input structure. This decoupling increases flexibility, allowing the same model architecture to handle diverse inputs with a unified architecture, thus streamlining development and enhancing the versatility of GenAI systems. This decoupling is done through techniques like prompt engineering [25]. In Chapter 6, we examine prompt engineering in detail.

Image represents a comparison of traditional Machine Learning (ML) and the Generative AI (GenAI) era.  The left side depicts traditional ML, showing a 'Model' at the top receiving input from multiple 'Features' (1 to N). Each feature is preprocessed individually ('Preprocessing +...') before being fed into the model.  Each preprocessing step receives an 'Input type...' as input.  The right side illustrates the GenAI era, where a 'Model' similarly sits at the top, but its input is a 'Long sequence of tokens.'  This sequence is generated by a 'Prompt Engineering' step, which in turn receives multiple 'Input type...' inputs.  Arrows indicate the flow of data, showing how preprocessed features are combined to feed the model in traditional ML, while in GenAI, multiple inputs are processed through prompt engineering to create a single token sequence for the model.  The overall structure highlights the shift from feature engineering in traditional ML to prompt engineering in the GenAI era.
Figure 30: Combining various inputs in traditional ML vs. GenAI era

To combine various inputs in Gmail Smart Compose, as shown in Figure 31, we combine multiple text inputs into one sequence with tags using a prompt template. We don't need to worry about missing optional fields if our training set includes such examples. The model handles various input combinations regardless of whether they include all details or only partial information. This flexibility demonstrates the model's robust design, allowing it to generate contextually appropriate outputs even with incomplete inputs. By including diverse scenarios in the training data, we ensure the model generalizes well across different input structures and still produces reliable results.

Image represents two rectangular boxes placed side-by-side, labeled 'Example 1' and 'Example 2' respectively, at the bottom.  Each box contains the text 'Inputs:...' centrally positioned, indicating that they represent placeholders for input data.  There are no visible connections or information flow between the two boxes; they are presented independently as two separate examples, likely illustrating different input scenarios or data structures for a system.  The boxes are empty except for the 'Inputs:...' text, suggesting that the specific input details are omitted for illustrative purposes.
Figure 31: Examples of combining text inputs

The benefits of two-stage training

The two-stage training strategy has several benefits, including:

  • Adaptability: The same base model obtained from the pretraining stage can be adapted for different tasks.
  • Improved generalization: Pretraining on large and diverse text data enables the model to develop a broad understanding of language. This helps to generalize better to various tasks.
  • Fast finetuning: The model learns general knowledge during the pretraining stage. This makes the subsequent finetuning process faster.
  • Handling data scarcity: For tasks where large datasets are unavailable, the knowledge gained during pretraining can compensate for this lack of data. This allows the model to perform well even with limited task-specific data.
  • Mitigating overfitting: If we train a model from scratch on a smaller, task-specific dataset, there is a risk it will overfit. In two-stage training, pretraining acts as regularization. The model first learns to understand language broadly before focusing on the specifics of a particular task.
  • Resource optimization: By separating the training process into two stages, we perform the computationally expensive pretraining once and can reuse the same model to adapt to different tasks. This reduces computational costs since we do not need to repeat the pretraining stage for each task.

Sampling

Generative models are trained to capture the underlying distribution of the training data. Once trained, these models can generate new samples that are similar to the data they were trained on. Sampling is the process of using a trained generative model to generate new data.

In the context of Smart Compose, sampling involves generating a likely email completion given the user’s partial email body and other relevant information. As Figure 32 shows, sampling is achieved by generating tokens one at a time. For example, when “Hi Alex, does today” is given to the model, the “work” token is selected as the next token based on the predicted probabilities. Next, “Hi Alex, does today work” is provided to the model as input, and the “for” token is chosen as the next token. This process continues until the model predicts the ⟨\langle⟨EOS⟩\rangle⟩ token.

Image represents a simplified model of text generation, likely for email composition.  A large, horizontally oriented, peach-colored rectangle labeled 'Model' represents the core generative model. Below the model are several white boxes representing input tokens: an unlabeled box signifying initial context, followed by 'Hi,' 'Alex,' ',', 'does,' and 'today,' grouped and labeled 'Partial email body.'  Solid black arrows indicate the flow of these input tokens into the model. Above the model are more white boxes representing output tokens: 'work,' 'for,' 'you,' '?', and '<EOS>', with '<EOS>' signifying the end of the sequence. Dashed black arrows show the model's output tokens flowing upwards.  The arrangement visually depicts the model processing the input ('Initial context...' and 'Partial email body') and generating the output ('work,' 'for,' 'you,' '?', '<EOS>'), suggesting a sequential, left-to-right generation process.
Figure 32: Sampling email completion token by token

There are primarily two types of strategies to generate new text in generative models: deterministic and stochastic. Let's have a look at each.

Deterministic

Deterministic methods generate text in a deterministic way, that is, without randomness or variability in the output. For example, at each step of token generation, the model selects the token with the highest probability from the predicted distribution. This method ensures that the generated text will always be the same for a given input, thus providing consistency and reproducibility. Figure 33 illustrates "greedy search," a simple deterministic method to generate text by iteratively choosing the next token based on the highest predicted probability.

Image represents a directed acyclic graph illustrating word probabilities in a sentence.  A thick horizontal line labeled 'How' connects to a box labeled '0.56' representing the word 'are'.  From '0.56', a thick line labeled 'you' connects to a box labeled '0.91'.  From '0.91', a thick line labeled 'doing' connects to a box labeled '0.39'.  Dashed lines represent weaker connections with associated probabilities.  A dashed line from '0.56' labeled 'am' connects to a box labeled '0.03'. Another dashed line from '0.56' labeled 'dog' connects to a box labeled '0.01'. A dashed line from 'How' labeled 'do' connects to a box labeled '0.26'. A dashed line from 'How' labeled 'come' connects to a box labeled '0.14'. A dashed line from '0.91' labeled 'work' connects to a box labeled '0.001'. A dashed line from '0.91' labeled '?' connects to a box labeled '0.38'.  The boxes contain numerical values, presumably representing probabilities or weights associated with the transitions between words in the sentence.  The graph visually depicts the probabilistic relationships between words, showing stronger connections with thicker lines and higher numerical values.
Figure 33: Greedy search
Pros:
  • Consistency: The generated text is always the same for the same input – a desirable property for systems requiring predictable results.
  • Predictable outputs: Fewer surprising outputs are generated because it always chooses the most probable token at each iteration.
Cons:
  • Lack of diversity: The model may miss less probable but more interesting tokens; thus, there will be less creativity in the generated text. For example, when generating a story, the model always choose the most common phrases, resulting in a predictable but less interesting narrative.
  • Repetitive text: The text may become repetitive, as the same high-probability token is always selected. For example, if the model generates a lengthy article, it might repeatedly use certain phrases. A real example of this is shown in Figure 34.
Image represents a simple text generation system.  At the top is a rectangular box containing the input text prompt: 'I enjoy walking with my cute dog, but I'm not sure if I'll ever...'.  Below this, a vertical arrow points downwards labeled 'Greedy search,' indicating the search method used. This arrow connects to a light peach-colored rectangular box labeled 'GPT-2,' representing the GPT-2 language model used for text generation. The arrow's direction shows that the input prompt is fed into the GPT-2 model via a greedy search algorithm.  The overall structure depicts a straightforward pipeline where the input prompt is processed by the GPT-2 model using a greedy search to generate text, although the generated text itself is not shown in the image.
Figure 34: Text generated by GPT-2 language model using greedy search

Stochastic sampling

Stochastic sampling methods introduce randomness into the generation process. For example, at each step of token generation, the model samples from the predicted distribution based on the probabilities assigned to each token. This means that each time text is generated, even with the same initial inputs, the generated text may vary.

Figure 35 shows two instances of sampling using the same initial token "How." The first time, the sequence of generated tokens leads to "How are you,"; the second time, a different sequence is generated using the same initial token due to the randomness inherent in sampling.

Image represents two examples of stochastic sampling. Each example shows a directed acyclic graph where nodes represent words ('How,' 'are,' 'come,' 'you,' 'am,' 'dog,' 'do') and edges represent probabilities.  The first example displays a 'How' node connected with a thick, solid line to an 'are' node (probability 0.56). From 'are,' a thick solid line connects to a 'you' node (probability 0.91), and a dashed line connects to an 'am' node (probability 0.03).  Dashed lines also connect 'How' to 'come' (probability 0.26) and 'are' to 'do' (probability 0.14), and 'are' to 'dog' (probability 0.01). The second example mirrors the structure of the first, but with different probabilities for the 'come' (0.26) and 'are' (0.56) nodes, and only shows the connections from 'How' to 'come' and 'are' and 'are' to 'do' (0.14).  Both examples are labeled 'Stochastic sampling example 1' and 'Stochastic sampling exampl...' respectively, indicating that they illustrate a concept of probabilistic word selection.
Figure 35: Stochastic sampling randomness
Pros:
  • Diversity: The presence of randomness allows for more varied outputs, which is particularly useful in applications such as dialogue generation.
  • Novelty: By sampling from the distribution, the model can explore less probable but potentially more interesting tokens, thus resulting in creativity and novel outputs.
Cons:
  • Inconsistency: The output may vary each time a text is generated. This is less suitable for applications that require precise, repeatable results.
  • Unexpected outputs: The randomness can lead to unexpected variations in the generated text, which might be inappropriate.

Which generation method is suitable for the Smart Compose feature?

For Smart Compose, deterministic methods are preferred for several reasons:

  • Consistency: Consistency in generated text is crucial for applications such as email completion, for which users expect predictable and reliable suggestions. Utilizing a deterministic method means that users won't see dramatically different suggestions each time they begin to type the same thing.
  • Better handling of common phrases: Deterministic methods are typically preferred in an email context, as more likely completions are prioritized over the novelty that stochastic methods offer.
  • Reduced risk of inappropriate suggestions: Stochastic methods might occasionally generate inappropriate suggestions due to their inherent randomness. This behavior is not desired in an email completion feature.

These reasons highlight why deterministic methods are preferred in applications requiring consistency such as email completion. Now that we have chosen deterministic text generation, let's examine two primary algorithms:

  • Greedy search
  • Beam search

Greedy search is the simplest deterministic algorithm. It always selects the token with the highest probability as the next token. As was shown in Figure 34, greedy search can lead to repetitive patterns in the generated text. This occurs because it follows a narrow path based on the highest probability tokens without considering alternative paths that might lead to more coherent sentences. Due to this limitation, greedy search is rarely used in practice.

Beam search [26] is a popular deterministic algorithm for generating text from a trained model. The core idea is to track multiple potential sequences of tokens simultaneously. At each step, the model calculates the probabilities for the next possible tokens for each sequence and selects the "top-k" most probable sequences. The value of k, known as beam width, is configurable.

Image represents a probabilistic context-free grammar (PCFG) tree illustrating word probabilities in a sentence.  A central node labeled 'How' branches into three main paths, each representing a different word choice: 'come,' 'are,' and 'do.'  These words connect with probabilities (0.24, 0.31, and 0.26 respectively) to subsequent nodes. Each of these nodes further branches out to other words with associated probabilities, indicated by dashed lines. For example, the 'are' node connects to 'plants' (0.21), 'animals' (0.36), and 'you' (0.91) with their respective probabilities. Similarly, the 'come' node connects to 'are' (0.001) with a probability. The 'do' node connects to 'you' (0.63), 'the' (0.001), and 'people' (0.21).  The 'are' node also connects to 'am' (0.03) and 'dog' (0.01).  The probabilities on the branches represent the likelihood of each word following the preceding word in the sentence, forming a probabilistic model of sentence structure.  The thicker lines represent higher probability connections.
Figure 36: Beam search calculating the top three most probable sequences (beam width=3 )

Here is a brief step-by-step process for generating text using beam search assuming a beam width of 3:

  • Initialization: Start with the user's partial email as the input to the trained model. The model predicts the probability distribution for the next token. Beam search selects the top three tokens with the highest probabilities.
  • Expansion: For each top three sequence, pass it to the model and obtain the probabilities of the next token.
  • Pruning: Select the top three sequences based on their cumulative probabilities.
Image represents a three-stage process visualized as directed graphs, illustrating the evolution of a probabilistic language model.  The first stage, 'Initialization,' shows a simple tree with a central node 'How' connected to 'are' (with weight 0.31) and 'do' (with weight 0.26), and 'come' (with weight 0.24).  The second stage, 'Expansion,' expands upon the previous structure.  The 'are' node now connects to 'am' (0.03), 'dog' (0.01), 'you' (0.91), and the 'come' node connects to 'plants' (0.21) and 'animals' (0.36).  The 'do' node connects to 'the' (0.001) and 'people' (0.21).  All connections are represented by dashed lines with associated weights.  The third stage, 'Pruning,' simplifies the graph from stage two.  Less probable connections are removed, resulting in a graph where 'How' connects to 'are' (0.31), 'come' (0.24), and 'do' (0.26).  'Are' connects to 'you' (0.91), and 'do' connects to 'you' (0.63).  'Come' connects to 'animals' (0.36).  The weights represent the probabilities of the connections, with thicker lines in the first and third stages indicating stronger connections.  The overall image demonstrates a process of building and refining a probabilistic model, likely for natural language processing.
Figure 37: First iteration of a beam search with beam width=3

The expansion and pruning steps are repeated until all three potential sentences reach the ⟨\langle⟨EOS⟩\rangle⟩ token or a maximum length. Once the beam search algorithm has stopped, we select the sequence with the highest cumulative probability as the output.

Beam search is effective in practice since it tracks several potential sequences simultaneously instead of the most probable sequence. However, beam search has two main drawbacks:

  • Limited diversity: Beam search often leads to similar outputs, which is not ideal for applications requiring diverse responses.
  • Struggle with long sequences: Beam search struggles with longer sequences because tracking too many sequences simultaneously can become computationally expensive.

The suggestions made by the Smart Compose feature are typically short; hence, capturing long-range dependencies is less critical. In addition, diversity in the email completions is not desired. For these reasons, we choose beam search as the primary sampling algorithm for generating suggestions.

Evaluation

Evaluation is essential in ML system design interviews. Interviewers will check if candidates can effectively test and validate the ML system they design. An ideal answer should cover both online and offline evaluations and discuss popular metrics for measuring a model's performance in each setting.

Let's explore some common metrics for evaluating the Smart Compose feature.

Offline evaluation metrics

Offline evaluation uses pre-collected and historical data to evaluate a model's performance. Its purpose is to ensure the model's performance is acceptable before deploying it to production. For example, we test a recommendation system on historical user interaction data to see how well it predicts user preferences. Similarly, we evaluate the performance of our trained model for the Smart Compose feature using historical email data. Two commonly used metrics are:

  • Perplexity
  • ExactMatch@N

Perplexity

Perplexity [27] is a standard metric used extensively in the offline evaluation of language models. This metric measures how accurately the model predicts the exact sequence of tokens present in text data. In mathematical terms, perplexity is defined as the exponential of the average "negative log-likelihood" of the predicted probability given the previous tokens in a sequence:

Image represents a mathematical formula for calculating Perplexity, labeled 'Perplexity(X)' on the left side. The formula is set equal to the exponential function, denoted by 'exp'. Inside the parentheses of the exponential function, there is a negative sign followed by a fraction '1/N', where N is an uppercase letter. This fraction is multiplied by a summation from i=1 to N. The term being summed is 'log P(x_i | x_{1:i-1})', which represents the logarithm of the conditional probability of the i-th element x_i given the preceding elements from x_1 to x_{i-1}. The entire sum multiplied by -1/N is the negative average log-likelihood of the sequence X. Therefore, the formula calculates the perplexity of a sequence X as the exponential of the negative average log-likelihood of that sequence according to a probability model P.

In this equation:

  • XXX is a tokenized sequence (x1,x2,⋯ ,xN)\left(x_1, x_2, \cdots, x_N\right)(x1​,x2​,⋯,xN​) in the text data that is used to evaluate how accurately the model predicts the sequence.
  • NNN is the number of tokens in the sequence.
  • P(xi∣x1:i−1)P\left(x_i \mid x_{1: i-1}\right)P(xi​∣x1:i−1​) is the conditional probability of the iii-th token given the preceding tokens, x1:i−1x_{1: i-1}x1:i−1​, that is, how likely the model is to predict the iii-th token given the previous tokens.

Figure 38 illustrates a concrete example to better understand perplexity.

The image is completely black and contains no visible components, arrangement, connections, or information flow.  Therefore, no description of its structure or interaction between components is possible.
Figure 38: Example of perplexity calculation

A lower perplexity value indicates that the model has assigned higher probabilities, on average, to the tokens that appear in the text data. Therefore, a lower perplexity means the model is better at predicting the next tokens.

ExactMatch@N

ExactMatch@N measures the percentage of generated phrases that are exactly N words long and that match the first N words of the ground-truth text. Figure 39 shows ExactMatch@3 calculations for three generated sequences. In practice, there are usually more than three sequences to evaluate.

Image represents a diagram illustrating a model's performance evaluation. Three input sentences ('Hi Jessica, what...', 'It was nice', 'I hope you') are fed into three separate instances of a 'Model,' each producing a prediction ('was our appointment,' 'meeting you today,' 'are doing well,' respectively).  These predictions are then compared to corresponding 'ground-truth' statements ('was our appointment today?', 'seeing you today', 'are doing well') in a separate column.  A final column, 'ExactMatch@3?', indicates whether each prediction exactly matches its ground truth (Yes or No).  Finally, at the bottom, the overall ExactMatch@3 score is calculated as 2/3 = 0.66, representing the proportion of exact matches out of the three input sentences.  The diagram visually shows the flow of information from input sentences through the model, to predictions, comparison with ground truth, and finally to the overall accuracy metric.
Figure 39: Example of calculating ExactMatch@3 for three sequences

Calculating ExactMatch@N for different values of N allows us to measure how the model performs at different suggestion lengths. To measure the overall performance of the model, we calculate the ExactMatch for all lengths up to a specific length and then take the average.

While Perplexity and ExactMatch@N have traditionally been used to evaluate Gmail Smart Compose, other metrics such as BLEU score and ROUGE-N, introduced more recently, have been found to be helpful. We examine these metrics in more detail in Chapter 3.

Online evaluation metrics

Online evaluation measures how a model performs in real time as users interact with the system. To evaluate the Smart Compose feature in an online environment, we use additional metrics beyond Perplexity and ExactMatch@N. These online metrics measure user engagement, the model's latency, and the overall impact on user experience.

Unlike offline metrics, which are usually standard, online evaluation metrics are defined based on specific requirements and needs. Companies often use hundreds of metrics for online evaluation. However, in an interview setting, we typically discuss the most common ones. In this section, we focus on the following metrics:

  • User engagement metrics
  • Effectiveness metrics
  • Latency metrics
  • Quality metrics

User engagement metrics

  • Acceptance rate: The percentage of suggestions made by the Smart Compose feature that are accepted by users. A higher acceptance rate indicates that the suggestions are relevant and useful to users.
  • Usage rate: The percentage of all composed emails that have utilized the Smart Compose feature. High usage rates typically indicate that users trust the feature.

Effectiveness metrics

  • Average completion time: Tracks the average time taken by users to compose emails with and without the aid of Smart Compose. A reduced average completion time using Smart Compose will indicate that the feature is speeding up the email writing process.

Latency metrics

  • System response time: Measures the time it takes for the Smart Compose suggestions to appear after the user begins typing. It's important to ensure this metric stays below a certain threshold so the suggestions are made before the user types them.

Quality metrics

  • Feedback rate: Measures the rate at which users provide feedback on the suggestions. Feedback is helpful for continuous improvement of the system.
  • Human evaluation: Qualitative assessments through user studies are employed to evaluate the usefulness of suggestions. This metric reflects user satisfaction with the Smart Compose feature.

These online metrics are essential for evaluating how well Smart Compose feature works in production. By monitoring these metrics, the stakeholders can obtain a holistic view of feature's performance.

Overall ML System Design

In this section, we propose a design for a simplified Smart Compose feature.

When designing such a feature, we should consider more than just the underlying model that predicts the next token. The system's effectiveness depends on various components working together to ensure the system is responsive, generates relevant suggestions, and maintains ethical standards. For the Smart Compose feature, we examine the following key components:

  • Triggering service
  • Phrase generator
  • Post-processing service

Let's explore each in more detail.

Triggering service

The triggering service activates the Smart Compose feature by monitoring user activity such as keystrokes. It decides when to activate the feature based on criteria such as the number of characters typed or the entering of specific keywords in the text. For example, if a user types "I," the service might not activate Smart Compose because it's too early to predict the user's intent. However, if the user types "I hope," the service will activate Smart Compose, as the additional context allows for more useful suggestions.

The triggering service ensures suggestions are not too frequent. Once the service determines that activating the Smart Compose feature will be useful, it triggers the phrase generator component, which we discuss next.

Phrase generator

The phrase generator is the core of the Smart Compose feature. It generates the most likely completion based on the partial text the user has already typed.

To achieve this, the phrase generator interacts with the trained model and employs beam search to generate the top-k most probable completions. Each completion ends with the ⟨\langle⟨EOS⟩\rangle⟩ token and an associated score that indicates how confident the model is about the completion.

Image represents a text generation system.  A rectangular box labeled 'Input text' containing the text '[Text] Hi Petra, it was...' feeds into a purple rectangular box labeled 'Phrase Generator.'  An arrow indicates this data flow. The 'Phrase Generator' then sends its output to a language model represented by a cloud labeled 'Model' via a process called 'Beam search,' indicated by an upward arrow. The model processes the input and returns a table of 'Top-5 completions' and their corresponding 'Score.'  The table lists five different text completions ('nice seeing you!', 'nice meeting you!', 'a pleasure to discuss th...', 'last Friday! Hopefully y...', 'good.') with associated numerical scores (0.28, 0.22, 0.13, 0.06, and 0.05 respectively), suggesting a ranking based on probability or relevance.  The arrow from the 'Phrase Generator' to the table shows the flow of generated text to the scoring and ranking system.
Figure 40: Beam search outputs top five potential completions (beam width = 5)

Given the possible completions, two critical considerations are necessary:

  • Removing long suggestions
  • Removing low-confidence suggestions

Removing long suggestions

As shorter suggestions are easier for the author to read as they are typing, we remove suggested phrases that are too long. For example, if a user types "Can you please," the phrase generator might suggest "help me with this?" Longer suggestions, such as "help me with this project that is due next week," will be too specific and, therefore, less likely to predict what the author intends to write.

Image represents a diagram illustrating a text generation process and its re-ranking.  The diagram shows two tables, each with 'Top-5 completions' and 'Score' columns, flanking a central rectangular box labeled 'Long-sequence...'. The left table lists five text completions ('nice seeing you!', 'nice meeting you!', 'pleasure to discuss t...', 'last Friday! Hopefull...', 'good.') with associated scores (0.28, 0.22, 0.13, 0.06, 0.05 respectively).  A black arrow points from this table to the 'Long-sequence...' box, indicating that these completions are input to a longer sequence generation process. The right table also displays 'Top-5 completions' and 'Score' columns, but the completions are re-ordered.  Red lines connect the completions in the left table to their corresponding positions in the right table, showing how the ranking has changed after the 'Long-sequence...' process.  The scores in the right table remain the same as in the left table, indicating that the re-ranking doesn't alter the individual completion scores, only their relative positions within the top-5.  The 'Long-sequence...' box likely represents a model or process that considers the context of a longer sequence to refine the ranking of the initial completions.
Figure 41: Removing long suggestions

Removing low-confidence suggestions

We remove suggestions with confidence scores below a certain threshold. This ensures we do not present suggestions if the model is not confident enough about it.

Image represents a process illustrating a low-confidence scenario in a text generation system.  The diagram shows two identical tables on either side of a central rectangular box labeled 'Low-confidence...'. Each table has two columns: 'Top-5 completions' and 'Score'. The left table displays three text completions ('nice seeing you!', 'nice meeting you!', 'good.') with corresponding scores (0.28, 0.22, 0.05 respectively).  A unidirectional arrow connects this table to the 'Low-confidence...' box, indicating that the table's data is input to the box. The 'Low-confidence...' box represents a stage where the system assesses the confidence level of the generated text.  Another unidirectional arrow connects the 'Low-confidence...' box to the right table. The right table is identical in structure to the left table, but the scores are altered.  Red lines connect the scores in the right table to different completions in the left table, showing a re-ranking or re-scoring of the completions after the low-confidence assessment.  Specifically, the score of 'good.' is increased, while the scores of 'nice seeing you!' and 'nice meeting you!' are decreased, suggesting a change in the system's confidence in the initial rankings.
Figure 42: Removing low-confidence suggestions

Finally, if the final list of suggestions is not empty, the phrase generator will pass the one with the highest confidence score to the post-processing service.

Post-processing service

The post-processing service addresses potential biases before suggestions are presented to the user. This component follows predefined rules to detect and correct bias efficiently. Common strategies to achieve this include:

  • Pronoun replacement: Replace gender-specific pronouns to ensure neutrality. For example, "he" or "she" might be replaced with "they" in contexts where gender is not specified.
  • Gender-neutral word replacement: Replace gendered words with gender-neutral alternatives where appropriate. This includes changing words like "chairman" to "chairperson" or "policeman" to "police officer."
  • Lexical analysis for sensitive terms: Use a predefined list of flagged terms that, if identified, can be replaced with neutral alternatives. For example, terms that might imply age, race, or disability biases are adjusted to ensure the suggestions will be perceived as respectful and neutral.
  • NSFW (Not Safe For Work) content filtering: Implement automated filters that scan for and flag explicit language. These filters use predefined lists of NSFW keywords, phrases, and patterns to detect and remove problematic content.

By implementing these rules, the post-processing service maintains ethical standards in the Smart Compose feature, thus ensuring that the suggestions provided are relevant, respectful, and inclusive.

Image represents a flowchart illustrating a generative AI system's response generation process.  The process begins with an input message ('Subject: Thanks\nHi Xue,...') which is processed by a 'Triggering...' block (1). This block's output feeds into a 'Phrase...' block (2), which in turn interacts with a 'Model' (a cloud-shaped component representing the underlying AI model) via a 'Beam search' (3) process. The 'Beam search' refines the output from the 'Phrase...' block, potentially addressing issues of length or confidence, as indicated by the 'Long and Low-confidence...' block (4) which receives feedback from the process. The refined output from the 'Phrase...' block then proceeds to a 'Post...' block (5) before finally generating the output message ('Subject: Thanks!\nHi Xue,...') (6).  The numbered circles (1-6) indicate the sequential flow of information between the blocks.  The system appears designed to generate a response to an input message, potentially improving the quality and conciseness of the response through iterative refinement using the model and beam search.
Figure 43: Smart Compose feature overall design

Here is a brief step-by-step workflow of the overall ML system employed by the Smart Compose feature:

  • Monitoring: The triggering service monitors the user's activity as they type.
  • Triggerring: The service triggers the phrase generator once it identifies specific patterns.
  • Beam search: The phrase generator employs beam search to get top-k potential completions from the trained model.
  • Filtering: The phrase generator interacts with the filtering component to remove long suggestions and those with low confidence scores.
  • Post-processing: The completion with the highest score is picked and passed to the post-processing service. The service replaces gender-specific pronouns and adjusts sensitive terms.
  • Display suggestion: The suggestion is displayed to the user for their consideration.

Other Talking Points

If there's extra time at the end of the interview, you may face follow-up questions or be asked to discuss advanced topics. This depends on factors such as the interviewer's preference, your expertise, and the requirements of the role. For senior roles, here are some topics you should prepare for:

  • Supporting Smart Compose in multiple languages [28].
  • Personalizing suggestions [28].
  • Incorporating additional context for better predictions [28].
  • Understanding how different tokenization algorithms work, such as BPE [11], SentencePiece [12], and WordPiece [29].
  • Understanding different ML objectives such as masked language modeling (MLM) and its variations [18].
  • The multi-token prediction objective and its pros and cons [30].
  • Balancing quality and inference latency [28].

Summary

Image represents a mind map summarizing the key aspects of generative AI system design.  The central node is labeled 'Summary,' branching out into seven main categories represented by differently colored lines:  'Clarifying requirements,' 'Framing as ML,' 'Data preparation,' 'Model development,' 'Evaluation,' 'Overall system components,' and 'Other talking points.'  'Model development' further branches into 'Architecture,' 'Training,' and 'Sampling,' each with multiple sub-branches.  'Architecture' details choices like 'Transformer,' 'Encoder-only,' 'Decoder-only,' and 'Encoder-decoder,' along with 'Text embedding' and 'Positional encoding' options. 'Training' includes 'Pretraining' and 'Finetuning,' while 'Sampling' offers 'Deterministic' and 'Stochastic' methods, including 'Greedy search' and 'Beam search.' 'Evaluation' is divided into 'Offline' metrics like 'Perplexity' and 'Exact Match@N,' and 'Online' metrics such as 'User engagement,' 'Effectiveness,' 'Latency,' and 'Quality,' with sub-metrics like 'Acceptance rate,' 'Average completion time,' and 'Human evaluation.'  'Overall system components' includes 'Triggering service,' 'Phrase generator,' and 'Post-processing service.'  Finally, 'Clarifying requirements' and 'Framing as ML' detail initial considerations like specifying input/output and choosing between RNNs and Transformers, while 'Data preparation' covers text cleaning, normalization, and tokenization methods including character, word, and subword levels (with examples like Byte-Pair Encoding, SentencePiece, and WordPiece).

Reference Material

[1] Gmail's Smart Compose feature. https://research.google/pubs/gmail-smart-compose-real-time-assisted-writing/. [2] Fundamentals of Recurrent Neural Network. https://arxiv.org/abs/1808.03314. [3] Attention Is All You Need. https://arxiv.org/abs/1706.03762. [4] Gated recurrent unit. https://en.wikipedia.org/wiki/Gated_recurrent_unit. [5] Long Short-Term Memory. https://deeplearning.cs.cmu.edu/F23/document/readings/LSTM.pdf. [6] RITA: Group Attention is All You Need for Timeseries Analytics. https://arxiv.org/abs/2306.01926. [7] FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. https://arxiv.org/abs/2205.14135. [8] Language identification. https://en.wikipedia.org/wiki/Language_identification. [9] FastText model for language identification. https://huggingface.co/facebook/fasttext-language-identification. [10] Transformer-XL. https://arxiv.org/abs/1901.02860. [11] Byte-Pair Encoding tokenization. https://huggingface.co/learn/nlp-course/en/chapter6/5. [12] SentencePiece tokenization. https://arxiv.org/abs/1808.06226. [13] Tiktoken library. https://github.com/openai/tiktoken. [14] Google's Gemini. https://gemini.google.com/. [15] SentencePiece library. https://github.com/google/sentencepiece. [16] Summary of tokenizers. https://huggingface.co/docs/transformers/en/tokenizer_summary. [17] OpenAI's tokenizers. https://tiktokenizer.vercel.app/?model=gpt-4-1106-preview. [18] BERT. https://arxiv.org/abs/1810.04805. [19] OpenAI's models. https://platform.openai.com/docs/models. [20] Meta's LLaMA. https://llama.meta.com/. [21] Introduction to Transformers by Andrej Karpathy. https://www.youtube.com/watch?v=XfpMkf4rD6E. [22] Transformer visualized. https://jalammar.github.io/illustrated-transformer/. [23] Common Crawl. https://commoncrawl.org/. [24] Cross-entropy. https://en.wikipedia.org/wiki/Cross-entropy. [25] Prompt engineering. https://platform.openai.com/docs/guides/prompt-engineering. [26] Beam search. https://en.wikipedia.org/wiki/Beam_search. [27] Perplexity. https://en.wikipedia.org/wiki/Perplexity. [28] Gmail Smart Compose: Real-Time Assisted Writing. https://arxiv.org/abs/1906.00080. [29] WordPiece tokenization. https://huggingface.co/learn/nlp-course/en/chapter6/6. [30] Better & Faster Large Language Models via Multi-token Prediction. https://arxiv.org/abs/2404.19737.

Footnotes

  • Visit https://platform.openai.com/tokenizer to see examples of different tokenizers. ↩
Chapter 3

Google Translate

~26 min read

Introduction

Google Translate is a widely used language translation service offered by Google. The service relies on machine learning (ML) models to understand and translate text between languages. As of 2024, the service supports over 130 different languages and has over a billion users [1]. This chapter explores the system design behind a language translation service.

Image represents a user interface showcasing a language detection and translation feature.  Two rectangular boxes are displayed side-by-side. The left box shows a text input area containing the English phrase 'Beautiful day!' along with a microphone icon suggesting voice input capability.  Above this box, a dropdown menu labeled 'Detect lang...' displays 'English' as the selected option with 'Spanish' also available.  A counter '14/5,...' is visible at the bottom, possibly indicating progress or a character limit. The right box displays the Korean translation '아름다운 날!'  Above this box, a similar dropdown menu labeled 'Korean' shows 'Spanish' and 'Russian' as additional options.  At the bottom of the right box, a button labeled 'Send Feedb.' suggests a feedback submission mechanism.  There is no explicit visual connection between the boxes, but the implied interaction is that the input text in the left box is translated into the selected language in the right box.
Figure 1: Language translation service

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: Are there specific languages the system should support initially? Interviewer: Let's focus on four languages: English, Spanish, Korean, and French. We can expand to more languages in the future.

Candidate: Considering the diversity of languages, do we have access to a sufficiently large and varied dataset for training? Interviewer: Yes. We have access to a substantial multilingual corpus, including formal documents, web content, and conversational texts, in all four languages. The dataset contains 300 million examples, an example being defined as a pair of sentences in the source and target languages.

Candidate: Do we have access to general text data? This is important, as it would allow us to pretrain a model on general text data and, thus, allow it to gain general knowledge. Interviewer: Assume we have access to terabytes of general text data in each of the languages, obtained from various sources.

Candidate: Will users specify the input text language, or should the system detect it automatically? Interviewer: Users cannot always identify a text’s language. Imagine a book title in a language with which the user is not familiar. Our system should detect the input language automatically.

Candidate: Is there a constraint on the length of the input text? Interviewer: Let’s build the system in such a way that it can support inputs of up to 1,000 words.

Candidate: Should the system support translation when there is no internet connection? In other words, should the model work on-device? Interviewer: The focus of this interview is not efficiency and model optimization for on-device deployment. Let’s assume an internet connection is required and that the model will be deployed on the cloud.

Candidate: Should the system support real-time translation? Interviewer: Not initially.

Frame the Problem as an ML Task

In this section, we frame the problem of building a translation system as an ML task. This involves understanding the system’s inputs and outputs and choosing a suitable ML approach.

Specifying the system’s input and output

The input to a translation system is a sequence of words in the source language and the target language provided by the user. The output is a sequence of words in the target language.

Image represents a simplified model of a machine translation system.  The input, labeled 'Source s...', feeds the phrase 'A beautiful day' into a central rectangular box labeled 'Language Translation...'.  A second input, labeled 'Desired language', provides the target language, 'Spanish'.  Both inputs are connected to the 'Language Translation...' box, indicating that both the source text and target language are necessary for the translation process. The 'Language Translation...' box processes the input and outputs the translated phrase 'Un día hermoso', labeled 'Translated sentence...'. The arrows indicate the flow of information, showing how the source sentence is transformed into the target language based on the specified desired language.
Figure 2: Input and output of a translation system

Choosing a suitable ML approach

In language translation, a sequence of words in one language is transformed into a sequence of words in another language. This sequence-to-sequence (seq2seq) structure is also found in other tasks, such as text summarization and speech recognition.

Seq2seq models, a class of ML models, are specifically designed to handle such tasks. These models transform an input sequence into an output sequence, which can vary in length from the input. Seq2seq models follow an encoder-decoder architecture, which has two main components:

  • Encoder: Processes the input sequence and transforms it into a sequence of context vectors, thus encoding the information in the input sequence.
  • Decoder: Utilizes the encoder’s context vectors to generate the output sequence one token at a time.
Image represents a simplified diagram of a neural machine translation (NMT) system.  The system consists of two main components: an Encoder (represented by a light green rectangle labeled 'Encoder') and a Decoder (represented by a light orange rectangle labeled 'Decoder').  An arrow indicates that the Encoder's output feeds directly into the Decoder.  The Encoder receives as input the English phrase 'I am graduating' (enclosed in a dashed-line box labeled 'English:'), processing it to create an internal representation. This representation is then passed to the Decoder. The Decoder generates the Spanish translation 'me estoy graduando' (enclosed in a dashed-line box labeled 'Spanish:'), which is shown as an output arrow pointing upwards from the Decoder.  The entire diagram illustrates the flow of information from English input through the Encoder and Decoder to produce a Spanish output, demonstrating a basic sequence-to-sequence model for machine translation.
Figure 3: Encoder-decoder model for English-to-Spanish translation

There are several architectures available for the encoder and decoder components. In particular, architectures designed to process sequential data, such as LSTMs, GRUs, and Transformers, can be employed. Among those, Transformers have shown superior performance in translation tasks, outperforming earlier models such as GRUs and LSTMs, particularly in handling long-range dependencies. Notably, the attention mechanism was originally introduced in the context of language translation [2].

As described in Chapter 2, Transformers have three variations: encoder-only, decoder-only, and encoder-decoder architecture. Encoder-only models such as BERT [3] are good at understanding and processing the input sequence but typically require additional mechanisms to generate output. Decoder-only models, such as OpenAI’s GPT [4] and Anthropic’s Claude [5], are highly effective at generative tasks.

While all three architectures offer strong performance and can be adapted for language translation tasks through techniques like prompt engineering, encoder-decoder models are usually preferred for three main reasons. First, the encoder-decoder architecture separates the input understanding and output generation, which is ideal for seq2seq tasks such as language translation. It allows the encoder to specialize in the source language and fully understand the input sequence before the decoder generates the output. For example, encoders often use bidirectional mechanisms, such as bidirectional LSTMs [6] or Transformers, which enable them to understand the context from both directions.

Second, this architecture naturally handles variable-length sequences. Encoder-decoder models are designed to accommodate input/output sequences of varying lengths, making them highly versatile across different applications. This flexibility is crucial for tasks where inputs and outputs do not have a fixed length relationship.

Finally, the cross-attention mechanism present in encoder-decoder Transformers enables the decoder to focus dynamically on relevant parts of the input sequence during generation. This targeted attention ensures that the output sequence remains closely aligned with important elements of the source sequence, thus improving the accuracy and quality of the translation. We will explore cross-attention in greater detail in the architecture section.

Data Preparation

In this section, we prepare raw textual data for the encoder-decoder Transformer. We have two types of data for training: general data and translation data. General data includes publicly available text from the Internet. Translation data comprises 300 million sentence pairs, each containing a source-language sentence and its corresponding translation in the target language.

Raw text in both general data and translation data is often noisy and not in the format the ML model expects. Since we covered preparing general data in Chapter 2, we will focus on preparing translation data. In particular, we focus on the following two steps:

  • Text preprocessing
  • Text tokenization

Text preprocessing

We apply the following preprocessing techniques to raw text in translation data:

  • Remove missing data: Remove pairs where either the source or target text is missing.
  • Remove noisy data: Remove pairs with HTML tags or incorrect language pairings.
  • Deduplication: Remove duplicate sentence pairs from the dataset to prevent the model from overfitting to certain examples.
  • Handle named entities: Language translation models often struggle with named entities. We identify these entities in the text and replace them with placeholder tokens. After translation, we replace the tokens with the original entities. For example, consider the sentence: "The California city, Burlingame, is named after diplomat Anson Burlingame." First, we detect the named entities: "California (location name),” “Burlingame (location name)," and "Anson Burlingame (person’s name)." Next, we replace these entities with placeholder tokens: "The ENTITY_1 city, ENTITY_2, is named after diplomat ENTITY_3." This approach helps the model focus on the sentence context during training without being confused by uncommon terms.

In modern language translation, particularly with models like Transformers, some traditional preprocessing steps have become less crucial or are handled differently. Here are a few preprocessing steps that were once essential in traditional translation models but are now unnecessary or less relevant:

  • Lowercasing: Modern language translation models can handle case sensitivity as part of their training. They can learn to distinguish between different forms of words based on case (e.g., “Apple” as a company vs. “apple” as a fruit) without needing to convert everything to lowercase. Therefore, lowercasing is often skipped to preserve the original case information.
  • Stop word removal: Stop words (e.g., “the,” “and,” “in”) are essential for the grammatical structure of sentences. Removing them can disrupt the fluency and meaning of translations. Modern language translation models benefit from having complete sentences, including stop words, to understand the context fully and produce more natural translations.
  • Stemming and lemmatization: Stemming (reducing words to their base or root forms) and lemmatization (reducing words to their dictionary forms) are not typically needed in modern language translation because these models are designed to handle morphological variations of words. The models learn to translate words into their correct forms based on context; therefore, reducing them to a base form could actually remove valuable information.
  • Punctuation removal: Punctuation is important for understanding sentence structure and meaning. Modern language translation models are trained to handle punctuation naturally; thus, removing it can degrade translation quality. Punctuation is usually preserved to help the model maintain the grammatical integrity of sentences.

Text tokenization

In the context of language translation in which we deal with several languages, the choice of text tokenization algorithm is important. For example, if we were to choose a word-level tokenizer, we would have hundreds of thousands of unique words across all languages in our vocabulary, which is huge and inefficient.

Image represents a word-level vocabulary table used in a natural language processing (NLP) system.  The table is structured as a two-column grid. The left column, labeled 'Token,' lists individual words or special tokens.  These include '<BOS>' (Begin of Sentence) and '<EOS>' (End of Sentence), representing sentence boundaries, along with example words like 'walking,' 'bonjour,' 'hello,' and 'fantastique.' The right column, labeled 'ID,' assigns a unique numerical identifier (integer) to each token.  The IDs start from 0 and increment sequentially.  The ellipses ('...') indicate that the table continues beyond the visible portion, implying a larger vocabulary with many more word-ID pairs.  The table's title, 'Word-level Vocabulary,' clearly indicates its purpose as a mapping between words and their numerical representations, essential for processing text data in NLP models.
Figure 4: A huge vocabulary size due to word-level tokenization

In language translation, handling the diversity of words across languages is a key challenge. Traditional word-level tokenization models often struggle with out-of-vocabulary (OOV) words, while subword-level tokenization algorithms are more efficient and can effectively address the OOV problem. Due to their importance and widespread use, it is valuable to examine Byte-Pair Encoding (BPE) [7], a commonly used subword-level tokenization algorithm, in detail.

Byte-Pair Encoding (BPE)

BPE builds a subword-level vocabulary through iterative merging. It starts with characters and iteratively merges the most frequent combinations into new subwords. This allows the model to break down words, even rare or unseen ones, into known components, thus enabling accurate understanding and translation. Let’s walk through a concrete example to better understand BPE.

Initial setup

Suppose we have a corpus with the following set of words: “cat,” “cats,” “dog,” and “dogs.”

Image represents a data processing pipeline where a corpus (represented as a beige cylindrical database) is processed to generate a word frequency table.  A unidirectional arrow indicates data flow from the 'Corpus' database to a table with two columns: 'Word' and 'Frequency'. The 'Word' column lists individual words ('cat', 'cats', 'dog', 'dogs'), while the 'Frequency' column shows the corresponding count of each word's occurrences within the corpus.  The table visually presents the results of analyzing the text data contained within the corpus, summarizing the frequency of each word.
Figure 5: Frequency of words in our corpus

In the initial setup, our goal is to initialize a vocabulary consisting of different characters and their frequency of occurrence in the corpus. To achieve this, we follow these steps:

  • Add a special end token, “</w>,” to the end of each word to mark its boundary. This special token helps the model know when a word has ended.
  • Tokenize the corpus by breaking down each word into individual characters.
  • Initialize the vocabulary with individual characters and their frequency of occurrence.
Image represents a three-step process of creating an initial vocabulary from a word frequency table.  The first table lists words ('cat,' 'cats,' 'dog,' 'dogs') and their frequencies (5, 3, 6, 4 respectively).  A numbered arrow (1) points from this table to a second table, where each word is now tagged with '</w>' (e.g., 'cat</w>'), indicating a word token, and frequencies remain the same.  A second numbered arrow (2) connects this table to a third table, which lists the character sequences of each word-token (e.g., 'cat</w>') and their frequencies.  Finally, a third numbered arrow (3) connects the character sequence table to a final table labeled 'Initial vocabulary,' which shows each unique character ('c,' 'a,' 't,' 's,' 'd,' 'o,' 'g,' '</w>') and its overall frequency across all word-tokens.  The frequencies in the final table represent the total count of each character in the initial word list.
Figure 6: Initial setup steps
Iterative merging

Once the initial vocabulary has been created, BPE iteratively merges the most frequent character pairs into subwords. This continues until the vocabulary reaches a predefined size or meets the stopping criteria.

Following are the first five BPE iterations:

  • Iteration 1: We first identify the most frequent character pair, which is "d" and "o," appearing together 10 times (in "dog" and "dogs"). We merge them to create a new token, "do." Although "og" also appears 10 times, "do" comes first alphabetically. The token "do" is added to the vocabulary, and the frequency counts are updated. "do" now occurs 10 times, and the individual counts of "d" and "o" are reduced accordingly. Figure 7: BPE iteration 1
  • Iteration 2: Now we look for the next most frequent pair, which is “do” and “g” (also from “dog” and “dogs”). These characters appear together 10 times, so we merge them to create the token “dog.”
Image represents a table showing token frequency.  The table has three columns: '#' (a numerical index), 'Token' (a character or word), and 'Frequency' (the count of occurrences).  Rows 0-3 list individual characters ('c', 'a', 't', 's') with frequencies of 8, 8, 8, and 7 respectively. Row 6 shows 'g' with a frequency calculated as '10-10=0'. Row 7 displays the token '</w>' with a frequency of 18. Row 8 shows 'do' with a frequency calculated as '10-10=0'. Finally, row 9 shows the token 'dog' with a frequency of 10. Two curved arrows indicate a cyclical or iterative process, suggesting the data might be processed repeatedly or represent a sequence of steps.  The table likely represents a step in a natural language processing or text analysis process, possibly related to tokenization and frequency counting before further processing.
Figure 8: BPE iteration 2
  • Iteration 3: Moving forward, we notice that “c” and “a” (from “cat” and “cats”) appear together 8 times. We merge these to create the token “ca.” After merging, “cat” can be represented as “ca” and “t.” The token “ca” now has a frequency of 8.
  • Iteration 4: We continue by merging “ca” and “t”, which appear 8 times together (from “cat” and “cats”). We merge them to form the token “cat.” Now, “cats” can be represented as “cat” and “s”, and “dogs” as “dog” and “s.” The frequency count for “cat” is updated to 8.
  • Iteration 5: Finally, the next most frequent pairing is “s” and “</w>” (from “dogs” and “cats”), which appears 7 times. We merge “s” and “</w>” to form the token “s</w>.”
Image represents a step-by-step process of updating token frequencies.  Three tables are shown, each with columns '#' (representing a token ID), 'Token', and 'Frequency'. The first table shows initial frequencies; for example, token 0 ('c') has a frequency of 8-8=0, token 1 ('a') has 8-8=0, token 2 ('t') has 8, and so on.  A rightward arrow indicates a transformation where the frequency of token 3 ('s') is reduced by 7, resulting in the second table.  This table shows updated frequencies, where 's' now has a frequency of 0, and '</w>' has 18-7=11.  Another rightward arrow shows a further transformation, likely another frequency update, resulting in the third table.  This final table shows further adjustments; for instance, '</w>' now has a frequency of 8, and a new token 's</w>' appears with a frequency of 8.  The curved arrows between tables suggest that the process involves iterative updates based on the previous table's values, possibly indicating a token frequency adjustment algorithm.
Figure 9: BPE iterations 3–5

BPE iteratively merges the most frequent character pairs, leading to a more compact representation of the corpus. The merging continues until we reach the desired number of tokens or iterations.

Image represents a simple table displaying token frequency data.  The table has three columns: '#' (a numerical identifier), 'Token' (a string of text), and 'Frequency' (a numerical count).  Each row represents a unique token and its corresponding frequency.  Specifically, row 1 shows token '</w>' with a frequency of 11; row 2 shows 'dog' with a frequency of 10; row 3 shows 'cat' with a frequency of 8; and row 4 shows 's</w>' with a frequency of 8.  The '#' column acts as a row index, providing a unique identifier for each token-frequency pair.  There are no connections or information flow between rows; the table simply presents a static summary of token occurrences.  The bottom line 'Text is not SVG - cannot display' indicates that the image itself might be a screenshot or a representation of data that was originally in a different format.
Figure 10: BPE vocabulary after 5 iterations

Note the special “</w>” token plays a key role in distinguishing between different word forms. For instance, the token “cat” followed by “</w>” indicates the end of the word “cat,” whereas the token “cat” without </w> could also be part of another word. This distinction helps BPE represent and interpret words accurately during translation, allowing it to efficiently handle both familiar and unseen words.

Once the vocabulary has been created, we construct our training data by replacing each tokenized sentence with a sequence of integers. This leads to multiple tables, each for a specific language pair. Figure 11 shows the prepared translation data for the English–French and English–Korean language pairs.

Image represents a data processing pipeline for machine translation.  The left side shows 'Original pairs' of sentences in English and another language (French and Korean in this example). Each pair consists of an English sentence and its translation in the target language, arranged in rows within a table.  The right side displays 'Tokenized pairs,' where each sentence from the original pairs has been converted into a sequence of numerical tokens.  These tokens are enclosed in square brackets, with each number likely representing a word or sub-word unit from a vocabulary.  Arrows indicate the flow of data from the original language pairs to their tokenized counterparts.  The tokenization process transforms the original text into numerical representations suitable for machine learning models, enabling the model to learn relationships between the languages.  The ellipses (...) indicate that the tables contain more data than is explicitly shown.
Figure 11: Constructed training data for English–Korean and English–French pairs

Model Development

We utilized an encoder-decoder Transformer to train language translation. In this section, we explore the architecture of the encoder and decoder, training strategies, and sampling methods.

Architecture

The key components in an encoder-decoder Transformer architecture are very similar to those of the decoder-only Transformer explained in Chapter 2. Let’s examine the encoder and decoder separately and highlight their key differences.

Encoder

The encoder processes the input sequence and outputs a sequence of embedding for each input token.

Image represents a diagram of a Transformer neural network architecture.  At the bottom, an 'Input sequence' feeds into a 'Text Embedding' layer, which is colored light orange.  Above this, a purple 'Positional Encoding' layer processes the embedded text.  Next, a larger light gray block labeled 'Transformer' contains a vertically stacked, repeating sequence of three layers: 'Normalization', 'Feed Forward', and 'Self-Attentio...' (truncated).  The 'Nx' label indicates that this sequence of three layers repeats N times.  Finally, three upward arrows emerge from the top of the Transformer block, representing the 'Output sequence'.  The data flow is strictly bottom-up: the input sequence is processed sequentially through the embedding, positional encoding, and the repeated Transformer layers, ultimately producing the output sequence.
Figure 12: Encoder components

The encoder consists of the following components:

  • Text embedding
  • Positional encoding
  • Transformer

Text embedding: This component converts each input token into an embedding vector. These embeddings capture the semantic information of each token.

Image represents a table illustrating the concept of word embeddings.  The table is divided into two columns: 'Token' and 'Embedding.' The 'Token' column lists individual words or word pieces, including '</w>' (likely representing the end of a word), 'dog,' 'cat,' and 's</w>' (likely representing the start of a word).  The 'Embedding' column displays a series of boxes representing the numerical vector associated with each token. Each row corresponds to a token and its associated embedding vector; the boxes within the 'Embedding' column visually represent the vector's dimensions, with each box implicitly holding a numerical value.  An ellipsis ('...') indicates that the table continues with more token-embedding pairs beyond what's explicitly shown.  The image visually demonstrates how each word (token) is transformed into a high-dimensional vector (embedding) which captures semantic meaning, allowing for computational processing and comparison of words.  The text 'Text is not SVG – cannot display' at the bottom indicates a limitation in rendering the image, likely due to the vector representation being non-standard.
Figure 13: Token embedding table

Positional encoding: The positional encoding component injects information about the position of each token in the input sequence. As discussed in the previous chapter, both fixed and learned methods are effective in practice. For simplicity, we choose a fixed positional encoding method such as sine–cosine encoding.

​​Transformer: The Transformer processes a sequence of token embeddings through a stack of Transformer blocks. Each block contains a self-attention layer that uses the multi-head attention (MHA) mechanism on the input sequence and a feed-forward layer, with normalization layers in between to ensure stability during training. Since the requirement specifies support for a 1,000-word input sequence, we do not need to employ optimized attention mechanisms for efficiency, as the standard attention mechanism is sufficient to handle this sequence length without significant performance issues.

Decoder

The decoder generates the output sequence one token at a time using the encoder's output and the previously generated tokens. The decoder has the following components:

  • Text embedding: Converts each token in the target sequence to an embedding
  • Positional encoding: Injects information about the position of each token
  • Transformer: Processes the target sequence and outputs an updated sequence of embeddings
  • Prediction head: Utilizes the updated embeddings to predict the next token.
Image represents a sequence-to-sequence model, likely a transformer-based architecture for text generation.  The model consists of two main parts: an encoder and a decoder. The encoder, a light gray rectangle labeled 'Encoder,' takes an 'Input sequence (s...' as input and processes it.  The output of the encoder, labeled 'Output sequence,' is then fed into the decoder, a larger gray rectangle labeled 'Transformer.' The decoder comprises several stacked layers: 'Text Embedding' (orange), 'Positional Encoding' (purple), 'Self-Attention...', 'Normalization', 'Cross-Attention...', 'Feed Forward', and 'Normalization' layers, all vertically stacked.  The 'Nx' label indicates that these layers are repeated N times.  The output of the decoder is fed into a light green rectangle labeled 'Prediction Head,' which generates the 'Predicted...' output sequence.  Arrows indicate the flow of information between components, showing how the input sequence is processed by the encoder, then passed to the decoder, which generates the predicted output sequence through multiple attention and feed-forward layers.  The 'Previously generate...' text at the bottom indicates that the decoder uses previously generated text as input for subsequent predictions.
Figure 14: Decoder components

What are the key differences between the encoder and decoder?

There are three key differences between the encoder and decoder:

  • Cross-attention layer
  • Self-attention mechanism
  • Prediction head
Cross-attention layer

The Transformer component in the decoder includes a cross-attention layer. This layer performs the MHA mechanism over the encoder's output. It enables each token in the decoder to attend to all embeddings in the encoder. This allows the cross-attention to effectively integrate information from the input sequence during the generation of the output sequence.

Image represents a diagram of a sequence-to-sequence model, likely a neural machine translation architecture.  At the bottom, an 'Input sequence' feeds into an 'Encoder,' depicted as a rectangular box. The encoder processes the input and produces three vertical rectangular blocks labeled 'Output s...', representing the encoded sequence. These three blocks then connect via numerous arrows to three vertical rectangular blocks within a dashed-line box labeled 'Decoder.'  The arrows connecting the encoder's output to the decoder are labeled 'Cross-Attention,' indicating the attention mechanism used to weigh the importance of different parts of the encoded input when generating the output. The decoder, also composed of three vertical rectangular blocks (with an ellipsis indicating continuation), processes the encoded information and generates the final output sequence.  The overall flow is from the input sequence through the encoder, then via cross-attention to the decoder, finally resulting in the decoded output sequence.
Figure 15: Cross-attention layer
Self-attention mechanism

The self-attention layer operates differently in the encoder and decoder. In the encoder, each token attends to all other tokens in the sequence. This helps the encoder understand the entire sequence comprehensively. In contrast, in the decoder, each token is restricted to attending to only those tokens that come before it by masking the future tokens in the sequence. This difference is important for generation tasks because the model should use only previously generated tokens, not future ones, to predict the next token.

Image represents a comparison of two self-attention mechanisms.  Each mechanism is depicted as two vertical columns of rectangular boxes, representing input and output vectors, respectively.  The left column in each mechanism shows three input vectors, each subdivided into multiple horizontal sections, likely representing word embeddings or hidden states.  These input vectors are connected to a central 'Self-Attention' box via upward-pointing arrows.  The 'Self-Attention' box represents the self-attention layer, which processes the relationships between the input vectors.  From the 'Self-Attention' box, downward-pointing arrows connect to three output vectors in the right column, also subdivided into horizontal sections mirroring the input vectors.  The key difference between the two mechanisms lies in the connectivity pattern between the input and output vectors within the self-attention layer.  The left mechanism shows a more fully connected pattern, with each input vector connected to each output vector, while the right mechanism shows a sparser connectivity, with each input vector primarily connected to a single or a few output vectors.  Both mechanisms are labeled 'Self-attention mechanism...' at the bottom.
Figure 16: Different self-attention mechanisms in the encoder and decoder
Prediction head

The decoder has a prediction head on top of the Transformer component. The prediction head usually includes a linear layer followed by a softmax layer to convert the Transformer’s output into probabilities over the vocabulary. These probabilities are used to determine the most likely next token.

Training

We employ a two-stage strategy to train a language translation model:

  • Unsupervised pretraining
  • Supervised finetuning

. Unsupervised pretraining

In this stage, we train a base model using a large corpus of general data. This creates a base model capable of understanding language, grammar, and context.

Let’s review the pretraining data, ML objective, and loss function for the pretraining stage.

Pretraining data

We utilize popular pretraining datasets such as C4 [8], Wikipedia [9], and StackExchange [10]. In contrast to Chapter 2, where we focused on pretraining a language model for English only, for language translation, we need a base model with a general understanding of multiple languages. Therefore, we do not remove non-English text data from these datasets. Instead, we keep the set of languages we expect the model to translate and remove any text data belonging to languages outside that set.

ML objective and loss function

In Chapter 2, we explored next-token prediction as the primary ML objective for language generation. Next-token prediction is not an ideal choice in encoder-decoder pretraining because the training is unsupervised. If we pass an entire sentence to the encoder, it will encode information in a way that allows the decoder to always predict the next word accurately, thus effectively "cheating." Instead, we use “masked language modeling,” a common ML objective for pretraining an encoder-decoder Transformer. Let’s examine it in more detail.

Masked language modeling (MLM)

In MLM, also known as masked token prediction, some of the input tokens are masked, and the model is trained to predict those masked tokens.

Image represents a simplified diagram of a sequence-to-sequence model, commonly used in machine translation or chatbot applications.  The diagram features two main rectangular blocks, labeled 'Encoder' (peach-colored with a golden border) and 'Decoder' (similar coloring and border), connected by a unidirectional arrow indicating data flow from the Encoder to the Decoder.  The Encoder receives input from a text box containing the phrase 'Thank you for inviting me,' which is crossed out, suggesting this input is not used in this specific example.  Above the Decoder, two rectangular boxes labeled 'you' and 'me' represent the output, with upward arrows indicating the Decoder generates outputs for both 'you' and 'me.'  The arrows illustrate the flow of information: the Encoder processes the (unused) input text, and its output is fed into the Decoder, which then produces separate outputs for 'you' and 'me,' likely representing a conversational exchange or translation.
Figure 17: An overview of the MLM objective

MLM allows the encoder to process the input sentence and encode it so the decoder can predict the masked words. As the masked words are never visible during the encoding process, this prevents the model from cheating,

To measure the model's performance in predicting the masked tokens, we use cross-entropy loss. This commonly used loss function measures the discrepancies between the predicted probabilities and the ground-truth tokens, thus guiding the training process. Here is a step-by-step explanation of how loss is calculated using the MLM objective:

  • Randomly select a subset of tokens in the input sequence and replace them with a mask token ("[MASK]"). For example, the input sentence "Thank you for inviting me" might become "Thank [MASK] for inviting [MASK]”.
  • Feed the masked sequence to the encoder so it can understand the context despite the missing tokens. The encoder outputs a sequence of new embeddings for each token.
  • Feed the decoder with the same input sequence, but, this time, none of the tokens are masked and the sequence has been shifted one position to the right by the insertion of a start token ("<BOS>"). Refer to Chapter 2 or [11] to understand why we shift the input sequence during training.
  • The decoder predicts the next token for each position in the sequence. Each prediction uses all previous input tokens and encoded information from the encoder.
  • Calculate the cross-entropy loss over the predicted probabilities and the ground-truth for the masked tokens only.
Image represents a sequence-to-sequence model, likely a transformer-based neural machine translation system or text generation model.  The bottom shows an input sentence 'Thank you for inviting me' (1), which is preprocessed into tokens 'Thank,' '[MASK],' 'for,' 'inviti...', '[MASK]' (2) and fed into an Encoder (peach-colored rectangle). The Encoder's output (3b) is then passed to a Decoder (another peach-colored rectangle). The Decoder receives input tokens '<BOS>', 'Thank', 'you', 'for', 'inviti...' (3a) and generates probability distributions for the next token in the sequence (4). These distributions are shown as columns of numbers, representing the probabilities of different words being the next token.  Two columns of binary vectors (5) represent the ground truth (correct next tokens) for calculating the cross-entropy loss, a measure of the difference between the predicted probabilities and the actual next tokens.  The arrows indicate the flow of information, showing how the input sentence is encoded, processed by the decoder, and used to predict the next tokens, with the loss function evaluating the accuracy of the predictions.
Figure 18: Cross-entropy loss calculation for MLM objective

In summary, we primarily use the MLM objective in pretraining encoder-decoder Transformers because it engages both the encoder and decoder. The encoder develops its understanding of the language by encoding the masked input text. The decoder learns to process this encoded information and predict the masked tokens. This objective prepares both the encoder and decoder for the supervised finetuning stage.

Before exploring the supervised finetuning stage, note that pretraining a base model is resource-intensive and, therefore, expensive. In practice, we often use publicly available encoder-decoder models such as Google’s T5 [12] or Meta’s BART [13], which have been pretrained on extensive datasets. This approach significantly reduces the cost and resources needed for pretraining.

. Supervised finetuning

Supervised finetuning, the second stage of our training process, adapts the base model to the specific task of language translation. It does this by finetuning the base model on translation data. To adapt the base model to language translation, we have two options:

  • Bilingual approach
  • Multilingual approach
Image represents two options for training a language model: Option 1, bilingual models, and Option 2, a multilingual model.  Option 1 shows a general language model database ('General...') feeding into a '1. Pretraining' step, which then produces a base model ('Base...'). This base model is then fed into separate '2. Finetuning' steps, each using a bilingual dataset (e.g., 'English-French...', 'English-Spanish...', 'English-Korean...'), resulting in separate bilingual models.  Option 2 shows a similar process, but instead of separate bilingual datasets, a single multilingual dataset ('English-Korean...', 'English-French...', 'English-Spanish...') is used.  A general language model database ('General...') feeds into '1. Pretraining,' creating a base model ('Base...'). This base model is then fed into a single '2. Finetuning' step using the multilingual dataset, resulting in a single multilingual model ('Multilingual...').  Both options involve a two-step process: pretraining on a general dataset and then finetuning on a specific (bilingual or multilingual) dataset.  The arrows indicate the flow of data between the stages.
Figure 19: Bilingual vs multilingual models
Bilingual approach

In this approach, we train models specific to each language pair. Training language-specific models has several advantages. First, they capture the unique linguistic nuances of each language pair. Second, they usually demonstrate higher translation accuracy due to their specialized natures. Finally, improving performance is simpler with language-specific models because we can easily isolate and address specific issues that may arise for each language pair. However, training, deploying, and maintaining multiple models is resource-intensive and costly.

Multilingual approach

Here, a single model is trained to translate between multiple languages. Multilingual models are simpler, less expensive, and easier to deploy and maintain than bilingual models. Recent studies such as mT5 [14] and mBART [15] have highlighted the trend toward multilingual translation models that often match or exceed the performance of bilingual models.

For this chapter, we prioritize translation accuracy over simplicity and, therefore, choose a bilingual approach.

Training data

Figure 20 shows an example of prepared training data where each table represents a language pair. In each table, a row represents one example, containing a sequence of token IDs for the sentence in the source language and a sequence of token IDs for the translation in the target language.

Image represents two tables, each displaying tokenized pairs of sentences in two different languages.  The left table shows English-Korean pairs, with the 'English' column listing sequences of numbers (e.g., [138, 18, 9, 2130], [138, 9561, 31, 72...], [309, 11001, 22, 7...], and so on) representing tokenized English sentences, and the 'Korean' column showing corresponding sequences of numbers (e.g., [186, 732, 666, 349, 81...], [226, 91022, 82483, 964...], [39485, 128320, 8532, 4...], etc.) for the Korean translations.  The right table similarly presents English-French pairs, with the 'English' column containing different numerical sequences (e.g., [15724, 374, 9439], [2028, 374, 15526], [4438, 527, 499, 3...]) representing tokenized English sentences, and the 'French' column showing corresponding numerical sequences (e.g., [12319, 20272, 282, 160...], [34, 17771, 1377, 57332], [10906, 44496, 2442, 84...]) for their French translations.  Both tables use ellipses (...) to indicate that the sequences continue beyond what's visibly shown.  The tables are labeled 'English-Korean tokenized pairs' and 'English-French tokenized pairs' respectively, indicating the language pairs and the nature of the data presented.
Figure 20: Example of prepared training data for different language pairs
ML objective and loss function

Whereas the pretraining stage was unsupervised, the finetuning stage is supervised. The encoder processes source sentence tokens for each training example, and the decoder generates the target sentence tokens. Since the decoder should generate tokens sequentially after training, we use next-token prediction as our ML objective. We use cross-entropy as our loss function to measure the accuracy of the predicted next token.

Image represents a sequence-to-sequence model, likely for machine translation, depicted as a neural network architecture.  The input, 'What is your name?', is fed into an 'Encoder' block, which processes the sentence. The encoder's output is then passed to a 'Decoder' block. The decoder receives an initial token '<BOS>' (Begin of Sentence) and iteratively predicts the next word in the target language (French in this example).  The decoder's predictions are represented as probabilities (e.g., 0.01, 0.06, 0.73, 0.11) for each word in the vocabulary.  These probabilities are compared to the correct next word sequence ('0 0 1 0'), which represents a one-hot encoding of the correct translation (presumably 'Quel est'). The difference between the predicted probabilities and the correct sequence is calculated as 'loss,' which is used to train the model.  Arrows indicate the flow of information: from the input words to the encoder, from the encoder to the decoder, from the decoder's predictions to the loss calculation, and finally, the loss is used to adjust the model's weights (not explicitly shown).  The decoder outputs 'Quel est' as the translated sequence.
Figure 21: Loss calculation during the finetuning stage

Figure 21 shows loss calculation during the finetuning stage. For simplicity, it visualizes a single prediction. In practice, as we saw in Chapter 2, the decoder predicts the next token for all positions simultaneously, and the losses are calculated for all predictions.

Sampling

During sampling, the trained model generates a potential translation by predicting each subsequent token based on the previously generated tokens and the context of the input sequence.

Image represents a sequence-to-sequence model, likely a neural machine translation system.  The diagram shows an encoder on the left, processing the input sequence 'What is your name?'. Each word is represented as a separate box, feeding into the encoder. The encoder processes this input and outputs a contextualized representation, which is then fed into a decoder on the right. The decoder, labeled 'Decoder,' receives this representation and generates an output sequence, shown as 'Quel est' in French.  The intermediate representation between the encoder and decoder is shown as vectors of probabilities (e.g., 0.01, 0.06, 0.73, 0.11 for 'Quel' and similar for 'est'). These probabilities likely represent the model's confidence in predicting each word in the output sequence.  The '<BOS>' token indicates the beginning of the sequence for the decoder.  The ellipses ('...') indicate that the model can handle sequences longer than what's explicitly shown, both in input and output.  The dashed lines connecting the output words to the decoder suggest a feedback loop, where the previously generated words influence the prediction of subsequent words.
Figure 22: Generating translation

As discussed in Chapter 2, there are two main strategies for sampling text in generative models: deterministic methods (e.g., beam search) and stochastic sampling. Here, we choose beam search for two main reasons:

  • Translation accuracy: Beam search usually leads to more accurate translations. This is because the algorithm evaluates multiple possible sequences and selects the most probable one.
  • Consistency: Beam search is deterministic, meaning it always produces the same output given the same input. This consistency ensures that translations will provide few surprises, which is critical in most translation systems. While diversity can be beneficial, it is neither essential nor desirable for language translation systems.

Note that in applications where diversity and creativity are more valued, such as creative writing, stochastic sampling methods are usually preferred. In Chapter 4, we will examine stochastic methods such as top-k and top-p sampling in detail.

CharacteristicDeterministic methodsStochastic methods
ApproachFollow a predictable process to generate outputGenerate output based on probability distribution
EfficiencyTypically less efficient due to tracking multiple pathsMore efficient since randomness allows for quicker selections
QualityCoherent and predictableDiverse and creative
RiskUsually lead to repetitive output for longer sequencesMight produce inappropriate output due to their creativeness
Use caseSuitable for tasks requiring consistency, such as language translationSuitable for tasks requiring creativity, such as open-ended text generation
MethodsGreedy search, beam searchMultinomial, top-k, top-p

Table 1: Comparison of deterministic and stochastic methods

Evaluation

Offline evaluation metrics

To thoroughly evaluate a language translation model, metrics should measure both translation accuracy and contextual appropriateness. The research community has proposed several metrics that, over the years, have become widely accepted as standards. Some commonly used metrics are:

  • BLEU
  • ROUGE
  • METEOR

BLEU

BLEU (BiLingual Evaluation Understudy) [16] is a precision-based metric that compares n-grams (a sequence of "n" words) of the candidate translation with n-grams of the reference translations and counts the ratio of matches. It ranges from 0 to 1, where a higher value indicates a more precise translation.

The BLEU score is calculated using the following formula:

where:

  • N is the maximum n-gram length considered for evaluation
  • BP is the brevity penalty
  • pn is the n-grams precision
  • wn represents the weight for different n-gram precisions

Let's explore each of these terms in detail.

Brevity Penalty (BP) BP is a constant term that penalizes translations shorter than the reference translation. The formula is:

where:

  • c is the translation length
  • r is the reference translation length

If the candidate translation length, c, is greater than the reference translation length, r, the brevity penalty is 1 (i.e., there is no penalty). If the candidate translation length is less than or equal to the reference translation length, the brevity penalty is an exponential decay based on the ratio of the lengths.

Precision (pn): Precision measures how many n-grams in the candidate translation are present in reference translations. It is calculated by dividing the number of matching n-grams by the total number of n-grams in the candidate translation. Figure 23 provides an example of calculating p2 for a candidate and one reference sentence.

The image represents a completely blank space; there are no visible components, arrangement, connections, or information flow of any kind.  No labels, text, URLs, or parameters are present.  The image is simply a solid black rectangle.
Figure 23: Example of calculating precision for 2-grams (p2)

Weights (wn) These weights correspond to the precision of each n-gram size. Usually, we distribute them evenly, giving each n-gram precision the same importance. For instance, for n-grams up to 4-grams, each wn would be 1/4.

BLEU’s main advantage is that it is simple and easy to compute. However, it has a major drawback: it can unfairly penalize translations that are correct but different from the reference translation. For example, if the reference translation is "The engineer discovered a new algorithm," and the generated translation is "The engineer found a new method," BLEU might penalize the generated translation even though it conveys the same meaning. Despite this limitation, BLEU remains insightful and widely used in practice to evaluate language translation models.

ROUGE

ROUGE (Recall-Oriented Understudy for Gisting Evaluation) [17] is a popular metric that complements BLEU by focusing on recall instead of precision. It measures the ratio of n-gram overlaps between the candidate and reference texts. For example, the ROGUE-N recall is defined as:

If you are interested to learn more about ROUGE and its formula, refer to [17].

Similarly to BLEU, ROUGE is easy to implement and efficient at calculating. However, its main drawback is its lack of contextual understanding. A translation with different but semantically similar words might receive a low ROUGE score.

METEOR

METEOR (Metric for Evaluation of Translation with Explicit ORdering) [18] is a popular metric for evaluating language translation models. It calculates precision and recall and then combines these measurements using a weighted harmonic mean.

Unlike BLEU and ROUGE, which rely on exact n-gram matches, METEOR considers synonyms and the morphology of words. For example, if the reference translation uses ”run” and the generated translation uses “running,” METEOR recognizes these as related terms. These synonyms are found using linguistic resources such as synonym dictionaries or lexical databases. One commonly used resource is WordNet [19], which organizes words into synonyms of various types and shows the relationships between those synsets.

Image represents a formula for calculating recall, specifically in the context of n-gram matching.  The formula is presented as a fraction. The numerator is labeled 'Number of matching n-grams,' representing the count of n-grams (sequences of 'n' consecutive words or characters) that are common to both a target text and a reference text. The denominator is labeled 'Total number of n-grams in the reference,' indicating the total count of n-grams present within the reference text.  The entire fraction is labeled 'Recall,' signifying that the result of this calculation represents the recall metric – a measure of how many of the relevant n-grams from the reference text were successfully retrieved or matched in the target text.  No URLs or specific parameters are visible; the formula is purely textual.
Figure 24: Example of relationships between words

While METEOR is a more comprehensive metric, it has some drawbacks. Let’s take a look at its pros and cons.

Pros:
  • Semantic understanding: METEOR evaluates translation quality more accurately when different wordings convey the same meaning. This is because it considers synonyms and stemming during the evaluation of translations.
  • Balanced evaluation: METEOR provides a balanced evaluation because it combines precision and recall. This helps identify translations that are both accurate and complete.
  • Correlation with human judgments: METEOR correlates better with human judgments than BLEU and ROUGE.
Cons:
  • Computational complexity: METEOR is harder to implement and takes more time to calculate than BLEU and ROUGE. This is because it requires additional steps, such as synonym and stemming matching.
  • Resource dependence: METEOR relies on linguistic resources such as synonym dictionaries and stemming algorithms, which may not be available for all languages.

To summarize, all three metrics offer insights into the model's performance and are commonly used in practice. Let's transition to online evaluation to understand how our model performs in real-world scenarios.

Online evaluation metrics

During the online evaluation, we evaluate how well our language translation system works in production. We use the following two metrics to measure how satisfied and engaged our users are:

  • User feedback: Collect ratings or feedback from users regarding the quality of translations. The metric is insightful since it directly reflects user satisfaction. Figure 25: Collecting user feedback
  • User engagement: Measure users’ engagement by monitoring how often they use the translation feature, how long they interact with it, and how frequently they return. This helps us understand how valuable and effective the translation tool is in real-world use.

Combining offline and online evaluation metrics gives us a more complete view of the performance of the language translation. This thorough evaluation ensures models fulfill technical standards and satisfy user expectations.

Overall ML System Design

In this section, we explore the ML design of a language translation system. In particular, we examine two key components:

  • Language detector
  • Translation service
Image represents a machine translation system's architecture.  A user icon on the left initiates the process by providing an 'Input sentence...' and specifying a 'Desired language...'. This input flows into a rectangular 'Language Detector' (light orange), which identifies the 'Detected language...' of the input sentence and passes this information to a central rectangular 'Translation Service' (light purple).  The Translation Service also receives the user's specified 'Desired language...'.  The Translation Service then uses a 'Beam search' algorithm to select the best translation from multiple potential translations represented by three cloud shapes: 'English-French...', 'Spanish-Korean...', and 'French-Korean...'. These clouds represent different language pairs and their respective translation outputs.  The final translated output, selected by the beam search, is implicitly indicated by the arrow from the Translation Service to the Korean text '정말 아름다운 날이에' (meaning 'It's a really beautiful day').  The dashed lines indicate the selection process of the beam search, showing the multiple potential translations considered before a final output is chosen.
Figure 26: Language translation overall design

Language detector

The language detector identifies the language of a given text, enabling us to use the model that has been trained specifically for that language. This task can be framed as a sequence classification task, and encoder-only architecture is a good candidate architecture for such a task. We can modify the encoder-only Transformer in two ways (Figure 27) to classify input sentences:

  • Average pooling: Pass the Transformer's outputs to an average pooling layer, and then a prediction head to output language class probabilities.
  • Last token representation: Use the last token representation from the Transformer's output and feed it to the prediction head for probability prediction.
Image represents two alternative architectures for a language model, labeled 'Option 1: average po...' and 'Option 2: using last...'.  Both options process a 'Sentence of unknown lang...' as input, which undergoes 'Text Embedding' and 'Positional Encoding'. This embedded sentence then feeds into a 'Transformer' block. The Transformer in both options consists of stacked layers of 'Normalization', 'Feed Forward', and 'Normalization' again, followed by a 'Self-Attentio...' layer.  The number of layers in the Transformer is indicated by 'Nx'. Option 1 uses 'Average Pooling' to aggregate the output of the Transformer, which is then fed into a 'Prediction Head' to generate a 'Predicted source...'. Option 2, however, directly uses the output of the final 'Normalization' layer of the Transformer, feeding it into the 'Prediction head' to produce a 'Predicted source...'.  Arrows indicate the flow of information between components, showing the sequential processing within each architecture.
Figure 27: Two options for building a language detector using an encoder-only Transformer

Translation service

The translation service interacts with the specific model based on the detected and desired languages. It then applies beam search to generate a sequence of tokens in the target language and converts the tokens back into text. The final translation is then shown to the user.

Other Talking Points

If time permits at the end of the interview, consider discussing these additional topics:

  • Supporting translation for languages with limited training data using transfer learning and multilingual models [20].
  • Approaching language translation using a decoder-only Transformer [21].
  • Continuously improving translation models through user feedback [22].
  • Optimizing techniques for efficient inference and on-device translation [23].
  • Developing a single multilingual model [24].
  • Other automatic metrics such as WER and how they are calculated [25][26].
  • How to build a language detection model [27].

Summary

Image represents a mind map summarizing the key aspects of a Generative AI system design.  The central node is labeled 'Summary,' from which several main branches emanate, representing major phases or components:  'Model development,' 'Evaluation,' 'Overall system components,' and 'Other talking points.'  The 'Model development' branch further subdivides into 'Data preparation' (including data cleaning, normalization, and tokenization), 'Architecture' (detailing encoder and decoder components using transformers and positional encoding), and 'Training' (covering unsupervised pre-training and supervised fine-tuning with methods like masked language modeling (MLM) using general text and email data, and next-token prediction). The 'Evaluation' branch splits into 'Offline' (using metrics like BLEU, ROUGE, and METEOR) and 'Online' (relying on user feedback and user engagement metrics).  The 'Overall system components' branch includes a 'Language detector' and 'Translator service.' Finally, 'Other talking points' includes 'Clarifying requirements' and 'Specifying input and output,' which are connected to the 'Summary' node directly.  Each branch and sub-branch uses a distinct color-coded line, enhancing visual clarity and organization.  The entire diagram provides a structured overview of the design process, from initial requirements to final evaluation and deployment considerations.

Reference Material

[1] Google Translate service. https://blog.google/products/translate/google-translate-new-languages-2024/. [2] Neural Machine Translation by Jointly Learning to Align and Translate. https://arxiv.org/abs/1409.0473. [3] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. https://arxiv.org/abs/1810.04805. [4] GPT models. https://platform.openai.com/docs/models. [5] Claude models. https://www.anthropic.com/claude. [6] Bidirectional Long Short-Term Memory (BLSTM) neural networks for reconstruction of top-quark pair decay kinematics. https://arxiv.org/abs/1909.01144. [7] BPE tokenization. https://huggingface.co/learn/nlp-course/en/chapter6/5. [8] C4 dataset. https://www.tensorflow.org/datasets/catalog/c4. [9] Wikipedia dataset. https://www.tensorflow.org/datasets/catalog/wikipedia. [10] Stack Exchange dataset. https://huggingface.co/datasets/HuggingFaceH4/stack-exchange-preferences. [11] How Transformers work. https://huggingface.co/learn/nlp-course/en/chapter1/4. [12] Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer. https://arxiv.org/pdf/1910.10683.pdf. [13] BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension. https://arxiv.org/abs/1910.13461. [14] mT5: A massively multilingual pre-trained text-to-text transformer. https://arxiv.org/abs/2010.11934. [15] Multilingual denoising pre-training for neural machine translation. https://arxiv.org/abs/2001.08210. [16] BLEU metric. https://en.wikipedia.org/wiki/BLEU. [17] ROUGE metric. https://en.wikipedia.org/wiki/ROUGE_(metric). [18] METEOR metric. https://www.cs.cmu.edu/~alavie/METEOR/pdf/Banerjee-Lavie-2005-METEOR.pdf. [19] WordNet. https://wordnet.princeton.edu/. [20] No Language Left Behind: Scaling Human-Centered Machine Translation. https://research.facebook.com/publications/no-language-left-behind/. [21] Decoder-Only or Encoder-Decoder? Interpreting Language Model as a Regularized Encoder-Decoder. https://arxiv.org/abs/2304.04052. [22] Towards Continual Learning for Multilingual Machine Translation via Vocabulary Substitution. https://arxiv.org/abs/2103.06799. [23] Efficient Inference For Neural Machine Translation. https://arxiv.org/abs/2010.02416. [24] Meta’s multilingual model. https://ai.meta.com/blog/nllb-200-high-quality-machine-translation/. [25] Machine translation evaluation. https://en.wikipedia.org/wiki/Evaluation_of_machine_translation. [26] Word error rate (WER) metric. https://en.wikipedia.org/wiki/Word_error_rate. [27] Automatic Language Identification using Deep Neural Networks. https://research.google.com/pubs/archive/42538.pdf.

Chapter 4

ChatGPT: Personal Assistant Chatbot

~41 min read

Introduction

ChatGPT [1] is a chatbot that was developed by OpenAI and launched in 2022. It generates human-like text based on the input it receives. The chatbot can assist with various tasks, including answering questions, providing explanations, and producing creative content.

ChatGPT has quickly become one of the most adopted applications in history. It gained over 100 million users in less than three months after its launch [2]. This rapid growth highlights the capabilities of generative AI and its potential to help with day-to-day tasks and enhance productivity. In this chapter, we examine the key components of building a chatbot similar to ChatGPT.

Image represents a simulated ChatGPT interaction.  At the top, 'ChatGPT' is labeled, suggesting a user interface for interacting with the large language model.  Below this, a user input box contains the prompt: 'write a short message so I apologize my manage...'.  Two response bubbles, each preceded by a small, stylized circular logo, appear below. The first response bubble contains the text 'Sorry for the inconvenience.' and the second contains 'Sorry for my mistak...'.  To the right, another response bubble shows a user's follow-up message: 'inconvenience? lol'. At the bottom, a button labeled 'Message ChatGPT' is shown with an upward-pointing arrow next to it, indicating the direction of message submission to the ChatGPT model.  The overall arrangement suggests a conversational flow, with the user's prompt initiating the interaction, followed by ChatGPT's responses and a subsequent user interaction.
Figure 1: Example of a conversation with ChatGPT

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: What languages should the chatbot support? Interviewer: Initially, let’s focus on English.

Candidate: We need to ensure the chatbot generates unbiased and safe outputs by having strict content moderation and algorithms in place. Is that a fair assumption? Interviewer: Certainly.

Candidate: Can you specify the range of tasks the chatbot is expected to perform? Interviewer: The chatbot should be able to handle tasks like providing information and answering questions.

Candidate: Does the chatbot take in or output non-text modalities, such as image, audio, or video? Interviewer: Let’s focus on a text-only chatbot for now. The input and the output are both text.

Candidate: Should the chatbot handle follow-up questions? How long should the chatbot maintain the conversation context? Interviewer: Good question. The chatbot should be able to handle follow-up questions within the same conversation session. Let’s say it is expected to have a context window of at least 4096 tokens.

Candidate: Is the chatbot expected to be able to browse websites, call external API, or search online? Interviewer: Let’s not focus on that in this round.

Candidate: Should the chatbot personalize its interactions with users? Interviewer: Let’s not focus on personalization.

Candidate: Do we have instruction-based training data? Interviewer: Yes, we have a dataset with 80,000 examples of instructions and answers.

Frame the Problem as an ML Task

Specifying the system’s input and output

The input to the chatbot is a text prompt provided by the user. The prompt can be a question, a command, or any other form of textual query. The output is a relevant and contextually appropriate response generated by the chatbot.

Image represents a simple data flow diagram illustrating a user interaction with a chatbot.  The diagram shows a left-to-right flow.  On the left, the user input 'where bill gates...' is depicted.  A black arrow points from this input to a rectangular box representing the 'Chatbot,' which is colored light orange with a golden-yellow border.  The chatbot processes the input.  Another black arrow then points from the chatbot box to the output on the right, which displays the response 'Bill Gates was born in Seattle,...'.  The text 'Text is not SVG - cannot display' is present at the bottom of the chatbot box, indicating a technical note about the image's creation. The overall structure demonstrates a basic question-answer interaction where a user query is fed into a chatbot, which then generates a relevant response.
Figure 2: Input and output of a chatbot

Choosing a suitable ML approach

Developing a chatbot is a language generation task in which a language model processes an input prompt and generates a response. This language model typically needs billions of parameters to learn effectively; hence, they are often called large language models (LLMs).

As we saw in previous chapters, the decoder-only Transformer is the standard architectural choice in language models. Most modern LLMs, such as OpenAI’s GPT [3], Google’s Gemini [4], and Meta's Llama [5], are all based on the decoder-only Transformer. In line with these models, we use a decoder-only

Data Preparation

The effectiveness of an LLM depends on the quality of its training data, which mainly comes from web sources. This data, often automatically crawled from websites, forums, and blogs, requires special considerations and careful preparation. The most common steps include:

  • Content extraction and parsing: Web-crawled data often contains extraneous elements, for example, HTML tags, advertisements, and navigation links. This step involves parsing the raw HTML content using libraries such as Beautiful Soup [6] or lxml [7] and extracting the main text body while discarding irrelevant sections. Techniques such as DOM analysis [8] and boilerplate detection [9] are applied to isolate and retain the core content relevant to language modeling.
  • URL and domain filtering: Not all web domains provide high-quality or relevant content. URL filtering uses predefined rules or machine learning (ML) classifiers to exclude unwanted sources, for example, low-quality blogs, content farms, or spam sites. Domain allowlisting or blocklisting techniques are also applied to curate data from trusted and relevant sources, ensuring the dataset’s quality and reliability.
  • Language identification: Crawled data often includes multilingual content, which needs to be filtered to match the target language(s) for training. Language detection tools such as fastText [10] or langid.py [11] are employed to classify and filter documents.
  • Content quality filtering: Not all web content is equally valuable for training purposes. Quality assessment techniques, including readability scoring, spam detection algorithms, and heuristic checks (e.g., content length, sentence structure), are used to evaluate and filter low-quality text. ML models can also be employed to predict the quality of web content based on features extracted from the text. This step is crucial to ensure that only high-quality data is used for training.

Along with these techniques, the following are commonly applied to both web-crawled data and other data sources, such as books, articles, and social media posts:

  • Remove inappropriate content: We use ML models to remove offensive, harmful, or NSFW content from training data. This ensures our model learns only appropriate and safe content.
  • Anonymize sensitive information: We anonymize any personally identifiable information (PII) in the dataset. This step is crucial to comply with privacy laws and ethical guidelines.
  • Remove low-quality data: We use ML models to remove low-quality text data. The models assess coherence, relevance, grammar, and readability. This step ensures the training data is high in quality and useful for training.
  • Remove duplicated data (Deduplication): We remove similar texts that might be present in different sources. For example, if the same news article is collected from multiple websites, we identify and retain only one copy. This step reduces redundancy in the training dataset and ensures the model is not overexposed to certain data.
  • Remove irrelevant data: We use heuristics and rule-based methods to remove irrelevant data. For example, we remove texts with non-standard characters or in languages that the chatbot is not expected to support.
  • Tokenize text: We use a subword tokenization algorithm such as Byte-Pair Encoding (BPE) to tokenize the text data. To review BPE, refer to Chapter 3.

Model Development

Architecture

The LLM’s architecture is based on a decoder-only Transformer. While the text embedding, Transformer blocks, and the prediction head are similar to the decoder-only Transformer discussed in Chapter 2, LLMs typically use more advanced positional encoding methods.

Image represents a diagram of a text generation model architecture.  At the bottom is a 'Text Embedding' layer, which presumably converts input text into numerical vectors. Above this is a 'Positional Encoding' layer, adding positional information to the embedded vectors.  The core of the model is a 'Transformer' block, which consists of a vertically stacked sequence of layers. This sequence is repeated Nx times, indicated by a curly brace and the label 'Nx'. Each repetition within the Transformer includes a 'Normalization' layer, a 'Feed Forward' layer, and another 'Normalization' layer, followed by a 'Multi-head...' layer (the ellipsis suggests further details omitted from the diagram). Finally, at the top is a 'Prediction Head' layer, responsible for generating the output text based on the processed information from the Transformer.  The data flow is bottom-up: text is embedded, positional information is added, then the data passes through the repeated Transformer layers, and finally, the prediction head generates the output.
Figure 3: Components of a decoder-only Transformer

Let’s examine LLM’s positional encoding in more detail.

Positional encoding

In a chatbot setting, the input sequence is typically much longer than a single sentence or email. As per the interviewer’s requirements, our goal is to build a system with a context window of at least 4096 tokens. This requires a positional encoding method that allows the model to understand the positions of all the tokens and the relationships between them.

In this section, we begin with a brief review of absolute positional encoding followed by an exploration of relative positional encoding. Finally, we delve into rotary positional embedding (RoPE) [12], a robust positional encoding method used by popular LLMs such as Llama 3 [13].

Absolute positional encoding

Absolute positional encoding refers to traditional methods such as sinusoidal or learnable encodings whereby each position in a sequence is represented by a unique vector.

In this approach, encoded positions are then added to the token embeddings, providing the model with information about where each token appears in the sequence. Formally, the attention keys and queries are computed using the following equations:

Where:

  • qmq_mqm​ is the query vector at position mmm,
  • knk_nkn​ is the key vector at position nnn,
  • WqW_qWq​ and WkW_kWk​ are learnable weight matrices,
  • eme_mem​ and ene_nen​ are token embeddings at positions mmm and nnn,
  • pmp_mpm​ and pnp_npn​ are positional vectors (either learnable or fixed) at positions mmm and nnn.

The attention score is calculated as a dot product of the query and key vectors:

Notice that positional encodings pmp_mpm​ and pnp_npn​ depend only on absolute positions. Therefore, this approach captures only information about absolute position, limiting the model's ability to capture relative distances between tokens and generalize to sequences with different lengths or unseen token positions. For example, a model trained on sequences of up to 512 tokens may struggle to generalize when applied to sequences with 4096 tokens. The sinusoidal patterns tend to become repetitive over long distances, resulting in a loss of information about token relationships. This shortcoming is addressed by relative positional encoding.

Relative positional encoding

In relative positional encoding, instead of encoding the absolute positions of tokens, we encode the differences in the positions of two tokens. This way, the model can focus on the relative distances between tokens, which is often more important than their absolute positions. For example, in a sentence, knowing that the word "car" follows the word "chased" is more informative than knowing the positions of the tokens as numbers 5 and 10.

The attention calculation in relative positional encoding can be expressed in different ways. The T5 paper [14] suggests that the second and the third interaction terms in the original expression in absolute positional encoding can be dropped and that the fourth term could be replaced by a learnable bias:

In contrast, the DeBerta paper [15] drops the last term and replaces the second and third terms, which consist of the absolute positional vectors pmp_mpm​ and pnp_npn​, respectively, with the relative positional vector Rn−mR_{n-m}Rn−m​ :

Relative positional encoding allows the model to understand the relationships between tokens independently of their absolute positions. However, it introduces additional complexity because qm⋅knq_m \cdot k_nqm​⋅kn​ in the attention mechanism can no longer be reduced to a simple dot product. This limits our ability to use efficient techniques such as linear attention [16]. RoPE, which we examine next, addresses this limitation by encoding both absolute and relative positional information through a rotation in the embedding space.

Rotary positional encoding (RoPE)

RoPE represents positional information as a rotation matrix applied to the token embeddings. This can be described mathematically as follows: Given an input sequence, RoPE applies a rotation matrix to each embedding. This transformation can be expressed as:

where qmq_mqm​ is token embedding at the position mmm, and R(θm)R\left(\theta_m\right)R(θm​) is a rotation matrix parameterized by the positional angle θm\theta_mθm​. This angle is typically derived from the position index mmm and is constructed in such a way that the rotation captures both the absolute and relative position information. This rotation matrix, constructed using trigonometric functions, rotates the embeddings in the complex plane, capturing both absolute and relative positional information.

Image represents a comparison of two 2D vector representations.  The left side shows a Cartesian coordinate system (x and y axes) with two vectors originating from the origin (0,0). A reddish-brown vector labeled 'cat' points upward and to the right, and a blue-gray vector labeled 'dog' points upward and to the right at a smaller angle than the 'cat' vector.  A curved arrow indicates an angle θ between the two vectors. Below the graph, the text 'The cat chased the dog' is written. The right side mirrors the structure, also showing a Cartesian coordinate system with two vectors originating from the origin.  However, the 'cat' vector (reddish-brown) points upward and to the left, while the 'dog' vector (blue-gray) points upward and to the right.  The angle θ between these vectors is also indicated by a curved arrow. Below this graph, the text 'Once upon a time, the cat ch...' is partially visible, suggesting a narrative context.  The overall image uses vector diagrams to potentially illustrate different interpretations or scenarios related to the phrase 'the cat chased the dog,' highlighting the change in relative vector directions and the angle between them.
Figure 4: RoPE in 2D

Figure 4 shows how rotational position encoding works by rotating word embeddings in a two-dimensional space. The words "cat" and "dog" are represented as vectors, and the angle between them, denoted by θ\thetaθ , encodes their positional relationship. On the left, the sentence is “The cat chased the dog.” The position of "cat" is shown in red, and the position of "dog" is shown in blue. The angle between these vectors captures the relative positioning of these two words in the sentence.

On the right, another sentence “Once upon a time, the cat chased the dog” is shown. Notice that the relative angle between the "cat" and "dog" vectors is still the same, but their absolute positions are different. This demonstrates how RoPE captures both the absolute and relative positions of words, allowing the model to understand the order and distance between words in a sentence.

In a higher-dimensional space, the rotation matrix can be extended to accommodate ddd dimensions:

Pros:
  • Translational invariance: RoPE encodes positional information in a way that remains consistent even when the positions of tokens shift. This helps the model handle changes in position better than other methods.
  • Relative position representation: RoPE’s rotations encode positional information geometrically within the embedding space. This enables the model to inherently understand the relative distances between tokens, unlike traditional sinusoidal encodings, which encode position additively without leveraging this geometric insight.
  • Generalization to unseen positions: Because RoPE encodes position through rotations, the resulting embeddings maintain consistent relationships, regardless of absolute position. This allows for better generalization across varying sequence lengths.
Cons:
  • Mathematical complexity: RoPE introduces additional mathematical operations involving rotations in the embedding space. While these are not overly complex, they are more intricate than traditional positional encoding methods such as sinusoidal or learned positional embeddings.

Training

In earlier chapters, we explored a two-stage strategy for training language models. However, those stages are not sufficient when training advanced chatbots. Most chatbots, including ChatGPT, use a three-stage training strategy:

  • Pretraining
  • Supervised finetuning (SFT)
  • Reinforcement learning from human feedback (RLHF)

Let’s discuss each stage in more detail to understand its purpose.

Image represents a three-stage process for training a chatbot.  Three cylindrical databases labeled 'General...', 'Instruction...', and 'Human Feedba...' (presumably representing general data, instruction data, and human feedback data, respectively) feed into three sequential processing stages.  The first stage, '1. Pretraining,' uses the 'General...' data to create a 'Base Model' represented as a light gray cloud.  The output 'Base Model' is then fed, along with data from the 'Instruction...' database, into the second stage, '2. SFT' (Supervised Fine-Tuning), which produces an 'SFT Model,' also represented as a light gray cloud.  Finally, the 'SFT Model' and data from the 'Human Feedba...' database are input into the third stage, '3. RLHF' (Reinforcement Learning from Human Feedback), resulting in a final 'Chatbot...' output, depicted as a light green cloud.  Arrows clearly indicate the data flow between each component, showing a linear progression from raw data to a refined chatbot model.
Figure 6: Three stages of training an LLM

. Pretraining

Pretraining is the initial stage of the training process. In this stage, a model is trained with an enormous volume of text data from the Internet. The purpose of pretraining is to create a base model with a broad understanding of language and world knowledge.

The pretraining stage requires significant computational resources. It typically requires thousands of GPUs, costs millions of dollars, and takes months of training.

Pretraining data

The pretraining data typically consists of a large corpus of general text data from various sources on the Internet, for example, web pages, books, and social media posts.

Several datasets are commonly used when pretraining LLMs. Each serves a unique purpose, from broadening the model's exposure to diverse language styles to deepening its understanding of specific domains. Commonly used datasets are:

  • Common Crawl: Common Crawl [17] is a publicly available dataset collected from a large number of web pages on the internet. It contains petabytes of data that have been regularly collected since 2008. This data often includes irrelevant information and harmful content; hence, significant data cleaning is needed to make it suitable for training LLMs.
  • C4: C4 [18], created by Google, is a cleaned version of the Common Crawl dataset specifically used for training LLMs.
  • GitHub: The GitHub dataset comprises a vast collection of open-source code repositories. Its purpose is to help the model understand programming languages and code structures.
  • Wikipedia: The Wikipedia dataset includes a wide range of factual information extracted from Wikipedia. This dataset is generally a more reliable source because it is written and edited more carefully.
  • Books: The books dataset is a collection of books across various genres. Books have long textual content and good data quality, both of which contribute to improving the performance of LLMs.
  • ArXiv: The Arxiv dataset contains academic materials and published papers. This dataset helps the model understand the terminology and knowledge within the academic domain.
  • Stack Exchange: Stack Exchange [19] is a website of high-quality questions and answers, primarily in the format of a dialogue between users. Most popular LLMs are trained on all or some of the listed datasets. For example, Meta’s Llama-1 model uses all the above datasets, consisting of about 1.4 trillion tokens. Table 1 shows the proportion of each dataset used by Llama-1 during training.
DatasetSampling proportionDisk size
Common Crawl67.0%3.3 TB
C415.0%783 GB
Github4.5%328 GB
Books4.5%85 GB
Wikipedia4.5%83 GB
ArXiv2.5%92 GB
Stack Exchange2.0%78 GB

Table 1: Llama 1 pretraining dataset

ML objective and loss function

As we are training a decoder-only Transformer for text generation, we use the standard next-token prediction as our ML objective. For the loss function, we employ cross-entropy loss to measure the difference between the predicted token probabilities and correct tokens.

The outcome of the pretraining stage

The pretraining stage produces a model that understands language well. This model, usually referred to as the base model, predicts text to follow the given input prompt, generating relevant and meaningful text.

Image represents a simple, vertically oriented diagram enclosed within a dashed-line border.  At the bottom, the text 'I want to learn programming' is positioned. An upward-pointing arrow connects this text to a light orange, rectangular box labeled 'Base Model' in the center.  Another upward-pointing arrow extends from the top of the 'Base Model' box to the text 'because it is a valuable skill' at the top of the diagram. The arrows visually represent a causal relationship, suggesting that the desire to learn programming ('I want to learn programming') leads to engaging with a 'Base Model,' which in turn is motivated by the perceived value of programming as a skill ('because it is a valuable skill').  The overall structure is minimalistic, focusing on the core relationship between motivation, a foundational model, and the ultimate goal.
Figure 7: Base model continuing a sentence

While the base model understands language well, it is only capable of continuing on from the text prompt. To make the model a useful chatbot that answers questions, we need to further train the base model. This leads to the next stage: supervised finetuning.

. Supervised finetuning (SFT)

SFT, also named instruction finetuning, is the second stage of the training process. In this stage, we finetune the base model on a smaller, high-quality dataset in a (prompt, response) format. The purpose of this stage is to preserve the base model’s language understanding and world knowledge while adapting its behavior to responding to prompts instead of just continuing them.

Training data

The training data for the SFT stage follows the (prompt, response) format. This data is usually called demonstration data because it demonstrates to the model how to respond to prompts.

Image represents a simple, rectangular box with rounded corners, representing a system's input and output.  The top section, labeled 'Prompt...', is a blank space intended for user input, likely text-based, to initiate a process or query.  Below this, a larger blank space labeled 'Response...' is provided for the system's output, also presumably text-based, in response to the prompt.  There are no visible connections or arrows indicating information flow between the prompt and response areas; the implication is that the input in the 'Prompt...' area triggers a process within the unseen system, resulting in the output displayed in the 'Response...' area.  At the very bottom, in small text, is the note 'text is not SVG - cannot display,' indicating a limitation in displaying the image's underlying format.
Figure 8: An example of demonstration data

The main differences between demonstration data and pretraining data, aside from format, are size and quality.

Size: Demonstration data is significantly smaller than pretraining data. It usually ranges from 10,000 to 100,000 (prompt, response) pairs. Table 2 shows the data sizes of popular demonstration datasets.

DatasetSizeNotes
InstructGPT [20]~14,500OpenAI’s GPT-3 instruction datasets
Alpaca [21]52,000Developed by Stanford researchers
Dolly-15K [22]~15,000Created by Databricks
FLAN 2022 [23]~104,000Developed by Google Research

Table 2: Common demonstration datasets

Quality: Demonstration data is of higher quality compared to pretraining data. The data is usually created by educated human contractors. In specialized industries such as healthcare or finance, it is essential to hire domain experts to ensure the accuracy and relevance of data. For instance, as shown in Table 3, over one-third of OpenAI’s labelers for GPT’s demonstration dataset held a master’s degree [20]. While this requirement is costly, it's crucial for producing reliable, industry-specific responses.

EducationPercentage
Less than a high school degree0%
High school degree10.5%
Undergraduate degree52.6%
Master’s degree36.8%

Table 3: The education levels of OpenAI’s labelers

ML objective and loss function

Although the training data differs from the pretraining stage, the model still learns a similar task: generating a text one token at a time based on the input prompt. Therefore, the ML objective and loss functions remain similar to those at the pretraining stage: next-token prediction ML objective and cross-entropy loss function.

Image represents a simplified diagram of a sequence-to-sequence model, likely used in a machine translation or text generation task.  At the bottom, the input 'What is the capital...' is fed into a rectangular 'Model' component, which represents the core neural network.  The model processes this input and outputs 'Predicted token...', visualized as four vertically stacked rectangles representing token embeddings.  Above this, 'Correct tokens' ('It is Paris.') are shown as a similar set of four vertically stacked rectangles.  Arrows indicate the flow of information: the input feeds into the model, the model produces predicted tokens, and these predicted tokens are compared to the correct tokens.  The comparison is quantified by 'cross-entropy loss,' which is calculated and represented by an upward-pointing arrow from the predicted tokens to the correct tokens.  The entire system is enclosed within a dashed box.  The rectangles represent token embeddings, with each rectangle likely containing a vector representation of a word or sub-word unit.
Figure 9: Loss calculation over a (prompt, response) example
The outcome of the SFT stage

The outcome of this stage is the SFT model, a finetuned version of the base model. Instead of merely continuing the text prompt, the SFT model generates detailed and helpful responses because it has been trained on demonstration data in a (prompt, response) format.

Image represents a simple flowchart enclosed within a dashed-line box.  At the bottom, the text 'I want to learn programming' indicates the starting point or goal. An upward-pointing arrow connects this text to a light orange, rectangular box labeled 'SFT Model,' representing a specific model or system.  Another upward-pointing arrow connects the 'SFT Model' box to the text 'Start with Python' at the top, suggesting that Python is the recommended or suggested programming language to interact with or utilize the 'SFT Model.' The overall structure depicts a linear flow, implying that to achieve the goal of learning programming ('I want to learn programming'), one should utilize the 'SFT Model' and start with Python.
Figure 10: The SFT model answers a prompt instead of continuing it

The SFT model usually generates a grammatically correct and reasonable response. However, it might not always generate the best response; its answers can be unhelpful or even unsafe. Figure 11 displays four plausible responses to a question. Only the second response is both safe and helpful. The first and fourth responses are grammatically and contextually correct but do not offer accurate advice. The third response is helpful but impolite.

Image represents a simple flowchart illustrating a generative AI model's response to a user prompt.  A central rectangular box labeled 'PromptWhat are some effective w...' represents the user's input, a question likely seeking effective ways to manage stress or similar.  From this central box, four curved arrows point to four separate rectangular boxes, each labeled 'Response 1,' 'Response 2,' 'Response 3,' and 'Response 4,' respectively. Each response box contains a different suggestion: Response 1 suggests 'Go skydiving for an adrenaline...'; Response 2 suggests 'Exercise regularly and maintain...'; Response 3 offers the more critical 'Shame on you! Try meditation!!!'; and Response 4 provides the somewhat dismissive 'Ignore your problems and hope t...'. The arrows visually depict the flow of information, showing how the AI model generates multiple diverse responses based on a single user prompt.
Figure 11: Various responses to a prompt

To ensure the model produces relevant, safe, and helpful responses, we must further finetune the model. This further finetuning is the primary focus of the next stage: RLHF.

. RLHF

RLHF, also known as the alignment stage, is the final stage in the training process. This stage aligns the model to human preferences, that is, it adapts the model to generate responses preferred by humans.

To understand RLHF, let's briefly revisit the SFT stage. In SFT, the model learns from demonstration data to produce a plausible response to a given prompt. However, demonstration data provides the model with one plausible response for a prompt, which is not necessarily the most helpful or relevant response. Usually, multiple responses can be plausible, and some will be more relevant than others, as shown in Figure 11.

If we have a separate reward model that can score how relevant a model’s response is to a prompt, we can further finetune the SFT model to generate not just any plausible response but one with a high score. This is the key idea behind RLHF. RLHF consists of two sequential steps:

  • Training a reward model
  • Optimizing the SFT model

.1 Training a reward model

The first step in RLHF is to train a reward model that evaluates the relevance of a response to a prompt. This model takes a (prompt, response) pair as input and produces a score predicting the helpfulness of the response. The higher the score, the more helpful the response is expected to be. Figure 12 illustrates the predicted scores for different (prompt, response) pairs.

Image represents a flowchart illustrating a reward model's scoring mechanism for two different responses to the same prompt.  The flowchart is divided into two sections by a dashed line, representing Example 1 and Example 2. Each section begins with a 'Prompt' box containing the text 'What are some effective w...', followed by a 'Response' box.  Example 1's response is 'Exercise regularly and maintain...', while Example 2's response is 'Shame on you! Try meditation!!!'.  Each 'Response' box is connected to a 'Reward Model' box (represented in light purple).  The 'Reward Model' processes the response and outputs a 'Score' to a circular box.  Example 1 receives a score of '5', while Example 2 receives a score of '1', indicating that the reward model assigns higher scores to responses deemed more effective or appropriate based on some underlying criteria not explicitly shown in the diagram.  The arrows clearly show the flow of information from the prompt and response to the reward model and finally to the score.
Figure 12: Reward model input and output
Reward model architecture

Training a model to output a score is a very common task in ML. There are various architectures we can employ for reward modeling: It can be a decoder-only, encoder-only, or encoder-decoder Transformer as long as it outputs a scalar value.

Based on public studies, there isn't a consistent pattern of reward models being larger or smaller than the language models they are used to train. For example, OpenAI uses a 6B reward model for the 175B language model [20]. Anthropic uses language models and reward models ranging from 10B to 52B parameters [24]. A typical option is to create a copy of the SFT model and add a prediction head to produce the relevance score for the given (prompt, response) pair.

Image represents a system for evaluating the quality of responses generated by a language model.  At the bottom, a 'Prompt' ('What is 2+2?') and a 'Response' ('Math is hard.') are input into a 'Reward Model...'. This model processes the prompt and response, producing multiple intermediate representations (shown as vertically stacked rectangles), which are then aggregated.  These aggregated representations are fed into a 'Prediction He...' module, which generates a prediction.  Finally, a 'score' (0.3 in this example) is output, representing the quality of the response as assessed by the system.  The ellipsis (...) indicates that multiple intermediate representations are generated by the Reward Model, suggesting a process involving multiple steps or features for evaluating the response.  The arrows depict the flow of information between the components.
Figure 13: Reward model architecture
Training data

To collect training data for reward modeling, we follow these steps:

  • Collect prompts: Manually create a list of prompts.
  • Generate multiple responses: Use the SFT model to generate multiple responses for each prompt.
  • Rank responses: Ask contractors to evaluate those responses and rank them based on their relevance. The reason they typically rank them instead of scoring each response is that ranking reduces subjectivity and inconsistency. It is easier and more intuitive for annotators to compare responses directly than to assign numerical scores, which can vary between annotators. This approach simplifies the evaluation process and ensures more reliable data for training.
  • Create preference pairs: Construct the training dataset by forming pairs in the format (prompt, winning response, losing response). In each pair, the winning response is preferred over the losing response based on the rankings from the previous step.

Figure 14 shows the process of collecting training data to train the reward model.

Image represents a system for evaluating responses from a Large Language Model (LLM).  The process begins (1) with a prompt list containing questions like 'What is the capital of France?', 'Name a famous physicist?', 'What's 2 + 2?', and 'Give a synonym for 'happy.''.  These prompts are fed (2) into an 'SFT Model' (likely a fine-tuned large language model), which generates three different responses (Response 1, Response 2, Response 3) for each prompt.  A human evaluator (3) then reviews these responses and determines a 'winning' and 'losing' response for each prompt, based on accuracy and quality. This information is compiled (4) into a table showing the winning and losing responses for each prompt. Finally, the evaluator provides rankings (R1 > R2 > R3, for example) indicating the relative quality of the three responses for each prompt, providing feedback on the LLM's performance.  The entire diagram illustrates a human-in-the-loop evaluation process for ranking the quality of LLM responses.
Figure 14: Collecting training data to train a reward model

Once we collect the training data, where each example is in (prompt, winning response, losing response) format, we define the ML objective and the associated loss function to train our reward model.

ML objective and loss function

The reward model aims to predict a higher score for the winning response compared to the losing response. More formally, for a given (prompt, winning response, losing response), the ML objective is to maximize Swin −Slose S_{\text {win }}-S_{\text {lose }}Swin ​−Slose ​, where:

  • Swin S_{\text {win }}Swin ​ is the predicted score for the (prompt, winning response) pair
  • Slose S_{\text {lose }}Slose ​ is the predicted score for the (prompt, losing response) pair

To achieve this ML objective, we need a loss function that penalizes the model when the difference between the winning and losing scores is too small. A commonly used loss function for this purpose is the margin ranking loss. The loss function is defined as:

Where mmm is a hyperparameter defining the margin. This margin indicates the minimum desired difference between the scores of the winning and losing responses. If the difference between SwinS_{\text {win}}Swin​ and SloseS_{\text {lose}}Slose​ is less than mmm, the optimizer will update the model parameters so that either SwinS_{\text {win}}Swin​ increases or SloseS_{\text {lose}}Slose​ decreases.

Image represents a simplified reward model for a generative AI system.  A central, peach-colored rectangle labeled 'Reward Model' receives input from three sources: 'Prompt,' displaying the text 'What is 2+2?'; 'Winning res...', showing the correct answer 'Four.'; and 'Losing resp...', displaying the incorrect answer 'Math is hard.'  Arrows indicate the flow of information into the Reward Model.  The Reward Model then outputs two values, represented by  '$S_{win}' and '$S_{los}', connected by a dashed line labeled 'Margin...', suggesting a comparison or difference between the winning and losing reward signals. Arrows point from the Reward Model to these output values, indicating that the model assigns different reward signals based on the correctness of the response.  The entire diagram illustrates how the system evaluates responses based on a prompt and assigns rewards accordingly.
Figure 15: Reward modeling loss calculation for a single example from training data
The outcome of reward modeling

The outcome of this step is a reward model that predicts relevance scores for (prompt, response) pairs. These scores reflect human judgments and are crucial for the second step in RLHF.

Image represents a simplified diagram of a reinforcement learning system, specifically focusing on the reward mechanism.  The diagram shows a rectangular box labeled 'Reward Model' in peach/light-orange with a golden border, representing the core component that evaluates the quality of a generated response.  Below this box, '(Prompt, Response)' indicates that the input to the Reward Model consists of a prompt and the corresponding generated response. A single upward-pointing arrow connects '(Prompt, Response)' to the 'Reward Model,' signifying the flow of data.  Another upward-pointing arrow connects the 'Reward Model' to the word 'Score' at the top, indicating that the Reward Model outputs a numerical score based on its evaluation of the prompt and response pair.  The overall structure illustrates a process where a prompt and response are fed into a Reward Model, which then generates a score reflecting the quality of the response.
Figure 16: The reward model predicts the relevance score for a (prompt, response) pair

.2. Optimizing the SFT model

In the second step of RLHF, the SFT model is optimized with the help of the reward model. The purpose of this step is to adapt the SFT model to generate responses that are not only plausible but also helpful, based on the scores from the reward model.

A common approach to optimize the SFT model is to employ a reinforcement learning (RL) algorithm such as proximal policy optimization (PPO) [25], where the SFT model is finetuned to maximize the scores predicted by the reward model. This finetuning process performs the following steps iteratively:

  • Generate model responses: The model generates multiple possible responses for a given prompt.
  • Compute rewards: The reward model scores these responses.
  • Update model weights: The RL algorithm updates model weights to maximize the expected reward. This step reinforces responses that receive higher scores from the reward model.

Figure 17 shows this process for a single response. In practice, multiple responses are generated and evaluated simultaneously.

Image represents a simplified reinforcement learning (RL) system diagram.  A light orange rectangle labeled 'RL Model' is the core component, receiving input from an unspecified source indicated by 'What is...'. The RL model processes this input and produces an output, represented by a downward arrow and the text 'Math is hard.', which signifies the model's computation. This output feeds into a light green rectangle labeled 'Reward...', representing the reward signal generated by the model's actions.  A score of '1.8' is shown, likely indicating the performance metric of the RL model.  This reward signal is then fed into a purple rectangle labeled 'PPO,' which stands for Proximal Policy Optimization, an optimization algorithm.  The PPO algorithm uses the reward to optimize the RL model, indicated by an arrow labeled 'Optimize' connecting PPO back to the RL Model.  The system forms a closed loop where the PPO algorithm improves the RL model based on the reward signal, creating a continuous optimization process.
Figure 17: Optimizing the model with the PPO algorithm
Training data

For this step, the training data usually includes a list of prompts created by contractors, typically ranging in number from 10,000 to 100,000.

ML objective and loss function

Well-known LLMs such as ChatGPT and Llama use RL algorithms such as PPO and direct policy optimization (DPO) [26]. However, the details of these algorithms are usually beyond the scope of most ML system design interviews. For more information, refer to [27] and [28].

The outcome of RLHF

The outcome of the RLHF stage is usually the final model that can be deployed as a chatbot. Table 4 lists some of the most popular LLMs.

LLM nameDeveloperRelease dateAccessParameters
o1OpenAISeptember 12, 2024Preview onlyUnknown
GPT-4oOpenAIMay 13, 2024APIUnknown
Claude 3AnthropicMarch 14, 2024APIUnknown
Gemini 1.5DeepMindFebruary 2, 2024APIUnknown
Llama 3Meta AIApril 18, 2024Open-Source8 and 70 billion
Grok-1xAINovember 4, 2023Open-Source314 billion
Mixtral 8x22BMistral AIApril 10, 2024Open-Source141 billion
GemmaDeepMindFebruary 21, 2024Open-Source2 and 7 billion
Phi-3MicrosoftApril 23, 2024Open-Source3.8 billion
DBRXDatabricksMarch 27, 2024Open-Source132 billion

Table 4: Popular LLMs

To summarize the training section, we employ a three-stage training strategy, including pretraining, SFT, and RLHF. Pretraining involves training a model on a large corpus of text to gain a broad language understanding. SFT finetunes the model to adapt its output to a (prompt, response) format. RLHF further refines the model's responses to be helpful, safe, and aligned with human preferences.

Image represents a flowchart illustrating the stages involved in training a large language model (LLM), specifically highlighting the progression from a base model to a refined model using reinforcement learning.  The flowchart is divided into four main columns representing distinct training stages: Pretraining, Supervised Finetuning, Reward Modeling, and Reinforcement Learning. Each stage consists of three rows detailing the dataset used, the computational resources employed (number of GPUs), and the algorithm applied.  The Pretraining stage uses internet data, thousands of GPUs, and a language modeling algorithm to create a 'Base Model' (examples: GPT, Llama, PaLM).  The Supervised Finetuning stage takes the Base Model as input, utilizes demonstration data and 1-100 GPUs with a language modeling algorithm to produce an 'SFT Model' (example: Vicuna-13B).  The Reward Modeling stage uses comparisons data, 1-100 GPUs, and a regression algorithm to create a 'Reward Model' based on the SFT Model. Finally, the Reinforcement Learning stage uses prompts, 1-100 GPUs, and a reinforcement learning algorithm, taking both the SFT Model and the Reward Model as input, to generate an 'RL Model' (examples: ChatGPT, Gemini). Arrows indicate the flow of information and the model's progression through each stage.  Each stage's input and output are clearly labeled, along with the computational resources and algorithms used.
Figure 18: Summary of LLM training, inspired by [29]

Sampling

In LLMs, sampling refers to how we select tokens from the model's predicted probability distribution to generate coherent and helpful responses.

Image represents a simplified illustration of a Large Language Model (LLM) generating text.  At the bottom, a sequence of tokens 'What is 2 + 2 ?' is fed as input to the LLM (represented by a peach-colored rectangle). The LLM processes this input and outputs a probability distribution for the next token. This distribution is shown as a vertical column of numbers next to the LLM, with probabilities 0.01, 0.01, 0.93, and 0.00 assigned to different tokens.  A curved arrow connects this probability column to a histogram labeled 'Token probabilit...', which visually represents the same probability distribution. The histogram shows that the token 'four' has a 93% probability, '<EOS>' (end of sequence) has 1%, 'able' has a small probability, and 'zebra' has a very small probability.  An upward arrow connects the highest probability token, 'four', to the output of the LLM, indicating that the LLM selects 'four' as the next word in the sequence based on its highest probability.
Figure 19: Selecting the next token from predicted probabilities

As discussed in Chapter 2, there are various methods for generating text. Some are deterministic, while others are stochastic. In this section, we examine these methods to determine which works better for open-ended text generation.

Image represents a hierarchical tree diagram illustrating different text generation methods.  At the top is a rectangular box labeled 'Text Generation Methods,' which branches down into two main categories: 'Deterministic' and 'Stochastic.'  The 'Deterministic' category further subdivides into two methods: 'Greedy Search' and 'Beam...', represented by rectangular boxes connected by downward-pointing arrows indicating the flow of information or hierarchical relationship.  Similarly, the 'Stochastic' category branches into three methods: 'Multinomial...', 'Top-k...', and 'Top-p...', each also depicted as rectangular boxes connected by downward-pointing arrows.  The overall structure shows a top-down breakdown of text generation approaches, classifying them as either deterministic or stochastic and then further specifying individual techniques within each category.  The ellipses (...) after some method names suggest further details or parameters are omitted for brevity.
Figure 20: Common methods for generating text

Deterministic methods

Deterministic methods such as beam search work well for tasks with short, predictable text lengths. However, they are less effective for open-ended generation, such as dialogue, where output length varies. Let's examine the common issues that arise when using deterministic methods like greedy search or beam search to generate text from LLMs.

Greedy search selects the token with the highest probability at each step of the generation process.

Image represents a directed graph illustrating word probabilities in a sentence.  A thick, solid horizontal line labeled 'How' connects to a box labeled '0.56' representing the word 'are'.  From '0.56', a thick solid line labeled 'you' connects to a box labeled '0.91'.  From '0.91', a thick solid line labeled 'doing' connects to a box labeled '0.39'.  Dashed lines represent weaker connections.  A dashed line labeled 'come' connects 'How' to a box labeled '0.14'.  A dashed line labeled 'am' connects '0.56' to a box labeled '0.03'. A dashed line labeled 'dog' connects '0.56' to a box labeled '0.01'. A dashed line labeled 'do' connects 'How' to a box labeled '0.26'. A dashed line labeled 'work' connects '0.91' to a box labeled '0.001'. A dashed line labeled '?' connects '0.91' to a box labeled '0.38'.  Each box contains a numerical value, presumably representing the probability of that word appearing in the context of the sentence, given the preceding words.  The graph visually depicts the probabilistic relationships between words in a sentence structure.
Figure 21: Greedy search

While this method is straightforward and often produces coherent text, it has two major issues:

  • Repetition
  • Suboptimal generation

Repetition: When we use greedy search to select the next tokens, the text quickly starts repeating. This is because the model sometimes gets "stuck" in loops, reusing the same sequence of tokens. This happens when the model identifies certain words following each other with high probability.

Image represents a simplified diagram illustrating a Large Language Model (LLM) interaction.  A peach-colored rectangle labeled 'LLM' is the central component.  Below the rectangle, the text 'How is the weather?' acts as an input prompt to the LLM.  An upward-pointing arrow connects this prompt to the LLM, indicating the flow of information into the model.  Above the rectangle, the text 'The weather today is sunny. The weathe...' represents the output generated by the LLM in response to the input prompt. An upward-pointing arrow connects the LLM to this output, showing the information flow from the model. The overall diagram depicts a basic question-answering process where a user's query ('How is the weather?') is processed by the LLM, resulting in a textual response ('The weather today is sunny...').
Figure 22: Repetitive output

Suboptimal generation: Greedy search ignores alternative paths during the text generation. It might miss a high-probability sequence of tokens hidden behind a low-probability token.

Beam search improves upon greedy search by considering multiple sequences simultaneously. At each step, it keeps track of the top k sequences, where k is configurable.

Image represents a probabilistic context-free grammar (PCFG) tree illustrating word probabilities in a sentence.  A central node labeled 'How' branches into three main paths, each representing a different word choice: 'come,' 'are,' and 'do.'  These words are connected with thick lines to subsequent nodes containing probabilities (0.24, 0.31, and 0.26 respectively). Each of these nodes further branches out via thinner, dashed lines to other words, representing possible continuations of the sentence. For example, the 'are' node connects to 'plants,' 'animals,' 'you,' and 'am' with associated probabilities (0.001, 0.21, 0.36, and 0.03 respectively for the 'are' node). Similarly, the 'come' node connects to 'are' and 'plants' with probabilities (0.24 and 0.21 respectively). The 'do' node connects to 'you,' 'the,' and 'people' with probabilities (0.63, 0.001, and 0.21 respectively).  The numbers within the boxes represent the conditional probability of a word given its parent node in the tree.  The overall structure shows the branching possibilities and associated probabilities of different word sequences, suggesting a language model's prediction of word choices based on preceding words.
Figure 23: Beam search with a beam width of 3

Beam search allows for more exploration and produces higher-quality text than greedy search. However, it can struggle with open-ended generation. Two common issues with beam search are:

  • Inefficiency
  • Repetition

Inefficiency: Beam search can be computationally inefficient because it requires evaluating multiple sequences at once, which can slow down the generation process.

Repetition: Beam search can lead to repetitive and generic responses. It sometimes gets stuck in a loop and repeats common phrases.

So far, we've seen that deterministic methods struggle with repetition and do not work well for text generation. Let's explore stochastic methods, which are more commonly used for text generation in LLMs.

Stochastic methods

Stochastic methods generate text by introducing randomness. This randomness makes them more suitable for open-ended text generation. Three popular stochastic methods are:

  • Multinomial sampling
  • Top-k sampling
  • Top-p (nucleus) sampling
Multinomial sampling

Multinomial sampling selects the next token based on the probability distribution of the model's predictions. Each token has a probability associated with it, and a token is chosen based on these probabilities.

Image represents a bar chart illustrating the probability distribution of choosing different auxiliary verbs ('are,' 'is,' 'do,' 'should,' 'hard') to complete a sentence fragment, likely within a natural language processing context.  The horizontal axis displays the auxiliary verbs, with their corresponding probabilities shown as bar heights.  'are' has the highest probability (37%), followed by 'is' (21%), 'do' (12%), 'should' (4%), 'hard' (2%), and '0.13%' representing progressively lower probabilities, indicated by an ellipsis suggesting further, less likely options.  Two dashed arrows highlight the most probable choices: one points to 'are' with the text 'Choose 'are' with...', indicating its high likelihood of selection; the other points to 'hard' with the text 'Choose 'hard' with 2...', suggesting a less likely but still considered option. The bottom annotation,  `$P(w I \text{'How'})$`, likely represents a conditional probability formula, indicating the probability of choosing a word *w* given the context 'How'.
Figure 24: Multinomial sampling

This approach ensures a wide variety of possible outputs. However, it introduces a significant amount of randomness, especially when the probability distribution is flat. This randomness often results in generations that are not coherent. For example, the generated text shown in Figure 25 is the output of the GPT-2 model using multinomial sampling.

Image represents a simple generative model architecture.  At the bottom is a rectangular box labeled 'Model,' representing a language model.  Above it, the text 'Multinomial samp...' indicates that the model uses multinomial sampling to generate text. A vertical arrow connects the 'Model' box to a large rectangular box at the top containing the text 'I enjoy walking with my cute dog for the rest of t...', which represents the generated text output. The arrow points upwards, showing the flow of information from the model to the generated text.  The ellipsis ('...') suggests that the generated text is truncated and continues beyond what's shown.  The overall diagram illustrates a basic text generation process where the model produces text through multinomial sampling.
Figure 25: GPT-2 output using multinomial sampling

Due to coherence issues, multinomial sampling is rarely used in LLMs for text generation.

Top-k sampling

Top-k sampling [30] is a more advanced method that selects from the k most likely tokens rather than sampling from the entire distribution.

Image represents a bar chart illustrating the probability distribution of different words given the context 'How'.  The horizontal axis displays a series of words: 'are,' 'is,' 'do,' 'should,' 'hard,' and an ellipsis indicating further words. The vertical axis represents probability, ranging from 0.0 to 1.0.  The height of each bar corresponds to the probability of that word following 'How'.  The bars are ordered from highest to lowest probability: 'are' (37%), 'is' (21%), 'do' (12%), 'should' (4%), 'hard' (2%), and '0.13%' representing a much lower probability. A dashed line encloses the three highest-probability words ('are,' 'is,' and 'do'). A curved dashed arrow extends from this enclosed area to the right, pointing to the text 'Sample from top three...', indicating that a selection is made from these top three words.  The bottom of the image shows a mathematical formula:  `$P(w I \text{'How'})$`, which likely represents the conditional probability of word *w* given the context 'How'.
Figure 26: Example of top-k sampling with k=3

Here is a step-by-step process to select the next token in top-k sampling:

  • The model predicts the probability distribution for the next token, providing a probability for each token in the vocabulary.
  • The tokens are sorted in descending order based on their predicted probabilities.
  • The top k tokens with the highest probabilities are considered for sampling.
  • The probabilities of the top k tokens are normalized to ensure they sum to 1.
  • A token is sampled from this normalized distribution.
Image represents a simple generative model architecture.  At the bottom is a rectangular box labeled 'Model,' representing a language model or similar generative AI.  Above this box, a vertical arrow points upwards, labeled 'Top-k sampling (k=50),' indicating that the model's output is processed using this sampling technique, where only the top 50 most probable next words are considered.  At the very top is a rectangular box containing the text 'I enjoy walking with my cute dog for the rest of...', representing an input prompt or a partial text sequence fed into the 'Model.' The arrow indicates that the output of the 'Model' after Top-k sampling is the continuation of the input text.  The value 'k=50' specifies that the Top-k sampling algorithm considers only the 50 most likely word candidates at each step of text generation.
Figure 27: GPT-2 output using top-k sampling with k=50

Top-k sampling balances coherence and diversity by picking from the top-k tokens. This reduces the chance of choosing irrelevant tokens while allowing some randomness. GPT-2 initially used top-k sampling, which was crucial to its success and popularity.

A major limitation of top-k sampling is that it always picks from a fixed number of top tokens. This is problematic depending on how the predicted probabilities are spread out. Let’s understand why.

Predicted token probabilities can be sharply or evenly distributed. With a sharp distribution, limiting choices to a fixed number of top tokens can produce nonsensical results because the model might miss the best choice. Conversely, with a flat distribution, this fixed limit restricts the model's creativity by not considering enough word options. For example, as shown in Figure 28, the model is 89% confident that the next token should be “lot,” but top-k sampling still considers "much" and "high" as possible next tokens to sample from.

Image represents a bar chart illustrating the probability distribution of a word (or n-gram) within a corpus, specifically focusing on the top three most frequent words. The horizontal axis displays different words: 'lot,' 'much,' 'high,' 'where,' 'this,' and an ellipsis indicating further words with lower probabilities. The vertical axis represents probability, ranging from 0.0 to 1.0.  The chart shows a tall bar for 'lot' representing 89% probability, followed by progressively shorter bars for 'much' (4%), 'high' (3%), 'where' (2%), 'this' (1%), and '0.13%' for the last visible word. A dashed line encloses the bars representing the top three most frequent words ('lot,' 'much,' 'high'). A curved dashed arrow extends from this enclosed area to the right, pointing to the text 'Sample from top three mos...', indicating that the enclosed area represents a sample from the top three most frequent words.  Below the chart, the formula '$P(w I \text{'Thanks a'})$' suggests the probability of word *w* given the preceding words 'Thanks a'.
Figure 28: Top-k sampling in sharp distribution

This limitation is addressed in top-p sampling, which we examine next.

Top-p (nucleus) sampling

Top-p sampling [31], also known as nucleus sampling, was developed in 2019. This method dynamically adjusts the number of tokens considered based on their combined probabilities. Instead of sampling only from the most likely k tokens, it chooses from the smallest possible set of tokens whose cumulative probability exceeds the probability p. This provides a more flexible and adaptive approach compared to top-k sampling.

Image represents two bar charts illustrating the concept of top-p sampling in a language model.  Each chart displays the probability distribution of the next word given a preceding text prompt. The left chart shows the probability distribution for the prompt 'Thanks a...', with 'lot' having the highest probability (89%), followed by 'much' (4%), 'high' (3%), 'where' (2%), 'this' (1%), and others with probabilities less than 1%.  A dashed line encloses the bars representing the top-p selection, indicating that the model would likely select from these words based on their cumulative probability.  The right chart shows the probability distribution for the prompt 'How', with 'are' (31%), 'is' (29%), 'do' (24%), 'come' (7%), 'confident' (4%), and others having lower probabilities.  Similarly, a dashed line encloses the top-p selection, suggesting the model would choose from these words.  Both charts have a y-axis ranging from 0.0 to 1.0 representing probability, and an x-axis showing the potential next words and their associated probabilities.  The text '$P(w I \text{'Thanks a'...}$ and '$P(w I \text{'How'})$' below each chart indicates the conditional probability calculation being visualized, where 'P' represents probability, 'w' represents the next word, and 'I' represents the given text prompt.  Curved dashed arrows labeled 'Top-p sampling...' point from the dashed selection boxes to the right, indicating the sampling process.
Figure 29: Top-p sampling adaptively chooses tokens based on the probability distribution

Here is a step-by-step process to select the next token in top-p sampling:

  • The model predicts the probability distribution for the next token, providing a probability for each token in the vocabulary.
  • The tokens are sorted in descending order based on their predicted probabilities.
  • Instead of selecting a fixed number of tokens, top-p sampling chooses the smallest possible set of tokens whose cumulative probability exceeds a threshold p.
  • The probabilities of the selected tokens are normalized to ensure they sum to 1.
  • A token is sampled from this normalized distribution.
Image represents a simple generative model architecture.  At the bottom is a rectangular box labeled 'Model,' representing a language model.  An upward-pointing arrow connects this box to a text label above it reading 'Top-p sampling (p=0.92),' indicating that the model's output is processed using top-p sampling with a probability threshold of 0.92. This sampling method selects the most probable words whose cumulative probability exceeds 0.92.  Finally, an upward-pointing arrow connects the sampling method to a rectangular box at the top containing the text 'I enjoy walking with my cute dog for the rest of...', which represents the generated text output of the model after the top-p sampling.  The overall diagram illustrates the flow of information from the model, through the top-p sampling process, to the final generated text.
Figure 30: GPT-2 output using top-p sampling with p=0.92

The top-p sampling is widely used in advanced LLMs to generate human-like text. This method ensures the text is coherent and contextually relevant by focusing on the most probable tokens while allowing some randomness.

While we covered the key aspects of different sampling methods, there are more details to each method. Two popular techniques often used in advanced sampling methods are:

  • Temperature
  • Repetition penalty
Temperature

Temperature is a parameter in sampling methods that controls the randomness of predictions during sampling. Mathematically, the temperature parameter T scales the logits (raw scores) of the model’s output before applying the softmax function to generate probabilities. The adjusted softmax formula with temperature is given by:

where:

  • xix_ixi​ are the logits (raw scores) for each possible output
  • TTT is the temperature parameter
  • pip_ipi​ represents the probability of output iii after applying the softmax function

When T=1T=1T=1, the softmax function operates normally. When T>1T>1T>1, the model generates a more uniform probability distribution, making predictions more random and diverse. Higher temperatures increase randomness, which helps the model generate more creative outputs. If the model starts to stray off-topic or produce meaningless outputs, this indicates that the temperature has been set too high.

Conversely, when T<1T<1T<1, the model's output becomes more deterministic, with the highest logit values having more influence on the final prediction. Lower temperatures reduce randomness, which is more suitable for tasks requiring precise answers, such as summarization or translation. If the model starts to repeat itself, this indicates that the temperature has been set too low. A temperature of 0 consistently leads to the same output, making the sampling deterministic.

Image represents a comparative visualization of histograms, each depicting a probability distribution.  Four separate histograms are presented, arranged horizontally. Each histogram is enclosed within a dashed-line box.  The x-axis of each histogram is implicitly defined and represents a range of values (not explicitly labeled), while the y-axis (also implicitly defined) represents the frequency or probability of those values. The histograms differ in their distributions, showing varying degrees of concentration and spread.  Each histogram is labeled at the bottom with 'Temperature = [value]', where the value is 0.0, 0.5, 2, and 5 respectively, indicating that the histograms likely represent probability distributions at different temperature settings. The height of the bars in each histogram corresponds to the probability or frequency of the values within the corresponding bin.  The overall image suggests an analysis of how a probability distribution changes with varying temperature parameters.
Figure 31: Different temperature values applied to the same logits
What are typical temperature values?

Most model providers set the permissible temperature range between 0 and 2. Figure 32 illustrates OpenAI's API reference for the temperature setting.

Image represents a rectangular box with a light gray border containing only the text 'temperature...' centrally aligned.  No other components, connections, or information flows are depicted within the box.  Below the box, a small caption reads 'Text is not SVG - cannot display,' indicating that the image is a placeholder or a failed attempt to render a more complex diagram, likely an SVG (Scalable Vector Graphics) file, which would have contained visual elements beyond simple text.  The overall impression is that the image is incomplete or a representation of missing data related to 'temperature.'
Figure 32: OpenAI’s temperature documentation [32]

In modern LLMs, the temperature parameter typically ranges from 0.1 to 1.5. When set beyond 1.5, outputs can become increasingly erratic and less coherent, which is undesirable. The optimal value depends on the desired behavior and is often determined empirically. The following table, created by [33], suggests possible temperature values for several use cases.

Use caseTemperatureTop-pDescription
Code generation0.20.1Generates code that adheres to established patterns and conventions. Output is more deterministic and focused. Useful for generating syntactically correct code.
Creative writing0.70.8Generates creative and diverse text for storytelling. Output is more exploratory and less constrained by patterns.
Chatbot responses0.50.5Generates conversational responses that balance coherence and diversity. Output is more natural and engaging.

Table 5: Empirical temperature and top-p ranges for different tasks

Repetition penalty

Similarly, applying a repetition penalty can explicitly reduce the likelihood of generating repetitive sequences of tokens. This can be achieved by terminating the generation when repetitive n-grams are detected (as controlled by the “no_repeat_ngram_size” parameter in Hugging Face models) or by directly modifying the probabilities of tokens that have already been sampled earlier in the sequence (such as the “frequency_penalty” in the ChatGPT API).

If you are interested in learning more about sampling methods in LLMs, refer to [30].

Evaluation

Offline evaluation metrics

Evaluating LLMs like ChatGPT requires more than traditional metrics such as perplexity. These models behave in complex ways and perform differently across various tasks. Therefore, we need to assess their skills in different tasks to ensure the model is both effective and safe.

In this section, we evaluate our LLM from the following perspectives:

  • Traditional evaluation
  • Task-specific evaluation
  • Safety evaluation
  • Human evaluation

Traditional evaluation

Traditional evaluation provides an initial understanding of the LLM’s performance using typical offline metrics. A common metric is perplexity, which measures how accurately the model predicts the exact sequence of tokens in the training data. A low perplexity value indicates that the model assigns higher probabilities, on average, to the tokens in the training data.

While these metrics are important for initial evaluation, they do not provide insights into an LLM's capabilities or limitations. For example, a low perplexity indicates the model is good at predicting the next tokens but does not measure its ability to understand code or solve math problems.

Task-specific evaluation

To effectively evaluate an LLM, we need to assess its performance across diverse tasks such as mathematics, code generation, and common-sense reasoning. This comprehensive approach helps identify the model’s strengths and weaknesses. Commonly used tasks for evaluating LLM’s capabilities are:

  • Common-sense reasoning
  • World knowledge
  • Reading comprehension
  • Mathematical reasoning
  • Code generation
  • Composite benchmarks
Common-sense reasoning

Common-sense reasoning evaluates a model's ability to make inferences based on everyday situations and general knowledge. It tests the model's understanding of basic human experiences, logical connections, and assumptions that people naturally make. Examples include interpreting idioms, understanding cause and effect in typical scenarios, and predicting likely outcomes in social situations.

Image represents a simple block diagram illustrating a basic input-output system, likely related to a generative AI model.  The diagram is enclosed within a dashed rectangular border.  The main body is divided into two sections by a vertical line. The left section, labeled 'Prompt...', represents the input area where a user would provide a prompt or query to the system. The right section, labeled 'Answer...', represents the output area where the system's response or generated content would be displayed. A single horizontal line connects the 'Prompt...' and 'Answer...' sections, indicating the flow of information from input to output.  The text 'Text is not SVG - cannot display' at the bottom indicates that the image itself is a placeholder and not a functional representation of a system.
Figure 33: Example of common-sense reasoning

Typical benchmarks for common-sense reasoning are PIQA (Physical Interaction QA) [34], SIQA [35], HellaSwag [36], WinoGrande [37], OpenBookQA [38], and CommonsenseQA [39], each of which focuses on different aspects. For example, the CommonsenseQA benchmark is a multiple-choice question dataset for which the questions require common-sense knowledge to answer. PIQA focuses on reasoning about physical interactions in everyday situations, while HellaSwag focuses on everyday events.

World knowledge

World knowledge refers to the model's factual knowledge about the world, including historical facts, scientific information, geography, and current events. An example would be answering questions about significant historical events or scientific principles.

Image represents a simple system diagram depicting a basic input-output process.  The diagram is enclosed within a dashed rectangular border.  The interior is divided into two sections by a vertical line. The left section, labeled 'Prompt...', represents the input to the system. A horizontal line connects the 'Prompt...' section to the right section, indicating the flow of information. The right section, labeled 'Answer...', represents the output generated by the system in response to the input.  No internal components or processes are shown within the system; only the input and output are explicitly represented. The text 'Text is not SVG - cannot display' is present at the bottom, indicating that the image is a placeholder and lacks detailed internal representation.
Figure 34: World knowledge example

Common benchmarks for this task include:

  • TriviaQA [40]: Questions are gathered from trivia and quiz-league websites.
  • Natural Questions (NQ) [41]: A dataset from Google that includes questions and answers found in natural web queries.
  • SQuAD (Stanford Question Answering Dataset) [42]: Contains questions based on Wikipedia articles.
Reading comprehension

Reading comprehension tasks evaluate a model's ability to understand and interpret text passages and answer questions based on them. This is critical for assessing a model’s ability to extract information from and reason in relation to given texts.

Image represents a simple diagram illustrating a basic input-output system, likely related to a large language model (LLM) or similar generative AI.  The diagram is enclosed within a dashed rectangular border.  This border is divided into two equal sections by a vertical line. The left section is labeled 'Prompt...' indicating the input area where a user would provide a text prompt or query. The right section is labeled 'Answer...', representing the output area where the system would generate a response. A single horizontal line connects the top of both sections, suggesting a unified system.  No explicit connections or data flow arrows are shown, implying a direct, implicit relationship between the prompt input and the answer output. The text 'Text is not SVG - cannot display' at the bottom indicates that the image is a static representation and not an interactive SVG.
Figure 35: Reading comprehension example from SQuAD

Typical benchmarks for reading comprehension are SQuAD [42], QuAC [43], and BoolQ [44].

Mathematical reasoning

Mathematical reasoning tasks evaluate a model's ability to solve mathematical problems.

Image represents a simple block diagram illustrating a basic input-output system, likely depicting a generative AI model.  The diagram is enclosed within a dashed-line rectangle.  The rectangle is horizontally divided into two sections by a solid line. The left section, labeled 'Prompt...', represents the input to the system, where a user would provide a text prompt or query. The right section, labeled 'Answer...', represents the output of the system, where the AI's generated response would appear.  A vertical line separates the input and output sections, visually suggesting a processing step occurring between them, although no internal components or processes are explicitly shown.  The information flow is unidirectional, from the 'Prompt...' input to the 'Answer...' output.  The overall simplicity suggests a high-level overview of the system, focusing solely on the input and output without detailing the internal workings of the AI model.
Figure 36: Mathematical reasoning example from GSM8K [45]

Two common benchmarks for mathematical reasoning tasks are:

  • MATH [46]: A dataset containing problems from high school mathematics competitions.
  • GSM8K (Grade School Math 8K) [45]: A dataset with grade school math problems to test the model's problem-solving skills.
Code generation

Code generation evaluates a model's ability to write syntactically correct and functional code given a natural language prompt.

Image represents a simple diagram illustrating a prompt-response interaction, likely within a code generation or large language model context.  The diagram is divided into two main rectangular sections by a vertical line. The left section, labeled 'Prompt...', is a blank space representing the input prompt given to the system. The right section, labeled 'Answer', contains the text 'def is_prime(n):...', indicating the system's response, which appears to be the beginning of a Python function definition for checking if a number is prime.  The two sections are separated by a horizontal line, suggesting a clear input-output relationship. The entire diagram is enclosed within a dashed-line rectangle, further emphasizing the system's boundaries.  No explicit data flow arrows are shown, but the implied flow is from the 'Prompt...' section to the 'Answer' section, representing the processing of the input prompt to generate the output response.
Figure 37: Code generation example from HumanEval

Common benchmarks for code generation are:

  • HumanEval [47]: Python coding tasks.
  • MBPP (MultiPL-E Benchmarks for Programming Problems) [48]: Multiple programming language tasks to evaluate multilingual code generation capabilities.
Composite benchmarks

In addition to specific benchmarks described above, composite benchmarks combine multiple tasks for a broader assessment. Popular composite benchmarks are:

  • MMLU (Massive Multitask Language Understanding) [49]: Consists of multiple-choice questions from a wide range of subjects including humanities, STEM, social sciences, and more, at various difficulty levels.
  • MMMU (Massive Multilingual Multitask Understanding) [50]: MMMU includes a wide range of multiple-choice questions covering many subjects with varying levels of difficulty. Unlike MMLU, which focuses on English, MMMU tests the models’ ability to understand and generate accurate responses across different languages, assessing not only multilingual capabilities but also reasoning and cross-cultural knowledge.
  • AGIEval [51]: A comprehensive benchmark designed to test artificial general intelligence across multiple domains and tasks.
  • Meta Llama 3 human evaluation [13]: A high-quality human evaluation set containing 1,800 prompts that cover 12 key use cases: asking for advice, brainstorming, classification, closed question answering, coding, creative writing, extraction, inhabiting a character/persona, open question answering, reasoning, rewriting, and summarization.

To summarize, we use various tasks and benchmarks to evaluate LLMs’ task-specific performance. This evaluation covers understanding and generating human-like responses across various domains. However, evaluation doesn't stop there. Safety evaluation is crucial for the responsible deployment of these models. Let's look deeper.

Safety evaluation

Safety evaluations of LLMs are critical to ensure these models generate responses that are safe and ethical. These evaluations focus on various tasks that help identify and mitigate risks such as the generation of harmful content. The main aspects of safety evaluation include:

  • Toxicity and harmful content
  • Bias and fairness
  • Truthfulness
  • User privacy and data leakage
  • Adversarial robustness
Toxicity and harmful content

We evaluate a model's ability to avoid generating toxic content. Toxicity includes:

  • Hate speech
  • Abusive language
  • Content that may pose harm to individuals, groups, or society
  • Content useful for planning attacks or violence
  • Instructions for finding illegal content
Image represents a simple, high-level diagram illustrating a basic input-output system, possibly related to a large language model or similar generative AI.  The diagram is divided into two equal rectangular boxes by a horizontal and a vertical line, creating four quadrants.  The top-left quadrant contains the label 'Prompt...' indicating an input area where a user would provide a prompt or query. The bottom-right quadrant is labeled 'Answer...', representing the output area where the system's response or generated content would appear.  A horizontal line connects the 'Prompt...' and 'Answer...' labels, visually representing the flow of information from input to output. The dashed lines around the entire diagram suggest a system boundary.  No other components, connections, or data flow details beyond this basic input-output relationship are depicted.
Figure 38: Model’s expected response to toxic prompts

Commonly used benchmarks to evaluate a model's toxicity are:

  • RealToxicityPrompts [52]: Consists of about 100,000 prompts that the model must complete; then a toxicity score is automatically evaluated using PerspectiveAPI [53].
  • ToxiGen [54]: This benchmark tests a model's ability to avoid generating discriminatory language.
  • HateCheck [55]: A suite of tests specifically for hate speech detection, covering various types of hate speech.

Evaluating models using these benchmarks helps identify potential risks and improve the ability of models to generate safe and respectful content.

Bias and fairness

We assess the model's responses for potential biases. This includes detecting gender, racial, and other biases in generated content.

Typical benchmarks are:

  • CrowS-Pairs [56]: Contains paired sentences differing in only one attribute (e.g., gender) to test for bias. This dataset enables measuring biases in 9 categories: gender, religion, race/color, sexual orientation, age, nationality, disability, physical appearance, and socioeconomic status.
  • BBQ [57]: A dataset of hand-written question sets that target attested social biases against different socially relevant categories.
  • BOLD [58]: A large-scale dataset that consists of 23,679 English text generation prompts for bias benchmarking across five domains.

These benchmarks help us ensure the model treats all demographic groups fairly and equally.

Truthfulness

We evaluate the LLM’s ability to generate truthful and factually accurate responses. This includes distinguishing between factual information and common misconceptions or falsehoods.

Image represents a simple diagram illustrating a basic input-output model, likely for a generative AI system.  The diagram is divided into two equal-sized rectangular boxes by a horizontal line, further subdivided into two equal-sized boxes by a vertical line. The top-left box is labeled 'Prompt...', indicating it's where user input or prompts are entered. The bottom-left box is empty, implying it's where the processed prompt would be stored or displayed.  The top-right box is empty, suggesting it's a placeholder for internal processing steps. The bottom-right box is labeled 'Answer...', indicating it's where the AI's generated response or output is displayed.  The boxes are outlined with dashed lines, suggesting a conceptual representation rather than a detailed architectural diagram.  There are no explicit connections shown between the boxes, implying a simplified representation of the data flow from prompt to answer.  The text 'Text is not SVG...cannot display' at the bottom indicates a limitation in displaying the image's content.
Figure 39: Truthfulness example from TruthfulQA

A common benchmark to evaluate truthfulness is TruthfulQA [59]. It measures the truthfulness of a model, i.e., its ability to identify when a claim is true. This benchmark can evaluate the risks of a model generating misinformation or false claims.

User privacy and data leakage

We evaluate the LLM’s tendency to leak sensitive information that it may have been exposed to during training. Since LLMs are trained on various publicly available data sources, they might know about people with a public internet presence. These assessments ensure that LLMs do not inadvertently disclose personal information. A common benchmark for this purpose is PrivacyQA [60].

Adversarial robustness

Adversarial robustness tests an LLM’s ability to handle inputs intentionally designed to confuse or trick the model. This is crucial for ensuring the model's reliability and safety in practice. Typical benchmarks for testing LLM’s adversarial robustness include AdvGLUE [61], TextFooler [62], and AdvBench [63].

To summarize, we use various benchmarks to evaluate the safety of the LLM, which is crucial to ensure users’ safety. While both task-specific and safety evaluations are essential, human evaluation remains the most reliable method for comprehensive assessment.

Human evaluation

In this approach, human evaluators are asked to rate the different aspects of an LLM such as helpfulness and safety. Human evaluation is critical for assessing nuanced aspects of helpfulness and safety that task-specific and safety benchmarks might miss.

Online evaluation metrics

Online evaluation metrics measure how an LLM performs when deployed in production. Commonly used metrics are:

  • User feedback and ratings
  • User engagement
  • Conversion rate
  • Online leaderboards

User feedback and ratings: Users can rate their satisfaction with the model's responses. This direct feedback from users highlights areas that need improvement.

Image represents a simple system illustrating user interaction with a question-answering system.  The system displays a question, 'Where is the capital of Franc...', within a rounded rectangle.  To the left, another rounded rectangle contains the answer, 'Paris.'. A dashed arrow originates near the 'Paris' answer, curves downwards, and points to the text 'User feedback' indicating that the answer 'Paris' is considered user feedback to the system.  The overall structure suggests a feedback loop where the system provides an answer ('Paris') and this answer is then used as feedback to improve the system's performance or understanding.  No URLs or parameters are visible.
Figure 40: Collecting users’ feedback

User engagement: Metrics such as “number of queries made” and “session duration” can be insightful signals to measure user engagement. High engagement levels often indicate the LLM is effective in providing helpful information.

Conversion rate: Conversion rate refers to the percentage of users who make a purchase or sign up for a service after interacting with the LLM. Conversion rate is a crucial metric to monitor because higher conversion rates indicate that users find the LLM useful enough to pay for the service.

Online leaderboards: Online leaderboards track the performance of various LLMs in real time, A notable example is LMSYS Chatbot Arena [64], a crowdsourced open platform designed to evaluate LLMs. These models are ranked based on more than 800,000 human pairwise comparisons.

Image represents a leaderboard ranking different large language models (LLMs).  The table is organized into columns representing:  'Rank (UB)' indicating the model's position, 'Model' listing the name and version of each LLM (e.g., `o1-preview`, `ChatGPT-40-latest (2024-09-03)`, `Gemini-1.5-Pro-Exp-0827`), 'Arena Score' providing a numerical score for each model's performance, '95% CI' showing the 95% confidence interval around the Arena Score (e.g., '+6/-7'), 'Votes' indicating the number of votes contributing to the score, and 'Organization' specifying the developer of each LLM (e.g., OpenAI, Google, xAI, Anthropic).  The rows represent individual LLMs, ordered by their Arena Score in descending order.  No explicit information flow is depicted; the table simply presents comparative performance data for various LLMs.
Figure 41: Chatbot Arena leaderboard

Overall ML System Design

Designing a chatbot system such as ChatGPT requires several components working together smoothly. Unlike traditional models, this system combines multiple services and pipelines to ensure efficiency, safety, and continuous improvement. In this section, we'll explore two key pipelines:

  • Training pipeline
  • Inference pipeline

Training pipeline

The training pipeline involves three critical stages: pretraining, SFT, and RLHF. These stages collectively ensure the model is capable and that it generates helpful and safe responses.

Inference pipeline

The inference pipeline includes several components that ensure the safety, relevance, and quality of the generated responses. This pipeline is responsible for real-time interaction with users. The key components in the inference pipeline are:

  • Safety filtering
  • Prompt enhancer
  • Response generator
  • Response safety evaluator
  • Rejection response generator
  • Session management
Image represents a flowchart depicting the process of generating a response from a language model.  The process begins with a 'Text prompt' which is fed into a 'Safety Filt...' block.  A diamond-shaped decision node labeled 'Safe?' determines if the prompt is safe; if yes, the prompt proceeds to a 'Prompt...' block, otherwise, a 'Rejection Response...' is generated.  The 'Prompt...' block feeds into a 'Response...' block, which utilizes 'Top-p sampling' and interacts with a 'Trained...' (presumably the language model) cloud component.  The 'Response...' output is then checked for safety in another 'Safe...' decision node. If safe, a 'Generated response' is output; otherwise, the process returns to the 'Rejection Response...'.  The entire process is managed by a 'Session Management' block, which receives the final generated response and likely handles session-related data.  The connections between blocks are represented by arrows indicating the flow of information.
Figure 42: Chatbot overall design

Let’s explore each component in more detail.

Safety filtering

This component analyzes the user prompt to detect harmful, inappropriate, or unsafe queries before it is processed by the model. For example, a prompt asking for instructions on creating a harmful device will be rejected and flagged.

Prompt enhancer

The prompt enhancer component refines and enriches the input prompt to make it more informative and detailed. It expands acronyms, corrects misspellings, and adds context where necessary.

Image represents a simple data flow diagram illustrating a prompt enhancement process.  The diagram shows an initial prompt, 'Tell me about NYC.', as input. This prompt flows rightward via a black arrow into a rectangular box labeled 'Prompt Enhancer,' which is light purple with a darker purple border.  The 'Prompt Enhancer' box represents a process that modifies or improves the input prompt.  From the 'Prompt Enhancer' box, another black arrow points rightward to the output, which is a more detailed and enhanced prompt: 'Tell me about New York City (NYC), h...'.  The ellipsis ('...') suggests that the output prompt is longer than what's fully displayed, implying the 'Prompt Enhancer' added information such as context or keywords.  The overall flow demonstrates a transformation of a concise prompt into a more comprehensive one suitable for a downstream process (not shown).
Figure 43: Example of prompt enhancement

This component ensures the text prompts are clear, unambiguous, and free of grammatical errors before passing it to the model, which helps the model generate better responses.

Response generator

The response generator interacts with the trained LLM and utilizes top-p sampling to generate a helpful response. This component can optionally use other techniques to improve the quality and safety of the generated response. For example, it might generate multiple possible responses and then choose the one that is more appropriate based on a set of predefined criteria.

Response safety evaluator

This component evaluates the generated response to detect harmful or inappropriate content before it is shown to the user. It acts as a final safeguard to ensure responses meet ethical and safety standards.

Rejection response generator

This component generates a proper response when the input prompt is unsafe or the generated response is unsuitable. It provides a clear and polite explanation of why the request cannot be fulfilled.

Session management

To maintain conversation context and handle follow-up questions effectively, specific handling is required. For example, when a user is chatting with a model about their favorite movies, the model needs to remember not just the current question, but also their previous mentions of different genres or films.

This component maintains the continuity and coherence of the conversation by tracking the chat history and managing the flow of dialogue. This is achieved by feeding the chat history, along with the enhanced prompt, into the response generator. This design ensures that each response is contextually relevant by referencing previous interactions and appropriately handling the state of the conversation.

Other Talking Points

If there is extra time at the end of the interview, here are some additional talking points:

  • Techniques for managing dialogue states and tracking context across multiple turns [65].
  • Employing advanced or more efficient ML objectives such as multi-token prediction [66].
  • Handling very long sequence lengths [67][68].
  • How to develop multimodal LLMs [69][70].
  • Techniques such as RAG to leverage external knowledge bases and databases to enhance LLM output [71]. We explore this in Chapter 6.
  • Efficiency techniques (e.g., distillation) for faster text generation.
  • Techniques for adapting LLMs to specific domains (e.g., customer service, healthcare) without forgetting previous knowledge [72].
  • Addressing security and privacy concerns in LLMs.
  • Different optimization algorithms such as PPO, DPO, and rejection sampling [73].
  • Red-teaming LLMs to reduce harm [74].
  • Super-alignment and its importance in developing LLMs [75].
  • How in-context learning works [76].
  • Grouped query attention and its benefits [77].
  • Employing chain-of-thought prompting techniques [78]. We explore this in Chapter 6.
  • Implementing KV cache [79].
  • Enhancing trust by requiring models to produce clear and verifiable justifications for their outputs [80].

Summary

Image represents a mind map summarizing the design of a generative AI system.  The central node is labeled 'Summary,' branching out into several main categories.  These include 'Caching mechanisms,' detailing aspects like specification (input and output), ML upscaling, and Docker/clip; 'Jobs processing,' encompassing web-crawling, URL and language identification, content quality filtering, inappropriate content removal, and data quality assurance; 'Architecture,' focusing on positional encoding, Transformer architecture, and prediction tasks; 'Training,' covering data generation, instruction data, vector prediction, training a large model, calibration, and sampling methods (deterministic, beam search, MCMC, top-k, top-p, temperature); 'Traditional metrics,' encompassing common-sense reasoning, world knowledge, reading comprehension, and code generation benchmarks; 'CI/CD,' including compilable benchmarks, triviality level validation, traffic noise, and data leakage/privacy issues; and 'Human evaluation,' covering user feedback, user comparisons, online leaderboards, and training updates.  Finally, a 'System components' branch details overall system components and other traffic mechanisms, while a 'Solicitor to' branch describes prompt parameters, response parameters, and response quality evaluation.  Each branch further subdivides into more specific sub-topics, creating a hierarchical structure illustrating the various components and their interrelationships within the generative AI system.

Reference Material

[1] OpenAI’s ChatGPT. https://openai.com/index/chatgpt/. [2] ChatGPT wiki. https://en.wikipedia.org/wiki/ChatGPT. [3] OpenAI’s models. https://platform.openai.com/docs/models. [4] Google’s Gemini. https://gemini.google.com/. [5] Meta’s Llama. https://llama.meta.com/. [6] Beautiful Soup. https://beautiful-soup-4.readthedocs.io/en/latest/. [7] Lxml. https://lxml.de/. [8] Document Object Model. https://en.wikipedia.org/wiki/Document_Object_Model. [9] Boilerplate removal tool. https://github.com/miso-belica/jusText. [10] fastText. https://fasttext.cc/. [11] langid. https://github.com/saffsd/langid.py. [12] RoFormer: Enhanced Transformer with Rotary Position Embedding. https://arxiv.org/abs/2104.09864. [13] Llama 3 human evaluation. https://github.com/meta-llama/llama3/blob/main/eval_details.md. [14] Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer. https://arxiv.org/abs/1910.10683. [15] DeBERTa: Decoding-enhanced BERT with Disentangled Attention. https://arxiv.org/abs/2006.03654. [16] Transformers are RNNs: Fast Autoregressive Transformers with Linear Attention. https://arxiv.org/abs/2006.16236. [17] Common Crawl. https://commoncrawl.org/. [18] C4 dataset. https://www.tensorflow.org/datasets/catalog/c4. [19] Stack Exchange dataset. https://github.com/EleutherAI/stackexchange-dataset. [20] Training language models to follow instructions with human feedback. https://arxiv.org/abs/2203.02155. [21] Alpaca. https://crfm.stanford.edu/2023/03/13/alpaca.html. [22] Dolly-15K. https://www.databricks.com/blog/2023/04/12/dolly-first-open-commercially-viable-instruction-tuned-llm. [23] Introducing FLAN: More generalizable Language Models with Instruction Fine-Tuning. https://research.google/blog/introducing-flan-more-generalizable-language-models-with-instruction-fine-tuning/. [24] Training a Helpful and Harmless Assistant with Reinforcement Learning from Human Feedback. https://arxiv.org/abs/2204.05862. [25] Proximal Policy Optimization Algorithms. https://arxiv.org/abs/1707.06347. [26] Direct Preference Optimization: Your Language Model is Secretly a Reward Model. https://arxiv.org/abs/2305.18290. [27] Illustrating RLHF. https://huggingface.co/blog/rlhf. [28] RLHF progress and challenges. https://www.youtube.com/watch?v=hhiLw5Q_UFg. [29] State of GPT. https://www.youtube.com/watch?v=bZQun8Y4L2A. [30] Different sampling methods. https://huggingface.co/blog/how-to-generate. [31] The Curious Case of Neural Text Degeneration. https://arxiv.org/abs/1904.09751. [32] OpenAI’s API reference. https://platform.openai.com/docs/api-reference/chat/create. [33] Cheat Sheet: Mastering Temperature and Top_p in ChatGPT API. https://community.openai.com/t/cheat-sheet-mastering-temperature-and-top-p-in-chatgpt-api/172683. [34] PIQA: Reasoning about Physical Commonsense in Natural Language. https://arxiv.org/abs/1911.11641. [35] SocialIQA: Commonsense Reasoning about Social Interactions. https://arxiv.org/abs/1904.09728. [36] HellaSwag: Can a Machine Really Finish Your Sentence? https://arxiv.org/abs/1905.07830. [37] WinoGrande: An Adversarial Winograd Schema Challenge at Scale. https://arxiv.org/abs/1907.10641. [38] Can a Suit of Armor Conduct Electricity? A New Dataset for Open Book Question Answering. ​​https://arxiv.org/abs/1809.02789. [39] CommonsenseQA: A Question Answering Challenge Targeting Commonsense Knowledge. https://arxiv.org/abs/1811.00937. [40] TriviaQA: A Large Scale Dataset for Reading Comprehension and Question Answering. https://nlp.cs.washington.edu/triviaqa/. [41] The Natural Questions Dataset. https://ai.google.com/research/NaturalQuestions. [42] SQuAD: 100,000+ Questions for Machine Comprehension of Text. https://arxiv.org/abs/1606.05250. [43] QuAC dataset. https://quac.ai/. [44] BoolQ: Exploring the Surprising Difficulty of Natural Yes/No Questions. https://arxiv.org/abs/1905.10044. [45] GSM8K dataset. https://github.com/openai/grade-school-math. [46] MATH dataset. https://github.com/hendrycks/math/. [47] HumanEval dataset. https://github.com/openai/human-eval. [48] MBPP dataset. https://github.com/google-research/google-research/tree/master/mbpp. [49] Measuring Massive Multitask Language Understanding. https://arxiv.org/abs/2009.03300. [50] Measuring Massive Multilingual Multitask Language Understanding. https://huggingface.co/datasets/openai/MMMLU. [51] AGIEval: A Human-Centric Benchmark for Evaluating Foundation Models. https://arxiv.org/abs/2304.06364. [52] RealToxicityPrompts: Evaluating Neural Toxic Degeneration in Language Models. https://arxiv.org/abs/2009.11462. [53] Perspective API. https://perspectiveapi.com/. [54] ToxiGen: A Large-Scale Machine-Generated Dataset for Adversarial and Implicit Hate Speech Detection. https://arxiv.org/abs/2203.09509. [55] HateCheck: Functional Tests for Hate Speech Detection Models. https://arxiv.org/abs/2012.15606. [56] CrowS-Pairs: A Challenge Dataset for Measuring Social Biases in Masked Language Models. https://arxiv.org/abs/2010.00133. [57] BBQ: A Hand-Built Bias Benchmark for Question Answering. https://arxiv.org/abs/2110.08193. [58] BOLD: Dataset and Metrics for Measuring Biases in Open-Ended Language Generation. https://arxiv.org/abs/2101.11718. [59] TruthfulQA: Measuring How Models Mimic Human Falsehoods. https://arxiv.org/abs/2109.07958. [60] Question Answering for Privacy Policies: Combining Computational and Legal Perspectives. https://arxiv.org/abs/1911.00841. [61] AdvGLUE Benchmark. https://adversarialglue.github.io/. [62] Is BERT Really Robust? A Strong Baseline for Natural Language Attack on Text Classification and Entailment. https://arxiv.org/abs/1907.11932. [63] AdvBench. https://github.com/llm-attacks/llm-attacks. [64] Chatbot Arena leaderboard. https://lmarena.ai/leaderboard. [65] A Survey on Recent Advances in LLM-Based Multi-turn Dialogue Systems. https://arxiv.org/abs/2402.18013. [66] Better & Faster Large Language Models via Multi-token Prediction. https://arxiv.org/abs/2404.19737. [67] Gemini 1.5: Unlocking multimodal understanding across millions of tokens of context. https://arxiv.org/abs/2403.05530. [68] HyperAttention: Long-context Attention in Near-Linear Time. https://arxiv.org/abs/2310.05869. [69] MM-LLMs: Recent Advances in MultiModal Large Language Models. https://arxiv.org/abs/2401.13601. [70] Multimodality and Large Multimodal Models. https://huyenchip.com/2023/10/10/multimodal.html. [71] What is Retrieval-Augmented Generation? https://cloud.google.com/use-cases/retrieval-augmented-generation. [72] How to Customize an LLM: A Deep Dive to Tailoring an LLM for Your Business. https://techcommunity.microsoft.com/t5/ai-machine-learning-blog/how-to-customize-an-llm-a-deep-dive-to-tailoring-an-llm-for-your/ba-p/4110204. [73] Llama 2: Open Foundation and Fine-Tuned Chat Models. https://arxiv.org/abs/2307.09288. [74] Red Teaming Language Models to Reduce Harms: Methods, Scaling Behaviors, and Lessons Learned. https://arxiv.org/abs/2209.07858. [75] Introducing superalignment. https://openai.com/index/introducing-superalignment/. [76] Language Models are Few-Shot Learners. https://arxiv.org/abs/2005.14165. [77] GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. https://arxiv.org/abs/2305.13245. [78] Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. https://arxiv.org/abs/2201.11903. [79] Efficiently Scaling Transformer Inference. https://arxiv.org/abs/2211.05102. [80] Prover-Verifier Games improve legibility of language model outputs. https://openai.com/index/prover-verifier-games-improve-legibility/.

Chapter 5

Image Captioning

~21 min read

Introduction

Image captioning is the process of generating text that describes an image. The generated text, also known as caption, should accurately reflect the image’s content.

Image captioning has multiple applications. For example, on social media platforms, it automatically suggests image captions, saving time for content creators. In online retail, it generates captions for product images, thus improving the shopping experience.

Image represents a simple modal dialog box with a text input field and two buttons.  The dialog box is titled 'Name Your Asset:' and contains a single text input field where 'Sun over mountains.png' is pre-filled. Below the input field are two buttons labeled 'Cancel' and 'OK'. A curved arrow points from the left, labeled 'Suggested...', indicating a suggested filename has been provided to the input field.  The dialog box also includes a small 'X' in the upper right corner, suggesting a close button.  The text 'Text is not SVG - cannot display' is present at the bottom, indicating a technical limitation in rendering the image.
Figure 1: Image captioning system suggests file names for an uploaded image

Beyond user-facing applications, image captioning is also used in systems that operate behind the scenes. For instance, in NSFW (Not Safe for Work) content moderation, image captioning systems can generate descriptive captions that help identify and flag inappropriate or explicit content by providing text-based interpretations of images. Additionally, image captioning can address the cold-start problem in recommendation systems, which occurs when a system lacks sufficient data on new users or items to make accurate recommendations. By generating descriptive captions, the system gains textual information that helps categorize and recommend new items based on their content.

In this chapter, we design a machine learning (ML) system that generates descriptive captions for images.

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: There are various types of images, including general everyday images and domain-specific images such as medical imagery or technical diagrams. Can I focus on general everyday images? Interviewer: Sure.

Candidate: Are there any specific applications or use cases we are targeting with this system? Interviewer: We are targeting name suggestions to designers when they upload their assets.

Candidate: Since the image captioner will be used for asset name suggestions, the captions should not be too long and detailed. Is this a fair assumption? Interviewer: Makes sense. The captions should be short, but descriptive and clear.

Candidate: Should the system support multiple languages, or will it focus only on English? Interviewer: Let’s focus on English only.

Candidate: What is the estimated size and diversity of the dataset? Interviewer: We have access to a large dataset with 400 million image–caption pairs focused on everyday images.

Candidate: Does the dataset consist solely of English captions? Interviewer: The dataset is not preprocessed. There might be captions in different languages, and some captions might be noisy or inaccurate. Additionally, captions for some images may be missing.

Candidate: Is real-time captioning required? Interviewer: The system should generate a caption quickly, though real-time speed is not necessary. A latency of 1–2 seconds is acceptable.

Candidate: How should the system handle images with ambiguous content or unclear focus? Interviewer: In such cases, the system should skip suggesting a caption.

Candidate: I assume the system should avoid generating biased captions or captions with offensive words. Is that a fair assumption? Interviewer: Great point. Yes, it is crucial to ensure our system remains fair and safe for users.

Candidate: What are the typical image dimensions? Very small images can be unclear, leading to incorrect captions. Interviewer: Let's assume the system only suggests names for images with a minimum resolution of 256 x 256 pixels.

Frame the Problem as an ML Task

Specifying the system’s input and output

The input to an image captioning system is an image. This image is processed by the model to generate a descriptive caption. The output, therefore, is a text that accurately describes the content of the image.

Image represents a simple data flow diagram illustrating an image captioning process.  The diagram begins with a square box labeled 'Input image' containing a line drawing of mountains and a sun.  A solid arrow points from this box to a rectangular, light orange box labeled 'Image Captioning...'. This second box represents the image captioning model or process.  Another solid arrow extends from the 'Image Captioning...' box to the text 'A simple drawing of mountains...', which is the output caption generated by the system. The overall flow shows the input image being processed by the image captioning system to produce a textual description of the image's content.
Figure 2: Input and output of an image captioning system

Choosing a suitable ML approach

The image captioning problem introduces a unique challenge: an ML model requires visual understanding to process the input image, language understanding to generate a caption, and the ability to bridge the gap between visual and textual modalities. This requires developing a multi-modal system.

A common approach to building multi-modal systems is to use an encoder-decoder framework. Similar to language translation—where we utilized an encoder-decoder architecture—we treat the image as a new "language" in this context. Specifically, we employ two main components, each handling one modality:

  • Image encoder
  • Text decoder

Image encoder

The image encoder is responsible for understanding the visual content of the image and encoding the image into a lower-dimensional representation.

Text decoder

The text decoder uses the encoded visual information from the image encoder to generate a descriptive caption.

Image represents a simplified diagram of an image captioning system.  At the bottom, an 'Input image' (depicted as a simple drawing of mountains and a sun) is fed into an 'Image Encoder' (a light green rectangle). The Image Encoder processes the image and outputs 'Encoded information' (textual representation of the image's content). This encoded information is then passed to a 'Text Decoder' (a light orange rectangle), which generates a textual description of the image.  The entire process is enclosed within a dashed-line box, and a thick upward-pointing arrow indicates the final output of the Text Decoder, which is presumably the generated caption ('A simple drawing of mountains w...').  The arrows illustrate the unidirectional flow of information from the input image through the encoder and decoder to the final text output.
Figure 3: Image captioning components

We will explore the architecture of these components in detail in the model development section. It's important to note that there are various approaches to tackling the image captioning problem. While we focus on the encoder-decoder framework here, alternative models such as BLIP-2 [1], BLIP-3 [2], and InternVL [3] offer different techniques and architectures for generating captions. If you're interested in these other methods, you can refer to [1] [2] [3] for a broader understanding of the image captioning landscape.

Data Preparation

In this section, we prepare the dataset to train our image captioning system.

Image represents a table with two columns: 'Image' and 'Caption'.  The table has at least three rows.  Each row in the 'Image' column is intended to hold an image, but these are not displayed due to the image format being unsupported.  The 'Caption' column provides textual descriptions for the corresponding images. The first row's caption is partially visible as 'A simple drawing of mounta...', suggesting an image of a mountain is intended. The second row's caption reads 'A minimalistic flower ic...', indicating a minimalist flower image. The third row has ellipses (...) in both columns, implying the table continues with more image-caption pairs.  There are no visible connections or information flow between the rows; each row functions independently as an image-caption pair.
Figure 4: Example of image–caption dataset

The dataset comprises 400 million pairs of images and captions. However, not all images or captions are suitable for training. Let’s examine data preparation for captions and images separately.

Caption preparation

Raw captions are often noisy and not in a format that is usable by the ML model. During caption preparation, we remove inappropriate captions and ensure the remaining ones are consistent and tokenized. In particular, we perform the following steps:

  • Remove pairs with a non-English caption: We remove image–caption pairs where the caption is not in English, as this model’s focus will be on English.
  • Remove duplicate images or captions: To ensure the diversity and quality of the training data, we eliminate duplicate images and captions. Duplicate images are identified using perceptual hashing techniques or image similarity models (e.g., CLIP image encoder), while duplicate captions are detected by exact match or semantic similarity checks (e.g., CLIP text encoder). Removing duplicates prevents the model from overfitting to redundant data and helps it learn a broader range of associations between images and text.
  • Remove irrelevant captions: We use a pretrained vision–language model (e.g., CLIP) to assess the relevance between images and their corresponding captions. A higher score usually indicates greater semantic relevance between the image and the text. We remove pairs with scores below a specific threshold, such as 0.25. This ensures our model learns from high-quality, relevant pairs. For more information on how CLIP scores the relevance between text and images, refer to Chapter 9.
  • Summarize long captions: Captions are often long and detailed. Training the model with these captions leads to the generation of similarly long captions, which doesn't suit our use case. To address this, we summarize the captions using a large language model such as Llama [4] to create brief, concise descriptions that meet our requirements.
  • Normalize captions: We apply standard text normalization techniques including lowercasing and trimming whitespaces to maintain consistency between captions.
  • Tokenize captions: We use a subword-level tokenization algorithm such as Byte-Pair Encoding (BPE) [5] to tokenize captions into a sequence of IDs. For a detailed review of text tokenization methods and the BPE algorithm, refer to Chapter 2 and Chapter 3.

Image preparation

As is the case for captions, not all images are useful. We remove images that might hurt training and ensure the remaining images are consistent and suitable for the model training. In particular, we perform the following steps:

  • Remove low-resolution images: We remove image–caption pairs in which the image resolution is less than 256×\times×256 because such low-resolution images might not provide enough detail for accurate caption generation.
  • Normalize images: We scale the pixel values to a normalized range, such as 0 to 1. This normalization makes the training process more stable.
  • Remove low-quality images: To maintain high-quality training data, we filter images that exhibit conditions such as blurriness, overexposure, underexposure, or other defects that degrade visual clarity. Image quality assessment methods, such as the LAION Aesthetics Predictor [6], help identify and remove subpar images by scoring them on factors such as sharpness, contrast, and lighting.
  • Adjust image dimensions: Images typically have a range of sizes and aspect ratios. We resize all images to a uniform size. This is critical since ML models require fixed-size inputs during training. When adjusting image dimensions to a uniform size, it is important to preserve their original aspect ratios. To do so, we often follow two steps:
  • Resizing: First, we resize the image so that the smaller dimension matches the target size. For instance, if our target size is 256×\times×256 and our original image is 512×\times×768, we resize it to 256×\times×384.
  • Center-cropping: Next, we center-crop the resized image to the target dimensions. From our previous example, we center-crop the 256×\times×384 image to 256×\times×256.
Image represents a data processing pipeline for image preprocessing.  It begins with an 'Original image' rectangle, labeled with dimensions 512 x 768 pixels, depicted in light blue. A solid arrow points from this rectangle to a second, light blue rectangle labeled '256' on its left side and '384' on its bottom, representing the image after '1. Resizing'.  This resizing step changes the image's aspect ratio. A thick black line within this second rectangle indicates the area selected for the next step. A curved arrow then connects this selected area to a third rectangle, colored light red, labeled '256' on both its sides, representing the final image after '2. Center-cropping'. This final rectangle shows the resulting 256 x 256 pixel image obtained by cropping the center of the resized image.  The entire diagram illustrates a two-step image transformation process: resizing to a non-square aspect ratio, followed by center cropping to a square image of the specified dimensions.
Figure 5: Resizing followed by center-cropping

This two-step method ensures our images maintain their aspect ratios and fit the required size for our ML model.

Model Development

Architecture

We framed image captioning as a multi-modal language generation task where the image encoder processes an input image, and the text decoder generates a descriptive caption. In this section, we explore the architecture of the image encoder and text decoder.

Image encoder

The image encoder is responsible for processing an image and encoding the information within it.

The output of the encoder plays a pivotal role in determining the quality and specificity of the generated captions. The encoder’s output can be either a single token, representing the entire image as a single feature vector, or a sequence of tokens, where each token corresponds to a specific region or aspect of the image. The choice between these two approaches has significant implications for how effectively the system captures and represents the visual content, and research has explored both options to understand their strengths and limitations.

Image represents a comparison of single-image and multi-image encoding processes.  On the left, a single 'Input image' icon, depicting a landscape photograph, feeds into a light-green rectangular box labeled 'Image Encoder.' The encoder processes the image and outputs a vertical array of several rectangular boxes representing a feature vector.  On the right, a similar setup is shown, but multiple 'Input image' icons are fed into the 'Image Encoder.'  The encoder's output is a horizontal array of multiple vertical arrays of rectangular boxes, indicating multiple feature vectors, with an ellipsis (...) suggesting the continuation of this pattern beyond the displayed number of images.  Arrows indicate the direction of data flow, from the input image to the encoder and then to the resulting feature vector(s).  The overall comparison highlights the difference in input and output when processing a single image versus multiple images using the same image encoder.
Figure 6: Image encoder outputting single token vs. sequence of tokens

When the encoder produces a single token as its output, it effectively compresses the entire image into one vector. This vector serves as a summary of the image, encapsulating its global features and overall context. The primary advantage of this approach lies in its simplicity; the architecture remains straightforward, with reduced computational complexity and lower resource requirements. A single vector emphasizes the overall content of the image, which can be particularly beneficial for generating concise and high-level captions that capture the general essence of the scene. However, this approach also has notable downsides. Condensing all visual information into one vector often means the loss of local details and specific nuances, which are crucial for generating descriptive and contextually rich captions. As a result, captions generated from single-token outputs may lean toward being more generic and may struggle with complex images that require detailed representation.

On the other hand, producing a sequence of tokens from the encoder allows the system to capture a more granular view of the image. Each token in the sequence corresponds to a distinct part or patch of the image, resulting in a richer and more comprehensive representation that includes both global and local features. This approach aligns particularly well with the attention mechanism, which is a cornerstone of modern generative models such as Transformers. The attention mechanism works best with sequence inputs, as it enables the decoder to focus dynamically on different regions of the image during caption generation. This capability of selectively attending to various parts of the image leads to more accurate, relevant, and detailed captions. By using a sequence of tokens, the model can generate captions that are not only more descriptive but also better aligned with the specific objects, actions, and contexts present in the image.

The image encoder architectures can be divided into the following:

  • CNN-based
  • Transformer-based
CNN-based

Convolutional Neural Networks (CNNs) are traditionally used for image-encoding tasks. CNNs excel at capturing spatial hierarchies in images through the use of convolutional filters. These filters detect patterns such as edges, textures, and objects at different scales.

CNN-based encoders process the input image and output a grid of feature vectors. For example, as shown in Figure 7, an input image passes through the CNN, producing a feature vector of size 3 x 3 x c. Here, c represents the channel size, which depends on the CNN architecture. While the CNN produces a 3 x 3 x c output, the Transformer in the text decoder needs a sequence of features (i.e., 9 x c). To achieve this, we use a flattening or reshaping operation that reorganizes the features from each of the nine positions in the 3 x 3 grid into a sequential format.

Image represents a data processing pipeline for image embedding.  At the top, a sequence of nine embedding vectors is shown, represented as columns of cells labeled 1 through 9, with an ellipsis (...) indicating that there are more than the three explicitly shown.  Each column, labeled 'c', represents a single embedding vector with multiple elements (the cells within the column).  These embedding vectors are collectively described as a 'Sequence of embeddings'.  An arrow labeled 'flatten' points downwards, indicating that this sequence is flattened into a single, three-dimensional tensor. This tensor, also labeled 'c', is shown as a cuboid structure, representing the combined embedding vectors.  This flattened tensor is then fed as input into a 'CNN-based...' module (represented by an orange rectangle), which presumably is a Convolutional Neural Network performing further processing. Finally, an upward arrow connects this CNN module to an 'Input image' symbol (a picture of a landscape), indicating that the entire pipeline starts with an input image which is processed by the CNN to generate the sequence of embeddings.
Figure 7: A CNN-based image encoding
Transformer-based

Transformer models, originally developed for natural language processing, have recently been adapted for image encoding with significant success. In this architecture, a Transformer analyzes images, extracts features, and encodes them into a sequence of embeddings. Specifically, a Transformer-based image encoder consists of:

  • Patchify
  • Positional encoding
  • Transformer
Image represents a simplified architecture for processing an image using a transformer-based model.  At the bottom, an 'Input image' (represented by an image icon) is fed into a processing pipeline. This pipeline consists of three stacked layers: a 'Patchify' layer (light green), a 'Positional...' layer (light red), and a 'Transformer' layer (light orange).  The Patchify layer likely divides the input image into patches. These patches are then processed by the Positional... layer, which probably adds positional information to the patches to maintain spatial context. The output of the Positional... layer is then fed into the Transformer layer, a core component of many modern image processing models, which processes the sequence of patches. The output of the Transformer is a 'Sequence of embeddings' represented as a series of 'c' vertically stacked rectangles labeled '1', '2', '3', ..., 's'.  Each rectangle represents an embedding vector, and the entire sequence captures the image's features.  The arrow indicates the flow of information from the input image through the processing layers to the final sequence of embeddings.
Figure 8: Transformer-based image encoding
Patchify

Since Transformers work with sequences, the image should first be converted into a sequence. This process involves three steps:

  • Divide the image into fixed-size patches
  • Flatten each patch
  • Linearly project each patch

For example, a 256 x 256 input image is divided into patches of 64 x 64. These patches are flattened into 4096-sized vectors and linearly projected into embedding vectors of size c, where c is the desired embedding size.

Image represents a data processing pipeline, specifically a 'Patchify' operation, within a larger system.  The process begins with a 256x256 input image. This image is then fed into the Patchify module, which is depicted as a light green box containing three sub-processes: Projection, Flatten, and Divide.  Before entering Patchify, the input image is first processed by a block that transforms a 64x64 input into a 4096-element vector. The Patchify module takes this 4096-element vector and performs the three operations.  The output of the Patchify module is shown as a grid of smaller squares, representing patches of the original image.  Above the Patchify module, a diagram shows the arrangement of these patches: sixteen columns (numbered 1 through 16) each containing 'c' number of rows, representing the division of the processed image into patches.  The arrows indicate the flow of data through the pipeline, from the input image to the Patchify module and finally to the resulting patch arrangement.
Figure 9: Patchification process
Positional encoding

Positional encoding assigns position information to each patch, specifying where each patch was located in the original image. This helps Transformers understand positions within the sequence.

Positional encoding can be implemented in various ways. Let’s briefly explore the following variations:

  • 1D vs. 2D positional encoding
  • Learnable vs. fixed positional encoding
D vs. 2D positional encoding

1D positional encoding employs a function that maps an integer (position in the sequence) to a c-dimensional vector, where c is usually the Transformer’s hidden dimension. This is commonly used in text sequences, with each token receiving a positional vector based on its place. When applied to images, 1D positional encoding encodes the position of each patch in a flattened sequence, which might not capture the two-dimensional spatial relationships in images.

2D positional encoding, on the other hand, maps two integers—representing the row and column positions in the image grid—into a c-dimensional vector. This encoding method is more suitable for images as it preserves the spatial structure.

Image represents a comparison of 2D and 1D positional embeddings in the context of image processing.  The left side depicts a 2D approach, showing a set of three (with ellipsis indicating more) vertical rectangular blocks labeled '$PE_...', representing 2D positional embeddings.  These blocks are connected via an upward-pointing arrow to a 3x3 grid labeled 'Image patches,' where each cell contains the repeating sequence '1...', '2...', '3...' respectively, suggesting that each patch receives the same 2D positional embedding.  Red lines divide the grid into the patches. A grey, curved line suggests a relationship between the patches. The right side mirrors this structure but uses a 1D approach.  Three vertical rectangular blocks labeled '$PE_...' (again, with ellipsis implying more) represent 1D positional embeddings.  These are similarly connected via an upward-pointing arrow to a 3x3 grid labeled 'Image patches,' but here, the cells are numbered sequentially from 1 to 9, indicating a linear, 1D positional embedding assignment to each patch.  The red lines again delineate the patches, and a grey, curved line shows the relationship between the patches.  The overall diagram contrasts how positional information is encoded in 2D versus 1D for image patches, highlighting the difference in how spatial relationships are represented.
Figure 10: 1D vs. 2D positional encoding
Learnable vs. fixed positional encoding

In learnable positional encoding, the model learns positional encodings during training. A neural network maps positions (1D or 2D) to a c-dimensional vector. In the fixed approach, positional encodings are determined by a fixed function such as sine–cosine. For more details, refer to Chapter 2.

There is often no best solution when choosing between 1D vs. 2D and learnable vs. fixed positional encoding. While Vision Transformer (ViT) [7] uses learnable 1D positional encoding, in practice, we often test different combinations to see which works best for a specific task.

Which architecture is suitable for our image encoder?

CNNs are effective at capturing local patterns in images but they struggle with long-range dependencies between distant regions of the image. In contrast, Transformers capture both local and global relationships in the image using a self-attention mechanism. This allows Transformers to model complex dependencies, making them ideal for tasks that require detailed, context-aware image understanding, for example, generating descriptive captions. For these reasons, we follow the ViT [7] and choose Transformer-based architecture as our image encoder.

Text decoder

The text decoder is responsible for generating the caption. As we saw in previous chapters, a decoder-only Transformer is the standard choice for text generation. The input to the decoder-only Transformer is a sequence of vectors corresponding to the input image. Its output is the caption, generated one token at a time.

Image represents a simplified architecture diagram of a text-to-image generation model.  At the top, four input boxes labeled 'A,' 'flower,' 'icon,' and '.' represent individual text tokens or prompts.  Arrows point upwards from these boxes, indicating data flow into a larger, light-orange rectangular block labeled 'Text Decoder...'. This block presumably processes the text inputs.  Below the 'Text Decoder...', three vertical stacks of smaller rectangular boxes (with an ellipsis '...' indicating more such stacks exist) represent the encoded image features. Arrows point upwards from these stacks into the 'Text Decoder...', suggesting that the decoder uses these features.  These stacks are connected to a light-green rectangular block at the bottom labeled 'Image Encoder,' indicating that this block processes the image data into the feature vectors.  An upward-pointing arrow connects the 'Image Encoder' to the feature vector stacks, showing the flow of encoded image information.  The overall structure depicts a process where text prompts are decoded and used in conjunction with encoded image features to generate an image.
Figure 11: Providing image as a sequence of embeddings

Training

The training approach for the image captioning model is similar to the strategies discussed in previous chapters. We follow a two-stage training strategy:

  • Unsupervised pretraining
  • Supervised finetuning

. Unsupervised pretraining

During this stage, the text decoder – which is a decoder-only Transformer – is trained on general data. The purpose of this stage is to develop a base model that has a broad understanding of language structure and is capable of generating coherent text. This knowledge is crucial for the model to perform well when it is later finetuned on a more specific task such as caption generation.

The pretraining stage is computationally expensive. It is common practice to use existing pretrained models to bypass this stage and, thus, significantly reduce computational costs. In this chapter, we use a pretrained decoder-only Transformer such as GPT-2 [8] or Llama [4].

Similarly, the image encoder can also be derived from pretrained models. Instead of training an image encoder from scratch, we can leverage powerful pretrained vision models such as CLIP [9] or ViT [7].

. Supervised finetuning

In this stage, we train both the image encoder and the text decoder on 400 million image–caption pairs. The image encoder improves its ability to encode image information effectively, and the text decoder learns to understand the sequence of image embeddings and generate a descriptive caption.

ML objective and loss function

The text decoder generates the caption one token at a time. Consistent with previous chapters, we use next-token prediction as our ML objective and employ cross-entropy loss [10] to guide the training process.

Image represents a sequence-to-sequence model for image captioning.  At the bottom, a green rectangle labeled 'Image Encoder' processes an image, producing a vector representation. This representation is then fed into a beige rectangle labeled 'Text Decoder.' The decoder processes this image embedding and generates a sequence of words as a caption.  The decoder's output consists of multiple vertical blocks, each representing a word embedding (e.g., 'A,' 'flower,' 'icon,' '.' and '<EOS>'). Arrows indicate the flow of information.  Above the decoder's output, another set of identical vertical blocks represents the 'Correct next...' word embeddings for each position in the caption.  These are compared to the decoder's 'Predicted...' word embeddings using 'Cross-entropy loss,' a metric that quantifies the difference between the predicted and actual word sequences, guiding the model's training to minimize this loss and improve caption accuracy.  The ellipses ('...') indicate that the sequence can be longer than what's explicitly shown.
Figure 12: Loss calculation over the predicted probabilities

Sampling

During sampling, the caption tokens are generated one at a time.

Image represents a neural network architecture for image captioning.  At the bottom, a green box labeled 'Image Encoder' processes an image, producing a vector representation. This vector is then fed upwards as input to a beige box labeled 'Text Decoder.' The Text Decoder processes this image embedding and generates a sequence of words.  Above the Text Decoder, multiple vertical stacks of boxes represent the predicted word embeddings at each time step of the decoding process.  These predicted embeddings are connected to individual word boxes ('A,' 'nice,' 'bloom,' '.') at the top, representing the selected tokens for the caption.  Dashed lines indicate the flow of information between the predicted word embeddings and the selected words, suggesting a process of iterative refinement or prediction.  The labels 'Selected t...' and 'Predicted...' indicate the selected tokens and the predicted embeddings, respectively.  The ellipses ('...') signify that the number of predicted word embeddings and selected tokens can extend beyond what's explicitly shown.
Figure 13: Generating a caption given an input image

While stochastic sampling methods can create creative captions, beam search ensures predictability. We use beam search for our image captioning system for the following reasons:

  • Quality: Beam search typically generates higher-quality captions, which is critical for accurately describing image content.
  • Consistency: The deterministic nature of beam search ensures that the model always produces the same caption for the same image. This consistency is crucial for image captioning.
  • Coherence: Beam search typically produces coherent captions, which is important for image captioning. This avoids sudden topic changes or contradictions such as "A person is walking house" or "A dog is reading a person."

Evaluation

Offline evaluation metrics

During offline evaluation, we assess the performance of the trained model on a validation dataset. This is achieved by comparing generated captions with reference (i.e., correct) captions and measuring their similarity.

Before exploring common metrics, let’s review validation data. Validation data contains examples not seen by the model during training. Each example includes an image and a set of reference captions. These captions are typically collected by having multiple human annotators describe each image.

In image captioning systems, it's common to have multiple reference captions for each image. This benefits both training and evaluation for the following reasons:

  • Robust training: Different people describe the same image in different ways. Multiple references allow the model to learn different ways of describing an image. This leads to a more robust model that is capable of describing images more accurately.
  • Comprehensive evaluation: Multiple captions provide a more thorough assessment of a model's performance. Comparing the generated caption to several correct reference captions leads to a fairer evaluation.
Image represents a table with two columns. The left column is labeled 'Image' and is left blank, presumably intended to hold an image. The right column is labeled 'Reference captions' and contains three rows, each providing a textual description that could correspond to the image in the left column.  The first row describes 'Blooming tulip with green leaves,' the second row says 'Close-up of a blooming tulip.', and the third row, which is truncated, begins with 'Single tulip with leave...'.  The table structure implies a relationship where each caption in the right column offers an alternative or more specific description of the same image in the left column.
Figure 14: An example of validation data

The following metrics are commonly used in the offline evaluation of image captioning models:

  • BLEU
  • ROUGE
  • METEOR
  • CIDEr

The first three metrics on the list are explored extensively in Chapter 3. In this chapter, we focus on CIDEr, which has been designed specifically to evaluate image captioning models.

CIDEr

CIDEr [11] is a popular metric for evaluating image captioning models. It uses consensus to evaluate the similarity of a generated caption to a set of reference captions. CIDEr gives higher scores to captions that are similar to multiple reference captions rather than just one. For a single example, CIDEr is calculated in three steps:

  • Represent captions using Term Frequency–Inverse Document Frequency (TF-IDF)
  • Calculate similarities
  • Aggregate the similarity scores
. Represent captions using TF-IDF

In the first step, we convert the generated caption and each reference caption into numerical representations using TF-IDF. TF-IDF evaluates a word's importance to a document by considering how frequently it appears in that document and how common or rare it is across the entire corpus. These importance scores are used to represent a sentence numerically. To learn more about TF-IDF, refer to [12][13].

Image represents a simplified diagram of a caption generation system.  The diagram shows three reference captions ('1. Blooming tulip with leaves', '2. A blooming tulip.', '3. Single tulip with leaves.') contained within a rectangular box labeled 'Reference captions'.  A second rectangular box labeled 'Generated caption' displays the output 'Tulip with leaves.'.  Both the reference and generated captions are connected via downward-pointing arrows to a central, peach-colored rectangular box labeled 'TF-IDF,' representing a term frequency-inverse document frequency algorithm.  Finally, an arrow points down from the TF-IDF box to a line of text showing a string of words ('abloomingleavessingletulipleaves') followed by reference numbers and associated weighted values (e.g., 'Ref 1: 'Blooming tulip with leaves'0.000.520.430.000.360.43'). This suggests the TF-IDF process transforms the reference captions into a weighted representation of their constituent words, which is then used to generate the final caption.
Figure 15: TF-IDF converting captions to numerical representations
. Calculate similarity

Next, we calculate the similarity between the generated caption and each reference caption. We do this by computing the cosine similarity between their TF-IDF representations.

Image represents a flowchart illustrating a similarity calculation process.  At the top, a partially visible text string suggests input references, possibly image captions like 'Blooming tulip with leaves' and 'A blooming...'. A light peach-colored rounded rectangle labeled 'Similarity...' acts as a central processing block.  An arrow points downwards from this block to a grey table. This table has two columns: 'Pair,' listing three rows of text starting with '<Reference 1, Generat...', '<Reference 2, Generat...', and '<Reference 3, Generat...',  and 'Cosine similarity sco...', showing corresponding numerical values (0.688, 0.257, and 0.766 respectively). These values likely represent cosine similarity scores calculated between the input references and generated text (indicated by '...'). The arrows indicate the flow of data: the input references are implicitly processed within the 'Similarity...' block, resulting in the cosine similarity scores displayed in the table.
Figure 16: Calculation of cosine similarity between generated and reference captions

A higher cosine similarity score (i.e., a score closer to 1) indicates greater similarity, while a lower value (closer to 0) indicates lesser similarity.

. Aggregate the similarity scores

Once we have the cosine similarity scores between the generated caption and each of the reference captions, we take an average of these scores. This average score reflects the overall similarity between the generated caption and the reference captions.

The final CIDEr score is calculated by averaging the similarity scores for all generated captions in the validation dataset. This provides a single metric to evaluate the model's overall performance.

Let’s see some of the pros and cons of the CIDEr metric.

Pros:
  • Consensus-based: CIDEr emphasizes consensus by rewarding captions that are similar to multiple reference captions. This leads to a more reliable evaluation of a model's performance.
  • Sensitive to important words: TF-IDF assigns more weight to unique words in their representation. This ensures that the CIDEr score reflects the importance of words and rewards captions that use those words.
  • Robust to different caption variations: CIDEr is robust to different variations of generations since it is calculated based on multiple reference captions.
Cons:
  • Computationally complex: Calculating TF-IDF representations in large datasets can be computationally expensive.
  • Sensitive to the quality of reference captions: The quality and diversity of reference captions impact the CIDEr score. Poor references can lead to misleading evaluations.
  • Penalizes novel yet accurate captions: CIDEr may penalize creative or novel phrases that are still accurate but are not present in the reference set.
  • Lack of semantic understanding: CIDEr relies on TF-IDF to measure the similarity between two sentences. This might not always capture the semantic similarity when captions are textually similar but semantically different. For example, "Coffee on top of the table" and "Table on top of the coffee" might have similar TF-IDF representations due to similar words, but they are not semantically similar.

Online evaluation metrics

Online evaluation metrics are important for assessing the performance of ML systems. However, they are often not the primary focus in image captioning systems for two main reasons. First, image captioning systems are usually part of a bigger system, making it harder to collect user interaction data. Second, collecting feedback from users is challenging. Unlike tasks where we can easily measure user satisfaction, evaluating image caption quality requires subjective judgment, which, by definition, varies between users. For example, a caption might be acceptable to one user but not to another, depending on their personal interpretation of the image.

In summary, standard offline metrics remain the primary method for evaluating our image captioning system. For the few use cases where image captioning impacts user experience directly, engagement metrics and user feedback can provide valuable insights into the system's performance.

Overall ML System Design

Building an image captioning system is more than just training a model. It requires various components working together. In this section, we discuss the following key components essential for building an image captioning system:

  • Image preprocessing
  • Caption generator
  • Post-processing
Image represents a diagram illustrating an image captioning system.  An 'Input image' is fed into a light-blue rectangular box labeled 'Image...', which presumably performs initial image processing.  The output flows into a light-orange rectangular box labeled 'Caption Generat...', representing the core caption generation model.  This model receives input from a light-green cloud-shaped box labeled 'Trained...', indicating a pre-trained model, via a downward-pointing arrow labeled 'Beam search,' suggesting a beam search algorithm is used for caption selection. The output from 'Caption Generat...' then goes into a light-purple rectangular box labeled 'Post-processing,' likely for tasks like grammar correction or formatting. Finally, the processed caption is outputted as 'Mountains wi...', implying the generated caption related to mountains.  The entire process is depicted as a linear flow from input image to final caption, with the trained model influencing the caption generation through the beam search process.
Figure 17: Image captioning overall design

Let’s briefly explore each component and understand its role.

Image preprocessing

Image preprocessing is the initial step that prepares an input image for the trained model. This involves resizing images to a standard size, converting them into a consistent format, and standardizing pixel values. This step ensures that images are consistent with what the model expects as input.

Caption generator

The caption generator is the core component that produces captions based on the prepared image. This component interacts with the trained model and employs beam search to generate a coherent caption. If the cumulative probability of the generated caption falls below a predefined confidence threshold, the name suggestion is disabled; otherwise, the caption is passed to the post-processing component. This ensures that the system avoids producing irrelevant captions for ambiguous images.

Post-processing

The post-processing component identifies biased terms or phrases in the caption and replaces them with neutral alternatives. This ensures fairness and inclusivity in generated captions. Additionally, it checks for the presence of offensive words and disables the name suggestion service if any are found.

Other Talking Points

If the interview finishes early, you might want to bring up the following topics:

  • Extending the image captioner to support other tasks, such as visual question answering (VQA) [14].
  • Adapting models to caption images from various domains [15].
  • Generating captions in multiple languages using multilingual datasets and cross-lingual transfer learning [16].
  • Optimization techniques for caption generation on edge devices [17].
  • Generating and ranking multiple plausible captions based on relevance [18].
  • Details of BLIP-2 and BLIP-3 methods and additional loss functions utilized for improving captioning [1] [2].

Summary

Image represents a mind map summarizing the design of a Generative AI system for image captioning.  The central node is labeled 'Summary,' branching into seven main categories: Clarifying Requirements, Specifying Input and Output, Data Preparation (divided into Text and Image preprocessing steps, including tasks like removing duplicates, normalizing captions, and adjusting image dimensions), Model Development (covering Architecture choices like CNN-based vs. Transformer-based models, including details on positional encoding and 1D vs. 2D approaches, and training methods such as unsupervised pre-training and supervised fine-tuning), Evaluation (with offline metrics like ROUGE, METEOR, and CIDEr, and online metrics implied), Overall System Components (including image preprocessing, caption generation, and post-processing), and Other Talking Points.  Each branch further subdivides into more specific tasks and design choices, illustrating the hierarchical structure of the system's development process.  The connections between nodes represent the sequential or hierarchical relationships between different stages and components of the system.  For example, Data Preparation precedes Model Development, and Evaluation follows Training.  The color-coding of branches helps visually distinguish between different aspects of the system design.

Reference Material

[1] BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models. https://arxiv.org/abs/2301.12597. [2] xGen-MM (BLIP-3): A Family of Open Large Multimodal Models. ​​https://www.arxiv.org/abs/2408.08872. [3] InternVL: Scaling up Vision Foundation Models and Aligning for Generic Visual-Linguistic Tasks. https://arxiv.org/abs/2312.14238. [4] Meta’s Llama. https://llama.meta.com/. [5] Byte-pair encoding tokenization. https://huggingface.co/learn/nlp-course/en/chapter6/5. [6] LAION-5B: An open large-scale dataset for training next generation image-text models. https://arxiv.org/abs/2210.08402. [7] An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale. https://arxiv.org/abs/2010.11929. [8] Language Models are Unsupervised Multitask Learners. https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf. [9] Learning Transferable Visual Models From Natural Language Supervision. https://arxiv.org/abs/2103.00020. [10] Cross-entropy. https://en.wikipedia.org/wiki/Cross-entropy. [11] CIDEr: Consensus-based Image Description Evaluation. https://arxiv.org/abs/1411.5726. [12] TF-IDF introduction. https://web.stanford.edu/class/cs276/19handouts/lecture6-tfidf-1per.pdf. [13] TF-IDF. https://en.wikipedia.org/wiki/Tf%E2%80%93idf. [14] Visual question answering introduction. https://huggingface.co/tasks/visual-question-answering. [15] Cross-Domain Image Captioning with Discriminative Finetuning. https://arxiv.org/abs/2304.01662. [16] Crossmodal-3600 — Multilingual Reference Captions for Geographically Diverse Images. https://research.google/blog/crossmodal-3600-multilingual-reference-captions-for-geographically-diverse-images/. [17] Efficient Image Captioning for Edge Devices. https://arxiv.org/abs/2212.08985. [18] Ensemble model using an image captioning and ranking example. https://cloud.google.com/dataflow/docs/notebooks/run_inference_multi_model.

Chapter 6

Retrieval-Augmented Generation

~34 min read

Introduction

In Chapter 4, we developed a chatbot capable of answering open-domain questions. However, many applications need access to additional information, such as company databases (e.g., internal documentation), real-time data (e.g., sports scores), or user-provided files (e.g., uploaded PDFs).

Allowing chatbots to access this information improves the accuracy and relevance of their responses, especially for fact-based or specialized tasks. A real-world example of such a system is Perplexity.ai [1], an AI-powered conversational search engine that uses web-based information to respond to user queries.

Image represents a system diagram illustrating a query-response process for finding upcoming concerts.  The top section shows a user's query: 'Upcoming concerts around me in San Francisco with dates.' This query is then fed into a 'Sources' section, which lists three different data sources: Bandsintown (bandsintown. 1), SeatGeek (seatgeek. 2), and Eventbrite (eventbrite. 3), each indicated by their logo and a numerical identifier.  These sources are visually connected to the query with a curved arrow indicating data retrieval.  The 'Retrieved extern...' label highlights this data acquisition. The next section, 'Perplexity,' acts as a processing layer, taking the retrieved data and synthesizing it into a concise summary: 'Here are some upcoming concerts in San Francisco with dates:'.  Below this, the system outputs a list of 'Major Upcoming Concerts' and 'Notable Upcoming Shows,' each with artist names, dates, and venues, some entries marked with a small '2' suggesting a secondary source or verification.  A 'Ask follow-up' button is present, along with a 'Pro' toggle, suggesting a paid feature.  The entire output is labeled 'Produced...', connected to the 'Perplexity' section by a curved arrow, showing the information flow from processing to the final result.  The logos of various music streaming services are also present in the 'Sources' section, suggesting potential integration with these platforms.
Figure 1: *Perplexity’s* output based on real-time information (Credit: [1])

In this chapter, we build a system similar to ChatPDF [2] that answers employee questions using internal company documents. Instead of reading FAQs, employees can ask the chatbot directly and receive answers based on those documents.

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: What does the external knowledge base consist of? Does it change over time? Interviewer: The knowledge base includes company Wiki pages and a company-wide “Stack Overflow”–style forum. The documentation does change, but at a slower pace compared to real-time updates.

Candidate: Do the Wiki pages and forums contain text, images, and other modalities? Interviewer: Assume each page is in PDF format and contains text, tables, and diagrams. For simplicity, other modalities do not need to be considered.

Candidate: Do the pages follow a fixed format or template? Interviewer: No, the formats vary. Some are double-column, some are single-column, and others are mixed.

Candidate: How many pages are there in total? Interviewer: We have around 5 million pages.

Candidate: Is it necessary for the system to include document references? Interviewer: Yes.

Candidate: Should the system respond in real time? Interviewer: Users can tolerate a slight delay of a few seconds.

Candidate: Does the system need to support multiple languages? Interviewer: To keep things simple, let’s stick to English.

Candidate: Should the system support user feedback or follow-up questions? Interviewer: Not initially. However, your design should be flexible enough to add support for feedback loops or follow-up questions.

Candidate: What is the expected growth in documents? Interviewer: The document base is expected to grow by twenty percent annually.

Candidate: Do we need to address safety concerns, such as preventing harmful, biased, or misleading outputs? Interviewer: Safety matters, but let's prioritize data handling, architecture, and performance efficiency.

Frame the Problem as an ML Task

Specifying the system’s input and output

The input to the ChatPDF system is a text prompt provided by the user. The model processes this prompt alongside a continuously updated document database containing both text and images. The output is a text-based response that accurately addresses the user's query.

Image represents a simplified system architecture diagram for a ChatPDF system.  The diagram shows a user query, 'How do I submit an...', entering from the left, which is labeled 'User query'. This query is fed into a centrally located, peach-colored rectangle labeled 'ChatPDF System'.  The ChatPDF System interacts with a dashed-line-bordered box labeled 'Document databases,' containing icons representing multiple database servers, stacked documents, and an image, suggesting the system accesses various document types (PDFs and images) stored within these databases.  Two-way arrows connect the ChatPDF System and the Document databases, indicating data flow in both directions. Finally, a response, 'To submit an expense report, log into...', is shown in a rectangle labeled 'Response' on the right, representing the system's output generated after processing the user's query and accessing the relevant information from the document databases.  The overall flow is left-to-right, showing the user query's progression through the system to produce a final response.
Figure 2: Input and output of a ChatPDF system

Choosing a suitable ML approach

Given the nature of the task, large language models (LLMs) are well-suited for text generation and are often the default choice. However, general-purpose LLMs may struggle with specific domains and, therefore, may need customization to handle external data sources. To enable an LLM to answer queries based on company-specific data, there are three main approaches:

  • Finetuning
  • Prompt engineering
  • Retrieval-augmented generation (RAG)

Let's explore each one in detail and discuss their trade-offs.

Finetuning

In this approach, a pretrained general-purpose LLM is finetuned on company-specific data, such as internal documents. By updating its weights, the LLM adapts to better understand the company's unique terminology, processes, and FAQs. Chapter 10 will explore advanced finetuning techniques such as LoRA [3] to adapt large models to specific data.

Image represents a three-stage process for creating a specialized AI model.  The process begins with a 'General-purpose...' (light gray rectangle) model, which is then fed into a 'Finetuning' (light orange rectangle) stage.  The input for the finetuning stage is a 'Company-specific...' (labeled above a stack of three light yellow cylindrical database icons), suggesting that company-specific data is used to refine the general-purpose model.  The output of the finetuning stage is then passed to create a 'Specialized...' (light green rectangle) model.  Arrows indicate the unidirectional flow of information between these stages, showing the transformation of a general-purpose model into a company-specific, specialized model through a finetuning process.
Figure 3: Finetuning approach
Pros:
  • Customizable: Finetuning allows the model to generate responses tailored to specific domains.
  • Enhanced accuracy: By finetuning the model on specialized data, it becomes more accurate and better able to handle niche topics.
Cons:
  • Computationally expensive: Updating the entire model’s parameters requires a lot of computational resources, which can be expensive.
  • Frequent retraining: This approach requires frequent finetuning to continuously incorporate up-to-date data into the model.
  • Requires technical expertise: This approach requires an understanding of ML principles and language model architectures, which can be a barrier for those without specialized knowledge.
  • Extensive data requirement: Finetuning requires a substantial, high-quality dataset, which can be difficult and time-consuming to collect.
  • Lack of references: Finetuned models usually can’t provide references for their answers, making it hard to verify or trace information back to its source.

Prompt Engineering

Prompt engineering guides a general-purpose LLM to produce specific outputs through carefully designed prompts. Unlike finetuning, this method keeps the underlying LLM unchanged and includes relevant information, such as company data or instructions, directly in the prompts to control the model’s behavior. For example, a prompt might include information such as the summary of company policies, as shown in Figure 4. Later in this chapter, we will explore more advanced prompt engineering techniques, such as few-shot and chain-of-thought prompting.

Image represents a simplified flowchart illustrating a system's response to a user query.  The process begins with a user input, 'What is the company's r...', which is fed into a 'Prompt Engine...'. This engine processes the input and generates a refined query, 'Read the following company policy and r...', which is then directed to a data source (represented by a dashed box).  Separately, a second path originates from the same 'Prompt Engine...', connecting to a 'General-purpose...' component. This component processes information and produces an output, 'The company reimburses employees for t...', which is also directed to a separate data source (represented by another dashed box).  The arrows indicate the flow of information between components, showing how the initial user query is processed through different stages to generate two distinct outputs, potentially from different data sources.
Figure 4: Prompt engineering approach
Pros:
  • Ease of use: The prompt engineering is simple to use and requires no technical skills, which makes it suitable for a wide range of users.
  • Cost-effectiveness: By leveraging a pretrained LLM, prompting incurs minimal computational costs compared to finetuning.
  • Flexibility: Prompts can be easily modified to experiment with different outputs without having to retrain the model.
Cons:
  • Inconsistency: The quality and relevance of responses can vary greatly depending on how the prompt is phrased.
  • Limited customization: The ability to tailor responses is limited to the effectiveness and creativity of the prompt design. Prompt engineering lacks the depth of customization that finetuning provides.
  • Limited to LLM’s existing knowledge: Outputs are confined to the information the LLM was initially trained on, making it less effective for highly specialized domains or providing responses based on the most current information.

RAG

RAG is an advanced method that combines the capabilities of a general-purpose LLM with a real-time retrieval system. Instead of relying solely on the LLM’s pretrained knowledge, RAG retrieves relevant information from external sources, such as a company’s internal documents, and feeds it into the LLM during inference. This approach ensures the LLM generates responses that are both relevant and accurate based on the available information.

A RAG system, as shown in Figure 5, has two components:

  • Retrieval: The retrieval component takes the user’s original prompt, finds the most relevant information from external sources, and returns it as context.
  • Generation: Typically, a general-purpose LLM uses the user's prompt and the retrieved information to generate a response.
Image represents a system for generating text based on information retrieved from a document database.  A rectangular box labeled 'Document databases' contains icons representing document files and database tables, indicating storage of various document types.  A downward-pointing arrow connects this box to a light orange rectangular box labeled 'Retrieval,' signifying the process of fetching relevant data from the databases.  A dashed-line box below 'Retrieval' shows '[retrieved 1]...', representing the retrieved data.  A horizontal arrow connects a dashed-line box containing the prompt 'What is the company's rei...' to the 'Retrieval' box, indicating that the retrieval process is initiated by a user query.  The 'Retrieval' box is connected via a downward-pointing arrow to a light blue rectangular box labeled 'Generation,' which represents the text generation process using the retrieved data. Finally, a right-pointing arrow connects the 'Generation' box to a dashed-line box containing the output text 'The company reimburses employees for t...', showing the generated response based on the input query and retrieved information.  The overall flow depicts a query-driven retrieval and generation pipeline.
Figure 5: Components of a RAG system
Pros:
  • Access to most current information: RAG can provide up-to-date responses by pulling data from external sources, thus improving the relevance and accuracy of the answers.
  • Contextual relevance: By retrieving information from external sources, RAG can add context to the model’s answers, making responses more detailed and relevant.
Cons:
  • Implementation complexity: Implementing RAG can be technically challenging, as it requires two components (retrieval and generation) to work together smoothly.
  • Dependence on retrieval quality: The quality of the responses is highly dependent on the relevance and accuracy of the retrieved information, which can impact the overall performance of the system.

Which approach is more suitable for ChatPDF?

Finetuning allows the LLM to generate more specialized responses but is computationally expensive and does not reference original documents, making it unsuitable for our needs. While prompt engineering provides a simple and flexible way to guide a general-purpose LLM without finetuning, it’s not scalable. This is because including the information from all external sources in the prompt typically exceeds LLM’s context window.

RAG offers a balanced solution in terms of ease of setup, cost, and scalability, making it ideal for handling large, evolving datasets and providing up-to-date information. This approach is particularly effective for internal query chatbots in corporate environments. Therefore, we choose RAG to build our ChatPDF system. In the model development section, we delve into prompt engineering and discuss how we combine it with RAG to further enhance the system.

Data Preparation

The performance of the RAG system relies on the quality of the knowledge database and the way it is indexed. When the knowledge base is sourced from websites, data-cleaning strategies such as removing inappropriate content or anonymizing sensitive information should be applied, as discussed in Chapter 4.

In this section, we focus on preparing data from a collection of PDF pages. This involves a three-step process:

  • Document parsing
  • Document chunking
  • Indexing

Document parsing

PDFs are one of the most widely used document formats. It is important to properly extract their content to prepare the data for LLM training and to ensure that the LLM can correctly answer questions based on the PDF’s content.

Parsing a PDF means converting its text, images, and other elements into a structured format that a language model can understand. There are two primary approaches for parsing PDFs:

  • Rule-based document parser
  • AI-based document parser

Rule-based document parser

The rule-based approach relies on predefined rules and patterns that are based on the layout and structure of the document. It attempts to “calculate” the layout and extract content accordingly, making it easy to implement when the document format is consistent and predictable.

However, rule-based methods struggle to handle a wide range of PDF types and formats because PDFs can vary considerably in design. The rigid nature of this method means that if the document does not match the expected format, it can result in mistakes when extracting the content. This makes rule-based parsing less useful when dealing with differing or complex document layouts.

AI-based document parser

AI-based methods take a different approach. They use advanced techniques such as object detection and OCR (Optical Character Recognition) [4] to identify and extract various elements from a document, for example, text, tables, and diagrams. These methods can handle a wide range of document layouts, making them better suited for dealing with complex documents.

There are various tools available for AI-based document parsing. For example, Dedoc [5] supports parsing a wide range of document formats and standardizing content into a consistent structure. Similarly, Layout-Parser [6] uses high-precision models to accurately detect different parts of a document, though the size of these models can slow down the process. To better understand AI-based document parsers, let’s take a closer look at how Layout-Parser works.

Layout-Parser takes a document image as input and generates a structured output using the following steps:

  • Layout detection: The parser uses advanced object detection models to detect and generate rectangular boxes around different content regions. These regions can include elements such as paragraphs, tables, images, or headers.
  • Text extraction: The content inside each rectangular box is processed using OCR to extract the text. The bounding box coordinates ensure the text is recognized in the correct order and format, maintaining the document's original structure.
  • Structured output generation: The parser produces a structured output containing two types of data: Text blocks: Includes the block’s coordinates, extracted text, reading order, and meta information. Non-text blocks: Includes the coordinates of figures or images.
Image represents a system for extracting structured data from a PDF document.  A PDF page, labeled 'PDF (Page...', is depicted on the left.  This page's layout is shown as a rectangular box containing several colored boxes representing different elements: a large blue box labeled 'Title' at the top, smaller blue boxes labeled 'Title' in the middle and bottom, and several orange boxes labeled 'Text' throughout.  A yellow box labeled 'Figure' is also present.  An arrow labeled 'Layout...' connects the PDF page to this layout representation.  This layout representation is then connected via an arrow to a box labeled 'OCR'. The OCR processes the layout information, extracting text from the orange and blue boxes, and representing the extracted text as an array of text blocks within a dashed-line box labeled 'Structured output' with the content '[textblock 1, textblock 2,...]'.  The overall flow is from the PDF page, through a visual representation of its layout, to an OCR process that outputs structured text blocks.
Figure 6: Converting a PDF page to a structured output for LLM

Several online services provide document parsing services, for example, Google Cloud Document AI [7] and PDF.co [8]. These services allow users to upload their documents and have them parsed without needing to set up and maintain the parsing system themselves.

Document chunking

Once we have identified the blocks of text, images, or tables in a document, the next step is to index them into a searchable database. For long text blocks such as those found in reports or books, indexing the entire content as a single item is ineffective. This is because the embedding vector representing an entire book or report might capture the general context but miss important details, which can result in less-accurate or incomplete retrieval results. Additionally, if we retrieve the entire book or report, it would exceed the token limit of most models, such as the 128K token limit for the GPT-4o model.1

Document chunking addresses these challenges by breaking the text into smaller, manageable pieces or ‘chunks.’ Chunking helps improve the quality and precision of the retrieval and ensures that each chunk fits within the model's input limit.

Some common strategies for chunking are:

  • Length-based chunking: This simple approach splits the text into chunks based on a specified length. While it's easy to implement, it can sometimes split sentences or logical sections in the middle, leading to fragmented or less-meaningful chunks. Tools like LangChain [9] provide text splitters, such as the CharacterTextSplitter and RecursiveCharacterTextSplitter, which allow for adjustable chunk sizes and overlap settings. These splitters can handle different separators and help maintain coherence across chunks.
  • Regular expression-based chunking: This approach uses regular expressions to split the text based on specific punctuation marks, such as periods, question marks, or exclamation points. It allows for better sentence-level chunking by keeping logical breaks intact, although it may still lack a deeper semantic understanding of the text.
  • HTML, markdown, or code splitters: For documents in structured formats like HTML or Markdown, specialized splitters are used. These tools split the text at element boundaries such as headers, list items, or code blocks, while preserving the document’s overall structure. For example, LangChain has MarkdownHeaderTextSplitter, HTMLHeaderTextSplitter, and PythonCodeTextSplitter, respectively. These splitters are useful for web pages or technical documentation, where maintaining the hierarchical structure is important. Figure 7: Length-based text chunking with LangChain

Indexing

After preparing the data through document parsing and chunking, the final critical step in the RAG system is indexing. Indexing is the process of organizing the chunked data into a structure that enables efficient and accurate retrieval. This step plays a key role in ensuring that the system can quickly locate relevant chunks of information when a query is made.

To determine the indexing process, it is crucial to understand various retrieval techniques and choose the one that best suits the task. Popular retrieval techniques include:

  • Keyword-based
  • Full-text search
  • Knowledge graph–based
  • Vector-based

Let’s first explore each technique, and then index our data to enable efficient retrieval.

Keyword-based

Traditional keyword-based retrieval relies on matching exact query terms with the content of documents. It is fast and simple but cannot understand the meaning of the query. For example, it may struggle with synonyms, leading to incomplete or irrelevant results. This approach is ineffective when dealing with large-scale datasets or when the goal is to retrieve information based on semantic similarity rather than exact word matches.

Full-text search engines such as Elasticsearch [10] offer a more advanced approach by scanning entire documents for relevant matches. This method allows for a comprehensive analysis of the document’s content, including partial matches and phrase searches. However, full-text search comes with higher computational overhead, especially when dealing with large datasets containing, for example, millions of PDF documents. Although effective for finding specific text, this approach is less efficient when it comes to semantic retrieval.

Knowledge graph–based

Knowledge graph–based retrieval is a sophisticated technique that leverages structured relationships between entities (e.g., people, places, or concepts) to retrieve information based on the connections between these entities. This method is excellent for answering complex queries and understanding relationships within the data. However, building and maintaining a knowledge graph requires significant effort, and it is not always practical for large, unstructured datasets such as PDF collections or Wiki pages. To learn more about knowledge graph–based retrieval, refer to [11].

Vector-based

Instead of relying on text-based matches, this method uses high-dimensional embeddings—numerical representations of the text and images—to measure the similarity between a query and the stored chunks of data. This technique enables the retrieval of relevant information even when the exact words in the query do not match the document content, making it more flexible and powerful for large-scale datasets.

Which retrieval technique is suitable for the ChatPDF?

To select an appropriate retrieval method, let’s first understand the scale of our system and estimate the number of data chunks involved. In this case, the company manages a large dataset of around 5 million pages. Suppose each page contains roughly 1,500 characters and includes three images. Using length-based chunking with a chunk size of 500 characters and a 200-character overlap, each page will generate 5 text chunks and 3 image chunks. Therefore, the total number of chunks the RAG system is dealing with is 5M(1500 / (500-200) + 3)=40M. This figure is expected to grow by roughly 20 percent each year, as indicated in the requirements section.

With around 40 million data chunks and a projected 20 percent annual increase, it's essential to select a retrieval technique that is scalable and can handle this growing volume efficiently.

Traditional retrieval methods [12] [13] such as keyword-based and full-text search have been widely used, but they face limitations in speed, scalability, and the ability to understand the semantic meaning of queries. Knowledge graph–based retrieval requires significant effort to build and maintain such graphs, making them a costly choice.

Vector-based retrieval, on the other hand, is the primary technique used in modern RAG systems due to the following advantages:

  • Semantic understanding: It can capture the semantic meaning of a query, allowing for more accurate retrieval even when the exact query terms are not present in the document.
  • Scalability: Using embedding vectors makes this method highly scalable and able to handle large datasets efficiently.
  • Efficiency: Once the data is indexed as embedding vectors, the system can efficiently retrieve the relevant chunks.

Due to these advantages, we choose vector-based retrieval and index our data accordingly.

Indexing data for vector-based retrieval

In a vector-based retrieval system, each chunk of data is converted into an embedding vector representing the content in a numerical format. When indexing, ML models are employed to compute the embeddings and store them in a vector database. This makes it easy for the RAG system to quickly compare them to the query’s embedding and retrieve the most relevant information without unnecessary processing at inference time. We'll dive into the architecture of these ML models and examine the retrieval process in more detail in the model development section.

Image represents a document processing and indexing pipeline.  The process begins with 'Document databases', depicted as a box containing icons representing various document types (text files and images).  These databases feed into 'Document parsing', a beige rectangle, which processes the documents. The output of parsing flows into 'Document chunking', another beige rectangle, dividing the parsed document into smaller chunks.  A table labeled 'Chunk' and 'Chunk data' shows the resulting chunks numbered 1 to M, each with its corresponding 'chunk output'.  The chunks then proceed to 'Indexing', a beige rectangle, which generates embeddings for each chunk.  A table labeled '#' and 'Embedding' illustrates this, showing M rows, each representing a chunk with its corresponding embedding vector (represented by empty boxes). Finally, the indexed chunks are stored in two databases labeled 'Index...', representing the final indexed data.  A separate table, connected via a dashed line to 'Document parsing', shows the structured output of the entire process, mapping page numbers (1 to N) to their corresponding textual outputs.
Figure 8: Data preparation steps from PDFs to indexed embeddings

In summary, we use a three-step approach to prepare PDFs for the RAG system. First, we apply document parsing techniques to convert the PDF into a structured format, breaking it down into text, tables, and images. Then, we use document chunking to split long text into smaller, manageable chunks. Finally, each chunk is converted to an embedding vector and indexed individually to improve retrieval accuracy.

Model Development

Architecture

This section explores the architecture of a RAG system, focusing on the ML models used in the indexing, retrieval, and generation components.

Image represents a three-stage process for a multimodal system. The first stage, labeled 'Indexing,' contains a light-green box labeled 'Text encoder' above a light-blue box labeled 'Image encoder.'  These encoders process textual and image data respectively, presumably generating embeddings.  The second stage, 'Retrieval,' shows only a light-green box labeled 'Text encoder,' suggesting that a text-based query is processed to generate an embedding for searching the indexed data.  The third stage, 'Generati...' (likely 'Generation'), contains a light-grey box labeled 'LLM' (Large Language Model).  The flow is sequential: the 'Indexing' stage creates embeddings from text and images; the 'Retrieval' stage uses a text encoder to find relevant embeddings from the index; and finally, the 'Generation' stage uses the retrieved information (implicitly passed from the retrieval stage) as input to the LLM to generate an output.  The dashed lines around each stage suggest distinct processing phases.
Figure 9: Various ML models in a RAG system

Indexing

As discussed in the data preparation section, we use ML models to convert data chunks (e.g., text or images) into embeddings. This process involves two ML models: a text encoder and an image encoder.

Text encoder

The text encoder is a neural network that converts input text into dense vector representations, or "embeddings." These embeddings capture the semantic meaning of the text, allowing for the assessment of the similarity of texts. During the indexing process, the text encoder converts each text chunk into an embedding, which is then stored in a database for efficient retrieval.

The architecture of the text encoder is typically based on an encoder-only Transformer, similar to what we covered in Chapter 3.

Image encoder

The image encoder transforms image data into embeddings. Its architecture can be either CNN-based or Transformer-based, as we covered in Chapter 5.

For effective retrieval, it is important to align the image embeddings with text embeddings. For example, if the query is “How many cats are in the company?” the system needs to ensure that the encoded query is close to the embeddings of relevant images, such as those featuring cats. There are two primary approaches to achieving this alignment:

  • Shared embedding space: Use image and text encoders that generate embeddings in a shared embedding space. CLIP [14] provides pretrained encoders with a shared embedding space, enabling cross-modal retrieval.
  • Image captioning: First, generate a textual description of the image using an image captioning model. The generated caption can then be encoded using a text encoder, ensuring that both image and text data exist in the same embedding space. This approach is helpful when using separate models for text and image encoders or when training a joint model is resource-intensive. To learn more about building an image captioning system from scratch, refer to Chapter 5.
Image represents two approaches to image captioning.  Approach 1 depicts a CLIP model, consisting of an Image Encoder (light blue) and a Text Encoder (light green), processing an image and generating a text embedding.  The output of both encoders is then fed into an index (represented by a database cylinder), presumably for storage or retrieval. Approach 2 shows a simpler system where an image is first processed by an 'Image Captioning' module (grey), generating a caption like 'The image shows a cat sitting...'. This caption is then fed into a Text Encoder (light green), and the resulting text embedding is stored in an index (database cylinder).  The dashed lines in Approach 2 indicate a potential feedback loop or further processing of the generated caption.  Both approaches ultimately aim to store image-text embeddings within an index for later use, but they differ in their initial processing steps and the type of information indexed.
Figure 10: Two approaches for achieving text–image alignment

In summary, the indexing process uses a text encoder and an image encoder to convert data chunks into embeddings. These models are often pretrained, meaning they can be directly applied without additional training. For the purposes of this chapter, we use a pretrained CLIP model as both the text and image encoder.

Retrieval

The retrieval process involves converting the user’s query into the same embedding space as the indexed data. This is done using the same text encoder employed during the indexing process. Once the query embedding is computed, it is compared with the stored embeddings to retrieve the most relevant data chunks.

Generation

The generation component is responsible for producing the final response based on the user query and the retrieved context. This task is typically handled by an LLM, which generates contextually relevant text.

RAG systems can work with various types of LLMs irrespective of their architecture, including decoder-only Transformers (see Chapter 4 for details) or cloud-hosted models that support finetuning via APIs [15] [16].

Training

Most of the components in a RAG system start with pretrained models, so finetuning the LLM is not typically the first step in optimizing performance. In many cases, a well-designed retrieval process combined with effective prompt engineering can yield satisfactory results. Finetuning should be considered when the system consistently fails to provide accurate or relevant answers, even after adjusting retrieval parameters and crafting prompts. For instance, if the retrieved documents are relevant but the LLM is not generating high-quality responses, finetuning could help the LLM better understand the context and nuances of the retrieved data.

One promising approach to finetuning LLMs in RAG systems is Retrieval-Augmented Fine-Tuning (RAFT). Let’s briefly examine RAFT.

RAFT

RAFT [17] introduces a novel training method to enhance the LLM’s ability to handle both relevant and irrelevant information within retrieved documents.

In traditional RAG systems, the LLM’s output depends heavily on the quality of the retrieved documents. However, irrelevant documents might be included in the retrieval results. These irrelevant documents can mislead the LLM, causing it to generate suboptimal responses. RAFT addresses this issue by incorporating a distinction between relevant and irrelevant documents during the finetuning process. This process involves two key steps:

  • Document labeling: Retrieved documents are labeled as either relevant (golden) or irrelevant (distractors). This provides the LLM with clear signals about the documents on which they should focus.
  • Joint training: During finetuning, the LLM is trained to generate responses based on the relevant documents while minimizing the influence of irrelevant documents. This requires adjusting the model’s loss function to penalize the use of irrelevant documents during response generation.

By training the model to prioritize relevant content and ignore distractors, RAFT improves the LLM’s ability to handle noisy retrieval results and generate accurate and relevant responses. This ability is crucial in real-world applications, where retrieval systems may not always be perfect. To learn more about RAFT, refer to [17].

Image represents a comparison of two training methods for a question-answering system, along with a testing methodology.  The top half depicts the 'Train: RAFT' method, which uses three sampled negative documents labeled 'Adam,' 'GloVe,' and 'ResNet' (marked with red 'X's), alongside a positive document ('Attention is all you need,' marked with a green checkmark) and a user query ('query,' represented as a cloud). These are combined to train a model (represented by a robot). The bottom half shows the 'Train: Golden Only' method, using only a single positive document ('Attention is all you need') and the same query to train a separate model.  A vertical line separates the training sections from the testing section ('Test: RAG Top-k'). The testing section shows three different models (LLaMa2, Sliding Window, and Mistral 7B), each receiving the same query and producing an output document (represented by a question mark).  These outputs are then fed into a final model (another robot) which is also labeled with 'What attention is used in Mistral,' indicating the testing focuses on the attention mechanism used in the Mistral 7B model. The 'top-k...' label suggests a top-k selection process is used to choose the best output from the three models before feeding it to the final model.
Figure 11: RAFT training method (Image taken from [17])

Sampling

Sampling typically involves generating new data with a generative model. In a RAG system, however, multiple components work together to produce a response to a user’s query. In this section, we explore these components and highlight techniques for improving performance in the retrieval and generation stages of a RAG system.

Retrieval

The retrieval process occurs in two main steps:

  • Computing the query embedding
  • Performing a nearest neighbor search
. Computing the query embedding

The first step involves converting the user’s query into an embedding using the text encoder. This embedding captures the semantic meaning of the query, allowing the system to compare it to the indexed embeddings of data chunks.

Image represents a simplified data flow diagram illustrating a text encoding process.  A user query, 'How do I submit an...', is presented as input within a rectangular box labeled 'User query'.  This query is then passed as input, via a directed arrow, to a light green rectangular box labeled 'Text encoder'. The text encoder processes the user's query. The output of the text encoder is a vector of numerical values (0.1, 0.9, 0.3, 0.4) represented as a column of cells, suggesting a numerical embedding of the text.  Below this vector, '$E_...' indicates that this is a part of a larger embedding vector, with the ellipsis suggesting further values not shown in the image. The arrows indicate the unidirectional flow of data from the user query through the text encoder to the resulting numerical embedding.
Figure 12: User query converted to embedding

Once the query embedding is computed, the system performs a nearest neighbor search to find data chunks that are most similar to the query. Nearest neighbor search addresses the task of identifying data points in a dataset that are closest to a given query point, based on a chosen similarity measure. Common measures include Euclidean distance [18], cosine similarity [19], or other distance metrics that capture relationships between data points in an embedding space.

Nearest neighbor search is a fundamental component of information retrieval, search engines, and recommendation systems. Even small improvements in its performance can lead to significant overall system gains. Given its importance, interviewers may want you to dive deeper into this topic.

Nearest neighbor algorithms generally fall into two categories:

  • Exact nearest neighbor
  • Approximate nearest neighbor
Exact nearest neighbor

Exact nearest neighbor search, also called linear search, is the simplest and most accurate form of nearest neighbor search. It calculates the distance between the query embedding, EqE_qEq​, and every item in the dataset, retrieving the kkk nearest neighbors.

Image represents a two-dimensional scatter plot with axes labeled X1 and X2.  The plot displays numerous data points marked as 'x' scattered across the plane. A subset of these data points, approximately five, are enclosed within a dashed elliptical boundary.  This ellipse is labeled with 'k=3' indicating a parameter likely related to the number of data points within the cluster or a clustering algorithm's parameter.  Within the ellipse, a short dashed line connects two 'x' points, and the text '$E_...' is positioned near this line, suggesting this might represent an error term or a distance calculation within the cluster. The remaining data points outside the ellipse are distributed across the plot, indicating potential separation into different clusters or groups.  The overall image suggests a visualization of a clustering algorithm's result, possibly k-means with k=3, showing the identified cluster and its centroid (or a similar representation implied by the ellipse and the '$E_...' notation).
Figure 13: Top-3 nearest neighbors to query embedding

While this method guarantees finding the true nearest neighbors, it has a time complexity of O(N×D)O(N\times D)O(N×D), where NNN is the number of items in the dataset and DDD is the embedding dimension. This linear complexity can make the process very slow when working with large-scale systems, such as a RAG system indexing tens of millions of items. For instance, performing an exact search across 40 million items for a single query would involve 40 million comparisons, leading to high computational costs and latency. Therefore, the exact nearest neighbor search is often too slow and computationally expensive to be employed in practice.

Approximate nearest neighbor (ANN)

In many applications, it's sufficient to retrieve items that are similar enough without needing to find the exact nearest neighbor. ANN algorithms use specialized data structures that allow the system to retrieve “close enough” neighbors without searching the entire dataset, thus reducing search time to sublinear complexity, for example, O(log⁡(N)×D)O(\log(N)\times D)O(log(N)×D). While these algorithms typically require some preprocessing or extra storage, they offer considerable performance benefits.

Various ANN algorithms can generally be divided into the following categories:

  • Tree-based
  • Locality-sensitive hashing
  • Clustering-based
  • Graph-based

While the interviewer typically will not expect you to know every detail of these categories, it is generally helpful to have a high-level understanding of them. Let’s dive in.

Tree-based

Tree-based algorithms partition the data space into multiple partitions. Then they leverage the characteristics of the tree to perform a faster search. For example, k-d tree [20] splits the space based on feature values, enabling faster searches by narrowing down relevant regions of the data. Other algorithms include R-trees [21] and Annoy (Approximate Nearest Neighbor Oh Yeah) [22].

Image represents a visualization comparing a tree-like structure with a 2D scatter plot.  The left side shows a tree structure with a root node at the top, branching down to two child nodes, each of which further branches into two leaf nodes.  Each leaf node is labeled with '$R_...', suggesting a similar data structure or result at each leaf.  The right side displays a 2D scatter plot with axes labeled 'X1' and 'X2'.  Numerous data points marked with 'x' are scattered across the plot.  The plot is partitioned into regions by lines, with each region labeled with '$R_...', '$R_x.', or a similar variation, suggesting a classification or clustering of the data points based on their X1 and X2 coordinates. A double-headed arrow connects the tree and the scatter plot, indicating a mapping or transformation between the hierarchical representation of the tree and the spatial representation of the scatter plot.  The labels suggest that the tree structure might represent a decision tree or a similar hierarchical model used for classification, and the scatter plot shows the resulting classification regions in the feature space defined by X1 and X2.
Figure 14: Partitioned space created by a tree
Locality-sensitive hashing (LSH)

LSH groups similar points into buckets using specialized hash functions. These functions ensure that points close in space are hashed into the same bucket. This drastically reduces the search space because only points in the same bucket as the query need to be examined, making LSH highly efficient for large datasets. You can learn more about LSH by reading [23].

Image represents a Locality Sensitive Hashing (LSH) scheme for approximate nearest neighbor search.  The diagram shows several clusters of data points, each represented by a dashed oval containing several small circles.  These clusters represent groups of similar data points in a high-dimensional space.  A horizontal dashed line separates the high-dimensional data space from a lower-dimensional hash table.  The label 'LSH(x)' and a downward-pointing arrow indicate that the data points are transformed using an LSH function.  Lines connect each cluster to one or more specific locations (represented by circles) within the hash table.  These connections show how the LSH function maps similar data points to the same or nearby buckets in the hash table.  The hash table is depicted as a rectangular structure divided into several sections, each containing several circles representing hash buckets.  Each section likely corresponds to a different hash function used in the LSH scheme.  The arrangement demonstrates that similar data points (those within the same cluster) are likely to be hashed to the same or nearby buckets in the hash table, facilitating efficient approximate nearest neighbor search.
Figure 15: LSH groups the data points into buckets
Clustering-based

Clustering-based algorithms organize data into clusters using distance metrics such as cosine similarity or Euclidean distance. This allows the search for the nearest neighbor to be limited to the cluster(s) most relevant to the query, reducing the number of comparisons required, as only data points within the selected cluster are considered. Specifically, once the indexed items are organized into clusters, nearest neighbors are retrieved in two steps:

  • Inter-cluster search: The query embedding is compared to the centroids of all clusters, and the clusters that are closer than a specified threshold are selected.
  • Intra-cluster search: The query embedding is compared to the items in selected clusters.

This two-step process—first narrowing down the search to a cluster, then conducting a finer search within that cluster—significantly improves efficiency. This process is shown in Figure 16.

Graph-based

Graph-based algorithms, such as HNSW (hierarchical navigable small world) [24], structure the data as a graph, where nodes represent data points and edges connect them based on proximity in the embedding space. HNSW operates by navigating through this graph in a hierarchical manner, beginning with a higher-level coarse graph and gradually moving down to finer levels. The search is refined at each level, exploring only nearby nodes, thus drastically reducing the search space.

Which nearest neighbor search category is best suited for a RAG retrieval system?

In RAG systems, the number of indexed items is typically massive and growing, often exceeding hundreds of millions of embeddings. The time complexity of the exact nearest neighbor search is too high, therefore, we rely on ANN algorithms to efficiently retrieve relevant data chunks.

Various ANN algorithms have their own strengths. Choosing the right ANN algorithm usually depends on factors such as the dataset size, required speed, and accuracy trade-offs. For simplicity, we employ a clustering-based ANN approach in the retrieval component of the RAG system.

Image represents a system for document retrieval.  The process begins with 'Document databases' containing various document types (text and images), undergoing 'Data preparation.' This prepared data is then indexed into two separate 'Index...' databases. These indices are subsequently clustered into three distinct 'Clusteri...' groups, visually represented as ovals containing differently colored dots representing documents. A user query, 'How many cats live i...', is input into a 'Text Encoder.'  The encoded query is then compared against the clusters.  The system uses an 'Inter-Cluste...' module to assess inter-cluster similarity, rejecting two clusters (indicated by red 'X' marks) and selecting one (indicated by a green checkmark).  The selected cluster is further processed by an 'Intra-Cluste...' module to refine the retrieval.  Finally, the system outputs a list of 'Retrieved...' documents (retrieved doc 1, retrieved doc 2,..., retrieved doc k) based on the intra-cluster similarity, effectively retrieving relevant documents based on the user's query.
Figure 16: Overall retrieval process

Several modern frameworks provide out-of-the-box support for ANN, including:

  • Elasticsearch [10]: A widely used search engine that supports vector similarity search.
  • FAISS [25]: A popular library developed by Meta that enables efficient nearest neighbor search for large datasets.
  • ScaNN [26]: A library developed by Google, designed for fast and efficient nearest neighbor search on large datasets.

These frameworks are commonly used in practice to make the retrieval components of large-scale systems both efficient and scalable.

Generation

The generation component takes the user query and retrieved context as input and generates a response using top-p sampling. However, we can further improve the quality of the generated response by incorporating prompt engineering techniques, as shown in Figure 17.

Image represents a simplified diagram of a text generation system.  A 'User query' enters the system from the left and flows into a rounded rectangular box labeled 'Generation'. Inside this box, the user query is first transformed into a 'Prompt...' (represented by a light purple rectangle), which is then fed into a light gray rectangle labeled 'LLM' (likely representing a Large Language Model).  A parameter, 'Top p...', is applied to the output of the LLM.  Finally, the processed output, labeled 'Response', exits the 'Generation' box on the right.  Above the 'Generation' box, a vertical arrow indicates that additional information, labeled 'Retrieved...', is incorporated into the 'Prompt...' before it's processed by the LLM.  The overall flow is linear, from user input to prompt creation, LLM processing with parameter application, and finally to the generated response.
Figure 17: Generation component overview

In this section, we dive into prompt engineering and explore how it enhances response generation in a RAG system.

Prompt engineering

Prompt engineering is a powerful technique that optimizes input prompts to help LLMs generate more accurate and contextually relevant responses. By carefully designing prompts, we can guide the model’s output to better align with specific tasks, improving overall performance. While prompt engineering can be applied in both the retrieval (e.g., crafting better queries to optimize search) and generation, we focus on applying it to the generation for educational purposes. The same approach can also be used to improve retrieval performance.

Let’s start this section with prompt design principles, followed by prompt engineering techniques.

Prompt design principles

Effective prompt design is crucial for maximizing the performance of language models. By following key principles, we can enhance the quality of the generated output and reduce irrelevant or confusing responses. Below are some essential prompt engineering principles:

  • Start simple: Begin with straightforward prompts and gradually introduce more complexity. Iterative experimentation is key to refining prompts. Tools such as Cohere’s Playground [27] allow you to easily test and adjust prompts as needed.
  • Break down complex tasks: Break down tasks involving multiple subtasks into smaller, manageable steps. This avoids overwhelming the LLM and ensures better focus on individual subtasks.
  • Use clear instructions: Be explicit with instructions, using clear, action-oriented commands such as "Write," "Summarize," or "Translate." Experiment with different instructions to find what works best for your task. Placing instructions at the beginning of the prompt, separated by delimiters such as "###," can also help organize the prompt.
  • Be specific: Specificity leads to more accurate responses. Clearly describe what you expect in terms of format, style, or outcomes. However, avoid overloading the prompt with unnecessary details—include only what is relevant to the task.
  • Experiment with prompt length: Consider the length of the prompt. Too much unnecessary information can confuse the LLM, while too little may result in vague responses. Strike a balance by being concise yet detailed enough to guide the LLM effectively.
Prompt engineering techniques

Several prompt engineering techniques have been developed to improve the quality of LLM outputs. Some of the most effective ones include:

  • Chain-of-thought prompting
  • Few-shot prompting
  • Role-specific prompting
  • User-context prompting
Chain-of-thought prompting

Chain-of-thought (CoT) prompting [28] involves guiding the model through intermediate reasoning steps before arriving at a final answer. This is especially useful for complex queries requiring multi-hop reasoning, where the model must combine information from multiple documents to generate a complete response. CoT prompts guide the model to break down its reasoning into steps, leading to more accurate and insightful answers.

Image represents a rectangular box containing a single line of text: 'Given the following documents, explain the step-by-...'.  The text is centrally aligned within the box and is written in a simple, sans-serif font.  No other components, connections, or information flow are visible within the image; the box only serves as a container for the prompt, indicating that a subsequent part of the image (which is not displayed) would contain the 'following documents' referred to in the prompt.  The text 'Text is not SVG - cannot display' below the box indicates that the image originally contained additional visual information, likely a diagram or flowchart, which could not be rendered.
Figure 18: Example of CoT

CoT has been further extended by techniques such as [29] that allow models to evaluate multiple reasoning paths before selecting the best response. OpenAI’s o12 [30] and [31] have shown that an LLM’s ability to handle more complex tasks can be improved by allocating more computational budget at inference time, also known as test-time compute scaling.

Few-shot prompting

Few-shot prompting [32] involves providing the model with a few examples of input-output pairs before the actual query. This method helps the model understand the desired format and tone of the output, improving its ability to generate responses that align with the provided examples.

Image represents a simple, text-based illustration of a question-answering system.  The image contains a single line of text within a rectangular box.  This line presents an example labeled 'Example 1,' showing a user query: 'How do plants absorb sunlight?'  A right-pointing arrow ('→') acts as a connector, visually indicating the flow of information from the query to the system's response. The system's answer, partially shown as 'Plants...', follows the arrow.  There are no other components, connections, or visual elements besides the text and the arrow. The text 'Text is not SVG - cannot display' at the bottom indicates that a visual component was intended but not rendered.
Figure 19: Example of few-shot prompting
Role-specific prompting

In some cases, the language model may need to adopt a specific "role" to generate an appropriate response. For example, in legal or medical domains, prompting the model to act as a subject-matter expert ensures that the response carries the necessary tone, accuracy, and authority.

Image represents a simple text-based prompt within a rectangular frame.  The only visible component is a single line of text reading 'You are an experienced contract lawyer with over 20 years of experience specializing in corp...', indicating a scenario or context for a problem to be solved.  The text is centrally aligned within the frame.  There are no other components, connections, or information flows depicted.  The bottom of the image contains the text 'Text is not SVG - cannot display,' suggesting that the image is a placeholder or a failed attempt to render a more complex diagram.
Figure 20: Example of role-specific prompting
User-context prompting

User-context prompting tailors the model’s output based on specific user information included in the prompt. By incorporating user profiles, preferences, or locations into the queries, the model can generate personalized responses that are more relevant to the users.

Image represents a rectangular box with a gray border.  The only visible content within the box is the text '[Other prompts]...', located in the top-left corner.  This suggests the box represents a container or placeholder for additional input prompts, which are not explicitly shown in the image.  There are no other components, connections, or information flows depicted within the box or connected to it. The bottom of the image displays the text 'Text is not SVG - cannot display,' indicating that the image is a placeholder for a more complex diagram that could not be rendered.
Figure 21: Example of user-context prompting

This method is particularly effective when user-specific information is crucial to shaping the response, such as in personalized recommendations or location-based queries.

Putting it all together: prompt engineering for response generation

Combining these techniques allows us to craft highly effective prompts for generating responses in a RAG system. Principles such as clarity and specificity can guide the model to produce more accurate outputs. Prompt engineering techniques can significantly enhance a RAG’s generation capabilities, resulting in more reliable and contextually appropriate outcomes.

Image represents a system architecture diagram illustrating the processing flow of a user's query within a large language model (LLM) system.  The diagram shows a vertical stack of five horizontal rectangular boxes representing different stages of processing, arranged from top to bottom. The top two boxes, colored light red and pale yellow respectively, represent 'Retrieved Context...' and 'Role-Specific...', indicating the retrieval of relevant contextual information and role-specific knowledge. The third box, light blue, contains the user's initial query labeled '[INITIAL_QUERY]...', which is the input to the system. The fourth box, light green, represents the 'CoT' (Chain of Thought) reasoning process. The bottom box, light purple, represents 'User-Context...', indicating the user's historical interaction data.  Arrows point from each of these boxes to the right, connecting them to corresponding labeled rectangular boxes outside the main stack: 'Retrieved Context...', 'Role-Specific...', 'Few-Shot Prompt...', 'CoT', and 'User-Context...'. These external boxes represent the outputs or components used in each stage. The overall flow suggests that the system uses retrieved context, role-specific information, a few-shot prompt, chain-of-thought reasoning, and user context to process the user's initial query.
Figure 22: Example of final prompt for response generation

Evaluation

Unlike traditional ML models, which are evaluated using well-defined quantitative metrics, evaluating RAG systems is more complex. This complexity arises because the quality of the final text response depends on the effectiveness of multiple components within the pipeline. To capture this multifaceted evaluation, we use a triad diagram to explain the relationship between different evaluation aspects.

Image represents a simplified model of a query-response system, focusing on relevance and faithfulness.  Three main components are depicted as ovals: 'Query,' 'Results,' and 'Context.'  A directed arrow labeled 'Answer Relevance...' connects 'Results' to 'Query,' indicating that the results' relevance influences the initial query.  Another arrow labeled 'Context Relevance' points from 'Query' to 'Context,' showing how the query's context is determined.  Finally, a bidirectional arrow labeled 'Faithfulness' connects 'Results' and 'Context,' suggesting a feedback loop where the faithfulness of the results to the context is evaluated and potentially influences the results.  The overall structure illustrates how a query, its context, and the resulting answers are interconnected, with relevance and faithfulness acting as key evaluation criteria.
Figure 23: Triad of RAG evaluation

The evaluation of a RAG system focuses on four key aspects:

  • Context relevance
  • Faithfulness
  • Answer relevance
  • Answer correctness

These aspects help assess how well the system retrieves, generates, and matches information relevant to the user’s query. Let’s examine each in more detail.

Context relevance

Context relevance measures how accurately and completely the retrieval component selects relevant documents based on the query. The goal is to ensure that all relevant content appears at the top of the retrieval results. This aspect directly evaluates the effectiveness of the retrieval mechanism. Common metrics used for context relevance include:

  • Hit rate
  • Mean reciprocal rank (MRR)
  • Normalized discounted cumulative gain (NDCG)
  • Precision@k

To learn more about evaluation metrics in retrieval and ranking systems, refer to [33][34].

Faithfulness

Faithfulness assesses whether the generated response is factually aligned with the retrieved context. It checks if the generation component is hallucinating (i.e., introducing information not grounded in the context). This is crucial because the system should produce answers that strictly reflect the source material. By evaluating faithfulness, we reduce the risk of generating plausible-sounding yet factually unaligned responses, thereby enhancing the reliability and trustworthiness of the output.

Image represents a system for generating different responses to a user's query using a Large Language Model (LLM).  A rectangular box labeled 'User's initial query: What are Marie Curie's main ac...' represents the user's input, which is a partial query about Marie Curie's accomplishments. This input, labeled 'Full prompt,' is fed into a central, light-green rectangular box labeled 'LLM,' representing the Large Language Model. The LLM processes the query and produces two different outputs, depending on a parameter seemingly related to the desired level of detail or confidence.  One output, labeled 'Marie Curie won Nobel Prizes in both Phys...', is associated with a 'High...' parameter, suggesting a more comprehensive or confident response. The other output, labeled 'Marie Curie only won a Nobel Prize in...', is associated with a 'Low...' parameter, indicating a less detailed or less confident response.  Arrows show the flow of information from the user's query to the LLM and then to the two different output boxes.
Figure 24: Example of faithfulness

Faithfulness can be assessed using the following methods:

  • Human evaluation: Experts manually review the generated responses to determine whether they are factually aligned and correctly referenced to the retrieved documents. This process involves cross-checking each claim against the source materials to ensure all information generated is substantiated.
  • Automated fact-checking tools: Tools such as [35] and [36] can automate the validation process by comparing the generated response against a database of verified facts. They offer a scalable solution for identifying inaccuracies, thus reducing the reliance on human evaluators.
  • Consistency checks: This method involves evaluating whether the LLM provides consistent factual information across multiple queries. Regular consistency checks ensure that the LLM does not produce contradictory information, which is essential for maintaining the reliability and coherence of the responses over time.

Answer relevance

Answer relevance measures how closely the generated answer matches the original query in terms of completeness and lack of redundancy. If the response includes irrelevant or redundant information or lacks important details, it scores low in relevance. This aspect can be evaluated by comparing the question and the answer using another language model (e.g., ChatGPT).

Image represents a simplified model of a Large Language Model (LLM) processing a user's query.  A rectangular box labeled 'User's initial query: What are the main cha...' represents the user's input, which is a truncated question about the main characteristics of something (likely a diet, based on the output). This 'Full prompt' is fed into a central, light-green rectangular box labeled 'LLM,' representing the core LLM processing unit. The LLM then outputs two responses, each in a separate rectangular box.  One box, connected to the LLM by a line labeled 'High relevance,' contains a response beginning 'A healthy diet should include a variet...', suggesting a high-relevance answer to the user's query. The other box, connected by a line labeled 'Low relevance,' displays a response starting 'A healthy diet is very important for o...', indicating a lower-relevance answer.  The diagram illustrates how an LLM processes an initial query and generates responses with varying degrees of relevance to the input.
Figure 25: Example of answer relevance

Answer correctness

Answer correctness focuses on how closely the generated answer matches the correct reference answer. It measures the similarity between the two using popular metrics including BLUE, ROGUE, and METEOR. To review these metrics, refer to Chapter 3.

Image represents a simplified model of a Large Language Model (LLM) processing a user's query.  A rectangular box labeled 'Full prompt' contains the user's initial query, 'User's initial query: When and where was th...', indicating an incomplete question. This 'Full prompt' box sends this input as an arrow to a central, light-green rectangular box labeled 'LLM,' representing the core LLM processing unit.  The LLM then outputs two separate responses, each in a rectangular box.  One box, connected to the LLM by an arrow labeled 'High correctn...', displays the response 'The Eiffel Tower was completed in 1889...', suggesting a high-confidence, accurate answer. The other box, connected by an arrow labeled 'Low...', displays an identical response 'The Eiffel Tower was completed in 1889...', implying a lower confidence level in this particular output despite the identical factual content.  The diagram illustrates how an LLM processes an input and produces outputs with varying confidence levels, even if the outputs themselves are factually the same.
Figure 26: Example of answer correctness

Overall ML System Design

A RAG system consists of several components that work together to retrieve and generate responses efficiently. In this section, we will explore the following key components:

  • Indexing process
  • Safety filtering
  • Query expansion
  • Retrieval
  • Generation
Image represents a system architecture diagram for a generative AI system.  The diagram is divided into two main sections: an 'Indexing process' and a 'Generation' process. The indexing process begins with 'Document databases' containing both text and image data.  These documents are processed, separating text and image components.  The text components are indexed into an 'Index...' database, and the image components are indexed into an 'Index (ima...)' database.  The generation process starts with a 'User query' that first passes through a 'Safety...' filter.  The filtered query is then processed to create a 'Query...' which is used to retrieve relevant information from the previously created indices via a 'Nearest Neighbor...' search.  The retrieved 'Text...' is combined to form a 'Prompt...', which is fed into an 'LLM' (Large Language Model). The LLM's output then undergoes another 'Safety...' check before producing the final 'Response'.  The entire generation process is enclosed within a 'Generation' box, highlighting the core functionality of the system.  The flow of information is clearly depicted through arrows connecting each component, showing the sequential processing steps.
Figure 27: RAG system overall design

Indexing process

The indexing process is responsible for converting the knowledge base into embeddings, which are then stored in an index table for efficient retrieval. This begins with document parsing and chunking, where the text and images in PDFs are broken down into meaningful data chunks. These data chunks are then converted into embeddings using a CLIP text and image encoder, ensuring that both text and image embeddings are mapped into a shared embedding space. Once the data chunks are embedded, they are stored in the index table, thus allowing for fast retrieval.

Safety filtering

The safety filtering component ensures that user requests are safe and comply with the system's guidelines. This involves checking queries for inappropriate or harmful content before processing them further. To learn more about safety filtering and evaluation, refer to Chapter 4.

Query expansion

Query expansion enhances the quality of the retrieval process by expanding the user's query to have a better flow and be free of typos and grammatical errors. By broadening the scope of the search, query expansion helps the system identify additional relevant data that might not have been explicitly mentioned in the original query, thereby increasing the chances of retrieving more relevant results.

To learn more about query expansion and its technical details, refer to [37].

Retrieval

The retrieval component is responsible for finding the data chunks that are most relevant to the user's query. The user query is first converted into an embedding using the CLIP text encoder, and then an ANN algorithm is used to efficiently retrieve the most similar data chunks in the index table.

Generation

Once the relevant data chunks are retrieved, the generation component produces the final output. This involves two main steps:

  • Prompt Engineering: The user query and retrieved context are combined into a prompt and then optimized using techniques such as CoT to structure the model’s reasoning process.
  • LLM: The LLM generates the final response using top-p sampling.

Other Talking Points

If time permits at the end of the interview, consider discussing these additional topics:

  • Tabular detection in document parsing [38] [39] [40].
  • Details of approximate nearest neighbor algorithms [20] [21] [23] [24].
  • Support user-uploaded documents [2].
  • Dynamic retrieval strategy [41] [42].
  • Query rewriting and expansion [43] [37].
  • Inference time CoT and test-time scaling [30] [31].

Summary

Image represents a mind map outlining the key considerations in designing a generative AI system.  The central node is labeled 'Summary,' branching into two main categories: 'Model development' and 'Evaluation.'  'Model development' further branches into 'Architecture,' 'Training,' and 'Sampling.'  'Architecture' details indexing methods (keyword-based, full-text search, knowledge graph-based, vector-based), retrieval techniques (ANN, LSH, tree-based, clustering-based, graph-based), and generation methods (LLM, text encoder, image encoder, prompt engineering techniques, Chain-of-Thought (CoT), few-shot learning, role-specific prompting, and user context). 'Training' includes the mention of 'Hall.' 'Sampling' is a leaf node. 'Evaluation' branches into 'Content relevance,' 'Faithfulness,' and 'Answer correctness.'  A separate branch from 'Summary' labeled 'Data preparation' details 'Clarifying requirements,' 'Specifying input and output,' 'Framing as ML,' 'Finetuning,' 'ML approach,' 'Prompt engineering,' 'RAG,' 'Rule-based,' 'Document parsing,' 'AI-based,' 'Length-based,' 'Document chunking,' 'Regex-based,' and 'Splitters.'  Finally, a branch labeled 'Overall system components' includes 'Indexing process,' 'Safety filtering,' 'Query expansion,' 'Retrieval,' and 'Generation.'  Another branch labeled 'Other talking points' is also present.  The entire mind map uses color-coded branches to visually group related concepts.

Reference Material

[1] Perplexity. https://www.perplexity.ai/. [2] ChatPDF. https://www.chatpdf.com/. [3] LoRA: Low-Rank Adaptation of Large Language Models. https://arxiv.org/abs/2106.09685. [4] Optical character recognition. https://en.wikipedia.org/wiki/Optical_character_recognition. [5] Dedoc GitHub Repository. https://github.com/ispras/dedoc. [6] LayoutParser: A Unified Toolkit for Deep Learning Based Document Image Analysis. https://arxiv.org/abs/2103.15348. [7] Google Cloud document parser API. https://cloud.google.com/document-ai/docs/layout-parse-chunk. [8] PDF.CO document parser API. https://developer.pdf.co/api/document-parser/index.html. [9] Character text splitter in LangChain. https://python.langchain.com/v0.1/docs/modules/data_connection/document_transformers/character_text_splitter/. [10] Elasticsearch. https://www.elastic.co/elasticsearch. [11] A Survey on Knowledge Graphs: Representation, Acquisition, and Applications. https://ieeexplore.ieee.org/document/9416312. [12] Manning, Christopher D. "Introduction to information retrieval." (2008). [https://nlp.stanford.edu/IR-book/information-retrieval-book.html] (https://nlp.stanford.edu/IR-book/information-retrieval-book.html) [13] Modern information retrieval: A brief overview. http://singhal.info/ieee2001.pdf. [14] Learning Transferable Visual Models From Natural Language Supervision. https://arxiv.org/abs/2103.00020. [15] OpenAI finetuning documentation. https://platform.openai.com/docs/guides/fine-tuning. [16] Anthropic finetuning. https://www.anthropic.com/news/fine-tune-claude-3-haiku. [17] RAFT: Adapting Language Model to Domain Specific RAG. https://arxiv.org/abs/2403.10131. [18] Euclidean distance. https://en.wikipedia.org/wiki/Euclidean_distance. [19] Cosine similarity. https://en.wikipedia.org/wiki/Cosine_similarity. [20] Multidimensional binary search trees used for associative searching. https://dl.acm.org/doi/10.1145/361002.361007. [21] R-trees: A dynamic index structure for spatial searching. https://dl.acm.org/doi/10.1145/971697.602266. [22] Annoy library. https://github.com/spotify/annoy. [23] Similarity search in high dimensions via hashing. https://www.cs.princeton.edu/courses/archive/spring13/cos598C/Gionis.pdf. [24] Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs. https://arxiv.org/abs/1603.09320. [25] Faiss Documentation. https://faiss.ai/. [26] ScaNN. https://research.google/blog/announcing-scann-efficient-vector-similarity-search/. [27] Developer Playground. https://docs.cohere.com/v2/docs/playground-overview. [28] Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. https://arxiv.org/abs/2201.11903. [29] Tree of Thoughts: Deliberate Problem Solving with Large Language Models. https://arxiv.org/abs/2305.10601. [30] OpenAI o1. https://openai.com/index/learning-to-reason-with-llms/. [31] Scaling LLM Test-Time Compute Optimally can be More Effective than Scaling Model Parameters. https://arxiv.org/abs/2408.03314. [32] Language Models are Few-Shot Learners. https://arxiv.org/abs/2005.14165. [33] Machine Learning System Design Interview. https://www.aliaminian.com/books. [34] Evaluation measure for information retrieval. https://en.wikipedia.org/wiki/Evaluationmeasures(information_retrieval). [35] Ragas. https://docs.ragas.io/en/stable/. [36] ARES: An Automated Evaluation Framework for Retrieval-Augmented Generation Systems. https://arxiv.org/abs/2311.09476. [37] Query2doc: Query Expansion with Large Language Models. https://arxiv.org/abs/2303.07678. [38] TableNet: Deep Learning model for end-to-end Table detection and Tabular data extraction from Scanned Document Images. https://arxiv.org/abs/2001.01469. [39] CascadeTabNet: An approach for end to end table detection and structure recognition from image-based documents. https://arxiv.org/abs/2004.12629. [40] Deepdesrt: Deep learning for detection and structure recognition of tables in document images. https://ieeexplore.ieee.org/document/8270123. [41] Active Retrieval Augmented Generation. https://arxiv.org/abs/2305.06983. [42] Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection. https://arxiv.org/abs/2310.11511. [43] ​​Precise Zero-Shot Dense Retrieval without Relevance Labels. https://arxiv.org/abs/2212.10496.

Footnotes

  • Accurate at the time of writing. ↩
  • Specifics are unknown to the public at the time of writing. ↩
Chapter 7

Realistic Face Generation

~31 min read

Introduction

One of the primary applications of generative AI is to generate realistic images of faces. This can be useful in entertainment, marketing, and virtual reality. In this chapter, we explore the technologies behind face generation.

Image represents a horizontal arrangement of four headshots, each depicting a different individual.  The images are presented side-by-side, with no visible connections or information flow between them.  From left to right, the first headshot shows a dark-haired man with a serious expression, wearing a dark-colored shirt. The second shows a woman with shoulder-length brown hair, wearing glasses, and smiling. The third shows a young woman with long dark hair, wearing a red shirt, and exhibiting a neutral expression. The fourth headshot depicts a man with graying hair and a goatee, wearing a dark suit and light blue shirt, with a slightly smiling expression.  There are no labels, text, URLs, or parameters associated with any of the images or their arrangement.  The images appear to be simply a collection of individual portraits.
Figure 1: Realistic faces generated by StyleGAN2 [1]

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: What is the primary application of the face generation system? Interviewer: The initial focus is on entertainment and content creation, but we would also consider using it for data collection in the future.

Candidate: Is the focus only on faces? Or does the entire body need to be generated? Interviewer: Let’s focus on faces only.

Candidate: Should the generated faces represent a diverse range of ethnicities, ages, and genders? Interviewer: Yes. This is crucial to ensure inclusivity and avoid biases.

Candidate: Should the system allow control over facial attributes? For example, editing the facial expression of a generated image while preserving its identity? Interviewer: Good question. Let’s start without attribute control. If we have time, we can optionally discuss attribute control.

Candidate: How will we source the training data? What is the size of the training data? Interviewer: We use publicly available datasets with proper licenses to ensure all data is in compliance with privacy regulations. There are 70,000 images of diverse faces in the dataset.

Candidate: What is the desired image resolution? Interviewer: Let’s aim for 1024x1024.

Candidate: What is the expected speed to generate a face? Interviewer: The system should generate faces in near real-time – less than a second.

Frame the Problem as an ML Task

Specifying the system’s input and output

In a face generation system, users usually don't provide specific inputs; they simply request the generation of a new face. Since machine learning (ML) models need numerical inputs to start, most image generation models begin with a random noise vector. This noise serves as the initial input, which the model then transforms into a realistic image. If the system supports attribute control, users can also provide desired attributes as input to guide the generation.

The output, which is generated in response to the random noise input, is a realistic image of a human face. This output should also reflect the desired attributes (if specified), such as age, gender, and hairstyle.

Image represents a simplified data flow diagram illustrating a generative model, possibly for image generation.  A user request (indicated by 'User requesti...') enters the system from the left and flows into a larger, light orange rectangle. Inside this rectangle, a smaller, light purple oval labeled 'Random Noise...' represents the initial random input to the model.  The orange rectangle also contains the text 'Face...', suggesting the model is generating a face image.  A black arrow connects the 'Random Noise...' oval to the 'Face...' text, indicating the processing of the random noise.  Finally, a black arrow extends from the right side of the orange rectangle to a plain white square, representing the output of the model—likely the generated face image.  The overall flow shows a user request initiating the generation process, using random noise as input, within a larger processing block, ultimately resulting in an output image.
Figure 2: Input and output of a face generation system

Choosing a suitable ML approach

In this section, we explore common ML approaches for image generation. We discuss the strengths and limitations of each approach and select the best fit for our use case.

While there are different approaches for generating images, we focus on those that are most widely used in the industry. There are four main approaches to image generation:

  • Variational autoencoder
  • Generative adversarial network
  • Autoregressive model
  • Diffusion model

Variational autoencoder

A variational autoencoder (VAE) is a generative model architecture designed to learn the distribution of data. This enables the VAE to generate new data points by sampling from this learned distribution.

A VAE consists of two main components:

  • Encoder
  • Decoder

Encoder: The encoder is a neural network that maps an input image into a lower-dimensional space, known as the latent space. The output of the encoder is a latent vector, an encoded representation of the input image.

Decoder: The decoder is another neural network that maps the encoded representation into an image. The output of the decoder is an image of the same size as the original input image.

During training, the VAE encodes the input into a latent space and then reconstructs the original input from this encoded representation. After training, the VAE can generate new images by sampling points from the learned multivariate Gaussian distribution and using the decoder to map these points into image form.

Through a reparameterization trick (see [2] for more details), VAEs model the latent vector as being sampled from a multivariate Gaussian distribution. The modeling of latent space helps the VAE learn meaningful representations that can be smoothly interpolated, which is advantageous for tasks such as image morphing and creating variations of input data.

Image represents a diagram illustrating the training and inference phases of a Variational Autoencoder (VAE).  The top section, labeled 'VAE training,' shows an input 'Image' (light blue rectangle) feeding into an 'Encoder' (orange rectangle). The encoder's output, a latent vector representation, is then passed to a 'Decoder' (light green rectangle), which reconstructs the image (light blue rectangle labeled 'Reconstru...'). The bottom section, 'VAE inference,' depicts the inference process. Here, the encoder is crossed out, indicating it's not used. Instead, a 'Random vector...' (text below a vertical rectangle representing the latent space) sampled from a 'multivariate Gaussian' (text at the bottom left) is fed directly into the 'Decoder' (light green rectangle).  The decoder then generates a new 'Generated...' image (light red rectangle).  The dashed lines delineate the two distinct phases, highlighting the difference between using an input image for training and using a random vector for generating new images during inference.
Figure 3: VAE training and inference process

VAEs have several strengths and weaknesses.

Pros:
  • Simple architecture: The encoder and decoder are neural network architectures that are simple to implement.
  • Fast generation: Compared to other approaches, VAEs offer fast image generation. The process involves sampling a random noise from the latent space and decoding it into an image using the decoder.
  • Stable training: Training a VAE is typically easy and stable.
  • Compression capability: Apart from image generation, VAEs are a powerful tool for compressing images into lower-dimensional representations.
Cons:
  • Less realistic images: VAEs struggle to capture high-frequency details. This leads to images that are less realistic compared to those generated by some other approaches.
  • Blurriness: A significant limitation of VAEs is their tendency to produce blurry images that lack sharp details.
  • Limited novelty: VAEs typically struggle to generate images that significantly differ from their training data. This limits their ability to produce novel outputs.
  • Limited control in generation: VAEs are not designed to support extra control inputs such as text descriptions or attribute controls for the desired image.

In summary, VAEs are not the best choice for generating high-quality, detailed images. Their strength, however, lies in efficiently encoding images into compact representations. In Chapter 11, we will explore VAEs and leverage their compression capabilities to build an efficient video generation system.

Generative adversarial network

A generative adversarial network (GAN) [3] consists of two networks:

  • Generator: A neural network that converts a random noise into an image.
  • Discriminator: Another neural network that determines whether a given image is real or artificially generated.

During training, these two networks engage in a continuous game: the generator learns to make more realistic images, while the discriminator becomes better at distinguishing real from generated ones. If a generated image is correctly classified as “generated,” the generator will receive a penalty for not generating a realistic image. This adversarial process continues until the generator generates images that the discriminator can no longer differentiate from real ones.

Image represents a diagram illustrating the training and inference phases of a Generative Adversarial Network (GAN).  The top section, labeled 'GAN training,' shows a data flow:  random vectors ('Random ve...') are fed into a 'Generator' (green box), which produces a 'Generated...' image (light red box). This generated image and a 'Real image' (light blue box) are both fed into a 'Discriminator' (orange box), which outputs classifications 'Fake' and 'Real,' respectively.  The discriminator's output is used to train both the generator and the discriminator. The bottom section, labeled 'GAN inference,' shows only the generator (green box) and the process of generating an image ('Generated...') from random vectors ('Random ve...'). The discriminator (grey box with an 'X' through it) is absent, indicating that during inference, only the generator is used to produce new images; the discriminator is not involved in the generation process.  Arrows indicate the direction of data flow between components.
Figure 4: GAN training and inference process
Pros:
  • High-quality generation: GANs are known for their ability to generate high-quality images.
  • Fast generation: While GANs are generally slower than VAEs, the generator can still generate an image in a single forward pass.
  • Attribute control: GAN architecture can be modified to control specific attributes such as age or expression. For example, a user can request a face image that is happy and old.
Cons:
  • Training instability: GANs are challenging to train. Common training issues are mode collapse [4], where the generator creates a limited variety of outputs, and non-convergence [5], where the GAN model fails to stabilize during training.
  • Limited control: While GANs allow for attribute control, it is challenging to go beyond that, for example, using a text description to generate an image [6].
  • Limited novelty: While GANs are good at generating variations of images in a certain domain, they typically struggle to generate novel images that are much different from their training data.

In summary, GANs are challenging to train, and they offer limited control over generated images. However, they can generate detailed images, and they support control over facial attributes, which makes them suitable for applications such as face generation and image editing.

Autoregressive model

In autoregressive modeling, image generation is formulated as a sequence generation task, where each part of an image is generated sequentially. This sequential generation enables the use of the Transformer architecture, allowing us to benefit from its powerful ability to capture long-range dependencies.

Image represents a diagram illustrating the training and inference processes of an autoregressive model, likely for image generation.  The left side depicts autoregressive training.  A 'Real image' (represented by a light blue square) is first 'Convert to sequence' (indicated by an arrow), resulting in a sequence of numbers (1 2 3 4 5 6 7 8 9) representing the image's features. This sequence is fed into a 'Transformer' (a large, light orange rectangle), which processes it and outputs a shifted sequence (2 3 4 5 6 7 8 9 .), where '.' likely represents an end token. The right side shows autoregressive inference.  The process begins with a 'random seed...' (indicated by a dashed arrow), which is fed into the 'Transformer' (another large, light orange rectangle). The Transformer outputs a sequence of image features (represented by smaller light blue squares), which are then 'Convert back to image' (indicated by arrows), resulting in a 'Generated...' image (a light pink square).  The inference process continues until an 'end token' is generated, signaling the completion of the image.  Both training and inference utilize a Transformer as the core processing unit, highlighting the model's autoregressive nature where the output of one step becomes the input for the next.
Figure 5: Autoregressive model training and inference process
Pros:
  • High detail and realism: Autoregressive models generate images with high levels of detail and sharpness.
  • Stable training: Compared to GANs, training autoregressive models is usually more stable.
  • Control over generation: It is possible to control image generation using additional inputs, such as a text prompt describing the desired image content. This flexibility comes from the Transformer architecture, which can support any number of inputs as part of the input sequence.
  • Support of multimodal conditioning: Autoregressive models easily support conditioning on different modalities. For example, if we provide a celebration audio as input, the generated image will match the audio. This flexibility is due to the Transformer architecture, which can support different modalities as input as long as they are provided as a sequence of numerical vectors.
  • Novelty: Autoregressive models are capable of generating novel and complex images. For example, they can generate an image of “an avocado on a chair on Mars” even if they haven't seen such examples in their training data.
Cons:
  • Slow generation: Autoregressive models generate the image sequentially, one token at a time. This sequential generation makes them slower compared to VAEs or GANs.
  • Resource-intensive: These models are usually very large, with billions of parameters. Training such large models requires significant computational resources, which increases the cost.
  • Limited image manipulation: Unlike VAEs and GANs, autoregressive models don’t have a structured latent space that can be easily explored or manipulated. This limits certain types of image manipulations such as attribute control in faces.

In summary, while autoregressive models are slow in generation due to their sequential nature, they can generate highly detailed and novel images. Many popular image generation models, such as OpenAI’s DALL-E [7] and Google’s Muse [8], are based on autoregressive modeling. Chapter 8 will examine this approach in more detail.

Diffusion model

Diffusion models are another popular approach for image generation, which has shown remarkable capabilities. Diffusion models formulate image generation as an iterative process. During training, noise is gradually added to images, and a neural network is trained to predict this noise. When generating images during inference, the process begins with random noise. The trained neural network is then used to iteratively denoise the image, transforming the noise into a meaningful image. This transformation occurs over a fixed number of steps, with the model adding details to the image at each step.

Image represents a diagram illustrating the training and inference phases of a diffusion model, likely for image generation.  The top section, labeled 'Diffusion training,' shows the process of adding noise to an original image iteratively until it becomes pure noise.  This is depicted by a sequence of images transitioning from a clear headshot to increasingly noisy versions, with arrows indicating the flow.  The label 'Adding noise' and ellipses (...) represent the iterative nature of the noise addition. The bottom section, 'Diffusion inference,' reverses this process.  It starts with an initial noisy image (labeled 'Initial...') and uses multiple 'Diffusion...' blocks (representing iterations of the diffusion model) to iteratively remove noise, progressively reconstructing a clearer image. The middle section, labeled 'Iteratively removing no...', shows the training process of reconstructing the original image from the noisy version using multiple 'Diffusion...' blocks, demonstrating the model learning to reverse the noise addition.  The final output in the inference phase is a generated image, different from the original image in the training phase, suggesting the model's ability to generate new images based on the learned noise removal process.  The arrows consistently indicate the direction of information flow (noise addition or removal) between the images and the diffusion model blocks.
Figure 6: Diffusion model training and inference process
Pros:
  • High detail and realism: Diffusion models can generate images of exceptional quality and realism.
  • Stable training: Compared to GANs, training diffusion models are typically stable.
  • Control over generation: Similar to autoregressive models, diffusion models can be controlled using various inputs, such as text describing the desired image.
  • Novelty and creativity: Diffusion models can generate novel and imaginative images.
  • Robustness to noisy images: Diffusion models are effective at removing noise from images because of their denoising process. This can be useful in certain applications such as image denoising.
Cons:
  • Slow generation: Diffusion models generate images in multiple denoising steps. This iterative process makes them slower compared to other methods.
  • Resource-intensive: Diffusion models are usually large, with billions of parameters. This makes them computationally intensive and, therefore, expensive to train.
  • Limited image manipulation: Unlike VAEs and GANs, diffusion models don’t have a structured latent space for manipulating images.

In summary, while diffusion models are slow, they have shown impressive performance in generating highly detailed, diverse, and imaginative images. Most state-of-the-art image generation models, such as DALL·E 3 [9], are based on diffusion models. Chapter 9 will examine diffusion models in great detail.

CharacteristicsVAEGANAutoregressiveDiffusion
QualityLowModerateHighExceptional
SpeedFastFastSlowSlow
Training stabilityStableUnstableStableStable
Control over generationLimitedLimitedFlexibleModerate
Facial manipulationNoYesNoNo
NoveltyLimitedLimitedHighHigh
Resource intensityModerateModerateHighHigh

Table 1: A comparison of different image generation approaches

For realistic face generation, we select GANs as our primary approach. GANs are particularly effective because they let us manipulate facial attributes through a structured latent space, which is an optional requirement in this chapter.

Image represents a simple diagram illustrating the effect of different hair styles on a person's appearance.  The diagram features a central node with two branches.  On the left, a photograph shows a young man with medium-length, slightly tousled brown hair. From this central image, two horizontal lines extend to the right. The top line is labeled 'Bald hair' and points to a photograph of the same man, but with his head shaved, showing a bald scalp. The bottom line is labeled 'Slicked-back...' and points to a photograph of the same man again, this time with his hair neatly combed back and styled. The arrangement clearly shows the transformation of the individual's appearance based on the alteration of his hairstyle, with the original image serving as the base for comparison.
Figure 7: Facial attribute manipulation. Images are taken from [10].

Data Preparation

Developing a realistic face generation system requires a large collection of images. Here, we have 70,000 diverse images of human faces. To prepare these images for training, we apply the following steps:

  • Remove low-quality or low-resolution images: We remove low-resolution images and use ML models to filter low-quality, blurry ones. This ensures the model learns only from high-quality images.
  • Augment images: We apply data augmentation techniques such as flipping, rotation, or color adjustment to artificially increase the size of the training data. This helps the model see more variations of the image during training and, thus, generalize better afterward.
  • Normalize and resize images: We resize all images to a standard dimension, for example, 1024x1024. We also normalize images to a standard range, typically between -1 and 1.
  • Enhance diversity: We use ML classifiers to tag images with gender, age, and other attributes. Then, we adjust the dataset to ensure a balanced representation of different groups. This step is crucial to prevent biases in generated faces.

Model Development

Architecture

GANs consist of two components: a generator and a discriminator. Let’s briefly examine the architecture of each component.

Generator

The generator component takes random noise as input and converts it into an image. Its architecture consists of a series of upsampling blocks, each of which increases the spatial dimensions (height and width) of its input. These blocks gradually transform the low-dimensional noise vector into a 2D image of the desired size.

Image represents a generative model architecture, likely for image generation.  The process begins with a 'Noise vector' of size 100, represented as a vertical stack of 100 units. This vector is then reshaped into a 1x1x100 tensor. This tensor is fed into a series of five 'Upsampling B...' blocks. Each upsampling block increases the spatial dimensions of the input tensor while reducing the number of channels.  The first block receives the 1x1x100 tensor and outputs a 4x4x1024 tensor.  Subsequent blocks progressively increase the dimensions to 8x8x512, 16x16x256, 32x32x128, and finally 64x64x3.  The output of the final upsampling block, a 64x64x3 tensor, represents the generated image, labeled 'Output...'.  The dimensions of each tensor are explicitly shown above each corresponding block, indicating the height, width, and channel count.  Arrows indicate the flow of information between blocks.
Figure 8: Series of upsampling blocks

Let’s talk about the three main components of the upsampling block:

  • Transposed convolution
  • Normalization layer
  • Non-linear activation
Transposed convolution

Transposed convolution, also known as deconvolution or upsampling convolution, is an operation used in neural networks to increase the spatial resolution of feature maps—essentially performing the opposite of a regular convolution. It’s widely used in applications such as image generation, semantic segmentation, and super-resolution where the goal is to reconstruct higher-resolution outputs from lower-resolution inputs.

Unlike standard convolution, which slides a filter across the input, transposed convolution starts by inserting zeroes between the pixels of the input feature map, effectively expanding it. The expanded input is then convolved with a filter, where the filter’s stride1 and padding2 are adjusted to achieve the desired output size. For example, starting with an input of 1x1x100, with 1024 filters of kernel size 1x1 and stride 1, we end up with a 4x4x1024 feature map. In the next step, with 512 filters of kernel size 3x3 and stride 1, we get an 8x8x512 feature map. These are the first two upsampling stages shown in Figure 8.

Image represents a visual depiction of a 2D convolution operation, likely within a convolutional neural network (CNN).  The image shows four sequential steps. In each step, a smaller, teal-colored matrix (the kernel or filter) is overlaid on a larger, underlying matrix (the input feature map). The kernel is shown in various positions, sliding across the input feature map.  The kernel's elements are implicitly multiplied with the corresponding elements of the input feature map underneath. The result of this element-wise multiplication and summation (not explicitly shown) is a single value that contributes to the output feature map. The output feature map is represented by a smaller matrix below the input, with shaded squares indicating the areas being calculated in each step. The input feature map is represented by a larger grid with dashed lines, showing the full extent of the input. The darker shaded squares in the output matrix represent the accumulated results of the convolution operation as the kernel moves across the input. The process demonstrates how the kernel convolves across the input, producing a smaller output feature map that captures spatial features from the input.
Figure 9: Transpose conv with 3x3 filter and *stride=1* over 4x4 inputs [11]

In PyTorch, this layer is usually implemented with “ConvTranspose2d.” To learn more about convolutions and transposed convolutions, refer to [11].

Normalization layer

A normalization layer improves the training stability by scaling the input data to have a consistent distribution.

Training GANs is unstable because it involves two networks (the generator and the discriminator) competing against each other. This can lead to problems like mode collapse, where the generator produces limited diversity, or oscillations, where the generator and discriminator fail to converge during training. Normalization helps stabilize the training by scaling the activations at each layer, thus reducing the risk of vanishing or exploding gradients. This helps maintain consistent distributions of activations, which is critical for balanced competition between the generator and discriminator. With a more robust optimization process, we can use a higher learning rate, speed up training, and reduce the time needed for convergence. We will discuss the training challenges and mitigations later in this chapter.

There are several normalization layers, each with its own way of normalizing data:

  • Batch normalization
  • Layer normalization
  • Instance normalization
  • Group normalization
Batch Normalization (BN)

BN [12] normalizes the inputs of a layer across the batch dimension by calculating the mean and variance for each feature. The normalized data is then scaled and shifted using learnable parameters.

  • Benefits: BN helps stabilize the learning process and allows for higher learning rates, speeding up training. It also acts as a regularizer, reducing chances of overfitting.
  • Usage: Commonly used in deep networks, including Convolutional Neural Networks (CNNs) and GAN generators.
Layer Normalization (LN)

LN [13] normalizes the inputs across the features of each individual sample rather than across the batch dimension. It, therefore, computes the mean and variance for each feature across the entire feature vector of each sample.

  • Benefits: LN is effective in settings where batch sizes are small or variable, such as in Recurrent Neural Networks (RNNs) and Transformers.
  • Usage: Frequently used in sequence models and scenarios where consistent behavior across samples is crucial.
Instance Normalization (IN)

IN [14] operates by normalizing across each feature map individually for each sample.

  • Benefits: IN is beneficial for tasks where the appearance of individual samples varies widely, as it allows the network to focus on content rather than style.
  • Usage: Commonly used in style transfer and image generation tasks.
Group Normalization (GN)

GN [15] normalizes inputs by dividing features into groups and normalizing within each group. It offers a balance between BN and LN.

  • Benefits: GN is useful for cases with very small batch sizes where BN might not be effective.
  • Usage: Often applied in tasks where BN fails due to small batch sizes or when layer behavior consistency is needed across groups of features.
Image represents a comparison of four different normalization techniques (Batch Norm, Layer Norm, Instance Norm, and Group Norm) used in neural networks, visualized as 3D tensors. Each technique is depicted using a cube representing a feature map with dimensions H (height), W (width), and C (channels), where N represents the batch size.  The cubes are consistently oriented with H and W along the vertical and horizontal axes respectively, and C along the depth.  A dark blue section within each cube illustrates the portion of the tensor over which normalization is performed. In Batch Norm, normalization is across the entire batch (N) for each channel (C) at each spatial location (H, W). Layer Norm normalizes across the H, W dimensions for each channel and each sample in the batch. Instance Norm normalizes across H and W for each channel within a single sample. Finally, Group Norm divides the channels into groups and normalizes across H, W within each group for each sample.  The light gray portion of each cube represents the remaining data not included in the normalization calculation for that specific method.
Figure 10: Comparison of different normalization methods [15]
Non-linear activation

Non-linear activation functions, such as ReLU [16], introduce non-linearity into the model, allowing it to learn complex patterns and representations. Without non-linearity, the network would essentially be a linear transformation, regardless of the depth, making it incapable of modeling intricate data distributions such as images, speech, or complex functions.

As shown in Figure 11, our generator consists of upsampling blocks (ConvTranspose2D), each followed by a normalization layer (BatchNorm2D) and a non-linear activation (ReLU). The final block uses "Tanh" [17] instead of "ReLU". This choice ensures the final outputs range between -1 and 1, matching the range of our image pixels after data preparation.

Image represents a generative model architecture, likely a type of Generative Adversarial Network (GAN) or similar, depicted as a sequence of processing blocks.  The input is a 'Noise vector,' represented as a small stack of rectangles, which feeds into a series of three identical upsampling blocks. Each upsampling block consists of a 'ConvTranspose2d' layer (for upsampling), followed by a 'BatchNorm2D' layer (for normalization), and finally a 'ReLU' activation function.  These blocks are arranged sequentially, with the output of one block feeding into the input of the next.  An ellipsis ('...') indicates the potential for more identical upsampling blocks. The final block differs slightly, replacing the ReLU activation with a 'Tanh' activation function. The output of this final block is a 3x64x64 tensor, visualized as a three-dimensional rectangular prism with dimensions labeled.  The arrows indicate the flow of data through the network, from the noise vector to the final output tensor.  The text 'Upsampling...' below each block highlights the upsampling operation performed within each block.
Figure 11: Generator architecture

Discriminator

The discriminator's job is to differentiate between real and generated images. It functions as a binary classifier, taking an image as input and outputting the probability that the image is real.

The discriminator comprises a series of downsampling blocks followed by a classification head. The downsampling blocks progressively reduce the spatial dimensions of the input image while extracting its features. The classification head then processes the extracted features to predict the probability that the input image is real.

Image represents a convolutional neural network (CNN) architecture for image classification.  The process begins with an input 'Image' represented as a 3D tensor of dimensions 64x64x3 (height x width x channels). This image then passes through a series of four 'Downsampling...' blocks, each reducing the spatial dimensions of the tensor while increasing the number of channels.  The first downsampling block outputs a 32x32x128 tensor, the second a 16x16x256 tensor, the third an 8x8x512 tensor, and the fourth a 4x4x1024 tensor.  These downsampling operations likely involve convolutional layers and pooling layers to extract features from the image at different scales.  The output of the final downsampling block (4x4x1024) is then fed into a 'Classific...' block, which is likely a fully connected layer or a series of fully connected layers responsible for classifying the image into different categories. Finally, the 'Classific...' block outputs a 'Probability' value, representing the likelihood of the image belonging to a specific class.  Arrows indicate the flow of data between the different components.
Figure 12: Series of downsampling blocks

A downsampling block consists of several convolution operations to progressively decrease the input's spatial dimension. In PyTorch, we typically use a "Conv2D" layer with a stride of 2 to halve the spatial dimensions. Like the generator, batch normalization (BatchNorm2D) and non-linear activation function (ReLU) are used in between convolution layers to enhance training stability and performance.

The classification head includes one or two fully connected layers followed by a sigmoid activation function. The sigmoid function ensures the final output ranges between 0 and 1, which is crucial for interpreting the output as a probability.

Image represents a convolutional neural network (CNN) architecture for image classification.  The input is a 64x64x3 image, depicted as a 3D cube with dimensions labeled. This image is fed into a series of two identical downsampling blocks (shown in pink), each consisting of a Conv2D layer, a BatchNorm2D layer, and a ReLU activation function.  Arrows indicate the flow of data between layers.  The output of the downsampling blocks is then passed to a classification block (shown in lavender) containing a Fully Connected layer followed by a Sigmoid activation function.  The ellipsis (...) between the downsampling blocks suggests the potential for repetition of this downsampling pattern. Finally, the output of the Sigmoid layer is a probability, represented by a small square labeled 'Probabili...', indicating the network's prediction for the image's class.  The labels 'Downsamplin...' and 'Classificat...' are truncated descriptions of the respective blocks' functions.
Figure 13: Discriminator architecture

Various versions of GANs have been developed over the years to serve different purposes. For instance, StyleGAN [18] modifies the generator's architecture to control attributes of generated faces, such as age, hair color, and facial expression. For more details on the StyleGAN architecture and its key architectural choices, refer to [18].

Training

To produce realistic images, we train the GAN using a unique process called adversarial training. In adversarial training, the generator and the discriminator are trained simultaneously in a game-like scenario. The generator aims to produce images that look real, while the discriminator improves its ability to distinguish between real and generated images. During this adversarial process, the generator learns to produce increasingly more convincing images. At the same time, the discriminator gets better at identifying fake images. This competitive process continues until the generator produces images that the discriminator can no longer detect as fake.

When training GANs, it is important to ensure both the generator and discriminator improve together, avoiding scenarios where one dominates the other. Such a balance is empirically shown to be crucial for successful training. To maintain this balance, it is common to alternate between the following two steps:

  • Train the discriminator for a few iterations while keeping the generator frozen.
  • Train the generator for a few iterations while keeping the discriminator frozen.
Image represents a diagram illustrating the training process of a Generative Adversarial Network (GAN).  The diagram is divided into two sections, separated by a dashed line.  The upper section, labeled '1 Training the discriminat...', depicts the training of the discriminator.  A 'Noise vector' is input into a 'Frozen...' component (presumably a pre-trained generator), which outputs a sample. This sample, along with samples from a 'Real...' dataset (represented as a cylinder), is fed into the 'Discriminator'. The discriminator outputs a 'Probability' indicating whether the input is real or generated. The lower section, labeled '2 Training the generator', shows the training of the generator.  A 'Noise vector' is input into the 'Generator', which produces a sample. This sample is then fed into a 'Frozen...' discriminator (the discriminator from the first step, now with fixed weights, indicated by a lock icon), which outputs a 'Probability'.  Both sections show the flow of data from the noise vector, through the generator or frozen generator, to the discriminator or frozen discriminator, and finally to a probability output.  The 'Real...' datasets in both sections represent real-world data used for training.  The lock icons indicate that the respective components are frozen during their respective training phases.
Figure 14: Generator and discriminator alternative training

Next, let’s examine the ML objective and loss function for training a GAN model.

ML objective and loss function

The generator and discriminator have their own specific, conflicting goals. The discriminator aims to distinguish accurately between real and generated images. The generator aims to produce images that the discriminator cannot distinguish from real ones. We first explore the loss function and ML objective of each component and then combine them into a unified loss function for the GAN.

Discriminator

We employ binary cross-entropy as the loss function for the discriminator, as it is commonly used in binary classification models.

Where:

  • D(x(i))D\left(x^{(i)}\right)D(x(i)) is the discriminator's predicted probabilities for a real image,
  • G(z(j))G\left(z^{(j)}\right)G(z(j)) is the generator's output (a fake image) given random noise,
  • mmm is the number of real images,
  • nnn is the number of fake images.

The discriminator’s ML objective is to minimize the binary cross-entropy loss function.

Generator

The generator aims to produce realistic images that the discriminator cannot distinguish from real ones. Ideally, the discriminator should predict probabilities close to 1 for images that have been produced by the generator. To achieve this, the ML objective is formulated as maximizing log⁡(D(G(z(j))))\log \left(D\left(G\left(z^{(j)}\right)\right)\right)log(D(G(z(j)))) for all fake images or, equivalently, minimizing the following loss function:

GAN’s minimax loss

The minimax loss [19], originally used in the GAN paper, unifies the generator’s and discriminator’s losses into a single function:

The discriminator aims to maximize the loss, while the generator aims to minimize it. Therefore, the overall ML objective is:

Besides the minimax loss, researchers have proposed other loss functions to improve training stability in GANs. To learn more about these loss functions, refer to [20].

Common training challenges in GANs

GANs are difficult to train compared to other generative models such as autoregressive or diffusion models. Discussing these challenges is beneficial in an ML interview. In this section, we discuss three main challenges of training GANs:

  • Vanishing gradients
  • Mode collapse
  • Failure to converge
Vanishing gradients

The vanishing gradient problem [21] occurs when gradients become very small during training. This problem primarily affects the generator. When the discriminator becomes too good at distinguishing between real and fake images, it provides very small gradient values for the generator to update its parameters. This slows down or stops the generator’s learning process.

Two common techniques to mitigate the vanishing gradient problem are:

  • Modified minimax loss
  • Wasserstein loss

Modified minimax loss: The original GAN paper points out that minimizing the original ML objective can cause training to stall. To overcome this, the paper recommends altering the generator's objective to maximize

This minor adjustment is inspired by formulating the ML objective from a different perspective. With this change, the generator aims to maximize the probability of fake images being identified as real, rather than minimizing the probability of fake images being identified as fake.

Wasserstein loss: This loss function is used in a modified GAN called a "Wasserstein GAN" or "WGAN." Let’s examine the ML objective for a WGAN’s discriminator and generator.

  • WGAN’s discriminator: The discriminator for a WGAN, also known as the "critic," differs from the one in a traditional GAN. Instead of classifying images as real or fake, the critic outputs a score representing the "realness" of an image. The critic loss is defined as the difference between the critic’s outputs for real images and fake images. Hence, the critic’s ML objective is to maximize the critic loss.
  • WGAN’s generator: The ML objective for the generator of a WGAN is to maximize the probability of fake images being identified as real:
Mode collapse

Ideally, a GAN model should produce different variations of images with different random inputs. Mode collapse refers to situations where the generator produces a limited variety of images. Let’s see why this might happen.

During training, the generator might learn to trick the system by finding one image that seems most plausible to the discriminator. Once the generator finds this most plausible image, it may keep producing the same image to fool the discriminator. Hence, the generator never learns to generate other images. This type of failure in a GAN is known as “mode collapse”. Two common techniques to mitigate mode collapse are:

  • Wasserstein loss
  • Unrolled GAN [22]

To learn more about the unrolled GAN and how it mitigates the mode collapse, refer to [4].

Failure to converge

Training GANs is typically challenging and the process is often unstable. This is due to the “failure to converge” problem, a common issue in training GANs. Let’s explore why this happens.

As the generator improves during training, the discriminator's performance declines because it becomes increasingly more difficult to distinguish between real and fake images. If the generator reaches a point where it can mimic real data perfectly, the discriminator’s accuracy drops to 50 percent; it effectively begins to make random guesses, much like flipping a coin. This decline in discriminator performance hinders GAN convergence since its feedback gradually becomes less and less useful to the generator. When training continues past a certain point, the generator starts training on useless feedback, and its quality may collapse as a result.

There are various approaches to improve the training stability and convergence of GANs:

  • Normalization: Applying techniques like batch normalization helps stabilize training by ensuring consistent distributions across layers.
  • Different learning rates: Using different learning rates for the generator and discriminator can help balance their progress and avoid instability in training.
  • Regularization: Employing regularization methods like weight decay prevents overfitting and helps maintain training stability.
  • Adding noise to discriminator inputs: Injecting noise into the inputs of the discriminator can prevent it from becoming too powerful early on, which helps balance the competition between the generator and the discriminator.

To learn more about the specific details of these approaches, refer to [21] and [23].

Sampling

Sampling is the process of generating new images from a trained GAN model. Before discussing sampling methods, let's first review the concept of latent space in a GAN.

During training, the generator learns to transform various noise vectors into images. This process forms a latent space—a multidimensional space where each point represents a potential noise vector. This latent space is meaningful to the GAN because its generator can map each point to its corresponding image.

Image represents a latent space, depicted as an oval containing numerous dark gray dots, representing data points (likely encoded features of images).  Two red dots are positioned within this space, suggesting generated or manipulated data points.  Dashed arrows connect these red dots to images of faces positioned outside the oval. One arrow points from a red dot to an image of a man, and another arrow points from a second red dot to an image of a woman. The label 'Latent space' is placed above the oval, clearly identifying the area containing the data points. The arrangement visually suggests that the latent space encodes facial features, and the red dots represent generated or manipulated representations of faces in this space, with the arrows indicating the mapping between the latent space representation and the actual image.
Figure 15: Latent space points map to face images

To generate a realistic face image, we sample a point from this latent space, known as a latent vector. The generator then takes this latent vector and transforms it into an image.

There are two methods to sample a latent vector from a learned latent space:

  • Random sampling
  • Truncated sampling

Random sampling

Random sampling uses a standard Gaussian distribution to draw latent vectors from the latent space. This ensures a diverse selection of latent vectors, leading to the generation of varied images.

Truncated sampling

Truncated sampling restricts the latent vectors to a smaller, high-probability region of the latent space. By truncating the distribution, the method reduces the chance of generating outliers, resulting in higher-quality images. This approach is beneficial when the primary goal is to maintain high realism in the generated faces. If you are interested in learning about the details and implementation of truncated sampling, refer to [24].

Image represents a comparison of two sampling methods: random sampling and truncated sampling.  The image is divided into two halves by a dashed vertical line. The left half is titled 'Random sampling' and contains a single, large, light-grey circle filling most of the space. This circle visually represents the entire sample space, with all points equally likely to be selected. The right half is titled 'Truncated sampling' and shows a similar light-grey circle, but this circle contains three smaller, irregularly shaped, light-grey ellipses. These ellipses represent the selected samples, indicating that only certain regions within the sample space are considered, resulting in a non-uniform probability distribution. The text 'Text is not SVG & cannot display' is present at the bottom center, likely indicating a limitation in rendering the image.  The overall arrangement clearly contrasts the uniform distribution of random sampling with the non-uniform, truncated distribution of the second method.
Figure 16: Random vs. truncated sampling (gray regions represent sampling areas).

In summary, random sampling ensures diversity by exploring the entire latent space, while truncated sampling focuses on a high-probability region to enhance realism. For realistic face generation, we utilize random sampling as it leads to diversity and usually works well in practice.

Evaluation

Offline evaluation metrics

Evaluating image generation systems involves assessing both the quality and diversity of the generated images. Several metrics have been developed for this purpose, such as Inception score [25], Fréchet Inception distance (FID) [26], and Kernel Inception distance (KID) [27]. Among these, Inception score and FID are the most widely used. Human evaluation also continues to be an essential method of assessing generative models.

In an ML system design interview, the interviewer’s goal is to assess your intuition and practical understanding, rather than test your detailed knowledge of formulas and theories. However, having a broad understanding of some of these metrics can still be helpful. Let’s briefly examine the Inception score and FID.

Inception score

The Inception score is a widely used metric to evaluate the quality of generated images in generative models such as GANs. The metric relies on a pretrained image classification model, such as “Inception v3” [28], to assess how well the generated images resemble real-world objects.

Here's a step-by-step explanation of how the metric is calculated:

  • Generating images: We start by generating a large set of images using the model we want to evaluate.
  • Computing class probabilities: For each generated image, the Inception model provides a probability distribution over all of its 1,000 object classes. A high-quality image should lead to a distribution with a peak (i.e., a high probability for one class) indicating that the model recognizes it as a clear instance of a class.
  • Calculating the marginal distribution: Marginal distribution refers to the average of the predicted class probabilities across all images. This helps us understand the overall distribution of classes represented in the generated set. If the images are diverse, the marginal distribution will be flat and spread across many classes.
  • Computing KL divergence: The KL divergence measures how different the predicted class distribution for each image is from the marginal distribution. High-quality images will have a distribution that is very different from the marginal distribution. This is because a high-quality image is expected to have a peak in its distribution, while the marginal distribution is expected to be close to uniform if the images are diverse.
  • Calculating the Inception score: The Inception score is the exponentiated average of the KL divergence across all images. A high Inception score indicates that individual images have been confidently classified into a variety of classes, which means the generated images are both diverse and of high quality.
Image represents a generative model evaluation pipeline.  It begins with a Generative Adversarial Network (GAN) (labeled 'GAN' in a green box, numbered '1') which outputs a series of data samples (represented by several light orange boxes within a dashed box). These samples are then fed into an 'Inception' model (labeled 'Inceptio...', numbered '2'), which processes them and produces a set of histograms representing the distribution of features.  These histograms are then compared to a 'Marginal distribution' (labeled 'Marginal d...', numbered '3'), also represented by histograms, using a Kullback-Leibler (KL) divergence metric (labeled 'KL-diverg...', numbered '4'). The KL divergence calculation results in a series of scores (represented by empty boxes next to KL divergence calculations), each score corresponding to a specific feature distribution comparison.  Finally, these scores are aggregated and fed into an 'Inception' model (labeled 'Incept...', numbered '5'), likely for further analysis or model refinement. The entire process visually depicts the evaluation of GAN-generated data by comparing its feature distribution to a reference distribution using KL divergence as a scoring mechanism.
Figure 17: Inception score calculation

How does the Inception score measure both diversity and quality?

  • Diversity: The Inception score evaluates diversity by checking if the generated images result in a nearly uniform marginal distribution across classes, indicating that the images are spread evenly across different classes.
  • Quality: High-quality images result in a sharp, peaked probability distribution, indicating that the image is clearly recognized as belonging to a particular class. The Inception score compares this distribution with the marginal distribution to assess image quality.

Fréchet inception distance (FID)

FID is another popular metric for evaluating the quality of images produced by generative models. It assesses how similar the distribution of generated images is to the distribution of real images. Unlike the Inception score, which uses class probabilities, FID considers the statistics of the features extracted by a pretrained model such as Inception v3. The Inception model is chosen because it is trained on a large and diverse dataset (ImageNet) and can extract meaningful features that represent the content and style of the images.

Here's a step-by-step explanation of how FID is calculated:

  • Generating images: We start by generating a large set of images using the model we want to evaluate. These images will be compared to a set of real images to evaluate their quality and diversity.
  • Extracting features: We pass each image (both generated and real) through the Inception v3 model and extract features (“activations”) from a specific layer, usually one near the end of the network. Features from this deep layer capture high-level information—such as shapes, textures, and objects—which is crucial for assessing the realism of the images.
  • Calculating mean and covariance: We calculate the mean and covariance of the extracted features separately for generated and real images. These statistical measures summarize the distributions of features for both sets of images.
  • Computing Fréchet distance: We calculate the FID as the Fréchet distance between the mean and covariance of generated and real images. The Fréchet distance measures how close the two distributions are. A lower FID indicates greater similarity between the distributions, meaning the generated images are more realistic and diverse. To learn more about the Fréchet distance and its formula, refer to [29].
Image represents a flowchart illustrating the process of calculating the Fréchet Inception Distance (FID) score to evaluate the quality of images generated by a Generative Adversarial Network (GAN).  The process begins with a GAN (labeled 'GAN') which generates a set of 'Fake images' (represented by orange rectangles). These fake images are then fed (arrow labeled '1') into an Inception network (labeled 'Inceptio...').  Simultaneously, a set of 'Real images' (represented by green rectangles) are also fed into the same Inception network (arrow labeled '2'). The Inception network extracts features from both the fake and real images.  These features are then processed (arrows labeled '3') to calculate the mean and covariance matrices for both the fake and real image sets.  The fake image features result in 'Fake mean' (a smaller rectangle) and 'Fake covari...' (a larger rectangle), while the real image features result in 'Real mean' and 'Real covari...' (similarly sized rectangles). Finally, these mean and covariance matrices are used to compute the FID score (arrow labeled '4'), a metric that quantifies the similarity between the distributions of real and fake images.  A lower FID score indicates higher image quality.
Figure 18: FID calculation

How does the FID measure both diversity and quality?

  • Diversity: The FID considers the covariance of the features, reflecting the spread and variation in the image features. A diverse set of generated images will have a feature distribution similar to that of real images, showing the model's ability to produce a wide range of different images.
  • Quality: FID ensures the generated images are high-quality by comparing their feature distributions to those of real images. If the mean and covariance of the generated images’ features are similar to those of the real images, this indicates that the generated images are likely to be of high quality.

FID and Inception score are useful for assessing the quality and diversity of image generation models, but they don't always align with human judgment. This is mainly because these metrics rely on ImageNet classes, which can introduce artifacts. The authors of [30] suggest that using a non-ImageNet-trained model like CLIP could provide a better alignment with human evaluation.

While CLIP-based metrics show promise in improving alignment with human judgment, they still cannot fully replace the insights gained from direct human feedback. Human evaluation still remains the most reliable method for assessing the quality of generated images, as it captures nuances that automated metrics might miss.

Human evaluation

Human evaluation is crucial for assessing image generation systems since automated metrics can miss subjective qualities such as aesthetic appeal. There are different protocols to perform human evaluation. One protocol, as outlined in [31], involves presenting users with pairs of images generated by different models. The human evaluators are asked to choose which image looks more photorealistic. This approach lets us compare models based on criteria that align more closely with human judgment.

Image represents a user interface element for a comparative image quality assessment.  The main component is a rectangular box displaying the question 'Which image has higher qualit...'  Inside this box are two adjacent, peach-colored square placeholders representing generated images, each outlined in gold. Below each image placeholder is a small, empty square, possibly for user selection or feedback.  A dashed arrow points from the text 'Generated b...' on the left to the leftmost image placeholder, indicating that this image is a result of a generation process. Similarly, a dashed arrow points from the rightmost image placeholder to the text 'Generated b...' on the right, showing the origin of the second image.  The overall structure suggests a user is presented with two generated images and asked to judge which one has superior quality.
Figure 19: Pairwise comparison during human evaluation

Online evaluation metrics

Various metrics are typically monitored in practice to ensure that the image generation system performs well and meets user expectations. Two common metrics are:

  • User feedback: This metric is vital as it directly reflects users' opinions about the generated images. User feedback can be gathered through surveys, ratings, or direct comments.
  • Latency: Latency refers to the time it takes from when a request is made until the image is fully generated and delivered to the user. Fast response times are crucial for maintaining a good user experience, especially in interactive applications. Monitoring latency helps identify performance bottlenecks and ensures the system meets user expectations.

Overall ML System Design

In this section, we explore the holistic design of a realistic face generation system. The key components we'll examine are:

  • Face generator
  • Training service
  • Evaluation service
  • Deployment service
Image represents a system architecture diagram for a face generation application.  A user request ('User requ...') initiates the process, flowing into a 'Face Generator' component (green). This component interacts with a Generative Adversarial Network ('GAN') (grey cloud), which is responsible for generating the face images. The generated face then proceeds to an unspecified component (white box), likely representing an output or display mechanism.  The 'Face Generator' and 'GAN' are enclosed within a dashed box, suggesting a modular inference component. Below this, a vertically stacked series of services manages the system's lifecycle:  'Deployment Ser...' (teal) handles deployment of the model, 'Evaluation Ser...' (rose) evaluates its performance, and 'Training Servi...' (light blue) trains the GAN model using data from 'Training D...' (yellow cylinder, representing a training dataset).  Arrows indicate the flow of data and control between components, showing the training data feeding into the training service, which in turn updates the evaluation service, deployment service, and ultimately the GAN within the Face Generator.
Figure 20: Realistic face generation overall design

Face generator

The face generator is the core component responsible for generating realistic faces. It handles user requests and interacts with the trained GAN model to sample high-quality images. Users can optionally specify desired attributes such as age, gender, hairstyle, and expression. The service leverages StyleGAN properties to adjust the noise vector in the latent space based on these attributes.

The architectural details of attribute control and latent manipulation aren’t typically discussed in ML system design interviews. If you are interested in learning more in this space, read [32][33].

Training service

The training service continuously improves the GAN model by periodically retraining it with user-approved generated images and new training data.

Evaluation service

The evaluation service automatically evaluates newly trained models. It uses predefined metrics to assess their performance. The evaluation results determine whether the new model meets quality standards and should replace the existing one.

Deployment service

The deployment service deploys improved models to the production environment. It ensures a smooth transition with minimal downtime during updates. The deployment service also monitors the performance of deployed models to ensure they function as expected.

Other Talking Points

In case there's extra time after the interview, you might discuss these further topics:

  • Various GAN architectures, such as DCGAN, WGAN, and StyleGAN, and the trade-offs of each architecture [34][35][18].
  • Techniques for stabilizing GAN training to avoid mode collapse and convergence issues, including the use of Wasserstein loss, gradient penalty, and other robust training methods [36].
  • Utilize conditional GANs (cGANs) to generate faces based on specific conditions or inputs [37].
  • Evaluation metrics of condition consistency [38][39].
  • Style-mixing in face generation [18].

Summary

Image represents a mind map summarizing the key aspects of generative AI system design.  The central node is labeled 'Summary,' branching out into five main categories: Clarifying Requirements, Data Preparation, Model Development, Evaluation, and Overall System Components.  'Clarifying Requirements' further branches into 'Framing as ML' (leading to 'ML approach' with sub-branches 'VAE' and 'GAN') and 'Specifying Input and Output.' 'Data Preparation' details steps like removing low-quality images, augmentation, normalization, and diversity enhancement. 'Model Development' breaks down into 'Architecture' (describing Generator components like Transposed Conv, Normalization layers (BN, LN, IN, GN), and non-linear activation functions, and Discriminator components), and 'Training' (including adversarial training, Minimax loss function, and challenges like vanishing gradients, mode collapse, and failure to converge).  'Evaluation' is divided into 'Offline' (Inception score, FID) and 'Online' (Human evaluation, User feedback, Latency) methods. Finally, 'Overall System Components' outlines the Face generator, Training service, Evaluation service, and Deployment service.  Each branch uses color-coding for visual distinction, and the overall structure provides a hierarchical view of the design process, from initial requirements to final deployment.

Reference Material

[1] StyleGAN2. https://arxiv.org/abs/1912.04958. [2] Auto-Encoding Variational Bayes. https://arxiv.org/abs/1312.6114. [3] Generative Adversarial Networks. https://arxiv.org/abs/1406.2661. [4] Combating Mode Collapse in GAN training: An Empirical Analysis using Hessian Eigenvalues. https://arxiv.org/abs/2012.09673. [5] Google’s GAN course. https://developers.google.com/machine-learning/gan/training. [6] StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks. https://arxiv.org/abs/1612.03242. [7] Zero-Shot Text-to-Image Generation. https://arxiv.org/abs/2102.12092. [8] Muse: Text-To-Image Generation via Masked Generative Transformers. https://arxiv.org/abs/2301.00704. [9] DALL·E 3. https://openai.com/index/dall-e-3/. [10] Attribute-specific Control Units in StyleGAN for Fine-grained Image Manipulation. https://arxiv.org/abs/2111.13010. [11] A guide to convolution arithmetic for deep learning. https://arxiv.org/abs/1603.07285. [12] Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift. https://arxiv.org/abs/1502.03167. [13] Layer Normalization. https://arxiv.org/abs/1607.06450. [14] Instance Normalization: The Missing Ingredient for Fast Stylization. https://arxiv.org/abs/1607.08022. [15] Group Normalization. https://arxiv.org/abs/1803.08494. [16] Deep Learning using Rectified Linear Units (ReLU). https://arxiv.org/abs/1803.08375. [17] PyTorch’s Tanh layer. https://pytorch.org/docs/stable/generated/torch.nn.Tanh.html. [18] A Style-Based Generator Architecture for Generative Adversarial Networks. https://arxiv.org/abs/1812.04948. [19] Minimax. https://en.wikipedia.org/wiki/Minimax. [20] Loss functions in GANs. https://developers.google.com/machine-learning/gan/loss. [21] Towards Principled Methods for Training Generative Adversarial Networks. https://arxiv.org/abs/1701.04862. [22] Unrolled Generative Adversarial Networks. https://arxiv.org/abs/1611.02163. [23] Stabilizing Training of Generative Adversarial Networks through Regularization. https://arxiv.org/abs/1705.09367. [24] Megapixel Size Image Creation using Generative Adversarial Networks. https://arxiv.org/abs/1706.00082v1. [25] Inception score. https://en.wikipedia.org/wiki/Inception_score. [26] GANs Trained by a Two Time-Scale Update Rule Converge to a Local Nash Equilibrium. https://arxiv.org/abs/1706.08500. [27] Demystifying MMD GANs. https://arxiv.org/abs/1801.01401. [28] Rethinking the Inception Architecture for Computer Vision. https://arxiv.org/abs/1512.00567. [29] FID calculation. https://en.wikipedia.org/wiki/Fr%C3%A9chet_inception_distance. [30] The Role of ImageNet Classes in Fréchet Inception Distance. https://arxiv.org/abs/2203.06026. [31] Hierarchical Text-Conditional Image Generation with CLIP Latents. https://arxiv.org/abs/2204.06125. [32] Alias-Free Generative Adversarial Networks. https://arxiv.org/abs/2106.12423. [33] StyleGAN3. https://nvlabs.github.io/stylegan3/. [34] Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks. https://arxiv.org/abs/1511.06434. [35] Wasserstein GAN. https://arxiv.org/abs/1701.07875. [36] Stabilizing Generative Adversarial Networks: A Survey. https://arxiv.org/abs/1910.00927. [37] Conditional Generative Adversarial Nets. https://arxiv.org/abs/1411.1784. [38] CLIPScore: A Reference-free Evaluation Metric for Image Captioning. https://arxiv.org/abs/2104.08718. [39] DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation. https://arxiv.org/abs/2208.12242.

Footnotes

  • Stride controls how much the filter moves across the input during convolution—larger strides skip more pixels ↩
  • Padding adds extra borders around the input to control the output size during convolution ↩
Chapter 8

High-Resolution Image Synthesis

~17 min read

Introduction

Generative AI offers a fascinating ability to create highly realistic and diverse images. In this chapter, we explore a technique that enables the generation of detailed and varied images in just seconds.

Image represents a placeholder indicating that an image, likely a diagram relevant to generative AI system design interview preparation, has been removed.  The placeholder consists solely of the word 'removed' in a sans-serif font, centrally positioned. Below this, a small, separate line of text reads 'Text is not SVG - cannot display,' explaining the reason for the image's absence.  No other components, connections, information flow, labels, URLs, or parameters are visible; the image is entirely textual and provides no visual information about the original diagram's content.
Figure 1: An image generated by VQGAN [1]

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: Should the system focus on specific categories of images at the start? Interviewer: For simplicity, let's begin with natural scenes and urban landscapes. We can explore other categories later.

Candidate: Do we have training data consisting of natural scenes? What's the dataset size? Interviewer: We have a large dataset with about 5 million high-resolution images of natural scenes and landscapes.

Candidate: Should the system support additional conditioning, such as input text describing the desired image? Interviewer: Good question. We'll focus on image generation without input conditions. However, the system should be flexible to support input prompts.

Candidate: What resolution range should we aim for when generating the images? Interviewer: The system should generate images with either 1024×\times×1024 or 2048×\times×2048 pixels, based on user requests.

Candidate: Should the images be generated in real time, or is some delay acceptable? Interviewer: Real-time generation isn't necessary. However, a reasonable processing time is important. Let's aim for five seconds per image.

Frame the Problem as an ML Task

Specifying the system’s input and output

For high-resolution image synthesis, the user simply requests a new image. The output is a high-resolution image.

Image represents a simplified workflow for image generation.  A user, depicted as a person icon labeled 'User,' initiates the process by submitting a request, indicated by the arrow and the text 'Requesting...'. This request flows into a rectangular box with rounded corners, colored peach and outlined in gold, labeled 'Image Generation...'. This box represents the core image generation process.  Finally, an arrow points from the 'Image Generation...' box to an empty square labeled 'Generated...', signifying the output of the process – the generated image.  The overall flow is linear, showing a sequential progression from user request to image generation and delivery.
Figure 2: Input and output of an image generation system

Choosing a suitable ML approach

As discussed in Chapter 7, there are several approaches to image generation, including VAEs, GANs, autoregressive models, and diffusion models. In this section, we choose the one best suited for the task.

Most variants of VAEs and GANs struggle to generate high-resolution images, such as those with resolutions of 512x512 pixels and above. They face a challenge known as posterior collapse. This occurs because, as the resolution increases, these models require a decoder with a higher capacity to capture additional details. During training, the decoder can become so powerful that it starts to ignore input from the latent space, as it can model the output independently. As a result, the latent variables contribute little to the generation process, reducing the diversity of the images.

While both autoregressive and diffusion models can generate high-resolution images, they differ significantly in complexity and resource requirements. Autoregressive models are often considered slow due to their sequential nature, where each pixel depends on the ones generated before it. This dependency leads to a time complexity that increases linearly with the number of pixels, resulting in an O(N2)O(N^2)O(N2) complexity for an image of size N×NN\times NN×N, and the process is difficult to parallelize. To address this limitation, autoregressive models generate images chunk by chunk instead of pixel by pixel. For example, generating a 1024×\times×1024 image using chunks of 64×\times×64 pixels requires only 256 steps or tokens, significantly reducing the computational overhead compared to traditional pixel-based methods.

On the other hand, the complexity of diffusion models increases super-linearly with image size, resulting in a computational complexity of O(TN2)O(TN^2)O(TN2), where NNN is the number of pixels and T represents the number of denoising steps. Larger images often require more refinement steps to maintain quality and coherence, which further escalates computational demand.

In practice, generating a high-resolution image using standard diffusion models can take several minutes1. In contrast, Transformer-based autoregressive models can accomplish similar tasks in seconds due to their chunk-based generation approach. For this chapter, we focus on autoregressive models for educational purposes. In Chapter 9, we will cover diffusion models in detail. Let's now delve into autoregressive models and their key components.

Image represents a two-part system for image processing, divided into an 'Image Tokenizer' module on the top and an 'Image Generator' module below, both delineated by dashed lines. The 'Image Tokenizer' module takes an input image, depicted by an icon, and processes it through a sequence of components: first, it enters a green trapezoidal 'Encoder', then flows to a yellow rounded rectangular 'Quantizer'. Above the Quantizer is a codebook labeled 'codebook C', visually represented as a grid of dashed rectangles within a yellow/orange textured area, with elements labeled e1 through ek referenced below it and a vertical brace labeled C. The Quantizer interacts with this codebook. The output from the Quantizer goes to a red trapezoidal 'Decoder'. The Decoder outputs an image, depicted by another icon, representing the reconstructed image from the quantized representation. The 'Image Generator' module initiates with a grey rectangular input labeled 'e6 Sampled first token', which is fed into an orange rounded rectangular 'Transformer'. The Transformer generates a sequence of tokens, shown as horizontal grey rectangles labeled 'e11 ... e77 e13'. This sequence of tokens is then passed upwards via an arrow to the 'Decoder' within the 'Image Tokenizer' module. The output from the Decoder in this context is shown leading to a dashed-line box labeled 'Generated Image', depicted by an icon of a plant in a pot, illustrating the image synthesized from the generated token sequence. Black arrows throughout the diagram indicate the direction of data flow.
Figure 3: Autoregressive image generation

Autoregressive models generate images by treating them as a sequence generation task. This approach relies on two primary components:

  • Image tokenizer
  • Image generator

Image tokenizer

Image tokenization refers to representing an image with a sequence of discrete tokens. This is crucial in autoregressive models, where the image is generated sequentially, chunk by chunk.

The image tokenizer is a separate model, trained independently. Its main functions are to encode an image into a sequence of discrete tokens and decode a sequence of discrete tokens back into an image.

Image represents a diagram illustrating an image tokenizer, split into encoding and decoding processes.  The encoding section shows an input (implied, not explicitly shown) flowing into a trapezoidal 'Encoder' (light green), which outputs to a rectangular 'Quantizer' (pale yellow). The Quantizer outputs to a trapezoidal 'Decoder' (light gray), which then outputs a sequence of numerical tokens represented by boxes labeled '6,' '11,' '381,' '...,' and '72.'  These tokens are then connected to a light blue square, representing the encoded image representation.  The decoding section mirrors this, starting with the same sequence of numerical tokens ('6,' '11,' '381,' '...,' and '72') as input. These tokens are fed into a trapezoidal 'Encoder' (light gray), then a rectangular 'Quantizer' (pale yellow), and finally a trapezoidal 'Decoder' (light red), which outputs a light blue square representing the decoded image.  The connections between components show the flow of information, with the encoded image representation from the encoding section being used as input for the decoding section.  The overall structure highlights the process of converting an image into a numerical token sequence (encoding) and reconstructing the image from that sequence (decoding).
Figure 4: Image tokenizer’s encoding and decoding

Image generator

The image generator is the primary model for generating images chunk by chunk. While there are various architectures for sequence generation, the decoder-only Transformer is the most effective choice for two reasons. First, the decoder-only Transformer has a flexible architecture that can handle different modalities. In a chatbot, it takes text tokens as input and generates text tokens as output. In image captioning, it takes an image as input and outputs text tokens. For image generation, it generates a sequence of image tokens as output, which are then decoded into an image.

Second, the Transformer architecture is effective at capturing long-range dependencies through its attention mechanism, which is beneficial for generating coherent images.

Image represents a comparison of three different generative AI tasks: text completion/chatbots, image captioning, and image generation.  Each task is depicted as a vertical column.  Each column shows a similar architecture: a bottom layer representing input (text for the first two, image for the third), followed by multiple smaller boxes representing an encoder, then a larger, peach-colored box labeled 'Decoder-only...', and finally a top layer representing the output (text for the first two, image for the third).  Arrows indicate the flow of information: the input feeds into the encoder, the encoder's output feeds into the decoder, and the decoder's output becomes the final output.  In the text completion/chatbot column, both input and output are text. In the image captioning column, the input is an image, and the output is text. In the image generation column, the input is text, and the output is an image, represented by a light green square.  The 'Decoder-only...' boxes suggest the use of a decoder-only transformer architecture in all three tasks.
Figure 5: Decoder-only Transformer’s flexibility in handling various modalities

In summary, we approach image generation with a Transformer-based autoregressive model. First, an image generator (decoder-only Transformer) generates a sequence of discrete tokens. Then, an image tokenizer decodes these tokens into the final image. We will explore the architecture, training, and sampling processes of these components in detail in the model development section.

Image represents a system for image tokenization and generation.  At the top, a light-blue square labeled 'Image' represents the input image.  This image is fed into an 'Image Tokenizer,' depicted as a rounded rectangle containing three trapezoidal components: a light-green 'Encoder,' a beige 'Quantizer,' and a light-red 'Decoder.' The image flows from the 'Image' square into the 'Encoder,' then through the 'Quantizer,' and finally into the 'Decoder.' The 'Quantizer' processes the encoded image, outputting a sequence of numerical tokens represented by a series of boxes containing numbers (6, 11, 381, ..., 72), indicating a variable-length token sequence. These tokens are then fed into an 'Image Generator' (a peach-colored rectangle at the bottom), which generates a new image based on the provided tokens.  The 'Image Generator' then sends the generated image back to the 'Decoder' to reconstruct the image.  The ellipsis (...) between 381 and 72 indicates that there are more tokens in the sequence than are explicitly shown.
Figure 6: Autoregressive image generation

Data Preparation

The data preparation process involves two crucial steps:

  • Image cleaning and normalization
  • Image tokenization

Image cleaning and normalization

In this step, we remove low-quality images from the training data and ensure the remaining ones are consistent. This is achieved by applying the following operations:

  • Remove low-quality images: We remove images with low resolution, excessive noise, or irrelevant content. We also ensure the dataset includes a wide range of styles, subjects, and compositions. This step is crucial for the generative model to produce diverse, high-quality images.
  • Normalize images: Normalization involves scaling pixel values to a range, typically 0 to 1, to stabilize the training process.
  • Resize images: Images often come in different sizes and aspect ratios. Resizing them to a uniform size ensures the model receives consistent inputs. Based on the interviewer’s requirements, we resize all images to 1024x1024.

Image tokenization

The image generator requires images to be represented as a sequence of discrete tokens. To achieve this, after training the image tokenizer, we tokenize all images in our training dataset into discrete tokens. It's important to note that this data preparation step is intended primarily for the image generator, not the image tokenizer.

Image represents a data processing pipeline for preparing image data for training.  It begins with a cylindrical database labeled 'Raw...' representing raw image data. This data flows right into a rectangular processing unit containing three vertically stacked steps: 'Filtering,' 'Normalization,' and 'Resizing.' The output of this unit is a second cylindrical database labeled 'Preprocessed...' containing the processed images.  This database is connected to an 'Image Tokenizer,' depicted as a bow-tie shape, composed of three sections: a green 'Encoder' on the left, a yellow 'Quantizer' in the center, and a pink 'Decoder' on the right. The preprocessed image data flows into the Encoder. The Quantizer processes the Encoder's output, and this output then flows into the Decoder. Finally, the Decoder's output is a table labeled 'Prepared training data,' which contains columns labeled 'ID' and 'Token sequence,' representing the structured data ready for model training.  The table shows multiple rows of token sequences, indicated by '...', signifying a variable number of tokens.
Figure 7: Data preparation process

These two steps ensure the training data is high-quality, consistent, and represented as a sequence of numerical inputs.

Model Development

Architecture

In this section, we explore the architecture of both the image tokenizer and the image generator.

Image tokenizer

The image tokenizer model has two functions:

  • Encoding an image into a sequence of discrete tokens
  • Decoding a sequence of discrete tokens back into an image

A common architecture specifically designed for image tokenization is the Vector-Quantized VAE (VQ-VAE) [2], which is a variant of the standard VAE discussed in Chapter 7. The VQ-VAE consists of three components:

  • Encoder
  • Quantizer
  • Decoder
Encoder

The encoder maps the input image into a lower-dimensional latent space. This component encodes important features of the image into an encoded representation.

The encoder's architecture is a deep convolutional neural network (CNN) with several convolution layers, each followed by a ReLU [3] activation function. These layers process the input image and extract visual features.

Image represents a simplified convolutional neural network (CNN) architecture for image encoding.  The process begins with an 'Image' input, depicted as a square. This image data flows rightward through a series of three convolutional layers. The first two layers, labeled 'Conv2D + ReLU,' are identical, each performing a 2D convolution followed by a Rectified Linear Unit (ReLU) activation function.  These layers are represented by light green rectangles.  The output of each layer is a 3D tensor, visually shown as progressively shrinking cubes above the layers, illustrating the dimensionality reduction that occurs through convolution and pooling (implied by the shrinking size). The third layer, simply labeled 'Conv2D,' performs only a 2D convolution, and its output is a final 3D tensor, represented by a taller, narrower cuboid labeled 'c' (likely representing the number of channels) and described as the 'Encoded representation...'. Arrows indicate the unidirectional flow of data from the input image through each layer to the final encoded representation.
Figure 8: The encoder converts an input image into an encoded representation containing 9 features, each with c channels
Quantizer

The quantizer converts continuous latent vectors into discrete tokens. There are two main reasons why VQ-VAE introduces a quantizer component to a standard VAE:

  • Avoiding posterior collapse
  • Reducing the learning space
Avoiding posterior collapse

Posterior collapse is a common issue in standard VAEs where the latent variables contribute little or are ignored because the decoder generates accurate outputs without using the latent space. The quantization step addresses this by discretizing the latent variables, thus forcing the model to use them during reconstruction. This ensures the decoder doesn't overpower the latent space and keeps the latent variables actively involved in shaping the output.

Reducing the learning space

Continuous vectors are difficult to predict sequentially because they have endless possibilities and small differences. By turning these vectors into discrete tokens, the quantizer simplifies the process by allowing the Transformer to focus on fewer options.

The quantizer uses an internal codebook to convert continuous latent vectors into discrete tokens. This codebook contains learnable embeddings that represent different patterns in the input images. Each embedding acts as a token, represented by an integer from 1 to k. The quantizer replaces each continuous vector with the closest token in the codebook based on Euclidean distance [4].

Image represents a simplified illustration of a quantization process likely within a generative AI system.  A three-dimensional data cube, appearing as a stack of smaller cubes, represents the input data. This cube is connected to a labeled 'Quantizer' box, suggesting a transformation process. The quantizer takes the input data and outputs a smaller, two-dimensional matrix (a grid of numbers: 1 2 7 8; 4 3 6 3; 7 9 6 8), representing the quantized version of the input.  Above the quantizer, a larger, rectangular grid divided into six vertical sections, each further subdivided into smaller cells, likely represents the memory or storage location where the quantized data is stored or processed further. The overall arrangement shows the flow of data from a high-dimensional input (the cube) through a quantization step (the quantizer box) resulting in a lower-dimensional, compressed representation (the matrix) stored in a designated memory area (the large grid).  The style suggests a conceptual diagram rather than a precise technical representation.
Figure 9: Quantization process

Note that the quantizer is an embedding table. Its sole parameter is the codebook, which is learned during training. The quantizer’s single responsibility is to map each continuous vector with the closest token in the codebook; therefore, the output is a collection of token IDs.

Decoder

The decoder converts discrete tokens back into the original image. It typically uses a deep CNN with transposed convolutions (ConvTranspose2d) to gradually transform the representation to the original image size. To learn more about convolutions and transposed convolutions, refer to [5].

Image represents a process flow starting with a grid of numbers, which is transformed into an image using a codebook. At the top is a box labeled 'Codebook', depicted as a grid of vertical segments labeled e1 through ek, representing embedding vectors, with a vertical brace labeled c indicating dimension. The process begins with a 3x3 grid of numbers (1, 27, 8, 43, 6, 33, 7, 96, 81) which is input into a purple rounded rectangle labeled 'Embedding Lookup'. An arrow points from 'Embedding Lookup' upwards to the 'Codebook', indicating that the numbers in the grid are used to look up embeddings from the codebook. The output of the 'Embedding Lookup' is represented by a 3D block composed of a 3x3 grid of smaller cubes, with a vertical brace labeled c on the left. This block is then processed sequentially through three red rounded rectangles, each labeled 'Transposed conv + ReLU'. Arrows connect the output of one stage to the input of the next. Intermediate outputs between the 'Transposed conv + ReLU' blocks are shown as larger 3D cuboids, growing in size and filled with grey or left unfilled, suggesting spatial upsampling. The final output after the third 'Transposed conv + ReLU' block is an outline of a square with an image icon inside, labeled 'Image' below, representing the resulting generated image. The diagram illustrates the process of converting a grid of discrete indices (numbers) into a continuous representation (embeddings) from a codebook, and then using transposed convolutions and ReLU activation functions to upsample this representation into a full image.
Figure 10: Decoding process

Image generator

The image generator generates a sequence of discrete tokens representing an image. As mentioned earlier, a decoder-only Transformer is often used for sequence generation tasks, which includes the following components:

  • Embedding lookup: Replaces each discrete token with its embedding from the codebook.
  • Projection: Projects each token embedding into a dimensionality that matches the Transformer's internal representation.
  • Positional encoding: Adds positional encodings to the sequence to provide spatial information.
  • Transformer: Processes the input sequence and outputs an updated sequence of vectors.
  • Prediction head: Utilizes the updated embeddings to predict the next token.
Image represents a generative model architecture, likely for text generation.  On the left, a 'Codebook' is depicted as a collection of vectors (represented by columns of cells labeled with '$e...') which are indexed by 'c'.  A thick arrow indicates these vectors are input to an 'Embedding Lookup' layer. This layer receives input from 'Previously genera...' (presumably previously generated tokens) and outputs embeddings.  These embeddings then pass through a 'Projection' layer and a 'Positional Encoding' layer before entering a 'Transformer' block. The Transformer consists of stacked layers of 'Multi-head...', 'Normalization', 'Feed Forward', and another 'Normalization' layer, repeated 'Nx' times.  The output of the Transformer feeds into a 'Prediction Head' layer, which ultimately produces the 'Predicted n...' (presumably the next token in the sequence).  The overall flow is sequential, with information moving from the codebook, through embedding and transformer layers, culminating in a prediction.
Figure 11: Decoder-only Transformer components

Training

In autoregressive image generation, we have two training stages:

  • Stage I: Training the image tokenizer
  • Stage II: Training the image generator

Stage I: Training the image tokenizer

The training process involves optimizing the encoder, decoder, and codebook so the model can accurately reconstruct the original images. This process can be described in three steps:

  • The encoder processes an input image and converts it into a continuous representation.
  • The quantizer replaces the continuous representation with discrete tokens using its internal codebook.
  • The decoder uses the discrete tokens to reconstruct the original image.
Image represents a system for compressing and reconstructing an image using a codebook-based quantization approach. The diagram shows a flow from an input image to a reconstructed image. The process begins with an 'Image', depicted as a square with a landscape icon, which is fed into a green rounded rectangular 'Encoder'. The output of the Encoder is a 3D block structure labeled with a vertical brace 'c', representing a compressed or feature space representation. This output is then processed by a yellow rounded rectangular 'Quantizer'. Above the Quantizer is a large box labeled 'Codebook', visually represented as a grid of vertical segments representing embeddings (e1 through ek) within a yellow textured area, with a vertical brace 'c' indicating dimension. An arrow points from the Quantizer upwards to the Codebook, suggesting the Quantizer interacts with the Codebook. Additionally, an arrow points from the Codebook downwards to the 3D block output of the Encoder, implying the Codebook is used in relation to the encoded representation, likely for finding the nearest embedding vectors. The Quantizer outputs a 3x3 grid of numbers (specifically showing the values 6, 28, 3 in the top row, 16, 97, 41 in the middle row, and 26, 39, 7 in the bottom row), representing the quantized indices from the Codebook. This grid of numbers is then input into a red rounded rectangular 'Decoder'. The Decoder takes these indices and outputs a square with a landscape icon, labeled 'Reconstructed image', completing the compression and reconstruction cycle. Arrows indicate the direction of data flow through the system components.
Figure 12: Image tokenizer training process

Since the quantizer lookup operation lacks a well-defined gradient for backpropagation, the VQ-VAE paper proposes approximating the gradient by copying it from the decoder input directly to the encoder output. This approach means that only the selected tokens receive gradients from the decoder, while unselected tokens do not receive any gradients.

Training data

We train the image tokenizer with 5 million images. Since the training is self-supervised and doesn't require image labels, we include other publicly available image datasets to enhance the tokenizer's robustness. In particular, we use the LAION-400M dataset [6], which contains 400 million images. This results in a richer codebook that captures diverse visual patterns.

ML objective and loss function

The ML objective of the image tokenizer is to accurately reconstruct original images from their quantized tokens. To achieve this ML objective, the following loss functions are typically employed during the training process:

  • Reconstruction loss
  • Quantization loss

Reconstruction loss: The reconstruction loss measures the difference between the original image and its reconstruction from the quantized tokens. It is typically calculated using the mean squared error (MSE) formula:

Where:

  • xix_ixi​ is the pixel value of the original image,
  • x^i\hat{x}_ix^i​ is the pixel value of the reconstructed image,
  • nnn is the total number of pixels in the image.

Quantization loss: The quantization loss measures the distance between the encoder’s outputs and the nearest embedding in the codebook. This loss encourages the encoder to produce outputs that are closer to the codebook embeddings.

Where:

  • E(x)E(x)E(x) is the continuous latent vector produced by the encoder, EEE, from the input xxx,
  • zqz_qzq​ is the quantized latent vector selected from the codebook ZZZ,
  • sg⁡(.)\operatorname{sg}(.)sg(.) represents the stop-gradient operation that blocks the gradients from flowing through the term. It is used here to prevent the codebook from being updated when optimizing the encoder.

For more details on the quantization loss formula, refer to the VQGAN paper [1].

In practice, using both reconstruction loss and quantization loss during training works well for reconstructing low-resolution images. However, for high-resolution images, the model may still produce artifacts. To improve reconstruction quality at high resolutions, two additional loss functions are typically employed:

  • Perceptual loss
  • Adversarial loss

Perceptual loss: Perceptual loss measures the difference between the features of the original and reconstructed images extracted from a specific layer of a pretrained model such as VGG [7]. The formula is:

Where:

  • ϕl\phi_lϕl​ denotes the feature map of the layer, l, from a pretrained VGG model,
  • xxx is the original image,
  • x^\hat{x}x^ is the reconstructed image.

The perceptual loss encourages the model to reconstruct images that are perceptually similar to the original images. VGG features encode high-level details such as content and style. The perception loss guides the training process so that the model can better preserve these details in the reconstructed images.

Adversarial loss: Adversarial loss is derived from GANs [8], where a discriminator tries to distinguish between real and reconstructed images. This loss is used to measure how well the image reconstructed by the image tokenizer can fool the discriminator. The formula, as we saw in Chapter 7, is:

Where:

  • DDD is the discriminator network,
  • x^\hat{x}x^ is the reconstructed image.

This loss function encourages the model to produce reconstructed images that a trained discriminator cannot distinguish from real images. The VQGAN paper introduced a patch-based version of this loss to reduce unnatural artifacts and improve the realism of the reconstructions.

Overall loss: The overall loss function is often a weighted sum of the individual losses described above. The weights (λi)(\lambda_i)(λi​) are hyperparameters that need tuning based on specific performance goals and experiments.

After training the image tokenizer, we convert all 5 million training images into discrete tokens and cache them, as detailed in the data preparation section. This step ensures that all images are represented as a sequence of discrete tokens, which is required for training the image generator.

Stage II: Training the image generator

Training the image generator, which is a decoder-only Transformer, is similar to the process described in earlier chapters. The training data consists of sequences of discrete tokens, and the model learns to predict these tokens sequentially during training.

We employ next-token prediction as our ML objective and cross-entropy as the loss function to measure how accurate the predicted probabilities are compared to the correct visual tokens.

Image represents a simplified diagram of a generative model's training process.  At the top, a column labeled 'Correct nex...' displays a sequence of four numbers: 0, 0, 1, 0. This represents the target or ground truth output sequence. Below, a column labeled 'Predicted...' shows the model's predicted output sequence: 0.1, 0, 0.8, 0.1.  These are probability values, indicating the model's confidence in each predicted digit. An arrow labeled 'loss' connects these two columns, signifying the calculation of a loss function to quantify the difference between the predicted and correct sequences.  This loss value is then used to update the model's parameters. At the bottom, a rectangular box labeled 'Image Generator...' represents the core generative model. Four upward arrows connect this box to four smaller boxes containing the numbers 1, 27, 8, and 16, which likely represent input parameters or features fed into the image generator. The overall flow shows how input parameters are processed by the image generator to produce a predicted sequence, which is then compared to the correct sequence to calculate a loss, enabling model training through backpropagation (implied, not explicitly shown).
Figure 13: Image generator loss calculation

Sampling

In autoregressive models, generating a new image involves two steps:

  • Generating a sequence of discrete tokens
  • Decoding discrete tokens into an image

. Generating a sequence of discrete tokens

In the first step, the image generator produces a sequence of tokens. The autoregressive nature of the generation ensures that each token is conditioned on preceding tokens, leading to coherent images.

Image represents a system for generating images.  On the left, a labeled box 'Codeb...' depicts a matrix or grid structure representing a codebook, with multiple cells (represented by smaller squares) containing unspecified values ('$$...$...') and labeled 'C' at the top left. A grey curved arrow connects this codebook to a rectangular box labeled 'Image Generator' in light orange.  This arrow is labeled 'Randomly selecting the f...', indicating a random selection of features from the codebook is fed into the Image Generator. The Image Generator receives input from three visible numbered squares (6, 27, 8) at the bottom, representing selected features.  Above the Image Generator, multiple vertical stacks of smaller squares labeled 'Predicted...' represent the generated image features. Each stack is topped by a numbered square (27, 8, 72), labeled 'Selected...', indicating the selected features for each generated image.  Dashed lines connect the input features (6, 27, 8) to the Image Generator and the Image Generator's output (Predicted...) to the selected features (27, 8, 72), suggesting a feedback loop or iterative process.  An ellipsis ('...') indicates that the system can handle more than three input features and generate more than three images.
Figure 14: Generating a sequence of discrete tokens using the image generator

Here is a step-by-step process to autoregressively generate a sequence of tokens:

  • Randomly select a token from the codebook as the first token. This initial token acts as a seed for the rest of the generation process.
  • Autoregressively generate tokens one by one. This involves: Passing the current sequence of tokens to the image generator to predict the probability distribution over the codebook Selecting the next token using a sampling method such as top-p sampling Appending the chosen token to the current sequence

This process continues until the entire image is generated. The number of iterations depends on the resolution and size of the desired output image. For example, generating an image of 1024×\times×1024 pixels, with each visual token representing a 64×\times×64 pixel block, requires 256 tokens. The process continues until all 256 tokens are generated. Once the sequence of tokens is complete, it is transformed into an actual image, which is the focus of the next step.

. Decoding discrete tokens into an image

In this step, the sequence of discrete tokens is transformed into an image by using the decoding functionality of the image tokenizer.

Image represents a two-step process for image generation.  Step 1 begins with a single numerical input '6', which feeds into an 'Image Generator'. This generator outputs a sequence of numbers (27, 8, 40, ..., 72), represented as a one-dimensional array.  A 'Reshape' operation then transforms this array into a two-dimensional matrix (3x3 in this example: 6, 27, 8; 40, 97, 41; 26, 39, 72). This matrix is then input into an 'Image Tokenizer', which consists of three components: an 'Encoder' (light green), a 'Quantizer' (beige), and a 'Decoder' (light red). The quantizer processes the matrix, and the decoder outputs a tokenized representation.  Step 2 involves this tokenized output being fed into a (blank) 'Generated...' box, implying the final image generation step.  The arrows indicate the flow of data between components, showing the transformation of the initial input '6' into a matrix, then a tokenized representation, and finally, a generated image.
Figure 15: Decoding tokens into an image

Evaluation

The evaluation metrics for high-resolution image synthesis are similar to those in Chapter 7. We'll briefly review them in this section without going into detail.

Offline evaluation metrics

The following metrics are typically employed to measure the quality and diversity of the generated images:

  • Inception score: Measures how similar the generated images are to images of real-world objects by utilizing a pretrained Inception v3 model. To learn more about the Inception score, refer to [9].
  • Fréchet inception distance (FID): Compares the distribution of generated images to real images by comparing features extracted from a pretrained Inception v3 model. This metric measures how similar the statistics of generated and real images are. To learn more about FID, refer to [10].
  • Human evaluation: Human evaluators are presented with pairs of images and asked to judge their photorealism and aesthetic qualities. The votes provide a statistical measure of which models produce more realistic images over time.

In addition to those metrics, it is common to evaluate other aspects of the model such as latency and cost.

  • Time to generate an image: Measures the time it takes for the model to generate an image. This metric is important to monitor since users generally expect quick results.
  • Cost per generation: Calculates the cost to generate an image. This metric depends on factors such as model complexity, resolution, and infrastructure expenses. Monitoring the cost of generation is crucial as it impacts business revenue.

Online evaluation metrics

In practice, companies monitor various metrics to assess the system's real-time quality. Common metrics include:

  • User feedback: Collects direct feedback from users regarding generated images.
  • Periodic surveys: Gathers user opinions on the quality and relevance of generated images.
  • Subscription rate: Measures how often users subscribe to services or features related to image generation.
  • Churn rate: Measures the rate at which users stop using the service.

Overall ML System Design

Once we are satisfied with the performance of the image generator and image tokenizer models, we can integrate them to construct the image synthesis system. The primary components in a high-resolution image synthesis system are:

  • Generation service
  • Decoding service
  • Super-resolution service
Image represents a simplified architecture diagram of an image generation system.  A user icon initiates the process, sending a request to a 'Generation...' module (light orange), which likely generates a lower-resolution image. This image is then passed to a 'Decoding...' module (light purple).  Simultaneously, the 'Generation...' module receives input from a cloud-shaped 'Image...' component, suggesting feedback or pre-existing image data is used.  The 'Decoding...' module receives input from a trapezoidal 'Tokenizer...' component, likely processing textual input for image generation. The output of 'Decoding...' feeds into a 'Super-Resolution...' module (light blue), which upscales the image resolution.  The final output, a higher-resolution image (indicated by a large square labeled '2048 x 2048'), is produced.  Intermediate stages are labeled with dimensions '1024 x 1024,' indicating image size at those points.  Arrows show the unidirectional flow of data between modules.  A small grid of squares above the 'Decoding...' module might represent a tokenized text input.
Figure 16: High-resolution image synthesis ML design

Understanding the purpose of each component and their interactions will provide a holistic view of the system. Let’s explore each in more detail.

Generation service

The generation service handles user requests and interacts with the trained image generator model to produce a sequence of visual tokens.

Decoding service

The decoding service interacts with the image tokenizer to convert the generated sequence of visual tokens into an image. Note that when we deploy the model, we don’t need the encoder in the image tokenizer – it is only used during training.

Separating generation and decoding services is crucial because the image generator and tokenizer are different models with distinct computational needs and latencies. This approach allows each service to scale independently and manage resources efficiently.

Super-resolution service

Super-resolution service uses a pretrained model to increase the resolution of generated images. For example, if the desired resolution is 2048×\times×2048 but the generator produces only 1024×\times×1024, we use a super-resolution model with a 2x upscale factor.

This service is crucial for applications requiring detailed and realistic visuals, such as medical imaging. There are many established solutions for super-resolution, from CNN-based [11] to GAN-improved [12]. To learn more about recent approaches, refer to [13].

Other Talking Points

If there's time remaining at the end of the interview, you could explore these additional points:

  • Extending autoregressive models to support text-based generation [14] [15].
  • Support applications such as image completion and image super-resolution [16].
  • Balancing diversity vs. fidelity in sampling, using techniques such as temperature scaling [17].
  • Enhancing the stability with adversarial training, gradient clipping, and learning rate scheduling [18][19].
  • Using progressive growing and multi-scale architectures to improve image quality and detail [20].
  • Creating interactive systems for users to refine and customize generated images [21].

Summary

Image represents a mind map summarizing the key aspects of designing a generative AI system for image generation.  The central element is a box labeled 'Summary,' from which several main branches radiate, each representing a crucial stage or component.  These branches include 'Clarifying requirements' (further branching into 'Framing as ML' with sub-branches 'ML approach' and 'Autoregressive modeling,' and 'Specifying input and output'); 'Data preparation' (branching into 'Image cleaning and normalization' and 'Image tokenization'); 'Model development' (branching into 'Architecture' detailing components like 'Image tokenizer,' 'Image generator,' and 'Decoder-only Transformer,' and 'Training' specifying loss functions such as 'Reconstruction loss,' 'Quantization loss,' 'Perceptual loss,' 'Adversarial loss,' and 'Cross-entropy loss,' along with processes like 'Generating discrete tokens' and 'Decoding tokens into an image'); 'Evaluation' (dividing into 'Offline' with metrics like 'Inception score,' 'FID,' 'Human evaluation,' 'Time to generate an image,' and 'Cost per generation,' and 'Online' with metrics like 'User feedback,' 'Periodic surveys,' 'Subscription rate,' and 'Churn rate'); and 'Overall system components' (branching into 'Generation service,' 'Decoding service,' and 'Super-resolution service'). Finally, a branch labeled 'Other talking points' is also present.  Each branch uses color-coding for visual distinction, and the overall structure is hierarchical, showing the relationships between different stages and components in the design process.

Reference Material

[1] Taming Transformers for High-Resolution Image Synthesis. https://arxiv.org/abs/2012.09841. [2] Neural Discrete Representation Learning. https://arxiv.org/abs/1711.00937. [3] Deep Learning using Rectified Linear Units (ReLU). https://arxiv.org/abs/1803.08375. [4] Euclidean distance. https://en.wikipedia.org/wiki/Euclidean_distance. [5] A guide to convolution arithmetic for deep learning. https://arxiv.org/abs/1603.07285. [6] LAION data set 400 million https://laion.ai/blog/laion-400-open-dataset/. [7] Very Deep Convolutional Networks for Large-Scale Image Recognition. https://arxiv.org/abs/1409.1556. [8] Generative Adversarial Networks. https://arxiv.org/abs/1406.2661. [9] Inception score. https://en.wikipedia.org/wiki/Inception_score. [10] FID calculation. https://en.wikipedia.org/wiki/Fr%C3%A9chet_inception_distance. [11] Image Super-Resolution Using Very Deep Residual Channel Attention Networks. https://arxiv.org/abs/1807.02758. [12] ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks. https://arxiv.org/abs/1809.00219. [13] NTIRE 2024 Challenge on Image Super-Resolution (×4): Methods and Results. https://arxiv.org/abs/2404.09790. [14] Muse: Text-To-Image Generation via Masked Generative Transformers. https://arxiv.org/abs/2301.00704. [15] VQGAN-CLIP: Open Domain Image Generation and Editing with Natural Language Guidance. https://arxiv.org/abs/2204.08583. [16] LAR-SR: A Local Autoregressive Model for Image Super-Resolution. https://openaccess.thecvf.com/content/CVPR2022/papers/ Guo_LAR-SR_A_Local_Autoregressive_Model_for_Image_Super-Resolution_CVPR_2022_paper.pdf. [17] Long Horizon Temperature Scaling. https://arxiv.org/abs/2302.03686. [18] Learning Rate Scheduling. https://d2l.ai/chapter_optimization/lr-scheduler.html. [19] Adversarial Training. https://adversarial-ml-tutorial.org/adversarial_training/. [20] Progressive Growing of GANs for Improved Quality, Stability, and Variation. https://arxiv.org/abs/1710.10196. [21] CogView2: Faster and Better Text-to-Image Generation via Hierarchical Transformers. https://arxiv.org/abs/2204.14217.

Footnotes

  • Certain optimizations and techniques (e.g., latent diffusion model) can significantly speed up the generation process in diffusion models. These methods are discussed in detail in Chapter 10 and Chapter 11. ↩
Chapter 9

Text-to-Image Generation

~27 min read

Introduction

In many cases, instead of allowing the model to generate content from random noise (as discussed in Chapters 7 and 8), we want to control the content of the generated image. Text-to-image generation is a fascinating application of generative AI that allows users to enter a text prompt, which the model transforms into a detailed image. Several text-to-image services are commercially available, such as OpenAI's DALL-E 3 [1], Google's Imagen [2], and Adobe's Firefly [3].

Image represents a humorous illustration depicting a halved avocado sitting on a teal-colored therapist's couch, expressing emotional distress.  The avocado has small arms and legs, a slightly sad facial expression, and a speech bubble emanating from it that reads 'I JUST FEEL SO EMPTY INSIDE.'  Opposite the avocado sits a therapist, represented by a figure with a spoon for a head, wearing a tan suit and holding a clipboard and pen.  A small, potted plant sits on a small wooden side table between the avocado and the therapist. The scene is set on a reddish-orange floor. The overall style is cartoonish and brightly colored, aiming for a comedic effect.  The text 'Prompt: An illustration of an avocado sitting in a therapist's cha...' appears above the image, indicating the prompt that generated the illustration.  At the bottom, the text 'Text is not SVG - cannot display' suggests that some text elements within the image are not properly rendered.
Figure 1: An example of a prompt and a generated image by OpenAI’s DALL-E 3 [1]

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: What resolution do we target for generated images? Interviewer: We aim for high-resolution images, specifically 1024x1024 pixels.

Candidate: Should the system support multiple languages for text input or just English? Interviewer: We'll focus on English initially, but the system's architecture should be adaptable for other languages later.

Candidate: How large is the dataset for training a text-to-image model? Interviewer: We have about 500 million images from user assets, most with captions.

Candidate: How detailed and complex can the text prompts be? Is there a limit to their complexity or length? Interviewer: The system should handle detailed text prompts, with a maximum length of 128 words.

Candidate: What speed should the system achieve for image generation? Interviewer: The goal is near–real-time generation. Let’s aim for 10 seconds per image.

Candidate: What types of images should the system generate? Are we focusing on a specific domain, like landscapes? Interviewer: The system should be capable of generating, based on text prompts, a wide range of images, including realistic landscapes, portraits, and abstract or conceptual art.

Candidate: It's important to ensure the images aren't biased by age, race, or gender. Can I start by focusing on those three attributes? Interviewer: Great point. It’s crucial to have a fair system. Let's begin by addressing those three attributes.

Candidate: Ethical considerations are crucial. We need filters and checks to avoid generating offensive, inappropriate, or harmful images. Does that sound correct? Interviewer: Yes, that’s correct.

Frame the Problem as an ML Task

Specifying the system’s input and output

The input to the system is a text prompt provided by the user that describes the desired image. This prompt usually includes details like scenes, objects, colors, styles, and emotions.

The output is a visually detailed image that adheres to the text prompt. For example, as shown in Figure 2, a prompt like "A boat on an ocean" produces an image depicting this scene.

Image represents a simplified data flow diagram illustrating a text-to-image generation process.  On the left, 'Text prompt:...' indicates a text input, representing the user's textual description for the desired image. A black arrow points right, signifying the flow of this text input into a centrally located, light-orange, rounded-rectangle box labeled 'Text-to-Image...'. This box represents the core text-to-image model or system.  Another black arrow extends right from the 'Text-to-Image...' box, indicating the output.  On the far right, a photograph of a sailboat on a calm sea is displayed, representing the generated image output from the 'Text-to-Image...' process. The overall diagram visually depicts the transformation of a textual prompt into a corresponding image through an unspecified text-to-image generation system.
Figure 2: Input and output of a text-to-image system. Image credit: [4]

Choosing a suitable ML approach

Text-to-image generation is a multimodal task that involves understanding text and generating a corresponding image. There are two primary approaches for building text-to-image systems:

  • Autoregressive models
  • Diffusion models

Let’s briefly review each and choose the one that best suits our needs.

Autoregressive models

These models treat text-to-image generation as a sequence generation task. A decoder-only Transformer takes a sequence of text tokens as input and outputs a sequence of visual tokens representing an image. An image tokenizer then decodes these visual tokens into the actual image.

Image represents a simplified diagram of a decoder-only transformer model generating an image from a text prompt.  At the bottom, a text prompt 'A boat on an ocean' is input.  This prompt is then tokenized into several units represented by empty squares labeled 'Text tokens'. These tokens are fed as input into a decoder-only transformer, depicted as a peach-colored rectangle with the label 'Decoder-only Transformer'.  The transformer also receives input from above, consisting of image tokens (also represented by empty squares labeled 'Image tokens'), which are likely embeddings representing an image.  The output of the transformer flows upwards, ultimately generating an image of a sailboat on the ocean, shown at the top of the diagram.  The arrows indicate the direction of information flow, showing how the text prompt and potentially existing image tokens are processed by the transformer to produce the final generated image.
Figure 3: Autoregressive text-to-image generation

Several text-to-image models have been developed using this approach, such as OpenAI’s DALL-E [5] and Google’s Muse [6].

Diffusion models

First introduced in 2019 [7], diffusion models gained mainstream attention about three years later. They use a different approach for text-to-image generation by starting with random noise and gradually transforming it into a clear image based on the text prompt. This process typically involves a text encoder, such as OpenAI’s CLIP [8] or Google’s T5 [9], which converts the text prompt into an embedding. This embedding captures the meaning of the prompt and guides the diffusion model to generate images that match it.1

Image represents a diagram illustrating a diffusion model for image generation.  The process begins with an 'Initial...' state, depicted as a square filled with random noise. This noise is fed into the first of a series of 'Diffusion Mod...' blocks, represented as light orange rectangles. Each 'Diffusion Mod...' block receives input from the previous block and a 'Text Enc...' block (light purple rectangle). The 'Text Enc...' blocks process text prompts, in this case, 'A boat on...', and their output is used to guide the diffusion process within the corresponding 'Diffusion Mod...' block.  The 'Diffusion Mod...' blocks iteratively refine the image, starting from the initial noise.  Intermediate results are shown as progressively clearer images of a sailboat on water.  The final 'Diffusion Mod...' block outputs a high-quality image of a sailboat, significantly improved from the initial noise.  Arrows indicate the flow of information between the blocks, showing how the text prompts and the intermediate image representations are used to generate the final image.
Figure 4: Diffusion-based text-to-image generation

Examples of diffusion-based text-to-image models include Google’s Imagen 3 [2], OpenAI’s DALL-E 2 [10], and Stability AI’s Stable Diffusion [11].

Diffusion versus autoregressive models

Autoregressive models frame text-to-image generation as a sequence generation task, while diffusion models approach it as an iterative refinement process. This key difference in modeling impacts their capabilities.

Image represents a Venn diagram comparing and contrasting diffusion and autoregressive generative models.  Two overlapping circles are presented. The left, peach-colored circle, is labeled 'Diffusion...' at the top and contains the text 'Exceptional...' and 'Expensive...' within it. The right, lavender-colored circle, is labeled 'Autoregressive...' at the top and contains 'Uniform architectu...' and 'Simple to imple...' within it. The overlapping section of the circles contains the text 'Slow gene...' and 'Billions...'.  The diagram visually illustrates the shared characteristics ('Slow gene...', 'Billions...') and distinct characteristics of each generative model type, highlighting that diffusion models are characterized as exceptional and expensive, while autoregressive models are described as having a uniform architecture and being simple to implement.
Figure 5: Diffusion vs. autoregressive model characteristics

Both diffusion and autoregressive models can produce realistic images, are slow in generation, typically have billions of parameters, and require substantial computational resources for training. Despite these similarities, they differ in three key aspects:

  • Implementation complexity: Autoregressive models are simpler to implement during both training and inference. During training, they are more statistically efficient because they can obtain useful gradient signals from all steps in a single forward-backward pass. In contrast, diffusion models are less statistically efficient, requiring sampling of different noise levels for each training example. At inference time, once the Transformer in an autoregressive model generates the sequence of visual tokens, these tokens form the final image. Diffusion models, however, refine the image over many steps, adding complexity to the implementation.
  • Image quality: Diffusion models have shown better performance in generating highly detailed and realistic images. Their iterative process allows the model to continuously refine and enhance fine details, leading to superior overall realism in the generated images.
  • Flexibility in sampling: Diffusion models are more flexible in trading off sampling speed and image quality. They can easily adjust the number of sampling steps—more steps usually lead to higher-quality images but take more time. Once trained, an autoregressive model cannot easily make such adjustments.

In this chapter, we choose diffusion models to prioritize exceptional image quality. In the model development section, we explore the architecture, training methods, and sampling techniques of diffusion models.

Data Preparation

Our dataset consists of approximately 500 million image–caption pairs. However, large-scale datasets often require substantial preprocessing before they can be used for model training. In this section, we explore common techniques to prepare images and captions for diffusion training.

Image preparation

We focus on two main steps to prepare the images: filtering inappropriate images and standardizing the remaining ones. Let's delve into each step in more detail.

Filtering inappropriate images

In large-scale datasets, many images may not be useful for training. It's crucial to remove these to ensure the model learns only from high-quality and safe data. To achieve this, we perform the following steps:

  • Remove small images: We discard image–caption pairs where the image size is smaller than a certain threshold, for example, 64×64 pixels. Small images are often of poor quality and may not provide valuable information for training.
  • Deduplicate images: We use deduplication methods, such as [12], to remove identical or perceptually similar images. This prevents the model from being biased toward certain images that appear more frequently.
  • Remove inappropriate images: We employ harm detection and NSFW (Not Safe For Work) detection models to filter out harmful content such as violence or nudity. This ensures the model doesn't learn to generate inappropriate images.
  • Remove low-aesthetic images: We use specialized ML models to eliminate images that aren't aesthetically pleasing. This helps the model focus on high-quality images during training.

Standardizing images

  • Adjust image dimensions: The diffusion model requires inputs of specific dimensions. Therefore, it's crucial to have training data of similar sizes. For example, if the expected model input is 128x128, we first resize the images so that the smaller dimension is 128, preserving the aspect ratio. Then, we center-crop them to achieve the final size of 128x128.
  • Normalize images: We normalize pixel values to a standard range such as [0, 1] or [-1, 1] for more stable training.
Image represents a data processing pipeline for image preparation.  It begins with a rectangular box labeled 'Original ima...' representing the input image.  This image flows rightward through a series of processing steps depicted as rounded rectangles. The first step, 'Resize,' changes the image dimensions.  Next, 'Center Crop' extracts a central portion of the resized image, indicated by a smaller square box above it with a visual representation of cropping using L-shaped lines.  A curved arrow connects this cropping visual to the square representing the cropped image. The image then proceeds to 'Normalize...', which likely adjusts pixel values. Finally, the processed image is outputted into a rectangular box labeled 'Prepared...'.  Arrows between each stage indicate the flow of the image data through the pipeline.
Figure 6: Image preparation steps

Caption preparation

In addition to images, captions are often irrelevant or missing. Here are common steps to ensure captions are consistent and of high quality:

  • Handle missing or non-English captions: For images without captions or with captions in another language, we use an image captioning model such as BLIP-3 [13] to automatically generate descriptive captions. If you would like to build an image captioning system from scratch, refer to Chapter 5.
  • Enhance captions: We use a pretrained model such as CLIP [8] to score the relevance of each image–caption pair. For pairs scoring below a threshold, we replace the original caption with an auto-generated one using the BLIP-3 model.
  • Remove poorly matched pairs: After enhancing captions, we remove image–caption pairs with CLIP similarity scores below a threshold. This step ensures that the model is exposed only to pairs whose captions accurately describe the images.

Model Development

Architecture

A diffusion model, as previously explained, progressively denoises a noisy image through multiple steps until it becomes clear. In each step, as illustrated in Figure 7, the model takes a noisy image as input and predicts the noise to be removed.2 Two common architectures are typically used for this purpose:

  • U-Net
  • Diffusion Transformer (DiT)
Image represents a simplified diagram of a denoising process within a generative model, likely for image generation.  The process begins with a 'Noisy image...' depicting a sailboat on water with added noise. This noisy image is fed into a 'Diffusion Mod...' (Diffusion Model) block, a key component of diffusion models.  The Diffusion Model also receives input from a 'Text Encoder' block, which processes the text prompt 'A boat on...' to provide contextual information. The Diffusion Model outputs a 'Predicted...' image, which is primarily noise but contains latent information about the sailboat. This noisy prediction then undergoes 'Noise removal,' a process that refines the image, resulting in a 'Refined...' image, a clearer depiction of the sailboat.  Above the main process flow, a smaller box visually demonstrates the noise removal step: an original image of a sailboat is shown, followed by a noisy version, and then an equals sign (=) leading to the same sailboat image but with reduced noise, mirroring the effect of the main process.  Arrows indicate the flow of data between the components.
Figure 7: Input and output of the diffusion model in a single step

U-Net

U-Net [14] is a convolutional neural network (CNN) architecture originally developed for biomedical image segmentation. It consists of a series of downsampling blocks followed by upsampling blocks, as shown in Figure 8.

Image represents a diagram illustrating a U-Net architecture for image processing.  The top section shows a series of six 3D rectangular blocks representing feature maps at different stages of processing, with dimensions labeled (e.g., 128x32x32, 256x16x16, etc.), decreasing in height and width and increasing in depth as they progress towards the center.  These blocks are connected by a curved arrow pointing to the 'Intermediate...' label, indicating a transition to the next stage. The bottom section depicts the U-Net itself.  A 3x64x64 input 'Image' block feeds into a sequence of processing blocks within the U-Net.  The initial blocks, labeled 'D' and colored light red, represent downsampling operations.  These are followed by a series of blocks labeled 'U' and colored light green, representing upsampling operations.  The 'D' blocks are grouped under 'Downsampling bl...' and the 'U' blocks under 'Upsampling bloc...', indicating the two main phases of the network.  Ellipses (...) indicate that multiple 'D' and 'U' blocks are present but not explicitly shown. Finally, the processed data exits the U-Net into a 3x64x64 output 'Predicted...' block.  The overall flow is from left to right, with the downsampling phase reducing spatial dimensions and the upsampling phase reconstructing them, ultimately producing a predicted image.
Figure 8: U-Net downsampling and upsampling blocks
Downsampling blocks

The downsampling blocks progressively reduce spatial dimensions (height and width) while increasing depth (number of channels), leading to a compressed representation of the input. Each downsampling block typically consists of the following:

  • Convolution operation: Extracts visual features from the input.
  • Batch normalization: Normalizes feature maps to stabilize training.
  • Non-linear activation: Introduces non-linearity to learn complex patterns.
  • Max-pooling: Reduces the feature map dimensions.
  • Cross-attention: Cross-attends to additional conditions, such as text prompt tokens. This is necessary to ensure the text prompt influences the predicted noise.
Image represents a diagram illustrating the architecture of a U-Net.  The top section shows a single block containing four processing layers arranged horizontally:  `Conv2D`, `BatchNorm...`, `ReLU`, and `MaxPool...`, followed by a `Cross-Atte...` layer.  These layers are depicted as individual boxes within a dashed-line rectangle, suggesting a repeated module.  Below this, the main U-Net architecture is shown.  It consists of a series of light-pink boxes labeled 'D' representing downsampling blocks, connected sequentially with arrows indicating data flow.  An ellipsis (...) indicates repetition of the 'D' blocks.  These downsampling blocks are grouped together and labeled 'Downsampling bl...'.  Following the downsampling blocks, a series of light-green boxes labeled 'U' represent upsampling blocks, also connected sequentially with arrows.  An ellipsis (...) again indicates repetition of the 'U' blocks.  These upsampling blocks are grouped and labeled 'Upsampling bloc...'.  A dashed line connects the top block to the downsampling section, implying that the top block represents the processing within each 'D' block.  The overall structure resembles the letter 'U', hence the name U-Net.
Figure 9: Typical layers in a downsampling block

Let's explore the cross-attention layer in more detail, as this is the first instance where we're applying cross-attention between different modalities—image and text inputs. The text prompt is processed by a text encoder, such as a Transformer-based model, which converts words or tokens into a sequence of continuous embeddings. These embeddings capture the semantic meaning of the text. During each denoising step of the diffusion process, the model receives a noisy image as input and processes it through layers like Conv2D and BatchNorm2D to extract visual features. In the cross-attention layer, the queries are derived from the image features, while the keys and values come from the text embeddings. This enables the model to align and integrate information effectively from the text into the image features.

Upsampling blocks

The upsampling blocks symmetrically increase spatial dimensions and decrease feature map depth. The final output matches the original input size, which, in this case, is the predicted noise. Each upsampling block consists of the following:

  • Transposed convolution: Uses operations like PyTorch’s ConvTranspose2D to process and increase the feature map’s dimensions.
  • Batch normalization: Normalizes feature maps to stabilize training.
  • Non-linear activation: Introduces non-linearity to learn complex patterns.
  • Cross-attention: Maintains the influence of additional conditions during upsampling.
Image represents a U-Net architecture diagram.  The main body shows a sequence of processing blocks.  On the left, several light-red blocks labeled 'D' represent downsampling blocks, arranged sequentially with arrows indicating data flow from left to right.  Ellipses (...) indicate the repetition of this pattern.  On the right, several light-green blocks labeled 'U' represent upsampling blocks, also arranged sequentially with data flowing from left to right, again with ellipses (...) showing repetition.  A gray brace underneath the 'D' blocks is labeled 'Downsampling bl...', and a similar brace under the 'U' blocks is labeled 'Upsampling bloc...'.  Above the upsampling blocks, a dashed box outlines a detailed view of a single upsampling block, showing four sub-blocks arranged horizontally: 'Transposed...', 'BatchNorm...', 'ReLU', and 'Cross-Atte...', indicating the constituent operations within each upsampling block.  The dashed lines connect this detailed view to the general upsampling block representation in the main U-Net diagram, illustrating the internal structure of the 'U' blocks.  The entire main body is labeled 'U-Net' at the top left, indicating the overall architecture.
Figure 10: Typical layers in an upsampling block

The U-Net architecture has various details and variations. Different implementations may use different layers and configurations. However, understanding the key components and structure is generally sufficient for most ML system design interviews. For more in-depth information, refer to [14].

DiT

DiT [15] is another popular architecture in diffusion models. Unlike U-Net, which uses a series of downsampling and upsampling layers, DiT primarily relies on a Transformer architecture to process the noisy input image and predict the noise.

Image represents a denoising model architecture.  At the bottom, a 'Noisy image' box feeds into a larger rectangular block representing the core model. Inside this block, from bottom to top, are: 'Patchify' (a layer that divides the image into patches), 'Positional Encoding' (adding positional information to the patches), a 'Transformer' (the main processing unit), and 'Unpatchify' (recombining the processed patches).  The output of the 'Unpatchify' layer is a 'Predicted noise' box, which represents the model's estimate of the noise in the input image.  A separate box labeled 'Conditions...' is connected to the input of the Transformer, suggesting that the model can incorporate additional contextual information.  The entire process aims to subtract the 'Predicted noise' from the 'Noisy image' to obtain a cleaner image (not explicitly shown).
Figure 11: DiT components

DiT is primarily inspired by the Vision Transformer (ViT) [16] architecture discussed in Chapter 5. DiT components are:

  • Patchify: Converts the input image into a sequence of patch embeddings.
  • Positional encoding: Attaches position information to each patch embedding to indicate its location in the original image.
  • Transformer: Processes the sequence of embeddings and other conditioning signals, such as the text prompt, to predict the noise for each patch.
  • Unpatchify: Converts the sequence of predicted noise vectors into an image with the same dimension as the original input image.

In summary, both U-Net and DiT architectures perform well in practice. U-Net was originally used in several text-to-image models such as Google’s Imagen [17] and Stability AI’s Stable Diffusion [11]. Recently, the DiT architecture has shown great promise for text-to-image generation. For educational purposes, we use the U-Net architecture in this chapter. Chapter 11 explores the DiT architecture in more detail.

Training

A diffusion model is trained by employing the diffusion process. The diffusion process has two phases:

  • Forward process
  • Backward process

Forward process

In the forward process, also known as the noising process, noise is gradually added to an image over multiple steps (denoted as t or timesteps) until the image becomes completely noisy. The value of t, representing the number of steps, is typically chosen randomly from a range, usually between 1 and 1,000. The forward process does not involve any ML models or parameter updates.

Image represents a sequence of image transformations.  It begins with a clear image of a sailboat on the water labeled '$x_0...' This image is then progressively altered. A rightward arrow indicates a transformation to a slightly noisier version of the same image, labeled '$x_1...'.  This process continues with the addition of more noise, represented by the text 'Noise...', and three dots indicating a series of intermediate steps. The next visible image, labeled '$x_{...}', shows a significantly noisier version of the original, where details are becoming obscured. Finally, a further transformation, indicated by another rightward arrow, results in a heavily degraded image labeled '$x_{...}', where the sailboat is barely discernible amidst the noise.  The labels suggest a sequence of images ($x_i$) where the subscript *i* represents the increasing level of noise added to the original image.
Figure 12: Forward diffusion process

Backward process

In the backward process, also known as the denoising process, an ML model learns to reverse the forward process. At each step, the model predicts the noise in the noisy image. This predicted noise is then used to reduce the noise in the input image. As shown in Figure 13, this process is repeated until the image becomes clear.

Image represents a denoising process using a diffusion model.  The diagram shows a sequence of four image representations, labeled  `$x_0...`, `$x_1...`, `$x_{...}...`, and `$x_t...`, progressing from a clear image of a sailboat at sea (`$x_0...`) to increasingly noisy versions (`$x_1...`, `$x_{...}...`, `$x_t...`).  Arrows indicate the flow of information:  `$x_0...` is fed into a 'Diffusion...' process (represented by a peach-colored box), which then outputs `$x_1...`.  This process is repeated, with each subsequent image becoming noisier due to added 'Noise...'.  The noisy image `$x_t...` is then fed into a second 'Diffusion...' process, suggesting a reverse diffusion process to reconstruct the original image from the noisy input.  The ellipses (...) in the labels suggest that the images represent a sequence of many steps, not just the four shown.
Figure 13: Backward diffusion process

With an understanding of both the forward and backward processes, we can now explore how they are applied during the diffusion training process.

Diffusion training process

During training, we introduce noise to the original image by simulating the forward process, then ask the model to predict this noise. This process involves four key steps:

  • Noise addition
  • Preparation of conditioning signals
  • Noise prediction
  • ML objective and loss calculation

This section includes some math for those who are interested, but the details do not affect the design of the ML system.

. Noise addition

The first step is to simulate the forward diffusion process by adding noise to the original image over multiple timesteps. At each timestep, we corrupt the image slightly by adding Gaussian noise. This gradual addition of noise transforms the image into pure noise over time.

The amount of noise added at each timestep is controlled by a noise schedule. The noise schedule is defined by a set of variance parameters, 1, 2, ...,T​, where T is the total number of timesteps. Each t(0,1) controls the amount of noise added at timestep t.

The noise schedule typically increases the values of β\betaβ incrementally:

Thus, smaller amounts of noise are added in the early steps, preserving more of the original image, and larger amounts of noise are added in the later steps, accelerating the diffusion process.

With the noise schedule defined, we can express the noisy data at timestep ttt using the noise addition formula:

where:

  • xtx_txt​ is the noisy image at timestep ttt,
  • xt−1x_{t-1}xt−1​ is the noisy image at timestep t−1t-1t−1,
  • ϵ\epsilonϵ is the Gaussian noise sampled from the standard normal distribution N(0,I)N(0, I)N(0,I),
  • βt\beta_tβt​ is the variance schedule parameter at timestep t, controlling the amount of noise added.

Iteratively adding noise over many steps can be time-consuming. Instead, it can be shown that the noisy data at timestep ttt can be directly derived from the original data, x0x_0x0​:

where:

  • xtx_txt​ is the noisy image at timestep ttt,
  • αt=1−βt\alpha_t=1-\beta_tαt​=1−βt​ and αt′=∏i=1tαi\alpha_t^{\prime}=\prod_{i=1}^t \alpha_iαt′​=∏i=1t​αi​ are reparameterizations of βt\beta_tβt​,
  • ϵ\epsilonϵ is the Gaussian noise sampled from the standard normal distribution N(0,I)N(0, I)N(0,I).

In summary, during noise addition, we randomly sample ttt and compute xtx_txt​ directly from x0x_0x0​, without the need to iteratively add noise at each timestep, using the following formula:

. Preparation of conditioning signals

To predict the added noise, the model typically expects two additional pieces of information: the image caption and the sampled timestep, ttt, which indicates the noise level. We use separate encoders (see Figure 14) to prepare each of these conditioning signals to be processed by the model.

. Noise prediction

The primary goal of training a diffusion model is to learn how to reverse the forward diffusion process-that is, to reconstruct the original data, x0x_0x0​, from its noisy version, xtx_txt​. It has been shown that directly predicting x0x_0x0​ is not as effective. Instead, training the model to predict the noise, ϵ\epsilonϵ, added during the forward process simplifies the task and improves performance. Therefore, in this step, the model predicts the noise, ϵ\epsilonϵ, given the noisy input, xtx_txt​, and the timestep, t.3

. ML objective and loss calculation

The ML objective is to minimize the difference between the true noise, ϵ\epsilonϵ, and the model's prediction. The loss function used is the mean squared error (MSE) between the true noise and the predicted noise:

where:

  • ttt is a timestep sampled uniformly from {1,2,…,T}\{1,2, \ldots, T\}{1,2,…,T},
  • ϵ∼N(0,I)\epsilon \sim N(0, I)ϵ∼N(0,I) is the Gaussian noise used in the forward process,
  • xtx_txt​ is the noisy data at timestep ttt, computed using the noise addition formula,
  • ϵθ(xt,t)\epsilon_\theta\left(x_t, t\right)ϵθ​(xt​,t) is the prediction of the neural network model (U-Net or DiT).
Image represents a diagram illustrating the training process of a text-to-image diffusion model.  The process begins with a training dataset (a table with 'ID', 'Image', and 'Caption' columns, showing example image-caption pairs).  This dataset feeds into a 'Noise addition' stage (1), where random noise is added to an image from the dataset using a 'Forward...' process and a specified 'Timestep...' (t=800). The resulting 'Noised image a...' is then input into a 'Noise prediction' stage (3), which uses a 'Diffusion...' model. This model receives input from a 'Preparation of...' stage (2), which takes the caption from the training dataset and a 'Timestep...' (t=800) to generate embeddings. The 'Diffusion...' model outputs a predicted noise image. Finally, a 'Loss calculation' stage (4) compares the predicted noise with the actual noise added in stage 1, calculating the loss to update the model's parameters.  The entire cycle, from noise addition to loss calculation, iteratively refines the model's ability to generate images from text captions.
Figure 14: A single iteration in diffusion training

To enhance the reading experience, we have omitted the mathematical details, such as the derivation of the tractable mean and the loss simplification. For more information on diffusion training, refer to [18].

Sampling

Sampling refers to generating a new image from a trained diffusion model. In this section, we’ll explore how sampling works in diffusion models and how noises are transformed into coherent images guided by the text prompt.

The sampling process starts with an image of random pixels, typically drawn from a Gaussian distribution. The model then gradually refines this image step by step. At each step, the diffusion model predicts the noise present in the current image and uses this prediction to adjust the image slightly in the right direction. This gradual refinement continues, each step producing a clearer image until a clear and detailed image is achieved.

Image represents a denoising diffusion process for image generation.  It begins with a rectangular box labeled 'Random Noise...', representing an initial input of random noise data.  An arrow points from this box to a noisy image labeled '$x_{99}...', indicating the initial state of the image. This noisy image is then fed into a rectangular box labeled 'Diffusion...', representing a diffusion model that processes the image.  The output of this first diffusion step is a less noisy image, also labeled '$x_{99}...', showing a slightly clearer image (in this case, a sailboat).  This process is repeated, indicated by an ellipsis ('...') connecting the output of the first diffusion step to the input of a second 'Diffusion...' box.  The second diffusion step further refines the image, resulting in a clearer image of the sailboat labeled '$x_{0}...'.  Crucially, both 'Diffusion...' boxes receive an additional input labeled 'Input tex...', suggesting textual prompts guide the denoising process towards a specific image.  The arrows illustrate the unidirectional flow of data through the system, transforming random noise into a coherent image based on the provided text prompt.
Figure 15: Sampling process

The basic sampling process described above has two drawbacks. First, it often fails to generate images that accurately match the text prompt. Second, it is slow, because generating each sample requires many iterative steps. The following two techniques are commonly employed in practice to mitigate the issues described above:

  • Classifier-free guidance (CFG): CFG [19] improves the alignment between images and text prompts in diffusion models. During training, the model learns to generate images with and without the text prompt. During sampling, CFG adjusts the balance between these two modes. CFG ensures the generated images closely match the text prompts by increasing the influence of the conditioned (text prompt) mode and reducing the unconditioned (no text prompt) mode. This adjustment guides the diffusion process to produce more accurate results. To learn more about CFG, refer to [19].
  • Reduction of diffusion steps: Sampling algorithms such as DDIM [20] reduce the number of diffusion steps from the standard 1,000 to as few as 20. This significantly speeds up the generation process while maintaining image quality. To learn more about DDIM, refer to [20].

In most ML system design interviews, the focus is on high-level concepts and how components work together, not on the intricate details. If you are interested in exploring diffusion models in more depth, refer to [21][19][20].

Challenges in text-to-image diffusion models

Diffusion models are typically very large. For example, DALLE-2 has 3.5 billion parameters [10]. This capacity is necessary since these models have to learn diverse concepts, shapes, and styles.

Training such large models poses several challenges during both training and sampling. The most common ones include:

  • Resource-intensive model training
  • Slow image generation

Resource-intensive model training

Training diffusion models is computationally intensive, requiring significant processing power. It also requires substantial GPU memory due to the size of the model and the high-dimensional nature of the generated images. Most modern GPUs may not have sufficient memory to fit model parameters, activations, and gradients during training. The following strategies are commonly employed to overcome these challenges:

  • Mixed precision training: This technique uses both 16-bit and 32-bit floating-point types to reduce memory usage and increase computational efficiency. To learn more, refer to [22].
  • Model and data parallelism: These methods distribute training across multiple devices. Most distributed training frameworks, such as FSDP [23] and Deepspeed [24], support various parallelism techniques.
  • Latent diffusion models: These models operate in a lower-dimensional space instead of pixel space, significantly speeding up training and inference. Chapter 11 examines this approach in more detail.

Slow image generation

Generating images from text in diffusion models is slow for two main reasons. First, due to the sequential nature of the diffusion sampling process, multiple steps are needed to refine the image. Second, as diffusion models have billions of parameters, significant computations occur at each step.

Common strategies to mitigate this challenge include:

  • Parallel sampling: Implementing parallel processing during sampling reduces the time needed to generate images [25].
  • Model distillation: A distilled model improves generation speed because of its reduced size, but it retains the behavior and performance of the original model. To learn more about model distillation in diffusion models, refer to [26].
  • Model quantization: This technique reduces the precision of the model's weights, which decreases memory usage and speeds up generation.

Evaluation

Offline evaluation metrics

A consistent and reliable benchmark is key to evaluating text-to-image models. DrawBench [17] serves this purpose by providing a curated set of prompts that test various aspects of image generation such as object composition, interaction, and context understanding. These prompts, ranging from simple to complex, help to assess how accurately the model generates images from text. Due to its comprehensiveness, we use DrawBench to evaluate our text-to-image model. Let’s examine both automated metrics and human evaluation to assess three key areas of the model’s ability to generate images:

  • Image quality
  • Image diversity
  • Image–text alignment

As discussed in previous chapters, Inception score (IS) [27] and Fréchet Inception distance (FID) [28] are two common metrics for evaluating quality and diversity in image generation systems. In this section, we focus primarily on image–text alignment.

Image–text alignment

Image–text alignment refers to how accurately the generated images match the text prompts. Measuring this alignment is important because it ensures the generated images are faithful to the user's input. A common metric for assessing this is CLIPScore [29], which evaluates the degree of alignment. Before diving into CLIPScore, let's briefly review CLIP.

CLIP

CLIP [8] is a model developed by OpenAI that has been trained to match images with their corresponding descriptions. It consists of two encoders: one for text and one for images. The text encoder converts input text into a text embedding; the image encoder converts the image into an image embedding.

Image represents a diagram illustrating the functionality of a CLIP (Contrastive Language–Image Pre-training) model.  The diagram is enclosed within a dashed-line box labeled 'CLIP model'.  On the left, an image depicting a sailboat on the ocean is shown, and the text 'A boat on an oc...' is displayed, indicating a textual description of the image.  Arrows indicate that both the image and the text are fed as input into the CLIP model. Inside the CLIP model, two rectangular boxes represent the processing of the image and text data separately. A light purple box labeled 'Text...' receives the textual input ('A boat on an oc...'), and a light green box labeled 'Image...' receives the image input (the sailboat picture).  Each of these boxes then outputs data to a series of adjacent rectangular blocks, representing the feature vectors generated by the model for the text and image respectively.  The arrows show the flow of information from the input (image and text) through the CLIP model's processing blocks to the final feature vector representations.  The bottom of the diagram includes a note stating 'Text is not SVG - cannot display,' indicating that the text description is not displayed as a visual SVG element.
Figure 16: CLIP encoders

During training, CLIP learns to align embeddings by bringing related text and image embeddings closer together and pushing unrelated ones apart. This helps CLIP develop a shared embedding space where both an image and its associated text will map into the same space.

After training, similar text descriptions map close to each other in the embedding space, and images map near their relevant descriptions.4

Image represents a diagram illustrating the functionality of a CLIP (Contrastive Language–Image Pre-training) model.  Three text descriptions ('A boat on an ocean,' 'A boat in lake,' 'A train in c...') are fed as input into a purple rectangle labeled 'Text...', representing the text encoder part of the CLIP model.  Simultaneously, an image of a sailboat on the water is fed into a light green rectangle labeled 'Image...', representing the image encoder. Both the text and image encoders output their respective embeddings, shown as three and one horizontal arrays of smaller rectangles, respectively. These embeddings are then mapped into a 2D 'Embedding space,' represented by a graph with x and y axes.  The text embeddings are represented by three 'x' marks in the embedding space, each corresponding to one of the input text descriptions, and their positions relative to each other and the image embedding (represented by another 'x' mark) illustrate their semantic similarity. Dashed lines connect the output of each encoder to their corresponding points in the embedding space, showing the mapping process. The overall diagram demonstrates how CLIP encodes both text and image inputs into a shared embedding space, allowing for comparison and similarity assessment.
Figure 17: Text and image feature vectors mapped to the CLIP embedding space

With an understanding of the CLIP model, we can now easily explore CLIPScore as a metric for evaluating image–text alignment.

CLIPScore

The CLIPScore measures the cosine similarity between the CLIP embeddings of a text description and an image. It shows how closely the image matches the text in the high-dimensional embedding space. A higher score indicates better alignment between an image and a description.

Human evaluation

Human evaluation complements the automated metrics by assessing both image quality and text alignment using the following approach:

  • Image quality: Human raters compare a generated image with a reference image by judging which of the images is more photorealistic. Image quality is determined by the percentage of times the generated image is chosen over the reference image.
  • Text alignment: Human raters are shown an image and its caption and then asked, "Does the caption accurately describe the above image?" The responses "yes," "somewhat," and "no" are scored as 100, 50, and 0, respectively. These scores are averaged separately for generated images and reference images to measure text alignment.

Online evaluation metrics

Online metrics measure how the model works in production. Common metrics to evaluate our text-to-image model include:

  • Click-through rate (CTR): The percentage of users who click on the generated images. A high CTR indicates that users find the generated images useful.
  • Time spent on page: The average time users spend with the service. Longer viewing times indicate higher user engagement.
  • User feedback: Direct feedback from users is collected through feedback. Positive feedback indicates satisfaction with the image quality and text alignment.
  • Conversion rate: The percentage of users who take a desired action (e.g., purchase, sign up) after interacting with generated images. A high conversion rate indicates satisfaction with the model's performance.
  • Latency: The time it takes to generate an image from a text prompt. Lower latency indicates faster performance, which is important for user satisfaction.
  • Throughput: The number of image generations the model can handle per second. High throughput ensures the service can serve more users.
  • Resource utilization: The computational resources (e.g., CPU, GPU, memory) used to run the model and serve users. Efficient resource utilization is key to reducing costs.
  • Average cost per user per month: Generating images with models that have billions of parameters is costly. If users are unhappy with the images, they might repeatedly generate new ones using the same prompt but different seeds, hoping for better results. This behavior increases our expenses. By monitoring this metric, we can ensure that costs remain justifiable.

Overall ML System Design

While the diffusion model is at the core of a text-to-image generation system, several other pipelines are crucial for ensuring efficiency, safety, and quality. In this section, we delve into the holistic design of a text-to-image generation system by examining the following pipelines:

  • Data pipeline
  • Training pipeline
  • Model optimization pipeline
  • Inference pipeline

Data pipeline

The data pipeline prepares data for training by removing inappropriate images, standardizing the rest, and storing them. It ensures captions are present and relevant and uses a pretrained model such as Google’s T5 [9] to pre-compute and cache caption embeddings. This caching reduces computation during training.

In addition to preparing text–image pairs from the training data, the pipeline also collects and processes newly generated data such as user prompts, generated images, and user feedback. This new data is added to the training set for future use.

Image represents a data processing pipeline with two parallel branches.  The top branch processes raw image data.  Two cylindrical database-like structures labeled 'Raw...' and 'User-generated...' represent input sources.  Data from these sources flows into a light green rectangular box labeled 'Inappropriate...', suggesting an initial filtering or moderation step.  The output then flows into another light green box labeled 'Image...', implying image processing or transformation. Finally, the processed image data is stored in a cylindrical database labeled 'Prepared...'. The bottom branch processes user-generated captions.  Data from a 'Raw...' database flows into a purple rectangular box labeled 'Caption Enhancer,' likely for improving the quality or clarity of the captions.  The enhanced captions then move to another purple box labeled 'Caption Encoder...', suggesting a process of converting the captions into a suitable format for storage or further processing.  The encoded captions are then stored in a cylindrical database labeled 'Caption...'.  Both branches are independent but process data originating from similar sources, suggesting a system designed to handle both image and caption data from user-generated content.
Figure 18: Data pipeline

Training pipeline

The training pipeline trains a model using the latest training data collected by the data pipeline.

Image represents a data processing pipeline for training a diffusion model.  Two cylindrical database-like components, labeled 'Prepared...' and 'Caption...', represent input data sources.  These sources are connected via lines to a rectangular 'Model Trainer' component, indicating that data from both 'Prepared...' and 'Caption...' are fed into the Model Trainer. The Model Trainer processes this combined input data and outputs a trained model, represented by an arrow pointing to a cloud-shaped component labeled 'Diffusion...', symbolizing the deployment of the trained diffusion model to a cloud environment.  The overall flow depicts the training process, where data from two sources are used to train a model which is then deployed.
Figure 19: Training pipeline

The training pipeline ensures that the model adapts to recent user prompts and is trained on higher-quality generated images.

Evaluation pipeline

The evaluation pipeline assesses newly trained models using predefined automated metrics to determine whether or not they meet performance and quality standards for deployment.

Model optimization pipeline

The model optimization pipeline is responsible for enhancing the efficiency of the model. There are several methods to optimize models:

  • Model compression: Use techniques such as quantization and pruning to reduce model size and generation time.
  • Model distillation: Distill the model into a smaller one to reduce the model size and generation time.
  • Optimized algorithms: Replace sampling with more efficient algorithms for faster generation.

Once the model optimization is completed, the optimized model can replace the existing model in production.

Inference pipeline

The inference pipeline handles user requests and generates images based on text prompts. It comprises several components, each playing an important role in ensuring the system's quality and safety. In this section, we will examine the key components:

  • Prompt auto-complete
  • Prompt safety service
  • Prompt enhancement
  • Image generation
  • Harm detection
  • Super-resolution service
Image represents a flowchart depicting the process of generating an image from a text prompt.  The process begins with a user typing a prompt (1) and submitting it (2) to a 'Prompt Safety...' module (a light-red rectangle) which checks if the prompt is safe.  If safe (3a), the prompt proceeds to a 'Prompt...' module (a light-purple rectangle) (4), then to an 'Image...' module (a light-gold rectangle) (6). The 'Image...' module receives input from both 'Text...' and 'Diffusion...' modules (represented by grey clouds) via connections labeled (5a) and (5b) respectively. The generated image then passes through a 'Harm...' module (a light-red rectangle) (6) for safety checks. If safe (7a), it proceeds to a 'Super-Resolution...' module (a light-blue rectangle) (8), resulting in a final generated image.  If at any point a safety check fails (3b or 7b), the request is rejected.  The entire process is numbered sequentially, indicating the order of operations.
Figure 20: Inference pipeline

Prompt auto-complete service

The prompt auto-complete service uses a specialized model to suggest possible next words or phrases in real-time as the user types their prompt. This enhances user experience by providing potential completions.

Image represents a simple user interface for a text-to-image generation system.  The main component is a large rectangular box divided into three horizontal sections, each containing a text prompt: 'A dog sitting in the backyard,' 'A dolphin jumping out of the water,' and 'A dog drawing another dog.'  Above these prompts, a smaller section displays 'A do,' suggesting an incomplete or initial prompt. To the right of the main box is a separate rectangular button labeled 'Generate.'  The implied interaction is that a user would complete the prompt in the top section (perhaps adding 'A dog'), select one or more of the prompts below, and then click the 'Generate' button to trigger the image generation process based on the selected text prompts.  No URLs or parameters are visible.
Figure 21: Suggested phrases by the auto-complete service

Prompt safety service

This service uses a text classification model to process user prompts and reject those that violate our usage policies, for example, requests for violence, hateful imagery, or nudity.

This service ensures that the system adheres to safety standards and prevents the generation of inappropriate images.

Prompt enhancement

The prompt enhancement component refines user prompts to improve their clarity, coherence, and details.

Image represents a simple data flow diagram illustrating prompt enhancement in a generative AI system.  The diagram shows an initial prompt, 'A dog sitting,' as the input. This prompt flows via a directed arrow into a rectangular box labeled 'Prompt Enhanceme...' (presumably short for 'Prompt Enhancement'), representing a process that refines the input.  This process outputs an enhanced prompt, 'A golden retriever dog sitting on a grassy field. The do...', which is shown flowing out of the 'Prompt Enhanceme...' box via another directed arrow. The output is a more detailed and specific description compared to the initial input, suggesting the addition of breed, location, and potentially further details implied by the ellipsis.  The overall flow demonstrates how a basic prompt is transformed into a richer, more descriptive prompt suitable for generating a more specific and detailed image or text.
Figure 22: An example of prompt enhancement

This component is widely used in advanced image and video generation systems [30], as it effectively helps the model produce better outputs. It improves the quality of generated images by offering the model a more coherent and detailed prompt.

Image generation

The image generation component is the core of the inference pipeline. It interacts with the T5 text encoder to encode the enhanced text prompt into a sequence of tokens. These tokens are passed to the diffusion model to generate one or multiple images for each prompt.

Harm detection

This component ensures that generated images are safe for users. If an image still contains violence or nudity despite previous safeguards, the component flags it and blocks it from being shown.

Super-resolution service

The super-resolution service increases the resolution of the generated images. This step ensures that the final output is visually appealing and meets resolution requirements.

In practice, text-to-image systems often use at least one super-resolution model because diffusion models typically cannot generate high-resolution images directly. Instead, the diffusion model is trained at a lower resolution, and specialized super-resolution models enhance the resolution. For example, the base model might generate a 64x64 image, which a first super-resolution model increases to 256x256, followed by a second model that boosts it to 1024x1024. Google's [31] follows this approach to achieve the desired resolution.

Image represents a data processing pipeline, visualized as a sequence of connected boxes and arrows.  The pipeline begins with a box labeled 'image generated b...' representing an input image. This image is fed into a light-blue, rounded-rectangle box labeled 'Super-Resolution #1...', which processes the image, presumably enhancing its resolution. The output of this first super-resolution step flows via a black arrow into an empty square box, acting as an intermediate stage.  From this intermediate stage, another arrow points to a second light-blue, rounded-rectangle box labeled 'Super-Resolution #2...', indicating a second super-resolution processing step. The output of this second step is then passed through a final arrow into a large, empty square box labeled 'Final...', representing the final, high-resolution output image.  The overall flow is linear, with data moving sequentially through the super-resolution stages.
Figure 23: A cascade of super-resolution models

In summary, various pipelines work together to ensure that a text-to-image system is reliable, high-quality, and safe. The data pipeline provides the foundation for continuous improvement, while the training and model optimization pipelines enhance the model's performance. The inference pipeline ensures safe, efficient, and high-quality image generation. These pipelines create a system ready for real-world challenges.

Other Talking Points

If time permits at the end of the interview, consider discussing these additional topics:

  • Using consistency models for faster image generation [26].
  • Employing RLHF for quality improvement [32].
  • Extending the text-to-image model to support inpainting and outpainting applications [33].
  • Personalizing the text-to-image model to a particular concept (Chapter 10).
  • Details of different scheduling techniques [34].
  • Details of DDPM and DDIM, including their theoretical foundations [20][18].
  • Supporting multiple aspect ratios and resolutions using techniques such as Patch n’ Pack [35].
  • Details of developing a re-captioning model [36][37][13].
  • Improving the diversity–fidelity trade-off with guidance [19].
  • More advanced controls over the generated images using techniques like ControlNet [38].
  • Controlling the style of the generated images [39].

Summary

Image represents a mind map summarizing the key aspects of a generative AI system design interview.  The central node is labeled 'Summary,' branching into five main categories represented by colored lines:  orange ('Clarifying requirements' and 'Other talking points'), light-coral ('Model development' and 'Evaluation'), light-blue ('Specifying input and output'), purple ('Data preparation'), and teal ('Overall system components').  The 'Model development' branch further subdivides into 'Architecture' (detailing U-Net, Diffusion, downsampling/upsampling blocks, patchify/unpatchify, positional encoding, and transformer components), 'Training' (including diffusion process specifics like forward/backward passes and MSE loss), and 'Sampling' (covering CFG and DDIM methods).  It also includes 'Challenges and mitigations' addressing mixed precision training, data and model parallelism, and latent diffusion models. The 'Evaluation' branch splits into 'Offline' (covering image quality, diversity, image-text alignment using CLIP scores, and human evaluation) and 'Online' (focusing on conversion rate, latency, throughput, and resource utilization).  The 'Overall system components' branch details the data, training, evaluation, and optimization pipelines, as well as the inference pipeline, which includes prompt auto-complete, safety service, enhancement, image generation, harm detection, and super-resolution services.  The 'Clarifying requirements' branch specifies framing the problem as an ML task and choosing between autoregressive and diffusion models.  Finally, the 'Data preparation' branch focuses on image and caption preparation.  The entire diagram visually depicts the interconnectedness of various stages, from initial requirements to final system deployment and evaluation metrics.

Reference Material

[1] OpenAI’s DALL-E 3. https://openai.com/index/dall-e-3/. [2] Imagen 3. https://arxiv.org/abs/2408.07009. [3] Adobe’s Firefly. https://www.adobe.com/products/firefly.html. [4] Introducing ChatGPT. https://openai.com/index/chatgpt/. [5] Zero-Shot Text-to-Image Generation. https://arxiv.org/abs/2102.12092. [6] Muse: Text-To-Image Generation via Masked Generative Transformers. https://arxiv.org/abs/2301.00704. [7] Generative Modeling by Estimating Gradients of the Data Distribution. https://arxiv.org/abs/1907.05600. [8] Learning Transferable Visual Models From Natural Language Supervision. https://arxiv.org/abs/2103.00020. [9] Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer. https://arxiv.org/abs/1910.10683. [10] Hierarchical Text-Conditional Image Generation with CLIP Latents. https://arxiv.org/abs/2204.06125. [11] High-Resolution Image Synthesis with Latent Diffusion Models. https://arxiv.org/abs/2112.10752. [12] On the De-duplication of LAION-2B. https://arxiv.org/abs/2303.12733. [13] xGen-MM (BLIP-3): A Family of Open Large Multimodal Models. https://www.arxiv.org/abs/2408.08872. [14] U-Net: Convolutional Networks for Biomedical Image Segmentation. https://arxiv.org/abs/1505.04597. [15] Scalable Diffusion Models with Transformers. https://arxiv.org/abs/2212.09748. [16] An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale. https://arxiv.org/abs/2010.11929. [17] Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding. https://arxiv.org/abs/2205.11487. [18] Denoising Diffusion Probabilistic Models. https://arxiv.org/abs/2006.11239. [19] Classifier-Free Diffusion Guidance. https://arxiv.org/abs/2207.12598. [20] Denoising Diffusion Implicit Models. https://arxiv.org/abs/2010.02502. [21] Introduction to Diffusion Models. https://lilianweng.github.io/posts/2021-07-11-diffusion-models/. [22] Mixed Precision Training. https://arxiv.org/abs/1710.03740. [23] FSDP tutorial. https://pytorch.org/tutorials/intermediate/FSDP_tutorial.html. [24] DeepSpeed. https://github.com/microsoft/DeepSpeed. [25] Parallel Sampling of Diffusion Models. https://arxiv.org/abs/2305.16317. [26] Consistency Models. https://arxiv.org/abs/2303.01469. [27] Inception score. https://en.wikipedia.org/wiki/Inception_score. [28] FID calculation. https://en.wikipedia.org/wiki/Fr%C3%A9chet_inception_distance. [29] CLIPScore: A Reference-free Evaluation Metric for Image Captioning. https://arxiv.org/abs/2104.08718. [30] Sora overview. https://openai.com/index/video-generation-models-as-world-simulators/. [31] Imagen Video: High Definition Video Generation with Diffusion Models. https://arxiv.org/abs/2210.02303. [32] Finetune Stable Diffusion Models with DDPO via TRL. https://huggingface.co/blog/trl-ddpo. [33] Kandinsky: an Improved Text-to-Image Synthesis with Image Prior and Latent Diffusion. https://arxiv.org/abs/2310.03502. [34] On the Importance of Noise Scheduling for Diffusion Models. https://arxiv.org/abs/2301.10972. [35] Patch n' Pack: NaViT, a Vision Transformer for any Aspect Ratio and Resolution. https://arxiv.org/abs/2307.06304. [36] InternVL: Scaling up Vision Foundation Models and Aligning for Generic Visual-Linguistic Tasks. https://arxiv.org/abs/2312.14238. [37] BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models. https://arxiv.org/abs/2301.12597. [38] Adding Conditional Control to Text-to-Image Diffusion Models. https://arxiv.org/abs/2302.05543. [39] StyleDrop: Text-to-image generation in any style. https://research.google/blog/styledrop-text-to-image-generation-in-any-style/.

Footnotes

  • In practice, we provide the diffusion model with additional conditioning inputs, such as the timestep. This will be discussed further in the training section. ↩
  • For simplicity, we omitted the timestep input to the diffusion model. This will be covered in more detail in the training section. ↩
  • For simplicity, we include only the noisy image, xt, and the timestep, t, as the input. As mentioned earlier, conditioning signals can also be included as inputs. ↩
  • For simplicity, the embedding space is visualized in 2D. In reality, it is a d-dimensional space, where d represents the embedding size. ↩
Chapter 10

Personalized Headshot Generation

~22 min read

Introduction

Personalized text-to-image (T2I) models are one of the emerging applications of generative AI. Imagine asking a T2I model to generate an image of your friend John with the prompt “John sitting on a chair while reading a book.” While the model will likely produce an image of a person sitting and reading, it probably won't depict “John.” To do that, we need to personalize a T2I model by having it learn the subject of interest (i.e., John).

Image represents a process demonstrating image generation in various styles.  A reference image, labeled 'Reference image,' shows a headshot of a smiling, balding man with a beard wearing a blue blazer. A large right-pointing arrow indicates a transformation.  The arrow points to a 2x2 grid of generated images.  Each square in the grid contains a different image of the same man, but in a drastically altered pose and style.  The top-left image depicts him as an ice sculpture, appearing as a statue in a winter setting. The top-right image shows him as an astronaut in a spaceship, operating a console. The bottom-left image portrays him as an American football player in a team uniform. Finally, the bottom-right image shows him as a pirate captain on a ship, holding a glass of amber liquid. The entire grid is labeled 'Generated images in novel poses and styles.'
Figure 1: Personalized T2I model generating identity variations (images taken from [1])

In this chapter, we explore how to develop a personalized T2I model capable of generating professional-quality headshots of specific individuals.

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer:

Candidate: Are the generated headshots primarily intended for business profiles, such as LinkedIn? Interviewer: Correct.

Candidate: I assume users will provide several images of themselves in different variations – pose, angle – with their faces visible. Is that correct? How many images will we ask them to upload? Interviewer: Yes, that’s correct. Let’s assume between 10 to 20 images.

Candidate: What if some images are not suitable, like if they're too dark or the face isn't visible? Interviewer: We need to detect those and notify the user to provide better images.

Candidate: Should users be able to specify features such as hairstyle in the generated images? Interviewer: For simplicity, let's assume attribute control isn't required.

Candidate: What resolution is required for the headshots? Interviewer: The system should support 1024x1024 outputs.

Candidate: Can I assume we can start from a pretrained generic T2I model? Interviewer: Yes.

Candidate: Should users be able to provide text prompts to control the generated headshots? Interviewer: We prefer to keep it simple, so assume users won't provide text prompts.

Candidate: How many headshot images should the system generate? Interviewer: 50 images.

Candidate: What is the expected latency? Interviewer: The user provides the images, and we notify them by email when the images are ready. The overall process should take less than an hour.

Frame the Problem as an ML Task

In this section, we use headshot generation as a case study to explore an important aspect of image generation: personalization. This process involves adapting a pretrained T2I model to learn a new subject, in this case, the user’s face.

Specifying the system’s input and output

The input includes several images of the user's face, taken from different angles and in different poses. The output consists of professional headshots of the individual. These headshots are high-quality and diverse, and they preserve the person's identity.

Image represents a data flow diagram illustrating an AI-powered headshot generation process.  The diagram begins with a dashed-line box labeled 'User's original images,' containing several irregularly arranged, light gray square placeholders representing the user's input images.  A solid arrow points from this box to a light orange, rounded-rectangle box labeled 'Personalized...'. This central box represents the AI processing stage where personalization occurs based on the input images.  A second solid arrow extends from the 'Personalized...' box to a second dashed-line box labeled 'AI-generated headshots.' This final box displays a grid of colored squares, each a different pastel shade, representing the AI-generated headshot outputs.  The arrangement of the output squares suggests a variety of generated options, with some squares having darker outlines than others.  Ellipses ('...') are used in both the input and output boxes to indicate that more images than shown are included in the respective sets.
Figure 2: Input and output of a headshot generation system

Choosing a suitable ML approach

Diffusion models work exceptionally well at generating very detailed and realistic images. A common practice for personalization is to start with a T2I model pretrained on a broad range of images as a base model.

There are two primary approaches to personalizing a pretrained T2I model: tuning-based and tuning-free.

Tuning-based methods finetune the T2I model on a set of reference images for each identity. This approach integrates the new identity into the model, allowing it to generate a variety of images while preserving the identity.

Image represents a system for personalizing a pretrained T2I (text-to-image) model.  A single, light-grey box labeled 'Pretrained T2I...' represents the base, pre-trained model.  From this box, three arrows extend, each labeled 'Personalize...', indicating a personalization process. Each arrow connects to a separate, differently colored box representing a personalized version of the T2I model: one light-orange, one light-blue, and one light-green, all labeled 'Personalized T2I...'.  Each of these personalized models then has an arrow pointing to a stack of papers labeled 'User 1 hea...', 'User 2 hea...', and 'User N hea...', respectively, suggesting that each personalized model generates images for a different user (or group of users).  The ellipsis ('...') after 'T2I' and 'hea' suggests that the labels are truncated for brevity, implying multiple models and users. The vertical ellipsis ('...') between the second and third personalization arrows indicates that this process is repeated for an unspecified number of users.
Figure 3: Tuning-based approach for T2I personalization

On the other hand, tuning-free methods bypass the need for finetuning the T2I model for each new identity. Instead, they finetune the pretrained T2I model along with a visual encoder once. After this training, the visual encoder extracts features from a new reference image and injects them into the T2I model. This allows the model to generate personalized images without adjusting its internal weights for each identity.

Image represents a system architecture diagram illustrating a multi-user text-to-image generation pipeline.  Multiple users, labeled 'User 1' to 'User N,' are represented as boxes on the left, each feeding input into a light orange box labeled 'Visual...'. This 'Visual...' box likely represents a visual processing or embedding stage.  The output from 'Visual...' flows into a larger light gray box labeled 'Pretrained T2I...', which signifies a pretrained text-to-image model.  Finally, the output from the 'Pretrained T2I...' model is directed to a stack of boxes on the right, labeled 'User 1 hea...' and 'User N hea...', representing the generated image outputs for each corresponding user.  The ellipses ('...') indicate that there are multiple users beyond User 1 and User N.  Arrows depict the unidirectional flow of data from users to the visual processing, then to the text-to-image model, and finally to the individual user's generated image outputs.
Figure 4: Tuning-free approach for T2I personalization

Tuning-free methods, such as Meta’s Imagine Yourself [1], are simpler because they only require training once with fewer parameters than training the entire T2I model. A single model should be deployed, and only one reference image is needed, allowing the same pretrained model to generate personalized images for multiple identities. However, these methods often rely on a single reference image to capture facial features, which may not capture all the details from different angles or expressions. Additionally, they require special adjustments tailored to the subject. For instance, [1] uses specific encoders and proposes a technique for generating synthetic paired data.

On the other hand, tuning-based methods tend to capture more detailed features of the subject. They are also more versatile, handling a wider range of subjects beyond human faces. Given these advantages, we focus on tuning-based methods in the rest of this chapter. If you are interested in learning more about tuning-free methods, refer to [2][3][1].

Several tuning-based methods can be used to achieve personalization, each offering unique advantages and disadvantages. Three of the most common ones are:

  • Textual inversion
  • DreamBooth
  • Low-rank adaptation (LoRA)

Textual inversion

Textual inversion [4] personalizes a T2I model by introducing a new special token that represents the subject and learning its embedding. During finetuning, the model updates the special token's embedding, while the diffusion model, text encoder, and other token embeddings remain unchanged.

Image represents a system for generating images from text descriptions using a diffusion model.  The system begins with a text input, shown as a table with columns labeled 'Token' and 'Embedd...', containing the tokens 'a,' 'the,' 'of,' and '<EOS>' along with their corresponding embeddings.  This table is processed by a 'Tokenizer' and an 'Embedding Layer,' which are stacked vertically and labeled as part of a 'Text Encoding...' block. The output of this block feeds into 'Encoding Layers,' which then provides input to a light-orange box labeled 'Diffusion Model.'  The 'Diffusion Model' outputs an image, which is then compared to a 'Real image of...' (presumably the ground truth) using a loss function.  The loss is fed back to the 'Diffusion Model' for training.  A light-green box labeled 'S*' represents the latent representation of the input text, which is connected to the 'Tokenizer' and the 'Diffusion Model.'  Padlocks are present on the input text, the 'Tokenizer,' 'Encoding Layers,' and 'Diffusion Model,' suggesting these components are protected or secured.  Finally, a small box at the bottom says 'A photo of S*', indicating the visual representation of the latent variable S*.
Figure 5: Textual inversion updating only the special token embedding

After finetuning, the model generates images of the new subject when prompted with the special token.

Image represents a text-to-image generation system using a diffusion model.  The process begins with a text prompt, 'A picture of S* standing in a prof...', which is fed into a text encoder. This encoder consists of three stacked components: a Tokenizer, an Embedding Layer, and Encoding Layers. The Tokenizer likely converts the text into numerical tokens, the Embedding Layer transforms these tokens into vector representations, and the Encoding Layers further process these embeddings to create a latent representation of the text's meaning. This latent representation is then input into a Diffusion Model (represented as a light orange rectangle).  Simultaneously, a random noise image (represented as a dark gray square labeled 'Random...') is also fed into the Diffusion Model. The Diffusion Model processes both the text embedding and the random noise, iteratively refining the noise until it generates a coherent image. The resulting generated image (represented as a blank white square labeled 'Generated...') is the output of the system.  Arrows indicate the flow of information between components.
Figure 6: Generating an image of the subject of interest

Let’s review the pros and cons of textual inversion.

Pros:
  • Efficiency: Textual inversion training involves learning only a new token embedding, making it a lightweight and efficient process.
  • Preservation of original model capabilities: The T2I model's capabilities are maintained since the diffusion model’s parameters remain unchanged.
  • Minimal storage requirements: Minimal storage is required because only the special token embedding needs to be stored for each personalized model.
Cons:
  • Difficulty in learning subject details: Textual inversion often struggles to learn new subject details accurately due to its limited capacity to encode these details. This limitation arises because the new subject is represented by a single token embedding.

In summary, while textual inversion is an efficient method for personalizing a T2I model, it often struggles to capture and preserve all the details of the new subject.

DreamBooth

DreamBooth [5] is a popular personalization method that was introduced by Google in 2023. It finetunes a pretrained diffusion model using images of the subject of interest. Unlike textual inversion, DreamBooth updates all the diffusion model's parameters during finetuning. This allows the model to capture the new subject's details more effectively.

Image represents a system for generating images from text descriptions, likely using a diffusion model.  The system begins with 'A photo of [V] person,' which serves as the input text. This text is fed into a 'Tokenizer,' followed by an 'Embedding Layer,' and then 'Encoding Layers,' collectively labeled 'Text Encod...', which processes the text into a numerical representation suitable for the model.  The output of the text encoding is then passed to a 'Diffusion Model' (represented as a light orange rectangle with a lock icon indicating a parameter), which generates an image. This generated image is compared to a 'Real image of...' (a placeholder for a real image corresponding to the input text), and the difference is calculated as 'loss.' This loss is used to train the diffusion model, improving its ability to generate images that match the input text descriptions.  The arrows indicate the flow of information, showing how the text is processed, the image is generated, and the model is trained through the loss function.
Figure 7: DreamBooth method updating the entire diffusion model

DreamBooth relies primarily on two techniques for successful finetuning:

  • Rare-token identifier
  • Class-specific prior preservation loss
Rare-token identifier

Most personalization methods select an identifier to represent the subject of interest. While textual inversion creates a new token for this purpose, DreamBooth selects an identifier using the existing vocabulary of tokens. The authors have found that simply choosing any existing token won’t work well in practice. Let’s explore why simple approaches such as selecting a common or random identifier won’t work, and why the rare-token identifier is preferred.

Challenges with common or random token identifier

A simple way to represent the subject of interest is to choose a common English word such as “unique” or “special”. This approach is problematic because the token usually has an established meaning. For example, if we choose “special” to refer to the subject of interest using a prompt like “a special person sitting”, the model might struggle because "special" already has a broad, established meaning in the context of language. The model has to separate this token from its original meaning and then learn a new meaning for it that references the new subject.

Another way to represent the subject is to randomly combine characters. This approach also poses issues because the tokenizer might treat each character separately, leading to strong prior associations for these characters. For example, if we choose "xxy5syt00" to represent the subject, the tokenizer might break it down into individual characters, each of which could have pre-existing associations within the model. This fragmentation can cause the model to generate outputs that are influenced by the meanings or patterns associated with those individual characters or sub-units, rather than treating the identifier as a unique and cohesive entity.

How the rare-token identifier works

DreamBooth resolves these problems by selecting rare tokens—those that appear infrequently in the training data. Representing the subject of interest with these tokens strikes a balance: they’re distinct enough to avoid strong prior associations but still cohesive so that tokenizers treat them as a single unit.

Here is the step-by-step process to form an identifier:

  • Identifying a few rare tokens in the vocabulary: The model's vocabulary contains a large set of tokens, each with a unique ID. A "rare token" is one that appears infrequently in the training data. Such rare tokens are identified by assessing token frequency distribution.
  • Generating a sequence of rare tokens: Once we have identified the rare tokens, we generate a sequence using some of these tokens.
  • Forming the identifier: The tokenizer converts the sequence of token IDs back into their corresponding text form. This forms an identifier to represent the subject. "XyZ", "SKS", and "[V]" are possible examples of an identifier.
Class-specific prior preservation loss

DreamBooth finetunes all layers of the diffusion model. While this enhances the quality of generated images, it can lead to overfitting, where the model loses diversity in its outputs. For example, training the model on images of a specific dog might make it struggle to generate images of other dogs.

To address this problem, DreamBooth uses class-specific prior preservation loss to maintain general class characteristics. This prevents the model from overfitting to the specific examples and losing its ability to generate diverse images that belong to the broader class. We will examine DreamBooth’s loss function in the training section.

DreamBooth has several pros and cons.

Pros:
  • Effective at learning subject details: Updating more parameters allows the model to learn the details of the subject more accurately.
  • Fewer images required: Because the entire diffusion model is updated, a smaller image set is needed to learn the subject.
Cons:
  • High storage requirement: After finetuning for each subject, the entire diffusion model has to be stored for future use. This can require several gigabytes per subject, which is costly and not scalable.
  • Resource-intensive: Updating the entire diffusion model demands more GPU memory during training.

In summary, DreamBooth learns subject details effectively but is costly to train and store. In contrast, textual inversion is efficient and compact, but less effective. Next, we'll explore LoRA, which offers a balanced approach.

LoRA

LoRA, introduced by Microsoft [6], is a powerful method for efficiently finetuning very large models. This method was originally developed for adapting large language models (LLMs) to specific tasks but was later adopted for other tasks including T2I personalization.

The key motivation behind LoRA is that finetuning all parameters of large pretrained models, such as GPT-3 [7], is time-consuming and costly. Instead, LoRA adapts a large model to a new task by introducing a small set of parameters and updating only those, thus significantly reducing computational costs.

Due to its importance, let's examine in detail the mathematical foundations of LoRA.

The mathematics of LoRA

In a typical neural network layer, a weight matrix, W∈Rdout ×din W \in \mathbb{R}^{d_{\text {out }} \times d_{\text {in }}}W∈Rdout ​×din ​, transforms the input vector, x∈Rdinx \in \mathbb{R}^{d_{i n}}x∈Rdin​, into the output vector y∈Rdout y \in \mathbb{R}^{d_{\text {out }}}y∈Rdout ​.

Image represents a simplified diagram of a machine learning model, likely for a supervised learning task.  The diagram shows three rectangular boxes arranged vertically. The bottom box, colored pale yellow, is labeled  `$x \in \m...` representing the input data (x) belonging to a space (m), likely a feature space. An upward arrow connects this box to the middle box. The middle box is larger and light gray, labeled 'Pretrained...' and `$W \in \mathbb{...}`, indicating a pretrained model with weight matrix W belonging to a space (likely a weight space represented by the mathematical notation).  Finally, an upward arrow connects the middle box to the top box, also pale yellow, labeled `$y \in \m...`, representing the output data (y) belonging to a space (m), likely the same space as the input. The arrows indicate the flow of information: the input data (x) is processed by the pretrained model (W) to produce the output data (y).  The ellipses (...) suggest that the full mathematical notation is not shown, implying more detailed information about the spaces and parameters is omitted for brevity.
Figure 8: A fully connected neural network layer

The goal of finetuning is to adjust weight parameters, WWW, to improve the performance of the specific task. Instead of modifying WWW directly, LoRA modifies the weights by introducing an additional low-rank component, ΔW\Delta WΔW, which can be expressed as a product of two learnable lowrank matrices:

where:

  • A∈Rdout ×drA \in \mathbb{R}^{d_{\text {out }} \times d_r}A∈Rdout ​×dr​,
  • B∈Rdr×dinB \in \mathbb{R}^{d_r \times d_{\mathrm{in}}}B∈Rdr​×din​,
  • din d_{\text {in }}din ​ and dout d_{\text {out }}dout ​ represent input and output dimensions,
  • rrr is a small integer representing the rank, typically much smaller than din d_{\text {in }}din ​ and dout d_{\text {out }}dout ​.
Image represents a diagram illustrating a generative AI system's architecture.  At the top, a yellow rectangle labeled  `$y \in \m...` represents the system's output.  An addition symbol (+) connects this output to two inputs: `$Wx$` and `$A(Bx)$`.  `$Wx$` originates from a gray rectangle labeled 'Pretrained...' and containing `$W \in \mathbb{...}`, representing a pre-trained model's weights.  A padlock icon next to this rectangle indicates that the pre-trained model's weights are protected.  `$A(Bx)$` is an input that feeds into a larger, enclosed section representing a fine-tuned model. This section contains two trapezoidal shapes: a light-blue one labeled with `$A$`, `$ \mathb...`, and some seemingly encoded text, and a light-green one below it labeled with `%3CmxGraphModel%3E%3...`, `$ \mathbb{R}..`, and a padlock icon, suggesting a graph-based model with protected parameters.  The light-blue trapezoid represents a LoRA (Low-Rank Adaptation) layer, indicated by a curved arrow pointing to a label 'LoRA I...'.  A padlock icon is present within the fine-tuned model section, suggesting protection of its parameters.  Finally, a yellow rectangle labeled `$x \in \m...` at the bottom represents the system's input, connected to the output of the fine-tuned model.  The overall flow shows the input `$x$` being processed through the pre-trained model and the fine-tuned LoRA model to produce the output `$y$`.
Figure 9: Injection of low-rank matrices

Learning the new parameters introduced by LoRA is more efficient than finetuning the full matrix. Specifically, the original matrix, WWW, has dout ×din d_{\text {out }} \times d_{\text {in }}dout ​×din ​ parameters, while the low-rank approximation introduces only r×(din +dout )r \times\left(d_{\text {in }}+d_{\text {out }}\right)r×(din ​+dout ​) parameters. For small values of rrr, this can lead to significant savings in both storage and computation.

LoRA for T2I personalization

To apply LoRA to our pretrained T2I model, we inject trainable parameters into the diffusion model and update only those parameters during finetuning to learn the new identity. This method requires training of only a fraction of the model's parameters, which is much faster and more memory-efficient.

Image represents a system for generating images from text descriptions.  At the top, a light orange box contains four vertical, pinkish-red rectangles labeled as 'Trainable LoR...' and connected via downward arrows to four locked white rectangles labeled as 'Frozen...'.  Curved arrows indicate that 'Trainable LoR...' components receive input, while the locked components receive input labeled 'Frozen...'. These components are connected to a larger, light orange box labeled 'Diffusion Model'.  The 'Diffusion Model' outputs to an unlabeled white box, which calculates a 'loss' compared to a 'Real image of...' (another unlabeled white box).  Below the 'Diffusion Model' is a white box labeled 'Text Encoder,' which receives input from a box labeled 'A photo of [V] person' and feeds upward into the 'Diffusion Model'.  The overall flow is that the 'Text Encoder' processes the input photo, the 'Diffusion Model' uses this information along with the outputs from the 'Trainable LoR...' and 'Frozen...' components to generate an image, and the loss is calculated by comparing the generated image to a real image.
Figure 10: LoRA method injecting and learning new parameters in the diffusion model
Pros:
  • Preserves original model capabilities: LoRA preserves the T2I’s capabilities by freezing the original model parameters.
  • Reduces memory and computational needs: LoRA updates only a small fraction of the model's parameters, making it more efficient than DreamBooth.
  • Minimizes storage requirements: Since the original model remains unchanged, only the LoRA layers are stored. This typically means just a few megabytes per personalized model, which is cost-efficient and scalable.
Cons:
  • Less effective learning: LoRA is less effective than DreamBooth because it finetunes only a small number of parameters, thus limiting its capacity to learn the new subject.
  • Slight increase in inference time: LoRA slightly increases inference time due to additional parameters and computations. However, this is often negligible compared to the overall benefits of reduced storage requirements and faster adaptation times.

Table 1 provides a comparison of the three tuning-based personalization methods.

Textual InversionLoRADreamBooth
Learning effectivenessLowModerateHigh
Required storageLowModerateHigh
Required training resourcesLowModerateHigh
Maintaining the original model’s capabilitiesYesYesNo

Table 1: Comparison of popular tuning-based personalization methods

Which method is more suitable for headshot generation?

The suitability of these methods depends on the use case and the system requirements. For headshot generation, we choose DreamBooth for three main reasons:

  • Better identity preservation: DreamBooth is most effective at preserving details of the subject, leading to better identity preservation.
  • Acceptable training time: According to [5], it takes around 15 minutes to finetune a diffusion model using DreamBooth. This training time is acceptable given that we are required to share the generated images with the user within an hour.
  • No need for storage: We don’t need to save personalized models after generating the headshots, so storage concerns with the DreamBooth approach are not relevant.

Data Preparation

The number of images needed varies depending on the method. Tuning-free methods generally require just one image, whereas tuning-based methods such as DreamBooth need around 10–20 images.

Since we are using DreamBooth, users are asked to upload 10–20 images. These images may come in different resolutions and aspect ratios. To prepare them for training, we follow these steps:

  • Image resizing
  • Image augmentation
  • Generic face data addition
Image represents a data processing pipeline for user-uploaded images.  On the left, a collection of variously sized and colored rectangular boxes labeled 'User-uploaded images' depicts the initial input images.  These images flow rightward, through a series of three processing blocks. The first two blocks, labeled 'Image...', likely represent image preprocessing steps (e.g., resizing, format conversion).  The third block, 'Generic...', suggests a more general processing stage, perhaps feature extraction or transformation.  An upward arrow connects this block to a cylindrical database labeled 'Generic...', indicating that processed data is stored. Finally, a rightward arrow from the 'Generic...' processing block leads to a stack of similar-sized, light orange rectangular boxes labeled 'Prepared images,' representing the final output—a collection of processed images ready for further use.  The entire diagram illustrates a sequential flow of data from raw user images through processing stages to a database and finally to a set of prepared images.
Figure 11: Preparing data for training

Image resizing

Diffusion models typically require fixed input dimensions, but user-uploaded images often vary in dimensions. We resize the images to uniform dimensions suitable for the diffusion model.

Image augmentation

T2I models require lots of images to learn concepts such as objects, identities, and scenes. However, for personalization, we often lack a large dataset. We use image augmentation techniques such as mirroring, slight rotations, and scaling to artificially expand the dataset. This step is essential when only a small number of images is available for training.

Generic face data addition

Training only on the provided images may cause the model to overfit to a specific identity and forget previously learned knowledge. To prevent this, we combine user-uploaded images with a larger, generic dataset of faces. We generate these images using a pretrained diffusion model with prompts such as "an image of a person."

Model Development

Architecture

The DreamBooth method finetunes a pretrained diffusion model. We use a model with a U-Net architecture, pretrained to output 1024x1024 images, similar to what we covered in Chapter 9. The architecture remains unchanged: a series of downsampling blocks followed by a series of upsampling blocks.

Training

To finetune a pretrained diffusion model, we follow the same process as training a diffusion model from scratch:

  • Noise addition: Noise is added to an image based on a randomly selected timestep.
  • Conditioning signals preparation: Separate encoders prepare the image caption and timestep as conditioning signals for the model to predict noise.
  • Noise prediction: The model predicts the noise to be removed from the noisy image using the conditioning signals.

Training data

The training data consists of user-uploaded images and generic face images added during data preparation. User-uploaded images are labeled as "An image of a [V] person," while generic face images are labeled as "An image of a person."

ML objective and loss function

The key challenge in personalization is to ensure the model can generate both general categories (e.g., human faces) and specific instances within those categories (e.g., a unique individual). To address this, we use two loss functions:

  • Reconstruction loss
  • Class-specific prior preservation loss
Reconstruction loss

This loss function measures the differences between the reconstructed image and the actual images of the specific subject. It helps the model preserve the subject's identity.

Class-specific prior preservation loss

This loss function measures the difference between the generated images and actual images of generic faces. It ensures the model maintains the characteristics of the human class and avoids overfitting to specific identities.

Overall loss

The overall loss function is a weighted combination of the reconstruction loss and the class-specific prior preservation loss. The formula for the overall loss can be expressed as:

α\alphaα and β\betaβ are hyperparameters that control the trade-off between maintaining a specific identity and preserving human characteristics. The ML objective is to minimize the overall loss, which allows the model to generate images of unique identities while retaining its ability to produce generic human face images.

Image represents a system for generating images using a diffusion model.  A user uploads an image ('Uploadin...') which is labeled as 'Subject...'.  Simultaneously, a pretrained diffusion model ('Pretrained...') receives general images ('General...') labeled as 'Generic...'. Both the user-uploaded 'Subject...' images and the 'Generic...' images are fed as input ('A photo of...') to a central 'Diffusion Model'.  The model processes these inputs and generates two sets of output images: one set ('Generated...') derived from the user's input, and another ('Generated...') derived from the general input.  Dashed red lines indicate feedback loops:  'Reconstruction loss' represents a feedback mechanism influencing the model's training based on the generated images from the 'Subject...' input, while 'Class-specific pri...' suggests a feedback loop adjusting the model based on the generated images from the 'Generic...' input.  The overall flow depicts a system where user-specific images are combined with general data to refine a diffusion model for image generation.
Figure 12: Overall loss calculation

Sampling

The sampling process for headshot generation is similar to the T2I generation discussed in Chapter 9, as both use diffusion models. However, a key difference lies in how we provide text prompts. In Chapter 9, the user provided the text prompt. For example, a user might input "a cat sitting on a chair," and the diffusion model would generate an image reflecting that text.

In headshot generation, the users don't provide prompts. Instead, we create a set of hand-engineered prompts. These prompts represent various professional settings and include the identifier used during training to ensure the generated images reflect the user's identity. Some examples include:

  • "A professional headshot of [V] smiling in front of a plain white background."
  • "A close-up of [V] with a neutral expression, wearing formal attire."
  • "A headshot of [V] with soft lighting, looking slightly to the left."
  • "A profile shot of [V] against a blurred outdoor background."
  • "A professional headshot of [V] wearing a business suit, with a confident expression."

After creating the prompts, we sample one image per prompt from the diffusion model. We follow the standard diffusion process sampling steps:

  • Generate initial random noise.
  • Iteratively denoise the input through multiple steps, using Classifier-free guidance (CFG) [8] during each step to reduce noise and refine image details. To review CFG, refer to [8] or Chapter 9.
Image represents a simplified diagram of a denoising diffusion process.  It begins with a rectangular box labeled 'Random Noise...', representing the initial input of random noise data.  An arrow points from this box to a square image depicting a noisy, multicolored texture labeled '$x_{999...}$, indicating the initial noisy state of the data. This noisy image is then fed into a rectangular box labeled 'Diffusion...', representing the first step of the diffusion process.  A dotted arrow then connects this box to another identical 'Diffusion...' box, suggesting multiple iterations of the diffusion process.  Finally, an arrow leads from the last 'Diffusion...' box to an empty white square labeled '$x_{0}$', representing the denoised output after multiple diffusion steps. Below the first and second diffusion boxes are labels 'A close-up of [V] with...' indicating that these boxes represent a process involving a variable V, likely a model or function used in the diffusion steps.  The arrows indicate the flow of data through the process, transforming random noise into a denoised output.
Figure 13: Sampling a headshot image

Evaluation

Offline evaluation metrics

It is important to evaluate personalized diffusion models to ensure our model is capable of preserving the user’s identity in the generated images. We assess the performance of a personalized diffusion model by focusing on three main aspects:

  • Text alignment
  • Image quality
  • Image alignment

Text alignment

Text alignment refers to how closely generated images match text prompts. A common metric for measuring this is the CLIPScore [9], which ensures the images are not only high quality but also relevant to the input text.

Image quality

As we explored in previous chapters, we employ common metrics such as FID [10] and Inception score [11] to measure the quality of the generated images.

Image alignment

Image alignment, particularly relevant to personalized text-to-image models, refers to assessing the visual similarity between generated images and the subject of interest. For instance, if the model is tasked with generating an image of a specific backpack, image alignment measures how closely the generated image resembles that backpack.

Commonly used metrics for measuring the visual similarity between the generated and original subject are:

  • CLIP score
  • DINO score
  • Facial similarity score
CLIP score

CLIP model [12] uses two encoders—one for images and one for text. These encoders are trained to ensure that the image and text embeddings of a relevant image–text pair are close in the embedding space.

Image represents a system for comparing generated and real images using a CLIP (Contrastive Language–Image Pre-training) model.  A light-blue box labeled 'Generated i...' represents a generated image, and an orange box labeled 'Real image' represents a real image. Both are fed as input into a dashed-line box labeled 'CLIP Model,' which contains a light-grey box labeled 'Text...' representing text input (likely a prompt or description) and a light-green box labeled 'Image...' representing the image input (either generated or real).  The CLIP model processes both the text and the image inputs separately. The outputs of the CLIP model for both the generated and real images are then fed into separate horizontal boxes representing feature vectors. A double-headed arrow connects these feature vectors, labeled 'Similarity,' indicating a comparison process that calculates the similarity between the feature vectors of the generated and real images.  The overall system aims to quantify the similarity between a generated image and a real image based on a textual description, using the CLIP model to embed both images and text into a common feature space.
Figure 14: Image alignment calculation with CLIP

To measure image alignment using CLIP, we discard the text encoder and use the image encoder to generate embeddings for both the generated and real images. We then calculate the cosine similarity between these embeddings to assess their similarity. Higher scores indicate that the personalized diffusion model creates images that are more visually similar to real images.

DINO score

DINO [13] is a self-supervised learning method developed by Meta. DINO learns visual representations of images without the need for labeled data. In particular, it uses a method called contrastive learning [14], whereby the model learns to distinguish between similar and dissimilar images by organizing them in an embedding space—similar images are placed closer together, and dissimilar ones are positioned farther apart.

DINO, along with its more recent variations like DINOv2 [15], is particularly good at capturing similarities between images because it is trained to recognize subtle differences. This makes DINO particularly effective for measuring image alignment. By comparing the embeddings of a generated image with a real one, DINO can evaluate how well the generated image matches the real one.

Image represents a system for comparing a generated image and a real image using a DINOv2 model.  A light-blue square labeled 'Generated i...' represents the input of a generated image. A light-orange square labeled 'Real image' represents the input of a real image. Both images are fed as input into a light-green box labeled 'DINOv2,' which presumably extracts image features. The DINOv2 output is then fed into two separate rectangular boxes representing feature vectors; one for the generated image and one for the real image.  A bidirectional arrow connects these two feature vector boxes, labeled 'Similarity,' indicating a comparison process that calculates the similarity between the feature vectors derived from the generated and real images.  The flow of information is unidirectional from the input images to DINOv2 and then to the feature vector representations, while the similarity comparison happens between the feature vectors.
Figure 15: Image alignment calculation with DINOv2 [15]
DINO versus CLIP

DINO is preferred for comparing images because it is trained to capture detailed visual features. For example, two images, one with a yellow jacket and another with a red jacket, might have a low DINO score due to the color difference. On the other hand, CLIP is better for comparing images with text, as it is trained to match descriptions with visuals. The same images with different jacket colors might have a high CLIP score if both reflect a person wearing a jacket.

Facial similarity score

While CLIP and DINO measure visual similarity between generated and real images, they aren't designed to assess identity preservation. For example, two face images might show different individuals, but CLIP and DINO could still give a high similarity score. To address this, we use a face recognition model to compare generated and real images. These models specialize in identifying and measuring facial similarity, which is a crucial requirement in a personalized headshot generation system.

Combining DINO, CLIP, and facial similarity scores provides a comprehensive evaluation of image alignment in the personalized diffusion model.

Online evaluation metrics

Online evaluation is crucial in headshot generation. It measures user satisfaction directly, which is vital when users pay for the service, as higher satisfaction often leads to increased revenue. We focus on two primary metrics:

  • User feedback: This metric directly reflects user satisfaction. After receiving their generated headshots, users rate their satisfaction on a scale from 1 to 5. High ratings indicate that the headshots meet or exceed expectations, while lower scores highlight improvements are needed.
  • Conversion rate to paid service: This metric measures the percentage of users who move from showing interest to becoming new paying customers. It is calculated by dividing the number of new paying customers by the total number of users who engaged with the service—such as visiting the website, signing up for a trial, or making inquiries—within a specific time period.

Overall ML System Design

Generating professional headshots requires more than just a diffusion model. In this section, we examine three key pipelines:

  • Data pipeline
  • Training pipeline
  • Inference pipeline

Data pipeline

This pipeline has two responsibilities:

  • Preparing images with the subject of interest
  • Preparing images of generic human faces
Image represents a system for preparing user-uploaded images for a machine learning model.  A user uploads multiple images (represented by differently colored rectangles within a larger rectangle labeled 'User-uploaded images'). These images are then processed by a 'Quality assessors' module depicted as a smartphone with functions like 'Face Detect...', 'Face Recogn...', 'Facial Expr...', 'Blur...', and 'Quality...'.  The output of this module is a set of 'Remaining...' images (colored rectangles) that pass the quality checks.  These images are then labeled 'Data...' and passed to a data preparation stage, resulting in a stack of 'Prepared...' images (orange rectangles). If the 'Quality assessors' module determines that more images are needed ('More...' decision diamond), a request is sent back to the user.  Images that fail the quality checks are discarded.  Finally, the 'Prepared...' images are combined with data from a 'Pretrained...' model (cloud shape) to complete the preparation process, resulting in a final stack of 'Prepared...' images (light blue rectangles).  The entire process is depicted as a flow chart with arrows indicating the direction of data flow between the different components.
Figure 16: Data pipeline components

Preparing images with the subject of interest

This process evaluates user-uploaded images to ensure they meet predefined standards and prepares them for training.

Specifically, it verifies that the images are diverse and contain only a single object of interest: the user's face. To achieve this, we use various heuristics and ML models to analyze the images, checking factors such as clarity, diverse angles, expressions, and the presence of the user's face. If any images fail to meet these criteria, they are rejected, and the user is asked to upload more. This ensures that only high-quality images are used to finetune the diffusion model.

Preparing images of generic human faces

This step involves preparing images with generic faces to prevent the model from overfitting to the subject of interest. We use the pretrained T2I model to generate these images with prompts like “a person sitting on a chair.”

Training pipeline

This pipeline is responsible for personalizing the pretrained diffusion model.

Image represents a system for creating personalized models.  On the left, a set of 'Prepared images' is shown, divided into two stacks of light orange and light blue squares, each representing a collection of images.  An arrow indicates these prepared images are input into a 'Model Trainer' (a light green rectangle).  The Model Trainer also receives input from a 'Pretrained...' (light gray cloud), suggesting a pre-existing model is used as a base.  The output of the Model Trainer is a 'Personalized...' (light yellow cloud), implying the process generates a customized model based on the input images and the pretrained model.  The arrows depict the flow of data: prepared images and the pretrained model are fed into the Model Trainer, which then produces a personalized model.
Figure 17: Finetuning a pretrained diffusion model

Inference pipeline

The inference pipeline is responsible for generating the headshots of the user using a personalized T2I model. Three main components in the inference pipeline are:

  • Image generator
  • Quality assessment service
  • Uploader service
Image represents a system workflow for generating and uploading personalized images.  A user initiates the process.  A hand-engineered text prompt,  'A professional headshot of [V] smiling in f...', is input, feeding into a 'Image...' processing block (light green). This block receives further input from a 'Personalized...' cloud service (yellow), suggesting that personalization parameters are fetched from there. The generated image then proceeds to a 'Quality Asses...' block (light red), which determines if the image meets quality standards.  A decision diamond ('Meets...') follows, routing images meeting the criteria to an 'Uploader...' block (light purple) for user upload, while images failing quality checks loop back to the 'Image...' block for regeneration using a different diffusion model ('Re-generate with a di...').  The entire process is visualized as a flowchart, showing the sequential steps and decision points involved in creating and delivering a personalized image to the user.
Figure 18: Inference pipeline components

Image generator

The image generator utilizes the personalized T2I model and hand-engineered text prompts to generate one image per prompt.

Quality assessment service

This service ensures the generated images meet identity preservation standards. This service uses a pretrained face recognition model to compare the generated headshot with the user's real images. If the generated image fails to preserve the user's identity, the service rejects it and requests that the image generator produce a new image using the same text prompt but with a different initial noise.

Uploader service

The uploader service manages the delivery of generated images to the user. It uploads the images to cloud storage so users can download their headshots.

Other Talking Points

If there is extra time at the end of the interview, here are some additional talking points:

  • Preventing catastrophic forgetting during the finetuning [16].
  • The details of choosing a rare token for the new subject, and its importance [5].
  • Details of class-specific prior preservation loss [5].
  • Addressing the issue of reduced output diversity after finetuning [5].
  • Supporting multiple sizes and aspect ratios in generated images [17].
  • Details of tuning-free methods such as Meta’s Imagine Yourself [1].
  • Mitigating the risks and ethical concerns around deepfake generation and detection [18].
  • ML techniques to handle personally identifiable information (PII) securely while ensuring data privacy [19][20].

Summary

Image represents a mind map summarizing key aspects of a Generative AI system design interview.  A central 'Summary' box branches into seven main colored categories:  Clarifying requirements (light orange) and Specifying Input and output (light blue) focus on initial project definition, including framing the problem as a Machine Learning (ML) task and choosing between tuning-free (e.g., Textual Inversion) or tuning-based (e.g., DreamBooth, LoRA) approaches. Data preparation (purple) details image resizing and augmentation, including generic face data addition. Model development (gold) covers architecture (U-Net), training (with reconstruction, class-specific prior preservation losses), and sampling. Evaluation (salmon) distinguishes between offline metrics (text alignment, image quality, CLIPScore, Inception score, FID) and online metrics (image alignment, user feedback, conversion rate). Overall system components (teal) outlines the data, training, and inference pipelines, along with the image generator, quality assessment service, and uploader service. Finally, Other talking points (light peach) suggests additional discussion areas.  Each branch further subdivides into more specific details, creating a hierarchical structure illustrating the interconnectedness of various design considerations.

Reference Material

[1] Imagine yourself: Tuning-Free Personalized Image Generation. https://ai.meta.com/research/publications/imagine-yourself-tuning-free-personalized-image-generation/. [2] MoA: Mixture-of-Attention for Subject-Context Disentanglement in Personalized Image Generation. https://arxiv.org/abs/2404.11565. [3] InstantID: Zero-shot Identity-Preserving Generation in Seconds. https://arxiv.org/abs/2401.07519. [4] An Image is Worth One Word: Personalizing Text-to-Image Generation using Textual Inversion. https://textual-inversion.github.io/. [5] DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation. https://arxiv.org/abs/2208.12242. [6] LoRA: Low-Rank Adaptation of Large Language Models. https://arxiv.org/abs/2106.09685. [7] Language Models are Few-Shot Learners. https://arxiv.org/abs/2005.14165. [8] Classifier-Free Diffusion Guidance. https://arxiv.org/abs/2207.12598. [9] CLIPScore: A Reference-free Evaluation Metric for Image Captioning. https://arxiv.org/abs/2104.08718. [10] FID calculation. https://en.wikipedia.org/wiki/Fr%C3%A9chet_inception_distance. [11] Inception score. https://en.wikipedia.org/wiki/Inception_score. [12] Learning Transferable Visual Models From Natural Language Supervision. https://arxiv.org/abs/2103.00020. [13] Emerging Properties in Self-Supervised Vision Transformers. https://arxiv.org/abs/2104.14294. [14] Contrastive Representation Learning. https://lilianweng.github.io/posts/2021-05-31-contrastive/. [15] DINOv2: Learning Robust Visual Features without Supervision. https://arxiv.org/abs/2304.07193. [16] An Empirical Study of Catastrophic Forgetting in Large Language Models During Continual Fine-tuning. https://arxiv.org/abs/2308.08747. [17] SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis. https://arxiv.org/abs/2307.01952. [18] Deepfakes, Misinformation, and Disinformation in the Era of Frontier AI, Generative AI, and Large AI Models. https://arxiv.org/abs/2311.17394. [19] Privacy-Preserving Personal Identifiable Information (PII) Label Detection Using Machine Learning. https://ieeexplore.ieee.org/document/10307924. [20] Does fine-tuning GPT-3 with the OpenAI API leak personally-identifiable information? https://arxiv.org/abs/2307.16382.

Chapter 11

Text-to-Video Generation

~23 min read

Introduction

Text-to-video generation is a key application of generative AI, enabling the generation of videos from textual descriptions. This chapter delves into the crucial components required to build a text-to-video model.

Image represents a video thumbnail showing a stylish woman walking down a rain-slicked Tokyo street at night.  The woman, wearing a black leather jacket and a long burgundy dress, is centrally positioned and carries a black handbag.  She is walking towards the viewer. The background features a bustling Tokyo street scene, filled with numerous brightly lit neon signs in Japanese script, reflecting in the wet pavement.  Buildings line both sides of the street, showcasing various advertisements and signage.  Other pedestrians are visible in the background, though somewhat blurred.  A play button icon is superimposed in the center of the video thumbnail, indicating that the image is a still from a video.  Above the thumbnail, the text 'Prompt: A stylish woman walks down a Tokyo street filled with warm glowing neon a...' provides a textual description of the video's content.  The bottom of the image contains partially obscured text, reading 'Text is not...nnot display,' suggesting a technical limitation in displaying the full text.
Figure 1: An example of a generated video by OpenAI’s Sora model [1]

Clarifying Requirements

Here is a typical interaction between a candidate and an interviewer.

Candidate: What is the expected length of the generated videos? Interviewer: Let’s aim for five-second-long videos.

Candidate: What video resolution are we targeting? Interviewer: We should aim for high-definition quality to ensure the videos suit a wide range of modern platforms and devices. Let’s aim for 720p resolution.

Candidate: Is 24 frames per second (FPS) the desired rate for the generated video? Interviewer: Yes.

Candidate: What is the expected latency for generating a video? Interviewer: Video generation is computationally expensive. For the start, a few minutes of processing time will be acceptable. In future iterations, we will optimize for efficiency and speed.

Candidate: Should we focus on a specific video category? Interviewer: No, the system should generate videos across various genres and subjects.

Candidate: Should the system support multiple languages for text input, or are we starting with English only? Interviewer: Let's start with English.

Candidate: Should the generated videos include audio output? Interviewer: Let's focus on silent videos for now. Audio could be considered for an enhancement for future iterations, but it’s not a priority at this stage.

Candidate: What is the approximate size of our training data? Interviewer: We have a large video dataset, around 100 million diverse videos with captions. Some captions might be noisy or non-English.

Candidate: A common approach to building a text-to-video model is to extend a pretrained text-to-image model to handle videos. Do we have a pretrained text-to-image model? Interviewer: Yes, that is a fair assumption.

Candidate: Considering the high computational demands of video generation, what is our compute budget? Interviewer: Training a video generation system requires significant computational resources. We have over 6000 H100 GPUs [2] available for text-to-video training.

Candidate: Shall we ensure the system has safeguards to prevent generating offensive or harmful videos is crucial? Interviewer: Great point. Yes, we need to ensure our proposed system is safe for users.

Frame the Problem as an ML Task

This section frames the text-to-video generation problem as an ML task and highlights the necessary considerations beyond those used in Chapter 9 for text-to-image generation.

Specifying the system’s input and output

The input is a descriptive text outlining a scene, action, or narrative. The output is a five-second 720p (1280 x720) video that visually and temporally aligns with the given text prompt.

For example, given a text input like "A dog playing fetch in a park on a sunny day," the system should generate a video depicting this scene, capturing the dog's movement, the park's environment, and the ambiance of a sunny day.

Image represents a simple data flow diagram illustrating a text-to-video generation process.  On the left, a text prompt, labeled 'A dog playing fetch in...', is shown. This prompt serves as the input.  A black arrow points from the text prompt to a light orange, rounded-rectangle box labeled 'Text-to-Video...'. This box represents the core text-to-video generation model or system.  Another black arrow extends from the 'Text-to-Video...' box to a light blue rectangle labeled 'Generated video,' which contains a play button symbol (▷) indicating the output is a video.  The overall flow depicts the transformation of a textual description into a video using a text-to-video model.
Figure 2: Input and output of a text-to-video system

Choosing a suitable ML approach

Text-to-video generation is similar in nature to text-to-image generation. Both generate visuals from textual descriptions. Techniques such as autoregressive modeling and diffusion models that are popular in text-to-image generation are also effective for text-to-video generation. As we saw previously, diffusion models have demonstrated strong performance in producing detailed and realistic visuals. Therefore, we choose a diffusion model to develop our text-to-video generation system.

There is, however, a crucial difference between them. For video generation, the model must process and generate a sequence of frames rather than a single image. This significantly increases the computational load. For instance, generating a five-second video at 24 FPS means the model must produce 120 frames. A 512x512 image might take around 1 second to generate on a high-end GPU such as the NVIDIA’s H100, but scaling this to a five-second 720p video would require much more time, as each 720p frame has about 3.6 times more pixels. As a result, generating a five-second 720p video could take around seven minutes.

Image represents a diagram illustrating two separate generative AI processes.  The top process shows a 'Text prompt' feeding into a 'Text-to-Image...' box, which in turn outputs a single light-blue rectangle representing a generated image.  The bottom process depicts a 'Text prompt' inputting into a light-orange 'Text-to-Video...' box. This box outputs a light-blue rectangle containing a play symbol (▷), representing a generated video. This video is then further broken down into a stack of twelve light-blue rectangles, labeled as '120 frames,' indicating the individual frames composing the generated video.  Arrows clearly show the unidirectional flow of information from input (text prompt) to processing (Text-to-Image or Text-to-Video) to output (image or video frames).
Figure 3: Text-to-video generating a sequence of frames

To address the complexity and computational cost of video generation, we employ the popular latent diffusion model approach. This approach was first popularized by the Stable Diffusion paper [3] and later applied and used by most video generation models, such as OpenAI's Sora [1] and Meta’s Movie Gen [4]. Let’s explore this approach further.

Latent diffusion model (LDM)

The core idea behind LDM is to have a diffusion model operate in a lower-dimensional latent space rather than directly in the pixel space. The diffusion model learns to denoise these lower-dimensional latent representations rather than the original video pixels in the training dataset.

Image represents a video compression and prediction model.  On the left, a stack of light-blue rectangles labeled 'Original video' depicts a sequence of video frames. A thick arrow labeled 'Compression' points right, indicating a compression process transforming the original video frames into a stack of smaller, lavender-colored rectangles labeled 'Latent...'. These compressed frames then flow into a light-orange, rounded-rectangle box labeled 'Latent...', representing a latent space.  '+ noise' is added to this latent representation before it proceeds to the right via another arrow. The output on the far right is a stack of multicolored, noisy rectangles labeled 'Predicted...', representing the reconstructed video frames after passing through the latent space and adding noise. The entire process is described as occurring within a 'Latent space'.
Figure 4: Diffusion model operating in a lower-dimensional latent space

LDM relies primarily on a compression network to compress video pixels into a latent representation. Let’s examine the compression network in more detail.

Compression network

The compression network is a neural network that maps video pixels to a latent space. It takes raw video as input and outputs a compressed latent representation, reducing both its frame count (temporal dimension) and its resolution (spatial dimensions).

The compression network is usually based on a Variational Autoencoder (VAE) [5] model that is trained separately from the diffusion model. The VAE's visual encoder transforms the input video into a latent representation, while its visual decoder reconstructs the original video frames from this latent space.

Image represents a simplified model of a video compression and decompression system.  The process begins with an 'Original video' represented as a three-dimensional rectangular prism.  This video is fed into a 'Visual...' encoder (represented as a trapezoidal shape), which processes the video and outputs a compressed representation. This compressed data, labeled 'Latent...', is shown as a smaller cube.  The 'Latent...' data then passes through a 'Visual D...' decoder (another trapezoidal shape), which reconstructs the video. The final output is a 'Reconstructed video,' also depicted as a three-dimensional rectangular prism, similar in shape to the original but potentially with some loss of information due to compression.  Arrows indicate the unidirectional flow of data between each component.
Figure 5: Compression network consisting of visual encoder and decoder
How does LDM address computational complexity?

LDMs require less computing power than standard diffusions because processing compressed representations is cheaper than handling high-dimensional pixels. To understand the impact of this compression, let's walk through an example.

Imagine we need a video with 24 FPS, a duration of five seconds, and a resolution of 720p. This means 120 frames, each with 1280x720 pixels—a substantial amount of data to process. If we use a compression network similar to [4] that reduces both the temporal and spatial resolution by a factor of 8, the video’s spatial dimension becomes 160x90 pixels, and its temporal dimension shrinks to 15 frames.

Image represents a data processing pipeline.  A large, light-grey, three-dimensional rectangular block representing input data with dimensions 120 x 1280 x 720 is shown. A curved arrow indicates data flow from this block to a rectangular box labeled '110,592,000...', suggesting a count or size of the input data.  The input block then sends data via a straight arrow to a trapezoidal, light-green block labeled 'Visual...', likely representing a visual processing or transformation stage.  This visual processing stage outputs data to another light-grey, three-dimensional rectangular block with dimensions 15 x 160 x 90. Finally, a curved arrow connects this output block to a rectangular box labeled '216,000...', indicating the size or count of the processed data.  The overall diagram illustrates the transformation of a large dataset through a visual processing step, resulting in a smaller dataset.
Figure 6: Impact of compression on data volume

This compressed representation is 512 times smaller than its pixel-space equivalent, making LDM training 512 times more efficient. This efficiency results in faster generation times and reduced resource consumption, which is especially valuable when handling high-resolution video data.

How to generate a video using a trained LDM

To generate a video using a trained LDM, we start with pure noise in the latent space. The LDM gradually refines it into a denoised latent representation. The visual decoder then converts this latent representation back into pixel space to produce the final video.

Image represents a video generation system pipeline.  It begins with a 'Random...' block, representing a source of random noise, which feeds into a sequence of three 'Latent...' blocks, each representing a latent space.  Each 'Latent...' block receives input from a corresponding 'Text Enc...' block below, labeled as 'Text Enc...', which presumably encodes text descriptions like 'a dog walking...'.  Arrows indicate the flow of information, showing that the output of each 'Latent...' block feeds into the next, suggesting a sequential or iterative process.  After the third 'Latent...' block, the output flows into a 'Denoised...' block, likely representing a denoising step. This is followed by a 'Visual De...' block (likely a visual decoder), which processes the denoised latent representation. Finally, the output of the 'Visual De...' block is a 'Generated video' block, representing the final generated video output.  The overall architecture suggests a text-to-video generation model using a latent space representation and a sequential refinement process.
Figure 7: Video generation using a trained LDM

For this chapter, we choose an LDM approach to develop our text-to-video generation system because it's efficient and it reduces computational load. To learn more about LDM, refer to [6].

Data Preparation

The dataset for text-to-video generation includes 100 million pairs of textual descriptions and their corresponding videos. These pairs cover various subjects and actions, allowing the model to learn from diverse videos. In this section, we prepare the videos and captions for training our LDM.

Video preparation

We focus on three key steps in preparing videos for training:

  • Filter inappropriate videos
  • Standardize videos
  • Precompute video representations in the latent space
Filter inappropriate videos

Large datasets often contain unwanted content. This step removes inappropriate videos to ensure the model learns only from high-quality ones. Common steps include:

  • Remove low-quality or short videos: We follow Movie Gen [4] and remove low-resolution, short, slow motion, or distorted videos with compression artifacts.
  • Remove duplicated videos (deduplication): We use a deduplication method such as [7] to eliminate identical videos. This ensures training data is diverse and the model will not be exposed to certain videos more than others.
  • Remove harmful videos: We use harm-detection models to identify and remove videos with explicit content. This step is vital to ensure our text-to-video model will not generate harmful videos.
Standardize videos
  • Adjust video length: We split longer videos into five-second clips to ensure training data consists only of videos of the same length.
  • Standardize frame rate: We re-encode the videos with higher frame rates to 24FPS to ensure all the videos have the same frame rates.
  • Adjust video dimensions: We resize and crop videos to a standard size, for example, 1280x720 pixels.
Precompute video representations in the latent space

As the LDM operates in the latent space, it needs only latent representations as input. Thus, each training iteration normally requires the following steps:

  • Extract frames from a video in the training data.
  • Pass these frames through a pretrained compression network to obtain latent representations.
  • Use the latent representations to continue training the diffusion model.

However, those steps are inefficient. Extracting frames and compressing them for millions of videos each time we train a new model slows diffusion training. Computing latent representations on the fly is resource-intensive and time-consuming.

To optimize the process, we precompute the latent representations for all videos and cache them in storage. During training, the diffusion model directly accesses the precomputed latent representations without waiting for frame extraction or compression processes. This approach significantly speeds up the diffusion training process, while keeping the storage cost manageable. Let’s run a quick calculation to understand the storage need.

Back-of-the-envelope calculation: Assume that each video frame, when compressed into a latent representation, reduces in size by a factor of 512. So, if a video with 1,000 frames takes up about 1,000 MB, its latent representation would only take around 2 MB. If we cache latent representations for 100 million videos, the total storage required would be around 200 TB. Given modern storage capabilities, this is relatively manageable, especially compared to the significant time saved during training.

Image represents a data processing pipeline for video data, likely in the context of training a machine learning model.  The pipeline begins with 'Original training video...' depicted as a collection of variously colored rectangular boxes, each containing a play button symbol (▷), representing individual video segments. These segments are then passed through a 'Filtering' stage, resulting in a smaller set of similarly symbolized rectangular boxes in a light blue rectangle.  This filtered data is then 'Standardized...', producing another set of video segments (represented by colored rectangles with play buttons) arranged vertically in a light blue rectangle.  Finally, the standardized data undergoes 'Precomputing...', transforming the data into a stack of smaller, colored cubic blocks, each also implying a video segment.  These precomputed blocks are then written to a 'Storage' database, represented by a large, pale yellow cylinder.  Arrows indicate the flow of data between each stage, showing the transformation and reduction of data as it progresses through the pipeline.
Figure 8: Video data preparation

Caption preparation

It's important to have high-quality, consistent captions. Some captions are likely to be missing or irrelevant. Common steps for preparing captions are:

  • Handle missing or non-English captions: For videos without captions or with captions in another language, we use models such as LLaMa3-Video [8] or LLaVA [9] to automatically generate descriptive captions.
  • Re-captioning: We improve existing captions using pretrained video captioning models such as LLaMa3-Video or LLaVA to generate longer, more detailed versions. The Sora team [1] has shown that this process is essential for enhancing quality and text alignment.
  • Precomputing caption embeddings: Diffusion model training requires caption embeddings for conditioning. We use the text encoder to precompute caption embeddings, speeding up LDM training.
Image represents a tabular structure illustrating a dataset for a video captioning model.  The table has three columns: 'ID', 'Video latents', and 'Caption embeddings'. The 'ID' column lists sequential identifiers for each data entry, ranging from 1 to N, where N represents an unspecified number of entries. The 'Video latents' column visually depicts each video's latent representation as a three-dimensional rectangular box, implying a compact, vectorized encoding of the video's visual content.  The 'Caption embeddings' column shows each video's corresponding caption represented as a set of vertical rectangular blocks, each block likely representing a word or a segment of the caption's embedding vector. The number of blocks varies across rows, suggesting captions of different lengths.  The ellipsis (...) indicates that the table continues beyond the shown rows, implying a larger dataset with more video-caption pairs.  There is no explicit connection shown between the 'Video latents' and 'Caption embeddings' columns, but the implicit relationship is that each video's latent representation (box) is paired with its corresponding caption embedding (set of blocks) sharing the same ID.
Figure 9: Prepared video–caption training data for training

Model Development

Architecture

When selecting the architecture for a text-to-video diffusion model, we have two main options: U-Net and DiT. We’ll examine each and determine the additional layers required to extend them to handle videos.

U-Net for videos

Let's briefly review the U-Net architecture before extending it to process videos. As we explored in Chapter 9, the U-Net architecture consists of a series of downsampling blocks followed by a series of upsampling blocks. Each downsampling block includes 2D convolutions to process and update image features and a cross-attention layer to update features by attending to the text prompt.

Image represents a U-Net architecture for image processing.  The input is a 64x64 image represented as a gray 3D block. This image is fed into a series of downsampling blocks (labeled 'D', colored light red), each consisting of a Conv2D layer, Batch Normalization, ReLU activation, Max Pooling, and a Cross-Attention mechanism (as indicated by the top dashed box).  These 'D' blocks sequentially reduce the spatial dimensions of the input.  The output of the final downsampling block then flows into a series of upsampling blocks (labeled 'U', colored light green), each mirroring the structure of the downsampling blocks but using transposed convolutions instead of standard convolutions (as shown in the top right dashed box).  These 'U' blocks increase the spatial dimensions, eventually reconstructing the image to the original 64x64 size. The 'D' and 'U' blocks are connected, forming the characteristic U-shape of the U-Net. The entire process is labeled 'U-Net,' with 'Downsampling b...' and 'Upsampling blo...' describing the respective block sequences. The final output is a 64x64 'Predicted...' image, represented as a gray 3D block.
Figure 10: U-Net architecture for image generation

However, these layers mainly focus on capturing the relationships between pixels within a single image. This design presents a challenge for videos, where maintaining temporal consistency is crucial for smooth motion and continuity across frames. Current layers, however, operate spatially within individual frames rather than across frames.

To address this shortcoming, we modify the U-Net architecture to understand relationships across frames. In particular, we inject two commonly used temporal layers:

  • Temporal attention
  • Temporal convolution
Image represents a diagram illustrating a downsampling and upsampling process within a likely neural network architecture.  The diagram is divided into two halves, representing these two processes.  The left half, labeled 'Downsampling...', shows a sequence of operations starting with a 'Temporal Conv' layer, whose output feeds into a horizontally arranged block containing a 'Conv2D', 'Batch Norm2D', 'ReLU', and 'MaxPool2D' layer.  A 'Temporal Attention' layer's output is also fed into this block, likely through concatenation or addition. The right half, labeled 'Upsampling...', mirrors this structure but in reverse. It begins with a 'Temporal Conv' layer feeding into a block containing 'ConvTranspose2D', 'Batch Norm2D', 'ReLU', and 'Cross-attention' layers.  A 'Temporal Attention' layer's output is also fed into this block.  The arrangement suggests a U-Net-like architecture where the downsampling path reduces spatial dimensions, followed by the upsampling path to reconstruct the original dimensions, with cross-attention mechanisms potentially enabling information flow between different levels of the network.
Figure 11: Injecting temporal layers into the U-Net’s downsampling and upsampling blocks

Let’s briefly review each layer.

Temporal attention: Temporal attention utilizes the attention mechanism across frames. Each feature is updated by attending to relevant features across other frames. Figure 12 shows how a certain feature in frame 2 is updated by attending to the features in the other frames.

Image represents a sequence of four frames, labeled 'Frame 1,' 'Frame 2,' 'Frame 3,' and 'Frame 4,' enclosed within a dashed-line rectangle. Each frame is depicted as a light green square containing a smaller, empty black square.  Curved arrows originate from the inner black squares of Frame 1 and Frame 2, pointing towards the inner black squares of Frame 2, Frame 3, and Frame 4.  Specifically, the inner square in Frame 1 has one arrow pointing to the inner square in Frame 2. The inner square in Frame 2 has two arrows, one pointing to the inner square in Frame 3 and another to the inner square in Frame 4.  The arrows suggest a flow of information or a dependency between the frames, possibly indicating a sequential process or data transfer.  The dashed line surrounding all frames suggests a boundary or a system encompassing the entire sequence.  An ellipsis ('...') after Frame 4 indicates that the sequence continues beyond the displayed frames.
Figure 12: Temporal attention updating features by looking across frames
  • Temporal convolution: Temporal convolution refers to applying a convolution operator to a 3D segment of data, to capture the temporal dimension. Figure 13 illustrates 2D and 3D temporal convolutions.
Image represents a comparison of 3D and 2D convolutions.  The left side depicts a 3D convolution illustrated as a larger, light-grey rectangular prism representing the input volume.  Within this larger prism, a smaller, salmon-pink rectangular prism labeled '3D...' represents the 3D convolutional kernel or filter. The text '3D convolution' is positioned below this illustration.  The right side mirrors this structure but in 2D: a larger, light-grey square represents the input image, and a smaller, salmon-pink square labeled '2D...' represents the 2D convolutional kernel. The text '2D convolution' is placed below this 2D representation.  Both diagrams visually demonstrate how a smaller kernel (either 3D or 2D) slides across a larger input volume or image to perform the convolution operation. The ellipses (...) in the labels suggest that the kernel's dimensions are not explicitly specified but are implied by the visual representation of the kernel's size relative to the input.
Figure 13: 2D convolution vs. 3D convolutions

In summary, to extend a U-Net architecture to process videos, we can interleave temporal convolution and temporal attention layers in each downsampling and upsampling block. These layers allow the U-Net architecture to model the motion in input videos and generate a sequence of frames that are temporally consistent. To learn more about how these layers can be interleaved, refer to [10].

DiT for videos

Unlike U-Net, which is based mainly on convolutions, DiT relies primarily on the Transformer architecture. As shown in Figure 14, DiT consists of four main components:

  • Patchify
  • Positional encoding
  • Transformer
  • Unpatchify
Image represents a denoising model architecture.  A 'Noisy image' box at the bottom feeds into a larger box containing four stacked processing layers: 'Patchify' (light green), 'Positional Encoding' (light red), 'Transformer' (light orange), and 'Unpatchify' (light green).  These layers sequentially process the noisy image.  The 'Patchify' layer likely divides the image into smaller patches for processing.  'Positional Encoding' adds positional information to the patches. The core processing happens within the 'Transformer' layer, a neural network architecture known for handling sequential data. Finally, 'Unpatchify' recombines the processed patches into a complete image.  An arrow indicates data flow from the 'Noisy image' through these layers.  A separate box labeled 'Conditions...' is connected to the input of the 'Transformer' layer, suggesting conditional information influences the denoising process.  The output of the entire process is 'Predicted noise,' represented by a box at the top, indicating the model's prediction of the noise present in the input image.  An upward arrow shows the flow of this predicted noise from the 'Unpatchify' layer.
Figure 14: DiT components

Let’s examine each component and understand its purpose.

Patchify

This component converts the input to a sequence of embedding vectors. It first divides the input into smaller, fixed-size patches. Each patch is then flattened to form a sequence of vectors. The flattened patches are finally transformed into patch embeddings using a projection layer. This step is crucial to align the embedding size of each flattened patch with the Transformer's hidden size.

The patchify process is similar for both image and video inputs. For images, it divides the input into fixed-size 2D patches. For videos, the video is divided into 3D patches.

Image represents a comparison of image and video processing pipelines, both employing a 'Patchify' operation.  On the left, an image is processed.  The image is first divided into 9 patches (represented as vertical rectangles labeled 'Patch em... c' and numbered '9'), each of which is then individually processed by a 'Patchify' module. This module consists of three sequential steps: 'Projection,' 'Flatten,' and 'Divide,' represented as stacked horizontal rectangles within a larger box labeled 'Patchify.'  The output of the Patchify module for each patch is a smaller set of square blocks. On the right, a similar process is shown for a video. The video is first divided into 18 patches (also represented as vertical rectangles labeled 'Patch em... C' and numbered '18').  Each patch is then processed by a 'Patchify' module (identical in structure to the image's module) resulting in a larger, three-dimensional array of cubic blocks.  Arrows indicate the flow of data between stages, showing how the initial image or video is broken into patches, then processed by the Patchify module, resulting in a transformed representation of the input.
Figure 15: Patchify for image vs. video
Positional encoding

The positional encoding component produces an embedding for each position in the original sequence. These embeddings provide the Transformer with information about the location of each patch in the original input.

Image represents a comparison of data processing for image and video inputs within a system likely involving a transformer network.  The left side depicts image processing:  Nine rectangular blocks labeled '1' through '9' represent a 3x3 image. These blocks are grouped under a curved bracket labeled 'c' indicating channels, and the number '9' below signifies the total number of input features. An upward arrow connects this image representation to a light-red rectangular box labeled 'Positional E...', likely representing a positional encoding layer. The right side shows video processing:  A 3x3x2 cube (represented as a 3x3 grid of cubes, with the depth implied) labeled '1' through '6' (and implied further numbers) represents a video frame, with '18' below indicating the total number of input features.  Similarly, an upward arrow connects this video representation to a light-red rectangular box labeled 'Positional E...', indicating the same positional encoding layer is used for both image and video data.  The difference lies in the input dimensionality: a 2D array for images (9 features) and a 3D array for videos (18 features), both processed through the same positional encoding step.
Figure 16: 1D positional encoding for image vs. video

As we saw in Chapter 2, there are different ways to encode positions: Some methods use fixed positional encoding during training, while other methods make the positional encoding learnable. There are also different ways to assign positions to each patch. For example, we can give each patch a single number to show its place in a sequence or use 3D coordinates (2D for images) to show where each patch is in space and time.

Image represents a comparison of different positional encoding methods in a system, likely for a neural network.  The left side shows a 2D encoding where a 3x3 grid of data points, represented by numbers like '1,1', '1,2', etc., feeds into a positional encoding function denoted as  `$F(i, j)` (where `i` and `j` likely represent row and column indices). This function's output is shown as a rectangular box.  The right side shows a 1D encoding where a 3x3 grid is flattened into a 1D sequence (1, 2, 3, 4, 5, 6, 7, 8, 9) and fed into a positional encoding function `$F(i)` (where `i` is the index in the sequence).  The output is again represented by a rectangular box.  Below this, the same comparison is shown for 3D encoding, where a 3x3x3 cube of data points is first represented as a 3D structure and then flattened into a 1D sequence before being processed by `$F(i,j,k)` (for 3D) and `$F(i)` (for 1D) respectively, with outputs shown as rectangular boxes.  Arrows indicate the flow of information from the data representation to the positional encoding function.  The label 'Positional encoding...' indicates the overall theme of the diagram.
Figure 17: 1D, 2D, and 3D positional encoding

There is not one best way to do positional encoding. We often need to run experiments to find the approach that will be most effective for the data and task. In this chapter, we follow OpenSora [11] and use RoPE [12] positional encoding. To learn more about positional encoding in text-to-video models, refer to [4].

Transformer

The Transformer processes the sequence of embeddings and other conditioning signals, such as the text prompt, to predict noise for each patch.

Image represents a sequence-to-sequence model architecture, likely used for denoising or generation tasks.  The model begins with an 'Input sequence...' represented as multiple vertical blocks, each block symbolizing a vector or embedding. These input vectors feed into a 'Transformer' block, which is depicted as a peach-colored rectangle containing stacked layers: 'Normalization,' 'Feed Forward,' 'Cross-Attention' (labeled with 'Nx' indicating a parameter likely related to the number of attention heads), another 'Normalization' layer, and finally 'Multi-head...' (implying multi-head self-attention).  The output of the Transformer is then used to predict 'Predicted noise,' also represented as multiple vertical blocks.  Separately, a 'Conditioning signal...' feeds into an 'Encoder' block, which then sends its output to the input of the Transformer, allowing the model to condition its generation on external information.  Arrows indicate the flow of information between components, showing how the input sequence, conditioned by the encoder's output, is processed by the Transformer to generate the predicted noise sequence.
Figure 18: Transformer component
Unpatchify

Unpatchify converts the predicted noise vectors back to the original input dimensions. It includes a LayerNorm for normalization, a linear layer to adjust vector length, and a reshape operation to form the final output.

Image represents a comparison of two different architectures for a generative model, likely focused on noise prediction and image generation.  Both sides share a similar structure. At the bottom, labeled 'Noise vectors predicted...', are multiple vertical rectangular blocks representing input noise vectors; the ellipsis (...) indicates that more such vectors exist.  These vectors are fed upwards into a green block labeled 'Unpatchify,' which processes them. Above 'Unpatchify,' a stacked block contains three layers: 'Reshape,' 'Linear,' and 'LayerNorm,' sequentially processing the output of 'Unpatchify.' Finally, at the top, a shape labeled 'Predicted noi...' represents the predicted noise output; on the left, this is a square, while on the right, it's a three-dimensional rectangular prism, suggesting a difference in the dimensionality or representation of the predicted noise between the two architectures.  The arrows indicate the flow of information from the noise vectors through the processing layers to the final predicted noise output.  The difference between the left and right sides lies primarily in the shape of the final predicted noise output, implying a variation in the output's dimensionality or structure.
Figure 19: Unpatchify component

U-Net vs. DiT

Both U-Net and DiT architectures are proven to be effective for text-to-video generation. The U-Net architecture has been around for longer and has been extensively tested. Popular U-Net-based text-to-video models include Stable Video Diffusion [13] by Stability AI and EMU video [14] by Meta.

The DiT architecture is more recent and has shown great promise, with superior results. DiT performs better with increased data and computational power due to the scalable nature of Transformers. In addition, it has a flexible architecture, making it easier to adapt to videos and other input modalities. Meta’s Movie Gen and OpenAI’s Sora is a popular model based on the DiT architecture.

In this chapter, we follow Sora and choose the DiT architecture.

Training

Training a video diffusion model is very similar to training an image diffusion model. During training, we add noise to the original video by simulating the forward process and train the model to predict the added noise. The three concrete steps involved in one iteration of training are:

  • Noise addition: A timestep is randomly sampled to determine the level of noise addition. The sampled timestep is used to add noise to the input video.
  • Noise prediction: The DiT model receives the noisy video as input and predicts the added noise based on conditioning signals such as text prompt and the sampled timestep.
  • Loss calculation: The loss is measured by comparing the predicted noise to the actual noise.

To review diffusion training in more detail, refer to Chapter 9.

ML objective and loss function

The primary loss function is the reconstruction loss, calculated using the mean squared error (MSE) formula. This loss measures the difference between the predicted noise and the actual noise, encouraging the model to accurately predict the added noise. The ML objective is to minimize the reconstruction loss, leading to accurate video reconstruction.

Researchers have experimented with adding other loss functions to enhance text-to-video performance. To learn more, refer to [4].

Challenges in training video diffusion models

Training a DiT model for text-to-video generation involves several challenges and design decisions. This section explores two important challenges:

  • Lack of large-scale video–text data
  • Computational cost of high-resolution video generation
Lack of large-scale video–text training data

Training large models requires lots of data. As opposed to training text-to-image models, where a huge amount of image–text paired data is available, paired video–text data is scarce. This scarcity presents a challenge in training effective video generation models.

There are two common strategies for addressing the lack of large-scale data:

  • Train the DiT model on both image and video data: This strategy treats each image as a single-frame video, thus allowing the model to train on both image–text and video–text data.
  • Pretrain the DiT model on image data: This strategy first pretrains the DiT model on image–text pairs to leverage extensive image data and build a strong visual foundation. The pretrained model is then finetuned on video–text pairs for video generation.
Image represents two strategies for training a video generation model.  Strategy 1 shows a 'Training' block receiving input from two cylindrical database representations labeled 'Image-text pairs' and 'Video-text pai...'.  The output of the 'Training' block is an arrow pointing to a light green cloud labeled 'Video...', representing the generated video. Strategy 2 depicts a 'Pretraining' block taking input from a cylindrical database labeled 'Image-text pairs,' outputting to a light orange cloud labeled 'Image...', which then feeds into a 'Finetuning' block.  The 'Finetuning' block receives input from a second cylindrical database labeled 'Video-text pai...' and outputs to a light green cloud labeled 'Video...', representing the generated video.  Both strategies ultimately generate videos ('Video...') but utilize different training approaches: Strategy 1 trains directly on both image-text and video-text pairs, while Strategy 2 uses a two-stage process, first pretraining on image-text pairs and then finetuning on video-text pairs.
Figure 20: Two strategies to utilize image–text training data

Both strategies leverage hundreds of millions of image–text data in training, allowing the DiT model to learn from both images and videos. For simplicity, we choose the first strategy, as it requires only one stage of training. However, both strategies can be effective in practice.

Computational cost of high-resolution video generation

As discussed earlier, processing and generating videos is more expensive than images. This is primarily because videos generally contain hundreds of frames, making the process slower and more costly. Generating high-resolution videos, such as 720p or 1080p, adds to the challenge.

Here are a few common strategies to reduce the computational cost of training high-resolution video generation models:

  • Employ an LDM-based approach: Instead of training the DiT model directly in pixel space, we use a compression network to convert videos from pixel space into a lower-dimensional latent space. Training the diffusion model in this latent space reduces the computational load.
  • Precompute video representations: By precomputing video representations in the latent space before training, we avoid repetitive computations during training. Utilizing this cached data speeds up the training process.
  • Utilize a spatial super-resolution model: As proposed by Google’s “Imagen video” [15], we use a separately trained model to upscale the resolution of generated videos. The DiT model generates videos at a lower resolution that are then enhanced to the desired resolution by a spatial super-resolution model. For example, the DiT model can generate videos at 720p, and a spatial super-resolution model can then upscale them to 1080p or 4K.
  • Utilize a temporal super-resolution model: As proposed by [15], we employ a model to increase the temporal resolution by interpolating between frames. For instance, if a video should be five seconds at 24 FPS (i.e., 120 frames total), the DiT model can generate it at 12 FPS (60 frames), and a temporal super-resolution model can then interpolate to achieve 24 FPS.
  • Use more efficient architectures: We can adopt an efficient implementation of the attention mechanism [16] to reduce the computational load during training. Additionally, techniques like Mixture of Experts (MoE) [17] can be used to accelerate the training process.
  • Use distributed training: We use distributed training techniques, such as tensor parallelism, to parallelize training across multiple devices. By splitting the model, data, or both across different devices, we can significantly speed up training and handle larger video datasets more efficiently. This approach is particularly useful for high-resolution video generation, where memory and computational demands are substantial. For an overview of distributed training, refer to Chapter 1.
Image represents a data processing pipeline for video generation.  It begins with a rectangular box labeled 'Latent...' (orange), representing input latent data, which flows (indicated by an arrow and numbered '1') into a trapezoidal box labeled 'Visual D...' (light green), representing a visual decoder.  The output of the visual decoder ('Generated video...', dimensions 40x23x8) is then processed in two parallel paths.  Path one involves a connection (numbered '2') to a rectangular box labeled 'Spatial...' (light purple), followed by an arrow and numbered '3' to another rectangular box labeled 'Temporal...' (light purple). Path two directly connects the visual decoder output to a large rectangular prism representing the 'Generated video...' (dimensions 320x180x60). The outputs of 'Spatial...' and 'Temporal...' are then combined (arrow and numbered '4') to create the final video, represented by a larger rectangular prism labeled 'Final video' with dimensions 1280x720x120.  The numbers within the boxes represent dimensions (likely height, width, and depth/frames) of the video data at each stage.  The arrows indicate the flow of data between processing stages.
Figure 21: Efficient text-to-video pipeline

Sampling

The sampling process in diffusion models starts with random noise, and the model iteratively denoises the sample until a fully denoised video representation in the latent space is obtained. For more details on sampling in diffusion models, refer to Chapter 9.

Image represents a diffusion model architecture for generating images from text prompts.  The process begins with a 'Random...' block, representing a randomly initialized latent vector, which is fed into a series of three 'Latent...' blocks. Each 'Latent...' block represents a stage in the diffusion process, receiving input from the previous stage and a 'Text Enc...' block.  The 'Text Enc...' blocks, labeled with 'a dog walking...', encode the text prompt ('a dog walking...') into a vector that conditions the diffusion process at each stage.  Arrows indicate the flow of information: the output of each 'Latent...' block is passed to the next, and the output of each 'Text Enc...' block is fed into the corresponding 'Latent...' block.  After three stages, the final 'Latent...' block outputs a 'Denoised...' vector, representing the generated image's latent representation.  The ellipsis (...) after the second 'Latent...' block indicates that this section could be repeated multiple times depending on the model's design.
Figure 22: Sampling process from a trained LDM

Evaluation

Offline evaluation metrics

A consistent benchmark is crucial for evaluating video generation models. VBench [18] and Movie Gen Bench [19] offer this by providing a curated set of prompts designed to test various aspects of video generation such as motion coherence, temporal consistency, and scene complexity. We can use these benchmarks to measure how well the model creates realistic and smooth videos, focusing on video quality, motion accuracy, and scene transitions. Let’s explore both automated metrics and human evaluation, focusing on three key areas:

  • Frame quality
  • Temporal consistency
  • Video–text alignment

Frame quality

Frame quality refers to measuring the quality of each frame independently. To measure this quality we employ FID [20] and Inception score (IS) [21], both of which are commonly used for images. The overall quality is calculated by averaging the FID and IS scores of all frames. Other metrics such as LPIPS [22] and KID [23] can also be used.

While FID and IS measure the quality of individual frames, they don't account for the temporal consistency in generated videos. For instance, a video might have high-quality frames but lack smooth transitions, resulting in a high FID score without visual coherence. Let's explore temporal consistency and the common metrics used to measure it.

Temporal consistency

Temporal consistency refers to how smoothly visual content transitions from one frame to the next. Evaluating temporal consistency is important to ensure the generated video flows naturally. A common metric for measuring temporal consistency is the Fréchet Video Distance (FVD).

FVD

FVD [24], which is an extension of FID, evaluates both the visual quality and temporal consistency of videos. It compares the statistical distribution of generated videos to real videos in an embedded space.

Here's a step-by-step guide to calculating the FVD score:

  • Generating videos: We start by generating a large set of videos using the model we want to evaluate. These videos will be compared against a set of real videos to evaluate their quality and consistency.
  • Extracting features: We pass each video (both generated and real) through a pretrained I3D model [25] and extract features from a specific layer. The I3D model extends the Inception v3 [26] architecture to sequential data by training it for action recognition.
  • Calculating mean and covariance: We calculate the mean and covariance of the extracted features separately for generated and real videos. These statistical measures summarize the distribution of features for both sets of videos.
  • Computing Fréchet distance: We calculate the FVD score as the Fréchet distance between the mean and covariance of generated and real videos. The Fréchet distance measures how close the two distributions are.

A lower FVD score indicates greater similarity between the distributions, meaning the generated videos are more realistic and temporally consistent.

Video–text alignment

Video–text alignment refers to how accurately the generated video reflects the textual description on which it was conditioned.

A commonly used metric to measure video–text alignment is the CLIP similarity score, calculated as follows:

  • Extracting frame-level features: We pass each video frame through a pretrained CLIP image encoder to get visual features. The text is encoded using the text encoder to obtain textual features.
  • Calculating similarities: For each frame, we compute the cosine similarity between its visual features and the textual features. This score indicates how well the frame content aligns with the text.
  • Aggregating per-frame similarities: We aggregate these similarity scores to get a single score representing the overall video–text alignment. Aggregation can be done by averaging, taking the maximum score, or using other statistical methods.

A high CLIP similarity score indicates that generated videos are aligned with their corresponding text.

Human evaluation

Alongside the described automated metrics, human evaluation is still vital for assessing generative models, as it provides a subjective assessment that complements automated measures.

For human evaluation, we generate videos from test prompts using two different models. We then present pairs of videos, one from each model, to human annotators. They choose the better video based on assessing video–text alignment, video quality, and temporal consistency. This process allows us to compare two models to see which one performs better.

Online evaluation metrics

Online evaluation metrics for text-to-video models are similar to those for text-to-image models. Important metrics include:

  • Click-through rate
  • Time spent on the page
  • User feedback
  • Conversion rate

These metrics help gauge user engagement, satisfaction, and overall model performance in production.

Overall ML System Design

In this section, we dive into the holistic design of a text-to-video generation system. In particular, we examine the following pipelines:

  • Data pipeline
  • Training pipeline
  • Inference pipeline

Data pipeline

The data pipeline prepares training data by filtering unsuitable images and videos, standardizing them, and precomputing and storing latent representations. It ensures captions are relevant and detailed by re-captioning and using a pretrained text encoder to precompute and store caption embeddings.

Image represents a data processing pipeline with three parallel processing paths.  The top path begins with a database cylinder labeled 'Raw...' representing raw image data. This data flows into a rectangular box labeled 'Inappropriate...', presumably for filtering inappropriate content.  The filtered images then move to a box labeled 'Image...', followed by a light green box labeled 'Image Latent...', which likely represents a latent space representation of the images. Finally, the processed data is stored in a database cylinder labeled 'Image...'. The middle path mirrors this structure, processing 'Raw Videos' through 'Inappropriate...', 'Video...', and 'Video Latent...' boxes, culminating in a 'Video...' database. The bottom path starts with another 'Raw...' database (likely containing text captions), which feeds into a 'Re-captioning' box. The output then goes to a light green 'Caption Embedding...' box, generating embeddings, and finally stores the result in a 'Caption...' database.  Arrows indicate the unidirectional flow of data between each processing stage.
Figure 23: Data pipeline

Training pipeline

The training pipeline trains the model using the training data prepared by the data pipeline.

Inference pipeline

The inference pipeline processes real-time user requests to generate videos from text prompts. As shown in Figure 24, it has several crucial components that ensure system quality and safety.

Image represents a flowchart depicting the process of generating a video from a user prompt within a generative AI system.  The process begins with a user typing a prompt (1) and submitting it (2) to a 'Prompt Safety...' module (light blue) which checks for safety concerns. If deemed safe (3a), the prompt proceeds to a 'Prompt...' module (pale yellow), then to a 'Video...' module (light orange). The 'Video...' module receives input from both a 'Text...' module (grey cloud) and an 'LDM' module (grey cloud) (5a and 5b), likely representing text-based and latent diffusion model processing.  The output then goes through a 'Visual...' module (light green) and a 'Harm...' module (slate grey) for further safety checks. If safe (8a), it moves to a 'Temporal...' module (light red), which receives input from a 'Spatial...' module (light red) (9). Finally, the processed information is sent to a 'Generate...' module (white square with a play button) (10) to produce the video output. If at any point a safety check fails (3b or 8b), the process is rejected, resulting in a 'Reject r...' outcome.  The numbered circles (1-10) indicate the sequential steps in the process.
Figure 24: Inference pipeline components

Most of the components are similar to those explored in Chapter 9 for text-to-image generation. The unique components for text-to-video generation are:

  • Visual decoder
  • Temporal super-resolution

Visual decoder

The LDM generates output in the latent space, not the pixel space. The visual decoder then uses the compression network to convert this latent representation back into the pixel space.

Temporal super-resolution

This component interpolates between the generated frames, leading to smoother motion in videos.

Other Talking Points

In case there's extra time at the end of the interview, you might discuss these further topics:

  • Ensuring sampling flexibility for variable durations, resolutions, and aspect ratios [1].
  • Extending the text-to-video model to downstream applications such as inpainting, outputpainting, video-to-video stylization, frame interpolation, super-resolution, and animating images (image-to-video) [10].
  • Support for controlling the generated videos such as the level of desired motion and the type of motion (camera vs. object motion) [27].
  • Using progressive distillation techniques to reduce the computational demands of training [28].
  • Details of spatial and temporal super-resolution models [15].
  • Details of re-captioning model [9][8].
  • Different noise schedulers. [29].
  • Noise conditioning augmentation techniques [30].
  • Personalizing a text-to-video model to a particular subject [31].
  • ControlNet for text-to-video models [32].
  • Details of Stable Cascade method [33].
  • Details of visual compression network [13].

Summary

Image represents a mind map summarizing the design of a video generation AI system.  The central node is labeled 'Summary,' branching out into several major categories.  The 'Clarifying Requirements' branch details specifying input and output, and framing the problem as a machine learning (ML) approach, specifically using Latent Diffusion Models (LDM).  The 'Data Preprocessing' branch covers video standardization, pre-computation, and caption handling (including missing or non-English captions) and pre-computing caption embeddings.  The 'Model Development' branch focuses on architecture (using U-Net, temporal attention, and positional encoding within a Diffusion model), training, and challenges (computational cost and limitations of long video runs).  The 'Evaluation' branch distinguishes between offline (frame quality metrics like PSNR, LPIPS, and KID; temporal consistency; video-text alignment; and click-through rate) and online (time spent on the page, user feedback, and conversion rate) metrics.  Finally, the 'Overall System Components' branch details the data pipeline, training pipeline, and inference pipeline, which includes components like a prompt safety service, video generator, visual detector, and spatial and temporal super-resolution.  The 'Other Talking Points' branch suggests additional discussion areas.  All branches are color-coded for clarity, and the connections visually represent the hierarchical relationships between different aspects of the system design.

Reference Material

[1] Video generation models as world simulators. https://openai.com/index/video-generation-models-as-world-simulators/. [2] H100 Tensor Core GPU. https://www.nvidia.com/en-us/data-center/h100/. [3] High-Resolution Image Synthesis with Latent Diffusion Models. https://arxiv.org/abs/2112.10752. [4] Meta Movie Gen. https://ai.meta.com/research/movie-gen/. [5] Auto-Encoding Variational Bayes. https://arxiv.org/abs/1312.6114. [6] The Illustrated Stable Diffusion. https://jalammar.github.io/illustrated-stable-diffusion/. [7] On the De-duplication of LAION-2B. https://arxiv.org/abs/2303.12733. [8] The Llama 3 Herd of Models. https://arxiv.org/abs/2407.21783. [9] LLaVA-NeXT: A Strong Zero-shot Video Understanding Model. https://llava-vl.github.io/blog/2024-04-30-llava-next-video/. [10] Lumiere: A Space-Time Diffusion Model for Video Generation. https://arxiv.org/abs/2401.12945. [11] OpenSora Technical Report. https://github.com/hpcaitech/Open-Sora/blob/main/docs/report_02.md. [12] RoFormer: Enhanced Transformer with Rotary Position Embedding. https://arxiv.org/abs/2104.09864. [13] Stable Video Diffusion: Scaling Latent Video Diffusion Models to Large Datasets. https://arxiv.org/abs/2311.15127. [14] Emu Video: Factorizing Text-to-Video Generation by Explicit Image Conditioning. https://arxiv.org/abs/2311.10709. [15] Imagen Video: High Definition Video Generation with Diffusion Models. https://arxiv.org/abs/2210.02303. [16] HyperAttention: Long-context Attention in Near-Linear Time. https://arxiv.org/abs/2310.05869. [17] Mixture of Experts Explained. https://huggingface.co/blog/moe. [18] VBench: Comprehensive Benchmark Suite for Video Generative Models. https://vchitect.github.io/VBench-project/. [19] Movie Gen Bench. https://github.com/facebookresearch/MovieGenBench. [20] FID calculation. https://en.wikipedia.org/wiki/Fr%C3%A9chet_inception_distance. [21] Inception score. https://en.wikipedia.org/wiki/Inception_score. [22] The Unreasonable Effectiveness of Deep Features as a Perceptual Metric. https://arxiv.org/abs/1801.03924. [23] Demystifying MMD GANs. https://arxiv.org/abs/1801.01401. [24] Towards Accurate Generative Models of Video: A New Metric & Challenges. https://arxiv.org/abs/1812.01717. [25] Quo Vadis, Action Recognition? A New Model and the Kinetics Dataset. https://arxiv.org/abs/1705.07750. [26] Rethinking the Inception Architecture for Computer Vision. https://arxiv.org/abs/1512.00567. [27] Moonshot: Towards Controllable Video Generation and Editing with Multimodal Conditions. https://arxiv.org/abs/2401.01827. [28] Progressive Distillation for Fast Sampling of Diffusion Models. https://arxiv.org/abs/2202.00512. [29] Schedulers. https://huggingface.co/docs/diffusers/v0.9.0/en/api/schedulers. [30] Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding. https://arxiv.org/abs/2205.11487. [31] CustomVideo: Customizing Text-to-Video Generation with Multiple Subjects. https://arxiv.org/abs/2401.09962. [32] Control-A-Video: Controllable Text-to-Video Generation with Diffusion Models. https://controlavideo.github.io/. [33] Introducing Stable Cascade. https://stability.ai/news/introducing-stable-cascade.