머신러닝AI2023. 3. 26. 01:39

 아래는 Python, Anaconda, AWS Cloud/Linux 경험을 가진 사용자가 ChatGPT같은 거대언어모델을 직접 구동해 보는 예시이다. 그 중심에는 Facebook인 Meta가 공개한 LLAMA가 있다. 그리고 경량형 quantization없이 LLAMA만 돌려보려면 6,7번을 건너뛰면 된다.

 

 

 ChatGPT가 공개되자, Meta도 LLAMA라는 프로젝트를 곧이어 공개했다. ChatGPT보다 경량형의 버전이면서 성능도 유사하다는 실험 결과를 같이 공개했다. 파라메터 크기 7B(70억), 13B, 33B, 65B 모델도 같이 공개했고, 연구신청을 하면 받을 수 있다. 그런데 이 모델들 이미 torrent 등에 공개되어 있으며, 약관을 검토해 본 유저들의  의견으로는 신기하게도 이를 다운로드하여 사용해도 불법은 아니라고 한다. ChatGPT류의 대형 모델 학습은 수백억원이 넘는 컴퓨팅 비용을 들어간다고 알려져있다. 이 결과물을 무료로 얻을 수 있게 된 것이다.

 

https://github.com/facebookresearch/llama

 

GitHub - facebookresearch/llama: Inference code for LLaMA models

Inference code for LLaMA models. Contribute to facebookresearch/llama development by creating an account on GitHub.

github.com

 

 이 Meta의 모델 공개는 곧바로 Stanford Alpaca라는 프로젝트로 이어졌다. Stanford Alpaca 프로젝트는 7B 모델을 가지고 Fine-tuning한 결과를 공유했는데, 특별히 대화 데이터를 손으로 만들 수 없으니, ChatGPT가 생성한 데이터를 사용했다(좀 반칙 같긴 하지만, 미래에는 이렇게 대세가 될 수 있겠다). Stanford Alpaca는 클라우드 상에서 시간당 몇만원이지만 그래도 개인이 몇시간은 부담할 정도의 A100 80G 4개의 GPU를 가지고 이 작업을 진행해 공개했고, 이를 직접 내 서버에 설치해 해보고 싶은 사람으로서는 고마운 일이 아닐 수 없다. 이제 ChatGPT류의 초 거대 모델을 큰 시행착오 없이 fine-tuning해서 각자 사용할 수 있는 길이 열린 셈이기도 하다.

 

 그런데 아직도, 이 A100 4개 GPU가 달린 서버의 사용은 좀 부담스럽다. 이정도 규모의 서버면 aws에서 한 시간에 몇만원씩 지불해야 하며 한 달 기준으로도 천만원이 넘는다. 그래서 다른 쪽에서는 이것의 quantization모델, 즉 부동소수점 연산의 정확도를 희생하는 더 경량형으로 만든 모델을 발표했다. 이렇게 하면 더 작은 GPU에서도 돌아간다.

 

 이 quantization 모델이 바로 우리가 해볼 아래 녀석이며, 소위 경량형 LLAMA이다. 어차피 LLAMA 공개된 파라메터 모델을 가지고 변형해서 사용하므로, 나중에 fine tuning을 하면 이것을 경량으로 돌릴 수 있는 방법(다시 변형해서 사용하면 되므로)을 체험하는 셈이기도 하다. 이렇게 되면 LLAMA를 구동해 볼 하드웨어 고민이 급속히 줄어 들게 된다.

 

https://github.com/qwopqwop200/GPTQ-for-LLaMa

 

GitHub - qwopqwop200/GPTQ-for-LLaMa: 4 bits quantization of LLaMa using GPTQ

4 bits quantization of LLaMa using GPTQ. Contribute to qwopqwop200/GPTQ-for-LLaMa development by creating an account on GitHub.

