이제 딥러닝 모델의 크기가 점점 커지고 있다.
따라서 당연하게도 연산량과 파라미터 수도 증가한다. 이는 메모리, 계산 자원, 배터리 등에 부담을 준다.
Vision 분야, NLP 분야 둘 다 그렇다.
따라서 이에 대해 두 가지 해결책을 제시했다. 당연히 이 둘의 목적은 모델 사이즈 축소+계산 효율성 향상+적은 에너지 사용이다.
1. Pruning
보라 : 걍 단순 가지치기, 초록 : 가지치기 하고 성능 하락 보완 위해 재학습, 빨강 : 가지치기-재학습-가지치기 ...
불필요한 연결(synapse)이나 뉴런을 제거하는 가지치기 기법이다.
인간의 뇌에서도 자연스럽게 pruning이 수행된다.
보통 2-4살 때는 사물의 어떤 것을 기억해야 할지 잘 모르기 때문에 모든 것을 기억하려 한다.
이때 synapse per neuron이 가장 크고, 이후로 갈수록 줄어든다.
그렇다면 가지치기를 하면서도 성능을 유지할 수 있는 방법을 생각해봐야 할 것이다.
어떤 패턴으로, 어떤 기준으로, 각 레이어에 대해 얼마나 제거할지, 제거 후 어떻게 다시 성능을 회복할지 등등..
Problem formulation
original weights를 W, pruned weights를 Wp라 하자.
이때의 목표는 ||Wp||0, 즉 0이 아닌 weight의 수 = N이 되도록 weight를 sparsify하는 것이다.
Pruning granularity(세분성)
Fine-grained/Unstructured : 단일 weight 수준에서 선택적으로 제거, 유연하지만 가속기에 적합하지 않다.
Coarse-grained/Structured : 필터나 채널 단위로 제거하는 것, 가속기에 적합.
ci : output channels, ci : input channels, kh : kernel size height, kw : kernel size width
그리고 다양한 종류의 prunig.. 이 각 방식은 trade-off가 존재함. 성능이냐 계산 효율성이냐
Fine-grained Pruning
제거 위치를 자유롭게 정할 수 있기에 더 많은 압축이 가능하다.
하지만 HW 최적화에 불리하고, 계산 흐름이 비정형이어서 병렬화가 어렵다.
Pattern-based Pruning
특정 sparsity pattern을 강제함으로써 HW 가속기 호환이 가능하다.
N:M sparsity : M개의 연속 weight 중 N개를 제거하는 방식. 만약 2:4 sparsity라면 4개 중 2개 제거, 즉 50% sparsity
Channel-level pruning
Conv layer에서 입력 또는 출력 채널 단위로 제거하는 방식이다.
채널 수가 감소하기에 직접적인 연산량 자체가 감소하는 장점이 있지만, 압축 비율이 낮을 수 있다는 단점도 있다.
Pruning criterion
이건 어떤 연결을 제거할지 결정하는 기준에 대한 내용이다.
기준이 좋아야 성능 손실이 적다. 여기서 핵심은 '덜 중요한 것부터 제거하자' 이다.
Magnitude-based pruning
가장 흔히 쓰이는 기준으로,
당연히 가중치가 가장 0에 가까운 것이 영향력이 작은 feature일 것이니, 절댓값이 작은 weight를 제거하는 것이다.
Row-wise magnitude 기준(L1-norm)이면, norm이 작은 row를 제거하게 된다.
그럼 비슷하게, row-wise 기준(L2-norm)이라면, l2-norm이 작은 row를 제거하게 되는 것인데, 제곱 기반이므로 큰 weight에 더 민감하게 반응한다.
Selection of neurons to prune
이건 weight가 아니라 뉴런 자체를 제거하는 방식이다.
Coarse-grained 방식 중 하나로, 뉴런의 중요도를 판단해 덜 중요한 뉴런을 제거하는 것이다.
Percentage-of-zero-based pruning
ReLU같은 비선형 함수는 0 출력을 많이 생성한다.
APoZ, 즉 뉴런의 출력 중 0이 된 횟수 / 전체 출력 수 를 보면 뉴런의 중요도를 알 수 있다.
왜냐면 뉴런이 0이 되는 경우가 많으면, 즉 APoZ가 크면, 뉴런이 잘 활성화되지 않는다는 뜻이다
그 반대로 APoZ가 작으면, 잘 활성화되는 뉴런으로, 다양한 입력에서 의미 있는 출력을 내는 뉴런이라고 해석할 수 있다.
그 예시로 아래 사진을 보자. channel 별로 APoZ를 계산하여 가장 큰 APoZ를 가진 channel은 빼는 것이다.
Pruning ratio
Layer마다 중요도가 다르기에 일괄적으로 같은 pruning 비율을 적용하면 안된다.
어떤 레이어는 민감하고, 어떤 레이어는 중복이 많고.. 등등의 이유로 말이다.
따라서 layer-wise로 감도 분석이 필요하다.
Sensitivity Analysis
1. 특정 레이어 Li를 선택한다.
2. 다양한 가지치기 비율로 가지치기를 수행한다.
3. 각 비율에 대해 성능 저하를 관찰한다.
4. 이를 모든 레이어에 대해 반복한다.
5. 전체 pruning budget 안에서 가장 성능이 좋은 조합을 선택한다.
혹은 그래프에서 정확도의 threshold를 정해 그정도까지 pruning을 한다.
Automatic pruning
기존 sensitivity 분석은 layer간 상호작용을 무시했었는데, 자동화된 접근법, 강화학습 기반으로 layer별 pruning ratio를 자동 결정하는 방식
Fine-tuning
pruning 후 성능 하락 가능성이 있기에 파인 튜닝으로 성능을 회복하는 경우가 많다. pruning을 세게 할수록 fine-tuning이 중요하다.
Iterative Pruning
pruning->fine-tuning 반복!
가지치기를 한 번에 많이 하지 않고 점진적으로 제거 비율을 증가한다. 이는 학습 성능을 유지하면서 압축률을 높일 수 있다.
2. Quantization
부동소수점 숫자를 더 적은 비트로 표현하여 경량화하는 기법이다.
메모리는 비싸고, 낮은 비트 너비의 연산은 더 저렴하고 빠르다.
부동소수점 값을 -> 고정된 수의 대표값으로 매핑하는 것. 예를 들어, 연속형 그래프를 이산형 그래프로 바꾸는 것!
이렇게 되면 저장 용량이 대폭 감소하게 된다.
그치만 아직은 계산이 대부분 float로 수행되기에 저장공간 최적화만 가능한 것이다.
K-means 기반 Weight Quantization
weight를 clustering한다. 각 클러스터의 중심이 대표값이 된다. 이 값들로 weight를 대체하는 것이다.
이 방법은 저장은 적게 들지만, 계산은 여전히 float 연산 기반이다. 실제 실행 시에는 lookup table에서 값을 찾아 계산하기에 연산량은 그대로이다.
Linear Quantization
이는 정수-실수 간 변환을 선형 함수로 매핑하는 것이다.
실제 실수값 = scale factor * ( quantized int - Zero point )
이런 식으로 말이다. 보통 정수 0이 실수 0에 매핑되도록 Z를 조정한다.
Per-tensor : 전체 텐서에 하나의 scale과 zero-point를 사용하는 것
Per-channel : 각 채널마다 다른 scale/zero-point를 사용하는 것 -> 정밀도 향상 가능, loss 낮아짐
Post-training quantization
Activation quantization
입력에 따라 출력 범위가 다르기 때문에, 이를 정수로 변환하기 위해 범위를 파악해야 한다.
두 가지 방식이 있는데,
1. Training 중에 EMA(지수 이동 평균)으로 구하는 방법과,
2. batch의 몇몇 샘플의 min/max값의 평균을 사용하는 방법이다.
Quantization bias correction
양자화는 작은 오차를 만들고, 이게 누적되어 이상해지는데, 이를 해결하려 한다.
이 오차를 보통 unbiased라고 생각하고 이를 보정(bias correction)하면 더 정밀한 양자화가 가능할 것이다.
Binary Quantization
weight를 1, -1로만 구성하는 경우이다.
근데 만약 여기에 Binary Activation까지 합쳐지면? 전체 연산이 아예 극도로 단순해진다. weighted sum 을 계산할 때 연산이 -1이나 +1 밖에 없는 것...
이건 그냥 정수 덧셈/곱셈도 필요없고 XNOR, bit count 연산으로도 충분하다. 그래서 속도가 엄청나게 상승한다.
당연히 정확도 측면에서는 손해가 많지만.. 극도로 경량화된 시스템에서는 적합하다.
특히 자원의 제약이 있는 환경에서 유용하게 쓰일 수 있다.
딱 봐도 숫자가 간결함!
Incremental network quantization
weight들을 한 번에 양자화하지 않고, 조금씩 나눠서 양자화하는 경우이다. 점진적으로 양자화를 시켜서 더 좋은 정확도를 낼 수 있다.
얘는 일단.. fp32에서 시작해서 weight를 두 그룹으로 나눈다. 큰 그룹만 먼저 양자화하고, 나머지는 학습으로 보정시킨다.
위 과정을 반복하며 50%->75%->87.5%->100% 의 양자화를 진행한다.
'AI > 딥러닝' 카테고리의 다른 글
RNN and Transformer (3) | 2025.06.19 |
---|---|
CNN applications and RNN (1) | 2025.06.18 |
CNN (1) | 2025.06.18 |
Numerical Stability, Optimization (1) | 2025.04.24 |
Regularization (1) | 2025.04.24 |