이번 글에서는 LLM 서버를 구축하는 것을 다룹니다. windows 환경에서 docker desktop을 사용하여 docker를 사용하고, 코드 작성 및 ssh 연결은 vscode를 사용합니다.
먼저, LLM 서버 구축을 위해 docker container를 생성합니다. GPT, Claude, CLOVA 등 API를 사용하고자 한다면 서버 구축 과정 없이 프로젝트를 진행해도 좋습니다. 베이스라인은 LLM 서버를 OpenAI API 형식에 맞추어 호출할 수 있는 서버를 구축합니다.
서버 구축은 크게 두 가지 방법이 있습니다. 첫 번째는 llama-cpp-python에서 제공하는 docker image를 사용하여 구축하는 방법입니다. 로컬에서 명령어 한 줄로 간단히 서버를 구축할 수 있기에 굉장히 편리한 방법입니다. 두 번째는 직접 docker image를 만들어 서버 환경을 만들어 구축하는 방법입니다. 직접 환경을 구축하기 때문에 원하는 부분을 커스터마이징 할 수 있다는 장점이 있습니다.
베이스라인은 두 번째 방법으로 서버를 구축하겠습니다.
먼저, API를 올리기 위한 docker container를 만들어야합니다. docker container는 dockerfile을 활용하여 image를 빌드하고, 빌드한 image로 container를 빌드합니다. 그럼, docker image 빌드를 위한 dockerfile 작성을 하겠습니다.
Docker container는 GPU사용을 위해 nvidia에서 제공하는 cuda 이미지를 기본으로 사용합니다. 다음으로 가상환경 관리를 위해 conda를 설치하고 ssh 연결을 위해 openssh를 설치합니다.
# 기본OS세팅 및 콘다세팅
# GPU사용을 위해 기본 이미지로 cuda 12.1.1 버전의 ubuntu 20.04 이미지를 사용
FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu20.04
USER root
# ubuntu 환경에서 필요한 도구를 설치
RUN apt-get update \
&& apt-get install -yq --no-install-recommends \
wget \
bzip2 \
ca-certificates \
sudo \
locales \
libgl1-mesa-glx \
libglib2.0-0 \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen
# 환경 구성에 필요한 환경 변수를 설정
ENV CONDA_DIR=/opt/conda \
SHELL=/bin/bash \
LC_ALL=en_US.UTF-8 \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8
ENV PATH=$CONDA_DIR/bin:$PATH
RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc
RUN sed -i.bak -e 's/^%admin/#%admin/' /etc/sudoers
RUN sed -i.bak -e 's/^%sudo/#%sudo/' /etc/sudoers
# 미니콘다를 설치, 설치 후 sh파일은 제거
RUN mkdir -p $CONDA_DIR
WORKDIR $HOME
ARG PYTHON_VERSION=default
ENV MINICONDA_VERSION=4.12.0 \
MINICONDA_MD5=d63adf39f2c220950a063e0529d4ff74 \
CONDA_VERSION=4.12.0
WORKDIR /tmp
RUN wget --quiet https://repo.continuum.io/miniconda/Miniconda3-py38_${MINICONDA_VERSION}-Linux-x86_64.sh
RUN /bin/bash Miniconda3-py38_${MINICONDA_VERSION}-Linux-x86_64.sh -f -b -p $CONDA_DIR
RUN rm Miniconda3-py38_${MINICONDA_VERSION}-Linux-x86_64.sh
RUN echo "conda ${CONDA_VERSION}" >> $CONDA_DIR/conda-meta/pinned
RUN conda config --system --prepend channels conda-forge
RUN if [ ! $PYTHON_VERSION = 'default' ]; then conda install --yes python=$PYTHON_VERSION; fi
RUN conda list python | grep '^python ' | tr -s ' ' | cut -d '.' -f 1,2 | sed 's/$/.*/' >> $CONDA_DIR/conda-meta/pinned
# SSH 사용을 위해 open_ssh를 설치
RUN apt update
RUN apt install -y --no-install-recommends openssh-server
RUN apt install -y libpam-pwquality
RUN echo 'PASS_MIN_LEN 8' >> /etc/login.defs
RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
RUN apt clean
RUN rm -rf /var/lib/apt/lists/*
# 비밀번호 변경
RUN echo 'root:Password' | chpasswd
# 구축된 서버에서 사용할 디렉토리 변경
WORKDIR /root/dev
# dockerfile과 동일 디렉토리에 entry.sh 파일을 구성하여 ENTRYPOINT로 사용
COPY entry.sh /entry.sh
RUN chmod +x /entry.sh
ENTRYPOINT [ "/entry.sh" ]
entry.sh은 ssh를 실행 후 sleep infinity를 통해 docker container가 종료되지 않게 합니다.
#!/bin/bash
service ssh start
sleep infinity
** gradio 서버 역시 이와 동일한 ubuntu 환경에서 구성됩니다.
dockerfile 작성이 완료되면, 이를 사용하여 docker image를 빌드합니다. docker_image_name에는 이미지 이름으로 사용하고싶은 이름을 입력하고, dockerfile에는 위에서 구성한 dockerfile의 파일명을 입력하면 됩니다.
docker build -t docker_image_name:latest -f dockerfile .
** windows 환경에서 docker 사용 시 주의할 점은, docker desktop이 실행된 상태에서 사용해야한다는 점입니다. 간혹, docker desktop 실행하지 않고 docker 명령어가 안된다는 이슈가 있는데, 반드시 docker desktop을 실행 후 docker 명령어를 사용해주세요.
docker container 생성이 완료되었다는 메세지가 나타나면, docker desktop 혹은 docker images 명령어를 통해 docker image 생성 여부를 확인해주세요.
docker image 빌드가 완료되면 이를 사용하여 docker container를 생성합니다. docker container는 docker run 명령어를 사용하여 생성하는데, 이 때 고려할 점은 volume의 사용 여부와 port forwarding의 사용 여부입니다. docker container를 빌드한 후에는 volume, port forwarding을 변경할 수 없기에 사용할 volume directory와 포트를 정한 후 빌드하시길 바랍니다.
베이스라인에서 22 포트는 ssh 통신, 7860 포트는 API 통신을 위한 포트입니다. `port_in_windows` 부분에 사용하고자 하는 포트 번호를 입력하세요.
volume은 docker container의 디렉토리와 localhost의 디렉토리를 연결하는 방법이며, 이를 통해 docker container에서 작업한 작업물을 localhost에서 볼 수 있습니다. `volume_directory_in_windows` 부분을 수정하여 원하는 local directory에 docker directory를 연결하세요. 만약, volume이 필요없다면 `-v ~ dev"` 부분을 제거하면 됩니다.
docker run -dit --gpus all --name container_name --restart unless-stopped -v "volume_directory_in_windows:/root/dev" -p port_in_windows1:22 -p port_in_windows2:7860 docker_image_name:latest
docker container 생성이 완료되면 vscode를 사용하여 docker container로 접속합니다.
1) vscode 실행 후 F1을 눌러 ssh 구성파일 열기
2) 아래 코드 입력 후 저장
** port_number는 docker container의 22번 포트와 포워딩된 포트를 입력해주세요.
Host container_sever
HostName 127.0.0.1
Port port_number
User root
3) vscode 사이드 바의 원격 탐색기 클릭 후 container_server 접속, /root 디렉토리 열기
접속이 완료되면 터미널을 열어 conda 경로와 cuda 경로를 설정합니다. 아래 두 링크를 확인해주세요.
https://leefromdata.tistory.com/68
[Ubuntu] CONDA 경로 설정
1. NVIDIA/CUDA 이미지를 기반으로 Dockerfile 구성 2. Dockerfile로 필요한 도커 이미지 생성 2-1. openSSH설치하는 코드가 있어 vscode로 접근가능 3. 도커 컨테이너 생성 export PATH=/opt/conda/bin:$PATH ~/ 경로의 .bash
leefromdata.tistory.com
https://leefromdata.tistory.com/67
[Ubuntu] CUDA 경로 설정
상황 1. NVIDIA/CUDA 이미지를 기반으로 Dockerfile 구성 2. Dockerfile로 필요한 도커 이미지 생성 2-1. openSSH설치하는 코드가 있어 vscode로 접근가능 3. 도커 컨테이너 생성 ls /usr/local # bin cuda cuda-12 cuda-12.1 .
leefromdata.tistory.com
conda와 cuda 경로 설정이 완료되면 서버에서 사용할 가상환경을 추가하고 필요한 패키지를 설치합니다.
# env_name은 사용하려는 가상환경의 이름, 3.9에는 사용하려는 python 버전을 입력합니다.
conda create -n env_name python=3.9
# 가상환경을 만든 후 활성화합니다.
conda activate env_name
# 필요한 패키지를 설치합니다.
CMAKE_ARGS="-DLLAMA_CUDA=on" FORCE_CMAKE=1 pip install 'llama-cpp-python[server]' --no-cache
가상환경 설정이 마무리되면 사용할 모델을 다운받습니다. 베이스라인에서는 llama-3-8B-instruct.Q4_K_M을 사용합니다. 허깅페이스에서 해당 하는 모델을 다운받아 `/root/dev` 디렉토리에 저장합니다.
https://huggingface.co/SanctumAI/Meta-Llama-3-8B-Instruct-GGUF/tree/main
SanctumAI/Meta-Llama-3-8B-Instruct-GGUF at main
huggingface.co
마지막으로 API 빌드를 위한 config 파일을 작성하고 실행합니다. config변수는 llama-cpp-python의 웹에서 확인할 수 있습니다.
https://llama-cpp-python.readthedocs.io/en/latest/server/
OpenAI Compatible Web Server - llama-cpp-python
Bases: BaseSettings Server settings used to configure the FastAPI and Uvicorn server. Source code in llama_cpp/server/settings.py class ServerSettings(BaseSettings): """Server settings used to configure the FastAPI and Uvicorn server.""" # Uvicorn Settings
llama-cpp-python.readthedocs.io
베이스라인은 포트 번호, 모델, 모델 별명(alias), chat foramt, GPU 사용 여부, context window, batch size 변수를 명시한 config 파일을 작성합니다. 모델은 사용 모델의 절대경로 혹은 상대경로를 의미합니다.
{
"host": "0.0.0.0",
"port": 7860,
"models": [
{
"model": "Meta-Llama-3-8B-Instruct.Q4_K_M.gguf",
"model_alias": "llama-3-8b-it-q4",
"chat_format": "llama-3",
"n_gpu_layers": -1,
"n_ctx":8192,
"n_batch":1
}
]
}
config 파일 작성 후 터미널에서 llama cpp server 실행 명령어를 입력하여 API를 실행합니다.
python -m llama_cpp.server --config_file config_file_name
마지막으로 fastapi swagger를 통해 API 테스트를 진행합니다. llamacpp API는 swagger를 지원하며, 이를 통해 API를 손쉽게 테스트할 수 있습니다. "http://127.0.0.1:port/docs"로 접속하여 swagger를 열 수 있습니다. 이 때, port는 이전에 설정한 API 포트 번호로 변경합니다.
swagger를 열면 아래 그림과 같은 화면을 볼 수 있는데, 그림의 붉은 박스(아래 방향 화살표, Try it out)를 클릭하고, JSON의 model 부분을 config에서 설정한 "model_alias"로 변경한 후 Execute를 클릭하면 Response에서 결과를 확인할 수 있습니다.
LLM with Naver API (0) | 2024.05.16 |
---|---|
LLM with RAG - Gradio server (0) | 2024.05.09 |
LLM with RAG - milvus server (0) | 2024.05.07 |
LLM with RAG (0) | 2024.05.07 |
BERT (0) | 2023.01.09 |
댓글 영역