컨버터중 ReduceMean 연산자 지원 문의

안녕하세요.
ENLIGHT TM NPU SW Tookit Manual version v2.0rl.f 문서 46p Appendix A.2 pytorch operator Table A.2에 reducemean 연산이 [h,w]가 가능하다고 적혀있는데,
image

제가 컨버트 하고자 하는 모델에는 reducemean 연산이 아래와 같이 정의되어 있습니다.

하지만 컨버터를 하는 도중 아래와 같은 에러가 나서 문의드립니다.


모델에 reducemean 연산에는 두개 다 1x2560 사이즈가 들어갑니다.

  1. 안되는 이유가 컨버터가 1x2560에서 2560을 채널로 인식해서 안되는건지, 아니면 [h,w]꼴의 2차원만 가능한건지 궁금합니다.

  2. 문서에 적혀있지 않은 sqrt, pow, reshape 외에 또 안되는 레이어가 있다면 알려주시면 감사하겠습니다.

  3. 모델 끝부분 slice는 왼쪽부터 1x91224 텐서를 각각 1x57600, 1x32400, 1x576, 1x624 로 자르는 operator 인데, 마찬가지로 문서에는 적혀있으나 아래와 같은 에러가 납니다. 32배수가 아니어서 지원안되는 것이 맞는지 확인 부탁드립니다.(row-wise의 뜻이 정확히 무엇인지도 설명부탁드립니다.)

image

  1. batchnormalization 말고 layer nomalization은 지원 계획이 아예 없는지 궁금합니다.

감사합니다.

안녕하세요.

사용하신 모델 공유 부탁드립니다.
확인해보고 답변 드리겠습니다.

감사합니다.

안녕하세요.

위의 여러가지 문제점 때문에 모델 구성을 변경하여 재학습 중입니다.

  1. layer norm을 제거하고 batch norm을 추가하여 학습하고 해당 모델을 convert하고자 하였으나 아래와 같은 에러가 났습니다.

BatchNorm1d를 사용하였는데, BatchNorm2d만 가능한지 궁금합니다.

  1. LayerNorm을 제거하고 batchnorm도 추가하지 않은 상태에서 convert를 시도했으나 flatten 레이어를 인지하지 못하는 걸로 생각됩니다. layernorm이 flatten 뒤에 붙어있을 땐 없는 오류였는데, layernorm을 지우고 원래 layernorm 뒤에 붙어 있던 linear를 바로 붙였더니 오류가 발생하였습니다.

사용한 모델 공유드립니다.
1번 모델 → BN.onnx
2번 모델 → LN.onnx
기존 모델 → orin.onnx

https://drive.google.com/drive/folders/1ifMKrszFQZG9LrkgguTbVv8Niqw4RVxb?usp=drive_link

감사합니다.

