ES /docs

MaskWork::maskPanos | script /tmp/lib/face-body-detector/sam3/model/encoder.py:358: UserWarning: No

RCA: MaskWork::maskPanos | PyTorch CUDA kernel cache warning

Error Log#

Datadog Logs

text
MaskWork::maskPanos | script /tmp/lib/face-body-detector/sam3/model/encoder.py:358: UserWarning: No PYTORCH_KERNEL_CACHE_PATH or HOME environment variable set! This disables kernel caching. (Triggered internally at /pytorch/aten/src/ATen/native/cuda/jit_utils.cpp:1426.)
  spatial_shapes.prod(1).cumsum(0)[:-1],

Impact#

  • Service: cupixworks-pano-postprocessor-instance
  • Team: arthtech
  • 발생 횟수: 2056
  • 최초 발생: 2026-04-06T08:32:07.770Z
  • 최근 발생: 2026-04-07T10:01:46.850Z

Root Cause Summary#

MaskWork.maskPanos() 메서드가 face-body-detector Python 스크립트를 child_process.spawn()으로 실행할 때, env 옵션에 INPUT_DIRPATH, OUTPUT_DIRPATH, OPTION_FILE_PATH 세 개의 환경 변수만 명시적으로 전달합니다. Node.js의 spawn() API는 env 옵션이 제공되면 부모 프로세스의 환경 변수를 상속하지 않고 지정된 변수만으로 환경을 구성합니다. 이로 인해 HOME, PATH, PYTORCH_KERNEL_CACHE_PATH 등 필수 환경 변수가 자식 프로세스에 전달되지 않아, PyTorch가 CUDA JIT 커널을 캐시할 수 없다는 경고를 매 추론(inference) 호출마다 stderr로 출력합니다. 이 경고는 mask-work.tsprocess.stderr.on('data') 핸들러에 의해 logger.error() 레벨로 기록되어 대량의 error 로그를 생성합니다.

Technical Analysis#

Code Path#

  • Entry point: mask-work.ts:23maskPanos() 메서드
  • Failure point: mask-work.ts:29-33spawn() 호출 시 env 옵션

maskPanos() 메서드에서 spawn()을 호출할 때 env 객체를 명시적으로 지정합니다:

typescript
// applications/agents/packages/cupix-pano-postprocessor/src/work/mask-work.ts:29-33
const process: ChildProcessWithoutNullStreams = spawn('stdbuf', ['-oL', 'bash', BlurScriptPath], {
    cwd: path.dirname(BlurScriptPath),
    stdio: 'pipe',
    env: { INPUT_DIRPATH: inputDir, OUTPUT_DIRPATH: outputDir, OPTION_FILE_PATH: optionPath }
});

Node.js child_process.spawn() 문서에 따르면, env 옵션이 제공되면 process.env를 상속하지 않습니다. 즉, HOME, PATH, PYTORCH_KERNEL_CACHE_PATH 등이 자식 프로세스에 전달되지 않습니다.

  • BlurScriptPath 정의: constants.ts:5
typescript
// applications/agents/packages/cupix-pano-postprocessor/src/config/constants.ts:5
export const BlurScriptPath = '/tmp/lib/face-body-detector/run.sh';

이 스크립트는 S3에서 다운로드된 prebuilt face-body-detector 패키지 내부의 shell 스크립트로, SAM3 encoder를 포함한 Python 추론 파이프라인을 실행합니다.

  • stderr 로깅: mask-work.ts:40-42
typescript
// applications/agents/packages/cupix-pano-postprocessor/src/work/mask-work.ts:40-42
process.stderr.on('data', (data) => {
    logger.error('MaskWork::maskPanos | script %s', data.toString());
});

Python의 UserWarning은 stderr로 출력되며, 이 핸들러가 모든 stderr 출력을 error 레벨로 기록합니다. Python warnings 모듈의 기본 동작은 경고를 stderr에 출력하는 것이므로, 기능적으로 치명적이지 않은 경고도 error 로그로 분류됩니다.

  • PyTorch 트리거 지점: /tmp/lib/face-body-detector/sam3/model/encoder.py:358

SAM3 encoder가 spatial_shapes.prod(1).cumsum(0)[:-1] 연산 시 CUDA JIT 커널을 컴파일하려 할 때, HOMEPYTORCH_KERNEL_CACHE_PATH도 없어 캐시 디렉토리를 결정할 수 없어 경고를 발생시킵니다. 이 경고는 PyTorch 내부 C++ 코드 /pytorch/aten/src/ATen/native/cuda/jit_utils.cpp:1426에서 트리거됩니다.

  • Dockerfile 확인: Dockerfile:20-22
dockerfile
# applications/agents/packages/cupix-pano-postprocessor/Dockerfile:20-22
FROM compute-base:cuda

ENV AGENT_NAME="cupix-pano-postprocessor"
ENV AGENT_PATH="packages/$AGENT_NAME"

