Сохранение и загрузка моделей PyTorch
В проектах глубокого обучения сохранение и загрузка моделей — это важнейший этап. Основные причины включают:
- Восстановление после прерывания обучения: Можно возобновить обучение с контрольной точки, если процесс обучения неожиданно прерван
- Развёртывание модели: Разверните обученную модель в производственной среде
- Совместное использование модели: Удобно делиться результатами модели между членами команды
- Трансферное обучение: Сохраняйте предобученные модели для других задач
- Оценка эффективности: Сохраняйте модели с разных этапов обучения для сравнения
Основные методы сохранения и загрузки
Сохранение всей модели
Это самый простой метод: сохранение архитектуры и параметров модели:
Пример
import torch
import torchvision.models as models
# Создание и обучение модели
model = models.resnet18(pretrained=True)
# ... код обучения ...
# Сохранить всю модель
torch.save(model, 'model.pth')
# Загрузить всю модель
loaded_model = torch.load('model.pth')
import torchvision.models as models
# Создание и обучение модели
model = models.resnet18(pretrained=True)
# ... код обучения ...
# Сохранить всю модель
torch.save(model, 'model.pth')
# Загрузить всю модель
loaded_model = torch.load('model.pth')
Преимущества:
- Простой и интуитивно понятный код
- Сохраняет полную структуру модели
Недостатки:
- Больший размер файла
- Зависит от определения класса модели
Сохранение только параметров модели (Рекомендуется)
Более рекомендуемый способ — сохранять только state_dict модели:
Пример
# Сохранить параметры модели
torch.save(model.state_dict(), 'model_weights.pth')
# Загрузить параметры модели
model = models.resnet18() # Сначала нужно создать модель с той же архитектурой
model.load_state_dict(torch.load('model_weights.pth'))
model.eval() # Установить режим оценки
torch.save(model.state_dict(), 'model_weights.pth')
# Загрузить параметры модели
model = models.resnet18() # Сначала нужно создать модель с той же архитектурой
model.load_state_dict(torch.load('model_weights.pth'))
model.eval() # Установить режим оценки
Преимущества:
- Меньший размер файла
- Более гибкий, можно загружать в разные архитектуры
- Лучшая совместимость
Сохранение и загрузка состояния обучения
В реальных проектах обычно также необходимо сохранять состояние оптимизатора, эпоху и другую информацию:
Пример
# Сохранить контрольную точку
checkpoint = {
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss,
# Можно добавить другую информацию, которую нужно сохранить
}
torch.save(checkpoint, 'checkpoint.pth')
# Загрузить чекпоинт
checkpoint = torch.load('checkpoint.pth')
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']
model.eval() # Или model.train() в зависимости от ваших потребностей
checkpoint = {
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss,
# Можно добавить другую информацию, которую нужно сохранить
}
torch.save(checkpoint, 'checkpoint.pth')
# Загрузить чекпоинт
checkpoint = torch.load('checkpoint.pth')
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']
model.eval() # Или model.train() в зависимости от ваших потребностей
Загрузка моделей на разных устройствах
Обработка совместимости CPU/GPU
Пример
# Указывайте map_location при сохранении
torch.save(model.state_dict(), 'model_weights.pth')
# Загрузка на CPU (когда модель обучалась на GPU)
device = torch.device('cpu')
model.load_state_dict(torch.load('model_weights.pth', map_location=device))
# Загрузка на GPU
device = torch.device('cuda')
model.load_state_dict(torch.load('model_weights.pth', map_location=device))
model.to(device)
torch.save(model.state_dict(), 'model_weights.pth')
# Загрузка на CPU (когда модель обучалась на GPU)
device = torch.device('cpu')
model.load_state_dict(torch.load('model_weights.pth', map_location=device))
# Загрузка на GPU
device = torch.device('cuda')
model.load_state_dict(torch.load('model_weights.pth', map_location=device))
model.to(device)
Загрузка моделей, обученных на нескольких GPU
Пример
# Сохранение модели с несколькими GPU
torch.save(model.module.state_dict(), 'multigpu_model.pth')
# Загрузка на один GPU
model = ModelClass()
model.load_state_dict(torch.load('multigpu_model.pth'))
torch.save(model.module.state_dict(), 'multigpu_model.pth')
# Загрузка на один GPU
model = ModelClass()
model.load_state_dict(torch.load('multigpu_model.pth'))
Преобразование моделей и совместимость
Совместимость версий PyTorch
Пример
# Укажите _use_new_zipfile_serialization=True при сохранении для лучшей совместимости
torch.save(model.state_dict(), 'model.pth', _use_new_zipfile_serialization=True)
torch.save(model.state_dict(), 'model.pth', _use_new_zipfile_serialization=True)
Преобразование в TorchScript
Пример
# Преобразуйте модель в формат TorchScript
scripted_model = torch.jit.script(model)
torch.jit.save(scripted_model, 'model_scripted.pt')
# Загрузите модель TorchScript
loaded_script = torch.jit.load('model_scripted.pt')
scripted_model = torch.jit.script(model)
torch.jit.save(scripted_model, 'model_scripted.pt')
# Загрузите модель TorchScript
loaded_script = torch.jit.load('model_scripted.pt')
Лучшие практики и типичные проблемы
Лучшие практики
- Соглашения об именовании: используйте осмысленные имена файлов, например
resnet18_epoch50.pth - Периодическое сохранение: Сохраняйте чекпоинт каждые несколько эпох
- Проверка загрузки: Проверьте функциональность загрузки сразу после сохранения
- Документация: Записывайте архитектуру модели и параметры обучения
- Контроль версий: Включайте файлы модели в систему контроля версий
Решения распространённых проблем
Проблема 1:Отсутствуют ключ(и) в state_dict
Решение: Убедитесь, что архитектура модели точно совпадает, или используйтеstrict=Falseпараметр:
model.load_state_dict(torch.load('model.pth'), strict=False)
Проблема 2:Недостаточно памяти CUDA
Решение: Сначала поместите его на CPU при загрузке:
Пример
model.load_state_dict(torch.load('model.pth', map_location='cpu'))
Проблема 3: Не удаётся загрузить модели старых версий
Решение: Попробуйте загрузить в разных версиях PyTorch или преобразовать формат модели
Примеры практического применения
Процесс сохранения и загрузки модели классификации изображений

