Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (seongtaejeong at gmail.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)
(시리즈 글이 2개 있습니다.)
Linux: 21. 리눅스에서 공유 라이브러리가 로드되지 않는다면?
; https://www.sysnet.pe.kr/2/0/11973

오류 유형: 957. NVIDIA Triton Inference Server - version `GLIBCXX_3.4.32' not found (required by /opt/tritonserver/backends/python/triton_python_backend_stub)
; https://www.sysnet.pe.kr/2/0/13939




NVIDIA Triton Inference Server - version `GLIBCXX_3.4.32' not found (required by /opt/tritonserver/backends/python/triton_python_backend_stub)

triton 서버에 파이썬 백엔드를 사용하는 경우, 이런 오류가 나온다면?

I0523 04:29:23.975315 1 stub_launcher.cc:385] "Starting Python backend stub: source /tmp/python_env_UM09Ut/0/bin/activate && exec env LD_LIBRARY_PATH=/tmp/python_env_UM09Ut/0/lib:$LD_LIBRARY_PATH /opt/tritonserver/backends/python/triton_python_backend_stub /model_dir/preprocessing/1/model.py triton_python_backend_shm_region_afffbc98-a153-4285-9cd5-7a0746a084a4 1048576 1048576 1 /opt/tritonserver/backends/python 336 preprocessing DEFAULT"
/opt/tritonserver/backends/python/triton_python_backend_stub: /tmp/python_env_UM09Ut/0/lib/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by /opt/tritonserver/backends/python/triton_python_backend_stub)
/opt/tritonserver/backends/python/triton_python_backend_stub: /tmp/python_env_UM09Ut/0/lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /opt/tritonserver/backends/python/triton_python_backend_stub)


예전 경험도 있고 하니,

리눅스에서 공유 라이브러리가 로드되지 않는다면?
; https://www.sysnet.pe.kr/2/0/11973

이번엔 제 스스로 원인 분석이 될 듯도 합니다. ^^ 우선, 저 상황에서 로그에 나온 "/tmp/python_env_UM09Ut/0/lib/libstdc++.so.6" 파일을 보면,

# ls /tmp/python_env_UM09Ut/0/lib/libstdc++.so -l 
lrwxrwxrwx 1 root root 19 May 23 01:35 /tmp/python_env_UM09Ut/0/lib/libstdc++.so -> libstdc++.so.6.0.29

저렇게 29 버전으로 연결돼 있고 따라서 "GLIBCXX_3.4.29" 버전의 so 파일이 존재하는 상황입니다. 하지만, 실행 주체인 (역시 로그에서 확인할 수 있는) /opt/tritonserver/backends/python/triton_python_backend_stub은 6.0.32 버전 이후로 갖는 함수를 사용하고 있어,

# strings /opt/tritonserver/backends/python/triton_python_backend_stub | grep GLIBCXX_3.4.32
GLIBCXX_3.4.32
_ZSt21ios_base_library_initv@GLIBCXX_3.4.32

실행이 안 되는 것입니다. 아니, 그런데 왜? triton 파이썬 백엔드가 요구하는 3.4.32가 아닌 3.4.29 버전의 so 파일을 로딩하려는 것일까요? 이유를 찾기 위해 오류 메시지가 발생한 시점의 로그를 살펴보면, 다음과 같은 선행 메시지가 보입니다.

I0523 04:29:23.974814 1 pb_env.cc:292] "Extracting Python execution env /model_dir/postprocessing/post_env.tar.gz"

그러니까, 아마도 conda가 6.0.29 버전의 libstdc++.so.6 파일을 패키징 처리한 것 같은데요, 실제로 post_env.tar.gz 압축을 풀어 보면, /lib 디렉터리에 libstdc++.so.6.0.29 파일이 존재합니다. 결국 conda 가상 환경 구성 자체에 이미 6.0.29 버전이 위치하고 있었던 것입니다.

