2022. 12. 21. 20:53ㆍDevelopers 공간 [Basic]/Software Basic
python 프로젝트를 구성하면서 pip으로 패키지를 관리하고, 때로는 패키지를 직접 만들어 사용하기도 합니다.
이런 다양한 방법들을 정리하고자 합니다.
<구성>
1. Python 관리하기
a. python과 pip 설치하기
b. 패키지 관리하기
2. 패키지 import 경로 순서
a. 1단계 sys.modules
b. 2단계 built-in modules
c. 3단계 sys.path (==$PYTHONPATH)
3. custom 패키지 관리하기
a. custom 패키지 구성하기 기초
b. Extension 구성하기
글효과 분류1 : 코드
글효과 분류2 : 폴더/파일
글효과 분류3 : 용어설명
글효과 분류4 : 글 내 참조
1. Python 관리하기
기본적으로 python과 pip을 다루는 것을 먼저 정리하겠습니다.
a. python 과 pip 설치하기
- 인터넷이 있을 때 python과 pip 설치 : ubuntu에서 python을 설치할 때, apt-get을 활용해 설치한 후, 설치된 python을 활용해 pip을 설치하고 최신 버전으로 업데이트 합니다.
- 기본적으로 ubuntu 버전에 따라 python3의 버전이 경험상 아래와 같이 설치됩니다.
Ubuntu 16.04 : python3.5
Ubuntu 18.04 : python3.6
Ubuntu 20.04 : python3.8
- 기본적으로 ubuntu 버전에 따라 python3의 버전이 경험상 아래와 같이 설치됩니다.
# python3 설치
sudo apt-get install python3
# python3 설치 : specific version
sudo apt-get install python3.7
ln -sf /usr/local/bin/python3.7 /usr/bin/python3
# 어떤 버전 python 인지 확인
which python # binary 위치
whereis python # binary, libraries related to binary
locate python* # python으로 된 모든 파일
# pip3 설치
sudo apt-get install python3-pip
# pip3 설치2
python3 -m pip install pip
# pip3 update
pip3 install --upgrade pip
- python, pip을 소스로 설치하기
- wget 이용해서 https://www.python.org/downloads/source/ 에서 설치 Gzipped source tarball을 다운로드
- 중간에 "can't decompress data; zlib not available" 인경우 apt-get install zlib1g-dev
wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
tar xvf Python-3.6.9.tgz
cd Python-3.6.9
./configure --enable-optimization
make
make altinstall
ln -s /usr/local/bin/python3.6 /usr/local/bin/python3
apt-get update
-----------------------------------------------------------------------------------------------------
< Dockerfile 예시 참조>
RUN apt-get install -y wget build-essential tk-dev libncurses5-dev libncursesw5-dev \
libreadline6-dev libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev \
libexpat1-dev liblzma-dev zlib1g-dev python-dev python-setuptools \
python-pip python-smbus libc6-dev openssl libffi-dev &&\
mkdir /home/Python
WORKDIR /home/Python
RUN wget http://nexus.hae-hpc.com/repository/etc/python/Python-3.6.9.tgz && \
tar xvf Python-3.6.9.tgz
WORKDIR /home/Python/Python-3.6.9
RUN ./configure && \
make && \
make altinstall
RUN python3.6 -m pip install --upgrade pip
RUN python3.6 -m pip install easydict numpy scikit-image opencv-python tqdm Pillow torch ==1.4 torchvision=0.5 tensorboard
-----------------------------------------------------------------------------------------------------
- pip 소스로 설치하기 : 아래는 python3.8이 존재할 때, pip3.8을 재설치하는 경우입니다.
- No module named 'distutils.cmd' 에러가 나는 경우 apt-get install python3-distutils
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3.8 get-pip.py
- python 삭제하기
# 소스로 설치한 경우
rm -rf /usr/bin/python3.*
rm -rf /usr/lib/python3.*
rm -rf /usr/local/bin/python3.*
rm -rf /usr/local/lib/python3.*
# apt-get으로 설치한 경우
apt-get purge python3.*
# apt-get으로 설치한 경우 : 직접삭제
rm -rf /usr/bin/python3.*
rm -rf /usr/lib/python3.*
rm -rf /usr/local/bin/python3.*
rm -rf /usr/local/lib/python3.*
rm -rf /var/lib/dpkg/info/python3*
rm -rf /var/lib/dpkg/info/libpython*
apt-get purge python3.*
apt-get purge libpython*
apt-get update
dpkg --configure -a
# 확인
dpkg -l | grep python3
- python과 관련된 우선순위 지정해주기
# Symbolic Link 활용하기
ln -s /usr/bin/python3.6 /usr/bin/python3
# update-alternatives 활용하기
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.5 1
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 2
update-alternatives --config python3
b. 패키지 관리하기
- 기본적으로 패키지를 설치하고, 재설치하고, 확인하는 명령어는 아래와 같습니다.
# Install
pip3 install package
# Re-Install
pip3 install --upgrade --force-reinstall
# Check List
pip3 list
# Uninstall
pip3 uninstall package
- 프로젝트에 셋팅된 설치 파일 한번에 설치하기 : 아래는 requirements.txt
alabaster==0.7.12
alembic==1.0.11
appnope==0.1.0
atomicwrites==1.3.0
attrs==19.1.0
Babel==2.7.0
b
ackcall==0.1.0
...
idna==2.8
imagesize==1.1.0
importlib-metadata==0.19
ipykernel==5.1.2
ipython==7.7.0
ipython-genutils==0.2.0
ipywidgets==7.5.1
itsdangerous==1.1.0
jdcal==1.4.1
pip3 install -r requirements.txt
- 패키지 버전 및 연결 상태 확인
- <Package>.__version__ : python 내에서 버전 확인
- <Package>.__file__ : 위치를 확인할 수 있다.
- pip3 show : python 패키지에 대해 자세한 정보를 보여주는 명령어 입니다.
python3 -c 'import torch; print(torch.__version__);print(torch.version.cuda)'
python3 -c 'import mmdet3d; print(mmdet3d.__file__)'
- torch 환경 확인하기
- python3 -m torch.utils.collect_env : PyTorch와 연결된 환경을 모두 알기 위한 방법입니다.
- from torch.utils.collect_env import get_running_cuda_version, run
get_running_cuda_version(run) : 현재 설치된 CUDA의 버전을 알려주는 명령어입니다. 어떤 GPU가 몇개 있는지 까지 확인할 수 있습니다. - pip3 show tensorflow : torch 의 경우 CUDA버전 확인 아래와 같이 가능
- 인터넷 없이 패키지 설치하기
- 인터넷 있는 곳에서 아래와 같이 pip3 download로 다운로드후에
- 위 https://bootstrap.pypa.io/get-pip.py에서 get-pip.py을 받아 wheel file로 설치
pip3 download tensorflow
python3 get-pip.py install pip-10.0.1-py2.py3-none-any.whl
2. 패키지 import 경로 순서
python 파일에서 import를 하면 아래와 같은 순서로 import 를 진행합니다. 이를 알고 프로젝트를 구성하면 편할 때가 많습니다.
a. 1단계 sys.modules
- 한 번 이상 import가 되었다면 여기에 추가 됩니다.
- python3 -c 'import sys; print(sys.modules)'
ex) {'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module 'importlib._bootstrap' (frozen)>, '_imp': <module '_imp' (built-in)>, '_thread': <module '_thread' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_weakref': <module '_weakref' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, '_frozen_importlib_external': <module 'importlib._bootstrap_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'posix': <module 'posix' (built-in)>, 'encodings': <module 'encodings' from ....
b. 2단계 built-in modules
- 파이썬에서 공식으로 제공하는 라이브러리로 내장되어있습니다. Python Standard Library(os, sys, time 등)이 여기에 포함됩니다.
- 위 예시에 보면 builtins 라고 표시된 것들이 built-in modules입니다.
c. 3단계 sys.path (==$PYTHONPATH)
- sys.path는 실행한 .py 파일이 속한 절대 경로가 기본적으로 포함되어있고, 추가로 $PYTHONPATH에 있는 경로가 추가됩니다.
- python3 -c 'import sys; print(sys.path)'
- root에 접근이 불가능할 때나 python 경로에 라이브러리가 추가되어있지 않을 때 $PYTHONPATH를 활용해 지정하면 해결할 수 잇습니다.
ex) /usr/local/lib/python3.6/site-packages를 추가
3. custom 패키지 관리하기
우리는 프로젝트를 패키지화 하기위해 *.pyx, *.cpp, *.cu 등을 컴파일하기도 합니다.
이렇게 하면 pip3로 설치한 것 처럼 할 수도 있고, 개인적으로 만들어 배포하고 안정적으로 관리하기에 유용합니다.
a. custom 패키지 구성하기 기초
- 먼저 custom 패키지 구성은 아래와 같이 합니다.
├── setup.py
├── src
├── fastfile.cpp
└── Include
└── version.h - setup.py 내용
- from setuptools import setup : custom 패키지를 빌드하기 위한 패키지입니다.
from distutils.core import setup : distutils를 활용할 수도 있습니다. - distutils: 리눅스배포 관리자에게 python project를 linux 배포 패키지(apt-get,pip등)으로 변환하는 표준 방법을 제공합니다.
- python 2.0이 출시된 이후 수년동안 build system과 package설치 프로그램을 언어 런타임 배포주기에 밀접하게 연결하는 것은 문제가 되는 것으로 밝혀져서 이제 프로젝트는 distutils를 사용하는 것보다 setuptools빌드 시스템+pip을 사용하는하도록 권장합니다.
- 결론 : distutils보다는 setuptools이 좋습니다.
- Parameters
- name : 패키지 이름
- version : 패키지 버전
- extra-compile-args : 컴파일 옵션을 줍니다.
- ext_modules : torch.utils.cpp_extension.CUDAExtension() 등을 활용해 실제 사용할 source 선택합니다.
** distutils를 활용하는 경우 from distutils.core import Extension를 활용합니다. - cmdclass : build_ext 등 명령어 따라 다르게 동작하도록 추가해줍니다.
- from setuptools import setup : custom 패키지를 빌드하기 위한 패키지입니다.
from setuptools import setup, Extension
setup(
name = 'fstfilepackage',
version = '0.1.1',
extra-compile-args={'cxx':['-lsource/include'], "nvcc":['-lsource/include']} //** -l : include 추가
ext_modules = [
Extension(
name = 'fastfilepackage'
sources = ['source/fastfile.cpp', 'source/fastfile.cu'], //** : source 추가
include_dirs = ["-lsource/include"],
)
]
)
- 실행
- python3 setup.py install : 한번의 실행으로 모든 모듈을 빌드하고 설치, python의 기본 path에 설치해버리는 것
- python3 setup.py install --install-lib ./FOLDER : --install-lib로 해당 모든 모듈의 빌드 디렉토리를 지정할 수 있습니다. 하지만 프로젝트에서 작업할 때는 부르기 어려우므로, $PYTHONPATH에 추가해두면 좋습니다.
- python3 setup.py build : 모든 것을 빌드합니다. 이후에 install하면 build 디렉터리의 모든 내용이 최신 상태이므로 수행할 작업이 없음을 빠르게 알 수 있습니다.
- python3 setup.py build_ext : C/C++이나 Cython extension 등을 빌드
- python3 setup.py build_ext --inplace : build-lib를 무시하고 compiled extensions을 pure Python modules 옆에 source directory에 넣어두는 방법입니다.
- pip3 install -e . : setup.py 파일이 있는 위치에서 실행하면 -e 혹은 --editable로 현재 자리에서 shared object를 만들고 python 기본 path에 현재 위치를 환경 변수로 추가합니다.
python3 setup.py --help-commands
python3 setup.py --help install
python3 setup.py install
python3 setup.py install --install-lib ./temp
python3 setup.py --help build_ext
python3 setup.py build_ext
python3 setup.py build_ext --inplace
pip3 install -e .
- 경로 참조하기 예시
- import os; os.path.dirname(os.path.abspath(__file__)) : 현재 위치를 프린트
- 아래는 Include 경로와 Src 경로를 얻는 방법입니다.
import numpy as np
np_include_path = np.__file__.replace("__init__.py", "core/include/")
INCLUDE_PATH = [
np_include_path
]
import glob
INCLUDE_PATH = glob.glob("~/THE_PATH/include/*")
import glob
SRC_PATH = glob.glob("THE_PATH/src/*.cpp")+glob.glob("THE_PATH/src/*.cu")
b. Extension 구성하기
이제 *.pyx, *.cpp, *.cu 등을 컴파일하기 위해 setup 함수를 어떻게 구성하는지 순서대로 설명하겠습니다.
- 종류 : Extension은 기본적인 Cythonize등과 함께 활용하는 Extension, CppExtension, CUDAExtension 등이 있습니다. 기본적으로 setuptools에서 제공하는 Extension을 활용하지만, torch에서 제공하는 함수를 사용하기도 합니다.
# 필수
from setuptools import setup
# 1. for Cpp
from torch.utils.cpp_extension import BuildExtension,CppExtension
# 2. for CUDA
from torch.utils.cpp_extension import BuildExtension,CUDAExtension
# 3. for Cython
from Cython.Build import cythonize
from setuptools import Extension
- CppExtension 예시 : C++파일들을 위한 Extension을 구성하는 방법입니다. RealName이라고 되어있는 부분이 import 할 때 쓰이는 이름입니다.
from torch.utils.cpp_extension import BuildExtension, CppExtension
setup(
name="Name",
ext_modules=[CppExtension(
name="RealName",
sources=["~mysource/*.cpp"],
extra_compile_args={
"cxx": ["-O2", "-I{}".format("~/myinclude")],
},
include_dirs=["~/myinclude"],
)],
cmdclass={
"build_ext" : BuildExtension
}
)
- CUDAExtension 예시 : cpp extension에 포함되며 C++/CUDA파일들을 위한 Extension을 구성하는 방법입니다. RealName이라고 되어있는 부분이 import 할 때 쓰이는 이름입니다.
- python3 setup.py install 한 경우 결과파일은 출력결과는 build폴더 외에 dist, RealName.egg-info 폴더 이렇게 생깁니다.
- 이중에 build폴더 내의 RealName.cpython-36m-x86_64-linux-gnu.so가 /usr/local/lib/python/ 등의 위치에 복사되기 떄문에 import하여 사용할 수 있습니다.
from torch.utils.cpp_extension import BuildExtension, CUDAExtension
setup(
name="Name",
ext_modules=[CUDAExtension(
name="RealName",
sources=[
"~mysource/*.cpp"
"~mysource/*.cu"
],
extra_compile_args={
"cxx": ["-O2", "-I{}".format("~/myinclude")],
"nvcc": ["-O2", "-I{}".format("~/myinclude")],
'-D__CUDA_NO_HALF_OPERATORS__',
'-D__CUDA_NO_HALF_CONVERSIONS__',
'-D__CUDA_NO_HALF2_OPERATORS__',
},
define_macros = [
('WITH_CUDA', None)
],
include_dirs=["~/myinclude"],
)],
cmdclass={
"build_ext" : BuildExtension
}
)
- Cythonize 예시 : Cython은 C로 컴파일되며, 실행하는 작업에 따라 적게는 몇 퍼센트에서 많게는 몇 배 더 높은 성능을 제공합니다. 파일 포맷은 *.pyx 이며, 해당 포맷에 맞는 문법이 존재합니다. RealName이라고 되어있는 부분이 import 할 때 쓰이는 이름입니다.
- python3 setup.py build_ext --inplace한 경우 결과 파일은 build폴더 외에 RealName.cpython-36m-x86_64-linux-gnu.so 와 RealName.c 이렇게 생깁니다.
- 이중에 RealName.cpython-36m-x86_64-linux-gnu.so를 직접 import 하여 사용할 수 있습니다.
from Cython.Build import cythonize
from setuptools import Extension
setup(
name="Name",
ext_modules = cythonize(Extension(
name="RealName",
sources=["~mysource/*.pyx"],
include_dirs=["~/myinclude"],
))
)
- Custom 패키지 사용하기 : 위와 같이 빌드된 이후에 import하는 방법은 아래와 같습니다. 위에 install과 build_ext 별로 다르게 만들어지는 것과 같이, install의 경우 직접 import할 수 있지만 build_ext는 파일위치로 직접 가서 import를 해야합니다.
# install 인 경우
try
import RealName
except ImportError:
print("ERROR")
RealName = None
# build_ext인 경우
try :
from PATHTO import RealName
except ImportError:
print("ERROR")
RealName = None
# cpp, cu : ~.h 내에 Function()을 정의한 경우
# pyx : pyx 내에 Function()를 정의한 경우
RealName.Function()
https://docs.python.org/ko/3/distutils/configfile.html
https://docs.python.org/ko/3/install/index.html
'Developers 공간 [Basic] > Software Basic' 카테고리의 다른 글
[OOP] Design Pattern 정리 (0) | 2023.05.15 |
---|---|
[PyTorch] DDP(Distributed Data Parallel) 셋팅하기 (0) | 2022.12.27 |
[AWS] SMDDP(Sagemaker's DDP) 기본 환경 셋팅 (0) | 2022.12.27 |
[Nvidia] GPU driver, CUDA, 라이브러리 셋팅하기 (0) | 2022.12.21 |
[Bash] Git 기초 및 구조 (0) | 2022.12.21 |