computer science

Triton server memory leak (메모리 릭) malloc설정을 바꿔보자

CoreTree 2024. 5. 13. 14:00
반응형

- 결론부터 말하자면 Triton inference api server 를 사용할때 docker image의 malloc을 지정하는 환경변수를 바꿔서 테스트해보는것을 추천한다. 자세한 방법과 내용은 글 하단에 작성해두었다.

 

반응형

 

 

일단 필자가 사용하는 서버에서 주로 메모리가 급증했던 구간은 python으로 preprocess하는 custom api 구간이었다. image를 byte array 형태로 직접 받도록 구성해두었다보니 요청량이 많아져 queue가 쌓이면 이미지를 메모리상에 두게되어 메모리 점유율이 급상승하는 형태를 띈다.

 

 

문제는 요청 이후 api측은 idel상태인데 메모리중 일부가 릴리즈되지 않는 경향을 보이는것이다. 

 

 

처음에는 python에서 garbage collecter가 동작해서 해결될거라 기대했지만 이상황이 반복되자 리소스 부족으로 한번 터졌다.

 

 

방법을 찾아보니 triton release note에 쓰여있는 내용을 발견했는데 내용은 이렇다.

 

 

 

malloc을 tcmalloc 또는 jemalloc으로 바꿔서 해당 현상을 해결할 수 있다는 이야기다. 어떤 값으로 되어있는지 확인해보자.

(Nvidia에서 제공하는 container에 직접 접근하여 실행하자. 컨테이너 내의 malloc관련 실제 경로를 찾아야한다.)

 

1. LD_PRELOAD 환경 변수 확인
시스템이나 특정 애플리케이션에서 LD_PRELOAD 환경 변수를 통해 다른 메모리 할당기(예: tcmalloc, jemalloc)를 로드하도록 설정했을 수 있다. 이 설정을 확인하려면 다음 명령을 사용해보자

echo $LD_PRELOAD


이 명령은 현재 셸 세션에서 LD_PRELOAD 환경 변수에 설정된 값을 출력한다. 시스템 전체적으로 설정된 값이 있을 수도 있는데, 이는 시스템의 부팅 스크립트나 서비스 설정 파일에서 찾아볼 수 있다.

2. 시스템 라이브러리와 프로세스 분석
현재 실행 중인 프로세스가 어떤 메모리 할당기를 사용하고 있는지 확인하려면, 해당 프로세스의 메모리 맵을 검사할 수 있다.

cat /proc/[pid]/maps


여기서 [pid]는 프로세스 ID입니다. 이 파일에는 프로세스가 사용 중인 모든 메모리 세그먼트와 해당 세그먼트를 구성하는 라이브러리의 경로가 포함되어 있습니다. libjemalloc.so나 libtcmalloc.so와 같은 항목을 찾으면 해당 메모리 할당기를 사용 중인 것이다.

 

[중요] 시스템 라이브러리 확인
시스템에 설치된 메모리 할당기 라이브러리를 확인하려면 다음과 같은 명령어를 사용할 수 있다.

ldconfig -p | grep -E 'libjemalloc.so|libtcmalloc.so'


이 명령은 시스템의 동적 링커 구성에서 jemalloc이나 tcmalloc 라이브러리를 검색한다.

기본 malloc 구현을 확인하는 것은 시스템 설정과 실행 중인 애플리케이션의 구성에 따라 달라질 수 있다. LD_PRELOAD와 같은 환경 설정, 프로세스 메모리 맵, 또는 시스템 라이브러리 목록을 검토하여 현재 활성화된 메모리 할당기에 대한 힌트를 얻을 수 있다.

여기서 얻은 경로를 아래의 코드에 적용해서 수행할 수 있다.

 

 

반응형

 

 

malloc 세팅 교체 방법

일단 triton docker container가 실행되는 시점에 malloc세팅과 관련된 `LD_PRELOAD` 환경변수를 바꿔야 한다.

## 아래 둘 중 하나를 사용할것 ##

# jemalloc 사용시
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so

# tcmalloc 사용시
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libtcmalloc.so

 

주의사항 : triton inference server docker에는 위의 lib이 모두 들어있다고 설명되어있다. 다만 경로는 필자가 제공한것과 다를수 있다.  방법으로 해당 경로를 찾고 값을 적용해야한다. 앞에서 언급한 " ldconfig -p | grep -E 'libjemalloc.so|libtcmalloc.so' " 명령어로 먼저 경로를 찾고 적용하자.

 

 

malloc 변경사항을 docker container에 설정하기

- docker run으로 직접 실행하는 경우 옵션을 넣어서 실행해보기

-e LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so 값을 실행문에 추가하면 된다. 이전에 이야기했듯이 컨테이너 내의 malloc관련 실제 경로를 먼저 찾고 값을 맞게 사용하자.

docker run <your options> -e LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so <your_docker_image>

 

 

- image build시 ENV를 직접 수정해서 빌드 이미지에 적용하기

Dockerfile를 통해 base image를 nvidia의 triton 전용 이미지로 build하고 있다면, Dockerfile에 직접 ENV를 주입해주는것도 좋겠다.

FROM ... as ...

## jemalloc 적용시
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so

## tcmalloc 적용시
# ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libtcmalloc.so


ENTRYPOINT ...

CMD ...

 

 

적용결과

필자는 malloc 세팅을 바꿔 실행하니 실제로 초기 구동시의 메모리 점유율부터가 달라졌으며 실제로 누수로 보여지는 현상이 어느정도 잡히는것을 확인했다.

 

몇번 더 테스트해본 결과 초기 메모리 점유율이 낮게 나온 malloc 세팅을 하는것이 결론적으로 도움이 되는것을 확인했다.

 

(필자는 jemalloc으로 세팅을 변경했을때 메모리 누수 현상이 잡히는것을 확인하였으나 jemalloc으로 바꾸는것이 정답은 아니다. 환경마다 tcmalloc이나 기본값이 맞을수도 있다고 하니 직접 세팅을 바꿔가며 메모리 값을 측정해봐야 하겠다)

 

 

반응형

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형