Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

LLMs: Transfer Learning with TensorFlow, Keras, Hugging Face

Fine-tune Flan-T5-large with TensorFlow and Hugging Face for question-answering; covering transfer learning, SQuAD preprocessing, and T5 architecture for NLP.

Oct 17, 2024 • 8 Minute Read

LLMs: Transfer Learning with TensorFlow, Keras, Hugging Face

Transfer learning is one of the most powerful techniques in deep learning, especially when working with Large Language Models (LLMs). These models, such as Flan-T5, are pre-trained on vast amounts of data, allowing them to generalize across many language tasks. Instead of training a model from scratch, we can fine-tune these pre-trained models for specific tasks, like question-answering.

In this guide, we will walk you through how to perform transfer learning on Flan-T5-large using TensorFlow and Hugging Face. We’ll fine-tune this model on the SQuAD (Stanford Question Answering Dataset), a popular dataset used to train models for answering questions based on a given context.

Key points we’ll cover include:

  • A detailed introduction to Hugging Face and how it helps in NLP.
  • Step-by-step explanation of the code, including how to load and fine-tune the Flan-T5-large model.
  • Freezing the large encoder and decoder layers, and unfreezing only the final layer for efficient fine-tuning.
  • A brief introduction to the SQuAD dataset and how to process it for our task.
  • An in-depth explanation of the T5 architecture and how Hugging Face’s AutoModel works.
  • Ways to improve the fine-tuning process for better performance.

What is Hugging Face?

Hugging Face is a popular platform and library that simplifies working with powerful models in Natural Language Processing (NLP). The key components include:

  1. Model Hub: A repository of pre-trained models that are ready to be fine-tuned on specific tasks.
  2. Transformers Library: Provides tools to load and fine-tune models easily.
  3. Datasets Library: A quick and easy way to load datasets, such as SQuAD, for training.

With Hugging Face, you don't need to build models from scratch. It offers access to a wide variety of pre-trained models, including BERT, GPT-3, and T5, which significantly reduces the time and resources needed to develop NLP solutions. By leveraging these models, you can quickly fine-tune them for specific downstream tasks like question-answering, text classification, and summarization.

What is AutoModel?

Hugging Face provides various model classes, but AutoModel is one of the most flexible and widely used. The AutoModel API abstracts away the complexities of manually selecting and loading models. You don’t need to know the specific class of each model beforehand; AutoModel will load the correct architecture based on the model's name.

For instance, AutoModelForSeq2SeqLM is used for sequence-to-sequence models like T5 or BART, which are typically used for tasks such as translation, summarization, and question-answering. The beauty of AutoModel is that it is model-agnostic—meaning you can swap out models with ease and still use the same code.

Here’s how it works in practice:

      from transformers import TFAutoModelForSeq2SeqLM, AutoTokenizer

# Load the pre-trained Flan-T5-large model and tokenizer
model_name = "google/flan-t5-large"
model = TFAutoModelForSeq2SeqLM.from_pretrained(model_name)  # Load model
tokenizer = AutoTokenizer.from_pretrained(model_name)  # Load tokenizer
    

The AutoModel dynamically loads the correct model architecture based on the model's name (in this case, flan-t5-large). This flexibility makes the development process much smoother and faster because you don’t need to worry about manually specifying each model's architecture.

Understanding the T5 Architecture

To understand how T5 works, let's first break down its architecture. T5 stands for Text-to-Text Transfer Transformer, and it was introduced by Google in 2019. The key idea behind T5 is that every NLP task can be cast as a text-to-text problem, whether it's translation, summarization, or even question-answering.

Key Components of T5:

  • Encoder-Decoder Architecture: T5 is a sequence-to-sequence (Seq2Seq) model. The encoder processes the input text, while the decoder generates the output.
  • Task-Agnostic Design: T5 converts every task into a text-to-text problem. For example, for question-answering, the input would be structured as “question: <question> context: <context>,” and the model is tasked with predicting the answer as text.
  • Pre-training with Span Corruption: T5 was pre-trained using a method called "span corruption," where random spans of text are replaced with special tokens, and the model is tasked with predicting these spans.

Here’s an example of how T5 might be applied to a question-answering task:

      Input: "question: What is T5? context: T5 is a text-to-text transfer 
transformer developed by Google."
Output: "T5 is a text-to-text transfer transformer."
    

The beauty of T5’s text-to-text framework is its flexibility. You can use the same model architecture for various tasks simply by rephrasing the input. This makes T5 highly versatile and adaptable for a range of NLP tasks.

Why T5 is Perfect for Transfer Learning

T5 has been pre-trained on a massive dataset known as C4 (Colossal Clean Crawled Corpus), which gives it a solid understanding of the structure of language. Through transfer learning, we can fine-tune this pre-trained model to specialize in a specific task, such as question-answering with the SQuAD dataset. By leveraging T5’s pre-trained knowledge, we only need to tweak the final layer to make it perform well on our task, which reduces training time and computational resources.

Loading and Preprocessing the SQuAD Dataset

Now that we have the model, we need data to fine-tune it. We'll use the SQuAD dataset, a collection of question-answer pairs based on passages of text.

      from datasets import load_dataset

# Load the SQuAD dataset
squad = load_dataset("squad")
train_data = squad["train"]
valid_data = squad["validation"]
    

