안녕하세요.
이번 글에서는 실행파일에 대해서 설명한 후, 파이썬으로 실행파일을 만드는 방법에 대해서 말씀드리도록 하겠습니다.
[Note]
실행파일 만드는 순서만 따로 보고싶으시다면 맨 아래 "6. python으로 작성된 딥러닝 실행파일을 만드는 방법 정리"만 참고하시면 될 것 같습니다.
1. 딥러닝 개발을 하는데 실행파일이 왜 필요한가요?
학계에서 딥러닝을 연구하시는 분들은 보통 파이썬으로 train 코드와 evaluation 코드를 작성하고, "train.py" or "test.py" 파일형태로 github에 올립니다. 특히 요즘 같이 top-tier 딥러닝 학회에 논문을 낼 때에는 자신의 코드를 github에 올린 후, 논문에 기재하기도 하죠. 이렇게 코드를 올리면 다운받아서 실제로 잘 돌아가는지도 확인할 수 있겠죠?
그렇다면 딥러닝을 비지니스에서 사용하려고 할 때는 어떨까요?
학계에서는 많은 연구자들에게 어필해야하므로 관련 코드를 github에서 볼 수 있게 해줍니다. 물론 연구자들은 전문가이기 때문에 언제든 github을 통해 돌려볼 수 도 있습니다. 논문도 훌륭하고 코드도 잘 돌아가면 그만큼 저자의 명성이 높아지겠죠.
비지니스에서는 어필해야할 사람들이 누굴까요?
바로, 투자자들입니다. 우리가 학계에서 처럼 투자자들에게 코드를 github에서 다운받아서 돌려보라고 할 수 있을까요? 투자자들이 모델학습에 관심이 있을까요?
학계와 달리 투자자들은 개발에 대해서 전혀 모르고 있을 가능성이 큽니다. 또한, 투자자들의 관심은 단지 모델이 잘 돌아가는지 눈으로 확인하는 것이죠.
그래서, 프로젝트 마무리 단계에 진입하면 자신들의 성과를 보여주기 위해 투자자들에게 개발한 모델을 시연합니다.
예를 들어, 우리가 숫자를 인식하는 딥러닝 프로그램을 만들었다고 해보겠습니다. 투자자들은 간단한 GUI 프로그램을 통해 숫자 인식을 제대로 하는지에만 관심이 있을거에요.
(↓↓↓ 18초 부터 ↓↓↓)
https://www.youtube.com/watch?v=m_VjcyjMlpQ
이러한 GUI 프로그램을 만들기 위해 필요한 것이 실행파일입니다. 즉, .exe 라는 확장자명을 가진 실행파일을 클릭하기만 하면 자동으로 GUI 프로그램이 실행되도록 해주는 것이죠. 이러한 실행파일을 실행시키기 위해서는 단지 학습이 완료된 모델들과 테스트 이미지만 있으면 됩니다.
(파이썬으로 간단한 GUI 프로그램을 만드는 방법은 "pyqt5" 모듈 or "tkinter" 모듈을 이용하면 됩니다. 이 내용은 따로 다루도록 하겠습니다.)
2. PyInstller 모듈
파이썬으로 실행파일을 만드는 과정은 간단합니다.
첫 번째, PyInstller 모듈을 설치해줍니다.
필자는 개발환경으로 anaconda를 이용하고 있기 때문에, anaconda 명령어로 설치해주었습니다.
conda install -c conda-forge pyinstaller
두 번째, 아래 명령어를 이용해 원하는 python파일(.py)을 실행파일(.exe)로 만들어 줍니다.
pyinstaller 원하는파일.py
[예시]
1. VS code 편집기에 YOLOv3를 구현해 놓습니다.
2. YOLOv3를 구현해 놓은 코드를 돌리면 __pycache__ 폴더가 생성됩니다.
(__pycache__ 폴더에는 컴파일되어 실행 준비가 된 Python 3 바이트 코드들이 저장됩니다)
3. 원하는 python 파일을 실행파일로 바꿔주기 위한 명령어를 입력합니다.
4. 명령어를 실행하면 아래와 같이 두 개의 폴더가 생성됩니다.
- dist 폴더: distribute(배포)의 약자입니다. 즉, 배포되는 파일이 들어 있는 디렉토리라고 보시면 됩니다. dist 폴더에 실행파일이 만들어졌음을 확인할 수 있습니다. 나중에 시연할 때에는 아래의 실행파일이용하면 됩니다.
3. pyinstaller 업데이트 (Feat. No module named)
지금부터는 아래와 같이 'main_for_exe.py' 파일을 실행파일로 만들어보겠습니다.
만약 pyinstaller를 처음 설치하고 바로 실행파일을 만들고 실행('main_for_exe.exe')하면, 아래와 같이 "No module named"라는 에러 메시지가 뜰 가능성이 있습니다. 제가 사용하고 있는 vscode에서는 문제 없이 잘 돌아갔는데, 왜 실행파일을 실행시키면 에러가 날까요?
이유는 간단합니다.
vscode의 interpreter는 anaconda or pip로 설치한 패키지들이 저장되어 있는 디렉토리의 path를 잘 잡아주고 있는 반면, 업그레이드 하지 않은 초기 버전의 pyinstaller 를 이용하면 해당 디렉토리를 못잡아주기 때문에 anaconda 명령어로 설치한 'torch' 모듈을 load 할 수 없게 되는 것이지요.
( ↓↓↓anaconda or pip로 설치한 패키지들이 저장되어 있는 디렉토리↓↓↓)
위와 같은 문제를 해결해주는 방법은 아래와 같이 pyinstaller를 업그레이드 해주는 것입니다. (사실, 최근에 설치했다면 위와 같은 오류가 생성되지는 않을 것입니다.)
pip install --upgrade pyinstaller
위와 같이 업그레이드를 시켜주고 다시 실행파일을 만들면 아래와 같이 hook path로써 "anaconda or pip로 설치한 패키지들이 저장되어 있는 디렉토리"를 잡아주는 것을 확인할 수 있습니다.
4. hidden module (Feat. hidden import)
만약 anaconda or pip로 설치한 모듈이 아닌 다른 github에서 다운 받는 모듈들을 사용하게 되면 추가적인 작업을 해주어야 합니다.
예를 들어, github에서 아래와 같이 'retinanet'이라는 모듈을 다운을 받았다고 가정해보겠습니다.
이때, 'main_for_exe.py'의 실행파일을 만들기 위해서는 추가된 retinanet 모듈의 path도 잡아주어야 합니다.
path를 잡아주는 방법은 간단합니다.
1. 실행파일을 생성했다면 동시에 spec 파일도 생성될 것 입니다.
2. vscode(or 다른 IDE)로 해당 spec 파일을 열어 줍니다.
3. hiddenimports 부분에 추가할 module을 입력 해줍니다.
retinanet.model 모듈을 추가해준 이유는 retinanet만 추가해줬을 때 아래와 같은 에러가 출력됐기 때문입니다.
4. hiddenimports를 추가해주었다면 spec 파일을 아래와 같이 다시 빌드해줍니다.
이렇게 하면 'no module name'과 같이 모듈을 인식하지 못하는 문제는 해결할 수 있을 것입니다.
(사실 pyinstaller 명령어에서 --hidden-import 라는 옵션이 있긴 한데, 위에서 언급한 대로 에러를 잡아가는게 더 정확했던것 같습니다.)
5. 실행파일과 script파일 경로 차이 해결
vscode에서는 문제없이 돌아간 파일을 실행파일로 만들면 아래와 같이 경로에러를 발생시키는 경우가 있습니다.
위의 에러가 난 이유를 아래 코드 디버깅을 통해 살펴보니 retina_model_path 경로 때문인 것으로 파악할 수 있었습니다. 아래 vscode 상에서는 "C:\\Users\\MI2RL\\Desktop\\script\\logs\\Retina_weight\\retinanet101_21.pt"로 잘 설정되어 있지만, 위의 Anaconda Prompt에서는 엉뚱한 경로를 설정하고 있는걸 확인할 수 있었습니다.
아래 디렉토리를 확인해 보니, main_for_exe.exe 실행 파일을 수행하면 현재 실행시킨 경로를 기준으로 파일경로가 재설정되는 듯했습니다. 자세히 말하자면, vscode 상에 'retina_model_path를 설정하는 코드를 보면 'prefix' 변수명에 'logs\Retina_weight\~' 경로를 합쳐주는걸로 되어있는데, vscode 상에서는 script 폴더에서부터 접근하는 반면,
실행파일을 돌리면 script\src\dist 폴더에서부터 접근하는 것으로 보였습니다.
그래서, vscode에서 main_for_exe.py을 실행시켰던 src 디렉토리로 main_for_exe.exe 파일을 옮겨준 후 다시 실행시켜보았습니다.
그러자, 앞서 언급한 경로문제는 해결되었지만, src\dist\main_for_exe 폴더에 main_for_exe.exe가 생성될 때 같이 생성된 다른 모듈들과의 호환문제가 발생했습니다.
위의 에러메시지를 보면 main_for_exe.exe 파일이 생성되는 디렉토리에 관련 모듈들도 동일한 디렉토리에 생성되는데, main_for_exe.exe 파일만 따로 빼내어 실행시키다보니 에러메시지가 나타났습니다.
그래서, src\dist 폴더에 main_for_exe.exe 파일에 모든 모듈을 통합하도록 --onefile 옵션을 주어 파일을 다시 컴파일을 해줍니다.
앞서 --onefile 옵션을 통해 아래와 같이 하나의 exe 파일로 생성됐습니다. 그리고, 해당 파일을 복사한 후
아래 폴더 위치에 다시 옮겨 놓습니다.
[Note]
만약, 위와 같이 main_for_exe.exe 파일을 src\dist 폴더에서 빼내지 않고, 애초에 main_for_exe.exe 파일을 main_for_exe.py 폴더가 위치한 src 폴더에 생성시키려면 아래와 같이 distpath 옵션에 src 폴더경로를 입력해주면 됩니다.
그리고, src 디렉토리에서 main_for_exe.exe 파일을 실행시키면, 아래와 같이 warning 메시지만 뜨고 문제 없이 실행되는 걸 확인 하실 수 있습니다.
6. 다른 local에서 실행파일 테스트하기
자신의 local 컴퓨터에서 문제 없이 돌아갔다면, 다른 사용자의 local 컴퓨터에서도 문제 없이 돌아갔는지 확인해야 합니다.
위의 예시를 기준으로 확인순서를 말씀 드리겠습니다.
- 다른 사용자의 local 컴퓨터에 script 폴더를 다운받습니다.
- src 폴더의 main_for_exe.exe를 실행시켜 줍니다.
만약 아래와 같은 에러가 생긴다면 CUDA를 설치하시고 다시 실행시키면 됩니다.
OSError: [WinError 126] 지정된 모듈을 찾을 수 없습니다. Error loading "C:\Users\MI2RL-JW\AppData\Local\Temp\_MEI260802\torch\lib\caffe2_detectron_ops_gpu.dll" or one of its dependencies.
[32] Failed to execute script 'test_OP_exe' due to unhandled exception!
(에러 원인을 찾아보니 아래와 같은 문구가 있어서 CUDA를 다시 설치하니 다른 local에서도 문제 없이 돌아가네요. 아마 코드자체가 gpu를 사용하겠금 구현되어 있어서 그런듯 합니다...)
(↑↑↑ 위의 메시지 출력↑↑↑)
7. python으로 작성된 딥러닝 실행파일을 만드는 방법 정리
지금까지 설명드린 내용을 종합하여 설명해보도록 하겠습니다.
1. pyinstaller 설치 및 업그레이드 (최근에 설치하는 것이라면 아래 명령어 중 하나만 선택하기만 해도 됨)
conda install -c conda-forge pyinstaller
pip install --upgrade pyinstaller
2. vscode 실행했던 디렉토리에 (모듈이 통합 된) exe 파일 및 spec 파일 생성 하기
pyinstaller --onefile --distpath 디렉토리명 실행파일명.py
(↓↓vscode에서 실행했던 main_for_exe.py 파일과 동일한 경로에 --distpath가 설정되어있는지 확인↓↓)
(↓↓↓아래와 같이 새 폴더 또는 파일이 생성됐는지 확인↓↓↓)
3. github으로 다운 받은 모듈이 있다면 hiddenimports 추가 && spec 파일 다시 빌드
[Note]
--distpath 설정해주어야 이전에 --distpath 경로에서 만들어진 exe 실행파일에 hiddenimports가 추가된 내용이 overwrite됩니다.
pyinstaller --distpath 디렉토리명 실행파일명.spec
4. 실행하기
실행파일.exe
5. 다른 local 컴퓨터에서 실행파일 테스트 (시연) 하기
- 다른 사용자의 local 컴퓨터에 script 폴더를 다운받습니다.
- src 폴더의 main_for_exe.exe를 실행시켜 줍니다.
만약 아래와 같은 에러가 생긴다면
OSError: [WinError 126] 지정된 모듈을 찾을 수 없습니다. Error loading "C:\Users\MI2RL-JW\AppData\Local\Temp\_MEI260802\torch\lib\caffe2_detectron_ops_gpu.dll" or one of its dependencies.
[32] Failed to execute script 'test_OP_exe' due to unhandled exception!
- Pytorch + CUDA를 설치하시고 다시 실행시킵니다.
- 1번이 안되면 spec 파일에 아나콘다\torch\lib 경로를 pathex에 추가시켜주고 다시 실행파일로 만들어줍니다
※만약, 해당 파일이 계속해서 실행이 안된다면 아래의 사항을 확인해주세요!
- 실행하려는 Local에서 GPU가 있는지 확인합니다.
- 만약, GPU가 없다면 코드에 try ~ except 문을 이용하여 GPU가 없을 시, CPU 코드로 돌아갈 수 있게 구현해 놓습니다.
(보통 딥러닝 모델을 inference 용도로만 사용하는 경우 해당 local에는 GPU가 없을 가능성이 있습니다. 클라우드 서버에서 돌리면 더더욱 그러한데, 그 이유는 클라우드에서 GPU 사용시 돈이 굉장히 많이 소요되기 때문이라고 합니다.)
[Note. pydicom 에러]
만약 pydicom 모듈이 포함된 실행파일을 만들었다면 아래와 같은 에러 메시지가 출력 될 수 도 있습니다.
1. 위 문제를 해결할 수 있는 한 가지 방법은 pydicom 모듈을 simpleITK 모듈로 바꿔주어 dicom 파일을 읽도록 하는 것이 있습니다.
https://89douner.tistory.com/284?category=991951
2. 사실 pydicom을 사용해서도 실행파일이 돌아갈 수 있게 하는 것이 더 큰 궁극적인 목적인데, 이를 위해서는 pydicom 버전을 2.0.0으로 downgrade해주면 해결이 됩니다.
이상 딥러닝 모델을 실행파일로 만드는 과정을 설명드렸습니다.
감사합니다!