Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Creating Own LLM›Model Compression: Quantization, Pruning, and Knowledge Distillation

Deployment and Advanced Topics

Model Compression: Quantization, Pruning, and Knowledge Distillation

Model compression reduces the size and computational cost of large language models (LLMs) without significantly sacrificing performance. It matters because deploying LLMs in resource-constrained environments—like edge devices or low-latency applications—requires efficient models. You reach for these techniques when your model is too large to deploy, too slow to infer, or consumes too much memory or power.

Why Compression Matters: The Trade-off Between Size and Performance

Large language models are powerful but come with significant computational and memory costs. A model with billions of parameters may achieve state-of-the-art results, but its size makes it impractical for deployment in environments with limited resources, such as mobile devices, embedded systems, or real-time applications. Compression techniques address this by reducing the model's footprint while preserving its ability to generalize. The core idea is to exploit redundancy in the model's parameters—many weights contribute minimally to the output, and some precision in calculations is unnecessary for maintaining performance. By understanding this trade-off, you can reason about when compression is appropriate: if your model is overparameterized (common in LLMs), compression can often remove or simplify parameters without harming accuracy. This section sets the stage for the techniques that follow, each of which targets a different aspect of this redundancy.

# Example: Measuring model size and inference time before compression
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

# Load a small pre-trained model for demonstration
model_name = "gpt2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# Measure model size in MB
def get_model_size_mb(model):
    param_size = sum(p.numel() * p.element_size() for p in model.parameters())
    buffer_size = sum(b.numel() * b.element_size() for b in model.buffers())
    total_size = (param_size + buffer_size) / (1024 ** 2)
    return total_size

model_size_mb = get_model_size_mb(model)
print(f"Model size: {model_size_mb:.2f} MB")

# Measure inference time for a single forward pass
input_ids = tokenizer("Hello, world!", return_tensors="pt").input_ids
start_time = torch.cuda.Event(enable_timing=True)
end_time = torch.cuda.Event(enable_timing=True)

start_time.record()
with torch.no_grad():
    outputs = model(input_ids)
end_time.record()
torch.cuda.synchronize()
inference_time_ms = start_time.elapsed_time(end_time)
print(f"Inference time: {inference_time_ms:.2f} ms")

Quantization: Reducing Precision to Save Space and Speed Up Inference

Quantization is the simplest and most widely used compression technique. It works by reducing the precision of the model's weights and activations, typically from 32-bit floating-point (FP32) to 8-bit integers (INT8) or even lower. The reasoning behind quantization is that neural networks are robust to small numerical errors—most weights don't need full FP32 precision to contribute meaningfully to the output. By quantizing, you reduce memory usage (since INT8 values take 4x less space than FP32) and speed up inference (since integer operations are faster than floating-point ones). However, quantization introduces noise, which can degrade performance if not managed carefully. To mitigate this, techniques like quantization-aware training (QAT) simulate the effects of quantization during training, allowing the model to adapt. Post-training quantization (PTQ) is simpler but may require calibration with representative data to minimize accuracy loss. Quantization is ideal when you need a quick win in deployment efficiency without retraining the model from scratch.

# Quantizing a model to INT8 using PyTorch's built-in tools
import torch.quantization

# Create a quantized version of the model
quantized_model = torch.quantization.quantize_dynamic(
    model,  # Original model
    {torch.nn.Linear},  # Layers to quantize
    dtype=torch.qint8  # Target dtype
)

# Compare sizes before and after quantization
quantized_size_mb = get_model_size_mb(quantized_model)
print(f"Quantized model size: {quantized_size_mb:.2f} MB (vs {model_size_mb:.2f} MB)")

# Measure inference time for the quantized model
start_time.record()
with torch.no_grad():
    outputs = quantized_model(input_ids)
end_time.record()
torch.cuda.synchronize()
quantized_inference_time_ms = start_time.elapsed_time(end_time)
print(f"Quantized inference time: {quantized_inference_time_ms:.2f} ms (vs {inference_time_ms:.2f} ms)")

Pruning: Removing Redundant Parameters to Slim Down the Model

Pruning takes a different approach by removing entire parameters or neurons from the model, rather than just reducing their precision. The intuition is that many parameters in a neural network are redundant—they contribute little to the output and can be safely removed without affecting performance. Pruning can be structured (removing entire neurons, filters, or layers) or unstructured (removing individual weights). Structured pruning is more hardware-friendly because it preserves the model's architecture, while unstructured pruning can achieve higher compression rates but may require specialized hardware to realize speedups. Pruning works because neural networks are overparameterized; during training, many weights converge to near-zero values, making them candidates for removal. The process typically involves identifying the least important weights (e.g., those with the smallest magnitudes), removing them, and fine-tuning the remaining weights to recover lost accuracy. Pruning is particularly useful when you need to reduce model size significantly, such as for deployment on edge devices with strict memory constraints.

