MLPerf Inference 수행하기

MLPerf Inference 수행하기

MLPerf Inference

딥러닝 모델 성능을 객관적으로 비교하고자 할 때 단순한 FPS, Latency 지표만으로는 부족합니다.
MLPerf는 이러한 문제를 해결하기 위해 등장한 가장 공신력 있는 AI 성능 벤치마크 표준으로, 기업과 연구기관에서 GPU 및 서버 성능 검증에 널리 사용됩니다.

이 문서에서는 MLPerf Inference 환경에서 Retinanet (Datacenter) 를 직접 실행하는 과정을 단계별로 안내합니다.


1. MLPerf란 무엇인가?

1.1 MLCommons & MLPerf 개요

MLPerf는 비영리 단체 MLCommons가 운영하는 AI 성능 벤치마크 모음입니다.
핵심 목표는 다음과 같습니다:

  • 아키텍처 중립성
  • 재현 가능성
  • 대표성 있는 워크로드 구성

즉, 누구나 동일한 기준으로 공정하게 성능을 비교할 수 있도록 설계되어 있습니다.

최근 공개 라운드:

Round 발표일
Inference v5.1 2025-09-09
Inference v5.0 2025-04-02

💡 TIP
실습과 참고 자료는 v5.0 기준으로 가장 많이 공유되어 있어, 실무 및 입문은 v5.0 진행을 권장합니다.
(이후 v5.1로 동일 방식으로 확장 가능)


1.2 Inference 벤치마크 시나리오

Inference 벤치마크는 학습 완료된 모델의 추론 성능을 측정합니다.

시나리오 설명
Offline 대량 요청을 모아 처리 → 최대 QPS 확인
Server 실시간 요청 처리 능력 + 지연시간 만족 여부 평가
SingleStream 요청 1개 기준 순차 처리 (Latency 중심)
MultiStream 여러 스트림 처리 시 프레임 드롭 없이 유지 가능 여부

⚠️ 주의 사항
Server 시나리오에서는 목표 요청 처리율과 지연시간을 만족하지 못하면 결과가 INVALID로 처리됩니다.


1.3 Closed vs Open Division

Division 특징 목적
Closed 모델/전처리/정확도 기준 고정 HW 성능 자체 비교
Open 모델 변경 가능 알고리즘/구조 혁신 실험

실무에서 GPU 성능 비교 목적이라면 Closed 사용이 일반적입니다.


1.4 LoadGen(트래픽 발생기)

모든 MLPerf 성능 측정은 LoadGen을 통해 동일한 요청 패턴을 생성하여 이루어집니다.
따라서 LoadGen 규칙 준수는 필수입니다.


2. MLPerf Inference 실행하기 (Closed / NVIDIA 기준)

목표

  • 환경: Datacenter
  • Benchmark: Retinanet
  • Version: inference_results_v5.0

2.0 사전 준비

항목 권장
OS Ubuntu 22.04 / 24.04
GPU Driver / CUDA 컨테이너 버전과 호환
Docker + NVIDIA Container Toolkit 필수
디스크 용량 데이터/엔진 포함 50GB~300GB

2.1 저장소 클론

git clone https://github.com/mlcommons/inference_results_v5.0.git
cd inference_results_v5.0/closed/NVIDIA\

2.2 데이터 루트 생성

export MLPERF_SCRATCH_PATH=/home/$USER/mlperf
mkdir -p $MLPERF_SCRATCH_PATH/{data,models,preprocessed_data}

2.3 Docker & NVIDIA Container Toolkit 설치

MLPerf 실행 환경은 컨테이너 기반입니다.
Docker는 컨테이너 런타임, NVIDIA Container ToolkitGPU Passthrough를 담당합니다.
둘 중 하나라도 없으면 컨테이너 내부에서 GPU를 사용할 수 없습니다.

⚠️ 주의 사항
호스트 NVIDIA Driver ↔ 컨테이너 CUDA 런타임 버전 호환성 확인 필수.


sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Docker Container 내부 GPU 확인

docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi


2.4 (필요 시) NGC 로그인

make prebuild 과정에서 nvcr.io (NVIDIA Container Registry) 이미지를 다운로드할 수 있습니다. 이때 인증이 필요할 수 있습니다. docker login nvcr.io

방화벽/프록시 환경에서는 해당 레지스트리를 바라 볼 수 있게 하거나, 미리 이미지를 준비해주세요.