// conda 가상 환경의 이름이 "test_env"라고 가정

$ ls ~/miniconda3/envs/test_env/lib/libstdc++.so
libstdc++.so         libstdc++.so.6       libstdc++.so.6.0.29

그리고 그 경로의 라이브러리를 사용하라고 triton_python_backend_stub 실행 시 LD_LIBRARY_PATH 환경 변수를 통해 전달하는 것을 로그에서 확인할 수 있습니다.

I0528 07:03:35.351471 1 stub_launcher.cc:385] "Starting Python backend stub: source /model_dir/preprocessing/python_env/bin/activate && exec env LD_LIBRARY_PATH=/model_dir/preprocessing/python_env/lib:$LD_LIBRARY_PATH /opt/tritonserver/backends/python/triton_python_backend_stub /model_dir/preprocessing/1/model.py triton_python_backend_shm_region_b0fc2220-a884-4074-b0e9-50111be4a834 1048576 1048576 1 /opt/tritonserver/backends/python 336 preprocessing DEFAULT"

자, 그럼 저걸 업데이트해야 하는데요, 이에 대해 검색해 보면,

Add a note on the GLIBCXX_3.4.30 not found issue when using custom ex… #280
; https://github.com/triton-inference-server/python_backend/pull/280/commits/2a41ca9f3fff80fb40ecfd103f14e88c214e4c9a

conda 환경에 conda-forge 채널로부터 libstdcxx-ng의 버전을 명시해 설치하는 내용이 나옵니다.

conda install -c conda-forge libstdcxx-ng=12 -y

실제로 12로 지정하면 6.0.30 버전으로 덮어써지는데요,

$ ls ~/miniconda3/envs/test_env/lib/libstdc++.so -l
lrwxrwxrwx 1 testusr testusr 19 May 23 14:58 /home/testusr/miniconda3/envs/test_env/lib/libstdc++.so -> libstdc++.so.6.0.30

해보니까, 13으로 지정해야 6.0.32 버전이 나옵니다.

$ conda install -c conda-forge libstdcxx-ng=13 -y

$ ls ~/miniconda3/envs/test_env/lib/libstdc++.so -l
lrwxrwxrwx 1 testusr testusr 19 May 23 15:02 /home/testusr/miniconda3/envs/test_env/lib/libstdc++.so -> libstdc++.so.6.0.32




참고로, 파이썬 백엔드는 docker 컨테이너의 경우 "/opt/tritonserver/backends/python/triton_python_backend_stub" 경로에 있으므로, 다음과 같이 의존성을 확인할 수도 있습니다.

# ldd /opt/tritonserver/backends/python/triton_python_backend_stub
        linux-vdso.so.1 (0x00007ffeac5c4000)
        libcudart.so.12 => /usr/local/cuda/targets/x86_64-linux/lib/libcudart.so.12 (0x00007f91bc800000)
        libpython3.12.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.12.so.1.0 (0x00007f91bbf59000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f91bbcdb000)
        libgcc_s.so.1 => /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f91bcbb2000)
        libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007f91bbac9000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f91bccfa000)
        libdl.so.2 => /usr/lib/x86_64-linux-gnu/libdl.so.2 (0x00007f91bcbab000)
        libpthread.so.0 => /usr/lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f91bcba6000)
        librt.so.1 => /usr/lib/x86_64-linux-gnu/librt.so.1 (0x00007f91bcba1000)
        libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007f91bcab8000)
        libz.so.1 => /usr/lib/x86_64-linux-gnu/libz.so.1 (0x00007f91bbaad000)
        libexpat.so.1 => /usr/lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f91bba81000)

# ls /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -l
lrwxrwxrwx 1 root root 19 Sep  9  2024 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -> libstdc++.so.6.0.33

위와 같은 경우 6.0.33 버전에 의존성이 있으므로 14 버전으로 구성해야 합니다.

$ conda install -c conda-forge libstdcxx-ng=14 -y




