application-architecture-reference.mdS1 시나리오를 구현 설계 수준으로 확장. 전제: 사진/영상을 던지면 대상의 상태(정적 포즈) 또는 모션(동적 움직임) 을 구조화 데이터로 반환. 재사용 모티프: 잔여 임차인 자산의 executor 플러그인 + 동기/비동기 병용 + 런타임 가중치 패턴. 작성 2026-06-24. 설계 문서(코드 아님). 인프라는 보유 클러스터 기준 매핑(배포 전 가용성 확인 필요).
"사진 1장 → 상태(포즈/마스크/부위/자세분류) 즉시 반환 · 영상 → 모션(키포인트 시계열·관절각·보행지표·이벤트) 잡 처리 반환" 하는 멀티-종(species) 비전 분석 API.
| State 모드 | Motion 모드 | |
|---|---|---|
| 입력 | 이미지 1장 | 영상(또는 프레임 시퀀스) |
| 처리 | 탐지→분할→키포인트→상태분류 | 프레임추출→탐지→추적→키포인트→시계열 집계 |
| 출력 | bbox·mask·keypoints·state | track별 키포인트 시계열·관절각·보행/주기 지표·이벤트 |
| 서빙 | 동기 HTTP (저지연) | 비동기 잡 (큐·워커) |
| 지연 | 수 초~수 분(영상 길이 비례) |
핵심 원칙: 모션은 상태의 시간축 확장. 상태 추론 코어를 프레임마다 호출 + 추적/집계 단계를 위에 얹는다. → 코어 1개를 두 모드가 공유.
┌───────────────────────────────────────────────────────┐
클라이언트 ─▶│ API Gateway (Ingress + FastAPI) : 인증/라우팅/검증 │
(상위 서비스) └───────────┬───────────────────────────────┬───────────┘
│ State(동기) │ Motion(비동기)
▼ ▼
┌────────────────────┐ ┌────────────────────────────┐
│ Sync Inference Svc │ │ Job API: 영상→MinIO 저장, │
│ (GPU Pod, HPA) │ │ 큐 enqueue, job_id 반환 │
│ 단일이미지→즉시결과 │ └───────────────┬────────────┘
└─────────┬──────────┘ │ enqueue
│ ┌─────────▼─────────┐
│ │ Queue (NATS/Redis)│
│ └─────────┬─────────┘
│ │ pull (KEDA 스케일)
│ ┌─────────▼──────────────┐
│ │ Worker Pool (GPU) │
│ │ executor-id 로 파이프선택 │
│ │ 추적+시계열 집계 │
│ └─────────┬──────────────┘
▼ ▼
┌──────────────────────────────────────────────────────────┐
│ Inference Core (model_server) ── 동기/비동기 공유 │
│ Detector → (Tracker) → Pose/Seg → DINOv3 feat → Head │
└───────────────────────────┬──────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Model Registry: MLflow │ Weights/Artifacts: MinIO │ 결과 메타: DB(PG) │
│ 이미지 레지스트리: Harbor │ PVC: NFS(nfs-default) │ GPU: kube-rtx3 등 │
└──────────────────────────────────────────────────────────────────────────┘
model_server) — 두 모드 공유. 모델 상주 + 단계 실행. (잔여 자산의 model_server.py 역할)executor-id = {species}_{task} 예: human_pose, dog_pose, horse_gait, cattle_lameness.
각 executor 번들이 선언(설정 파일, 잔여 자산의 run.yaml 역할):
executor: horse_gait
detector: { model: yolo26x_horse, weights: minio://models/horse/det.pt, classes: [horse] }
pose: { model: rtmpose_animal, weights: minio://models/horse/pose.pt, skeleton: horse_22kpt }
segment: { model: yolo11l-seg } # 선택
backbone: { model: dinov3_vitb16 } # 상태분류/few-shot 특징
state_head: { weights: minio://models/horse/state_clf.pt, labels: [stand, walk, trot, ...] }
tracker: { model: bytetrack } # motion 전용
analytics: { joint_angles: [...], gait: true, asymmetry: true }
output_schema: motion_v1
| 대상 | 골격 | 추천 모델 | 데이터 |
|---|---|---|---|
| 사람 | 17/26 kpt | RTMPose, ViTPose, YOLО-pose | COCO, MPII (성숙) |
| 개·고양이·말 등 사족 | 종별 17~26 kpt | AP-10K 사전학습→파인튜닝, RTMPose-animal | AP-10K, AnimalPose, 자체 라벨 |
| 공통 백본 | — | DINOv3 특징 → 소형 상태 헤드 | few-shot 적응 |
image → detect(bbox) → crop → [segment(mask)] + pose(keypoints)
→ DINOv3 feature → state classifier →
{subject, bbox, mask?, keypoints[], state, confidence}
video → ffmpeg 프레임 샘플(목표 fps) → per-frame detect → tracker(ID 부여)
→ per-frame pose → 트랙별 키포인트 시계열 버퍼
→ 시계열 후처리/분석:
· 스무딩(One-Euro / Savitzky-Golay)
· 관절각(키포인트 3점) 시계열
· 보행 주기/케이던스(사지 신호 자기상관)
· 좌우 비대칭 지수(파행/lameness)
· 속도·스트라이드(스케일 보정 시 절대값, 아니면 상대값)
· 이벤트 탐지(점프/낙상/이상자세)
→ 트랙별 집계 + 요약
⚠️ 절대 단위(거리/속도)는 카메라 캘리브레이션/스케일 기준이 있어야 신뢰. 없으면 각도·주기·비대칭 등 스케일 불변 지표로 한정 권장.
POST /v1/analyze/state # 동기
body: multipart{ image, executor }
200 → { subject, bbox, keypoints[], mask_url?, state, confidence, model_version }
POST /v1/analyze/motion # 비동기
body: multipart{ video | source_url, executor, fps?, callback_url? }
202 → { job_id, status: "queued" }
GET /v1/jobs/{job_id}
200 → { status: queued|running|done|failed, progress, result_url?, error? }
(status=done) result(MinIO) →
{
executor, video_meta:{duration, fps_sampled, frames},
tracks: [
{ track_id, species, kpt_series:[{t, keypoints[]}],
joint_angles:{ hip:[...], stifle:[...] },
gait:{ cadence, stride_rel, cycle_count },
asymmetry_index, events:[{t, type, score}] }
],
summary, model_version, artifacts:{ overlay_video_url, keypoints_csv_url }
}
| 역할 | 사용 자원 | 비고 |
|---|---|---|
| 컨테이너 레지스트리 | Harbor | harbor-credentials 기존 |
| GPU 실행 | kube-rtx3(.54, 4×RTX3090) + 기타 GPU노드 | GPU전용 taint → toleration/nodeSelector |
| 모델 레지스트리 | MLflow (mlflow.mydevops.co.kr) | 가중치 버전/실험 추적 |
| 아티팩트/입출력 | MinIO (minio.minio.svc:9000) | 영상 업로드·결과 저장 |
| 큐 | NATS(클러스터 존재) 또는 Redis | KEDA로 큐 길이 기반 스케일 |
| 영속 스토리지 | NFS(StorageClass nfs-default) | PVC/모델 캐시 |
| 분산 실행(옵션) | Ray(ray-space) | Ray Serve(동기) + Ray Job(비동기) 대안 |
| 메타 DB | PostgreSQL | 잡 상태/결과 인덱스 |
캐파 주의: 메모리 기록상 워커 4대 CPU 포화/일부 GPU 전용화. GPU 가용량 사전 산정 후 동시 잡 수 상한 설정.
model_server(잔여 자산 패턴). 고처리량 시 Triton/TorchServe 또는 Ray Serve.worker_runtime 개념 재현.application-architecture-reference.mdhorse-worker-analysis.md