The SQuAD dataset is widely used for training models in question-answering tasks. Each data point in the dataset consists of a context (a passage of text), a question, and the corresponding answer, which is a span of text found within the context.

Preprocessing the Dataset

Before feeding the data into the model, we need to tokenize it. Tokenization converts raw text into numerical values (tokens) that the model can understand. For T5, we must format the input as a combination of the question and context.

      # Preprocessing function to tokenize inputs and outputs
def preprocess_function(examples):
    # Combine the question and context into a single string
    inputs = ["question: " + q + " context: " + c for q, c in 
zip(examples["question"], examples["context"])]
    model_inputs = tokenizer(inputs, max_length=512, truncation=True, 
padding="max_length", return_tensors="tf")

    # Tokenize the answer (label)
    labels = tokenizer(examples["answers"]["text"][0], max_length=64, 
truncation=True, padding="max_length", return_tensors="tf")
    model_inputs["labels"] = labels["input_ids"]
    return model_inputs

# Preprocess the dataset
train_data = train_data.map(preprocess_function, batched=True)
valid_data = valid_data.map(preprocess_function, batched=True)
    

This function tokenizes both the question-context pairs (the input) and the answers (the output). Tokenization is necessary for transforming raw text into tokenized sequences that the model can process.

Fine-Tuning the Model (Transfer Learning)

Here’s where we perform transfer learning. To make fine-tuning efficient, we freeze the encoder and decoder layers, and unfreeze only the final layer. This strategy ensures that the computationally heavy layers are kept intact while allowing the final layer to specialize in the task of answering questions.

      from tensorflow.keras.optimizers import Adam

# Freeze all layers by default (encoder, decoder, embedding layers)
for layer in model.layers:
    layer.trainable = False

# Unfreeze only the final task-specific layer
model.layers[-1].trainable = True

# Compile the model with the correct Hugging Face loss function for 
TensorFlow
optimizer = Adam(learning_rate=3e-5)
model.compile(optimizer=optimizer, loss=model.hf_compute_loss)

# Fine-tune the model on the SQuAD dataset
model.fit(train_data.shuffle(1000).batch(8), epochs=3, 
validation_data=valid_data.batch(8))
    

Explanation:

  • Freezing the encoder and decoder layers: We freeze these layers because they are very large and already pre-trained on vast amounts of data. Fine-tuning them would require significant computational resources and time. By freezing them, we preserve their general language understanding and focus on fine-tuning the final layer.
  • Unfreezing the final layer: This allows the model to learn task-specific information from the SQuAD dataset. The final layer will be responsible for generating the answer based on the question-context pair.
  • Fine-tuning: We use a small learning rate and train the model for 3 epochs to adapt it to our dataset.

Evaluating the Model

Once the model is fine-tuned, it’s important to test how well it performs on the validation set.

      # Select a sample from the validation set
sample = valid_data[0]

# Tokenize the input text
input_text = "question: " + sample["question"] + " context: " + sample["context"]
input_ids = tokenizer(input_text, return_tensors="tf").input_ids

# Generate the output (the model's answer)
output = model.generate(input_ids)
answer = tokenizer.decode(output[0], skip_special_tokens=True)

print(f"Question: {sample['question']}")
print(f"Answer: {answer}")
    

This code takes a sample question-context pair, tokenizes it, and uses the fine-tuned model to generate an answer. The tokenizer decodes the output back into human-readable text.

Ways to Improve Fine-Tuning

Although we’ve covered the basics of fine-tuning, there are several ways you can further improve the performance of your model:

  1. Data Augmentation: Use data augmentation techniques to increase the size of your training data. This could include paraphrasing questions or slightly modifying the context to create more training samples.
  2. Use of Transfer Learning Techniques: Explore other transfer learning techniques like Parameter Efficient Fine-Tuning (PEFT), which allows fine-tuning of smaller subsets of the model’s parameters.
  3. Optimization: Try using more advanced optimizers like AdamW or LAMB for better convergence. Additionally, consider experimenting with different learning rates, batch sizes, and warmup steps.
  4. Experiment with Hyperparameters: You can experiment with hyperparameters like learning rate, number of epochs, and dropout rates. Use a small validation set to tune these hyperparameters.
  5. Leverage TPUs or Multi-GPU Training: If you’re working with a large dataset or model, consider using TPUs (Tensor Processing Units) or multiple GPUs to speed up the training process.

Conclusion

In this guide, we walked through the entire process of fine-tuning a pre-trained LLM (Flan-T5-large) using TensorFlow and Hugging Face. By freezing the computationally expensive encoder and decoder layers and only fine-tuning the final layer, we optimized the training process while still adapting the model to our specific task of question-answering on the SQuAD dataset.

T5’s text-to-text framework makes it highly flexible and adaptable to various NLP tasks, and Hugging Face’s AutoModel abstraction simplifies the process of working with these models. By understanding the architecture and principles behind models like T5, you can apply these techniques to a variety of other NLP tasks, making transfer learning a powerful tool in your machine learning toolkit.

Axel Sirota

Axel S.

Axel Sirota is a Microsoft Certified Trainer with a deep interest in Deep Learning and Machine Learning Operations. He has a Masters degree in Mathematics and after researching in Probability, Statistics and Machine Learning optimization, he works as an AI and Cloud Consultant as well as being an Author and Instructor at Pluralsight, Develop Intelligence, and O'Reilly Media.

More about this author