2023년 2월 23일 목요일

NVIDIA GPU 도커 이미지 기반 딥러닝 모델 실행 및 vscode 디버깅 개발 환경 쉽게 만들어보기

이 글은 우분투 20.04 이상 버전에서 NVIDIA GPU 도커 이미지를 사용해 딥러닝 개발 및 vscode 디버깅 환경을 쉽게 만들어보는 방법을 간략히 정리한다.

NVIDIA GPU는 딥러닝 개발 시 필수적인 하드웨어이다. 이런 이유로, 딥러닝 개발 시 NVIDIA GPU 드라이버, CUDA, PyTorch등 라이브러리를 설치해 사용하는 경우가 많다. 하지만, 엔비디아 CUDA 기반 딥러닝 환경 설치 테크트리는 전문가가 아니면 쉽지 않은 일인데다가, 매번 변경되는 각 버전으로 인한 패키지 의존 문제, ldconfig 를 통한 버전 갱신, 설정 변경으로 인한 딥러닝 모델 서비스 코드의 각종 에러는 골치아픈 문제 중 하나다.


NVIDIA FAIL--; (질문삽질 무한반복 HELL, Stackoverflow)

이를 해결할 수 있는 여러 방법이 있는 데, 1) AWS, 에저, 구글에서 비싼 클라우드 GPU 인스턴스 서비스를 사용하거나 2) 언제 서버 데이터 날라가도 이상하지 않는 CoLab을 이용하거나 3) 업체로 부터 비싼 딥러닝 개발스택설치 서버를 구입하거나 4) 무료 제공하는 NVIDIA GPU 도커를 사용하는 방법이 있다. 여기서는 4)번 방법을 사용해 딥러닝 개발환경을 만들어 보는 방법을 간략히 공유한다.

안정적으로 동작하는 NVIDIA GPU 이미지를 만들어 두고, 이를 필요할 때 다른 도커 이미지에서 해당 라이브러리를 호출할 수 있다면, 앞의 문제를 일부 해결할 수 있다. 엔비디아 컨테이너 툴킷(엔비디아 도커)는 다른 도커 이미지가 운영되는 컨테이너에서 NVIDIA GPU를 사용할 수 있도록 자동으로 마운트해준다. 다음 그림과 같이 컴퓨터에 설치된 NVIDIA GPU카드를 소프트웨어에서 구동할 수 있도록 NVIDIA 도커 이미지가 다른 어플리케이션 도커 이미지에 라이브러리를 연결, 제공해주는 방식이다.

엔비디아 도커 이미지 구조

엔비디아 도커를 설치하면, 다른 도커 이미지에서 --gpus 란 도커 GPU 사용 옵션을 이용할 수 있다. 이 옵션을 사용하면, 자동으로 실행 도커 이미지의 NVIDIA GPU관련 라이브러리 폴더 등을 NVIDIA DOCKER이미지에 제공되는 라이브러리로 자동 마운트해주고, 버전도 맞춰줘서 매우 편리하다. 

참고로, 도커는 가상 이미지 컨테이너로 미리 만들어 놓은 이미지를 로딩해, 재활용할 수 있다. 가상머신보다 가볍고, 프로그램 실행환경을 독립적으로 구축할 수 있어, 서버에서 편리하게 사용된다. 도커 가상 이미지는 docker build란 명령으로 dockerfile에 정의된 운영체제, 라이브러리 설치 명령을 해석해 이미지로 만들어진다. 
도커 개념

도커 컨테이너에 대한 상세 내용은 다음 링크를 참고한다.

엔비디아 도커 설치
우선 우분투(설치 링크) 운영체제가 필요하다. 기본적으로 NVIDIA DRIVER는 설치되어 있다고 가정한다(드라이버 설치 방법 링크). 

이후, 터미널에서 다음 링크를 참고해 도커를 설치한다. 
도커 설치 후, 우분투 터미널에서 다음 명령을 입력해 도커 저장소에 이미지 다운로드를 위한 키를 설정한다.
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

엔비디아 도커를 다음 명령으로 설치한다.
sudo apt-get update
sudo apt-get install -y nvidia-docker2

