GPU 없이 카페에서 딥러닝하기

Ubuntu 원격 작업을 위한 환경을 구축하는 방법을 소개합니다

안녕하세요. 메이아이의 CPO 김찬규입니다.

딥러닝 모델 연구 개발을 위해서는 GPU가 필수적입니다. 모델을 이것저것 구현하고 실험해 보기 위해서는 내가 작성한 모델이 제대로 돌아가는지, 학습은 잘 되는지 확인해 봐야 합니다. 그러나 괜찮은 GPU가 있다면 10분이면 끝날 일을 CPU에서는 몇 시간이 걸리곤 합니다. 그렇기 때문에 사실상 딥러닝을 노트북으로 한다는 것은 불가능한 일입니다.

하지만 개발자와 카페는 또 떼려야 뗄 수 없는 불가분의 관계에 있습니다. 애초에 개발자는 커피를 입력받아 코드를 출력하는 직업일뿐더러, 무언가 막다른 길에 봉착해있을 때는 사무실에서 카페로 작업 환경을 옮겨주는 것이 필수적이죠.

그러나 노트북으로 딥러닝을 돌리다가는 어떤 정신적/회계적 피해를 입을지 예상조차 할 수 없겠습니다. 그래서 이번에는 카페에서도 (물론 집에서도) 딥러닝을 할 수 있도록, GPU가 장착되어 있는 머신에 자유롭게 원격 접속할 수 있는 환경을 구축하는 방법을 정리하여 올려보겠습니다.

저의 작업용 데스크탑도 그러하고, 많은 딥러닝을 위한 머신들이 그러하기 때문에 접속할 대상이 되는 머신의 OS가 Ubuntu라는 것을 상정하겠습니다. 특히 저의 환경은 Ubuntu 18.04 LTS 임을 참고해 주세요.


공유기 포트 포워딩

먼저 공유기의 포트 포워딩 기능을 이용하는 방법입니다. 이 방법은 가장 쉽고 간편하지만, 공유기를 사용하지 않거나 공유기의 관리자 권한을 획득할 수 없는 경우에는 활용이 불가능하겠습니다.

접속하고자 하는 Ubuntu 머신에 공유기를 통한 네트워크 연결은 이미 설정되어 있다고 가정합니다. 이때, 매번 IP 주소가 바뀌는 것을 방지하기 위해서는 네트워크 설정의 IPv4 method가 manual로 설정되어 있어야 합니다. 해야 하는 일은 단 하나입니다. 바로 공유기 설정 페이지에 접속하여 적절한 포트 포워딩 규칙을 추가해 주는 것입니다. 다음 순서를 따라 설정해 주면 되겠습니다. 공유기 설정 페이지의 UI 등은 공유기에 따라 다를 수 있음에 유의해 주세요.

  1. 공유기 설정 페이지 내부의 “트래픽 설정"에서 “포트 포워딩 설정"을 선택
  2. 외부 포트에 원하는 아무 포트(e.g. 10005)를 입력
  3. 내부 IP 주소에 접속하고자 하는 Ubuntu 머신의 네트워크 설정에서 확인할 수 있는 IPv4 Address를 입력
  4. 내부 포트로는 SSH의 기본 포트인 22를 입력
  5. 나머지 칸은 적당히 채우거나 비워둔 채로 규칙 추가

설정이 잘 되었다면, 다음과 같은 SSH 명령어를 통해 어디서든 여러분의 작업용 머신에 접속할 수 있습니다. Public IP 주소는 역시 공유기 설정 페이지에서 확인하실 수 있습니다.

ssh USERNAME@PUBLIC_IP_ADDRESS -p 10005

단 이 경우 패스워드만으로도 접속이 가능하기 때문에 보안에 취약할 수 있습니다. 보안에 조금 더 신경 쓰고자 한다면 'ssh-keygen'을 통해 공개 키를 생성한 후 '~/.ssh/authorized_keys'에 추가해 주는 등의 조치를 취할 수 있겠습니다. 저의 작업 환경에서는 공유기를 사용하지 않는 관계로, 적절한 이미지 예시를 제공하지 못하는 점에 사과의 말씀을 드립니다.


SSH Reverse Tunneling

개인적으로 제가 가장 선호하는 방법입니다. 약간의 비용이 들지만, 가장 안정적이고 대부분의 환경에서 활용이 가능하기 때문입니다.