github.com

 

 이 녀석은 CUDA 11버전대의 16GB 이상의 GPU 메모리를 가진 장비만 있으면 돌릴 수 있다. 그렇다! 가정용으로는 RTX 3090 이상이면 된다. Nvidia RTX 3090은 24GB의 GPU 메모리를 지원한다 (구매하실 분이라면 800w 이상의 파워와 큰 케이스, 그리고 발열에 신경 써야 한다는 점을 미리 고려하면 좋겠다)

 

 하지만 여기서는 번잡하게 직접 구매하기보다는,  AWS 클라우드에 있는 NVIDIA V100 GPU를 탑재한 클라우드 서버를 사용해보았다. 인텔계열 CPU에 가장 작은 크기의 V100서버가 바로 p3.x2large 유형의 EC2 서버이다. NVIDIA V100 16GB 1 GPU를 제공한다. 대략 아래와 같이 준비한다. 동급의 다른 클라우드도 괜찮으나 OS나 gpu 메모리 및 실제 기대 속도 정도는 고려해 보자. 수많은 시행착오 끝에 V100이 이 작업에서의 가성비가 좋다는 것을 알았다. 다만 quantization안한 LLAMA는 30GB이상 GPU이면 좋다.

 

1. AWS에 p3.x2large instance(시간당 $4.3)를 만든다. 스토리지는 100GB용량 G2급 SSD(한달에 1.3만원)를 선택한다. OS는 국민 무료 리눅스인 ubuntu 22.04로 지정한다.

 

 1) 가정용 RTX 3090은 메모리가 24GB이고 V100보다 빨라서, 이를 보유하고 있다면 클라우드 쓸 이유는 없다. 불행히도 Nvidia K80, 3070같은 것들은 12GB이하의 GPU 메모리를 가지고 있고,  LLAMA의 제일 작은 모델인 7B에서 조차, 12GB이하의 메모리를 가진 GPU에서 진행하다가는 out of memory 오류에 직면하게 된다.

 

 2) 디스크 용량은 OS영역(/)에 최소 30GB이상, 전체적으로는 100GB이상이 필요하다. 필자는 150GB를 잡았다. 디스크가 부족해지면 나중에 골치가 아프기 때문인데, 지금 이 설명의 실습만 진행할 것이면 100GB도 가능하다.

 

 3) AWS region은 미국 오레곤이 동일 instance 비용이 더 저렴($3.1)하고, 데이터를 교환하는 양이 많지 않으니 오레곤을 선택해도 무리가 없을 수도 있다. 다만, 여기서는 Seoul region기준으로 하였다.

 

2. AWS의 기본 ubuntu 22.04 OS 에는 cuda가 설치되어 있지 않다. 아래 가이드를 통해 cuda를 설치한다.

 

 1) 아래 가이드는 cuda를 모두 지운상태에서 다시 시작하는데(remove, purge등), 그럴 필요까지는 없지만 진행해도 무방하다. 여기서는 두루 많이 쓰는 cuda 11.7 을 기준으로 설치한다. 드라이버 다운로드를 위해 nvidia 회원가입도 필요하다. 설치의 맨 나중에 다운받은 cudnn의 압축을 풀고 해당 폴더를 cuda로 변경한 후 파일을 복사하는 것만 주의하면 된다. 잘 설치될 것이다. 

 

https://gist.github.com/primus852/b6bac167509e6f352efb8a462dcf1854

 

Instructions for CUDA v11.7 and cuDNN 8.5 installation on Ubuntu 22.04 for PyTorch 1.12.1

Instructions for CUDA v11.7 and cuDNN 8.5 installation on Ubuntu 22.04 for PyTorch 1.12.1 - cuda_11.7_installation_on_Ubuntu_22.04

gist.github.com

 

# install cuDNN v11.7
# First register here: https://developer.nvidia.com/developer-program/signup

# 필자의 경우에는 따로 PC에서 다운로드 받아서 업로드하여 사용했다(로그인을 해야만 다운로드가 가능)

 

  $ tar -xz cudnn-linux-x86_64-8.5.0.96_cuda11-archive.tar.xz

  $ mv cudnn-linux-x86_64-8.5.0.96_cuda11-archive cuda

  $ sudo cp...  #제공된 github의 instruction 문구를 따른다.

 

