Развертывание моделей PyTorch

Развёртывание моделей — это процесс внедрения обученных моделей машинного обучения в практические приложения. PyTorch предоставляет различные инструменты и методы для достижения этой цели.

Зачем нужно развёртывание моделей

  • Интеграция с приложениями: интеграция возможностей ИИ в веб-, мобильные или встраиваемые системы
  • Оптимизация производительности: оптимизация скорости инференса модели для сред эксплуатации
  • Управление ресурсами: эффективно использовать вычислительные ресурсы для обеспечения сервисов с высокой конкурентностью

Обзор процесса развёртывания


Подготовка и оптимизация модели

Форматы экспорта модели

PyTorch в основном поддерживает следующие форматы экспорта:

Формат Особенности Применимые сценарии
TorchScript Собственный формат PyTorch, сохраняет возможности динамического графа Используется внутри экосистемы PyTorch
ONNX Открытый стандарт, совместимый с разными фреймворками Среда для совместной работы с несколькими фреймворками
Torch-TensorRT Оптимизированный формат NVIDIA Ускорение инференса на GPU

Экспорт в TorchScript

Пример

import torch
import torchvision

# Загрузить предварительно обученную модель
model = torchvision.models.resnet18(pretrained=True)
model.eval()

# Пример входных данных
example_input = torch.rand(1, 3, 224, 224)

# Метод 1: Экспорт через трассировку
traced_script = torch.jit.trace(model, example_input)
traced_script.save("resnet18_traced.pt")

# Метод 2: Экспорт с помощью скриптов
scripted_model = torch.jit.script(model)
scripted_model.save("resnet18_scripted.pt")

Примечания:

  1. torch.jit.traceЛучше подходит для моделей без потока управления
  2. torch.jit.scriptМожет обрабатывать модели со сложной логикой, например с условными операторами
  3. Обязательно вызовите перед экспортомmodel.eval()

Выбор решения для развертывания

Локальные решения для развертывания

LibTorch (C++ API)

Пример

#include <torch/script.h>

int main() {
    // Загрузка модели
    torch::jit::script::Module module;
    module = torch::jit::load("resnet18.pt");
   
    // Подготовка входных данных
    std::vector<torch::jit::IValue> inputs;
    inputs.push_back(torch::ones({1, 3, 224, 224}));
   
    // Выполнение инференса
    auto output = module.forward(inputs).toTensor();
    std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';
}

ONNX Runtime

Пример

import onnxruntime as ort

# Создание сеанса инференса
sess = ort.InferenceSession("model.onnx")

# Подготовить входные данные
input_name = sess.get_inputs()[0].name
input_data = np.random.rand(1, 3, 224, 224).astype(np.float32)

# Выполнить инференс
outputs = sess.run(None, {input_name: input_data})

Облачные решения для развертывания

TorchServe (Официальный фреймворк для обслуживания)

Пример

# Установка
pip install torchserve torch-model-archiver

# Упаковать модель
torch-model-archiver --model-name resnet18 \
                     --version 1.0 \
                     --serialized-file model.pth \
                     --extra-files index_to_name.json \
                     --handler image_classifier \
                     --export-path model_store

# Запустить сервис
torchserve --start --model-store model_store --models resnet18=resnet18.mar

Создание REST API с помощью FastAPI

Пример

from fastapi import FastAPI
from PIL import Image
import io
import torch

app = FastAPI()
model = torch.jit.load("model.pt")

@app.post("/predict")
async def predict(image: UploadFile = File(...)):
    img_data = await image.read()
    img = Image.open(io.BytesIO(img_data))
    # Предобработка...
    with torch.no_grad():
        output = model(img_tensor)
    return {"prediction": output.argmax().item()}

Советы по оптимизации производительности

Ускорение с помощью квантования

Пример

# Динамическое квантование
quantized_model = torch.quantization.quantize_dynamic(
    model, {torch.nn.Linear}, dtype=torch.qint8)

# Статическое квантование
model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
torch.quantization.prepare(model, inplace=True)
# Калибровка...
torch.quantization.convert(model, inplace=True)

Использование TensorRT для ускорения

Пример

import torch_tensorrt

# Оптимизация компиляции
trt_model = torch_tensorrt.compile(model,
    inputs=[torch_tensorrt.Input((1, 3, 224, 224))],
    enabled_precisions={torch.float32}  # Или {torch.float16}
)

# Сохранить оптимизированную модель
torch.jit.save(trt_model, "model_trt.pt")

ЧАВО

Вопрос 1: Что делать, если во время развертывания возникают проблемы совместимости версий?Ответ: Рекомендуется использовать контейнеры Docker, чтобы зафиксировать версии окружения, или черезcondaсоздание выделенной среды.

Вопрос 2: Как отслеживать производительность развернутых моделей?Ответ: Вы можете интегрировать инструменты мониторинга, такие как Prometheus, для отслеживания задержки, пропускной способности и использования ресурсов.

Вопрос 3: Как реализовать горячие обновления после развертывания модели?Ответ: TorchServe поддерживает управление версиями моделей и A/B-тестирование, позволяя динамически переключать версии модели через API.

Другие расширения