여러분의 노트북을 C, 그리고 접속하고자 하는 머신을 A라고 합시다. 또 A와 C에서 SSH를 통해 접속 가능한 B라는 서버가 있다고 합시다. 이러한 상황에서 SSH reverse tunneling은 A와 C에서 B로의 접속이 가능하다는 사실을 이용하여, B로부터 A로 향하는 reverse tunnel을 뚫어 C > B > A 순으로의 우회 접속을 가능하게 합니다. 이 예시에서는 B의 10005번 포트와 A의 (역시 SSH 기본 포트인) 22번 포트를 연결하는 reverse tunnel을 생성해 보도록 하겠습니다.

서버 B 만들기

먼저 B라는 서버를 하나 만들어야겠습니다. 만약을 위해 언제든 편하게 켜고 끌 수 있고, 안정적인 연결을 지원하는 서버이면 무엇이든 가능한데, 저는 개인적으로 익숙한 AWS의 EC2 서비스를 이용하겠습니다.

먼저 AWS console에 로그인해 줍니다. 계정이 없다면 하나 만들어주세요. 새로 생성한 계정에 한하여 무려 12개월간의 Free Tier 서비스를 이용할 수 있는 권한을 줍니다. 그리고 다음과 같이 Find Services에 “EC2”를 검색하여 EC2 서비스로 접속해 주세요.

그 다음 EC2 서비스 페이지의 좌측 바에서 “Instances”를 찾아 클릭해 아래와 같은 instance 페이지로 이동해주세요.

저는 이미 실행되고 있는 인스턴스가 하나 있습니다. 좌측 상단의 파란색 버튼을 눌러 인스턴스를 생성합니다. 다음과 같이 설정하여 하나 만들어주세요!

  1. Ubuntu Server 18.04 LTS 선택
  2. 나머지는 입맛대로 선택 혹은 그대로 두셔도 무방합니다.
  3. 마지막 단계로 넘어가 우측 하단의 파란색 버튼 “Launch” 클릭

Key pair는 새로 생성하셔도 좋고 기존의 것을 사용하셔도 좋습니다. 다운로드된 key pair는 '~/.ssh' 폴더로 옮겨주세요. 이제 instance 페이지로 돌아가 잠시 기다리면 Instance State가 running으로 변경된 것을 확인할 수 있습니다. 다음의 명령어를 통해 생성된 인스턴스로 접속할 수 있다면 지금까지는 성공적입니다. 참고로 AWS의 Ubuntu 인스턴스의 기본적인 username은 “ubuntu”입니다. Public DNS Address는 인스턴스 페이지에서 확인하실 수 있습니다.

ssh ubuntu@PUBLIC_DNS_ADDRESS

이때 Permission Denied 같은 오류가 뜬다면, 십중팔구 생성된 키 페어(.pem 파일)의 권한 문제입니다. 너무 넓은 권한이 주어져있다면, 보안상 접속을 거부하게 되어 있습니다. 다음과 같은 명령어를 통해 권한을 재설정해 주세요.

chmod 600 ~/.ssh/CREATED_KEY_PAIR_FILE

서버 B 설정하기

이제 성공적으로 서버 B를 생성했으니, 간단한 설정을 통해 reverse tunneling이 가능하도록 해 주어야 합니다. 먼저 ssh configuration을 통해 포트 포워딩이 가능하도록 해 줍니다. 'sudo vim/etc/ssh/sshd_config'를 통해 sshd_config 파일을 열고, GatewayPorts 옵션을 yes로 바꿔줍니다. 없다면 추가해 줍니다.

이제 변경된 설정을 적용하기 위해 ssh 서비스를 재시작해 줍니다.

또 다음과 같은 명령어를 통해 방화벽 설정을 해 줍니다.

이제 서버 B의 설정은 완료되었습니다. 마지막으로 AWS EC2 서비스 페이지로 돌아가, 10005번 포트로의 접속이 가능하도록 Inbound Rule을 수정해 주어야 합니다.

먼저 인스턴스 정보에 있는 Security Groups를 클릭하여 해당 Security Groups 페이지로 이동해 줍니다. (저 launch-wizard-2라고 쓰여 있는 파란 글씨입니다.)

인스턴스 정보

아래와 같은 페이지에서 하단의 Inbound rules 탭을 클릭한 후, Edit inbound rule 버튼을 클릭해 줍니다. 그 후 다음과 같이 Port range에 10005를, Source 선택 드랍다운을 클릭하여 Anywhere를 선택한 후 저장해 줍니다. 이때 Anywhere를 사용하면 별다른 제약 없이 어디서든 접속할 수 있기 때문에 보안에 취약할 수 있음에 주의해 주세요.

Inbound rule 수정하기

Reverse Tunnel 생성

사실상 reverse tunneling을 위한 과정은 서버 생성 후 설정까지만 하면 거의 다 끝난 것입니다. A에서 reverse tunnel을 생성하는 일만 남았습니다. Reverse tunnel을 생성하는 SSH 명령어는 다음과 같습니다. A 컴퓨터에서 다음과 같은 명령어를 실행해 주세요.

