TorchServe 성능 가이드

TorchServe 성능 가이드

TorchServe로 서빙하는 PyTorch 모델의 메모리 사용량·지연(latency)·처리량(throughput)을 최적화하고 싶다면 이 문서가 출발점이에요. 이 페이지에서 다루는 것 외에 추가로 시도해볼 항목은 성능 체크리스트에 정리돼 있으니 함께 참고하면 좋아요. PyTorch 모델 최적화부터 TorchServe 설정 튜닝, 벤치마킹·프로파일링까지 한 흐름으로 살펴볼게요.

출처: Performance Guide — PyTorch/Serve

PyTorch 모델 최적화하기

프로덕션용 PyTorch 모델을 최적화하는 방법은 다양해요. 지식 증류(distillation), 양자화(quantization), 퓨전(fusion), 프루닝(pruning), 환경 변수 설정 등이 있는데, 직접 벤치마크해 보고 가장 효과 좋은 방식을 찾는 걸 권장해요.

일반적으로 모델 자체를 최적화하는 건 어렵기 때문에, 가장 쉬운 접근은 ORT·TensorRT·IPEX·FasterTransformer 같은 런타임으로 내보내는(export) 거예요. TorchServe GitHub 페이지에 이런 런타임을 통합한 예시가 많아요. 원하는 런타임이 지원되지 않으면 PR을 열어 추가할 수 있어요.

torch.compile

PyTorch 2.0부터 torch.compile은 많은 모델에 기본 제공 속도 향상(약 1.8x)을 제공해요. 야간 기준으로 추적하는 대시보드에서 확인할 수 있어요.

  • torch.compile로 완전히 최적화된 모델은 최대 10x까지 성능이 개선돼요.
  • 작은 배치 크기를 쓸 때 mode="reduce-overhead"를 쓰면 CUDA 그래프를 활용해 성능이 좋아질 수 있어요.
  • TorchServe에서 torch.compile을 쓰는 모든 예시는 이곳에서 찾을 수 있고, torch.compile GenAI 예시 상세는 이 링크에 있어요.
# torch.compile 사용 예시 (모델 컴파일)
model = torch.compile(model, mode="reduce-overhead")

ONNX와 ORT 지원

TorchServe는 ONNX 모델을 네이티브 지원하며 ORT로 가속 CPU·GPU 추론을 할 수 있어요. ONNX는 일반 PyTorch 모델과 조금 다르게 동작하는데, 변환할 때 입력·출력 차원을 명시적으로 설정하고 이름을 붙여야 해요.

TorchServe에서 할 수 있는 작업을 한눈에 보면 이래요.

  • 직렬화된 ONNX 가중치를 패키징 — torch-model-archiver --serialized-file model.onnx ...
  • base_handler.py에서 ort_session = ort.InferenceSession(self.model_pt_path, providers=providers, sess_options=sess_options)로 가중치 로딩 — CPU·GPU 추론 모두에 합리적 기본값 지원
  • 커스텀 핸들러로 ONNX 모델이 기대하는 형식에 맞춰 전처리·후처리 함수 정의

TorchServe 도커에서 GPU로 ONNX를 쓰려면 NVIDIA CUDA 런타임을 기본 이미지로 한 이미지를 빌드해야 해요.

TensorRT

TorchServe는 TensorRT로 최적화된 모델도 지원해요. TensorRT 런타임을 활용하려면 이 지침에 따라 모델을 변환하면 직렬화된 가중치가 생기고, 이를 torch.jit.load()로 로딩해요. 변환 후에는 PyTorch가 Torchscript 모델과 TensorRT 모델을 다루는 방식에 차이가 없어요.

Better Transformer

PyTorch의 Better Transformer는 torch.nn.TransformerEncoder의 하위 호환되는 고속 경로를 구현해 트랜스포머 인코더 추론을 빠르게 해줘요. 모델 작성자가 모델을 수정할 필요가 없죠. 많은 일반 실행 시나리오에서 2x 이상의 속도·처리량 향상을 보여요.

TorchServe 최적화하기

