UFID v1 관련 문의드립니다

현재 AI-G 보드에서 UFLD v1 모델을 사용하여 컴파일 단계까지는 정상적으로 완료하였습니다. 컨버팅 과정에서 마지막 reshape layer를 제거한 후 custom_postproc.c 파일을 수정하여 후처리 작업을 진행하고 있으나, 원하는 결과가 나오지 않아 문의드립니다.

혹시 reshape layer를 제거한 이후의 전체 컨버팅 절차나 참고할 만한 예제 코드, 또는 샘플 파일 등이 있다면 안내해주실 수 있을지 문의드립니다. 관련 자료나 조언을 주시면 문제 해결에 큰 도움이 될 것 같습니다.

안녕하세요. TOPST 매니저입니다.
현재 후 처리를 custom type으로 설정하고 모델을 변환하는 과정에 대한 가이드는 준비 중에 있습니다.
현재 주신 모델에서 모델 뒷단의 reshape를 제거하셨는데, 현재 reshape는 한정적으로 지원하여 flatten 즉, 데이터의 배열 순서를 바꾸지 않는 기능에 해당하는 reshape 연산을 지원합니다.
때문에 reshape 2개를 모두 제거할 필요 없이 마지막 1개의 레이어인 reshape를 제거하고 컨볼루션 연산을 최종 출력으로 선택하시면 됩니다.
이후엔 1x14472x1x1의 출력이 나오는데 해당 값을 custom_postproc.c에서 for문을 통해 reshpae 과정을 거쳐 1x201x18x4로 변환하시면 됩니다.

ufld 모델은 pytorch모델로 모델 자체에 후처리 과정이 포함되어 있지않아 공식 github에서도 모델을 실행할 때 후처리 과정을 거치게 됩니다.
1x201x18x4는 각각 배치사이즈, x, y, 차선 id를 뜻하며 해당 출력을 가지고 softmax → 가중 평균 합 → argmax(차선 인지 판단하는 작업) 을 거쳐 최종적으로 4x18에 해당하는 72개의 차선 좌표를 얻으실 수 있습니다.
이 연산은 공식 github의 demo.py를 통해 참고하셔서 작성하시면 될것 같습니다.

진행하다 막히시는 부분이 생기신다면 언제든 댓글 남겨주세요.
감사합니다.


–force-output 혹시 여기에 Gemm는 어떻게 코드를 작성해야 하는지 알고싶습니다.

Gemm 연산을 c코드로 구현하겠다는 말씀이실까요?
Gemm은 코드로 작성하지 않고 최종 출력 레이어로 선택하시면 됩니다. 작성하실 부분은 reshape 연산만 작성하시고 이후에는 ufld 좌표를 구하기 위한 연산을 진행하시면 됩니다.
Gemm 레이어의 이름은 .enlight로 변환된 모델을 netron으로 여셔서 확인하시면 됩니다.
감사합니다.

위의 그림과 같이 최종 출력 레이어를 선택 하라는 말로 이해 했는데 python
양자화 코드에서 ./EnlightSDK/converter.py ./input_networks/ufld_culane.onnx --type unknown --logistic softmax --dataset Custom --dataset-root ./my_dataset_path --output ./output_networks/UFLD.enlight --enable-track --mean 0.485 0.456 0.406 --std 0.229 0.224 0.225 --num-class 4 --variance 0.1 0.2 --force-output Conv2d_20___pool_Conv –force-output 이게 최종 출력을 강제로 지정하는 코드로 알고 있습니다. .enlight로 변환된 모델을 netron.app에서 열어서 Gemm 레이어의 이름을 확인 하려고 했는데 .enlight 파일은 netron에서 열리지 않아서 문의드립니다. EnlightSDK/analyze.py로 봤을때는 아래와 같은 이름만 나와서 사용하기 힘들거 같습니다.

.enlight 파일이 열리지 않으신다면 기존의 netron을 제거하시고 setup_venv.sh 스크립트를 통해 다시 가상환경을 설치하시고 netron을 사용하면 적용될 것 같습니다.

