WSL2 Ubuntu 22.04 setup

윈도우용 ubuntu 22.04에 python 3.10이 설치되어 있어서 요 녀석을 새로 깔았다. CUDA 12, CUDNN 8로 설치하면 잘 동작한다.

CUDA: https://developer.nvidia.com/cuda-downloads?target_os=Linux linux에서 wsl-ubuntu로 다운로드

sudo apt-key del 7fa2af80

wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda-repo-wsl-ubuntu-12-1-local_12.1.1-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-12-1-local_12.1.1-1_amd64.deb
sudo cp /var/cuda-repo-wsl-ubuntu-12-1-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda

CUDNN: https://developer.nvidia.com/rdp/cudnn-download 다운로드

sudo dpkg -i cudnn-local-repo-ubuntu2204-8.9.0.131_1.0-1_amd64.deb
sudo cp /var/cudnn-local-repo-ubuntu2204-8.9.0.131/cudnn-local-D7522631-keyring.gpg /usr/share/keyrings/

sudo apt-get update
sudo apt-get install libcudnn8
sudo apt-get install libcudnn8-dev
sudo apt-get install libcudnn8-samples

# 테스트
sudo apt-get install libfreeimage3 libfreeimage-dev

cd /usr/src/cudnn_samples_v8/mnistCUDNN
sudo make
./mnistCUDNN

sudo apt install cuda-toolkit-12
/usr/local/cuda/bin/nvcc --version

기타 등등

# zsh
sudo apt install zsh tree -y
sudo chsh -s /bin/zsh 
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# ZSH_THEME="itchy"

# pipenv
wget https://bootstrap.pypa.io/get-pip.py

python get-pip.py
pip install -U pip pipenv --no-cache-dir

# PATH 추가하기
echo export PATH='/usr/local/cuda/bin:/home/dice/.local/bin:$PATH' >> ~/.zshrc

faster cpython

예전에 pypy가 cpython보다 빠르다는 것을 보고 잘 모르겠지만 뭔가 이상하다 라고 생각했었는데, 귀도 반 로섬의 faster cpython이라는 프로젝트의 존재와 얼마 전 나온 python 3.11 릴리즈 노트의 속도 개선을 보고 이상함이 어느 정도 해소되는 기분이 들었다.

유튜브에 이를 명쾌하게 설명해주는 유익한 영상도 있었다. cpython 3.10보다 25% 정도 성능 개선되었다고하며 언급한 개선 포인트들을 보면 아래와 같다. GIL이나 c 모듈과 관련된 부분은 영향이 거의 없지만, 순수 파이썬 측면에서어느 정도 예측 가능한 코드를 작성하는게 성능향상에 도움이 된다는 흥미로운 결론이 나온다.

  • Lazy Python Frame: CPython은 함수 호출 시 PyFrameObject를 매번 생성해주는데, 이를 경량화시킨 _PyInterpreterFame으로 대체하고 object pooling 방식으로 관리함. 벤치마크에서 3~7% 기여
  • PEP 659: Specialization/Super Instruction – 전자는 빈번하게 실행되는 명령어의 타입을 예측할 수 있으면 특수화된 instruction으로 대체하는 방식으로, 타입 예측이 잘 되게 코드를 작성하면 성능향상이 된다고 한다. 후자는 자주 조합되는 명령어셋을 super instruction으로 만들어서 VM 오버헤드를 감소시키는 방식이다(요 방식은 버전업에 따라 바뀔 수 있어서 end user에게는 노출이 안된다). 이 예측이 어떻게 이뤄지냐가 핵심인듯한데, 이는 European Conference on Object-Oriented Programming에 게재된 <Inline caching meets quickening> 이라는 논문과 비슷하다고 하다.
  • Deep Frozen Project: 표준 라이브러리를 바이트코드로 만들어서 cpython 바이너리에 박아둠(ㅋㅋㅋ). 인터프리터 기동시간이 10~15% 개선. 또 자주 쓰는 메소드’명’ 들도 singleton object를 활용해서 박아둔다.