혹은 이런 오류 메시지가 발생한다면?

I0527 05:01:23.630588 1 pb_env.cc:292] "Extracting Python execution env /model_dir/preprocessing/pre_env.tar.gz"
I0527 05:01:23.631184 1 stub_launcher.cc:385] "Starting Python backend stub: source /tmp/python_env_WtprbR/0/bin/activate && exec env LD_LIBRARY_PATH=/tmp/python_env_WtprbR/0/lib:$LD_LIBRARY_PATH /opt/tritonserver/backends/python/triton_python_backend_stub /model_dir/postprocessing/1/model.py triton_python_backend_shm_region_c30a0918-191c-49c9-bc42-da9567c6e646 1048576 1048576 1 /opt/tritonserver/backends/python 336 postprocessing DEFAULT"
I0527 05:01:27.312170 143 pb_stub.cc:320]  Failed to initialize Python stub for auto-complete: ImportError: libGL.so.1: cannot open shared object file: No such file or directory

At:
  /tmp/python_env_WtprbR/0/lib/python3.12/importlib/__init__.py(90): import_module
  /tmp/python_env_WtprbR/0/lib/python3.12/site-packages/cv2/__init__.py(153): bootstrap
  /tmp/python_env_WtprbR/0/lib/python3.12/site-packages/cv2/__init__.py(181): <module>
  <frozen importlib._bootstrap>(488): _call_with_frames_removed
  <frozen importlib._bootstrap_external>(999): exec_module
  <frozen importlib._bootstrap>(950): _load_unlocked
  <frozen importlib._bootstrap>(1333): _find_and_load_unlocked
  <frozen importlib._bootstrap>(1360): _find_and_load
  /model_dir/postprocessing/1/model.py(5): <module>
  <frozen importlib._bootstrap>(488): _call_with_frames_removed
  <frozen importlib._bootstrap_external>(999): exec_module
  <frozen importlib._bootstrap>(950): _load_unlocked
  <frozen importlib._bootstrap>(1334): _find_and_load_unlocked
  <frozen importlib._bootstrap>(1360): _find_and_load

I0527 05:01:27.575096 1 python_be.cc:2266] "TRITONBACKEND_ModelFinalize: delete model state"
E0527 05:01:27.575174 1 model_lifecycle.cc:654] "failed to load 'postprocessing' version 1: Internal: ImportError: libGL.so.1: cannot open shared object file: No such file or directory\n\nAt:\n  /tmp/python_env_WtprbR/0/lib/python3.12/importlib/__init__.py(90): import_module\n  /tmp/python_env_WtprbR/0/lib/python3.12/site-packages/cv2/__init__.py(153): bootstrap\n  /tmp/python_env_WtprbR/0/lib/python3.12/site-packages/cv2/__init__.py(181): <module>\n  <frozen importlib._bootstrap>(488): _call_with_frames_removed\n  <frozen importlib._bootstrap_external>(999): exec_module\n  <frozen importlib._bootstrap>(950): _load_unlocked\n  <frozen importlib._bootstrap>(1333): _find_and_load_unlocked\n  <frozen importlib._bootstrap>(1360): _find_and_load\n  /model_dir/postprocessing/1/model.py(5): <module>\n  <frozen importlib._bootstrap>(488): _call_with_frames_removed\n  <frozen importlib._bootstrap_external>(999): exec_module\n  <frozen importlib._bootstrap>(950): _load_unlocked\n  <frozen importlib._bootstrap>(1334): _find_and_load_unlocked\n  <frozen importlib._bootstrap>(1360): _find_and_load\n"
I0527 05:01:27.575246 1 model_lifecycle.cc:789] "failed to load 'postprocessing'"

libGL.so 파일의 로딩에 실패한 것인데요, 그런 경우라면 dockerfile에 미리 설치해 두는 식으로 해결할 수 있습니다.