도커 서비스를 재시작한다.
sudo systemctl restart docker

다음 명령을 실행해, 우분투 20.04 이미지를 설치하고, nvidia-smi 명령을 실행해 본다.
docker run --rm --gpus all ubuntu:20.04 nvidia-smi

다음과 같은 화면이 나오면 제대로 설치된 것이다.

vscode 도커 디버깅을 위해 도커 그룹을 생성하고, 현재 사용자를 해당 그룹에 추가한다.
sudo groupadd docker
sudo usermod -aG docker $USER 

도커 이미지 기반 vscode 디버깅 환경 구축
우선 vscode 개발도구를 설치한다.
설치 후, vscode를 실행한다. vscode에서 다음과 같이 좌측 Extension 설치 메뉴를 선택해, Remote Development, docker, docker explorer  확장모듈을 설치한다. 이를 통해, 원격으로 도커 이미지와 vscode를 연결해 사용할 수 있다. 

vscode와 연결해 디버깅하기를 원하는 도커를 터미널에서 실행한다. 다음은 도커 실행 예시이다. vscode가 도커 디버깅할 수 있도록 newgrp로 docker그룹 변경한 후(이후 도커 그룹 빠져나올때는 exit 명령 입력), 도커 이미지를 실행한다. local host와 docker remote host간의 폴더 마운트를 위해 -v 옵션을 사용한다. 
newgrp docker
docker run -v ~:/tf --gpus all -it pytorch/pytorch bash

참고로, vscode에서 파이썬 디버깅 개발 환경이 필요하다면, 당연히 해당 도커 이미지에 파이썬 패키지가 제대로 설치되어 있어야 한다. 

다음, 상태창의 녹색 remote development 아이콘을 선택하고, 메뉴 중 Attach to Running Container 메뉴를 선택해, 실행 중인 도커 이미지와 연결한다. 
상태창의 remote development 아이콘

remote development 메뉴 리스트

해당 도커와 연결되어 실행된 vscode의 terminal 메뉴를 실행한다. 

터미널에서 다음 명령을 실행한다. 결과가 그림과 같으면 제대로 도커 이미지와 연결된 것이다.
nvidia-smi

다음과 같이 마운팅된 root의 tf폴더를 Open한다.

그럼 다음과 같이 마운팅된 폴더를 확인할 수 있다.

이제 파이썬 코드를 vscode의 new file 메뉴로 하나 생성한다. 

해당 소스파일에 아래 코드를 입력한다.
import math

value = math.cos(math.pi)
print(value)

확장모듈 중 Python Extention Pack과 Intellicode 모듈을 다음과 같이 설치한다.


이제, vscode의 디버깅 모드를 실행하고, 파이썬 인터프린터를 선택한다. 만약, 파이썬 디버깅이 불가능하다면, 프로젝트에 launch.json 파일을 추가해, 아래와 같이 파이썬 디버깅 환경 정보를 추가해야 한다(참고).
{
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "$(file)",
            "console": "integratedTerminal"
        }
   ]
}

이제 해당 파이썬 코드를 실행되면, 다음과 같이 디버깅할 수 있다.

로컬 호스트의 폴더를 보면, 도커에서 작성된 파일을 확인할 수 있다.

GPU기반 딥러닝 개발을 테스트하기 위해, 다음과 같이 PyTorch 코드를 입력해 본다.
import torch
flag = torch.cuda.is_available()
if flag:
print(torch.cuda.device_count())
print(torch.cuda.current_device())
print(torch.cuda.device(0))
print(torch.cuda.get_device_name(0))

브레이크 포인트를 설정하고, 디버깅해본다. 다음과 같이 실행되면 성공한 것이다.

마무리
엔비디아 도커 이미지를 이용하면, 다른 도커 이미지에서 패키지, 드라이버 의존 에러 지옥에 빠지지 않고 편리하게 딥러닝 모델을 개발, 실행할 수 있다. vscode의 remote development 확장모듈을 이용하면, 도커 이미지, ssh와 같이 원격으로 접속해 실행되는 프로그램 소스를 손쉽게 디버깅할 수 있다. 
이를 통해, 엔비디아 CUDA 기반 딥러닝 개발 환경의 복잡한 테크트리와 각종 문제에서 벗어날 수 있다. 

