엔지니어링

Nov 21, 2023

엔지니어링

Backend.AI Model Service Hands-on: GPT-NeoX 실행하기

  • 조규진

    선임 소프트웨어 엔지니어

Nov 21, 2023

엔지니어링

Backend.AI Model Service Hands-on: GPT-NeoX 실행하기

  • 조규진

    선임 소프트웨어 엔지니어

Backend.AI 23.09 버전이 정식으로 공개되었습니다. 23.09 버전의 핵심 기능인 Model Service에 대해서는 이전의 Sneak Peek: Backend.AI Model Service 미리 보기 글에서 다뤘던 바가 있습니다. 그 이후로 GUI 지원, 인증 토큰 이력 관리 등의 다양한 새로운 기능이 추가되었는데요, 이러한 새 기능을 포함해서 Backend.AI Model Service를 쉽고 간편하게 이해할 수있도록 튜토리얼 형식으로 따라가 보는 시간을 가져보도록 하겠습니다.
이번 튜토리얼 게시글에서는 Backend.AI Model Service를 이용해서 GPT-NeoX 모델을 Triton Inference Server 위에서 구동하는 법에 대해 안내합니다. Triton Inference Server는 NVIDIA에서 내놓은 오픈 소스 모델 인퍼런스 프레임워크이며, 자사의 TritonRT, FasterTransformer 및 TritonRT-LLM 및 PyTorch, TensorFlow, vLLM 등의 다양한 모델을 HTTP 및 gRPC 1 로 간편하게 제공할 수 있습니다.

Model VFolder 생성

  1. 데이터 & 폴더 탭으로 이동합니다. "새 폴더" 버튼을 클릭하여 VFolder 생성 다이얼로그를 엽니다.
  2. 새 모델 폴더를 생성합니다. 폴더 이름은 어떻게 적어도 관계 없지만 하단의 "사용 방식" 을 "Model" 로 설정해야 합니다. 모든 값을 지정하였으면 하단의 "생성" 버튼을 클릭합니다. 이제 모델 VFolder가 생성되었습니다.

FasterTransformer 형식 모델 변환

  1. "세션" 탭으로 이동합니다. "시작" 버튼을 클릭하여 세션 생성 다이얼로그를 엽니다.
  2. "실행 환경" 을 ngc-pytorch 로, 버전23.07 을 선택합니다. 선택이 완료되었으면 오른쪽 아래의 화살표 아이콘을 클릭합니다.
  3. 세션에 탑재할 VFolder를 선택하는 창입니다. 모델을 적재하기 위해 "마운트할 모델 스토리지 폴더" 섹션 아래에서 방금 생성한 VFolder를 선택합니다. 선택이 완료되었으면 오른쪽 아래의 화살표 아이콘을 클릭합니다.
  4. 모델 세션에서 사용할 자원량을 지정하는 창입니다. CPU 코어를 16개 이상, RAM은 128GB 이상 할당하여야 원활한 모델 변환이 가능합니다. 선택이 완료되었으면 오른쪽 아래의 화살표 아이콘을 클릭합니다.
  5. 모든 설정이 올바르게 적용되었는지 확인한 후 아래의 "시작" 버튼을 클릭하여 세션을 시작합니다.
  6. 세션이 생성되면 다음과 같이 앱을 선택하는 팝업이 나타납니다. "Console" 앱을 클릭하여 터미널 환경으로 접근합니다.
  7. 다음 쉘 스크립트를 실행하여 GPT-NeoX 20B 모델을 다운로드하고 FasterTransformer 형식에 맞게 변환합니다. 스크립트에서 <VFolder 이름> 이라고 언급된 부분을 생성한 모델 VFolder 이름으로 치환해서 실행해야 함에 주의하세요.
cd /home/work/<VFolder 이름> pip install -U transformers bitsandbytes git clone https://github.com/NVIDIA/FasterTransformer git clone https://huggingface.co/ElutherAI/gpt-neox-20b cd neo-gptx-20b git lfs install git lfs pull

GPT-NeoX 20B 모델은 실행에 40GB 이상의 VRAM을 요구합니다. 사용할 물리 GPU의 VRAM이 이보다 작아 모델을 여러 GPU에 나눠서 실행해야 할 경우, -i_g 매개 변수의 숫자를 사용할 GPU 갯수에 맞춰서 조정하세요.

cd /home/work/<VFolder 이름> mkdir -p triton-deploy/gpt-neox-20b-ft python ~/<VFolder 이름>/FasterTransformer/examples/pytorch/gptneox/utils/huggingface_gptneox_convert.py \ -i /home/work/<VFolder 이름>/gpt-neox-20b \ -o /home/work/<VFolder 이름>/triton-deploy/gpt-neox-20b-ft \ -i_g 1 \ -m_n GPT-NeoX-20B

  1. 7번까지의 과정을 모두 완료했다면 VFolder 아래에 다음과 같은 폴더들이 존재할 것입니다.