# Pruning a model by removing small-magnitude weights
import torch.nn.utils.prune as prune

# Apply unstructured pruning to all linear layers
for name, module in model.named_modules():
    if isinstance(module, torch.nn.Linear):
        prune.l1_unstructured(module, name='weight', amount=0.3)  # Prune 30% of weights

# Check sparsity (percentage of pruned weights)
for name, module in model.named_modules():
    if isinstance(module, torch.nn.Linear):
        print(f"Layer {name} sparsity: {100. * float(torch.sum(module.weight == 0)) / float(module.weight.nelement()):.2f}%")

# Measure size and inference time after pruning
pruned_size_mb = get_model_size_mb(model)
print(f"Pruned model size: {pruned_size_mb:.2f} MB")

start_time.record()
with torch.no_grad():
    outputs = model(input_ids)
end_time.record()
torch.cuda.synchronize()
pruned_inference_time_ms = start_time.elapsed_time(end_time)
print(f"Pruned inference time: {pruned_inference_time_ms:.2f} ms")

Knowledge Distillation: Training a Smaller Model to Mimic a Larger One

Knowledge distillation is a more advanced technique that trains a smaller "student" model to replicate the behavior of a larger "teacher" model. Unlike quantization or pruning, which modify an existing model, distillation creates a new model from scratch. The key insight is that the teacher model's outputs (logits) contain more information than just the hard labels—soft probabilities reveal relationships between classes that the student can learn. For example, if the teacher assigns high probabilities to multiple similar classes, the student can learn to mimic this nuanced behavior. Distillation typically involves two loss terms: one for the student's predictions vs. the ground truth (hard labels) and another for the student's predictions vs. the teacher's softened outputs. The temperature parameter controls how much the teacher's logits are softened, with higher values emphasizing smaller probabilities. Distillation is powerful because it can produce compact models that retain much of the teacher's performance, but it requires training a new model, which can be computationally expensive. It's ideal when you need a model that is both small and highly accurate, such as for deployment in latency-sensitive applications.

# Knowledge distillation example: training a small student model to mimic a larger teacher
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
import torch.nn as nn
import torch.nn.functional as F

# Load teacher and student models
teacher_model_name = "gpt2-medium"
student_model_name = "gpt2"

teacher_tokenizer = AutoTokenizer.from_pretrained(teacher_model_name)
teacher_model = AutoModelForCausalLM.from_pretrained(teacher_model_name)
student_model = AutoModelForCausalLM.from_pretrained(student_model_name)

# Define distillation loss
class DistillationLoss(nn.Module):
    def __init__(self, temperature=2.0, alpha=0.5):
        super().__init__()
        self.temperature = temperature
        self.alpha = alpha
        self.ce_loss = nn.CrossEntropyLoss()

    def forward(self, student_logits, teacher_logits, labels):
        # Soft loss: student vs. teacher softened logits
        soft_loss = F.kl_div(
            F.log_softmax(student_logits / self.temperature, dim=-1),
            F.softmax(teacher_logits / self.temperature, dim=-1),
            reduction='batchmean'
        ) * (self.temperature ** 2)
        
        # Hard loss: student vs. ground truth
        hard_loss = self.ce_loss(student_logits, labels)
        
        return self.alpha * soft_loss + (1 - self.alpha) * hard_loss

# Example training step (simplified)
def train_step(student_model, teacher_model, inputs, distillation_loss):
    with torch.no_grad():
        teacher_outputs = teacher_model(**inputs)
    
    student_outputs = student_model(**inputs)
    loss = distillation_loss(
        student_outputs.logits,
        teacher_outputs.logits,
        inputs["labels"]
    )
    
    loss.backward()
    return loss.item()

# Example usage
inputs = teacher_tokenizer("Hello, world!", return_tensors="pt", padding=True, truncation=True)
inputs["labels"] = inputs["input_ids"]  # For language modeling

distillation_loss = DistillationLoss()
loss = train_step(student_model, teacher_model, inputs, distillation_loss)
print(f"Distillation loss: {loss:.4f}")

Combining Techniques: When and How to Use Multiple Compression Methods