레퍼런스
부록: launch.json 설정
프로그램을 디버깅할 때 명령행 인자 등을 미리 설정해야 할 때가 있다. 이 경우, 프로젝트 폴더에 launch.json 파일을 생성하고, args 키를 정의해 인자를 추가해야 한다. 다음 영상을 참고한다.


2023년 2월 16일 목요일

간단한 트랜스포머 동작 원리와 Pytorch 기반 비전 트랜스포머 ViT 소개

이 글은 간단한 트랜스포머 동작 원리와 Pytorch 기반 비전 트랜스포머 ViT를 소개한다. 

개념
트랜스포머트는 국부적인 특징을 캡쳐해 학습하는 CNN과는 다르게, 전체 데이터 영역의 특징을 학습한다. 간단한 동작 순서는 다음과 같다. 

1. 주어진 데이터를 토큰으로 분해한 후, 임베딩 기법으로 유일한 값으로 수치화한다. 
2. 수치화된 토큰은 라벨링된 토큰 순서열(앞의 텍스트 프롬프트에 대한 다음 텍스트 예측이라면, 텍스트 자체가 입력 및 라벨링 데이터를 포함하게 됨)의 확률을 학습하는 데 사용한다.
3. 학습은 토큰이 다음에 출연할 토큰의 확률을 계산하는 방향으로 진행된다. 이를, 어텐션(attension)이라 한다.
4. 이를 계속 반복한다. 

다음 그림은 이 과정을 보여준다.
트랜스포머 개념

트랜스포머 모델은 이미 텍스트 예측, 비전 분류 등에서 SOTA를 달성하였다. GPT는 이 기술을 적극 활용한 도구이다. 

ViT 소개
Transformer는 ChatGPT, BERT 등과 같은 자연어 처리 분야에서 발전되었다. 이를 사용해, 비전 분류에서 Vision Transformer (ViT)가 구현되었다. 이는 분류에서 SOTA를 달성했다(다만, YOLO등에 비해 실행 자원 등을 많이 사용하는 단점이 있다).
트랜스포머 개념 및 논문 설명

ViT 트랜스포머 기술은 다음 같이 오픈소스를 통해 이미 공유되어 있다. 
PyTorch로 구현하는 방법은 다음과 같다.

마무리
트랜스포머는 다양한 비정형 데이터를 학습, 분류, 예측할 수 있는 가능성을 열어준다. 이를 통해, 멀티모달 학습모델 생성 및 사용이 가능하다. GPT4는 대중이 사용하는 멀티모달 트랜스포머 모델의 시작이 될 것이다. 

참고

2023년 2월 8일 수요일

개발 후 자동화된 통합/배포/운영을 위한 DevOps CI/CD 파이프라인 및 오픈소스 도구 소개

이 글은 개발 후 자동화된 통합/배포/운영을 위한 DevOps CI(Continuous Integration)/CD(Continuous Delivery) 파이프라인과 오픈소스 도구를 간략히 소개한다.


CI/CD 파이프라인은 자동화된 테스트, 버전 관리, 지속적인 통합, 제공 및 배포를 포함하는 개발 방법론이다. 통합은 자동화를 통해 애플리케이션을 빠르고 효과적으로 배포할 수 있다. CI/CD는 여러 자동화된 테스트/배포 도구를 포함한다. 이 도구를 통해, 개발 배포 과정을 자동화할 수 있지만, 이 기술을 사용하기 이전에 작업하는 방식, 절차, 습관의 변화가 필수적이다.

지속적인 통합/배포 개념
CI/CD는 소프트웨어 개발 프로세스를 자동화하여, 배포 시간을 몇 달에서 몇 시간으로 단축할 수 있다.

