LLama2 윈도우에 설치부터 실행까지 – 튜토리얼

추석연휴에 본가에 내려갔는데, 최근 AI에 관심이 많으신 아버지가 Llama2를 좀 써보고 싶다고 하셔서 연휴내내 Pytorch, Cuda를 지지고 볶았다. 시행착오 끝에 가장 쉽게 돌려보는 방법을 찾았다.

AI관련 교육을 예전에 들은적이 있긴 한데, Cuda를 설치하거나 GPU기반 추론을 돌릴일이 한번도 없어서 없어서 이번 기회에 좀 정리를 해보았다.

요약: 윈도우 + WSL2 조합을 이용해서 실행한다.
WSL1에서는 GPU가 지원이 안되기 때문에 WSL1 을 쓰고 있으면 WSL2로 버전 업데이트를 해주어야 한다.
Cuda 11.4를 쓴다.
최신 Nvidia 그래픽 드라이버를 설치한다.

1. Llama2 모델을 다운받아야 한다.
구글에 llama2 download 라고 치면, 여기서 https://ai.meta.com/llama/ 링크가 나오는데meta 링크로 들어가 준다.

홈페이지에 들어가서 Download the Model을 눌러주자

이름, 성, 이메일주소(모델을 다운받을 수 있는 링크가 메일로 온다), 국가, 소속을 입력하고 다운받을 모델 llama2 & llama chat 을 선택

쭉 내려서 accept policy 하고 Accept and Continue 버튼 클릭

여기까지 하면 입력한 이메일로 Llama2를 받을 수 있는 링크와 다운로드에 필요한 URL이 같이 메일로 오게된다.

지금 박스로 가려진 부분은 다운로드를 받을 때 필요하니 복사해서 한쪽 메모장에 저장해둔다.

1번 Visit the Llama repository 라고 되어있는 링크를 클릭하면 Llama2다운로드할 수 있는 코드가 있는 레포지토리의 링크가 있다.

https://github.com/facebookresearch/llama 이 주소이고, 이를 다운로드 하기위해서는 zip파일로 다운 또는 git을 설치하고 git 명령어로 clone할 수 있다.

이 레포에 가면 필수적으로 wgetmd5sum 이 설치되어 있어야 한다고 한다. wget은 https://sound10000w.tistory.com/229이런 블로그들에 가면 설치방법이 잘 나와있다. 따라서 설치한다.

그리고 이 레포에 있는 파일들을 다운받아야 하는데, git을 설치하고 clone 으로 현재 레포를 로컬에 다운로드 한다.

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

나는 D드라이브에 git clone 명령어로 다운을 받았다.

다운로드된 llama 폴더로 들어가서 download.sh를 실행시킨다.

Email에 받은 url을 입력하라는 메세지가 뜨는데, 아까 메모장에 복사해두었던 링크를 붙여넣으면 된다(shift + insert).

링크를 제대로 입력했으면, 다운로드할 모델의 리스트를 입력하라는 창이 뜬다. 여기서 7B, 또는 7B-chat을 입력하면 된다. 숫자가 클수록 데이터의 양이 많지만, 그만큼 학습이나 추론을 하려면 어마어마한 GPU 리소스가 필요하다.

입력을 하고나면, 모델이 쭉 다운로드가 될 것이다. 다운로드하는데 인터넷 속도에 따라서 한참 걸리니 다음 스텝을 진행하면 된다.

2. WSL을 설치하고 필요한 CUDA 라이브러리 들을 설치한다.

WSL 버전2 까지 다루면 내용이 너무 많아지니 Ubuntu20.04설치 관련 문의는 댓글에 주시면 최대한 답변을 드리겠다.

Microsoft Store에 들어가서 Ubuntu20.04 버전을 다운받는다.

설치하고나서 CMD 명령 프롬프트 창에 wsl -l -v 라고 쳤을 때 Ubuntu-20.0.4의 Version이 2라고 되어있으면 바로 진행하면 되고, 아니면 wsl --set-version Ubuntu-20.04 2 이렇게 업데이트를 해줘야 한다.
에러가 나면, https://learn.microsoft.com/ko-kr/training/modules/wsl-introduction/install-and-setup 참고해서 디버깅을 하길 바란다.

이제부터는 pytorch를 위해 cuda 11.4를 설치하는 과정이다.