While each compression technique is powerful on its own, combining them can yield even greater efficiency gains. For example, you might first prune a model to remove redundant parameters, then quantize the remaining weights to further reduce size and speed up inference. Alternatively, you could distill a large model into a smaller one and then apply quantization or pruning to the student model. The order matters: pruning before quantization is generally better because pruning reduces the number of parameters, making the remaining ones easier to quantize accurately. Similarly, distillation followed by pruning or quantization can produce highly efficient models, but the student model must be trained carefully to avoid overfitting. The key is to understand the trade-offs: combining techniques can compound their benefits but may also amplify their drawbacks, such as increased implementation complexity or potential accuracy loss. Always validate the compressed model's performance on your specific task and hardware. This section reinforces the idea that compression is not a one-size-fits-all solution—experimentation and iteration are essential to find the right balance for your use case.

# Combining pruning and quantization
# Step 1: Prune the model
for name, module in model.named_modules():
    if isinstance(module, torch.nn.Linear):
        prune.l1_unstructured(module, name='weight', amount=0.2)  # Prune 20% of weights

# Step 2: Quantize the pruned model
quantized_pruned_model = torch.quantization.quantize_dynamic(
    model,
    {torch.nn.Linear},
    dtype=torch.qint8
)

# Measure final size and inference time
final_size_mb = get_model_size_mb(quantized_pruned_model)
print(f"Final model size: {final_size_mb:.2f} MB")

start_time.record()
with torch.no_grad():
    outputs = quantized_pruned_model(input_ids)
end_time.record()
torch.cuda.synchronize()
final_inference_time_ms = start_time.elapsed_time(end_time)
print(f"Final inference time: {final_inference_time_ms:.2f} ms")

# Compare all techniques
print("\nSummary of compression techniques:")
print(f"Original: {model_size_mb:.2f} MB, {inference_time_ms:.2f} ms")
print(f"Quantized: {quantized_size_mb:.2f} MB, {quantized_inference_time_ms:.2f} ms")
print(f"Pruned: {pruned_size_mb:.2f} MB, {pruned_inference_time_ms:.2f} ms")
print(f"Quantized + Pruned: {final_size_mb:.2f} MB, {final_inference_time_ms:.2f} ms")

Key points

  • Model compression reduces the size and computational cost of LLMs by exploiting redundancy in parameters, making them practical for resource-constrained environments.
  • Quantization works by reducing the precision of weights and activations, which saves memory and speeds up inference but may introduce noise that degrades performance if not managed carefully.
  • Pruning removes redundant parameters or neurons, either in a structured or unstructured way, to slim down the model while preserving its ability to generalize.
  • Knowledge distillation trains a smaller student model to mimic a larger teacher model by learning from softened probabilities, capturing nuanced relationships between classes.
  • Combining compression techniques, such as pruning followed by quantization, can yield greater efficiency gains but requires careful validation to avoid compounding accuracy loss.
  • The order of applying compression techniques matters; for example, pruning before quantization is generally more effective because it reduces the number of parameters first.
  • Compression is not a one-size-fits-all solution, and experimentation is necessary to find the right balance between size, speed, and performance for your specific use case.
  • Always validate the compressed model's performance on your target task and hardware to ensure it meets the required accuracy and latency constraints.

Common mistakes

  • Mistake: Applying quantization uniformly across all layers of an LLM without considering layer sensitivity. Why it's wrong: Some layers (e.g., attention heads) are more sensitive to precision loss, leading to disproportionate performance degradation. Fix: Use mixed-precision quantization or profile layer sensitivity before quantizing.
  • Mistake: Pruning weights based solely on magnitude without fine-tuning. Why it's wrong: Magnitude-based pruning can remove structurally important weights, causing accuracy collapse. Fix: Use gradual pruning with iterative fine-tuning or structured pruning to preserve model integrity.
  • Mistake: Using knowledge distillation with a teacher and student model of identical architecture. Why it's wrong: The student model lacks capacity to learn compressed representations effectively. Fix: Design the student model with a smaller architecture (e.g., fewer layers or hidden units) to enforce compression.
  • Mistake: Ignoring task-specific evaluation during model compression. Why it's wrong: Compression techniques may degrade performance on specific tasks (e.g., summarization vs. QA) differently. Fix: Evaluate compressed models on representative downstream tasks, not just perplexity or generic benchmarks.
  • Mistake: Assuming knowledge distillation transfers all nuances of the teacher model. Why it's wrong: Distillation may lose rare but critical patterns (e.g., long-tail knowledge). Fix: Combine distillation with fine-tuning on high-quality data or use contrastive distillation to preserve edge cases.