config.properties에서 성능을 위해 조절할 주요 설정은 batch_sizebatch_delay예요. 배치 크기가 클수록 처리량이 높아지지만 지연이 커져요.

두 번째로 중요한 설정은 워커 수와 GPU 수인데, CPU·GPU 성능에 큰 영향을 줘요.

동시성과 워커 수

TorchServe는 CPU와 GPU에서 워커 스레드 수를 설정하는 구성(config)을 노출해요. 워크로드에 따라 서버를 빠르게 해주는 중요한 속성이 있는데, 특히 부하가 큰 작업에서 더 큰 효과가 있어요.

CPU에서 TorchServe

CPU에서 TorchServe를 쓸 때는 config.properties에 다음을 설정하면 성능을 높일 수 있어요.

cpu_launcher_enable=true
cpu_launcher_args=--use_logical_core

이 설정은 런처 코어 고정(core pinning)을 통해 성능을 크게 개선해요. 원리는 간단히 말하면 이래요.

  • 하이퍼스레딩이 켜진 시스템에서는 스레드 친화도를 물리 코어에만 고정해 논리 코어를 피해요.
  • NUMA가 있는 멀티소켓 시스템에서는 스레드 친화도를 특정 소켓에 고정해 소켓 간 원격 메모리 접근을 피해요.

GPU에서 TorchServe

number_of_gpu라는 config 속성은 서버가 모델당 특정 개수의 GPU를 쓰게 해요. 여러 모델을 등록하면 이 값은 모든 모델에 적용돼요. 이 값을 너무 낮게(예: 0 또는 1) 두면 GPU가 충분히 활용되지 못하고, 반대로 너무 높게(시스템의 가용 최대 GPU 이상) 두면 모델당 워커가 과하게 생성돼 GPU 경쟁이 생기고 스레드 스케줄링이 비효율적일 수 있어요.

ValueToSet = (Number of Hardware GPUs) / (Number of Unique Models)

즉 하드웨어 GPU 수를 고유 모델 수로 나눈 값을 쓰는 게 기준이에요.

NVIDIA MPS

NVIDIA GPU는 여러 프로세스가 CUDA 커널을 실행할 수 있게 하지만 단점도 있어요.

  • 커널 실행이 일반적으로 직렬화돼요.
  • 각 프로세스가 자체 CUDA 컨텍스트를 만들어 추가 GPU 메모리를 차지해요.

이런 단점을 피하기 위해 NVIDIA MPS(Multi-Process Service)를 활용해 성능을 높일 수 있어요. TorchServe에서 NVIDIA MPS를 쓰는 방법은 이 문서를 참고해요.

NVIDIA DALI

NVIDIA DALI(Data Loading Library)는 딥러닝 애플리케이션을 가속하는 데이터 로딩·전처리 라이브러리예요. 인기 있는 딥러닝 프레임워크의 내장 데이터 로더·데이터 이터레이터를 대체하는 휴대용 드롭인(drop-in)으로 쓸 수 있고, 이미지·비디오·오디오 데이터를 로딩·처리하는 고도로 최적화된 빌딩 블록 모음을 제공해요. TorchServe와 DALI 최적화 통합 예시는 이곳에서 찾을 수 있어요.

벤치마킹

다양한 모델·TorchServe 설정을 비교하기 쉽게, p50·p90·p99 지연 같은 성능 데이터를 깔끔한 리포트로 출력하는 헬퍼 스크립트를 제공해요. 대부분 JSON 또는 YAML로 설정을 정하면 되고, TorchServe 벤치마킹에 대한 자세한 내용은 이 문서를 참고해요.

프로파일링

TorchServe는 PyTorch 프로파일러를 네이티브 지원해서 코드의 성능 병목을 찾는 데 도움을 줘요.

BaseHandler를 오버라이딩하는 커스텀 핸들러나 initialize 메서드를 만들었다면, _infer_with_profiler를 실행하려면 self.manifest 속성을 정의해야 해요.

export ENABLE_TORCH_PROFILER=TRUE

PyTorch 프로파일러에 대해 더 배우려면 이 링크를 방문해요.

더 알아보기 (Learn more)