최신 CPU에서 BERT와 유사한 모델의 추론 확장 - 파트 2
TL;DR
Hugging Face는 메모리 할당자, 병렬화 라이브러리, 그리고 Bayesian optimization의 사용과 같은 소프트웨어 구성 요소를 최적화함으로써 Intel Ice Lake Xeon CPU에서 BERT와 유사한 모델의 추론 성능을 크게 향상시킬 수 있음을 입증했습니다. 이러한 최적화는 AVX-512 및 VNNI와 같은 하드웨어 기능과 결합되어 CPU 기반 인프라에서 NLP 워크로드의 더 효율적인 확장을 가능하게 합니다.
AI 효율성을 위한 Intel 소프트웨어 활용
Intel 하드웨어에서 AI 워크로드의 성능을 극대화하기 위해 개발자는 Intel oneAPI 제품군 아래의 소프트웨어 최적화 스택을 활용할 수 있습니다. 이러한 도구들은 PyTorch 및 TensorFlow와 같은 고수준 프레임워크와 기본 CPU 아키텍처 사이의 간극을 메우기 위해 설계되었습니다.
주요 소프트웨어 구성 요소
- Intel oneMKL (Math Kernel Library): 매우 효율적인 선형 대수 루틴을 제공합니다.
- Intel OpenMP 및 oneTBB (Threading Building Blocks): 계산의 고수준 병렬화를 위한 프레임워크입니다.
- Intel oneDNN: PyTorch 및 TensorFlow(버전 2.5.0부터)에 기본적으로 통합된 딥 뉴럴 네트워크 프리미티브(예: ReLU, fully-connected layers) 라이브러리입니다.
- Intel PyTorch Extension (IPEX): 주요 PyTorch 라이브러리에 업스트림되기 전에 최적화를 위한 실험실 역할을 하는 전문화된 프레임워크입니다.
CPU 추론을 위한 성능 튜닝 노브(Knobs)
추론 성능은 주로 세 가지 요소에 의해 결정됩니다: 메모리 내 데이터 표현, 수학적 연산자의 구현, 그리고 병렬화의 효율성입니다.
메모리 할당 및 관리
메모리 할당(OS로부터 동적 메모리를 요청하는 프로세스)은 속도와 단절편화(fragmentation)에 영향을 미를 수 있습니다. glibc와 같은 기본 할당자는 범용적이지만, 전문화된 할당자는 멀티스레드 딥러닝 워크로드에서 동기화 오버헤드를 줄일 수 있습니다:
- tcmalloc (Google): 각 스레드에 로컬 메모리 세그먼트를 유지하여 글로벌 크리티컬 패스를 줄임으로써 다양한 워크로드에서 종종 가장 좋은 성능을 제공합니다.
- jemalloc (Facebook): 특정 저전력/저동시성 상황에서 가장 빠를 수 있습니다.
- mimalloc (Microsoft): 메모리 관리를 개선하기 위한 또 다른 대안입니다.
계산의 병렬화
여러 CPU 코어를 효율적으로적으로 활용하려면 단순히 코어 수를 늘리는 것 이상의 것이 필요합니다. CPU 캐시 무효화 및 동시 데이터 액세스와 같은 요소는 확장을 방해할 수 있습니다. Hugging Face는 스레드 디스패칭 및 리소스 바인딩을 최적화하기 위해 Intel 하드웨어에 OpenMP 사양의 Intel 구현체("IOMP")를 사용할 것을 권장합니다.
최적화된 수학적 연산자
최신 CPU는 클록 사이클당 여러 항목을 처리하는 SIMD (Single Instruction Multiple Data) 명령어를 사용합니다. Intel CPU는 SSE2, AVX, AVX2, 및 AVX-512를 지원합니다. Intel MKL 및 oneDNN과 같은 라이브러리는 이러한 연산자를 효율적으로 구현하여 Linear + ReLU 또는 Convolution과 같은 일반적인 패턴에 대한 성능 향상을 가능하게 합니다.
Intel Ice Lake Xeon CPU에서의 벤치마크
벤치마크는 Ubuntu 20.04.2 LTS 환경의 Intel Ice Lake Xeon Platinum 8380 CPU를 사용하여 PyTorch 1.9.0 및 TensorFlow 2.5.0를 다양한 배치 사이즈(1에서 128까지)와 시퀀스 길이(8에서 512까지)에 대해 테스트했습니다.
Eager vs. Graph Mode
- Eager Mode (PyTorch, TensorFlow): 계산 그래프는 실행 중에 발견됩니다. 이는 유연성을 제공하지만 런타임 오버헤드를 유도하며 연산자 융합(예: Convolution + ReLU)을 더 어렵게 만듭니다.
- Graph Mode (TorchScript, TensorFlow Graph, Intel TensorFlow): 그래프를 사전에 미리 알고 있으므로 가지치기(pruning), 연산자 융합, 그리고 사전 계획된 메모리 할당이 가능합니다.
확장에 대한 주요 결과
- **코어 확장성(Core Scaling): 단일 코어 수의 증가가 일반적으로 지연 시간을 감소시키지만, 반드시 단조적으로 감소하지는 않습니다. 워크로드 크기와 할당된 리소스 사이에는 트레이드오프가 있습니다.
- Inter-Socket Overhead: 여러 CPU(멀티 소켓)가 있는 시스템에서 모든 코어를 사용하면 소켓 간 통신으로 인해 상당한 지연 시간 오버헤드가 발생할 수 있습니다.
- Allocator Impact: 메모리를 동적으로 관리해야 하는 eager mode에서는 리소스를 미리 예약할 수 있는 graph mode에 비해 할당자(예: tcmalloc)의 선택이 성능에 더 뚜렷한 뚜렷한 영향을 미칩니다.
Intel SigOpt를 이용한 자동 성능 튜닝
최적의 설정에 대한 탐색 공간이 매우 방대하기 때문에(코어 수, 메모리 할당자, 병렬화 라이브러리, Transparent Huge Pages, KMP block time의 조합), 무차별 대입 방식의 튜닝은 비효율적입니다. Hugging Face는 Bayesian optimization을 사용하여 최적에 가까운 구성을 찾기 더 빠르게 찾는 Intel SigOpt를 활용했습니다.
SigOpt 결과
- 효율성: SigOpt는 무차별 대입 방식의 결과와 매우 유사한 성능을를 제공했습니다. 가장 큰 차론은 8.6%였습니다.
- Parameter Importance: 코어 수는 일관적으로 가장 중요한 파라미터입니다. 하지만, 더 큰 시퀀스 길이(예: 512)의 경우, 병렬화 라이브러리(OpenMP vs. Intel OpenMP)의 선택이 메모리 할당자보다 상대적으로 더 중요해집니다.
- Resource Optimization: SigOpt는 더 적은 코어(예: 16 코어)를 사용하는 것이 때때로 최적의 지연 시간을 제공할 수 있음을 식별했습니다. 이를 통해 여러 모델 인스턴스를 병렬로 실행하여 전체 처리량을 개선할 수 있습니다.
결론
Intel Ice Lake Xeon CPU에서 프로덕션 환경을 위한 BERT와 유사한 모델을 최적화하는 것은 계층적 접근 방식이 필요합니다: 저수준 하드웨어 기능에서 시작하여, 프레임워크 특정 최적화(oneDNN와 같은)로 이동하고, 마지막으로 메모리 할당자 및 OpenMP 구현체와 같은 시스템 수준의 노브를 튜닝하는 것입니다. 이러한 노력은 Hugging Face Optimum 라이브러리와 Infinity 제품에 통합되어 고효율 컨테이너화된 추론 솔루션을 제공합니다.