Vitis-AI를 외부에서 ssh로 원격접속하는 법

KiJungKong·2024년 1월 23일
0
post-thumbnail
==========================================
 
__      ___ _   _                   _____
\ \    / (_) | (_)            /\   |_   _|
 \ \  / / _| |_ _ ___ ______ /  \    | |
  \ \/ / | | __| / __|______/ /\ \   | |
   \  /  | | |_| \__ \     / ____ \ _| |_
    \/   |_|\__|_|___/    /_/    \_\_____|
 
==========================================

1. 포트포워딩

우선 윈도우에서 WSL으로의 포트포워딩을 설정해야한다.

우선 WSL상에서 ifconfig 명령어를 쓸 수 있어야 되므로 WSL을 실행해서 net-tools를 설치한다.

sudo apt install net-tools

그리고 나서 다시 윈도우로 돌아와

다음의 코드블럭을 전부 복사해서 wsl-portforward.ps1이라는 임의의 파워쉘 스크립트 파일에다가 붙여넣는다. (물론 다른 이름이어도 괜찮다.)

# wsl-portforward.ps1

## WSL에 들어가서 IP주소 따오기
# WSL에 들어가 ifconfig eth0 명령어를 통해 eth0 인터페이스를 출력,
# grep을 통해 inet(IPv4)이 존재하는 줄을 찾아서 그 줄을 $remoteport 변수에 넣음
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"

## $remoteport 변수에 유효한 IPv4 주소가 있는지 정규식으로 검사
# $found에 WSL의 IP주소를 찾았을 경우 True 못찾았으면 False가 들어감
# $matches에는 해당 정규식과 같은 패턴을 가진 문자열이 들어감
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';

# 찾았다면 $remoteport 변수에 WSL의 IP주소만 남기고, 못찾았다면 오류 메시지를 출력하고 스크립트를 종료
if( $found ) {
  $remoteport = $matches[0];
  echo "WSL 2의 IP주소: $remoteport"
} 
else {
  echo "WSL 2의 IP주소를 찾을 수 없습니다.";
  exit;
}

## 포트포워딩할 포트 번호들을 배열로 선언 
# 쉼표로 구분하여 원하는 포트 번호를 추가
$ports=@();

## 포트포워딩할 주소를 선언
# 0.0.0.0은 모든 주소
# 특정 주소로 제한하고 싶다면 변경하면 됨
$addr='0.0.0.0';

## 포트 번호들을 반복문으로 순회하면서, 각 포트 번호에 대해 
## netsh interface portproxy 명령어를 사용하여 포트포워딩

for( $i = 0; $i -lt $ports.length; $i++ ){
    $port = $ports[$i];
    # 기존에 있던 포트포워딩 규칙을 삭제하고, 새로운 규칙을 추가
    iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
    # $addr 주소의 $port 포트로 들어오는 연결을 $remoteport 주소의 $port 포트로 전달
    iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}

# 설정된 포트포워딩 규칙들을 출력
Invoke-Expression "netsh interface portproxy show v4tov4";

이 코드에서

## 포트포워딩할 포트 번호들을 배열로 선언 
# 쉼표로 구분하여 원하는 포트 번호를 추가
$ports=@();

괄호 안에다가 포트 번호를 넣으면 된다. 하나만 넣어도 되고 뚫고 싶은 포트 번호가 여러 개면 쉼표로 구분하여 추가하면 된다.

예시로 이런식으로 넣었다 가정하고 실행하면

포트를 두개 (1234, 5678) 적은 이유는 따로 의미가 있는 것이 아니고 임의로 아무 포트를 적은 것이다.
이따 ssh 포트로 1234를 사용하는 예시를 보여줄 것이다.

아래 ipv4 수신 대기, ipv4에 연결 부분을 보면 제대로 포트포워딩이 된 것을 확인할 수 있다.

지금 등록 하려던 포트로 이전에 다른 포트포워딩 규칙을 만든적이 없다면

지정된 파일을 찾을 수 없습니다.

이렇게 뜰 것이다. 이건 문제가 아니고 당연히 뜰 수 밖에 없는것이다.

만약 지우려면 아까 코드의 for문에서

