Глубокое обучение развивается очень быстрыми темпами, и в настоящее время его применение можно найти во всех аспектах человеческой жизни. Поскольку каждый месяц выпускаются тысячи моделей, а возможности каждой из них улучшаются, стало необходимым оптимизировать их так, чтобы их можно было использовать на практике. Чаще всего моделисты сталкиваются с трудностями при производстве своих моделей из-за аппаратных ограничений или низкой производительности, вызванной неоптимизированными моделями.
Существуют различные методы, которые можно использовать для оптимизации моделей глубокого обучения, например: Квантование, при котором выполняются вычисления и сохраняются тензоры с меньшей разрядностью, чем с точностью с плавающей запятой. В результате это позволяет более компактно представлять модель и использовать высокопроизводительные векторизованные операции на многих аппаратных платформах, тем самым экономя нам много затрат на вычисления логического вывода и поддерживая точность логического вывода. Существуют и другие методы, такие как сокращение, дистилляция знаний и т. д.
Однако все эти методы требуют изменений в сетевой архитектуре или конвейере обучения с последующей тонкой настройкой, которая может занять много времени.
А вот и OpenVino, набор инструментов с открытым исходным кодом для оптимизации и развертывания моделей глубокого обучения, разработанный Intel. Он может улучшить производительность и эффективность модели на различных аппаратных платформах. Можно также развернуть преобразованные модели OpenVino в облачные экземпляры, такие как AWS C5, которые имеют выделенные процессоры Intel и будут очень эффективны для выполнения выводов на этих оптимизированных моделях.
В этой статье я покажу вам пример преобразования модели Pytorch CycleGAN в OpenVino и выполнения вывода с тем же, а также наблюдайте, как это помогает улучшить задержку. Сначала мы преобразуем модель Pytorch в Onnx, а затем в OpenVino. Для целей этой статьи мы будем использовать предварительно обученную модель Yosemite summer-to-winter от CycleGAN, а также их конвейер логического вывода.
Конвейер преобразования Pytorch в Onnx
### Assuming you have cloned the Cycle GAN repo from github: https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix ### run download_cyclegan_model.sh script to download pretrained summer2winter_yosemite_pretrained model (instructions on github page) ### Create a jupyter notebook and follow the below code snippets from models import create_model from options.test_options import TestOptions import torch from polygraphy.backend.onnx import fold_constants import onnx opt = TestOptions.parse() opt.netG = 'resnet_9blocks' opt.norm = 'instance' opt.checkpoints_dir = './checkpoints' ### directory storing the pre-trained model opt.name = 'summer2winter_yosemite_pretrained' model = create_model(opt) model.setup(opt) ### conversion to onnx dummy_inp = torch.rand(1, 3, 256, 256) onnx_filepath = './summer2winter_yosemite.onnx' torch.onnx.export(model, dummy_inp, onnx_filepath, opset_version=10, input_names = ['inp_img']) ### optional step to do Constant folding which involves pre-computing expressions that do not depend on runtime information converted_onnx_model = onnx.load('./summer2winter_yosemite.onnx') constant_folded_model = fold_constants(onnx_model) onnx.save(constant_folded_model, './summer2winter_yosemite_folded.onnx') ### This will give you converted onnx model, which can itself be used for on-device deployment
Установка OpenVino — документы
python3 -m venv openvino_env source openvino_env/bin/activate python -m pip install --upgrade pip pip install openvino-dev==2022.1.0. ### tested on this version currently
Тестовая установка OpenVino
mo -h ### This will return the help message for Model Optimizer if installation finished successfully
Преобразование Onnx в OpenVino
### To convert, run the following in your terminal (you can use either onnx model or the folded onnx model) ### input_model - specify your input onnx file ### data_type - use fp16 to convert model to fp16 precision for better performance ### output_dir - directory where your openvino files will be saved mo --input_model summer2winter_yosemite_folded.onnx --data_type fp16 --output_dir "./summer2winter_yosemite_openvino"
После выполнения он создаст следующие 3 файла в вашем каталоге.
summer2winter_yosemite_folded.bin - this contains the model weights ~23 Mb summer2winter_yosemite_folded.mapping - ~15 Kb summer2winter_yosemite_folded.xml - this contrains the model structure ~175 Kb
Теперь, когда у нас есть модели Pytorch и OpenVino, давайте сделаем вывод на приведенном ниже примере изображения и сравним их время выполнения и качественные результаты.
### Pytorch Model Inference from util.util import tensor2im from data.base_dataset import get_transform from PIL import Image import numpy as np input_image_filename = 'Yosemite_summer.jpg' input_image = Image.open(input_image_filename).convert('RGB') transformation = get_transform(opt, grayscale = False) transformed_img = transformation(input_image).unsqueeze(0) if opt.eval: model.eval() with torch.no_grad(): output_image = model.netG_A(transformed_img) output_image = tensor2im(output_image) ### final Pytorch result image ### OpenVino Model Inference from openvino.inference_engine import IECore, IENetwork from openvino.runtime import Core ie_obj = IECore() openvino_network = ie_obj.read_network(model = 'summer2winter_yosemite_folded.xml', weights = 'summer2winter_yosemite_folded.bin') executable_network = ie_obj.load_network(network = openvino_network, device='CPU') openvino_output = executable_network.infer({'inp_img': transformed_img}) arr_key = list(openvino_output.keys())[0] ### get key for putput image openvino_output_img = torch.from_numpy(np.asarray(openvino_output[arr_key])) openvino_output_image = tensor2im(openvino_output_img) ### final OpenVino result image
Построение полученных изображений для сравнения качества
import matplotlib.pyplot as plt plt.figure(figsize = (30, 30)) plt.subplot(1, 2, 1) plt.gca().set_title('Pytorch Output', fontsize = 'xx-large') plt.imshow(output_image) plt.subplot(1, 2, 2) plt.gca().set_title('OpenVino Output', fontsize = 'xx-large') plt.imshow(openvino_output_image)
Из приведенных выше изображений мы видим, что между двумя выходными изображениями почти нет заметных различий. Кроме того, при сравнении времени выполнения логического вывода для моделей Pytorch и OpenVino для 19 запусков было замечено, что модель summer2winter_yosemite CycleGAN OpenVino работает на 50 % быстрее. по сравнению с Pytorch, что является значительным преимуществом, если мы пытаемся интегрировать эту модель в приложение для реального использования.
Заключение
OpenVino – это набор инструментов с открытым исходным кодом, представленный Intel для оптимизации моделей глубокого обучения. Он представил новый формат представления промежуточного графа, известный как IR, вместе с набором операций для представления сети глубокого обучения, которая обычно представляется в виде ориентированного графа. Он использует файл XML и двоичный файл, представляющий график или IR. Чтобы узнать больше об IR и Opsets, вы можете обратиться к их официальной документации здесь.
OpenVino определенно сделал путь к производственной реализации модели глубокого обучения намного более эффективным. Мы можем развертывать эти модели не только на различных аппаратных устройствах, но и в облачных экземплярах для бесперебойной работы приложений.
На этом первая часть этого руководства по оптимизации модели глубокого обучения с использованием OpenVino завершена. Во второй части мы рассмотрим оптимизацию модели с помощью TensorRT, предназначенного для графических процессоров Nvidia и подходящего для более крупных моделей.
Если вам понравился этот урок и вы нашли его полезным, подпишитесь на другие интересные блоги и уроки!