TextBrewer Documentation

repository·master·Indexed 23 days ago

https://github.com/airaria/textbrewer

A PyTorch-based model distillation toolkit for Natural Language Processing (NLP) designed to compress large models, such as Transformers, into smaller student models. It supports single-teacher, multi-teacher, and multi-task distillation across tasks like text classification, machine reading comprehension, and sequence labeling. Key features include mixed soft-label and hard-label training, dynamic loss weight adjustment, and adaptive layer matching via EMDDistiller.

Tokens
22.7K
Snippets
24
Records
119
Agent score
78%

What's inside TextBrewer

  1. Overview of TextBrewer

    master

    TextBrewer is a PyTorch-based model distillation toolkit specifically designed for Natural Language Processing (NLP). It enables users to compress models to increase inference speed and reduce memory usage while minimizing performance loss.

    Key features include:

    • Wide support: Compatible with various architectures, particularly transformer-based models.
    • Flexibility: Allows designing custom distillation schemes by combining different techniques.
    • Ease of use: Users can perform distillation without modifying the underlying model architectures.
    • NLP-focused: Suitable for tasks such as text classification, machine reading comprehension, and sequence labeling.
  2. Overview of TextBrewer core components

    master

    TextBrewer is a PyTorch-based toolkit designed for Knowledge Distillation (KD) in NLP tasks. It is model-agnostic (primarily targeting Transformer architectures), non-intrusive (no need to modify model structures), and supports various NLP tasks like text classification, reading comprehension, and sequence labeling.

    The framework is organized into three main functional blocks:

    1. Distillers: The core engine of the distillation process. Different distiller classes provide different distillation modes. Available distillers include GeneralDistiller, MultiTeacherDistiller, and MultiTaskDistiller.
    2. Configurations and Presets: Handles training and distillation method configurations. It provides predefined distillation strategies and various knowledge distillation loss functions.
    3. Utilities: Auxiliary tools, such as model parameter analysis.

    To use TextBrewer, you need a trained teacher model, a student model (to be distilled), and your training dataset.

  3. Overview of TextBrewer features and components

    master

    TextBrewer is a PyTorch-based toolkit for knowledge distillation of NLP models, specifically designed for transformer-based architectures. It supports various tasks like text classification, machine reading comprehension, and sequence labeling.

    Core Components

    1. Distillers: The core engines of distillation. Examples include GeneralDistiller, MultiTeacherDistiller, and BasicTrainer.
    2. Configurations and presets: Classes for managing training and distillation settings, including predefined loss functions and strategies.
    3. Utilities: Auxiliary tools, such as model parameter analysis.

    Key Features

    • Mixed soft-label and hard-label training.
    • Dynamic loss weight and temperature adjustment.
    • Various distillation loss functions (e.g., hidden states MSE, attention-matrix-based loss, neuron selectivity transfer).
    • Support for intermediate feature matching losses.
    • Multi-teacher distillation.
    • Flexibility to use user-defined loss functions and modules without modifying model architectures.
  4. Use cached teacher values to skip teacher forward pass

    master

    To optimize training, you can provide pre-computed teacher outputs via a dataset. If your dataset returns a dictionary containing the key 'teacher_cache', TextBrewer will treat the contents of batch['teacher_cache'] as the output from the teacher and feed it directly to the teacher's adaptor.

    When 'teacher_cache' is present, the teacher's forward method is not called, saving computation time.

    Note: The items in teacher_cache should match the expected output format of the teacher model (e.g., a tuple of (logits, loss)).

    import torch
    from torch.utils.data import Dataset, TensorDataset, DataLoader
    
    class TSDataset(Dataset):
        def __init__(self, teacher_dataset, student_dataset, teacher_cache):
            # teacher_dataset and student_dataset are normal datasets 
            # whose each element is a tuple or a dict.
            # teacher_cache is a list of items; each item is the output from the teacher.
            assert len(teacher_dataset) == len(student_dataset), \
                f"lengths of teacher_dataset {len(teacher_dataset)} and student_dataset {len(student_dataset)} are not the same!"
            assert len(teacher_dataset) == len(teacher_cache), \
                f"lengths of teacher_dataset {len(teacher_dataset)} and teacher_cache {len(teacher_cache)} are not the same!"
            self.teacher_dataset = teacher_dataset
            self.student_dataset = student_dataset
            self.teacher_cache = teacher_cache
    
        def __len__(self):
            return len(self.teacher_dataset)
    
        def __getitem__(self,i):
            return {'teacher' : self.teacher_dataset[i], 'student' : self.student_dataset[i], 'teacher_cache':self.teacher_cache[i]}
    
    teacher_dataset = TensorDataset(torch.randn(32,3),torch.randn(32,3))
    student_dataset = TensorDataset(torch.randn(32,2),torch.randn(32,2))
    
    # We make some fake data and assume teacher model outputs are (logits, loss)
    fake_logits = [torch.randn(3) for _ in range(32)]
    fake_loss = [torch.randn(1)[0] for _ in range(32)]
    teacher_cache = [(fake_logits[i],fake_loss[i]) for i in range(32)]
    
    tssdataset = TSDataset(teacher_dataset=teacher_dataset,student_dataset=student_dataset, teacher_cache=teacher_cache)
    dataloader = DataLoader(dataset=tsdataset, ... )
  5. Implement a Callback to evaluate student models

    master
    A callback is a user-defined function called by the distiller at each checkpoint after the student model is saved. It is primarily used to evaluate the performance of the student model during the training process.
  6. Feed different batches to Student and Teacher

    master

    When distilling models with different vocabularies (e.g., RoBERTa to BERT), the student and teacher cannot share the same input. To handle this, you can create a custom Dataset that returns a dictionary containing separate keys for the student and teacher inputs.

    TextBrewer will automatically unpack the dictionary and feed batch['student'] to the student (and its adaptor) and batch['teacher'] to the teacher (and its adaptor) following the standard forward conventions.

    import torch
    from torch.utils.data import Dataset, TensorDataset, DataLoader
    
    class TSDataset(Dataset):
        def __init__(self, teacher_dataset, student_dataset):
            # teacher_dataset and student_dataset are normal datasets 
            # whose each element is a tuple or a dict.
            assert len(teacher_dataset) == len(student_dataset), \
                f"lengths of teacher_dataset {len(teacher_dataset)} and student_dataset {len(student_dataset)} are not the same!"
    
            self.teacher_dataset = teacher_dataset
            self.student_dataset = student_dataset
    
        def __len__(self):
            return len(self.teacher_dataset)
    
        def __getitem__(self,i):
            return {'teacher' : self.teacher_dataset[i], 'student' : self.student_dataset[i]}
    
    teacher_dataset = TensorDataset(torch.randn(32,3),torch.randn(32,3))
    student_dataset = TensorDataset(torch.randn(32,2),torch.randn(32,2))
    tssdataset = TSDataset(teacher_dataset=teacher_dataset,student_dataset=student_dataset)
    dataloader = DataLoader(dataset=tsdataset, ... )
  7. Define an adaptor to interpret model outputs

    master

    An adaptor is a function used by the GeneralDistiller to map raw model outputs to a dictionary of features required for distillation losses.

    For many Transformer-based models, the model output is a tuple where specific indices correspond to logits and hidden states. A common pattern is:

    • model_outputs[1]: Logits
    • model_outputs[2]: Hidden states

    Example adaptor implementation:

    def simple_adaptor(batch, model_outputs):
        return {'logits': model_outputs[1], 'hidden': model_outputs[2]}
    def simple_adaptor(batch, model_outputs):
        # model output's second and third elements are logits and hidden states
        return {'logits': model_outputs[1], 'hidden': model_outputs[2]}
  8. Distill when teacher and student have different inputs or vocabularies

    master

    If your teacher model and student model do not share vocabularies or require different input formats, you must feed different batches to the teacher and the student.

    For detailed implementation instructions, refer to the documentation section: Feed Different batches to Student and Teacher, Feed Cached Values.

  9. Understand the TextBrewer distillation workflow

    master

    The distillation process in TextBrewer is divided into two main stages:

    Stage 1: Preparation

    1. Train the teacher model.
    2. Define and initialize the student model.
    3. Construct a dataloader, an optimizer, and a learning rate scheduler.

    Stage 2: Distillation

    1. Construct a TrainingConfig and a DistillationConfig, then initialize a distiller.
    2. Define an adaptor (to adapt model inputs and outputs) and a callback (executed by the distiller during training).
    3. Call the .train() method of the distiller to begin the process.
  10. Use cached teacher logits to speed up distillation

    master

    To save time on the teacher model's forward pass during distillation, you can use pre-stored logits from the teacher model instead of computing them on the fly.

    For detailed implementation instructions, refer to the documentation section: Feed Different batches to Student and Teacher, Feed Cached Values.

  11. Run distillation experiments with Distillers

    master
    Distillers are the primary objects used to perform experiments in TextBrewer. To run a distillation process, you must initialize a distiller object (such as BasicDistiller, GeneralDistiller, MultiTeacherDistiller, or MultiTaskDistiller) and then call its train method.