3. 작업을 진행함에 있어서 Anaconda로 python을 구성하는게 편하고, Anaconda라는 것이 상황별로 격리된 python 환경을 구성해 변경해가며 쓸 수 있는 점은 이해가 필요하다. 그리고 Anaconda는 환경이 늘어날 수록 디스크를 많이 소요하기 때문에 용량 부족한 파티션에 설치는 피한다(물론 하나의 대용량 디스크라면 어디든 상관없지만)

 

 아래가 Anconda 제어하는 conda의 주요 명령어이니 작업에 참고하라. Anaconda 인스톨 방법은 ubuntu 22.04로 같이 검색하면 많이 나오고 아래가 주요 절차나 명령이다.

 

 #Anaconda 패키지를 받아 설치한다. 설치 시의 default 사항 중에 init 허용이 no로 되어있는데 이것만 yes로 바꿔주자.

  $ sudo bash Anaconda3-2020.11-Linux-x86_64.sh
  $ sudo vi ~/.bashrc
   ##bin과 condabin을 PATH에 추가한다.##

  $ source ~/.bashrc  #입력한 PATH추가를 활성화한다
  $ conda -V              #버전 및 작동 확인

  $ conda config --set auto_activate_base False

 

#아래는 주요 예시 명령이다(지금 실행할 필요는 없다). conda통한 환경생성/활성화/비활성화/삭제/목록 정보를 볼 수 있다


  $ conda create -n gptq python=3.9    #python 3.9기반의 gptq라는 이름의 conda 환경을 만든다

  $ conda activate gptq                         #gptq라는 conda환경을 활성화한다

  $ conda deactivate                             #해당 conda환경을 나간다

  $ conda remove -n gptq --all              #잘못 설치시 이 명령으로 gptq 환경을 모두 모두 지우고, 다시 conda create로 만들 수 있다.

  $ conda info --envs                             #설치된 환경들 목록을 확인한다

 

4. cuda가 정상적으로 설치 되었으면 아래와 같이 확인 가능하다. 그 전에 서버 리붓은 한번 해주고 확인하자.

 

 $ lspci | grep -i NVIDIA
 3b:00.0 3D controller: NVIDIA Corporation GV100GL [Tesla V100 PCIe 16GB] (rev a1)

 

 $ /usr/local/cuda/bin/nvcc --version
 nvcc: NVIDIA (R) Cuda compiler driver
 Copyright (c) 2005-2021 NVIDIA Corporation
 Built on Wed_Jun__2_19:15:15_PDT_2021
 Cuda compilation tools, release 11.4, V11.4.48   #예시이므로 버전명은 각기 설치 버전에 따르자(ubuntu 20.04에서는 11.4가 유리했다)
 Build cuda_11.4.r11.4/compiler.30033411_0

 $ nvidia-smi
  #GPU 이름과 gpu 메모리, gpu 사용량 정보 등을 확인할 수 있다. 메인 GPU에 16gb 이상의 메모리가 필요하다. CUDA 11.7 버전도 확인하자.

 

5. quantization 전에 사전 작업이 필요한데, https://huggingface.co 에 가입하고 LLAMA 7B버전 가중치 모델도 다운받아야 한다.

 

 1) huggingface.co에 가입 후에는 token을 생성해 복사해둔다. https://huggingface.co/settings/tokens

 그리고 아래와 같이 huggingface 설정도 추가한다.

 

 $ git config --global credential.helper store

 $ huggingface-cli login     #login직후에 미리 복사해둔 token을 넣어준다. 

 

 2) LLAMA 7B 모델도 다운받자.

 

 $ conda create --name pyllama python=3.9 -y

 $ conda activate pyllama

 $ cd /work

 $ mkdir llama_data

 $ git clone https://github.com/juncongmoo/pyllama

 $ cd pyllama

 $ pip install pyllama -U

 $ pip install -r requirements.txt    #이 설치가 pyllama설치만으로도 처리되어, 필요했는지 불명확한데 일단 실행하자

 $ python -m llama.download --model_size 7B --folder ../llama_data

 $ conda deactivate

 

6. 이제 quantization LLAMA를 설치해서 돌려볼 수 있는 아래 github을 다운로드하고 설명된대로 따르자.

 

상세한 실행 방법은 아래 가이드를 따르면 된다.

https://github.com/qwopqwop200/GPTQ-for-LLaMa

 

GitHub - qwopqwop200/GPTQ-for-LLaMa: 4 bits quantization of LLaMa using GPTQ

4 bits quantization of LLaMa using GPTQ. Contribute to qwopqwop200/GPTQ-for-LLaMa development by creating an account on GitHub.