work@main1[PRRLCIqu-session]:~/GPT-NeoX-Triton-FT$ ls -al total 62 drwxr-xr-x 5 work work 11776 Oct 12 12:14 . drwxr-xr-x 9 work work 4096 Oct 12 12:29 .. drwxr-xr-x 14 work work 12800 Oct 12 11:24 FasterTransformer drwxr-xr-x 3 work work 16896 Oct 12 10:18 gpt-neox-20b drwxr-xr-x 3 work work 11776 Oct 12 11:56 triton-deploy

이제 Triton Inference Server의 설정 파일을 추가할 차례입니다. triton-deploy/gpt-neox-20b-ft/config.pbtxt 파일을 생성하고 다음 내용을 추가합니다.

7번 과정에서 -i_g 매개 변수의 값을 1이 아닌 다른 값으로 설정했을 경우, 아래 설정의 tensor_para_size 값을 -i_g 값과 일치하도록 수정해야 합니다.

name: "gpt-neox-20b-ft" backend: "fastertransformer" default_model_filename: "gpt-neox-20b-ft" max_batch_size: 1024 model_transaction_policy { decoupled: False } input [ { name: "input_ids" data_type: TYPE_UINT32 dims: [ -1 ] }, { name: "start_id" data_type: TYPE_UINT32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "end_id" data_type: TYPE_UINT32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "input_lengths" data_type: TYPE_UINT32 dims: [ 1 ] reshape: { shape: [ ] } }, { name: "request_output_len" data_type: TYPE_UINT32 dims: [ -1 ] }, { name: "runtime_top_k" data_type: TYPE_UINT32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "runtime_top_p" data_type: TYPE_FP32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "beam_search_diversity_rate" data_type: TYPE_FP32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "temperature" data_type: TYPE_FP32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "len_penalty" data_type: TYPE_FP32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "repetition_penalty" data_type: TYPE_FP32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "random_seed" data_type: TYPE_UINT64 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "is_return_log_probs" data_type: TYPE_BOOL dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "beam_width" data_type: TYPE_UINT32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "bad_words_list" data_type: TYPE_INT32 dims: [ 2, -1 ] optional: true }, { name: "stop_words_list" data_type: TYPE_INT32 dims: [ 2, -1 ] optional: true }, { name: "prompt_learning_task_name_ids" data_type: TYPE_UINT32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "top_p_decay" data_type: TYPE_FP32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "top_p_min" data_type: TYPE_FP32 dims: [ 1 ] reshape: { shape: [ ] } optional: true }, { name: "top_p_reset_ids" data_type: TYPE_UINT32 dims: [ 1 ] reshape: { shape: [ ] } optional: true } ] output [ { name: "output_ids" data_type: TYPE_UINT32 dims: [ -1, -1 ] }, { name: "sequence_length" data_type: TYPE_UINT32 dims: [ -1 ] }, { name: "cum_log_probs" data_type: TYPE_FP32 dims: [ -1 ] }, { name: "output_log_probs" data_type: TYPE_FP32 dims: [ -1, -1 ] } ] instance_group [ { count: 1 kind: KIND_CPU } ] parameters { key: "tensor_para_size" value: { string_value: "1" } } parameters { key: "pipeline_para_size" value: { string_value: "1" } } parameters { key: "data_type" value: { string_value: "fp16" } } parameters { key: "model_type" value: { string_value: "GPT-NeoX" } } parameters { key: "model_checkpoint_path" value: { string_value: "/models/triton-deploy/gpt-neox-20b-ft/1-gpu" } } parameters { key: "enable_custom_all_reduce" value: { string_value: "0" } }
  1. 마지막으로 Backend.AI Model Service 정의 파일을 VFolder 루트 아래에, model-definition.yaml (model-definition.yml 도 허용) 추가해야 합니다. Triton Inference Server를 실행하기 위한 모델 정의 파일을 자세히 들여다 보겠습니다.
models: - name: "GPT-NeoX" model_path: "/models/triton-deploy" ...

모델 이름과 모델의 경로를 지정하는 부분입니다.

여기서 설정한 이름과 경로는 모델 서버 프로세스에서 각각 BACKEND_MODEL_NAME, BACKEND_MODEL_PATH 환경 변수로 접근할 수 있습니다.

... service: start_command: - tritonserver - --model-repository=/models/triton-deploy - --disable-auto-complete-config - --log-verbose - "1" ...

모델 서버 프로세스를 시작하기 위한 명령줄 구문을 정의하는 부분입니다.

... port: 8000 ...

모델 서버 프로세스가 노출하는 API 통신용 포트를 기입하는 부분입니다. 지정하지 않은 경우, Triton Inference Server는 기본적으로 HTTP API 통신을 위해 8000 번 포트를 노출합니다. 그러므로 모델 정의 파일에도 해당 포트를 그대로 적어줍니다.

... health_check: path: /v2/health/ready max_retries: 3 max_wait_time: 5 expected_status_code: 200

