Concepts / Preparing the GPT Model for Classification Fine-Tuning

Preparing the GPT Model for Classification Fine-Tuning

The output layer of a pre-trained GPT model is replaced with a new torch.nn.Linear layer so the model can produce one output per class.

  • Programming

A Model That Knows Text but Not Your Question

A pre-trained GPT model has already learned general patterns from a large amount of text. That general knowledge is valuable, but the model was not built to answer one specific question, such as whether a message is spam or not spam. To use it for a classification task, two things must happen before fine-tuning begins: its final layer has to be adapted so it produces one output for each class the task requires, and the model has to be placed on the device where it will run. This article walks through the setup step that adapts the final layer, and then the step that prepares the model to run on an available device.

The setup is short, but every line changes something specific. As you read it, ask two questions about each line: what object is being changed, and what value does that object end up holding? Keeping those two questions in mind will make the rest of the article easier to follow.

The Model Before and After the Swap

The key idea is that only one part of the model is swapped out. The replacement is a single assignment to the model's out_head attribute. Nothing else in the setup code redefines the model, so the rest of the GPT architecture stays exactly as it was loaded. Only the final layer, the one that turns internal representations into outputs, is changed.

Read the diagram as a comparison. On the left is the model as it was loaded, with its original output layer. On the right is the same model after the assignment. The output layer is the only element marked as changed. The rest of the architecture is shown on both sides because it carries over untouched.

Reading the Replacement Line by Line

The replacement follows the pattern described in the setup. The left side of the assignment names the spot in the model that gets overwritten. The right side creates a new torch.nn.Linear object, and the assignment stores that object in place of the old layer. Here is the replacement in the form the setup describes, with num_classes set to 2 before the layer is created:

python

Read the anatomy from left to right. The attribute on the left is the location being overwritten. The call on the right defines the new layer's shape. The in_features value is fixed at 768 in this setup, while the out_features value is taken from num_classes. This means that changing the number of classes changes only the output side of the layer.

Setting out_features from the Number of Classes

The value of num_classes becomes the out_features argument, so it determines how many outputs the new layer produces. Each output position corresponds to one class. With num_classes equal to 2, the layer produces two outputs, one for each class. Changing the task to a different number of classes means changing only that value.

What do you think happens?

If num_classes were set to 3 instead of 2, how many outputs would the new layer produce?

  • 2

  • 3

  • 768

  • 5

Reveal answer
Answer:

3

The out_features argument is taken from num_classes, so a value of 3 gives three outputs. The 768 input features stay the same, because they describe what the layer receives, not how many classes there are.

Worked example

Changing the task from two classes to four

A classification task now needs four classes instead of two. Which value changes, and what is the resulting layer?

  1. 1
    Identify the value that depends on the class count

    The setup ties out_features to num_classes, so num_classes is the value to change.

  2. 2
    Update num_classes

    Set num_classes = 4 before the layer is created.

  3. 3
    Check what stays fixed

    in_features stays at 768, because it describes the width of the input the layer receives and does not depend on the class count.

  4. 4
    Write the new layer

    The replacement becomes torch.nn.Linear(in_features=768, out_features=4).

Result

The new output layer has 768 input features and 4 outputs, one for each class. Only out_features changed.

  • Common mistake

    Changing in_features when the number of classes changes

    What it looks like

    Setting in_features=4 because the task now has four classes

    Why it fails

    in_features describes the width of what the layer receives from the rest of the model. It does not depend on the number of classes.

    Do this instead

    Keep in_features at 768 and change only num_classes, which feeds out_features.

  • Common mistake

    Assuming the whole model is rebuilt by the replacement line

    Why it fails

    The replacement is a single assignment to out_head. Nothing else in the setup redefines the model.

    Do this instead

    Expect the rest of the GPT architecture to stay as it was loaded.

Choosing and Moving the Device

After the output layer is replaced, the setup prepares where the model will run. The setup code first creates a device object. It selects CUDA when torch.cuda.is_available() reports that CUDA is available, and selects the CPU otherwise. The device is chosen based on what the machine offers rather than being hard-coded. The final line, model.to(device), applies that choice to the model.

The flowchart traces one decision. The check asks whether CUDA is available. A yes answer selects cuda, and a no answer selects cpu. Both paths then reach the same final step, model.to(device), which moves the model onto the selected device. The device is therefore chosen at run time from what the machine offers, and the model follows that choice.

Notice the order of the setup. The device selection comes after the output layer replacement. The model is first adapted to the classification task, and then it is placed on the device where it will run. Both steps happen before any training or fine-tuning begins.

Mistakes When Preparing the Model

  • Common mistake

    Hard-coding the device as CUDA

    Why it fails

    The device is chosen from what the machine offers. A hard-coded CUDA device would fail on a machine where CUDA is not available.

    Do this instead

    Create the device with the torch.cuda.is_available() check, which selects CUDA when available and the CPU otherwise.

  • Common mistake

    Running the device step before the layer replacement and assuming the order does not matter

    Why it fails

    The setup adapts the model to the classification task first and places it on the device second. Keeping that sequence makes the setup easy to read and matches the described order.

    Do this instead

    Replace the output layer first, then choose the device and call model.to(device).

Check Your Setup Reasoning

MEDIUM

A colleague says that to adapt a model for a four-class task, they changed in_features from 768 to 4 and left num_classes unchanged. Explain which value is wrong, what each value should be, and what the layer's outputs would be after the correct change.

Hints
  • Ask which value describes the width of the input the layer receives from the rest of the model.
  • Ask which value is taken from num_classes and feeds out_features.
  • Compare your answer with the worked example on changing from two classes to four.

Key Takeaways

  • A pre-trained GPT model is not built for a specific question, so its output layer is replaced with a new torch.nn.Linear layer that produces one output per class.
  • The replacement is a single assignment to model.out_head, and the rest of the GPT architecture stays as it was loaded.
  • in_features is fixed at 768, and out_features is taken from num_classes, so changing the class count changes only the output side of the layer.
  • The device is chosen with torch.cuda.is_available(), selecting CUDA when available and the CPU otherwise, and model.to(device) applies that choice to the model.
  • Both the output layer replacement and the device selection happen before fine-tuning begins.

Related concepts

More concepts starting with P