지속적 통합에는 코드베이스에 대한 지속적인 코드 통합 프로세스가 포함된다. 사소한 코드 변경으로 인해 원하지 않는 결과가 발생하므로, 소규모 통합을 자주 수행하는 것이 중요하다. 사람 개입 없이 빌드 자동화를 통해 모든 통합의 오류를 확인한다.

이는 CI 서버 및 코드 관리 시스템을 비롯한 자동화 도구에 크게 의존한다. 이를 통해 문제를 조기에 감지하고, 제거할 수 있다. 지속적인 코드 통합은 팀 협업을 촉진하고, 개발자가 고품질 소프트웨어를 신속하게 제공할 수 있도록 한다.

CD는 버그 수정, UI/기능 개선과 같은 작고 빈번한 소프트웨어 변경 사항을 배포하는 방법론이다. 기본적으로 CI가 끝나는 지점에서 CD가 시작된다. 본질적으로 CD에는 지속적인 통합 코드의 스테이징, 테스트 및 배포가 포함된다. CD는 전적으로 운영 영역에 속한다.

CD는 소프트웨어가 CD/CI 파이프라인을 통과할 때, 오류 및 보안 취약성을 식별하기 위한 자동화된 회귀 테스트, 성능 모니터링을 자동 실행한다. 

지속적 통합/배포 도구
애자일 개발 방법론 채택이 증가함에 따라, 여러 CI/CD 도구가 시장에 출시되었다. 

Jenkins
Jenkins는 사용자가 실시간으로 테스트하고 보고할 수 있는 오픈 소스 교차 플랫폼 Java 기반 도구이다. 사용하기 쉬운 Jenkins는 Azure , Google Cloud, AWS 및 DigitalOcean 을 포함한 주요 클라우드 플랫폼과의 원활한 통합을 제공한다. 

CI/CD 파이프라인에는 개발자가 도메인별 언어를 사용하여 모델링 및 구현에 사용할 수 있는 유용한 도구 세트가 포함되어 있다.

MacOS, Windows 및 Linux 플랫폼에서 사용할 수 있는 Jenkins는 강력한 커뮤니티와 1500개 이상의 플러그인으로 구성된 플러그인 생태계를 보유하고 있다. 오픈 소스이고 무료이며 강력하고 확장 가능하므로 대규모 조직과 신생 기업 모두가 선호한다.

Sippable
소프트웨어 회사 Jfrog가 개발한 Shippable은 DevOps 엔지니어가 예측 가능한 소프트웨어 릴리스를 만드는 데 사용할 수 있는 CI/CD 도구 중 하나이다. Docker 지원을 제공하는 Shippable 자동화 플랫폼은 언제 어디서나 애플리케이션의 개발, 테스트, 프로비저닝 및 배포를 간소화한다.

HipChat, Slack, Kubernetes, Google Container Engine, Amazon ECS, Docker, Bitbucket, GitHub, Nose, xUnit, JUnit, Cucumber 등 도구와 원활하게 통합된다.

GitLab CI
GitLab CI는 Windows, macOS 및 Linux와 같은 여러 플랫폼에서 사용할 수 있다. 친숙한 UI로 설계된 GitLab CI는 지속적인 통합, 제공, 코드 검토 및 배포를 포함한 다양한 기능을 간단한 대시보드에 담았다.

GitLab CI는 Shell Executor를 통해 빌드를 트리거할 수 있다. 

TeamCity
JetBrains에서 개발한 TeamCity는 Jira Software, Azure DevOps, NuGet, Maven, Visual Studio Team Services 및 Docker와의 통합을 지원하는 무료 오픈소스 CI/CD 도구이다.

TeamCity는 Linux 및 Windows에서 사용할 수 있으며, 병렬 빌드를 실행하여, 사용자에게 다양한 환경에서 동시에 빌드를 실행할 수 있는 유연성을 제공한다.

TeamCity는 vSphere, VMWare, Google Cloud 및 AWS를 포함한 다양한 클라우드 플랫폼에서 잘 작동한다. Kotlin 기반 DSL(도메인 스펙 언어)을 사용하여 파이프라인을 정의할 수 있다.