Interview questions

What is model quantization, and why is it important when creating your own LLM?

Model quantization is the process of reducing the precision of the numbers used to represent a model's weights and activations, typically from 32-bit floating-point to 8-bit integers or even lower. This is crucial when creating your own LLM because it significantly reduces the model's memory footprint and computational requirements. For example, a 32-bit model can be compressed to 8-bit with minimal accuracy loss, making it feasible to deploy on edge devices or in environments with limited resources. Quantization also speeds up inference, which is essential for real-time applications. Here’s a simple example using PyTorch: `quantized_model = torch.quantization.quantize_dynamic(model, {torch.Linear}, dtype=torch.qint8)`. This line converts linear layers to 8-bit integers dynamically during inference.

How does pruning work in the context of LLMs, and what are its benefits?

Pruning is a technique where we remove less important weights, neurons, or even entire layers from a model to reduce its size and computational complexity. In LLMs, this is often done by identifying weights with the smallest magnitudes or those that contribute the least to the model's output. The benefits include faster inference, lower memory usage, and reduced energy consumption, which are critical for deploying LLMs in resource-constrained environments. For instance, you can use magnitude-based pruning in PyTorch like this: `torch.nn.utils.prune.l1_unstructured(module, name='weight', amount=0.3)`. This prunes 30% of the smallest weights in the specified module. After pruning, it’s important to fine-tune the model to recover any lost accuracy.

Explain knowledge distillation and how it can be applied to compress an LLM.

Knowledge distillation is a technique where a smaller 'student' model is trained to mimic the behavior of a larger 'teacher' model. The student learns not just from the ground truth labels but also from the teacher's output probabilities, which contain richer information about the data. For LLMs, this means training a smaller model to replicate the predictions of a larger, more accurate model. The process involves generating soft labels from the teacher model and using them to train the student. For example, in PyTorch, you might use a custom loss function that combines the standard cross-entropy loss with a distillation loss, like the Kullback-Leibler divergence between the teacher and student outputs. This approach allows you to create a more compact model with minimal performance degradation.

Compare quantization and pruning in terms of their impact on model performance and deployment.

Quantization and pruning are both model compression techniques, but they impact performance and deployment differently. Quantization reduces the precision of weights and activations, which primarily lowers memory usage and speeds up inference with minimal accuracy loss. It’s particularly effective for deployment on hardware with limited precision support, like mobile devices or specialized AI chips. Pruning, on the other hand, removes entire weights or neurons, which can significantly reduce the model's size and computational load but may require fine-tuning to recover accuracy. Quantization is generally easier to implement and has a more predictable impact on performance, while pruning can lead to more aggressive compression but may introduce sparsity, which some hardware doesn’t handle efficiently. For example, a quantized model might run faster on a GPU, while a pruned model might struggle unless the hardware supports sparse computations.

How would you implement a combined approach of quantization and knowledge distillation for an LLM you’re creating?

To implement a combined approach of quantization and knowledge distillation for an LLM, I would start by training a large teacher model to achieve high accuracy. Next, I’d use knowledge distillation to train a smaller student model, ensuring it learns from both the ground truth labels and the teacher’s soft probabilities. Once the student model is trained, I’d apply post-training quantization to further reduce its size and improve inference speed. For example, in PyTorch, I’d first distill the model using a custom loss function: `loss = alpha * ce_loss + (1 - alpha) * kl_div_loss`. After training, I’d quantize the student model using `torch.quantization.quantize_dynamic`. This combined approach leverages the strengths of both techniques: knowledge distillation ensures the student model retains as much accuracy as possible, while quantization makes it efficient for deployment. The key is to balance the trade-offs between model size, speed, and accuracy.

What challenges might you face when applying pruning to an LLM, and how would you address them?

Applying pruning to an LLM presents several challenges, primarily around maintaining model accuracy and handling the resulting sparsity. One major issue is that aggressive pruning can lead to significant accuracy loss, especially if the model isn’t fine-tuned properly afterward. To address this, I’d use iterative pruning, where I gradually prune the model in small increments, fine-tuning after each step to recover accuracy. Another challenge is that pruned models often have sparse weight matrices, which can be inefficient on hardware that doesn’t support sparse computations. To mitigate this, I’d explore structured pruning, which removes entire neurons or layers rather than individual weights, resulting in a denser, more hardware-friendly model. For example, in PyTorch, I might use `torch.nn.utils.prune.ln_structured` to prune entire channels in a convolutional layer. Additionally, I’d monitor the model’s performance on a validation set throughout the process to ensure the pruned model meets the desired accuracy targets.