PC 소리 다중 출력하기

책상을 넓게 쓰려고 블루투스 스피커를 의자 뒤 책장 위로 옮겼는데 아무래도 소리가 뒤에서 나오다보니 잘 안쓰게되어서, 스피커와 모니터로 동시 출력하도록 만들어줬다. 일단 일반 스트레오 스피커를 뒤에다 놓다보니 좌우 반전 문제가 있었는데 이 부분은 Equalizer APO로 해결했다.

다중 출력은 voicemeeter banana 요 녀석을 이용했는데, 사운드 제어판에서 기본 장치로 voicemeeter input을 선택한 뒤 아래 두 설정을 거쳐준다.

1. 오른쪽 위에 A1, A2, A3 부분에서 사용하려는 재생 장치를 넣어준다.

2. 블루투스 스피커와 모니터 싱크를 위해 오른쪽 위 메뉴에서 system setting으로 들어간 뒤 delay를 조절해준다. 아래 비디오를 재생했을 때 ‘따닥’ 하는 소리가 안나오도록 이진 탐색을 해주면 된다.

ffmpeg 캠코더 영상 인코딩+합치기

옛날 캠코더로 찍은 영상을 ieee 1394로 디지털화 시켜놓은 것들이 있는데, 영상들 길이가 매우 짧고 (수 초 ~ 수 분) 용량이 매우 커서 (2시간 기준 24GB) 이것들을 하나로 합치고 인코딩하기로 했다.

처음에는 아래처럼 moviepy 라이브러리를 이용해봤는데 인코딩 옵션 넣는 것도 명확하지 않은 것 같고 무엇보다 3080을 하나도 안쓰길래 ffmpeg으로 넘어갔다.

def concatenate(video_clip_paths, output_path, method="compose"):
    """Concatenates several video files into one video file
    and save it to `output_path`. Note that extension (mp4, etc.) must be added to `output_path`
    `method` can be either 'compose' or 'reduce':
        `reduce`: Reduce the quality of the video to the lowest quality on the list of `video_clip_paths`.
        `compose`: type help(concatenate_videoclips) for the info"""
    # create VideoFileClip object for each video file
    clips = [VideoFileClip(c) for c in video_clip_paths]
    if method == "reduce":
        # calculate minimum width & height across all clips
        min_height = min([c.h for c in clips])
        min_width = min([c.w for c in clips])
        # resize the videos to the minimum
        clips = [c.resize(newsize=(min_width, min_height)) for c in clips]
        # concatenate the final video
        final_clip = concatenate_videoclips(clips)
    elif method == "compose":
        # concatenate the final video with the compose method provided by moviepy
        final_clip = concatenate_videoclips(clips, method="compose")
    # write the output video file
    final_clip.write_videofile(output_path, codec='h264')

ffmpeg은 링크에서 다운로드 받아서 program files에 넣고 bin 폴더를 환경 변수로 추가했다. 파일을 합치는 방법은 ffmpeg wiki에 나와있다. 다만 캠코더 영상을 합칠 때 숙지할 사항들이 있었는데,

  • 코덱 옵션을 원본 영상을 따라가도록 넣으면(-c copy) 에러를 뱉기 때문에 인코딩 옵션을 꼭 넣어줘야 한다. 어짜피 파일 크기도 줄여야하니 그냥 인코딩까지 동시에 넣기로 하고 원인을 찾아보지는 않았다.
  • 디언터레이싱 옵션을 넣어줘야 한다. 어떤 인코딩 옵션을 줘도 영상에 가로줄이 생겨서 이상하다 싶었는데 이게 원인이었다. -vf yadif=parity=auto 같이 적당히 넣어주니 해결된다.
  • h264 옵션을 줄 때 libx264 말고 h264_nvenc로 줘야 GPU를 갈구어준다. 속도는 3500x + 3080 기준 gpu 사용 여부에 따라 6~7배 / 20배 정도 나온다.