Health Check 기능을 활성화 및 설정하는 부분입니다. Health Check 기능이 활성화 된 경우, Backend.AI에서는 해당 경로에 지속적으로 HTTP GET 요청을 보내서 expected_status_code (생략 가능, 기본값 200) 에 해당하는 HTTP 응답 코드를 반환하는지를 검증합니다. 만약 모델 서버가 응답하지 않거나, 혹은 정의되지 않은 응답 코드를 반환하는 경우, Backend.AI는 해당 세션을 불량한 (Unhealthy) 세션으로 판단하고 서비스에서 제외합니다. 세션이 서비스에서 제외되더라도 해당 세션은 자동으로 종료되지 않으며 Model Service 관리자가 컨테이너 로그 등을 확인하여 적절한 조치를 직접 취해야 합니다.
Health Check 기능은 해당 구문을 완전히 생략하는 것으로 비활성화 시킬 수 있습니다. 이렇게 할 경우 Backend.AI는 모델 서버의 상태를 검사하지 않고 항상 Healthy 상태인 것으로 간주합니다.
max_wait_time 은 API 응답 Timeout을 정의하는 부분입니다. 초 단위의 숫자를 기입해야 합니다.
max_retries 는 해당 모델 서버를 Unhealthy 상태로 판단하기 전까지 요청을 재시도하는 회수를 뜻합니다.
완성된 모델 정의 파일은 다음과 같습니다.

models: - name: "GPT-NeoX" model_path: "/models/triton-deploy" service: start_command: - tritonserver - --model-repository=/models/triton-deploy - --disable-auto-complete-config - --log-verbose - "1" port: 8000 health_check: path: /v2/health/ready max_retries: 3 max_wait_time: 5

모델 정의 파일에 대한 더 자세한 내용은 Backend.AI WebUI 문서 에서 확인하실 수 있습니다.

이제 Model Service를 실행하기 위한 모든 준비가 완료되었습니다.

Model Service 생성

  1. "모델 서빙" 탭으로 이동합니다. "서비스 시작" 버튼을 클릭하여 Model Service 생성 창을 엽니다. 각 섹션에 대해 조금 더 상세히 살펴보겠습니다.
    • 서비스 이름: Model Service 이름을 지정하는 칸입니다. Model Service의 이름은 Model Service Endpoint의 Subdomain으로 사용될 수 있습니다 (추후 업데이트 예정).
    • 자원 그룹: Model Service용 Inference Session이 생성 될 자원 그룹을 선택하는 칸입니다.
    • 앱을 외부에 공개: 이 기능이 활성화 될 경우, 모델 서버로 향하는 모든 API 요청은 인증 헤더를 첨부해야 이루어질 수 있습니다. Model Service 인증에 대한 자세한 내용은 Backend.AI WebUI 문서 를 참고하세요.
    • 원하는 라우팅 수: 모델 서버 프로세스가 실행되는 추론 세션 수를 지정하는 칸입니다. 이 값을 1보다 큰 숫자로 설정할 경우 여러 개의 동일한 세션이 생성되고, API 요청은 이 세션들에게 균등하게 분배하는 라운드-로빈 로드 밸런서 기능이 활성화 됩니다. 이 값은 Model Service 생성 이후 언제든지 수정 가능합니다.
    • 추론 세션의 자원량을 지정하는 패널입니다.

GPT-NeoX 20B 모델은 구동에 최소 40GB 이상의 vRAM을 요구합니다.
Backend.AI의 fGPU 단위와 vRAM의 관계는 사용 중인 Backend.AI의 설정에 따라 다르게 적용될 수 있습니다. 자세한 사항은 사용 중인 Backend.AI 의 관리자와 상의하세요.

모든 값을 올바르게 설정했다면 "확인" 버튼을 눌러 Model Service를 생성합니다.
2. Model Service가 생성되었습니다. 추론 세션의 모델 프로세스가 아직 준비되지 않은 Model Service의 경우 상태가 "PROVISIONING" 에 머무르게 됩니다. "세션" 탭의 "INFERENCE" 섹션을 클릭하면 1에서 생성한 Model Service에 해당하는 추론 세션이 생성되었음을 확인할 수 있습니다. Model Service 관리자는 "제어" 행의 클립보드 아이콘을 클릭하여 추론 세션의 모델 서버 프로세스에 관련된 로그를 확인할 수 있습니다. 3. 모델 서버 프로세스가 정상적으로 실행되면 하단의 라우트의 상태와 상단의 상태가 모두 "HEALTHY" 로 변경되며, "서비스 엔드포인트" 에 Model Service에 접근하기 위한 주소가 나타납니다. 이제 해당 주소를 통해 추론 세션에 실행된 Triton Inference Server에 접근할 수 있습니다.

마치며

지금까지 Backend.AI Model Service를 이용해서 LLM 모델 서빙을 시작하는 방법에 대해 알아보았습니다. Model Service 기능은 Backend.AI의 Cloud Beta에서 사용 가능합니다. 지금 여러분만의 모델 서빙을 시작해 보세요!

1: Backend.AI Model Service에서는 지원하지 않음

도움이 필요하신가요?

내용을 작성해 주시면 곧 연락 드리겠습니다.

문의하기

본사 및 HPC 연구소

서울특별시 강남구 선릉로 577 CR타워 8층

© Lablup Inc. All rights reserved.