Стиснення моделей зменшує розмір та обчислювальні вимоги моделей зберігаючи точність. Це дозволяє деплоймент на edge пристроях, зменшує витрати на serving та покращує латентність. Техніки включають квантизацію, pruning, knowledge distillation та ефективні архітектури.
Де використовується
Стиснення моделей дозволяє ML скрізь:
- Мобільні застосунки: On-device інференс для приватності, офлайн використання
- IoT пристрої: Сенсори, камери, embedded системи
- Edge computing: Рітейл, виробництво, транспортні засоби
- Зменшення хмарних витрат: Швидший інференс, менші витрати
- Real-time системи: Вимоги низької латентності
- Browser ML: TensorFlow.js, ONNX.js застосунки
Продукти: Siri (on-device), Google Lens, smart home пристрої, автономні транспортні засоби.
Техніки стиснення
| Техніка | Опис | Стиснення | Втрата точності |
|---|---|---|---|
| Квантизація | Зменшення precision (FP32→INT8) | 4x | 0-2% |
| Pruning | Видалення непотрібних ваг | 2-10x | 0-5% |
| Knowledge distillation | Тренування меншої моделі | 10-100x | 1-5% |
| Architecture search | Пошук ефективної архітектури | Різне | Мінімальна |
| Weight sharing | Sharing ваг між шарами | 2-4x | 1-3% |
Типові цілі
| Метрика | Сервер | Mobile | Embedded |
|---|---|---|---|
| Розмір моделі | GBs | 10-100 MB | < 10 MB |
| Латентність | 10-100ms | 20-100ms | < 50ms |
| Пам'ять | GBs | 100s MB | < 100 MB |
| Потужність | Висока | Середня | Низька |
Що ви робите на практиці
- Профілюйте baseline модель - Розмір, латентність, точність, пам'ять
- Встановіть обмеження деплойменту - Специфікації цільового пристрою
- Оберіть підхід стиснення - На основі обмежень та типу моделі
- Застосуйте стиснення - Квантизація, pruning, distillation
- Fine-tune за потреби - Відновіть втрату точності
- Валідуйте на цільовому hardware - Тестування на реальному пристрої
- Оптимізуйте runtime - TensorRT, ONNX Runtime тощо
- Бенчмаркте ретельно - Латентність, точність, пам'ять
- Деплойте та моніторте - Відстежуйте real-world performance
- Ітеруйте - Подальша оптимізація за потреби
Квантизація
Зменшення числової точності ваг та активацій.
Post-training quantization (просте):
import torch
# Завантаження FP32 моделі
model = torch.load('model.pth')
# Динамічна квантизація (тільки ваги)
quantized_model = torch.quantization.quantize_dynamic(
model,
{torch.nn.Linear, torch.nn.LSTM},
dtype=torch.qint8
)
# Статична квантизація (ваги + активації)
model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
torch.quantization.prepare(model, inplace=True)
# Калібрування з репрезентативними даними
with torch.no_grad():
for batch in calibration_dataloader:
model(batch)
torch.quantization.convert(model, inplace=True)
Quantization-aware training (вища точність):
import torch.quantization as quant
# Підготовка моделі для QAT
model.qconfig = quant.get_default_qat_qconfig('fbgemm')
model_prepared = quant.prepare_qat(model, inplace=False)
# Тренування з fake quantization
optimizer = torch.optim.Adam(model_prepared.parameters())
for epoch in range(num_epochs):
for batch in train_loader:
loss = train_step(model_prepared, batch)
loss.backward()
optimizer.step()
# Конвертація в квантизовану модель
model_quantized = quant.convert(model_prepared)
Pruning
Видалення ваг або структур що мало впливають на точність.
Magnitude pruning:
import torch.nn.utils.prune as prune
# Prune 30% ваг з найменшою величиною
for name, module in model.named_modules():
if isinstance(module, torch.nn.Conv2d):
prune.l1_unstructured(module, name='weight', amount=0.3)
# Зробити pruning постійним
for name, module in model.named_modules():
if isinstance(module, torch.nn.Conv2d):
prune.remove(module, 'weight')
Structured pruning (видалення цілих filters/channels):
# Prune цілих фільтрів на основі L1 норми
def prune_filters(model, amount=0.3):
for name, module in model.named_modules():
if isinstance(module, torch.nn.Conv2d):
prune.ln_structured(
module,
name='weight',
amount=amount,
n=1, # L1 норма
dim=0 # Prune фільтри
)
Knowledge Distillation
Тренування меншої "студентської" моделі імітувати більшу "вчительську".
import torch
import torch.nn as nn
import torch.nn.functional as F
class DistillationLoss(nn.Module):
def __init__(self, temperature=3.0, alpha=0.5):
super().__init__()
self.temperature = temperature
self.alpha = alpha
self.kl_loss = nn.KLDivLoss(reduction='batchmean')
self.ce_loss = nn.CrossEntropyLoss()
def forward(self, student_logits, teacher_logits, labels):
# Soft targets від teacher
soft_loss = self.kl_loss(
F.log_softmax(student_logits / self.temperature, dim=1),
F.softmax(teacher_logits / self.temperature, dim=1)
) * (self.temperature ** 2)
# Hard targets
hard_loss = self.ce_loss(student_logits, labels)
return self.alpha * soft_loss + (1 - self.alpha) * hard_loss
def train_distillation(teacher, student, train_loader, epochs=10):
teacher.eval()
student.train()
optimizer = torch.optim.Adam(student.parameters(), lr=1e-3)
distill_loss = DistillationLoss()
for epoch in range(epochs):
for batch_x, batch_y in train_loader:
with torch.no_grad():
teacher_logits = teacher(batch_x)
student_logits = student(batch_x)
loss = distill_loss(student_logits, teacher_logits, batch_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
Метрики оцінки
| Метрика | Формула | Ціль |
|---|---|---|
| Compression ratio | Original / Compressed size | Вище = краще |
| Speedup | Original latency / New latency | Вище = краще |
| Accuracy retention | New acc / Original acc | Ближче до 1.0 |
| Memory reduction | Original mem / New mem | Вище = краще |
Типові помилки та чек-лист
- [ ] Занадто агресивне стиснення: Значна втрата точності
- [ ] Неправильний hardware target: Оптимізація для неправильного пристрою
- [ ] Відсутність калібрування: Погана квантизація без calibration data
- [ ] Ігнорування runtime: Модель стиснута але runtime не оптимізований
- [ ] Batch size mismatch: Тест з іншим batch size ніж production
Чек-лист для продакшену
Перед деплоєм: - [ ] Benchmark на цільовому пристрої - [ ] Валідація точності після стиснення - [ ] Тест з різними input sizes - [ ] Profiling пам'яті та латентності
Після деплою: - [ ] Моніторинг latency розподілу - [ ] Відстеження accuracy в production - [ ] Порівняння з нестиснутою моделлю - [ ] A/B тест на user experience
Інструменти та стек
| Категорія | Інструменти |
|---|---|
| Квантизація | PyTorch quantization, TensorRT |
| Pruning | Neural Magic, NVIDIA Apex |
| Distillation | Hugging Face transformers |
| Runtime | TFLite, ONNX Runtime, OpenVINO |
Приклад міні-кейсу
Сценарій: Стиснення BERT для mobile inference.
Підхід: - Knowledge distillation до DistilBERT - INT8 quantization - ONNX export для mobile runtime
Результати: - Розмір: 440MB → 65MB (6.8x) - Латентність: 250ms → 45ms (5.5x) - Accuracy: 91.2% → 89.5% (1.7% drop)
Пов'язані сторінки
- Індекс: ML Field Guide
- Інференс на пристрої
- Privacy-Preserving ML
Додаткові матеріали
Спробуйте наживо
Дослідіть пов'язану модель на практиці: відкрийте Model Compression Lab — Shrink a Network Without Wrecking It і змінюйте параметри під час роботи. Усе лишається у вашому браузері.
▶ Відкрити симуляцію Model Compression Lab — Shrink a Network Without Wrecking It