안녕하세요.

  1. 안되는 이유가 컨버터가 1x2560에서 2560을 채널로 인식해서 안되는건지, 아니면 [h,w]꼴의 2차원만 가능한건지 궁금합니다.
    → NPU 에서 지원 가능한 ReduceMean은 N,C,H,W 4dimension 구조의 tensor만을 지원합니다. 4dim인 겨우 RedeceMean(w/ axes = [h, w])은 global average pooling과 동일한 동작입니다.
    하지만 테스트 신경망에서 Reducemean은 Flatten 이후 2dimension 이며 2dimension 입력에 대한 Reducemean은 지원하지 않습니다.

  2. 문서에 적혀있지 않은 sqrt, pow, reshape 외에 또 안되는 레이어가 있다면 알려주시면 감사하겠습니다.
    → Pow, Sqrt, Div는 dimension 크기와 관계없이 지원하지 않습니다. reshape의 경우, reshape이후 flatten 이 오는 경우에 한하여 제한적으로 지원하고 있습니다.
    아래 그림과 같이 Gemm → 4 [ Slice → Reshape → output*] 구조 신경망을 예로 설명 드리겠습니다
    2 dimension 입력에 대한 Slice와 Reshape은 NPU Toolkit에서 지원하지 않습니다.


    대신 Gemm 이후 Slice, Reshape layer는 post process 과정에서 처리하고 ONNX 신경망에서는 제외하는 것을 제안 드립니다.

  3. 모델 끝부분 slice는 왼쪽부터 1x91224 텐서를 각각 1x57600, 1x32400, 1x576, 1x624 로 자르는 operator 인데, 마찬가지로 문서에는 적혀있으나 아래와 같은 에러가 납니다. 32배수가 아니어서 지원안되는 것이 맞는지 확인 부탁드립니다.(row-wise의 뜻이 정확히 무엇인지도 설명부탁드립니다.)
    → Slice 처리 방안은 “2”에서 답변 드린 봐와 같이 post processing 에서 처리가 적절해 보입니다.
    row-wise: 4 dimension (= B,C,H,W) 입력 텐서의 height 방향으로 slicing 가능하다는 의미 입니다.

  4. batchnormalization 말고 layer nomalization은 지원 계획이 아예 없는지 궁금합니다.
    → 지원계획이 없습니다.

  1. layer norm을 제거하고 batch norm을 추가하여 학습하고 해당 모델을 convert하고자 하였으나 아래와 같은 에러가 났습니다.


    BatchNorm1d를 사용하였는데, BatchNorm2d만 가능한지 궁금합니다.
    → 네. 그리고 BatchNorm2d → Flatten 순으로 신경망을 변경하시면 처리 가능합니다.

  2. LayerNorm을 제거하고 batchnorm도 추가하지 않은 상태에서 convert를 시도했으나 flatten 레이어를 인지하지 못하는 걸로 생각됩니다. layernorm이 flatten 뒤에 붙어있을 땐 없는 오류였는데, layernorm을 지우고 원래 layernorm 뒤에 붙어 있던 linear를 바로 붙였더니 오류가 발생하였습니다.
    → 추가 테스트 후 답변 드리겠습니다.

감사합니다.

우선 답변 감사드립니다.
다른 내용은 모두 확인했고, flatten이 convert 되지 않는 문제만 테스트 진행해보고 답변주시면 감사하겠습니다.


Flatten 입력 H, W 값이 1인 경우에만 지원하고 있습니다. Flatten → Reshape으로 변경하면 추가 학습 과정없이 Toolkit에서 지원 가능합니다.

말씀해주신데로 reshape을 사용하고 slice 이후는 제거한 후에 convert해보았습니다.
하지만 convert와 quantization 까진 잘 되었으나 compile 단계에서 아래와 같은 오류가 발생합니다.

감사합니다.

안녕하세요.
Reshape 으로 변경하신 신경망 전달해 주시면 디버깅 후에 필요하면 툴킷 업데이트 해 드리겠습니다.
감사합니다.

https://drive.google.com/drive/folders/1ifMKrszFQZG9LrkgguTbVv8Niqw4RVxb?usp=drive_link

모델 공유드립니다.

감사합니다.

onnx file을 export 한 소스를 전달해 주시면 좀 더 빠르게 대응해 드릴 수 있을 것 같습니다.

감사합니다.

model을 훈련시킨 소스 코드(model_culane.py), pth 파일을 onnx로 변환하는 코드(pt2onnx.py), 그리고 onnx 파일로 변환하기 전 pth 파일 3가지 추가 첨부하였습니다.

참고사항 : 해당 파일들은 GitHub - cfzd/Ultra-Fast-Lane-Detection-v2: Ultra Fast Deep Lane Detection With Hybrid Anchor Driven Ordinal Classification (TPAMI 2022)
ufldv2 git hub에서 더 자세히 확인 가능합니다.

안녕하세요.
신경망 입력 크기를 1024x320 에 512x320 정도로 줄여야 합니다. 줄어든 신경망 크기에 따라 Gemm parameter 로 변경해야 합니다.
변경하신 신경망 onnx파일 공유 부탁드립니다.
감사합니다.

줄여야하는 이유가 뭘까요? 저번에 입력크기는 1028 이하로 줄여야 한다고 하셨는데, 512까지 줄이면 성능이 많이 떨어질 것으로 예상됩니다. 그리고 reshape을 해야하는건데 gemm 파라미터로 어떻게 진행해야하는지도 설명 부탁드립니다. channel로 convolution을 말씀하시는건가요?

감사합니다.

안녕하세요.