for( $i = 0; $i -lt $ports.length; $i++ ){
    $port = $ports[$i];
    # 기존에 있던 포트포워딩 규칙을 삭제하고, 새로운 규칙을 추가
    iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
    # $addr 주소의 $port 포트로 들어오는 연결을 $remoteport 주소의 $port 포트로 전달
#    iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}

이렇게 삭제하는 부분이 아닌 2번째 추가하는 부분을 주석처리하면 된다.

참고: 인터페이스 포트 프록시에 대한 Netsh 명령 | Microsoft Learn

2. 방화벽 설정

키보드에 윈도우키를 누르고 방화벽 검색후 방화벽 상태 확인에 들어간다.

그리고 고급 설정을 누르고

인바운드 규칙을 누르고 새 규칙을 누른다.

포트로 설정 한 후 다음

뚫고 싶은 포트 적고 다음

포트를 두개 (1234, 5678) 적은 이유는 따로 의미가 있는 것이 아니고 임의로 아무 포트를 적은 것이다.
이따 ssh 포트로 1234를 사용하는 예시를 보여줄 것이다.

그리고 나서 디폴트로 둔 다음 다음을 누르는 것을 반복한다.

이름은 나중에 알아보기 쉽게 적는다. (나중에 필요 없으면 찾아서 지울 수 있도록)

3. openssh-server 설치

Vitis-AI/docker_run.sh 75번째줄

docker_run_params=$(cat <<-END
    -v /dev/shm:/dev/shm \
    -v /opt/xilinx/dsa:/opt/xilinx/dsa \
    -v /opt/xilinx/overlaybins:/opt/xilinx/overlaybins \
    -e USER=$user -e UID=$uid -e GID=$gid \
    -v $DOCKER_RUN_DIR:/vitis_ai_home \
    -v $HERE:/workspace \
    -w /workspace \
    --rm \
    --network=host \
    ${DETACHED} \
    ${RUN_MODE} \
    $IMAGE_NAME \
    $DEFAULT_COMMAND
END
)

잘 보면

--network=host

도커의 네트워크 모드를 bridge가 아닌 host로 실행하는 것을 볼 수 있다.

-p <host port number>:<container port number>

따라서 굳이 도커 실행시 이런 옵션을 추가해주지 않는다.

Vitis-AI 를 실행한다.

cd /{설치 경로}/Vitis-AI
./docker_run.sh xilinx/vitis-ai-tensorflow2-gpu:latest

# 만약 제가 예전에 썼던 글(Vitis-AI 설치 및 테스트)를 보시고 alias를 등록하셨던 분은
# > vitis-ai

Vitis-AI에 들어가서 openssh-server를 설치한다.

sudo apt install openssh-server

그리고 나서 ssh서버 설정파일 (/etc/ssh/sshd_config)을 좋아하는 편집기로 연다.

sudo vi /etc/ssh/sshd_config

그리고 아래와 같이 수정한다.

## 15번째 줄
#Port 22
Port 1234 # <- 원하는 포트

## 57번째 줄
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes # <- 주석을 해제
#PermitEmptyPasswords no

보통 구글링 해보면 다들 ssh세팅 할 때 key 만들어서 하던데

귀찮기도 하고 잠깐 잠깐 접속할거니깐

key만드는건 생략하고 password쳐서 들어가도록 만든다.

위 코드에서 password 쳐서 들어갈 수 있도록 해주는 게 PasswordAuthentication yes 이거다.

어차피 도커 안에서 host로 접근 못하는 가상환경이다. (공유폴더 제외)

Vitis-AI 컨테이너 안에만 귀중한 개인정보는 넣지 않도록 한다.

그리고 나서 패스워드를 설정해야 된다.

passwd

여기서 설정한 패스워드는 외부에서 ssh로 접속할 때 입력할 패스워드이다.

그리고 나서 아래의 명령어를 통해 ssh 서비스를 시작한다.

> sudo service ssh start
 * Starting OpenBSD Secure Shell server sshd                 [ OK ]

이 명령어는 Vitis-AI를 킬때 마다 실행해야되는 명령어이다. 잘 기억해두도록 하자.

Vitis-AI에는 systemctl을 사용할 수 없다. 따라서 아래의 명령어는 사용 불가이다.

sudo systemctl enable ssh

docker는 디폴트로 컨테이너에 systemctl 을 사용하지 못하게 막아둔다고 한다.

systemctl을 사용할 수 있도록 만들 수는 있겠지만 일만 커질거 같고

귀찮으니 sudo service ssh start를 킬때 마다 실행하는 것으로 타협한다.

4. 외부에서 Vitis-AI 실행

  ssh vitis-ai-user@(ip주소) -p (포트)

ssh클라이언트가 설치되어 있는 외부에서 원격접속한다.

ip주소는 컴퓨터의 내부 아이피를 적던지
공유기에서 포트포워딩을 해놓았다면
외부 ip주소 또는 도메인을 적으면 된다. (포트도 마찬가지)

이렇게 되면 성공이다.

vscode-server로도 접속 가능하다.


파이썬과 주피터 노트북을 설치하면

따로 pip install jupyter과 같은 아무런 설치과정 필요없이 바로 주피터 노트북 파일을 읽고 쓸수 있는것은 당연하며


vitis-ai-tensorflow2 커널을 선택하여 실행할 수도 있다.

5. 추가적으로 해줘야 할 작업들

Please install target_factory package to quantize with targets. 오류
  [DB INFO] Vitis AI Model Inspector...

Traceback (most recent call last):
  File "./code/inspect_resnet18_cifar10.py", line 69, in <module>
    inspector = vitis_inspect.VitisInspector(target="/opt/vitis_ai/compiler/arch/DPUCZDX8G/ZCU102/arch.json") # Vitis AI Model Inspector의 객체 생성
  File "/opt/vitis_ai/conda/envs/vitis-ai-tensorflow2/lib/python3.8/site-packages/tensorflow_model_optimization/python/core/quantization/keras/vitis/vitis_inspect.py", line 156, in __init__
    logger.error(
  File "/opt/vitis_ai/conda/envs/vitis-ai-tensorflow2/lib/python3.8/site-packages/tensorflow_model_optimization/python/core/quantization/keras/vitis/utils/common_utils.py", line 75, in error
    raise err_type('[VAI ERROR] ' + msg)
ValueError: [VAI ERROR] Please install `target_factory` package to quantize with targets.

이것은 Model Inspection을 돌리면 발생하는 오류로

오류 내용을 잘 보면 Vitis AI에서만 독점적으로 사용 가능한 라이브러리
target_factory가 안잡히는 것을 볼 수 있다.

주피터 노트북에서 Model Inspection, Model Quantization 실행시에 이러한 문제가 없었다. 터미널에서 source run_all.sh main_cifar10 실행시에만 발생한 문제이다.

> env | grep LD_LIBRARY_PATH
LD_LIBRARY_PATH=/opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu

이는 ssh로 접속하면 환경변수가 다 날라간다는 문제가 있어서
위의 사진과 같이 'LD_LIBRARY_PATH'에 /opt/vitis_ai/conda/envs/vitis-ai-tensorflow2/lib가 존재하지 않아 생긴 문제이다.

따라서

export LD_LIBRARY_PATH=/opt/vitis_ai/conda/envs/vitis-ai-tensorflow2/lib:/opt/xilinx/xrt/lib:/usr/lib:/usr/lib/x86_64-linux-gnu

이를 .bashrc에 추가한 후 source ~/.bashrc를 하면 Model Inspection, Model Quantization이 동작이 된다.

도커 커밋

이제 위의 작업을 다 끝마치면 도커 커밋을 하면 된다.

WSL이 열린 터미널 창을 띄운 다음
현재 실행중인 도커 컨테이너 목록을 확인한다.

컨테이너 ID를 잘 확인한 후

❯ docker ps -l
CONTAINER ID   IMAGE                                    COMMAND                  CREATED          STATUS          PORTS     NAMES
013e7039a8fd   xilinx/vitis-ai-tensorflow2-gpu:latest   "/opt/nvidia/nvidia_…"   54 seconds ago   Up 28 seconds             dazzling_bohr

아래 명령어를 쳐서 도커 커밋한다.

docker commit -m "image-classifiers installed" {실행중인 도커 컨테이너 ID} {만들길 원하는 도커 컨테이너 이름:태그}

# Example
docker commit -m "image-classifiers installed" 013e7039a8fd xilinx/vitis-ai-tensorflow2-gpu:latest

Alias를 등록한다.

vi ~/.zshrc # zsh말고 bash를 쓰는경우에는 .bashrc
# vitis-ai
alias vitis-ai='cd ~/{설치한 경로}/Vitis-AI; ./docker_run.sh {만든 도커의 이름}:{만든 도커의 태그}'

# Example
alias vitis-ai='cd ~/works/AMD/Vitis-AI; ./docker_run.sh xilinx/vitis-ai-tensorflow2-gpu:latest'
profile
공기정

0개의 댓글

관련 채용 정보