diff --git a/advanced_source/super_resolution_with_onnxruntime.py b/advanced_source/super_resolution_with_onnxruntime.py index 2a3a3dadd..5e0c7943e 100644 --- a/advanced_source/super_resolution_with_onnxruntime.py +++ b/advanced_source/super_resolution_with_onnxruntime.py @@ -1,29 +1,27 @@ """ -(optional) Exporting a Model from PyTorch to ONNX and Running it using ONNX Runtime +(선택) PyTorch 모델을 ONNX으로 변환하고 ONNX 런타임에서 실행하기 ======================================================================== -In this tutorial, we describe how to convert a model defined -in PyTorch into the ONNX format and then run it with ONNX Runtime. +이 튜토리얼에서는 어떻게 PyTorch에서 정의된 모델을 ONNX 형식으로 변환하고 또 어떻게 그 변환된 모델을 +ONNX 런타임에서 실행할 수 있는지에 대해 알아보도록 하겠습니다. -ONNX Runtime is a performance-focused engine for ONNX models, -which inferences efficiently across multiple platforms and hardware -(Windows, Linux, and Mac and on both CPUs and GPUs). -ONNX Runtime has proved to considerably increase performance over -multiple models as explained `here -`__ +ONNX 런타임은 ONNX 모델을 위한 엔진으로서 성능에 초점을 맞추고 있고 여러 다양한 플랫폼과 하드웨어(윈도우, +리눅스, 맥을 비롯한 플랫폼 뿐만 아니라 CPU, GPU 등의 하드웨어)에서 효율적인 추론을 가능하게 합니다. +ONNX 런타임은 `여기 +`__ 에서 +설명된 것과 같이 여러 모델들의 성능을 상당히 높일 수 있다는 점이 증명되었습니다. -For this tutorial, you will need to install `ONNX `__ -and `ONNX Runtime `__. -You can get binary builds of ONNX and ONNX Runtime with -``pip install onnx onnxruntime``. -Note that ONNX Runtime is compatible with Python versions 3.5 to 3.7. +본 튜토리얼을 위해서는 `ONNX `__ +and `ONNX Runtime `__ 를 설치해야합니다. +ONNX와 ONNX 런타임의 바이너리 빌드를 ``pip install onnx onnxruntime`` 를 통해 받을 수 있습니다. +ONNX 런타임은 버전 3.5에서 3.7까지의 Python과 호환됩니다. -``NOTE``: This tutorial needs PyTorch master branch which can be installed by following -the instructions `here `__ +``노트``: 본 튜토리얼은 PyTorch의 master 브랜치를 필요로하며 `링크 `__ 에서 +설치할 수 있습니다. """ -# Some standard imports +# 필요한 import문 import io import numpy as np @@ -33,24 +31,22 @@ ###################################################################### -# Super-resolution is a way of increasing the resolution of images, videos -# and is widely used in image processing or video editing. For this -# tutorial, we will use a small super-resolution model. +# 초해상화(super-resolution)란 이미지나 비디오의 해상도를 높이기 위한 방법으로 이미지 프로세싱이나 비디오 편집에 널리 +# 사용되고 있는 방법입니다. 이 튜토리얼에서는 사이즈가 작은 초해상화 모델을 사용하도록 하겠습니다. # -# First, let's create a SuperResolution model in PyTorch. -# This model uses the efficient sub-pixel convolution layer described in -# `"Real-Time Single Image and Video Super-Resolution Using an Efficient -# Sub-Pixel Convolutional Neural Network" - Shi et al `__ -# for increasing the resolution of an image by an upscale factor. -# The model expects the Y component of the YCbCr of an image as an input, and -# outputs the upscaled Y component in super resolution. +# 먼저, 초해상화 모델을 PyTorch에서 구현하겠습니다. +# 이 모델은 `"Real-Time Single Image and Video Super-Resolution Using an Efficient +# Sub-Pixel Convolutional Neural Network" - Shi et al `__ 에서 소개된 +# 효율적인 서브픽셀 합성곱 계층을 사용하여 이미지의 해상도를 업스케일 인자만큼 늘립니다. +# 모델은 이미지의 YCbCr 성분 중 Y 성분을 입력값으로 받고 업스케일된 초해상도의 Y 채널 값을 리턴합니다. # -# `The -# model `__ -# comes directly from PyTorch's examples without modification: +# 아래는 +# `링크 +# `__ +# 에서 구현된 것을 그대로 가져온 모델입니다: # -# Super Resolution model definition in PyTorch +# PyTorch에서 구현된 초해상도 모델 import torch.nn as nn import torch.nn.init as init @@ -81,88 +77,77 @@ def _initialize_weights(self): init.orthogonal_(self.conv3.weight, init.calculate_gain('relu')) init.orthogonal_(self.conv4.weight) -# Create the super-resolution model by using the above model definition. +# 위에서 정의된 모델을 사용하여 초해상도 모델 생성 torch_model = SuperResolutionNet(upscale_factor=3) ###################################################################### -# Ordinarily, you would now train this model; however, for this tutorial, -# we will instead download some pre-trained weights. Note that this model -# was not trained fully for good accuracy and is used here for -# demonstration purposes only. +# 위 과정이 끝나면 일반적인 경우에 모델을 학습시키기 시작할 것입니다. 하지만 본 튜토리얼에서는 +# 미리 학습된 가중치들을 사용하도록 하겠습니다. 참고로 이 모델은 높은 정확도에 이를 때까지 학습되지 않았고 +# 본 튜토리얼을 원활히 진행하기 위한 목적으로 사용하는 것입니다. # -# It is important to call ``torch_model.eval()`` or ``torch_model.train(False)`` -# before exporting the model, to turn the model to inference mode. -# This is required since operators like dropout or batchnorm behave -# differently in inference and training mode. +# 모델을 변환하기 전에 모델을 추론 모드로 바꾸기 위해서 ``torch_model.eval()`` 또는 ``torch_model.train(False)`` 를 +# 호출하는 것이 중요합니다. +# 이는 dropout이나 batchnorm과 같은 연산들이 추론과 학습 모드에서 다르게 작동하기 때문에 필요합니다. # -# Load pretrained model weights +# 미리 학습된 가중치를 읽어옵니다 model_url = 'https://s3.amazonaws.com/pytorch/test_data/export/superres_epoch100-44c6958e.pth' -batch_size = 1 # just a random number +batch_size = 1 # 임의의 수 -# Initialize model with the pretrained weights +# 모델을 미리 학습된 가중치로 초기화합니다 map_location = lambda storage, loc: storage if torch.cuda.is_available(): map_location = None torch_model.load_state_dict(model_zoo.load_url(model_url, map_location=map_location)) -# set the model to inference mode +# 모델을 추론 모드로 전환합니다 torch_model.eval() ###################################################################### -# Exporting a model in PyTorch works via tracing or scripting. This -# tutorial will use as an example a model exported by tracing. -# To export a model, we call the ``torch.onnx.export()`` function. -# This will execute the model, recording a trace of what operators -# are used to compute the outputs. -# Because ``export`` runs the model, we need to provide an input -# tensor ``x``. The values in this can be random as long as it is the -# right type and size. -# Note that the input size will be fixed in the exported ONNX graph for -# all the input's dimensions, unless specified as a dynamic axes. -# In this example we export the model with an input of batch_size 1, -# but then specify the first dimension as dynamic in the ``dynamic_axes`` -# parameter in ``torch.onnx.export()``. -# The exported model will thus accept inputs of size [batch_size, 1, 224, 224] -# where batch_size can be variable. -# -# To learn more details about PyTorch's export interface, check out the -# `torch.onnx documentation `__. +# 이제 Tracing이나 스크립팅을 통해서 PyTorch 모델을 변환할 수 있습니다. +# 이 튜토리얼에서는 tracing을 통해 변환된 모델을 사용하도록 하겠습니다. +# 모델을 변환하기 위해서는 ``torch.onnx.export()`` 함수를 호출합니다. +# 이 함수는 모델을 실행하여 어떤 연산자들이 출력값을 계산하는데 사용되었는지를 기록합니다. +# ``export`` 함수가 모델을 실행하기 때문에, 우리가 직접 텐서를 입력값으로 넘겨주어야 합니다. +# 이 텐서의 값은 알맞은 자료형과 모양이라면 랜덤하게 결정되어도 무방합니다. +# 특정 차원을 동적인 차원으로 지정하지 않는 이상, ONNX로 변환된 그래프의 경우 입력값의 사이즈는 모든 차원에 대해 고정됩니다. +# 예시에서는 모델이 항상 배치 사이즈 1을 사용하도록 변환하였지만, 첫번째 차원을 ``torch.onnx.export()`` 의 +# ``dynamic_axes`` 인자에 동적인 차원으로 지정해주면 됩니다. +# +# PyTorch의 변환 인터페이스에 대해 더 자세히 알고 싶다면 +# `torch.onnx 문서 `__ 를 참고해주세요. # -# Input to the model +# 모델에 대한 입력값 x = torch.randn(batch_size, 1, 224, 224, requires_grad=True) torch_out = torch_model(x) -# Export the model -torch.onnx.export(torch_model, # model being run - x, # model input (or a tuple for multiple inputs) - "super_resolution.onnx", # where to save the model (can be a file or file-like object) - export_params=True, # store the trained parameter weights inside the model file - opset_version=10, # the ONNX version to export the model to - do_constant_folding=True, # whether to execute constant folding for optimization - input_names = ['input'], # the model's input names - output_names = ['output'], # the model's output names - dynamic_axes={'input' : {0 : 'batch_size'}, # variable lenght axes +# 모델 변환 +torch.onnx.export(torch_model, # 실행될 모델 + x, # 모델 입력값 (튜플 또는 여러 입력값들도 가능) + "super_resolution.onnx", # 모델 저장 경로 (파일 또는 파일과 유사한 객체 모두 가능) + export_params=True, # 모델 파일 안에 학습된 모델 가중치를 저장할지의 여부 + opset_version=10, # 모델을 변환할 때 사용할 ONNX 버전 + do_constant_folding=True, # 최적하시 상수폴딩을 사용할지의 여부 + input_names = ['input'], # 모델의 입력값을 가리키는 이름 + output_names = ['output'], # 모델의 출력값을 가리키는 이름 + dynamic_axes={'input' : {0 : 'batch_size'}, # 가변적인 길이를 가진 차원 'output' : {0 : 'batch_size'}}) ###################################################################### -# We also computed ``torch_out``, the output after of the model, -# which we will use to verify that the model we exported computes -# the same values when run in ONNX Runtime. +# ONNX 런타임에서 변환된 모델을 사용했을 때 같은 결과를 얻는지 확인하기 위해서 ``torch_out`` 를 계산합니다. # -# But before verifying the model's output with ONNX Runtime, we will check -# the ONNX model with ONNX's API. -# First, ``onnx.load("super_resolution.onnx")`` will load the saved model and -# will output a onnx.ModelProto structure (a top-level file/container format for bundling a ML model. -# For more information `onnx.proto documentation `__.). -# Then, ``onnx.checker.check_model(onnx_model)`` will verify the model's structure -# and confirm that the model has a valid schema. -# The validity of the ONNX graph is verified by checking the model's -# version, the graph's structure, as well as the nodes and their inputs -# and outputs. +# ONNX 런타임에서의 모델 결과값을 확인하기 전에 먼저 ONNX API를 사용해 ONNX 모델을 확인해보도록 하겠습니다. +# 먼저, ``onnx.load("super_resolution.onnx")`` 는 저장된 모델을 읽어온 후 +# 머신러닝 모델을 취합하여 저장하고 있는 상위 파일 컨테이너인 onnx.ModelProto를 리턴합니다. +# onnx.ModelProto에 대해 더 자세한 것은 `onnx.proto 기술문서 `__ 에서 +# 확인하실 수 있습니다. +# ``onnx.checker.check_model(onnx_model)`` 는 모델의 구조를 확인하고 +# 모델이 타당한 스키마를 가지고 있는지를 체크합니다. +# ONNX 그래프의 타당성은 모델의 버전, 그래프 구조, 노드들, 그리고 입력값과 출력값들을 모두 체크하여 +# 결정됩니다. # import onnx @@ -172,18 +157,15 @@ def _initialize_weights(self): ###################################################################### -# Now let's compute the output using ONNX Runtime's Python APIs. -# This part can normally be done in a separate process or on another -# machine, but we will continue in the same process so that we can -# verify that ONNX Runtime and PyTorch are computing the same value -# for the network. -# -# In order to run the model with ONNX Runtime, we need to create an -# inference session for the model with the chosen configuration -# parameters (here we use the default config). -# Once the session is created, we evaluate the model using the run() api. -# The output of this call is a list containing the outputs of the model -# computed by ONNX Runtime. +# 이제 ONNX 런타임의 Python API를 통해 결과값을 계산해보도록 하겠습니다. +# 이 부분은 보통 별도의 프로세스 또는 별도의 머신에서 실행되지만, 이 튜토리얼에서는 모델이 +# ONNX 런타임과 PyTorch에서 동일한 결과를 출력하는지를 확인하기 위해 동일한 프로세스에서 계속 실행하도록 +# 하겠습니다. +# +# 모델을 ONNX 런타임에서 실행하기 위해서는 미리 설정된 인자들(본 예제에서는 기본값을 사용합니다)로 +# 모델을 위한 추론 세션을 생성해야 합니다. +# 세션이 생성되면, 모델의 run() API를 사용하여 모델을 실행합니다. +# 이 API의 리턴값은 ONNX 런타임에서 연산된 모델의 결과값들을 포함하고 있는 리스트입니다. # import onnxruntime @@ -193,55 +175,50 @@ def _initialize_weights(self): def to_numpy(tensor): return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy() -# compute ONNX Runtime output prediction +# ONNX 런타임에서 계산된 결과값 ort_inputs = {ort_session.get_inputs()[0].name: to_numpy(x)} ort_outs = ort_session.run(None, ort_inputs) -# compare ONNX Runtime and PyTorch results +# ONNX 런타임과 PyTorch에서 연산된 결과값 비교 np.testing.assert_allclose(to_numpy(torch_out), ort_outs[0], rtol=1e-03, atol=1e-05) print("Exported model has been tested with ONNXRuntime, and the result looks good!") ###################################################################### -# We should see that the output of PyTorch and ONNX Runtime runs match -# numerically with the given precision (rtol=1e-03 and atol=1e-05). -# As a side-note, if they do not match then there is an issue in the -# ONNX exporter, so please contact us in that case. +# 이제 PyTorch와 ONNX 런타임에서 연산된 결과값이 서로 일치하는지 오차범위 (rtol=1e-03, atol=1e-05) +# 이내에서 확인해야 합니다. +# 만약 결과가 일치하지 않는다면 ONNX 변환기에 문제가 있는 것이니 저희에게 알려주시기 바랍니다. # ###################################################################### -# Running the model on an image using ONNX Runtime +# ONNX 런타임에서 이미지를 입력값으로 모델을 실행하기 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ###################################################################### -# So far we have exported a model from PyTorch and shown how to load it -# and run it in ONNX Runtime with a dummy tensor as an input. +# 지금까지 PyTorch 모델을 변환하고 어떻게 ONNX 런타임에서 구동하는지 가상의 텐서를 입력값으로 하여 +# 살펴보았습니다. ###################################################################### -# For this tutorial, we will use a famous cat image used widely which -# looks like below +# 본 튜토리얼에서는 아래와 같은 유명한 고양이 사진을 사용하도록 하겠습니다. # # .. figure:: /_static/img/cat_224x224.jpg # :alt: cat # ###################################################################### -# First, let's load the image, pre-process it using standard PIL -# python library. Note that this preprocessing is the standard practice of -# processing data for training/testing neural networks. +# 먼저, PIL 라이브러리를 사용하여 이미지를 로드하고 전처리하겠습니다. 이 전처리는 신경망 학습과 테스트에 +# 보편적으로 적용되고 있는 전처리 과정입니다. # -# We first resize the image to fit the size of the model's input (224x224). -# Then we split the image into its Y, Cb, and Cr components. -# These components represent a greyscale image (Y), and -# the blue-difference (Cb) and red-difference (Cr) chroma components. -# The Y component being more sensitive to the human eye, we are -# interested in this component which we will be transforming. -# After extracting the Y component, we convert it to a tensor which -# will be the input of our model. +# 먼저 이미지를 모델의 입력값 사이즈(224x224)에 맞게 리사이즈합니다. +# 그리고 이미지를 Y, Cb, Cr 성분으로 분해합니다. +# Y 성분[역자 주: 휘도 성분]은 그레이스케일(회색조) 이미지를 나타내고, Cb 성분은 파란색에서 밝기를 뺀 색차 성분, +# Cr은 빨강색에서 밝기를 뺀 색차 성분을 나타냅니다. +# 사람의 눈은 Y 성분에 더 민감하게 반응하기 때문에 저희에게는 현재 이 성분이 중요하고, 이 Y 성분을 변환할 것입니다. +# Y 성분을 뽑아낸 뒤에, 추출한 Y 성분을 모델의 입력값이 될 텐서로 변환합니다. # from PIL import Image @@ -261,9 +238,8 @@ def to_numpy(tensor): ###################################################################### -# Now, as a next step, let's take the tensor representing the -# greyscale resized cat image and run the super-resolution model in -# ONNX Runtime as explained previously. +# 다음은 리사이즈된 그레이스케일 고양이 이미지 텐서를 앞서 설명했던 것처럼 초해상도 모델에 넘겨주어 +# ONNX 런타임에서 실행하도록 하겠습니다. # ort_inputs = {ort_session.get_inputs()[0].name: to_numpy(img_y)} @@ -272,17 +248,15 @@ def to_numpy(tensor): ###################################################################### -# At this point, the output of the model is a tensor. -# Now, we'll process the output of the model to construct back the -# final output image from the output tensor, and save the image. -# The post-processing steps have been adopted from PyTorch -# implementation of super-resolution model -# `here `__. +# 이렇게 하면 모델의 결과값은 텐서가 됩니다. +# 이제 모델의 결과값을 처리하여 결과값 텐서에서 마지막 최종 출력 이미지를 만들고 이를 저장해보도록 하겠습니다. +# 후처리 단계는 `링크 `__ 에 +# 구현되어있는 초해상도 모델 코드에서 가져온 것입니다. # img_out_y = Image.fromarray(np.uint8((img_out_y[0] * 255.0).clip(0, 255)[0]), mode='L') -# get the output image follow post-processing step from PyTorch implementation +# PyTorch 버전의 후처리 과정 코드를 이용해 결과 이미지 만들기 final_img = Image.merge( "YCbCr", [ img_out_y, @@ -290,7 +264,7 @@ def to_numpy(tensor): img_cr.resize(img_out_y.size, Image.BICUBIC), ]).convert("RGB") -# Save the image, we will compare this with the output image from mobile device +# 이미지를 저장하고 모바일 기기에서의 결과 이미지와 비교하기 final_img.save("./_static/img/cat_superres_with_ort.jpg") @@ -299,14 +273,15 @@ def to_numpy(tensor): # :alt: output\_cat # # -# ONNX Runtime being a cross platform engine, you can run it across -# multiple platforms and on both CPUs and GPUs. -# -# ONNX Runtime can also be deployed to the cloud for model inferencing -# using Azure Machine Learning Services. More information `here `__. +# ONNX 런타임은 크로스플랫폼 엔진으로서 CPU와 GPU 뿐만 아니라 여러 플랫폼에서 실행될 수 있습니다. # -# More information about ONNX Runtime's performance `here `__. +# ONNX 런타임은 Azure Machine Learning Services와 같은 클라우드에 배포되어 모델 추론을 하는데 +# 사용될 수도 있습니다. +# 더 자세한 내용은 `링크 `__ 를 +# 참조해주십시오. # +# ONNX 런타임의 성능에 관한 것은 `여기 `__ 에서 +# 확인하실 수 있습니다. # -# For more information about ONNX Runtime `here `__. +# ONNX 런타임에 관한 더 자세한 내용은 `이 곳 `__ 을 참조해 주세요. # diff --git a/intermediate_source/dist_tuto.rst b/intermediate_source/dist_tuto.rst index 9d4011e68..e2e6262fa 100644 --- a/intermediate_source/dist_tuto.rst +++ b/intermediate_source/dist_tuto.rst @@ -74,7 +74,7 @@ PyTorch에 포함된 분산 패키지(예. ``torch.distributed``)는 연구자 ``dist.init_process_group`` 에서 일어나는 놀라운 일을 살펴볼 것이지만, 기본적으로는 프로세스가 자신의 위치를 공유함으로써 서로 통신할 수 있도록 합니다. -지점-대-지점 간(Point-to-Point) 통신 +점대점(Point-to-Point) 통신 --------------------------------------- .. figure:: /_static/img/distributed/send_recv.png @@ -85,13 +85,13 @@ PyTorch에 포함된 분산 패키지(예. ``torch.distributed``)는 연구자 송신과 수신 -하나의 프로세스에서 다른 프로세스로 데이터를 전송하는 것을 지점-대-지점 간 통신이라고 합니다. -지점간 통신은 ``send`` 와 ``recv`` 함수 또는 즉시 응답하는(*immediate* counter-parts) +하나의 프로세스에서 다른 프로세스로 데이터를 전송하는 것을 점대점 통신이라고 합니다. +두 지점 간 통신은 ``send`` 와 ``recv`` 함수 또는 즉시 응답하는(*immediate* counter-parts) ``isend`` 와 ``irecv`` 를 사용합니다. .. code:: python - """블로킹(blocking) 지점-대-지점 간 통신""" + """블로킹(blocking) 점대점 통신""" def run(rank, size): tensor = torch.zeros(1) @@ -114,7 +114,7 @@ PyTorch에 포함된 분산 패키지(예. ``torch.distributed``)는 연구자 .. code:: python - """논-블로킹(non-blocking) 지점-대-지점 간 통신""" + """논-블로킹(non-blocking) 점대점 간 통신""" def run(rank, size): tensor = torch.zeros(1) @@ -141,7 +141,7 @@ PyTorch에 포함된 분산 패키지(예. ``torch.distributed``)는 연구자 그러나, ``req.wait()`` 를 실행한 후에는 통신이 이루어진 것을 보장받을 수 있기 때문에, ``tensor[0]`` 에 저장된 값은 1.0이 됩니다. -지점-대-지점 간 통신은 프로세스 간 통신에 대한 세밀한 제어를 원할 때 유용합니다. +점대점 통신은 프로세스 간 통신에 대한 세밀한 제어를 원할 때 유용합니다. `바이두(Baidu)의 DeepSpeech `__ 나 `페이스북(Facebook)의 대규모 실험 `__ 에서 사용하는 것과 같은 멋진 알고리즘을 구현할 때 사용할 수 있습니다.