github.com

 해당 github에 나와있는 설명을 조금은 변형해보았다.

 

 $ mkdir /work   #여기서는 /work 디렉토리라고 가정하자. 어디에든 용량이 넉넉한 곳에 만들면 된다.

 $ cd /work

 $ conda create --name gptq python=3.9 -y   #전용 conda 환경을 하나 만들고 activate한다

 $ conda activate gptq

 $ conda install pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia

 $ git clone https://github.com/qwopqwop200/GPTQ-for-LLAMA 

 $ cd GPTQ-for-LLaMa

 $ pip install -r requirements.txt   #해당 gptq 환경에 필요한 python 패키지를 설치한다

 $ pip install accelerate

 $ python setup_cuda.py install   #cuda를 잘 설치했으면 잘 넘어가진다

 $ CUDA_VISIBLE_DEVICES=0 python test_kernel.py     #GPU 작동 테스트이다.

 

#상기 작업시 아래 조치가 필요한 경우가 있었다

 pip install -r requirements.txt전에 requirements.txt 의 safetensors==0.3.0 -> 0.3.1로 조정

 pip install accelerate 이후에 pip install protobuf==3.20.3 실행

 

7.  앞서 5번 절차에  이어 이제 LLAMA 7B(llama_data)의 데이터를 huggingface 표준 format으로 바꾸는 작업을 하고, quantization까지 처리한 후에 실제 최종 모델을 실행해보자.

 (사실은 13B(130억건) 데이터도 가능 한데, parameter 크기가 올라갈수록 서버 메모리나 GPU 메모리 사용 제한이 올라간다. 그 제한의 정도는 모델별/경량화 여부별 차이가 있다.)

 

 $ cd /work/GPTQ-for-LLaMa

 $ conda activate gptq

 

#huggingface format으로 변경한다. 

 $ python convert_llama_weights_to_hf.py --input_dir /work/llama_data --model_size 7B --output_dir /work/llama_hfdata

 

#quantization하여 저장한다. 7B의 경우 32개 레이어별로 작업하고, V100보다 느리면 몇시간이 소요될 수 있다.

 $ CUDA_VISIBLE_DEVICES=0 python llama.py /work/llama_hfdata/llama-7b c4 --wbits 4 --groupsize 128 --save llama7b-4bit-128g.pt  #V100에서는 1시간 정도가 소요된다.

 

#생성한 quantization 모델값으로 실제 text 생성 실행을 해보자.

 $ CUDA_VISIBLE_DEVICES=0 python llama_inference.py /work/llama_hfdata/llama-7b --wbits 4 --groupsize 128 --load llama7b-4bit-128g.pt --text "is there lama?"

 

Loading model ...
Done.
 is there lama?
There are three possibilities:
1. There are no Lamas.
2. There are Lamas.
3. You don't exist.
If you're right, you don't exist

 

답변이 나오는 것을 확인할 수 있다.

 

8.  여기까지 왔으니 Meta의 7B 모델을 Meta의 inference code로 그대로 실행하는 것은 어떤가? 당신이 확보한 GPU 메모리가 30GB이상이라면 소스 수정 없이 가능하다(그리고 수정하면 16GB에서도 가능하다!)

 