NPU 에서 연산 layer 동작은 32 ch의 배수로 처리 합니다.

테스트 중인 ufldv2.onnx 신경망의 마지막 Conv의 output dim은 [1x8x10x32] 은 NPU에서는 32의 배수로 동작합니다.
그리고 Reshape을 거친 Gemm input dim은 4배 증가 한 2560 → 10240이 됩니다.
이렇게 증가한 Gemm 실제 input tensor dim 10240이 8192 보다 작아야 합니다.

첨부드리는 동영상과 압축 파일은 800x288 입력 영상에 대한 오픈엣지 학습 ufld 신경망입니다.
오픈엣지 신경망은
Conv 1x1 in_ch=512, out_ch=8 대신 Conv가 3x3 stride=2, out ch = 32

두 번째 Gemm out_ch 91224 대신 14472로 변경 하였습니다.

마지막으로 1024x300에서 width만 512로 줄이는 방법 대신 800x288로 width, height 를 동시에 줄이는 것이 좋을 것 같습니다. 말씀하신 것과 같이 정확도는 하락 할 것 같지만, 일반적으로 영상 크기에 비례하여 떨어지지 않습니다.

감사합니다.

답변 감사합니다. 첨부해주신 ufldv1 확인해보겠습니다.
마지막으로 더 여쭤보면,

그리고 Reshape을 거친 Gemm input dim은 4배 증가 한 2560 → 10240이 됩니다.

  1. 4배가 되는 이유가 제가 배치사이즈를 4로 잡았기 때문인가요? 만약 배치를 2로 잡아서 8192보다 작은 5120이 되게 하면 문제가 없을까요? 4배가 되는 이유가 궁금합니다.

  2. 마지막 출력 Gemm output은 91224를 유지해도 문제 없을까요?

  3. 800x288로 바꾼 후에도 reshape을 하려면 32채널이 되도록 하면 되는건가요?

  4. 1024x320을 유지하고 마지막 cov를 변경하여 conv_output(=gemm_input)을 1x32x4x12 정도로 줄인다면 문제 없을까요?

  5. permute 연산은 안되나요?

감사합니다.

  1. 4배가 되는 이유가 제가 배치사이즈를 4로 잡았기 때문인가요? 만약 배치를 2로 잡아서 8192보다 작은 5120이 되게 하면 문제가 없을까요? 4배가 되는 이유가 궁금합니다.
    → NPU HW 가 처리하는 ch 단위가 32 배수입니다. 그래서 원래 Conv [1x8x10x32] 해당하는 연산을 ch방향으로 zero padding을 28개 추가해서[1x32x10x32] 에 해당하는 연산과 DRAM에 write 합니다. Batch와는 관련 없습니다.

  2. 마지막 출력 Gemm output은 91224를 유지해도 문제 없을까요?
    → 저희 OE는 91224 → 14472로 변환해서 원하는 결과를 얻었습니다. 전에 말씀드린 것과 같이 91224x2048은 ~180MB에 해당하는 layer weight size 입니다. 보드에서 실행할 수 있는 버퍼 크기가 얼만큼인지 확인 하셔야 합니다.

  3. 800x288로 바꾼 후에도 reshape을 하려면 32채널이 되도록 하면 되는건가요?
    → 첫 번째 질문에서 답변 드린 것과 같이 8ch로 하셔도 가능은 해 보이나, NPU는 32ch 단위로 동작하기 때문에 ch을 8로 줄여서 얻을 수 있는 이득이 없습니다. 가능한 한 NPU SW toolkit에서 테스트 된 Conv2d 3x3 stride=2 in_ch=512, out_ch=32 추천합니다.

  4. 1024x320을 유지하고 마지막 cov를 변경하여 conv_output(=gemm_input)을 1x32x4x12 정도로 줄인다면 문제 없을까요?
    → 컴파일은 가능해 보입니다. 하지만 마지막 Gemm layer 를 변경하지 않으면 보드에서 원하는 FPS를 얻기 힘들며, 저희도 BSP 지원에 많은 노력을 하셔야 할 것으로 예상 됩니다.

네 답변 감사합니다.

추천해주신 방법으로 시도해보겠습니다.

감사합니다.