FROM nvcr.io/nvidia/tritonserver:25.04-py3

RUN apt-get update && apt-get install libgl1 -y

SHELL ["/bin/bash", "-c"]
WORKDIR /home/ubuntu




비록 동작은 하지만 다음과 같은 경고가 거슬린다면?

I0527 05:11:05.790675 1 stub_launcher.cc:385] "Starting Python backend stub: source /tmp/python_env_PP7fff/0/bin/activate && exec env LD_LIBRARY_PATH=/tmp/python_env_PP7fff/0/lib:$LD_LIBRARY_PATH /opt/tritonserver/backends/python/triton_python_backend_stub /model_dir/preprocessing/1/model.py triton_python_backend_shm_region_970603fa-20f8-4bb4-a4ed-cbead6cf17ae 1048576 1048576 1 /opt/tritonserver/backends/python 336 preprocessing DEFAULT"
/tmp/python_env_PP7fff/0/lib/python3.12/site-packages/albumentations/check_version.py:147: UserWarning: Error fetching version info <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1010)>
  data = fetch_version_info()

아래의 글에 힌트가 나오는데요,

SSL: CERTIFICATE_VERIFY_FAILED certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)')))
; https://stackoverflow.com/questions/77442172/ssl-certificate-verify-failed-certificate-verify-failed-unable-to-get-local-is

SSL_CERT_DIR 환경 변수를 설정하는 것으로 해결할 수 있습니다.

export SSL_CERT_DIR=/etc/ssl/certs/

triton 컨테이너를 구동하는 경우에는 -e 옵션으로 전달해도 됩니다.

docker run --gpus='"device=0"' -it --rm --shm-size=8g -e SSL_CERT_DIR=/etc/ssl/certs/ ...[생략]...




마지막으로 문서에 보면,

Creating Custom Execution Environments
; https://github.com/triton-inference-server/python_backend?tab=readme-ov-file#creating-custom-execution-environments

conda 가상 환경을 pack/unpack한 것뿐만 아니라 애당초 conda create -p 옵션으로 디렉터리를 지정해 만든 가상 환경도 지원한다고 나옵니다. 그런데, 실제로 그런 식으로 구성한 후,

$ export PYTHONNOUSERSITE=True

$ conda create -p /home/testusr/test/triton_server_example/triton/preprocessing/python_env python=3.12 -y
$ conda activate /home/testusr/test/triton_server_example/triton/preprocessing/python_env

$ conda install -c conda-forge libstdcxx-ng=14 -y
$ conda install pip -y
$ conda install conda-pack -y
$ pip install -r pre_requirements.txt

$ conda deactivate

$ conda create -p /home/testusr/test/triton_server_example/triton/postprocessing/python_env python=3.12 -y
$ conda activate /home/testusr/test/triton_server_example/triton/postprocessing/python_env

$ conda install -c conda-forge libstdcxx-ng=14 -y
$ conda install pip -y
$ conda install conda-pack -y
$ pip install -r post_requirements.txt

$ conda deactivate

config.pbtxt 파일의 경로도 맞춰주고,

parameters: {
    key: "EXECUTION_ENV_PATH", 
    value: {string_value: "$$TRITON_MODEL_DIRECTORY/python_env"}
}

실행해 보면 이런 오류가 발생합니다.

...[생략]...
I0528 07:26:05.285089 1 python_be.cc:1849] "Using Python execution env /model_dir/postprocessing/python_env"
I0528 07:26:05.285850 1 pb_env.cc:267] "Returning canonical path since EXECUTION_ENV_PATH does not contain compressed path. Path: /model_dir/postprocessing/python_env"
I0528 07:26:05.285923 1 python_be.cc:2266] "TRITONBACKEND_ModelFinalize: delete model state"
E0528 07:26:05.285951 1 model_lifecycle.cc:654] "failed to load 'postprocessing' version 1: Internal: Path /model_dir/postprocessing/python_env/bin/activate does not exist. The Python environment should contain an 'activate' script."
I0528 07:26:05.285967 1 model_lifecycle.cc:789] "failed to load 'postprocessing'"
...[생략]...

