-
TENSOR RT 란??뜯고 또 뜯어보는 컴퓨터/TENSORRT 2021. 10. 7. 15:13반응형
Welcome to TENSOR RT!
안녕하세요 Tensor RT 에 대해 처음 쓰는 글인데, 모델을 Tensor RT 로 변환 하려다 보니, 어려움이 많아 직접 글을 적게 되었습니다. 혹시 오탈자나 틀린 부분이 있으면 알려주세요! 언제나 환영입니다. 본 글은 엔비디아 TensorRT 도큐먼테이션을 참고하였습니다. https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html
1. Introduction
NVIDIA® TensorRT™ is an SDK that facilitates high performance machine learning inference. It is designed to work in a complementary fashion with training frameworks such as TensorFlow, PyTorch, and MXNet. It focuses specifically on running an already-trained network quickly and efficiently on NVIDIA hardware.TENSOR RT 란?
TENSOR RT 란 양자화 및 컬리브레이션, 그래프 최적화, 커널 자동 튜닝 등등의 기법으로 모델을 GPU 상에서 추론속도를 증가시켜주는 역활을 합니다. 밑은 가장 간단한 예시인데, 밑의 예시는 구글의 LENET 모델의 Inception module 을 virtical optimization을 시켜줌으로써, 최적화 시켜주는 가장 간단한 예시입니다. Tensor RT 로 된 수많은 자료가 있지만, 본 포스팅은 TENSOR RT 를 통한 최적화 방법에 대해 집중적으로 다룰 수 있도록 하겠습니다.
- TENSOR RT 의 설치 방법은 DOCKER 설치로 진행하였으며, https://eehoeskrap.tistory.com/414?category=705774꾸준희 님의 블로그에 굉장히 자세히 설명이 되어있으니 참고하길 바랍니다.
TENSOR RT 기본
1. Introduction
NVIDIA® TensorRT™ is an SDK that facilitates high performance machine learning inference. It is designed to work in a complementary fashion with training frameworks such as TensorFlow, PyTorch, and MXNet. It focuses specifically on running an already-trained network quickly and efficiently on NVIDIA hardware.공식 문서에 나와있는 Tensor RT 에 대한 설명은 다음과 같습니다. Tensor RT란, 공식문서에서는 Machine Learning Inference(추론) 속도를 증가시켜주는 SDK 로 정의가 되어있고, 현재 수많은 머신러닝 프레임 워크 TensorFlow, PyTorch, MXNet 등과 호환이 된다고 합니다.
TENSOR RT CAPABILITY
2.1. C++ and Python APIs
TensorRT’s API has language bindings for both C++ and Python, with nearly identical capabilities. The Python API facilitates interoperability with Python data processing toolkits and libraries like NumPy and SciPy. The C++ API can be more efficient, and may better meet some compliance requirements, for example in automotive applications.- TENSOR RT 의 경우 현재 파이썬 과 C++ 에 대한 API 를 지원해주고 있으며, 파이썬의 경우 NumPy 와 SciPy 등의 라이브러리와 호환이 가능하고, C++ API 의 경우, cuda control 이나 호환성 부분에서 더욱 안정적인 적용이 가능합니다.추가로 필자가 Tensor RT를 사용해본 결과, Tensor RT 와 관련한 github 자료 및 내가 원하는 모델을 Tensor RT로 바꿔주고 싶을 때에는 C++이 훨씬 유리하고 유연하다는 것을 말해주고 싶다..
TENSOR RT PHASE DESCRIPTION
TENSOR RT의 사용방법을 알기전, 기본 사항부터 말씀드리겠습니다. TENSOR RT 의 경우 크게 두가지 PHASE 로 구분이 되어 있는데, 첫번째 단계는 TENSOR RT 로 모델을 구성하는 단계입니다. 이 경우, TENSOR RT 가 타켓 GPU 즉, 현재 내가 쓰고 있는 GPU에 모델을 최적화를 시켜주게 되고(Build Phase), 두번째 단계에서는 최적화된 모델을 추론(Run INFERENCE PHASE)하는데 쓰이게 됩니다. 두번째 PHASE 는 Run Inference 단계로 최적화 된 모델을 가지고 추론을 실시하게 되는 단계입니다.
- BUILDER PHASE - 첫번째 단계
TENSOR RT 는 BUILDER 라는 객체를 가지고 있는데, Network 객체와, 추론 ENGINE 이라는 객체를 만들어 냅니다. 이때 TENSOR RT NETWORK 객체는 TENSOR layer 와 TENSOR 를 가지고 네트워크를 직접 만들 수도 있고, 이미 뽑아낸 모델(Pytorch 와 텐서플로로 미리 build 된 모델)로 TENSORRT Network 엔진을 빌드 할 수도 있는데, 필자는 후자를 강력히 추천합니다. 힘들게 Pytorch 나 Tensor Flow로 모델을 만들어 놨는데, Tensor RT 로 다시 쌓는건 모델이 커질 경우, 굉장히 노동력이 드는 일이기 때문입니다..
하지만 직접 LAYER 를 쌓아줘야 하는일이 있을때도 있는데, 이는 내가 만든 네트워크 Layer 나 특정 tensor를 Tensor RT 가 지원을 하지 않는 경우입니다. 하지만 Tensor RT도 발전을 거듭하는 만큼, 이런일이 발생하는 것은 많이 보지 못하였습니다. ( 참고, 이렇게 생산된 ENGINE 의 경우, Tensor RT 의 버전과 자신이 쓰는 장비에서만 최적화가 된 것이니, 다른 장비에서 돌릴려면, 그 장비에서 또한 마찬가지로 세팅을 해서 ENGINE을 빌드 해줘야합니다.)
처음에는 이해가 잘 안가지만, 예를 한번 봐보면 좀 더 직관적으로 되실 겁니다. (c++ 로도 가능하지만, 빠른 이해를 위해 Python 으로 설하겠습니다 C++ 를 Wrapper 형태로 파이썬 모듈을 작성한 것이라, 파이썬 스럽진 않지만, 빠른 이해와 C++ API 또한 같은 방식으로 이용됩니다.)
다음은 Pytorch 로 작성된 간단한 모델 예시 입니다.
Class net(nn.Module): def __init(self): super(Net,self).__init__() self.conv1 = nn.Conv2d(1, 20, kernel_size = 5) self.conv2 = nn.Conv2d(20,50, kernel_size = 5) self.fc1 = nn.Linear(800,500) self.fc2 = nn.Linear(500,10) def forward(self, x): x = F.max_pool2d(self.conv1(x), kernel_size=2, stride=2) x = F.max_pool2d(self.conv2(x), kernel_size=2, stride=2) x = x.view(-1, 800) x = F.relu(self.fc1(x)) x = self.fc2(x) return F.log_softmax(x, dim=1)
모델은 훈련시키고 난 다음, Weight 파일을 저장하고, 다음과 같이 Builder 를 통해 Network 모델을 정의해 줍니다.
밑에 주석으로 달아 놨지만, Builder 를 선언하기전, TRT LOGGER 를 미리 설정하여, 해당 Logger 를 통해 Builder 를 작성하여 줍니다.# builder 를 선언하기 전 LOGGER 를 먼저 정의 trt.Logger.Warning 말고도 많은 Logger 및 커스텀 Logger가 작성 가능하니 참고. TRT_LOGGER = trt.Logger(trt.Logger.WARNING) ''' 여기서는 TRT_LOGGER 를 설정해주어 Builder 를 만들어주었는데, 방금 만든 Logger를 인자로 넘겨주어 Builder 를 설정해줍니다. 그 다음 builder를 통해 create_network() 를 불러오고 network() 객체를 만들어 주게 됩니다. ''' builder = trt.Builder(TRT_LOGGER) network = builder.create_network() config = builder.create_builder_config()
Builder Config 작성
Builder 의 Config 를 작성해주어야 하는데, Builder 의 Config 는 어떠한 방식으로 모델을 최적화 할것인지에 대한 config(Batch size, input name, output name 등등)입니다. 따라서 Config 를 작성해주면 Tensor RT 는 config에 따라 input 과 output 그리고 runtime 속도등을 최적화 시켜줍니다.# builder 의 config 객체를 생산해준다. -> default config 를 생성 config = builder.create_builder_config() # config 의 max_workspace 를 생성. config.max_workspace_size = common.GiB(1) config.set_flag(trt.BuilderFlag.REFIT)
그 다음 Builder 를 통해 생성된 Network 객체 와 Config 객체 를 가지고, 최종적으로 모델 엔진을 빌드하러 가면 됩니다.
class ModelData(object): INPUT_NAME = "data" INPUT_SHAPE = (1, 28, 28) OUTPUT_NAME = "prob" OUTPUT_SIZE = 10 DTYPE = trt.float32 # 네트워크에 내가 직접 layer 와 weight를 넣어주는 함수 def populate_network_with_some_dummy_weights(network, weights): # 예시로 더미 weight를 생성해서 넣어줌. 나중에 weights를 통해 넣어줄 수 있다. conv1_w = np.zeros((20,5,5), dtype=np.float32) conv1_b = np.zeros(20, dtype=np.float32) # network 모델에 Tensor RT layer 를 쌓아주는 모습 input_tensor = network.add_input(name=ModelData.INPUT_NAME, dtype=ModelData.DTYPE, shape=ModelData.INPUT_SHAPE) conv1 = network.add_convolution(input=input_tensor, num_output_maps=20, kernel_shape=(5,5), kernel=conv1_w, bias=conv1_b) conv1.name = "conv_1" # 이렇게 이름을 적어줘야 나중에, weight 를 통한 Match가 가능(지금은 dummy weight) conv1.stride = (1, 1) network.set_weights_name(conv1_w, 'conv1.weight') conv2_w = weights['conv2.weight'].numpy() conv2_b = weights['conv2.bias'].numpy() conv2 = network.add_convolution(pool1.get_output(0), 50, (5, 5), conv2_w, conv2_b) conv2.stride = (1, 1) 최종적으로 network.mark_output 을 생성. fc2.get_output(0).name = ModelData.OUTPUT_NAME network.mark_output(tensor=fc2.get_output(0))
이제 builder 를 통한 모델 Build 가 마무리 되었는데, 여기서 주의할 점은 builder 가 완료되기 전에 weight 메모리를 release 해주지 말라는 것입니다. Tensor RT 변환을 하기위한 첫번째 단계가 끝났는데, 다음 포스팅에서는 Runtime API 를 돌리는 법에 대해 설명드리겠습니다.
반응형'뜯고 또 뜯어보는 컴퓨터 > TENSORRT' 카테고리의 다른 글
TENSOR RT _ SIMPLE MNIST 예제 (0) 2021.10.12 TENSOR RT - (2) (0) 2021.10.07 - BUILDER PHASE - 첫번째 단계