Naver Engineering Day 2023 - AI 경량화: 더 빠르고 저렴한 AI 서비스
AI 경량화: 더 빠르고 저렴한 AI 서비스
https://www.youtube.com/watch?v=NVNCPGWe5Ss
Naver Biz CIC / AI Serving Dev
- Inference Latency
- 서버 부하
- 전력소모 효율
- ...
모델의 아키텍처가 성능을 좌우하는데, 서비스 상황에 맞춰 아키텍처 자체를 실험적으로 바꾸며 최적값을 찾기 위한 작업은 어렵다.
- 아키텍처를 고정한 채, 효율성을 더 높이기 위한 삽질기.
실험에 사용한 조건 중 num_thread 고정
- dynamic allocation에서 발생하는 속도차이 무시하기 위함.
- 같은 모델이라도 다소 느린 속도.
경량화 이론은 매우 어렵지만, 서비스 적용을 위한 코드 수정은 (이론에 비하면) 쉬운 편이다.
AI 모델 트렌드는 '더 큰 모델, 더 많은 파라미터로 더 좋은 성능을 낸다'.
- NLP / CV 가리지 않고 같은 추세.
예컨대 inference에만 500ms가 필요한 모델이 있다고 하자. 서비스를 위한 목표치는 150ms.
- 별다른 모델 아키텍처 수정 없이, 정확도 손실 없이
- 각종 최적화 방법을 써서 모델 응답속도를 125ms 정도로 4배 향상시킬 수 있다면?
클로바에서 만든 LaRva 베이스 모델의 경량화 버전을 사용한 PoC.
- batch 수행 시 평균 175ms 정도의 inference latency.
- 이 정도면 실시간 서비스에 적용하기는 쉽지 않음.
compressed model을 사용하면, inference latency가 45ms. 대략 4배의 성능향상이 있다.
- 실시간 서빙이 가능한 정도로 경량화.
학계의 경량화 트렌드는 대략 위와 같음.
- 이 중에서는 Pruning / Low-Rank 기법이 가장 활발하게 연구중.
- Quantization / Knowledge Distillation은 가끔 유의미한 기법이 소개되는 중
1. Quantization
경량화 기법 중 제일 먼저 적용해볼만 함.
- 적용이 쉽고 리소스도 적게 들어가지만
- 효과는 높은 편
pytorch 기준, 2~3배 정도의 inference speed 향상이 가능함.
- Dynamic Quantization은 코드 4줄.
- Static Quantization은 모델 Layer 구조를 이해하고 있다면 그다지 어렵지 않음
원래 signal processing 계열에서도 자주 쓰이던 아날로그 -> Binary로 signal 전환하는 원리를 적용함.
- float32 -> int8 바꾸는 것만으로도 모델 크기는 4배 감소, 속도는 2~3배 빨라짐.
- framework-agnostic한 기법이므로 안정성, 신뢰성 문제도 발생하지 않음.
Pruning 기법으로 인한 성능 향상에도 독립적임 - 서로 정확도에 악영향을 미치지 않음. (2016년 논문)
실제 적용 시 겪는 troubleshooting은 크게 두 가지.
- Unsupported Layer
- 특정 op kernel / layer에서 not supported -> 직접 추가.
- torch.jit.script 모듈로 wrapping되어 있을 경우 실패함
- jit.script 모듈로 변환하기 전에 미리 quantization을 적용하는 것밖에 방법이 없음
2. Pruning
가장 활발히 연구중이며 포텐이 높은 분야. 단 적용까지 삽질할 가능성도 높음
- 기본 방식: "완성된 모델 내부의 Layer를 타고 내려가며 Target Sparsity에 맞는 함수를 사용한다"
개념적으로는 위와 같은 그림이 자주 언급되므로, 모델이 단순화되거나 / 파라미터 개수가 줄어든다고 이해할 수 있으나
실제로 적용해보면 파라미터 개수는 그대로임.
- 이론과 달리, 실제로 파라미터를 없애는 게 아니라 zeroing-out (원래 가지고 있던 파라미터 값을 0으로 만든다) 방식을 쓰기 때문.
- 모델의 내부 tensor를 보면
- 오른쪽: Dense (모든 행렬의 가중치가 0이 아님)
- 왼쪽: sparsity (예컨대 90%라면, 행렬 파라미터 중 0이 차지하는 비율이 90%)
즉 tensor shape에는 문제 없음.
sparse한 행렬 연산은 일반적인 행렬 연산인 GEMM (General Matrix Multiply) 과 완전히 다른 SpAMM (Sparse Approximate Matrix Multiply)이 사용됨.
- cpu / gpu instruction에 따라 최대 1100% 이상 차이날 수 있음.
- 실험 근거도 있음.
그런데 실제로 써보면 pruning 하고 나서 연산속도가 두 배는 느림. 심지어 자주 발생함.
- masking된 original weight가 있는지 확인하고, original weight를 프레임워크에서 지워준다.
- pruning하면 모델이 original / pruning 된 weight 두 개를 들고 있음. 기존의 가중치 지워줘야 함.
- 그래도 해결이 안 된다? -> tensorflow / pytorch에서 기본적으로는 SpAMM을 지원하지 않기 때문.
- SpAMM을 지원하는 math 라이브러리 설치. (동작할 하드웨어에서 지원하는 걸로.)
이런 이슈들을 해결해야 연산 속도 향상을 체감할 수 있음.
Naive한 pruning를 해버리면, accuracy / precision 등 중요 성능지표가 실제로 하락하는 모습을 볼 수 있음.
그런데 왜 논문에서는 기본적으로 모델은 over-parameterized되어 있으며, 'pruning'의 정확도가 큰 차이 없다고 말하고 있을까?
Over-parameterized된 것들을 찾아내는 기법들이 속속 등장하는 중.
- 쓸모없는 가중치는 제거, 필요한 것들만 남기면 성능이 유지된다.
- 효과가 있음을 확인한 논문이 있음.
빠른 적용으로는 iterative pruning 기법을 추천.
- 완성된 모델을 target-sparsity로 pruning
- 3 epoch 정도 retrain
그리고, 그래프를 잘 보면 '정확도가 향상된' 수치가 나옴.
- over-parameterized를 주장하는 근거로 쓰인다.
흥미로운 건, 인간 뇌 뉴런과 시냅스 개수도 위와 비슷한 추세를 따라간다는 것.
- 생후 2~4년 즈음에는 뉴런 하나당 연결된 시냅스 개수가 15,000개에 달하지만
- 나이를 먹으면 점차 연결된 시냅스 개수가 감소해서 7,000개 정도 -> 반토막.
- 그러나 전반적인 지식수준이나 정확도 등에서는 일반적으로 성인의 두뇌가 아이보다 월등함.
딥러닝 모델도 이와 비슷할 것이라고 주장하는 학자들이 꽤 많음.
Pruning된 모델은 그렇지 않은 모델에 비해 3배 더 빠르고, 전력소모가 7배 적다.
3. Low-Rank Methodology
가장 먼저 적용해볼 만한 기법은 Low-Rank Approximation - 행렬 근사.
- SVD (Singular Value Decomposition)
- bottleneck convolution operation의 연산속도 2~3배 향상.
- 메모리 사용량을 5~13배까지 줄일 수 있음을 2014년 논문에서 발표함.
단 행렬 분해기법인 만큼 선례가 잘 없고, 최적화가 어려울 수 있어서 stable service에 적용하기는 쉽지 않음.
- LoRA (Low-Rank Adaptation) 등 신기법이 LLM에 적용되면서
- 아주 적은 양의 parameter retrain만으로도 base model의 응답값을 personalized할 수 있다는 점이 확인됨.
4. Knowledge Distillation
실서비스 도입 직전에 적용을 고려해볼만한 것.
더 크고 정밀한 Teacher Model에서 학습한 weight를 더 작은 student model로 전이시키는 것.
- 같은 도메인 내에서 모델 지식을 전달 - Model Compression 효과
- transfer learning과 비슷해 보이지만, transfer learning은 서로 다른 도메인에서 지식을 전달하는 방식.
그런데, 'Weight 전이' 보다는 '정확도 보강' 목적으로 더 쓰인다. 완성된 모델의 Self-Distillation 형태로.
- 학습, 경량화 기법까지 전부 적용한 '완성된 모델'을 retrain해서 1%의 정확도라도 높이는 기법임.
- 하이퍼 파라미터 / 모델의 구조 변경보다 훨씬 적은 비용으로 성능을 올릴 수 있다.
모델 구조가 조금만 달라도 효과를 보기 쉽지 않기에
일반적으로는 Teacher -> Student 방식의 Knowledge Distillation은 효과가 없거나 역효과 나는 경우도 종종 있음.
- 제대로 효과를 보려면 상당한 리소스가 필요함.
그래서, 완성된 모델의 Self-Distillation 형태로 쓴다.
모델 경량화 Risk / Benefits
전력 이슈.
- AI model도 CPU / GPU / TPU 등 특정 리소스 위에서 프로세스를 통해 연산한 결과물 - 전력소모 / 비용 이슈.
- 같은 32bit여도 type에 따라 연산에 필요한 리소스 양이 다르다.
- int ADD: 0.1[pJ], float ADD: 0.9[pJ]. 9배 차이
- 모델 파라미터 타입만 바꿔도 전력소모량이 훨씬 적다
더 빠른 inference, 하드웨어 장비에도 더 적은 부하.
물론 Naive한 경량화는 성능 하락으로 이어지지만, 검증된 기법을 잘 사용하면 됨.
- AI모델 경량화는 새로운 기법이나 연구결과가 꾸준히 나오고 있는 분야.
Risk?
데이터셋, 모델 아키텍처에 따라 완전히 다른 결과를 내놓기 때문에, 특정 모델에서 효과적인 기법이 다른 모델에서는 역효과가 나는 경우도 있음.
- Pruning? 특정 뉴런이나 시냅스에 핵심 정보가 몰려 있는 경우, 그 부분이 잘려나가면 속도 이점은 없고 정확도만 낮아짐
- Quantization? int 타입으로 변환했을 때 개별 파라미터의 정보 손실이 크다면 효과 없음
- Knowledge Distillation? teacher / student 모델 구조 다르면 효과를 보기 힘듬
아직 전반적으로 성숙하지는 않은 분야.
- 노하우에 의존하는 경향, 정형화된 방법이 아직은 없음.
Benefits?
성능변화와 속도변화를 예측하고, 설명할 수 있다.
- 완성된 모델을 분석하는 과정이 반드시 수반되기 때문에, 적용 시의 추이를 예측할 수 있음.
- 예측한 대로 동작하지 않을 때 기술적 해석이 가능하고, 개선 지점을 명확히 특정할 수 있음.
- 불확실성 감소 - stable
직관적이고 안정적인 output
- Accuracy 변화 / inference latency / resource usage 변화 등은 누구나 쉽게 이해할 수 있음.
- 검증된 모델을 바꾸지 않은 채 개선하는 방식
확장성 / 지속성
- 서비스 가능한 모델에도 추가 비용절감, 확장성, 더 많은 Traffic intake 가능.