Buildkite
Buildkite는 개발자에게 온프레미스 플랫폼에서 확장 가능하고 안전한 파이프라인을 실행할 수 있는 기능을 제공한다. 사용자는 Docker, macOS, Linux, Windows에 Buildkite를 설치하고 중앙 집중식 플랫폼의 여러 에이전트에서 병렬로 작업을 실행할 수 있다. 사용자가 GraphQL API를 활용하는 도구를 구축할 수 있다.

Codefresh
Kubernetes 에서 개발된 Codefresh는 GitOps를 완벽하게 지원한다. Puppet , Pulumi, Terraform, Slack, GitLab, Bitbucket 및 GitHub 와 같은 잘 알려진 도구와의 통합을 제공한다 .

Kubernetes 대시보드를 통해 Codefresh는 프로그래머에게 Azure, Amazon Web Services, Kubernetes를 포함한 다양한 플랫폼에서 가시성, 확장성 및 뛰어난 속도를 제공한다.

Codefresh Runner라는 CLI(Command Line Interface)를 통해, 코드 배포, 빌드 트리거 및 테스트 실행을 위한 확장 가능하고 효과적인 방법을 제공한다.

Bitrise
Bitrise는 모바일 앱 개발에 사용되는 대부분의 프로그래밍 언어(예: Flutter, Reactive Native, Iconic, Cordova, Objective C, Swift 및 Kotlin)에 대한 강력한 지원을 제공한다. Bitrise는 오픈 소스 프로젝트로 개별 모바일 애플리케이션 개발자에게 무료로 제공된다. 

Bitrise는 사용자가 값비싼 하드웨어를 설치하지 않아도 되도록 해준다. GitLab Enterprise, GitHub, Bitbucket, GitLab 및 GitHub Enterprise와 같은 임시, 공용 및 개인용 Git 서비스와 잘 연결된다. 

AutoRABIT
AutoRABIT은 Salesforce 플랫폼용 맞춤형 솔루션을 제공하는 CI/CD 도구 중 하나이다.

대화식의 사용자 친화적인 인터페이스를 제공하며, 120개 이상의 메타데이터 유형을 지원한다. AutoRABIT은 사용자가 Salesforce 지향 도구를 시스템에 통합하는 데 필요한 노력을 피할 수 있도록 도와준다.

Strider
MongoDB를 데이터베이스로 사용하는 Strider는 JavaScript/NodeJS로 작성되었다. Ruby, NodeJS 및 Python을 포함하여 광범위한 언어를 지원한다.

사용자는 Strider를 Bitbucket, Heroku, GitHub Enterprise, GitLab, GitHub 및 Slack과 통합하여 알림을 받을 수 있다. Strider의 내장 플러그인으로 다양한 기능을 쉽게 확장하고, 사용자 정의할 수 있다.

파이프라인의 보안
CI/CD 파이프라인은 팀이 사람의 실수를 줄이고, 개발팀의 결과물을 운영하는 데 도움이 된다. 하지만, 악의적인 행위의 표적이 될 수도 있다. 따라서 CI/CD 파이프라인 보호를 고려할 필요가 있다.

암호 관리는 CI/CD(지속적인 통합 및 배포) 중요한 보안 방법이다. 암호는 암호, 토큰 및 개인 키와 같이 노출되어서는 안 되는 민감한 정보이다. 권한이 없는 개인이나 시스템이 파이프라인에 접속할 수 없도록, 안전한 위치에 암호가 저장되어야 한다. 이를 위한, 인기 있는 암호 관리 도구는 Hashicorp Vault, AWS Secrets Manager 및 Azure Key Vault 등이 있다.

다른 보안 방법은 개발 산출물 컨텐츠 자체를 암호화하는 것이다. AES-256과 같은 보안 암호화 알고리즘을 사용하고, 암호화 키를 정기적으로 교체하여, 시간이 지나도 컨텐츠가 안전하게 유지되도록 한다.

마무리
CI/CD를 통해 애플리케이션을 신속하고 효과적으로 배포할 수 있다. CI/CD는 여러 자동화된 테스트/배포 도구를 포함한다. 이 도구를 통해, 개발 배포 과정을 자동화할 수 있다. 다만, 어떤 기술이든 제대로 활용하기 전에 우리가 작업하는 방식, 절차, 습관의 변화는 필수적일 것이다.