물론, conda unpack으로 한 경우에는 저 경로에 activate 스크립트가 존재하는데요,

# cat /model_dir/postprocessing/python_env/bin/activate
_conda_pack_activate() {
    local _CONDA_SHELL_FLAVOR
    if [ -n "${BASH_VERSION:+x}" ]; then
        _CONDA_SHELL_FLAVOR=bash
    elif [ -n "${ZSH_VERSION:+x}" ]; then
        _CONDA_SHELL_FLAVOR=zsh
    elif [ -n "${KSH_VERSION:+x}" ]; then
        _CONDA_SHELL_FLAVOR=ksh
    elif [ -n "${POSH_VERSION:+x}" ]; then
        _CONDA_SHELL_FLAVOR=posh
    else
        # https://unix.stackexchange.com/a/120138/92065
        local _q="$(ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1)"
        if [ "$_q" = dash ]; then
            _CONDA_SHELL_FLAVOR=dash
        else
            (>&2 echo "Unrecognized shell.")
            return 1
        fi
    fi

    # https://unix.stackexchange.com/questions/4650/determining-path-to-sourced-shell-script/
    local script_dir
    case "$_CONDA_SHELL_FLAVOR" in
        bash) script_dir="$(dirname "${BASH_SOURCE[0]}")";;
        zsh) script_dir="$(dirname "${(%):-%x}")";;  # http://stackoverflow.com/a/28336473/2127762
        dash) x=$(lsof -p $$ -Fn0 | tail -1); script_dir="$(dirname "${x#*n}")";;
        *) script_dir="$(cd "$(dirname "$_")" && echo "$PWD")";;
    esac

    local full_path_script_dir="$(cd "${script_dir}" > /dev/null && pwd)"
    local full_path_env="$(dirname "$full_path_script_dir")"
    local env_name="$(basename "$full_path_env")"

    # If there's already a source env
    if [ -n "$CONDA_PREFIX" ]; then
        # If the source env differs from this env
        if [ "$CONDA_PREFIX" != "$full_path_env" ]; then
            # Check whether deactivate is a function or executable
            type deactivate >/dev/null 2>/dev/null
            if [ $? -eq 0 ]; then
                . deactivate >/dev/null 2>/dev/null
            fi
        else
            return 0  # nothing to do
        fi
    fi
    export CONDA_PREFIX="$full_path_env"
    export _CONDA_PACK_OLD_PS1="$PS1"
    PATH="$full_path_env/bin:$PATH"
    PS1="($env_name) $PS1"

    case "$_CONDA_SHELL_FLAVOR" in
        zsh) rehash;;
        posh) ;;
        *) hash -r;;
    esac

    # Run the activate scripts
    local _script_dir="${full_path_env}/etc/conda/activate.d"
    if [ -d "$_script_dir" ] && [ -n "$(ls -A "$_script_dir")" ]; then
        local _path
        for _path in "$_script_dir"/*.sh; do
            . "$_path"
        done
    fi
}

_conda_pack_activate

딱히 어떤 식으로 더 맞춰줘야 하는 것인지 잘 모르겠습니다. 이에 대해 혹시 아시는 분은 덧글 부탁드립니다. ^^





[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 5/30/2025]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 106  107  108  109  110  111  112  113  114  115  116  117  118  119  [120]  ...
NoWriterDateCnt.TitleFile(s)
10947정성태4/27/201622790.NET Framework: 573. .NET CLR4 보안 모델 - 4. CLR4 보안 모델에서의 조건부 APTCA 역할파일 다운로드1
10946정성태4/26/201625587VS.NET IDE: 106. Visual Studio 2015 확장 - INI 파일을 위한 사용자 정의 포맷 기능 (Syntax Highlighting)파일 다운로드1
10945정성태4/26/201618654오류 유형: 327. VSIX 프로젝트 빌드 시 The "VsTemplatePaths" task could not be loaded from the assembly 오류 발생
10944정성태4/22/201620384디버깅 기술: 80. windbg - 풀 덤프 파일로부터 텍스트 파일의 내용을 찾는 방법
10943정성태4/22/201625290디버깅 기술: 79. windbg - 풀 덤프 파일로부터 .NET DLL을 추출/저장하는 방법 [1]
10942정성태4/19/201620655디버깅 기술: 78. windbg 사례 - .NET 예외가 발생한 시점의 오류 분석 [1]
10941정성태4/19/201620266오류 유형: 326. Error MSB8020 - The build tools for v120_xp (Platform Toolset = 'v120_xp') cannot be found.
10940정성태4/18/201623868Windows: 116. 프로세스 풀 덤프 시간을 줄여 주는 Process Reflection [3]
10939정성태4/18/201624897.NET Framework: 572. .NET APM 비동기 호출의 Begin...과 End... 조합 [3]파일 다운로드1
10938정성태4/13/201623858오류 유형: 325. 파일 삭제 시 오류 - Error 0x80070091: The directory is not empty.
10937정성태4/13/201632571Windows: 115. UEFI 모드로 윈도우 10 설치 가능한 USB 디스크 만드는 방법
10936정성태4/8/201643571Windows: 114. 삼성 센스 크로노스 7 노트북의 운영체제를 USB 디스크로 새로 설치하는 방법 [3]
10935정성태4/7/201628025웹: 32. Edge에서 Google Docs 문서 편집 시 한영 전환키가 동작 안하는 문제
10934정성태4/5/201626044디버깅 기술: 77. windbg의 콜스택 함수 인자를 쉽게 확인하는 방법 [1]
10933정성태4/5/201631533.NET Framework: 571. C# - 스레드 선호도(Thread Affinity) 지정하는 방법 [8]파일 다운로드1
10932정성태4/4/201624045VC++: 96. C/C++ 식 평가 - printf("%d %d %d\n", a, a++, a);
10931정성태3/31/201624415개발 환경 구성: 283. Hyper-V 내에 구성한 Active Directory 환경의 시간 구성 방법 [3]
10930정성태3/30/201622368.NET Framework: 570. .NET 4.5부터 추가된 CLR Profiler의 실행 시 Rejit 기능
10929정성태3/29/201632774.NET Framework: 569. ServicePointManager.DefaultConnectionLimit의 역할파일 다운로드1
10928정성태3/28/201638468.NET Framework: 568. ODP.NET의 완전한 닷넷 버전 Oracle ODP.NET, Managed Driver [2]파일 다운로드1
10927정성태3/25/201627047.NET Framework: 567. System.Net.ServicePointManager의 DefaultConnectionLimit 속성 설명
10926정성태3/24/201627222.NET Framework: 566. openssl의 PKCS#1 PEM 개인키 파일을 .NET RSACryptoServiceProvider에서 사용하는 방법 [10]파일 다운로드1
10925정성태3/24/201620902.NET Framework: 565. C# - Rabin-Miller 소수 생성 방법을 이용하여 RSACryptoServiceProvider의 개인키를 직접 채워보자 - 두 번째 이야기파일 다운로드1
10924정성태3/22/201622107오류 유형: 324. Visual Studio에서 Azure 클라우드 서비스 생성 시 Failed to initialize the PowerShell host 에러 발생
10923정성태3/21/201622645.NET Framework: 564. C# - DGML로 바이너리 트리 출력하는 방법 [1]파일 다운로드1
10922정성태3/21/201623638.NET Framework: 563. 디버깅 용도로 이진 트리의 내용을 출력하는 방법파일 다운로드1
... 106  107  108  109  110  111  112  113  114  115  116  117  118  119  [120]  ...