Nvidia 레포에서 Cuda 패키지 정보를 추가하고, 설치하게 되면 11.4 버전으로 잘 깔리게된다. Cuda12버전이 깔리면 Pytorch랑 아직 호환이 안되어서 에러가 발생하기 때문에 11.4로 설치했다.

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/11.4.0/local_installers/cuda-repo-wsl-ubuntu-11-4-local_11.4.0-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-11-4-local_11.4.0-1_amd64.deb
sudo apt-key add /var/cuda-repo-wsl-ubuntu-11-4-local/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda

여기까지 되었으면, WSL 에서 아까 GIT CLONE으로 다운로드한 디렉토리로 향한 후 Python 패키지들을 설치해준다.

파이썬3가 깔려있지 않고, venv나 pip도 없기 때문에 이것들을 먼저 설치하고, 가상환경을 만들어준 후 패키지를 설치한다.

# python pip and venv
sudo apt install -y python3-pip python3-venv

# go to llama directory and make venv
cd <llamapath>
sudo python3 -m venv venv

# activate venv and install package
source venv/bin/activate
sudo pip install -e .

파이썬 패키지 설치가 다 끝나면, torchrun 명령어로 예시 코드를 실행할 수 있다.

torchrun --nproc_per_node 1 example_chat_completion.py --ckpt_dir llama-2-7b-chat/ --tokenizer_path tokenizer.model

모델에 따라 nproc_per_node (MP)가 달라지는데, 7B의 경우 1로 설정하면 실행이 가능하다.

여기서 example_chat_completion.py는 이미 메타에서 예제코드로 만들어놓은 코드로, 이미 입력이 정해져 있고, 사용자 입력을 넣을 수 없다.

나는 코드를 일부 수정해서 사용자 Input에 대한 답을 주도록 고쳐보았다.

def main(
    ckpt_dir: str,
    tokenizer_path: str,
    temperature: float = 0.6,
    top_p: float = 0.9,
    max_seq_len: int = 512,
    max_batch_size: int = 8,
    max_gen_len: Optional[int] = None,
):
    """
    Entry point of the program for generating text using a pretrained model.

    Args:
        ckpt_dir (str): The directory containing checkpoint files for the pretrained model.
        tokenizer_path (str): The path to the tokenizer model used for text encoding/decoding.
        temperature (float, optional): The temperature value for controlling randomness in generation.
            Defaults to 0.6.
        top_p (float, optional): The top-p sampling parameter for controlling diversity in generation.
            Defaults to 0.9.
        max_seq_len (int, optional): The maximum sequence length for input prompts. Defaults to 512.
        max_batch_size (int, optional): The maximum batch size for generating sequences. Defaults to 8.
        max_gen_len (int, optional): The maximum length of generated sequences. If None, it will be
            set to the model's max sequence length. Defaults to None.
    """
    generator = Llama.build(
        ckpt_dir=ckpt_dir,
        tokenizer_path=tokenizer_path,
        max_seq_len=max_seq_len,
        max_batch_size=max_batch_size,
    )
    while True:
        # instead of hardcoding set content as user input
        dialogs: List[Dialog] = [
            [{"role": "user", "content": input("Enter your message: ")}],
        ]
        start = time.time()

        results = generator.chat_completion(
            dialogs,  # type: ignore
            max_gen_len=max_gen_len,
            temperature=temperature,
            top_p=top_p,
        )

        for dialog, result in zip(dialogs, results):
            for msg in dialog:
                print(f"{msg['role'].capitalize()}: {msg['content']}\n")
            print(
                f"> {result['generation']['role'].capitalize()}: {result['generation']['content']}"
            )
            print("\n==================================\n")
        end = time.time()
        print(f"Time taken: {end - start} seconds")

if __name__ == "__main__":
    fire.Fire(main)

모델 초기화 후 계속해서 사용자 입력을 받을 수 있도록 While문을 돌렸다.
중간중간 얼마 걸렸는지 체크할 수 있도록, 시간 체크하는 부분정도 추가된 간단한 코드이다.

RTX A5000을 쓰고 있는데, 모델 로딩에 90초, 추론에는 질문 길이에 따라 다르지만 대략 30초 내외로 걸렸다. 본가에 있는 RTX3090으로는 로딩 90초 추론에는 5분정도 걸렸다.

rtx3090에서 돌렸는데 318초 걸렸다. 동일한 질문으로 A5000에서는 30초, 그래픽은 비싼값을 한다.