베이스 이미지는 inference_results_v5.0/closed/NVIDIA/Makefile.docker 내부에 nvcr로 검색을 하면 필요한 이미지명을 찾을 수 있습니다.


2.5 프리빌드 (이미지 구성 및 의존 패키지 설치)

make prebuild는 MLPerf 실행에 필요한 도커 이미지 + 라이브러리 + 벤치 실행 스크립트를 자동 세팅합니다.

make prebuild

⚠️ 주의 사항
도커 이미지 및 캐시 용량으로 인해 최소 수십 GB 필요합니다. (저희 케이스의 경우 이미지만 약 80~90GB 정도 사용되었습니다.)


2.6 컨테이너 실행 스크립트 구성 및 실행

반복 실행 시 동일한 런타임 환경을 유지하는 것이 매우 중요합니다.
특히 --net host, --shm-size, --ulimit memlock 등이 성능에 영향을 줍니다.

cat <<'SH' > docker_run.sh
#!/usr/bin/env bash
set -euo pipefail

export MLPERF_SCRATCH_PATH="${MLPERF_SCRATCH_PATH:-/home/$USER/mlperf}"
export BUILD_PATH="$(pwd)"
CPU_LIST="$(taskset -c -p $$ | awk '{print $NF}')"
IMAGE_TAG="mlperf-inference:closed-nvidia-v5.0"

docker run --rm -it \
  --gpus all --net host \
  --shm-size=32g --ulimit memlock=-1 \
  --cpuset-cpus "$CPU_LIST" \
  -v /etc/localtime:/etc/localtime:ro \
  -v "$MLPERF_SCRATCH_PATH:$MLPERF_SCRATCH_PATH" \
  -v "$BUILD_PATH:/work" \
  -e MLPERF_SCRATCH_PATH="$MLPERF_SCRATCH_PATH" \
  -e NVIDIA_VISIBLE_DEVICES=all \
  --name mlperf-dev \
  "$IMAGE_TAG" \
  bash
SH
chmod +x docker_run.sh
./docker_run.sh

2.7 (선택) 커스텀 시스템 등록

서버의 CPU / NUMA / GPU 토폴로지 정보를 MLPerf 시스템 정의에 등록합니다.

python3 -m scripts.custom_systems.add_custom_system

Tip: 노드 구성이 DGX가 아니라면 자동으로 인식이 안될 수 있습니다. 노드별로 별도 등록을 권장합니다.


2.8 엔진 및 커널 빌드 (TensorRT 최적화)

다음 build 과정에는 현재 시스템 정보가 들어갑니다. 그 중에 GPU 고유의 SM 아키텍처 ID 값이 중요한데, default로 현재 시스템 정보가 들어감으로 만약 빌드하는 환경과 테스트하는 환경이 다를 경우 테스트할 환경의 GPU SM Architecture ID 값을 정확히 설정해야 성능이 제대로 나옵니다.

GPUSM 값
L40S89
A10080
H10090

make build SM=89


2.9 모델 / 데이터 다운로드 + 전처리

이 단계는 Retinanet 벤치마크에 필요한 모델 가중치, 데이터셋, 전처리 캐시 생성을 수행합니다.

명령역할설명
make download_model BENCHMARKS=retinanet모델 다운로드Retinanet 평가에 사용되는 공식 모델 가중치를 준비합니다. 정확도 검증 기준이 Closed 규정에 의해 통일됩니다.
make download_data BENCHMARKS=retinanet원본 데이터 다운로드COCO 등 Retinanet 검증용 데이터셋을 MLPerf 구조에 맞게 가져옵니다. (인터넷 연결 필요)
make preprocess_data BENCHMARKS=retinanet전처리 수행 → 캐시 생성이미지 리사이징, 정규화 등 실행 시 반복되는 CPU 부하 작업을 사전에 처리하여 추론 속도를 최대화합니다.
make download_model BENCHMARKS=retinanet
make download_data  BENCHMARKS=retinanet
make preprocess_data BENCHMARKS=retinanet
전처리 결과는 $MLPERF_SCRATCH_PATH/preprocessed_data 에 저장됩니다

2.10 엔진 생성 + 벤치 실행

이 단계는 실제로 추론을 수행하는 단계입니다.

MLPerf 실행은 크게 두 흐름으로 나뉩니다:

