Эксперимент по хирургическому удалению слоёв из языковой модели
TL;DR
Я взял TinyLlama (1.1B параметров, 22 слоя) и начал удалять из неё слои, чтобы проверить гипотезу: современные LLM переобучены, и многие слои делают одно и то же.
Результаты:
Удалил 1 средний слой → +10% скорость, -4% качество
Удалил 7 слоёв (безопасных) → +30% скорость, -2.5% качество
Удалил первый слой → модель сломалась
Неожиданно: Layer 2 важнее Layer 0! (+6.67 vs +3.92 perplexity)
Протестировал все 22 слоя по отдельности. Вот что нашёл.
Зачем это нужно?
Стартапы тратят миллионы долларов на GPU для инференса LLM. OpenAI, по слухам, тратит $700k в день только на вычисления. Любая оптимизация, которая ускоряет модель без потери качества — это прямая экономия денег.
Layer pruning — один из способов ускорения. Идея простая:
Современные модели имеют десятки слоёв (GPT-4 предположительно 120+)
Не все слои одинаково полезны
Некоторые можно удалить, и модель этого почти не заметит
Исследование ShortGPT (2024) показало, что можно удалить 25% слоёв из LLaMA-2 с потерей менее 5% качества. Я решил проверить это на практике.
Сетап эксперимента
Железо: MacBook Pro M4 Pro, 24GB RAM
Модель: TinyLlama-1.1B-Chat-v1.0
1.1 миллиарда параметров
22 слоя (decoder blocks)
Архитектура LLaMA
Метрики:
Perplexity — насколько модель "удивляется" тексту (ниже = лучше)
Tokens/second — скорость генерации
Качество генерации — субъективная оценка выходного текста
Код: PyTorch + HuggingFace Transformers. Удаление слоя = буквально убираем его из model.model.layers:
def remove_layers(model, layers_to_remove):
original_layers = list(model.model.layers)
new_layers = [
layer for i, layer in enumerate(original_layers)
if i not in layers_to_remove
]
model.model.layers = nn.ModuleList(new_layers)
return model
Результаты
Сводная таблица
Что удалил | Perplexity | Δ Quality | Tokens/s | Δ Speed | Работает? |
|---|---|---|---|---|---|
Ничего (baseline) | 1.82 | — | 59 | — | ✅ |
Средний слой (#11) | 1.89 | -4% | 64 | +10% | ✅ |
3 средних слоя (#10-12) | 2.24 | -23% | 66 | +12% | ✅ |
Первый слой (#0) | 5.74 | -215% | 64 | +10% | ❌ |
7 безопасных слоёв | ~1.87 | ~-2.5% | ~77 | ~30% | ✅ |
Примечание: точные измерения — 10 прогонов, 5 warmup, MPS backend
Главное открытие: средние слои избыточны
Удаление одного слоя из середины модели (слой #11 из 22) дало:
+10% к скорости генерации (59 → 64 tokens/sec)
Всего -4% к качеству (perplexity 1.82 → 1.89)
При удалении 7 безопасных слоёв (3, 4, 5, 9, 10, 11, 12) можно получить ~30% ускорения.
Генерация осталась полностью адекватной:
Prompt: "Once upon a time"
Baseline: (не измерял)
После удаления слоя #11: "Once upon a time, I was a web developer. Today, I am a freelance web developer. I have worked for some of the most prestigious web..."
Модель по-прежнему генерирует связный, грамматически корректный текст.
Первый слой — священный
А вот что случилось, когда я удалил первый слой:
После удаления слоя #0: "Once upon a time and a time. Therefore, the therefore, the therefore. Therefore, the therefore, the therefore. Therefore, the..."
Модель сломалась. Perplexity взлетела с 1.82 до 5.74 (в 3 раза хуже). Текст превратился в бессмысленное повторение.
Почему? Первые слои отвечают за:
Базовые attention patterns
Позиционное кодирование
Фундаментальное понимание структуры языка
Без них модель теряет способность понимать, как слова связаны друг с другом.
Визуализация: важность каждого слоя
Я протестировал удаление каждого слоя по отдельности и измерил деградацию качества:

Layer 0: ████████████████████████████████████████ +3.92 