감사합니다.

Gemm layer까지 양자화는 완료 하였습니다. 감사합니다. 추후에 질문 있으면 다시 댓글 달겠습니다!

1 Like

UFLD 모델로 이미지 입력에서는 정상 동작을 확인했습니다. 다만 공식 문서에서는 카메라/이미지 처리 예시만 있는데 동영상(mp4) 파일을 tcnnapp로 직접 처리할 수 있는지 확인하고자 문의드립니다.

동영상의 경우 현재는 rtpm을 통해 추론이 가능합니다.
tcnnapp 내부 소스에서 이미지 대신 비디오를 프레임 단위 입력으로 하여 dsi에 영상 출력 기능을 구현하셔야 할 것 같습니다.
감사합니다.

RTPM으로 영상 스트림을 프레임 단위로 UFLD 차선 추론까지는 확인했습니다. 이제 추론 결과를 영상에 오버레이로 표시하려고 합니다.

~/topst-sdk/build/ai-g-topst/tmp/work/cortexa53-telechips-linux/tc-nn-app/1.0.0-r0/git/ 아래 NPU Sample Application Code를 수정한 뒤 bitbake로 다시 빌드하고, 펌웨어를 업데이트한 다음 tcnnapp를 실행하면 되는지 문의드립니다.

네, 해당 소스에서 코드를 수정한 뒤 bitbake tc-nn-app -c compile -f 명령어를 통해 tc-nn-app을 빌드하시고
topst-sdk/build/ai-g-topst/tmp/work/cortexa53-telechips-linux/tc-nn-app/1.0.0-r0/build/ 밑에 생성된 tcnnapp만 scp 명령어로 aig 보드에 전송한 후 chmod 755 tcnnapp을 통해 권한 주시고, ./tcnnapp으로 명령어 실행하시면 될 것 같습니다.

혹시 지금 추론까지는 확인하셨다고 하셨는데 모델 빌드시에 post_process.c 내부에서 따로 구조체를 선언하고 해당 값을 run_post_process 함수의 인자로 넣어서 tcnnapp 내부에서 사용 가능하도록 수정하셨을까요? 아니면 단순히 모델 내부에서 printf 로그로 추론 결과를 확인만 하셨을까요?

현재는 custom_postproc.c에서 모델의 후처리를 통해 UFLD 좌표를 계산한 뒤, printf 로그로 PC 측 결과와 동일함을 확인했습니다.

영상 오버레이를 위해서는 post_process.c에 결과 구조체를 정의하고 그 값을 run_post_process() 인자로 전달해, tcnnapp에서 활용할 수 있도록 수정해야 하는지 문의드립니다.

네 맞습니다.
reserved 인자 대신 만드신 구조체 ex) loc[72]와 같이 정의 후 넣으시면 tcnnapp 내부 소스에서 똑같은 loc를 선언해 추출하여 활용 가능합니다.

제가 g_lane_loc 구조체를 정의하고 custom_postproc.c에서 후처리한 좌표 값을 넣어서 tcnnapp 내부에서 g_lane_loc 안에 좌표값이 들어가 있는것을 확인했는데 혹시 rtpm에 좌표값에 선이나 점을 표현하기 위한 코드를 어디 부분을 수정해야 되는지 잘 모르겠어서 문의드립니다. NnAppMain.c 파일 안에 NnDrawResult() 함수 안에서 g_lane_loc()를 읽어 출력 프레임 버퍼(outputMapBase)에 직접 그리면, 그 결과가 NnOutputResultFrame()을 통해 RTPM으로 볼 수 있는게 맞는지 아니면 NnRtpm.c 소스코드도 수정해야 하는지 문의드립니다.

NnDrawResult() 안에서 loc를 읽어 프레임 버퍼에 그리면 단순하게 dsi 디스플레이에만 출력되게 됩니다. rtpm으로 보시려면 NnRtpm.c소스 내부에서 json 파일로 변환 후 전송하는 코드까지 구현하시면 될 것 같습니다.
감사합니다.