All Creating Own LLM interview questions →

Check yourself

1. When quantizing an LLM from FP32 to INT8, you observe a 5% drop in accuracy on a summarization task. Which approach is most likely to recover the lost performance while maintaining compression?

  • A.Revert to FP32 for all layers to eliminate quantization error
  • B.Apply mixed-precision quantization, keeping sensitive layers (e.g., attention) in FP16 while quantizing others to INT8
  • C.Increase the model size to compensate for the accuracy loss
  • D.Use post-training quantization without any calibration data
Show answer

B. Apply mixed-precision quantization, keeping sensitive layers (e.g., attention) in FP16 while quantizing others to INT8
The correct answer is mixed-precision quantization because it balances compression and accuracy by preserving precision in critical layers. Option 1 negates compression entirely. Option 3 increases model size, violating the goal of compression. Option 4 ignores the need for calibration, which is essential for minimizing quantization error.

2. You prune 30% of the weights in an LLM using magnitude-based pruning and observe a significant accuracy drop. What is the most effective way to mitigate this without increasing model size?

  • A.Prune fewer weights (e.g., 10%) to reduce the impact
  • B.Use structured pruning (e.g., entire attention heads) followed by fine-tuning
  • C.Retrain the model from scratch with the pruned architecture
  • D.Apply knowledge distillation to the pruned model using the original model as a teacher
Show answer

B. Use structured pruning (e.g., entire attention heads) followed by fine-tuning
Structured pruning followed by fine-tuning preserves model integrity by removing entire components (e.g., attention heads) rather than individual weights, making it easier to recover accuracy. Option 1 reduces compression effectiveness. Option 3 is computationally expensive and unnecessary. Option 4 may help but is less direct than fine-tuning the pruned structure.

3. In knowledge distillation for LLMs, why is it important to use a temperature-scaled softmax on the teacher model's logits?

  • A.To reduce the computational cost of distillation by simplifying the teacher's outputs
  • B.To amplify the differences between the teacher's logits, making it easier for the student to mimic rare patterns
  • C.To smooth the teacher's probability distribution, exposing the student to richer information about class relationships
  • D.To ensure the teacher and student models use the same tokenization scheme
Show answer

C. To smooth the teacher's probability distribution, exposing the student to richer information about class relationships
Temperature scaling smooths the teacher's probability distribution, revealing relationships between classes (e.g., 'cat' vs. 'dog') that are otherwise obscured in hard labels. Option 1 is incorrect because temperature scaling increases computational cost. Option 2 describes the opposite effect (temperature actually reduces differences). Option 4 is unrelated to logit scaling.

4. You compress an LLM using 4-bit quantization and observe that its performance degrades significantly on a question-answering task but remains stable on text generation. What is the most likely explanation?

  • A.The quantization process introduced random noise that affects QA more than generation
  • B.QA tasks rely more on precise attention mechanisms, which are sensitive to low-bit quantization
  • C.The calibration data used for quantization was biased toward text generation
  • D.4-bit quantization is inherently incompatible with QA tasks
Show answer

B. QA tasks rely more on precise attention mechanisms, which are sensitive to low-bit quantization
QA tasks often require precise attention to context and factual details, which are disrupted by aggressive quantization. Option 0 is unlikely because quantization noise is systematic, not random. Option 2 is incorrect because calibration data bias would affect both tasks. Option 3 is overly absolute.

5. When combining pruning and knowledge distillation to compress an LLM, which order of operations is most effective?

  • A.Prune first, then apply knowledge distillation to the pruned model
  • B.Apply knowledge distillation first, then prune the distilled student model
  • C.Prune and distill simultaneously in a single training loop
  • D.The order does not matter; both techniques are independent
Show answer

A. Prune first, then apply knowledge distillation to the pruned model
Pruning first reduces the model size, and distillation then helps recover accuracy by leveraging the teacher's knowledge. Option 1 risks pruning a model already compressed by distillation, compounding accuracy loss. Option 2 is less efficient because simultaneous training is complex and may not converge. Option 3 is incorrect because the techniques interact; pruning affects the student's capacity to learn from distillation.

Take the full Creating Own LLM quiz →

← PreviousFine-Tuning Pre-Trained Models for Specific TasksNext →Serving LLMs: APIs, Microservices, and Scalable Inference

Creating Own LLM

36 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app