Полный пример кода
Пример
import torch
import torch.nn as nn
import torch.optim as optim
# Определим простую модель
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc = nn.Linear(10, 2)
def forward(self, x):
return self.fc(x)
# Инициализация
model = SimpleModel()
optimizer = optim.SGD(model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()
# Имитация процесса обучения
for epoch in range(5):
# Имитация шагов обучения
inputs = torch.randn(32, 10)
labels = torch.randint(0, 2, (32,))
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# Сохраняем чекпоинт каждые 2 эпохи
if epoch % 2 == 0:
checkpoint = {
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss.item(),
}
torch.save(checkpoint, f'checkpoint_epoch{epoch}.pth')
print(f'Чекпоинт сохранён на эпохе {epoch}')
# Финальное сохранение
torch.save(model.state_dict(), 'final_model.pth')
# Пример загрузки
loaded_model = SimpleModel()
loaded_model.load_state_dict(torch.load('final_model.pth'))
loaded_model.eval()
# Тестирование загруженной модели
test_input = torch.randn(1, 10)
with torch.no_grad():
output = loaded_model(test_input)
print(f'Тестовый вывод: {output}')
import torch.nn as nn
import torch.optim as optim
# Определим простую модель
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc = nn.Linear(10, 2)
def forward(self, x):
return self.fc(x)
# Инициализация
model = SimpleModel()
optimizer = optim.SGD(model.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()
# Имитация процесса обучения
for epoch in range(5):
# Имитация шагов обучения
inputs = torch.randn(32, 10)
labels = torch.randint(0, 2, (32,))
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# Сохраняем чекпоинт каждые 2 эпохи
if epoch % 2 == 0:
checkpoint = {
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss.item(),
}
torch.save(checkpoint, f'checkpoint_epoch{epoch}.pth')
print(f'Чекпоинт сохранён на эпохе {epoch}')
# Финальное сохранение
torch.save(model.state_dict(), 'final_model.pth')
# Пример загрузки
loaded_model = SimpleModel()
loaded_model.load_state_dict(torch.load('final_model.pth'))
loaded_model.eval()
# Тестирование загруженной модели
test_input = torch.randn(1, 10)
with torch.no_grad():
output = loaded_model(test_input)
print(f'Тестовый вывод: {output}')