gRPC 추론 API
백엔드와 Python 추론 런타임은 50051 포트의 gRPC(protos/inference.proto, 서비스
InferenceService)를 통해 통신합니다. 운영자가 이 API를 직접 호출하는 경우는 드뭅니다 —
백엔드가 클라이언트입니다 — 하지만 파이프라인을 디버깅하거나, 박스에서 커스텀 클라이언트를
통합하거나, 추론 로그를 읽을 때는 이 계약이 중요합니다.
서비스 메서드
섹션 제목: “서비스 메서드”| RPC | 유형 | 목적 |
|---|---|---|
StreamInference | 양방향 스트림 | 센서 윈도우 입력, 예측 출력 — 실시간 핫 패스 |
LoadModel | 단항(unary) | ONNX 모델 검증 + 등록 + 핫스왑(무중단) |
ValidateModel | 단항(unary) | 비변경 검사: 형상 + SHA-256, 아무것도 로드하지 않음 |
HealthCheck | 단항(unary) | 서비스 상태 + CPU/GPU/메모리 메트릭 |
StreamLogs | 서버 스트림 | 최소 레벨로 필터링한 추론 로그 테일링 |
StreamInference
섹션 제목: “StreamInference”각 InferenceRequest는 request_id, timestamp(Unix epoch ms, 센서 샘플링 시점에 백엔드가
한 번만 찍고 변경 없이 그대로 반환됨 — 따라서 시계 동기화 문제가 없습니다), 평탄한 features
배열, 그리고 메타데이터 맵을 전달합니다.
각 InferenceResponse는 predictions와 confidence_scores, 서빙 중인
model_id/model_version, inference_time_ms, 그리고 세 개의 타임스탬프를 반환합니다:
| 필드 | 의미 |
|---|---|
window_start_timestamp | 예측 윈도우에서 가장 오래된 입력 샘플 |
window_end_timestamp | 가장 최신 입력 샘플 — 예측의 “기준 시점” |
emitted_at | 방출 시점의 벽시계 시간. emitted_at − window_end_timestamp는 엔드투엔드 지연 시간의 근사값 |
모델 워밍업 중(슬라이딩 윈도우가 아직 가득 차지 않음)에는 응답이
metadata["warming_up"] = "true"를 전달하며, 백엔드는 이를 대시보드에서 숨깁니다.
LoadModel
섹션 제목: “LoadModel”모델 버전을 등록하고 이중 버퍼링으로 실행 중인 세션에 핫스왑합니다 — 새 세션은 락 바깥에서 로드 및 워밍업된 뒤, 참조가 원자적으로 교체되므로 스트리밍이 결코 멈추지 않습니다.
- 콘텐츠 해시 기준 멱등성: 동일한 SHA-256으로 같은
(model_id, version)을 다시 보내면 성공 no-op입니다. 다른 SHA-256으로 같은 버전을 보내면version_conflict로 거부됩니다 — 버전은 불변입니다. - 응답은
input_shape,output_shape,registered_path, 그리고 계산된sha256을 반환합니다. - 새 모델의
(window_size, n_features)가 이전 것과 다르면, 윈도잉 파이프라인이 재구성되고 워밍업이 다시 시작됩니다.
ValidateModel
섹션 제목: “ValidateModel”모델 업로드 중 백엔드가 사용하는 순수 검사입니다. 일회용 런타임 세션을 열어 입력/출력 형상과
SHA-256을 추출하고, 아무것도 등록하지 않은 채 {valid, message, input_shape, output_shape, sha256}을
반환합니다.
검증은 모델 계약을 강제합니다:
- ONNX 파일 ≤ 500 MB, 로드 가능, ONNX 체커 통과
- Opset 13–18
- 입력 텐서
input의 형상(batch, window_size, n_features)— 3차원 필수. 배치 차원은 동적일 수 있음 - 출력 텐서
output의 형상(batch, 3)=[health_score, failure_probability, rul_normalized]
HealthCheck 및 StreamLogs
섹션 제목: “HealthCheck 및 StreamLogs”HealthCheck는 대시보드 헬스 패널(GPU 부하, 메모리, 가동 시간)을 구동합니다.
상태, CPU, 호스트 메모리, 가동 시간 외에 응답에는 다음 필드가 포함됩니다(전체 메시지는
protos/inference.proto의 HealthCheckResponse):
| 필드 | 의미 |
|---|---|
swap_used_mb, swap_total_mb | 호스트의 스왑. 호스트에 스왑이 없으면 -1 |
container_memory_used_mb, container_memory_limit_mb | 추론 컨테이너의 메모리 사용량과, 컨테이너가 중지되는 메모리 한도(RAM + 스왑). 한도가 없거나 읽을 수 없으면 -1 |
gpu_metrics.memory_kind | MEMORY_KIND_SHARED(Jetson: GPU가 시스템 RAM을 사용하므로 GPU 메모리 필드는 호스트 값과 같음), MEMORY_KIND_DEDICATED(독립 VRAM), 또는 MEMORY_KIND_UNKNOWN |
model_window_size, model_feature_count | 엔진에 실제로 로드된 모델 세션의 윈도우 길이와 피처 수. 로드된 모델이 없으면 0 |
model_loaded, stub_mode | 사용 가능한 모델 세션이 로드되었는지, 엔진이 합성 출력을 내보내고 있는지 여부 |
이 필드들은 추가된 필드입니다. 이전 버전의 추론 엔진은 이를 보내지 않으므로 0(또는
MEMORY_KIND_UNKNOWN)으로 도착하며, 대시보드는 해당 값을 보고되지 않음으로 표시합니다.
StreamLogs는
Python 서비스의 로그 스트림을 백엔드로 전달하고, 백엔드는 이를 LogViewer용으로 영속화합니다 —
min_level로 필터링하세요.
런타임 구성
섹션 제목: “런타임 구성”추론 컨테이너가 인식하는 환경 변수(compose 파일에서 설정):
| 변수 | 기본값 | 효과 |
|---|---|---|
EXECUTION_MODE | auto | 실행 공급자: auto(CUDA, CPU는 폴백), cuda, cpu. TX2에서는 TensorRT를 사용하지 않습니다. |
STRICT_EP | off | 1 = 핀 고정된 GPU 모드를 조용히 CPU로 저하시키는 대신 시작을 거부 |
MODEL_PATH | /app/models/predictive_maintenance_op15.onnx | 시작 시 로드되는 시드 모델 |
MODEL_STORAGE_PATH | /data/models | 등록된 모델 버전이 저장되는 위치 |
LOG_DIR | 미설정 | 회전형 온디스크 로그 파일(inference.log) 활성화. 미설정 = 콘솔 전용 |
FORCE_CPU | off | EXECUTION_MODE=cpu의 레거시 별칭 |