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

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  128  129  130  131  132  [133]  134  135  ...
NoWriterDateCnt.TitleFile(s)
1753정성태9/22/201421366오류 유형: 240. Lync로 세미나 참여 시 소리만 들리지 않는 경우 [1]
1752정성태9/21/201441609Windows: 100. 윈도우 8 - RDP 연결을 이용해 VNC처럼 사용자 로그온 화면을 공유하는 방법 [5]
1751정성태9/20/201439683.NET Framework: 464. 프로세스 간 통신 시 소켓 필요 없이 간단하게 Pipe를 열어 통신하는 방법 [1]파일 다운로드1
1750정성태9/20/201424678.NET Framework: 463. PInvoke 호출을 이용한 비동기 파일 작업파일 다운로드1
1749정성태9/20/201424559.NET Framework: 462. 커널 객체를 위한 null DACL 생성 방법파일 다운로드1
1748정성태9/19/201426107개발 환경 구성: 238. [Synergy] 여러 컴퓨터에서 키보드, 마우스 공유
1747정성태9/19/201429395오류 유형: 239. psexec 실행 오류 - The system cannot find the file specified.
1746정성태9/18/201426545.NET Framework: 461. .NET EXE 파일을 닷넷 프레임워크 버전에 상관없이 실행할 수 있을까요? - 두 번째 이야기 [6]파일 다운로드1
1745정성태9/17/201423890개발 환경 구성: 237. 리눅스 Integration Services 버전 업그레이드 하는 방법 [1]
1744정성태9/17/201431861.NET Framework: 460. GetTickCount / GetTickCount64와 0x7FFE0000 주솟값 [4]파일 다운로드1
1743정성태9/16/201421665오류 유형: 238. 설치 오류 - Failed to get size of pseudo bundle
1742정성태8/27/201427964개발 환경 구성: 236. Hyper-V에 설치한 리눅스 VM의 VHD 크기 늘리는 방법 [2]
1741정성태8/26/201422081.NET Framework: 459. GetModuleHandleEx로 알아보는 .NET 메서드의 DLL 모듈 관계파일 다운로드1
1740정성태8/25/201433487.NET Framework: 458. 닷넷 GC가 순환 참조를 해제할 수 있을까요? [2]파일 다운로드1
1739정성태8/24/201427395.NET Framework: 457. 교착상태(Dead-lock) 해결 방법 - Lock Leveling [2]파일 다운로드1
1738정성태8/23/201423016.NET Framework: 456. C# - CAS를 이용한 Lock 래퍼 클래스파일 다운로드1
1737정성태8/20/201420502VS.NET IDE: 93. Visual Studio 2013 동기화 문제
1736정성태8/19/201426472VC++: 79. [부연] CAS Lock 알고리즘은 과연 빠른가? [2]파일 다운로드1
1735정성태8/19/201419106.NET Framework: 455. 닷넷 사용자 정의 예외 클래스의 최소 구현 코드 - 두 번째 이야기
1734정성태8/13/201420813오류 유형: 237. Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
1733정성태8/13/201427131.NET Framework: 454. EmptyWorkingSet Win32 API를 사용하는 C# 예제파일 다운로드1
1732정성태8/13/201435405Windows: 99. INetCache 폴더가 다르게 보이는 이유
1731정성태8/11/201427900개발 환경 구성: 235. 점(.)으로 시작하는 파일명을 탐색기에서 만드는 방법
1730정성태8/11/201423016개발 환경 구성: 234. Royal TS의 터미널(Terminal) 연결에서 한글이 깨지는 현상 해결 방법
1729정성태8/11/201419034오류 유형: 236. SqlConnection - The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.
1728정성태8/8/201431286.NET Framework: 453. C# - 오피스 파워포인트(Powerpoint) 파일을 WinForm에서 보는 방법파일 다운로드1
... 121  122  123  124  125  126  127  128  129  130  131  132  [133]  134  135  ...