별다른 에러 메시지가 없다면 성공적으로 터널이 생성된 것입니다. 하지만 네트워크 연결이 불안정하다면, 터널이 불시에 끊겨버릴 위험이 있습니다. 이를 방지하기 위해서는 간단하게 autossh를 사용할 수 있습니다. autossh를 설치하신 후, 명령어를 다음과 같이 대체해 주세요. 터널을 또 생성하기 위해서는 기존의 터널을 끊어 주어야 합니다. 'ps aux|grepssh' 명령어로 해당 터널 Process ID를 확인하시고, 'kill PID'로 끊어주세요.

이제 C 컴퓨터에서 다음의 명령어로 터널을 통해, A 컴퓨터로 접속할 수 있습니다. 이때 USERNAME은 서버 B의 username인 ubuntu가 아니라, A 컴퓨터의 username임을 유의해 주세요. 물론 생성된 키 페어도 미리 C 컴퓨터로 옮겨 놓고 권한 설정도 동일하게 해 주셔야 합니다.

터널 자동으로 생성하기

이로써 SSH reverse tunneling 원격 작업 환경 구축이 완료되었습니다. 하지만 아직 석연치 않은 구석이 딱 하나 있습니다. 바로 컴퓨터를 재시작할 때마다 터널을 새로 만들어주어야 한다는 것입니다. 이러한 수고를 덜기 위해 '/etc/rc.local' 파일을 다음과 같이 수정해 주시고요. 없다면 하나 만들어주세요.

위 스크립트는 Ubuntu 머신이 부팅될 때마다 실행됩니다. 'su USERNAME -c' 부분은 명령어를 root가 아닌 USERNAME 유저로 실행시키기 위함입니다. 위에서 작성한 파일을 다음의 명령어로 실행 가능한 파일로 만들어 줌으로써, 정말로 모든 과정이 마무리되었습니다.


크롬 원격 데스크탑

구글이 놀랍게도 무료로 제공하는 서비스입니다. 크롬 원격 데스크탑은 접속하고자 하는 컴퓨터에 크롬이 실행되고 있는 한 언제 어디서든 해당 컴퓨터에 접속할 수 있도록 해 줍니다. 게다가 CLI 기반의 원격 접속인 다른 두 방법과 다르게 머신의 GUI를 자유롭게 사용할 수 있다는 장점도 가지고 있습니다. (물론 SSH를 통하여도 X11 Forwarding을 통해 GUI를 사용할 수 있기는 합니다.)

설치 방법 역시 간단합니다. 여기를 눌러 '크롬 원격 데스크탑' 서비스 페이지에 접속하여, 안내에 따라 크롬 확장 프로그램과 네이티브 프로그램을 설치해 주기만 하면 되는데요. 다만 크롬이 항상 실행되어 있어야 한다는 점(따라서 재부팅 등의 작업 이후로는 원격 접속이 어려울 수 있다는 점)과, Ubuntu에서는 아직 어딘가 불안정한 면이 있다는 점이 단점이 되겠습니다.

실제로 제가 직접 설치해 보았을 때 Ubuntu에서는 프로그램이 제대로 설치되지 않는 모습을 보여주었습니다. Ubuntu에서 크롬 원격 데스크탑을 정상적으로 설치하기 위해서는 먼저 .deb 파일을 설치한 후, 다음과 같은 명령어로 적절한 디렉토리를 직접 생성한 후 크롬 확장 프로그램을 설치해 주어야 했습니다.

이제 크롬 원격 데스크탑을 설치한 후, 접속하고자 하는 기기를 등록해 줍니다. 다른 컴퓨터의 크롬에서 원격 데스크탑 페이지에 접속해 보면 다음과 같이 등록된 기기가 나타납니다.

ⓒremotedesktop

등록된 기기를 클릭하면 크롬을 통해 해당 기기로 접속하실 수 있습니다.


마치며

지금까지 GPU가 장착되어 있는 컴퓨터에 원격으로 접속하여 작업할 수 있는 환경을 구축하기 위한 총 세 가지 방법을 정리해 보았습니다. 보안, 안정성, 효용 등의 측면을 고려하여 세 가지 방법 중 적절한 방법을 선택하여 활용해 보시면 좋을 것 같습니다. 여러분의 즐거운 카페 코딩에 도움이 되었길 바랍니다!


You've successfully subscribed to 메이아이 공식 블로그
Great! Next, complete checkout to get full access to all premium content.
Error! Could not sign up. invalid link.
Welcome back! You've successfully signed in.
Error! Could not sign in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.