디버깅 가이드
디버깅 가이드 (Debugging Guide)
이 가이드는 Triton이 예상과 다르게 동작하거나 실패하는 흔한 상황에서 첫 단계로 할 문제 해결(troubleshooting)을 정리해요. 문제를 다음 범주로 나눠볼게요.
- 설정(Configuration): Triton이 설정 파일에서 오류를 보고.
- 모델(Model): 모델 로드나 추론이 실패.
- 서버: 서버가 크래시하거나 사용 불가 상태.
- 클라이언트: 클라이언트가 서버와 데이터를 주고받지 못함.
- 성능: Triton이 최적 성능을 내지 못함.
어떤 범주의 문제든, 가능하면 최신 Triton 컨테이너에서 실행해 보는 게 좋아요. 옛 컨테이너도 지원하지만 수정 사항은 다음 릴리스에 병합되므로, 최신 릴리스를 확인하면 이미 해결된 문제인지 알아볼 수 있습니다.
Triton의 GitHub 이슈를 검색해 누군가 같은 문제를 이미 질문했는지도 볼 수 있어요. 오류를 받았다면 그 오류에서 키워드 몇 개를 검색어로 쓰면 됩니다.
Triton은 다양한 문제에 걸쳐 쓰이는 여러 오류·상태 유형을 제공해요. 개요는 다음과 같습니다.
| 오류 | 정의 | 예시 |
|---|---|---|
| Already Exists | 이미 존재하는 항목이 있어서 동작을 수행할 수 없을 때 반환 | 등록된 모델이 다시 등록 실패 |
| Internal | Triton 코드 내부의 예기치 않은 실패가 있을 때 반환 | 메모리 할당 실패 |
| Invalid Arg | 함수에 잘못된 인자가 제공됐을 때 반환 | 모델 설정에 잘못된 파라미터 |
| Not Found | 요청한 리소스를 찾을 수 없을 때 반환 | 공유 라이브러리를 찾을 수 없음 |
| Unavailable | 요청한 리소스는 있지만 사용 불가할 때 반환 | 요청한 모델이 추론 준비가 안 됨 |
| Unknown | 오류 사유를 알 수 없는 경우 반환 | 이 오류 코드는 사용하면 안 됨 |
| Unsupported | 지원되지 않는 옵션일 때 반환 | 모델 설정에 해당 백엔드가 아직 지원하지 않는 파라미터 포함 |
설정(Configuration) 문제
진행하기 전에 모델 설정 문서가 질문을 해결해 주는지 먼저 확인하세요. 그 외에 사용 사례에 맞는 샘플 모델 설정을 찾을 수 있는 가장 좋은 곳은 다음과 같습니다.
- 서버 qa 폴더. 대부분의 기능을 다루는 테스트 스크립트를 찾을 수 있고, 일부는 모델 설정 파일을 갱신하며 테스트해요.
- Custom_models, ensemble_models, python_models에 각 사용 사례의 설정 예시가 있어요.
- L0_model_config는 다양한 종류의 불완전한 모델 설정을 테스트합니다.
perf_analyzer나 Model Analyzer에서 문제가 생겼다면, 모델을 Triton에 직접 로드해 보세요. 이렇게 하면 설정이 잘못된 건지, perf_analyzer나 Model Analyzer 옵션을 갱신해야 하는 건지 확인할 수 있어요.
모델 문제
1단계. Triton 밖에서 모델 실행
모델을 로드하거나 실행하는 데 문제가 있다면, 첫 단계는 모델이 자체 프레임워크에서 Triton 밖으로도 실행되는지 확인하는 거예요. 예를 들어 ONNX 모델은 ONNX Runtime에서, TensorRT 모델은 trtexec에서 실행해 볼 수 있어요. 이 확인이 실패하면 문제는 프레임워크에 있는 것이지 Triton에 있는 게 아닙니다.
2단계. 오류 메시지 찾기
오류 메시지를 받았다면 코드 검색을 통해 어디서 생성됐는지 찾을 수 있어요. GitHub의 코드 검색 방법은 여기에 있어요. Triton 조직 전체를 검색하려면 이 링크를 이용하면 됩니다.
오류 메시지가 Triton 코드의 한두 곳에서만 나타난다면, 무엇이 잘못됐는지 꽤 빨리 알 수 있어요. 그렇지 않더라도 이 링크를 저장해 두고 이슈 관련 도움을 요청할 때 제공하면 좋아요. 흔히 우리가 가장 먼저 보는 것 중 하나입니다.
3단계. 디버그 플래그로 빌드
다음 단계는 디버그 플래그로 빌드하는 거예요. 안타깝게도 디버그 컨테이너는 제공하지 않으니, 빌드 가이드를 따라 컨테이너를 빌드해야 합니다. 거기에 디버그 심볼을 추가하는 섹션이 있어요. 빌드한 뒤 컨테이너에 GDB(apt-get install gdb)를 설치하고 GDB로 Triton을 실행(gdb --args tritonserver…)하면 됩니다. 필요하면 두 번째 터미널을 열어 다른 컨테이너에서 스크립트를 실행할 수 있어요. 서버가 세그폴트하면 backtrace를 입력하면 오류가 생성된 위치를 알려주는 콜 스택이 나오고, 그걸로 오류의 원인을 추적할 수 있습니다. 디버깅 후에도 버그가 남아 있다면, 그 정보가 우리 작업을 빠르게 하는 데 필요합니다.
고급 GDB 사용자는 변수 값 검사, 브레이크포인트 추가 등을 통해 문제 원인을 찾을 수도 있어요.
구체적 문제 — 정의되지 않은 심볼
여기서 선택할 수 있는 옵션이 몇 가지 있습니다.
- 이는 보통 Triton이 사용하는 프레임워크의 버전과 모델을 만드는 데 사용한 프레임워크 버전이 서로 맞지 않아서 생겨요. Triton 컨테이너가 사용하는 프레임워크 버전을 확인하고, 모델을 생성할 때 사용한 버전과 비교해 보세요.
- 백엔드가 사용하는 공유 라이브러리를 로드한다면, Tritonserver를 실행하는 명령 앞에 LD_PRELOAD를 넣는 것을 잊지 마세요.
LD_PRELOAD=<name_of_so_file.so> tritonserver --model-repository…백엔드를 직접 빌드했다면 링크 오류일 수 있어요. 백엔드와 서버가 제대로 빌드됐다고 확신하면, 서버가 올바른 백엔드를 로드하는지 다시 확인하세요.
서버 문제
보통 서버 자체에서 오류가 나지는 않아야 해요. 서버가 내려가면 대개 모델 로드나 추론 중 문제가 생긴 것이고, 위의 섹션으로 디버그할 수 있어요. 특히 위의 디버그 플래그로 빌드 섹션을 따라 그런 문제를 해결하는 게 유용합니다. 다만 이 섹션에서 발생할 수 있는 몇 가지 구체적인 경우를 다뤄볼게요.
서버에 연결할 수 없음
서버 연결이나 health 엔드포인트(curl -v localhost:8000/v2/health/ready)를 통해 상태를 확인하는 데 문제가 있다면, 명령을 실행하는 위치에서 서버가 실행 중인 네트워크에 도달할 수 있는지 확인하세요. 가장 흔한 경우는 클라이언트와 서버를 별도의 Docker 컨테이너로 시작하면서 네트워크를 공유하도록 --net=host를 쓰지 않은 경우입니다.
간헐적 실패
이건 디버그하기 가장 어려운 부류 중 하나예요. 가능하면 서버를 디버그 플래그로 빌드해 정확히 무슨 일이 일어나는지 백트레이스를 얻고 싶을 거예요. 또 이게 얼마나 자주 발생하는지, 흔한 원인인지 기록해 두는 게 좋습니다. 서버 자체는 유휴 상태에서 실패하지 않아야 하므로, 특정 동작(모델 로드/언로드, 모델 추론 실행 등)이 이를 유발하는지 확인해 보세요.
개별 모델로 인한 서버 실패
모델이 실패해도 서버가 시작되길 원하면 exit-on-error=false 옵션을 쓰세요. 특정 모델이 실패해도 서버 health 엔드포인트가 ready를 보여주길 원하면 --strict-readiness=false 플래그를 사용합니다.
교착 상태(Deadlock)
gdb로 교착 상태를 디버그하는 데 유용한 단계들입니다.
$info threads로 어떤 스레드가 대기 중인지 확인.- 스레드로 이동:
$thread 4. - 백트레이스 출력:
$bt. - 잠금이 있는 프레임으로 이동:
$f 1. - 잡고 있는 뮤텍스의 메모리 출력:
$p *mutex. - 이제
owner아래에서 뮤텍스 소유자를 볼 수 있음.
클라이언트 문제
다양한 클라이언트 사례를 다루려면 클라이언트 repo의 예시가 가장 좋은 자료예요. Python·Java·C++로 작성된 클라이언트와 많은 일반 사용 사례의 실행 예시를 볼 수 있고, 주요 함수를 검토하면 코드 흐름을 파악할 수 있습니다.
클라이언트 성능 최적화 질문을 자주 받는데, Triton 클라이언트는 입력 텐서를 원시 이진(raw binary)으로 보내요. 그러나 gRPC는 직렬화·역직렬화 오버헤드가 있는 protobuf를 사용합니다. 가장 낮은 지연시간을 원한다면 C API가 gRPC/HTTP와 연관된 지연시간을 제거해요. 클라이언트와 서버가 같은 시스템에 있다면 공유 메모리(shared memory)도 데이터 이동을 줄이는 좋은 선택입니다.
성능 문제
이 섹션은 예상 밖의 성능을 디버그하는 방법을 다룹니다. 성능 최적화를 찾고 있다면 Optimization과 Performance Tuning 가이드를 참고하세요.
가장 쉬운 시작은 perf_analyzer를 실행해 각 모델의 요청 생애주기, 처리량, 지연시간을 세분화해서 보는 거예요. 더 상세한 보기가 필요하면 서버 실행 시 트레이싱을 활성화하면 됩니다. 그러면 정확한 타임스탬프를 얻어 무슨 일이 일어나는지 파고들 수 있어요. gRPC·HTTP 클라이언트에서도 트레이싱 플래그를 사용해 perf_analyzer로 트레이싱을 켤 수 있습니다. 트레이싱 활성화가 Triton 성능에 영향을 줄 수 있지만, 요청 생애주기 전반의 타임스탬프를 검토하는 데는 유용해요.
성능 프로파일링
다음 단계는 성능 프로파일러를 사용하는 거예요. 추천하는 프로파일러 중 하나는 Nsight Systems(nsys)이고, 선택적으로 NVIDIA Tools Extension(NVTX) 마커를 포함해 Triton을 프로파일할 수 있습니다.
Triton 서버 컨테이너에는 이미 nsys가 설치돼 있어요. 다만 Triton은 기본적으로 NVTX 마커로 빌드되지 않습니다. NVTX 마커를 쓰려면 build.py로 Triton을 빌드할 때 --enable-nvtx 플래그를 사용하세요. 이렇게 하면 큐잉, 추론 실행, 출력 처리 같은 요청 처리 단계 일부에 대한 상세 정보가 제공됩니다.
nsys profile tritonserver --model-repository …로 Triton을 프로파일할 수 있어요. nsys 문서에 전체적인 그림을 잡기 위한 더 많은 옵션·상세 내용이 있습니다.
이슈 제출
초기 디버깅 단계를 진행했는데도 결과가 없다면, 우리에게 이슈를 제출하는 게 다음 단계입니다. 그 전에 몇 가지 질문에 답해 주세요.
- 여러 모델 및/또는 예제 모델로 재현되나요? 아니면 모델에만 국한된 문제인가요?
- 어떤 프로토콜(예: HTTP vs gRPC)로도 재현되나요? 아니면 한 프로토콜에서만인가요?
위 답변이 무엇을 제출할지 결정해 줍니다. 문제가 특정 상황에서만 발생한다면 그 내용을 보고서에 꼭 포함하세요. 문제가 여전히 있다면 아래를 전부 제출해 주세요.
- Triton을 빌드/풀하고 모델을 실행하는 데 쓴 명령 또는 스크립트.
- Triton을 빌드했다면 빌드에 사용한 버전 또는 브랜치.
- 모델 설정 파일.
- 받은 오류 및 로그.
- 서버 크래시가 관련된 문제라면 덤프의 백트레이스가 도움이 됩니다.
- 가장 상세한 로그를 얻으려면 상세 로깅(
--verbose-log=1)을 활성화해 주세요.
- 문제가 모델에만 국한된 경우, 모델 또는 문제를 재현하는 토이 모델.
- 조사를 빠르게 해 줄 그 밖의 모든 것.