레퍼런스

2023년 2월 5일 일요일

사물인터넷 데쉬보드 Thingsboard IoT 소개

이 글은 Thingsboard 사물인터넷 데쉬보드를 간단히 소개한다. 이 라이브러리를 이용하면, 손쉽게 아래와 같은 데쉬보드를 만들 수 있다. 이와 유사한 것들은 Grafana, Node-RED 등이 있다. 리액트 등 프론드엔드 테마는 여기를 참고한다.

씽스보드 화면 예시

설치
다음 설치 메뉴얼을 따라 씽스보드를 설정한다.
사용법
다음 명령을 이용해, 서비스를 실행한다.
netstat -tulpen |grep 80
sudo kill -9 $(sudo lsof -t -i:8080)
sudo service thingsboard start
service --status-all


그럼 서버가 실행되며, 이를 통해, 데쉬보드를 인터넷으로 서비스할 수 있다.

에러가 발생하면, 다음 명령으로 확인할 수 있다.
cat /var/log/thingsboard/thingsboard.log | grep ERROR

마무리
이와 같이, javascript node.js 기반 다양한 데쉬보드 프론트엔드 테마 오픈소스 라이브러리가 있으며, 이를 이용해, 복잡하고 동적인 데쉬보드를 손쉽게 개발할 수 있다. 이를 메터포트 등 그래픽 뷰어를 이용해 커스텀하면 디지털트윈과 같은 시스템을 손쉽게 개발할 수 있다.

레퍼런스

우분투 리눅스 user is not in the sudoers file 에러 해결 방법

이 글은 우분투 user is not in the sudoers file 에러 수정 방법을 간략히 정리한다. 

이 에러는 root 권한에서 다음과 같이 멍청한? 짓을 할 때 발생할 수 있다. 

sudo usermod -g docker $USER


이 짓을 설명하자면, 현재 루트 권한 사용자를 docker란 그룹으로 옮김으로써 스스로 sudo 그룹을 탈퇴시켜버려 모든 명령어를 실행할 수 없게 하란 뜻이다. 원래 입력하고자 하는 명령은 다음과 같은 것이었다.
sudo usermod -aG docker $USER

이런 유사한? 짓을 했다면, sudo 로 실행되는 명령 apt update, apt-get 을 사용하지 못하는 벌을 받게 되어 있다(아~ T.T). 

user is not in the sudoers file 

구글링하면, sudo 권한을 잃었는 데, usermod를 실행해 유저를 추가하라는 등 넌센스 답들이 넘쳐난다. 멘붕하지 말자. 다음을 잘 따라하면, 다시 멘탈을 되찾을 수 있다.

1. 우선, 우분투를 재부팅한다.
2. GNU GRUB 메뉴에서 Advanced options for Ubuntu 를 선택한다.

3. 다음 메뉴에서 recovery mode 로 표시된 항목 아무거나 선택한다.

4. Recovery Menu에서 다음 root 메뉴를 선택한다. 그럼 루트 권한으로 터미널이 실행될 것이다. 만약, "Press Enter for maintenance" 프롭프트가 보이면 엔터를 친다.

5. 루투 권한으로 실행된 터미널에서 아래 명령을 입력해, 파일 시스템과 마운트하고, sudo 그룹에 유저를 다시 추가해 준다.
mount -o rw,remount /
usermod -aG sudo <user name>

6. exit 명령을 입력하고, 보여진 Recovery Menu에서 resume메뉴를 선택해, 재부팅한다.

7. 다시 우분투 리눅스로 로그인하면, 다음과 같이 sudo 그룹 명령을 실행할 수 있다.

한번의 실수로 한시간을 날렸다(아 ~ㅆㅂ). 앞으로는 아무 생각없이 이런짓 하지 말자.

참고: group user 명령
groups
whoami
cat /etc/group | grep $USER
cat /etc/passwd | grep 'docker'
sudo gpasswd -a $USER docker
newgrp docker
exit