LLM Compression: Sparse Fine-Tuning, LoRA и SFT на практике
[🎯 Введение и мотивация]
Представьте: вы запускаете модель Llama 2 70B на inference. Один запрос потребляет 15 ГБ VRAM и занимает 8 секунд. Клиенты жалуются на задержки, а серверы перегреваются. Это не гипотетическая ситуация — ежедневная реальность для команд, работающих с большими языковыми моделями. Проблема: современные LLM требуют колоссальных вычислительных ресурсов. Обучение одной модели может стоить $1 млн+, а инференс — становиться узким местом в продуктах.
Усугубление: как только вы добавляете fine-tuning для специфичной задачи (например, медицинского консультирования), затраты растут экспоненциально. Без оптимизации вы можете потратить месяцы на вычисления, чтобы получить… модель, которая все равно не помещается в production. Конфликт: между мощностью LLM и практическими ограничениями оборудования существует пропасть, которую нужно преодолеть.
Решение: сжатие моделей через Sparse Fine-Tuning, LoRA и Supervised Fine-Tuning (SFT). Это не просто тренды — это революция в развертывании LLM. В этом руководстве мы превратим абстрактные концепции в работающие инструменты: от архитектуры до кода на PyTorch, от теории до реальных kpi. Вы не просто узнаете что — вы поймете как и почему.
[📋 Что вам понадобится]
Предварительные знания:
- Python 3.8+ и PyTorch 2.0+
- Понимание backpropagation и матричных операций
- Опыт работы с Hugging Face Transformers
- Базовые знания о архитектуре Transformer
Инструменты:
- GPU с 24+ ГБ VRAM (для экспериментов)
- Доступ к датасету (например, Alpaca для SFT)
- Weights & Biases для логирования экспериментов
- Библиотеки:
bitsandbytes,peft,datasets
Практические задания:
- Реализовать Sparse Fine-Tuning на синтетическом датасете
- Обучить LoRA-адаптер для модели GPT-2
- Сравнить метрики SFT vs сжатых версий
Время: 6-8 часов на прохождение с выполнением заданий
[🏗️ Фундаментальные основы]
Ментальная модель: Архитектор и ремонтник
Представьте LLM как огромный небоскреб (оригинальная модель). Его нужно адаптировать под новые нужды — например, под медицинский центр. Вместо сноса и перестройки (полного дообучения) мы используем три подхода:
- Sparse Fine-Tuning: заменяем только ключевые несущие стены (5-10% весов), оставляя остальное нетронутым.
- LoRA: устанавливаем модульные блоки (адаптеры) на существующие этажи, не затрагивая несущие конструкции.
- SFT: полная перестройка с нуля — ресурсоемко, но обеспечивает максимальную точность.

Ключевые концепции
1. Parameter-Efficient Fine-Tuning (PEFT)
[🎓 Для новичков]: Техники, которые позволяют обучать только малую долю параметров модели. Представьте, что вы меняете фильтр в системе очистки воды, а не всю трубу. [🚀 Для экспертов]: PEFT достигает этого через низкоранговую аппроксимацию, маскирование параметров или добавление адаптеров. Pitfall: агрессивная спarsity может разрушить предобученные знания.
2. Sparse Training
[🎓 Для новичков]: Обучение только части нейронов, как если бы вы включали свет только в комнате, где работаете. [🚀 Для экспертов]: Реализуется через gradient masking и structured pruning. Оптимизация: используйте dynamic sparsity, которая адаптируется под данные.
3. Low-Rank Adaptation (LoRA)
[🎓 Для новичков]: Разложение большой матрицы на две маленькие. Как разложить 1000-страничную книгу на 2 коротких тетради. [🚀 Для экспертов]: Математически: (W = W_0 + BA), где (B \in \mathbb{R}^{d \times r}), (A \in \mathbb{R}^{r \times k}), (r \ll \min(d,k)). Rank (r) — гиперпараметр (обычно 4-64).
4. Supervised Fine-Tuning (SFT)
[🎓 Для новичков]: Обучение модели на размеченных данных, как ученика с преподавателем. [🚀 Для экспертов]: Требует качественных датасетов с инструкциями. Pitfall: если данные содержат ошибки, модель «выучит» и их.
Вопросы для самопроверки:
- Почему полное дообучение LLM 70B требует 1000× больше GPU-часов, чем LoRA?
- Как изменится loss при увеличении rank в LoRA с 8 до 64?
- Почему Sparse Fine-Tuning может потерять в точности на малых датасетах?
[🔬 Глубокий технический анализ] 
Архитектура Sparse Fine-Tuning
graph TD
A[Original Model Weights] --> B[Sparsity Mask Generator]
B -->|Gradient-based| C[Active Neurons: 5-10%]
C --> D[Backpropagation]
D --> E[Update Only Active Weights]
E --> F[Compressed Model]
Интерактивный ментальный эксперимент:
«Что если мы увеличим sparsity до 1%?» → Модель потеряет способность к обобщению, так как критические нейроны будут отключены. Оптимальное значение зависит от датасета и архитектуры.
Алгоритм LoRA
flowchart LR
Input -->|X| Original_Weights
Original_Weights -->|W_0| Output
Subgraph LoRA_Adapter
direction LR
B[Matrix B: d×r] -->|BA| A[Matrix A: r×k]
end
Original_Weights -->|W_0 + BA| Output
Производительность:
- Память: (O(d \times r + r \times k)) вместо (O(d \times k))
- Параметры: при (r=8), обучение всего 0.1% от оригинальных весов
Ограничения
| Метод | Точность | Скорость инференса | Память VRAM |
|---|---|---|---|
| Full SFT | ✅✅✅ | ❌❌❌ | ❌❌❌ |
| Sparse FT | ✅✅ | ✅✅ | ✅✅ |
| LoRA | ✅✅✅ | ✅✅✅ | ✅✅✅ |
[💻 Пошаговое практическое руководство]
Шаг 1: Подготовка окружения
Установите необходимые библиотеки:
pip install torch peft datasets bitsandbytes transformers
Сэндвич-подход для кода:
1. Объяснение: Мы загрузим модель GPT-2, создадим маску для спарсного обучения и инициализируем оптимизатор, который будет обновлять только активные веса.
2. Код:
import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer
from peft import LoraConfig, get_peft_model
# Загрузка модели
model = GPT2LMHeadModel.from_pretrained("gpt2")
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
# Создание маски спарсности (10% весов)
mask = torch.rand_like(model.transformer.h[0].attn.c_proj.weight) > 0.9
print(f"Активные веса: {mask.sum().item() / mask.numel():.2%}")3. Анализ: Маска генерируется случайным образом. В продакшене используйте gradient-based sparsity для лучшего результата. mask.sum().item() покажет, сколько весов останется активными.
Шаг 2: Реализация LoRA
1. Объяснение: Настроим LoRA для слоя внимания, добавив низкоранговые адаптеры.
2. Код:
# Конфигурация LoRA
lora_config = LoraConfig(
r=8, # ранг
lora_alpha=32,
target_modules=["attn.c_proj\