데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      효율적 시맨틱 검색을 위한 kubernetes GPU inference 시스템 구축하기

      sjlee 25.04.01
      2,563 12 3
      DEVOTEE 요약
      최근 인공지능 기술의 발전으로 시맨틱 검색, 즉 벡터 검색의 중요성이 부각되고 있으며, 이는 전통적인 키워드 기반 검색을 넘어 질의의 의도를 이해하고 의미적으로 연관된 정보를 찾는 데 효과적입니다. 이를 위해 GPU와 같은 고성능 인프라의 중요성이 커졌고, NVIDIA의 Triton Inference Server를 활용하여 시맨틱 검색을 위한 GPU 기반 추론 서버를 Kubernetes 클러스터에 구축하였습니다. 이 시스템은 다양한 AI 모델을 서빙하기 위한 최적의 환경을 제공하며, ONNX 변환을 통해 모델 최적화와 하드웨어 가속기를 지원하여 시맨틱 검색과 같은 실시간 응답이 중요한 서비스에 효율적으로 대응할 수 있습니다.
      DEVOTEE 추천 블로그

      시작하며

      ​최근 인공지능(AI) 기술의 발전으로 인해 검색 분야에서도 시맨틱 검색, 즉 벡터 검색의 중요성이 부각되고 있습니다.

      전통적인 키워드 기반 검색과 시맨틱 검색은 각각의 강점이 있으며, 특정 상황과 요구에 따라 효과적으로 활용될 수 있습니다.


      키워드 기반 검색은 입력한 질의에서 주요 단어나 구문을 추출하여 문서에서 정확히 일치하거나 부분적으로 일치하는 항목을 찾아냅니다.

      이러한 방식은 다음과 같은 경우에 효과적입니다.

      • 정확한 용어 검색: 특정한 단어나 구문을 포함하는 문서를 찾을 때 유용

      • 구조화된 데이터 검색: 데이터베이스에서 정확한 필드 값을 기반으로 검색할 때 적합

      • 단순하고 빠른 검색: 비교적 간단한 알고리즘으로 빠른 검색 결과를 제공

      시맨틱 검색은 단어와 문장의 의미를 벡터 형태로 표현하여, 질의와 문서 간의 의미적 유사성을 기반으로 검색 결과를 제공합니다. 이는 다음과 같은 상황에서 효과적입니다.

      • 동의어 및 유의어 처리: 동일한 의미를 가진 다양한 표현을 인식하여 관련 결과를 제공

      • 문맥 기반 검색: 단어의 문맥을 이해하여 보다 정확한 검색 결과를 제공

      • 자연어 처리: 사용자의 질의를 자연어로 이해하고 처리하여, 보다 인간 친화적인 검색 경험을 제공​

      사용자들은 원하는 정보를 찾기 위해 점점 더 복잡하고 다양한 형태의 질의를 던지고 있으며,

      이러한 요구에 맞춰 검색서비스는 단순한 키워드 매칭을 넘어 질의의 의도를 이해하고 의미적으로 연관된 정보를 찾아내는 방향으로 발전하고 있습니다.


      이러한 배경에서 검색서비스팀은 문맥 기반 검색을 강화하고자 에이닷 뉴스 검색 서비스에 시맨틱 검색을 적용했고, 검색 품질저하를 야기하는 아래 2가지 이슈를 개선하였습니다.

      • 검색어와 의미적으로 관련성이 없는 뉴스 (검색어: 애플 → 이주연, 비키니로 뽐낸 글래머 몸매…섹시 애플힙)

      • 검색어가 등장하긴 하지만 여러 키워드가 같이 등장해 관련성이 떨어지는 뉴스 (검색어: 애플 → 삼성전자, 미래 가치 브랜드서 애플 제쳤다...퓨처브랜드 1위)

      이를 실현하기 위해서는 실시간 수준의 시맨틱 검색이 가능해야 하며, 대규모 데이터를 빠르게 처리할 수 있는 GPU와 같은 고성능 인프라 구축과 효율적인 활용이 필수적입니다.


      최근 GPU 인프라 기술의 발전으로 이러한 복잡한 연산을 실시간으로 처리하는 것이 가능해졌습니다.

      특히, NVIDIA의 triton inference server는 다양한 AI 모델의 추론을 효율적으로 수행할 수 있도록 설계되어 GPU의 성능을 최대한 활용하여 실시간으로 AI 모델을 서빙하는 데 최적화되어 있으며,

      kubernetes를 활용하여 컨테이너 기반의 애플리케이션 배포, 스케일링 및 관리를 자동화하여, 확장 가능하고 안정적으로 운영할 수 있습니다.

      이러한 배경에서 검색서비스팀은 시맨틱 검색, 나아가서 LLM 기반의 질의 분석 등의 활용을 위해 GPU 기반 추론 서버를 kubernetes 클러스터에 구축하였습니다.

      이 글에서는 NVIDIA triton inference server와 ONNX 변환을 이용하여 kubernetes에 GPU 기반 추론 서버를 구축하는 과정을 다루고자 합니다.


      NVIDIA Triton Inference Server

      NVIDIA triton inference server는 AI 모델 서빙을 위한 오픈소스 솔루션으로, 다양한 딥러닝 프레임워크를 지원하며 GPU 리소스 활용을 극대화하는 데 최적화된 추론 서버입니다.

      TensorFlow, PyTorch, ONNX, TensorRT 등 여러 백엔드를 지원하여 프레임워크에 구애받지 않고 다양한 모델을 규격화하여 배포할 수 있는 유연성을 제공합니다.

      kubernetes 환경과의 통합을 통해 안정적인 운영과 확장성 역시 보장하며, 대규모 AI 추론 워크로드를 효과적으로 처리할 수 있습니다.


      Triton inference server는 아래와 같은 구조를 따라야 합니다.

      model_repository/
        └── sample_model/
            ├── 1/
            │   └── model.onnx (onnx 모델 변환 가정)
            └── config.pbtxt
      • sample_model : 모델 이름

      • 1/ : 버전 디렉토리 (숫자형 버전)

      • model.onnx : ONNX 모델 파일

      • config.pbtxt : Triton 설정 파일

      주요 특징 중 하나는 dynamic batching 기능으로 여러 요청을 하나의 배치로 묶어 처리함으로써 GPU 활용률을 극대화하고 지연 시간을 줄이는 최적화 기법입니다.

      아래와 같이 config.pbtxt 에 명시하여 적용할 수 있습니다.

      dynamic_batching {
        preferred_batch_size: [4, 8]
        max_queue_delay_microseconds: 100000
      }

      preferred_batch_size와 max_queue_delay_microseconds를 통해 배치 크기와 대기 시간을 조정하여 메모리 사용량과 API 성능을 최적화할 수 있습니다.

      • scheduler가 여러 요청을 대기시켰다가 일정 크기(preferred_batch_size)에 도달하면 해당 요청을 하나의 batch로 처리합니다.

      • scheduler가 너무 오래 대기하지 않도록 일정 시간(max_queue_delay_microseconds)에 도달하면 batch 크기에 상관없이 바로 실행됩니다.

      이 기능은 트래픽이 증가할 경우 자동으로 배치 크기를 조정하며 효율적인 서빙을 가능하게 합니다.


      또한 multi-instance 기능을 통해 동일한 모델의 여러 인스턴스를 병렬로 실행하여 다수의 요청을 균등하게 분산 처리할 수 있습니다.

      아래와 같이 config.pbtxt 에 명시하여 적용할 수 있습니다.

      instance_group [
        {
          kind: KIND_GPU
          count: 3
        },
        {
          kind: KIND_CPU
          count: 3
        }
      ]

      각 인스턴스는 특정 하드웨어(GPU 또는 CPU)에서 실행되며, 인스턴스 수와 배치 크기에 따라 하드웨어 리소스를 최적화하여 최대 성능을 발휘합니다.

      이를 통해 특정 GPU에 과부하가 걸리는 상황을 방지하고 안정적인 추론 서비스를 제공할 수 있습니다.


      Triton inference server는 이러한 최적화 모듈을 통해 더 많은 모델을 동일한 GPU에서 실행 가능하게 하여 서빙 효율을 극대화합니다.

      또한 통합된 모델 관리 체계를 제공하여 다양한 모델을 단일 리소스 관리 체계에서 실행할 수 있으며, 이를 통해 운영의 복잡성을 줄이고 확장성을 높일 수 있습니다. 

      여기에 ONNX 변환과 같은 모델 최적화가 더해진다면 서빙 효율을 극대화하여 더 낮은 지연 시간의 API 개발이 가능하며, 시멘틱 검색과 같은 실시간 응답이 중요한 서비스에 좋은 솔루션이 될 수 있습니다. 

      다음으로 모델 최적화를 목적으로 활용했던 ONNX 변환에 대해 설명해 드리겠습니다.


      ONNX

      ONNX 란

      ONNX(Open Neural Network Exchange)는 다양한 딥러닝 프레임워크 간의 모델 교환과 호환성을 보장하기 위해 개발된 오픈소스 표준입니다.

      TensorFlow, PyTorch 등 서로 다른 프레임워크에서 개발된 딥러닝 모델을 ONNX 형식으로 변환하면, 최종 배포 환경에서 프레임워크에 구애받지 않고 실행할 수 있습니다.

      ONNX는 딥러닝 모델을 표현하기 위한 오픈 스탠다드 포맷으로, 딥러닝 모델의 구조와 연산을 JSON 형식처럼 직관적으로 표현할 수 있습니다.


      ONNX 주요 장점

      • 그래프 연산 최적화

        ONNX는 모델의 그래프 연산을 최적화하여 실행 속도를 높이고 메모리 사용량을 줄입니다. 주요 최적화 기법은 다음과 같습니다.

        • 연산 병합(Operation Fusion)

          • 연속된 연산(예: <conv>, <batchnorm>, <relu>)을 하나의 연산으로 병합하여 처리합니다. 이를 통해 데이터 이동을 최소화하고 메모리 할당을 줄이며 캐시 효율을 높일 수 있습니다.

        • 상수 폴딩(Constant Folding)

          • 상수 값으로 결과가 고정되는 연산(예: add(5, 3))을 계산하여 상수로 대체합니다. 이는 불필요한 계산을 제거해 실행 속도를 높입니다.

        • 불필요한 노드 제거

          • 실제 출력에 기여하지 않는 노드를 제거하여 그래프를 간소화합니다.

        • 공통 하위 표현식 제거

          • 동일한 연산이 중복될 경우 중간 결과를 변수에 저장하여 재사용함으로써 효율성을 극대화합니다.

      • 저정밀 연산 지원

        • ONNX는 FP16(half precision)과 INT8(8-bit integer)와 같은 저정밀 연산을 지원합니다.

        • 기본값인 FP32에 비해 FP16은 메모리 사용량을 2배, INT8은 4배 줄일 수 있으며, 연산 속도 역시 더 빠릅니다.

        • 이는 대규모 모델을 배포할 때 특히 유용하며, GPU 및 CPU에서 효율적인 실행이 가능합니다.

      • 텐서 레이아웃 최적화

        • ONNX는 하드웨어에 최적화된 텐서 레이아웃을 사용하기 편리합니다.

        • GPU에서는 NCHW(batch_size, channel, height, width) 형식이 더 빠르고, CPU에서는 NHWC(batch_size, height, width, channel) 형식이 더 빠릅니다.

        • ONNX는 이러한 레이아웃 변환을 지원하여 다양한 하드웨어 환경에서 최적의 성능을 제공할 수 있습니다.

      • 다양한 하드웨어 가속기 지원

        • ONNX는 GPU, TPU, CPU 등 다양한 하드웨어 가속기에서 효율적으로 실행될 수 있도록 설계되었습니다.

        • 불필요한 연산을 제거하고 연산 순서를 최적화하여 실행 속도를 높이며, 온디바이스에서도 경량화된 추론이 가능합니다.

      • 하이브리드 방식의 모델 그래프

        • ONNX는 기본적으로 정적 그래프로 모델을 변환하지만, dynamic_axes 설정을 통해 동적 그래프의 유연성을 추가할 수 있습니다.

        • 이를 통해 정적 그래프의 최적화 장점과 동적 그래프의 유연성을 동시에 활용할 수 있으며, triton inference server 의 dynamic batching 기능과도 잘 결합됩니다.


      정적 그래프 vs 동적 그래프

      ONNX는 기본적으로 모델을 정적 그래프로 변환하도록 설계되었지만, dynamic_axes 설정으로 하이브리드 방식으로 사용할 수 있습니다.

      정적 그래프의 최적화 장점과 동적 그래프의 유연성을 동시에 활용 가능하며, triton inference server의 dynamic batching 을 사용하기도 용이합니다.

      특징

      정적 (ONNX, TensorFlow)

      동적 (PyTorch)

      그래프 정의 시점

      모델 정의 시점에 그래프 고정

      실행 시점에 매번 그래프 생성

      유연성

      고정되어 있어 유연성이 부족

      조건문, 반복문 사용 가능, 유연함

      디버깅

      디버깅 어려움

      디버깅 쉬움

      주요 활용 사례

      배포 및 추론(Inference)

      학습(Training)

      ONNX는 딥러닝 모델 교환 및 배포를 위한 강력한 표준 포맷으로서 다양한 프레임워크 간 호환성을 제공하며, 최적화된 추론 성능과 하드웨어 가속기 지원으로 AI 시스템의 효율성을 극대화 할 수 있습니다.


      ONNX 변환 소스 예시

      • (pytorch model 기준) 아래와 같이 input/output 특성과 동적으로 할당할 차원을 파라미터로 넣으면 간단하게 변환이 가능하며, 아래 케이스에서는 batch_size 및 sequence_length 차원에 대해 동적 차원을 설정하였습니다.

      torch.onnx.export(
      model=model,
      args=(features['input_ids'], features['attention_mask'], features['token_type_ids']),
      f=model_output,
      input_names=['input_ids', 'attention_mask', 'token_type_ids'],
      output_names=['last_hidden_state', 'pooler_output'],
      dynamic_axes={
      'input_ids': {0: 'batch_size', 1: 'sequence_length'},
      'attention_mask': {0: 'batch_size', 1: 'sequence_length'},
      'token_type_ids': {0: 'batch_size', 1: 'sequence_length'},
      'last_hidden_state': {0: 'batch_size', 1: 'sequence_length'},
      'pooler_output': {0: 'batch_size'},
      },
      opset_version=17,
      verbose=True
      )
      • model : 변환할 pyTorch 모델

      • args : 더미 입력 데이터 (입력 형상 정의)

      • f : 저장할 ONNX 파일 경로

      • input_names : ONNX 입력 노드 이름

      • output_names : ONNX 출력 노드 이름

      • dynamic_axes : 동적 차원 설정

      • opset_version : ONNX opset 버전 (최신 기능은 17 이상 권장)

      • verbose : 변환 과정의 상세 정보 출력 여부


      GPU Inference Server in Kubernetes

      시스템 개요

      시스템은 GPU 기반 인프라를 활용하여 대규모 추론 요청을 처리할 수 있도록 설계되었습니다.


      주요 특징은 다음과 같습니다.

      • triton inference server 를 기반으로 모델 배포 및 관리를 수행

      • kubernetes 클러스터 환경을 통해 확장성 및 가용성을 확보하고 GPU 클러스터를 구축하여 대규모 추론 요청을 효율적으로 처리하도록 설계

      • 모델을 다양한 프레임워크 포맷(ONNX, Python, TensorRT 등)으로 배포 가능

      • prometheus와 grafana를 활용한 모니터링 시스템 도입으로 실시간 상태 관리

      • S3를 통해 모델 저장소를 관리하며, triton inference server에서 이를 연동하여 배포

      구조도


      컴포넌트 구성

      주요 컴포넌트 구성은 다음과 같습니다.

      • triton inference server

        • requests/response handling:

          • HTTP/gRPC를 통하여 클라이언트 요청을 처리합니다.

        • scheduler:

          • dynamic batcher: 여러 요청을 자동으로 병합하여 처리 효율을 높일 수 있습니다.

          • sequence batcher: 입력 시퀀스를 최적화하여 효율적으로 시계열 데이터를 처리합니다.

        • framework backends:

          • ONNX, Python, TensorRT 등을 지원해 다양한 모델 포맷을 유연하게 사용 가능합니다.

        • model management:

          • 다양한 버전의 모델을 관리하며 필요에 따라 GPU/CPU 버전을 구분하여 최적의 리소스 활용이 가능합니다.

      • kubernetes 클러스터

        • GPU 노드를 포함한 다중 노드로 구성됩니다.

        • 같은 kubernetes 클러스터 안에서 triton inference server와 연동되어 클러스터 내 GPU 자원을 효율적으로 분배합니다.

      • S3

        • 모델 저장소는 S3를 활용하여 관리됩니다.

        • triton inference server는 컨테이너 이미지 실행 시 S3에 저장된 모델 저장소를 자동으로 참조하며, 이를 통해 모델 설정 변경이나 롤아웃이 가능합니다.

        • 이러한 구조는 모델 업데이트 및 배포 과정을 간소화하고 유연성을 제공합니다.

      • prometheus

        • GPU 노드 및 triton inference server에서 보내는 상태/헬스 메트릭을 수집하며, grafana, alertmanager와 연동하여 수집된 메트릭 데이터를 기반으로 실시간 모니터링과 알람 기능을 제공합니다.


      요청 처리 과정

      데이터 흐름 및 요청 처리 과정은 다음과 같습니다.

      데이터처리

      • 클라이언트 요청

        • HTTP 를 통해 클라이언트에서 추론 요청이 전송됩니다.

      • 요청/응답 처리

        • request/response handling가 클라이언트의 요청을 수신하고, 내부적으로 이를 스케줄러에 전달합니다.

      • 스케줄링

        • 요청을 받은 스케줄러는 dynamic batcher 를 통해 GPU 리소스를 최적화합니다.

      • 모델 추론

        • triton inference server는 다양한 포맷을 지원하지만 호환성과 사용 편의성 측면에서 뛰어난 ONNX 프레임워크 기반으로 요청을 처리합니다.

      • 결과 반환

        • ONNX 기반으로 처리된 결과는 request/response handling 레이어를 통해 클라이언트로 전송됩니다.

      • 메트릭 전송

        • triton inference server는 상태/헬스 메트릭을 HTTP로 prometheus에 전송합니다.

        • grafana를 통해 시각화하고, 사전 설정한 규칙에서 벗어나는 경우 alertmanager를 통해 이상 징후를 알립니다.


      모델 추가/교체 과정

      새로운 모델이 추가된 경우 변경 사항의 반영 및 배포가 필요합니다. 이러한 경우 kubernetes의 argo-workflow를 통해서 새로운 모델을 추가/교체하고 있습니다.

      처리 과정은 다음과 같습니다.

      모델교체

      • 모델 추가/교체 확인

        • 자체 모델의 경우 HDFS / 오픈소스 모델의 경우 huggingface 환경에서 추가/교체 대상 모델을 확인합니다.

      • 모델 다운로드

        • 추가/교체 대상 모델을 다운로드합니다.

      • ONNX 변환

        • input/output 특성과 동적으로 할당할 차원을 파라미터로 넣어 onnx 타입으로 모델을 변환합니다.

      • regression 테스트

        • 테스트를 통해 onnx 변환 이전 결과와 변환 이후의 결과를 비교합니다.

        • 테스트를 통해 기존 모델의 결과와 교체 모델의 결과를 비교합니다.

      • 모델 저장소 반영

        • regression 테스트를 통과한 모델에 대하여 모델 및 triton config 정보들을 모델 저장소에 업로드합니다.

      • 배포

        • rollout을 통해 추가/교체된 모델을 적용합니다.


      성능 테스트

      • 테스트 환경

        • 하드웨어: NVIDIA A40 GPU 1장

        • Pod 구성: Pod 1개, Instance 1개

        • Dynamic Batch: Batch 크기 4/8

        • 질의 토큰수: 입력 텍스트 길이 256 토큰

        • 메모리 사용량: A40 GPU 메모리 약 4GB 점유

        • 사용 모델: LaBSE (https://huggingface.co/sentence-transformers/LaBSE)

        • 처리량: 위 조건에서 Instance 1개에서 처리가능한 최대 처리량 (tps: 400, 동시 호출량: 50)으로 잡고 서비스 리소스를 산정

      동시 호출(concurrency)

      처리량 (Infer/sec)

      평균 latency (ms)

      p50 latency (ms)

      p90 latency (ms)

      p95 latency (ms)

      p99 latency (ms)

      tokenizer latency (ms)

      tokenizer Overhead (ms)

      tokenizer Queue (ms)

      ONNX  infer latency (ms)

      ONNX infer Overhead (ms)

      ONNX infer Queue (ms)

      Compute Input (ms)

      Compute Infer (ms)

      Compute Output (ms)

      1

      230.234

      4.339

      4.323

      4.359

      4.369

      4.434

      1.093

      0.001

      0.008

      3.184

      0.037

      0.009

      0.017

      3.103

      0.017

      2

      373.833

      5.345

      5.267

      5.601

      5.693

      5.858

      1.12

      0.001

      0.008

      4.167

      0.039

      0.01

      0.017

      4.081

      0.019

      3

      420.659

      7.127

      7.126

      8.267

      8.315

      8.4

      1.095

      0.001

      0.008

      5.964

      0.04

      1.229

      0.017

      4.656

      0.02

      4

      420.256

      9.513

      9.493

      9.605

      9.647

      9.765

      1.096

      0

      0.008

      8.346

      0.04

      3.605

      0.017

      4.663

      0.02

      5

      420.369

      11.888

      11.859

      13.675

      14.003

      14.281

      1.095

      0

      0.008

      10.723

      0.042

      5.984

      0.018

      4.658

      0.021

      6

      420.487

      14.264

      14.232

      14.354

      14.421

      15.419

      1.1

      0.001

      0.008

      13.095

      0.043

      8.358

      0.019

      4.654

      0.021

      7

      421.092

      16.616

      16.639

      18.464

      18.728

      18.866

      1.09

      0

      0.008

      15.45

      0.043

      10.721

      0.019

      4.645

      0.021

      8

      422.002

      18.948

      18.942

      19.069

      19.111

      19.366

      1.095

      0

      0.008

      17.778

      0.044

      13.059

      0.018

      4.635

      0.021

      9

      426.081

      21.108

      21.274

      23.178

      23.325

      23.499

      1.103

      0.001

      0.01

      19.937

      0.041

      15.261

      0.017

      4.598

      0.019

      10

      424.713

      23.538

      23.479

      23.721

      23.796

      25.292

      1.106

      0

      0.008

      22.35

      0.039

      17.66

      0.018

      4.612

      0.02

      11

      423.558

      25.96

      25.975

      27.692

      28.151

      28.547

      1.101

      0.001

      0.008

      24.779

      0.042

      20.077

      0.019

      4.619

      0.021

      12

      424.117

      28.287

      28.233

      28.512

      28.613

      30.209

      1.099

      0

      0.008

      27.108

      0.04

      22.41

      0.017

      4.62

      0.02

      13

      423.355

      30.697

      30.698

      32.355

      32.767

      33.357

      1.104

      0.001

      0.008

      29.517

      0.041

      24.812

      0.018

      4.625

      0.02

      14

      423.648

      33.037

      32.956

      33.282

      33.4

      35.619

      1.091

      0

      0.008

      31.865

      0.04

      27.164

      0.018

      4.622

      0.02

      15

      424.312

      35.342

      35.422

      37.136

      37.357

      38

      1.099

      0.001

      0.009

      34.162

      0.04

      29.468

      0.018

      4.616

      0.02

      16

      423.758

      37.754

      37.687

      38.071

      38.217

      39.654

      1.103

      0

      0.009

      36.57

      0.041

      31.87

      0.018

      4.619

      0.021

      50

      425.616

      117.086

      117.327

      118.124

      118.501

      120.576

      1.196

      0.001

      0.103

      115.765

      0.042

      111.088

      0.018

      4.595

      0.021

      100

      425.87

      233.229

      234.631

      236.509

      237.323

      243.906

      1.451

      0.002

      0.358

      231.586

      0.041

      226.913

      0.019

      4.591

      0.021

      150

      426.399

      348.274

      351.698

      354.248

      354.936

      356.948

      1.997

      0

      0.915

      345.888

      0.042

      341.221

      0.018

      4.586

      0.02

      200

      426.219

      462.872

      469.022

      471.342

      471.926

      474.031

      2.616

      0.001

      1.521

      459.967

      0.044

      455.304

      0.02

      4.577

      0.021


      배포

      • Anti-Affinity 설정

        • 아래와 같이 설정하여 파드들이 가능한 서로 다른 노드에 배포되도록 설정했습니다.

        • preferredDuringSchedulingIgnoredDuringExecution 설정으로 조건을 만족하는 노드가 있으면 해당 노드에 스케줄링되지만, 조건을 만족하지 않아도 다른 노드에 스케줄링 되는 방식으로 적용하였습니다.

      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - podAffinityTerm:
            labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - triton-inference-server
            topologyKey: kubernetes.io/hostname
          weight: 1
      • 전용 노드 할당

        • nodeSelector와 tolerations를 사용하여 GPU 서빙 전용 노드에 파드를 배치하도록 제한했습니다.

        • 이를 통해 다른 용도의 컨테이너가 GPU 리소스를 선점하지 않도록 보장했습니다.

      nodeSelector: 
        aisearch.sktelecom.com/gpu-serving: "true"
      
      tolerations:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
          operator: Equal
      • 상태 확인

        • readinessProbe를 사용하여 파드가 트래픽을 받을 준비가 되었는지 확인합니다.

      readinessProbe:
        failureThreshold: 3
        httpGet:
          path: /v2/health/ready
          port: 8000
          scheme: HTTP
        initialDelaySeconds: 5
        periodSeconds: 1
        successThreshold: 1
        timeoutSeconds: 1
      • graceful shutdown

        • minReadySeconds와 terminationGracePeriodSeconds를 설정하여 안전한 종료 프로세스를 보장합니다.

      minReadySeconds: 10
      terminationGracePeriodSeconds: 60
      • 컨테이너 리소스 할당

        • GPU: 아래와 같은 이유로 Pod(ReplicaSet) 별 1장씩 할당하였습니다.

          • 장애 격리: 단일 GPU에 문제가 발생해도 다른 Replica의 생성에 영향을 미치지 않습니다.

          • 리소스 보장: 각 Replica가 전용 GPU를 사용함으로써 성능 간섭을 최소화하고 일관된 추론 성능을 제공합니다.

          • 확장성: GPU 별로 독립적인 모델 인스턴스를 실행할 수 있어, 워크로드에 따라 유연하게 확장이 가능합니다.

          • 고가용성: 하나의 GPU나 노드에 장애가 발생해도 다른 레플리카들이 계속 서비스를 제공할 수 있어 전체 시스템의 가용성이 향상됩니다.

        • CPU: Throttling으로 인한 지연을 방지하고자 CPU 리소스 limit은 설정하지 않았습니다.

      resources:
        limits:
          memory: 64Gi
          nvidia.com/gpu: "1"
        requests:
          cpu: "8"
          memory: 64Gi


      장애 복구 전략 및 모니터링

      고가용성과 안정성을 보장하기 위한 장애 복구 전략을 고려하고 있습니다.

      • kubernetes 기반 자동 복구

        • kubernetes의 ReplicaSet, Deployment을 활용하여 장애 복구를 자동화하고 있으며,

          GPU 노드에 장애가 발생하더라도 다른 GPU 노드에서 트래픽을 수용할 수 있도록 설계되어 서비스 중단없이 복구가 가능합니다.

      • prometheus 기반 모니터링 및 알람

        • prometheus를 활용하여 GPU 사용률, 응답 지연 시간, 요청 수 등 다양한 지표를 실시간으로 모니터링합니다.

        • alertmanager와 연동하여 이상 징후를 사전에 감지하고 즉각적인 알람을 전송함으로써 장애 대응 시간을 단축할 수 있습니다.

      모니터링은 메트릭 기반으로 구성하였으며, prometheus에서 수집하고 있는 메트릭이 특정 조건에 해당하는 경우 alertmanager를 통해 알람이 전송되는 구조입니다.


      triton inference server와 GPU 관련하여 수집하고 있는 주요 메트릭은 다음과 같습니다.

      • triton inference server

        • 초당 요청 성공/실패

        • 평균 요청 시간

        • 평균 배치 크기

        • 평균 큐 대기 시간

      • triton inference server 메트릭 관련 대시보드 예시

        • .

      • triton inference server 메트릭 관련 알람 예시

        • ..

      • GPU 노드

        • 온도

        • 메모리 사용량

        • GPU 사용률

        • 전력 소비량

      • GPU 메트릭 관련 대시보드 예시

        • ...

      • GPU 메트릭 관련 알람 예시

        • ....


      맺으며

      본 글에서는 kubernetes 환경에서 NVIDIA triton inference server와 ONNX 변환을 활용하여 GPU 기반 추론 서버를 구축하는 방법을 살펴보았습니다.

      시맨틱 검색은 단순한 키워드 매칭을 넘어 문맥과 의미를 이해하는 검색 방식으로, 사용자 경험을 크게 향상시킬 수 있습니다.

      이러한 시맨틱 검색을 효율적으로 구현하기 위해서는 복잡한 딥러닝 모델의 실시간 추론이 필요하며, 이는 GPU와 같은 고성능 하드웨어와 최적화된 소프트웨어 스택이 필요합니다.


      검색 품질을 높이기 위해 시맨틱 검색과 같은 AI 기술을 도입하는 과정에서, 한 가지 중요한 과제는 GPU 리소스를 얼마나 효율적으로 활용할 수 있는지 였습니다.

      이를 위해 다양한 딥러닝 프레임워크를 지원하고, dynamic batching과 multi-instance와 같은 최적화 기법을 통해 GPU 리소스를 최대한 사용할 수 있게 도와주는 NVIDIA triton inference server를 구축하였고,

      여기에 모델의 그래프 연산을 최적화하고 다양한 하드웨어에서 효율적으로 실행될 수 있도록 ONNX 변환 모듈을 추가하였습니다.

      Kubernetes 환경에서 이러한 기술들을 통합한 결과, 확장성/안정성/효율성을 모두 갖춘 시스템을 구축할 수 있었으며, 모델 배포와 교체, 모니터링 및 알람 설정 등이 자동화되어 운영의 복잡성 또한 크게 줄어들었습니다. 

      실제 성능 테스트 결과, A40 GPU 카드 한 장 만으로도 낮은 지연 시간과 높은 처리량으로 기대 이상의 성능을 달성할 수 있었습니다.


      향후 시맨틱 검색을 다양한 검색 분야에 적용하고, 이를 넘어 멀티모달 검색, 질의 분석, 문서 요약 등 다양한 검색과 관련된 기반기술에도 위 시스템을 적용할 예정이며, 

      나아가 더 다양한 AI 모델들을 서빙하고, 멀티 GPU 환경에서의 최적화, 분산 추론 등으로 확장해 나가려고 합니다.


      긴 글 읽어주셔서 감사합니다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      sjlee 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기