https://github.com/facebookresearch/llama 의 가이드를 따르자.

 

 $ cd /work

 $ git clone https://github.com/facebookresearch/llama

 $ cd llama

 $ conda create -n llama python=3.9 -y

 $ conda activate llama

 $ pip install -r requirements.txt

 $ pip install -e .

 $ torchrun --nproc_per_node 1 example.py --ckpt_dir /work/llama_data/7B --tokenizer_path /work/llama_data/tokenizer.model

 # 7B model은 nproc_per_node가 1이다 

 

 이제 GPU 메모리 부족 이야기를 해보자. 7B모델 13GB가까이가 모두 gpu메모리에 올라가고, 실제 연산을 위해 17GB가 추가로 필요해 총 30GB의 용량이 필요하다(max_seq_len이 1024일때), example.py의 max_seq_len은 512로 줄이면, 24GB(RTX 3090의 지원 메모리)이하로도 가능하다. 그러나 여전히 위 실행은 p3.2xlarge 16GB GPU 메모리에서는 out of memory 오류가 발생한다.

 

 그러나 이때 더 과감하게 max_seq_len을 50까지 줄이면(512 --> 50까지 줄여보자) 이 16GB V100 GPU 메모리에서도 가능하다

 example.py에서 아래 소스상의 빨간색 영역을, 아래처럼 바꾸자.

 

 $ cd /work/llama 

 $ conda activate llama 

 $ vi example.py

  ...

  def main(

  ...

  max_seq_len: int = 50, #512가 원래값

  ...

  prompts = [  "I believe the meaning of life is" ]  #여러줄 있는 것을 한줄로 줄인다

  ...

 $ torchrun --nproc_per_node 1 example.py --ckpt_dir /work/llama_data/7B --tokenizer_path /work/llama/tokenizer.model

> initializing model parallel with size 1
> initializing ddp with size 1
> initializing pipeline with size 1
Loading
Loaded in 11.93 seconds
I believe the meaning of life is to find happiness and be satisfied with what you have.
But sometimes we have to struggle to find it. So, do we know the best way to achieve happiness?
Is happiness merely a mental state?

 

Token길이가 짧아서 아쉽지만, 구동은 해볼 수 있다.

 

9. 기타

 

 1) LLAMA 7B정도의 모델이면 13GB정도의 파라메터 파일인데 quantization된 최종 파일은 4GB가 조금 덜된다. 정확도는 조금은 낮아지겠으나 실행 부담은 적다. 위 7번 설명을 들으면 왜 이런 활동이 GPU 메모리 부담을 낮추는지 이해할 수 있다.

 

 2) fine-tuning은 통상 A100 80GB 이상 4개 GPU 정도에서 진행한다(모델 size에 따라 다르겠다). Stanford Alpaca나 KoAlpaca프로젝트의 관련 github이 이미 공개되어 있다. 물론 학습과정에서 fine-tuning할 데이터도 필요하다. 수기로 만들어내기 힘드니 ChatGPT API로 만들어내고 있다는 것은 늘 신기하다(아마도 향후 이 방법으로 다른 중소형 LLM들을 더 고성능으로 훈련시키지 않을까도 싶다. 이제 ChatGPT는 LLM들의 선생님이 될 기세다)

 

 3) LLAMA는 다국어가 학습 데이터에 섞여 들어가 있지만 기본은 20개 wikipedia 언어(bg, ca, cs, da, de, en, es, fr, hr, hu, it, nl, pl, pt, ro, ru, sl, sr, sv, uk)이고, 불행히도 여기에는 글로벌 IT회사라면 대부분 포함시키는 아시아권 언어가 의외로 포함되어 있지는 않다.

 

 4) 모델 성능이 중요하다면 여기서 다루는 7B가 아니라 13B, 65B모델도 고려할 필요가 있겠다. 이 부분은 아마 지속 추가 모델 공개가 있지 않을까 기대한다. 이때 아시아쪽 언어가 추가되길 기대해보자.

 

 4) AWS p3.x2large는 꺼두면 서버는 과금이 되지는 않는다. 필자의 경우에는 3시간 미만으로 $20안에 상기 실습을 해볼 수 있었다. 나중에 다시 해볼 목적으로 서버를 꺼두기만 한다고 하더라도 디스크는 지속 과금이 된다. G2(범용 SSD)가 1GB당 월 0.01$으로 가이드대로 하면 월1만원이 조금 넘는다.

 

 5) AWS에서 제공하는 GPU 다음 단계 40GB 메모리 instance는 이제  p4d.24xlarge (8 GPUs) 가 있다. 시간당 $46 수준으로 앞서 p3.x2large의 10배이다(밝힌대로 가격은 Seoul region기준이나, 미국 region들이 상대적으로 저렴하긴하다.) 80GB 모델이 AWS에 제공되는지는 아직 찾을 수 없었다. (80GB 서버가 구글 클라우의 us 어느 region에는 가지고 있긴 하다!)

 

 6) RTX 4080도 실험을 했다. 해당 GPU는 nividia-525 driver에 cuda 11.4로 테스트를 해서 잘 작동함을 확인했다. (4080의 경우 cuda 11.x버전으로 진행하도록 많은 유저들이 추천하고 있다)

 

 7) RTX 4080 ubuntu 22.04, nvidia-525 driver, cuda 11.8에서도 작동했다.

반응형
Posted by 작동미학