Dockerfile에서 PYTORCH_KERNEL_CACHE_PATHHOME 환경 변수를 명시적으로 설정하지 않습니다. 컨테이너 레벨에서는 HOME이 기본값(/root)으로 존재하지만, spawn() 호출이 이를 자식 프로세스에 전달하지 않습니다.

Log Evidence#

Datadog에서 사용한 쿼리:

text
service:cupixworks-pano-postprocessor-instance status:error "MaskWork" "PYTORCH_KERNEL_CACHE_PATH"

시간 범위: 2026-04-06T08:00:00Z ~ 2026-04-06T12:00:00Z

가장 초기 발생 로그 (2026-04-06T08:02:36.306Z):

text
MaskWork::maskPanos | script /tmp/lib/face-body-detector/sam3/model/encoder.py:358: UserWarning: No PYTORCH_KERNEL_CACHE_PATH or HOME environment variable set! This disables kernel caching. (Triggered internally at /pytorch/aten/src/ATen/native/cuda/jit_utils.cpp:1426.)
  spatial_shapes.prod(1).cumsum(0)[:-1],

추가 확인 쿼리 — 동일 서비스의 다른 에러 패턴:

text
service:cupixworks-pano-postprocessor-instance status:error -"MaskWork"

관련 에러 패턴 (동일 root cause에서 파생):

text
MaskWork::maskPanos | script /tmp/lib/face-body-detector/cupix_inference.py:266: RuntimeWarning: overflow encountered in exp

overflow encountered in exp 에러는 cupix_inference.py에서 sigmoid 계산 시 수치 오버플로우가 발생한 별도의 이슈이지만, 동일한 stderr → error 로깅 패턴으로 기록됩니다.

운영 컨텍스트 (로그 속성 기반):

  • Host: Docker 컨테이너 (hostname 591f8190b029)
  • Region: us-west-2
  • Environment: production
  • 로그 수집: Filebeat 7.17.15, /tmp/workspace/agent-json-2026.04.07.log

에러 발생 빈도: 약 26시간 동안 2056회 (시간당 ~80회, 분당 1회 이상). 이는 매 파노라마 이미지 추론 시마다 경고가 발생함을 의미합니다.

Fix Recommendation#

즉시 조치 (Critical)#

  • 파일: applications/agents/packages/cupix-pano-postprocessor/src/work/mask-work.ts:32
  • spawn()env 옵션에 ...process.env를 spread하여 부모 프로세스의 환경 변수를 상속하도록 변경해야 합니다. 이렇게 하면 HOME, PATH, PYTORCH_KERNEL_CACHE_PATH 등이 자식 프로세스에 전달됩니다.
  • 또는, 최소한 HOME: process.env.HOME, PATH: process.env.PATH 를 명시적으로 추가해야 합니다.

단기 개선 (1주 이내)#

  • stderr 로깅 레벨 분류: mask-work.ts:40-42에서 stderr 출력을 무조건 logger.error()로 기록하는 대신, Python UserWarning/RuntimeWarning 패턴을 감지하여 logger.warn()으로 분류하는 로직 추가를 검토해야 합니다. 이를 통해 실제 에러와 경고를 구분할 수 있습니다.
  • Dockerfile에 PYTORCH_KERNEL_CACHE_PATH 설정: Dockerfile에서 ENV PYTORCH_KERNEL_CACHE_PATH=/tmp/.pytorch_cache를 설정하여 컨테이너 레벨에서도 캐시 경로를 명시하면, spawn() env 수정과 함께 이중 안전장치 역할을 합니다.

장기 개선 (재발 방지)#

  • face-body-detector prebuilt 패키지의 Python 스크립트 내에서 warnings.filterwarnings를 사용하여 불필요한 UserWarning을 억제하거나, 환경 변수 부재 시 fallback 캐시 경로를 자체적으로 설정하도록 개선해야 합니다.
  • 모든 spawn() 호출에 대해 환경 변수 상속 여부를 코드 리뷰 체크리스트에 추가하여, 유사한 환경 변수 누락 문제를 방지해야 합니다.

Monitoring#

  • 수정 배포 후 동일 에러 로그 감소 확인:
text
service:cupixworks-pano-postprocessor-instance status:error "PYTORCH_KERNEL_CACHE_PATH"
  • stderr 경고와 실제 에러를 분리한 후, 실질적인 mask 처리 실패 모니터링:
text
service:cupixworks-pano-postprocessor-instance status:error "MaskWork::maskPanos | error code"

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: trivial

이 에러는 PyTorch의 UserWarning이 stderr를 통해 error 레벨로 기록된 것으로, mask 처리 자체의 정확성이나 성공 여부에는 영향을 주지 않습니다. 다만, 커널 캐싱이 비활성화되어 매 추론마다 CUDA 커널이 재컴파일되므로 경미한 성능 저하가 발생할 수 있습니다. spawn() env 수정은 1줄 변경으로 해결 가능한 trivial 수준입니다.