단계명령설명
A. 엔진 생성 (사전 컴파일)make generate_enginesTensorRT가 모델을 GPU 아키텍처(SM)에 최적화된 실행 형식 (*.plan 엔진 파일)으로 변환합니다. 시간 오래 걸릴 수 있음
B. 하네스 실행 (실제 측정)make run_harnessLoadGen 규칙에 따라 Offline / Server 시나리오를 수행하여 실제 성능 결과(QPS, Latency)를 얻습니다.
C. All-in-One 실행make runA + B를 한 번에 수행합니다.
# A. TensorRT 엔진만 먼저 생성 (재실행 시 성능/속도 유리)
make generate_engines RUN_ARGS="--benchmarks=retinanet --scenarios=offline,server"

# B. LoadGen 기반 성능 측정 실행 (QPS/Latency 결과 산출)
make run_harness RUN_ARGS="--benchmarks=retinanet --scenarios=offline,server"

# C. 한 번에 실행 (엔진 생성 + 측정)
make run RUN_ARGS="--benchmarks=retinanet --scenarios=offline,server"

Server 시나리오 주의
Server 모드는 실시간 요청 처리 조건이 포함되며,

  • 목표 Latency 만족 못하면 INVALID가 발생합니다.
  • QPS 수치를 무리하게 높이면 실패율 증가 & 규정 위반이 되므로
    → Batch, Streams, Workspace Size는 점진적으로 튜닝

2.11 테스트 Configuration 수정하기

MLPerf는 /configs/retinanet/Offline 경로에 각 시나리오별 설정 파일을 사용합니다.
내 서버 환경(L40S, A100 등)에 맞게 /configs/retinanet/Offline/custom.py를 작성하면 됩니다.

/work/configs/retinanet/Offline/custom.py

예시 코드

from code.common.constants import Benchmark
from code.common.systems.system_list import KnownSystem
from configs.configuration import ConfigRegistry, OfflineGPUBase, HarnessType, AccuracyTarget, PowerSetting

# 내 시스템 ID (custom_systems.add_custom_system 실행 후 생성된 이름으로 교체)
SYS = KnownSystem.MyHost_L40Sx4_TRT

@ConfigRegistry.register(HarnessType.LWIS, AccuracyTarget.k_99, PowerSetting.MaxP, SYS)
class Retinanet_Offline_Custom(OfflineGPUBase):
    benchmark = Benchmark.Retinanet
    precision = "fp16"              # fp32 / fp16 / int8 중 Closed 기준 충족 값
    gpu_batch_size = 8              # GPU별 batch 크기
    offline_expected_qps = 6000.0   # 예상 QPS (스케줄러 힌트용)
    workspace_size = 8 << 30        # TensorRT 워크스페이스 크기 (8GiB)
    use_graphs = True               # CUDA Graphs 사용 (성능 향상)
    start_from_device = True        # 입력이 GPU에 이미 올라와 있다고 가정
    gpu_inference_streams = 2       # GPU 병렬 스트림 수
    gpu_copy_streams = 1            # HtoD 복사 스트림 수
    numa_config = "all"             # NUMA 전체 사용
    num_warmups = 200               # 워밍업 반복 수

💡 Tip:
시스템에 따라 gpu_batch_size → gpu_inference_streams → offline_expected_qps 순으로 점진적으로 조정하며 로그에서 QPS가 증가하는 방향으로 튜닝하세요.

2.12 결과 로그 확인

cd build/logs
ls -l *log_summary*.txt
cat *_log_summary*.txt

결과 로그는 build/logs 위치에서 확인할 수 있으며, 해당 로그에는 사용된 configuration과 결과값이 있습니다.

체크 항목이유
VALID / INVALIDServer 조건 미충족 여부 확인
Offline QPS최대 처리 능력 척도
P95 / P99 Latency (Server)실시간 성능 기준
엔진/배치 설정 기록재현성 확보 및 튜닝 근거

마무리하며

MLPerf Inference는 단순한 GPU 성능 벤치마크를 넘어,
AI 인프라 전체의 효율성과 시스템 설계 품질을 검증하는 사실상의 표준입니다.

이번 가이드를 따라 실행하면, 단일 GPU 서버부터 멀티 노드 클러스터까지 객관적이고 재현 가능한 추론 성능 측정을 직접 수행할 수 있습니다.
또한 Retinanet뿐 아니라 BERT, ResNet50, 3D-Unet 등으로 확장해 다양한 워크로드를 테스트할 수도 있습니다.