Paper : https://arxiv.org/pdf/2312.00858
Github : https://github.com/horseee/DeepCache
DeepCache : training 없이 Diffusion 모델을 가속화하는 새로운 방법
DeepCache는 Diffusion 모델의 연속적인 Denoising Step 속에서 일관되게 나타나는 Feature가 있다는 것을 바탕으로, 일관적인 Feature를 매번 계산하지 않고 한번 계산한 후 캐시처럼 저장해두고 다음 단계에서 그대로 불러와서 쓰는 방법임
DeepCache는 Diffusion 모델이 사용하고 있는 U-Net 구조의 특성을 살려, High-level Feature들(일관되게 유지되는 Feature들)은 재사용하고, Low-level Feature들만 싸게 업데이트해서 사용함
DeepCache는 매우 좋은 성능을 가지고 있음
속도는 빨라지되, Output Quality는 유지함
Stable Diffusion v1.5에서는 2.3배 빨라짐
CLIP Score은 0.05만 감소함
LDM-4-G에서는 4.1배 빨라짐
ImageNet에서 FID는 0.22만 감소함
기존에 존재하는 방법들(Pruning, Distillation 등)보다 뛰어남
기존에 존재하는 방법들은 Retraining 과정이 필요하지만 DeepCache는 Retraining이 필요 없음
DeepCache는 기존 Sampling 방법들과 함께 쓸 수 있음
(같은 처리량에서도 DDIM, PLMS만 쓸 때보다 DDIM + DeepCache, PLMS + DeepCache 방법이 훨씬 뛰어난 결과를 보여줌)
Cache
: 반복적으로 데이터를 불러오는 경우에, 지속적으로 DBMS 혹은 서버에 요청하는 것이 아니라 Memory에 데이터를 저장하였다가 불러다 쓰는 것
(참고하면 좋을만한 사이트)
Diffusion Model의 무한한 확장성에도 불구하고, 항상 대두되는 고질적인 문제점은 바로 Inference Time임
Step-by-step Denoising Process를 거쳐 이미지를 생성하므로, 시간이 너무 오래 걸림
그래서 보통 Diffusion을 가속화하기 위해서는 2가지 방법을 많이 씀
본 논문에서는 두 번째 방법처럼 각 Denoising Step마다 Model Inference Overhead를 줄여서 Diffusion 모델을 최적화하는 것이 목표임
기존 두 번째 방법들은 가속화하기 위해 보통 모델 구조를 재디자인하는데, 이렇게 모델 구조를 바꾸려면 또 대규모 데이터셋을 이용해서 경량화된 모델을 재학습시키는 과정이 필요함
뭐 다른 방법이더라도 무조건 어떤 방법이든 재학습시키는 과정은 필요함
그렇기 때문에 본 논문에서 집중해서 해결하고자 했던건 이거임
How to significantly reduce the computational overhead at each denoising step without additional training, thereby achieving a cost-free compression of Diffusion Models?
어떻게 하면 추가적인 학습 과정 없이도 각 Denoising 단계에서 Computational Overhead를 크게 줄일 수 있을까? 그리고 어떻게 추가 비용 없이 Diffusion 모델을 경량화할 수 있을까?
그래서 본질적으로 Reverse Denoising process 자체에 집중하기로함
그럼 어떻게 Denoising Process를 이용해서 Efficiency하게 만들 수 있을까?
Denoising Process를 보면, High-level Feature들이 유지되는 것을 볼 수 있음

이 그림에서처럼 High-leve Features 즉, 곰돌이, 케이크, 밥 모양은 step 0 부터 나타나고 step이 늘어나도 일관적으로 계속 유지됨
그래서 본 논문의 핵심 아이디어는 이렇게 step마다 유지되는 High-level Feature들을 한번만 계산해서 cache처럼 저장해두고, 매 subsequent 단계들마다 불러와서 쓰자는거임
그리고 다행히 이런 High-level Feature들은 cacheable 하기 때문에, 한번만 계산한 후에 다음 step에서 다시 가져와서 사용할 수 있음
또 다행히 Diffusion Model에서 쓰이는 U-Net 구조가 구조상 각 Denoising step마다 High-level Feature들을 유지한 채로, Low-level Feature들만 업데이트해서 Cache 할 수 있음
이렇게 해서 Retraining 과정없이 Diffusion model의 Efficiency와 Speed를 올릴 수 있게 됐음!
추가적인 학습 과정없이 Diffusion 모델을 가속화했다!
추가 학습 과정없이 빠르게 이미지를 생성하는, Runtime 동안 Dynamically Diffusion 모델을 경량화할 수 있는 DeepCache 방법을 제안했음
High-level Feature들을 Cache하여 불필요한 연산을 줄이고, Non-uniform 1:N Startegy를 제안했음
다양한 환경에서 실험을 마쳤고, Retraining이 필요했던 기존 방법들(pruning, distillation)보다 월등하게 Efficient 하다는 것을 증명했음
*그래서 최근에 sLLM ~들을 보면 다 DeepCache를 쓰고 있더라 보여주면 좋을듯
*최근에 mLLM 학습 시도하다가 버전 맞추기가 너무 까다로워서 도대체 뭘까하고 찾아보다가 리뷰하게 됐다
*버전관련 꿀팁도 보여주면 좋을듯
Diffusion 모델이 High-dimension Image Generation이 가능하게된 건 맞지만,Denoising Step을 Reverse하는 과정때문에 고질적으로 속도 저하가 생길 수 밖에 없음
그래서 현재 연구들은 Diffusion 모델을 가속화하기위해 2가지 방법에 집중하고 있음
Sampling Step의 수를 줄이는 방법
각 Sampling Step마다 걸리는 Inference 시간을 줄이는 방법
본 논문에서는 두 번째 방법으로 접근하고 있음
Diffusion 모델은 Forward Process와 Reverse Process로 이루어져있음
Forward Process

Reverse Process

U-Net 구조의 특성 상 High-level Feature와 Low-level Feature를 잘 결합함

Diffusion 모델은 U-Net 구조를 따르므로, 이런 U-Net의 특성을 이용해서 High-level Feature만 Caching 한 후, Low-level Feature만 업데이트하여 결합할 수 있음

그래프에서보면 각 모델들마다 순차적으로 Denoising 하는 과정에서 서로 인접한 단계에서 생성된 이미지는 매우 유사한 구간이 존재함
심지어 DDPM for Lsun-Church는 최대 80%까지 높은 유사성 보임
즉, 유사한 이미지를 여러번 생성하면서 불필요한 연산을 할 필요 없단 얘기임
모델 별로 다른 유사성 패턴을 보이긴 하지만, 연속되는 스텝 간의 변화가 일반적으로 작으므로 High-level Feature를 한번만 계산해서 불필요한 연산을 줄이는 방법을 찾음
High-level Feature에 대한 Cache를 생성함

High-level Feature와 Low-level Feature를 합침


논문에서 실험한 이 HeatMap을 보면 3개의 모델 모두 대각선으로 흰색 영역(유사도가 높은 영역)이 뚜렷하게 나와있음
= 연속된 단계 간 유사도가 높다!
그래서 N step마다 High-level Feature를 캐싱하고 재사용할 수 있음
Inference를 진행해야하는 Step들을 모아서 집합으로 표현하면 다음과 같음

따라서 예를 들어, T=100, N=5 라고 가정해보자.
k = ⌈100/5⌉ = 20 # Cache를 업데이트해야하는 횟수
I = {0, 5, 10, 15, ..., 95} # Inference를 진행해야하는 Step들
# 처리 순서
Step 0: 전체 추론 (캐시 생성)
Step 1: 부분 추론 (캐시 사용)
Step 2: 부분 추론 (캐시 사용)
Step 3: 부분 추론 (캐시 사용)
Step 4: 부분 추론 (캐시 사용)
Step 5: 전체 추론 (새로운 캐시 생성)
...반복...
이렇게 5번마다 캐시가 재생성되고, 재사용되면서 Denoising이 진행됨
물론 N에 따라 결과는 천차만별이 될 수 있으므로, 적절한 N의 값을 찾는 것이 중요함!
- N이 커질수록, 계산량은 감소하지만 품질이 저하될 수 있음
- N이 작아질수록, 계산량이 증가하므로 가속화하는 의미가 없어짐
1:N Inference는 N step동안 High-level Feature는 절대! 변하지 않는다는 가정하에서 Inference를 가속화한 방법임
하지만 만약 Step 수가 늘어났을 때(N의 값이 커졌을 때), High-level Feature가 변하면 어떡하지?

이 그래프의 LDM처럼 Feature의 Smiliarity가 모든 step에서 유지되지 않는 경우도 있음
그래서 나온게 바로 Non-uniform 1:N Inference 임
원래 1:N Inference에서는 N을 정해서 모든 구간에서 균일하게 Inference하는 Step을 정했다면, Non-uniform 1:N Inference는 유사도가 낮은 구간에서 더 자주 Sampling 할 수 있도록 하는 방법임
아래 수식은 유사도가 낮은 구간 근처에서 더 밀도있게 Sampling step을 늘린 Inference step의 집합을 표현한 수식임
이 중에서 L 은 유사도가 크게 감소하는 Step을 중심으로 삼고 이 중심점을 기준으로 전체 step을 균등하게 나누는 집합을 의미함

linear_space(start, end, number of sampling step) : start에서 end까지 균일하게 number of sampling step으로 나눠서 집합으로 저장하는 함수여기서 p의 값을 결정하는 방법은?
모델의 특성에 따라 p 값은 달라질 수 있으므로, 일단 p=2, p=3을 기준으로 실험하면서 최적의 p 값을 찾으면 됨
(중심점에서 p차 함수 모양으로 Sampling Step의 빈도가 변한다고 생각하면됨)
- p = 1 : 거의 균일한 샘플링
- p = 2 : 중간 정도의 비균일성
- p > 2 : 매우 비균일한 샘플링 (중심점 주변에 매우 조밀하게 있을 경우)
그리고 이 L 집합들을 가지고 균일하게 나눴던 1:N Inference처럼 Inference를 진행해야하는 Step들을 모아서 집합으로 표현하면 다음과 같음

unique_int() : 주어진 숫자들을 정수로 변환하고 중복을 제거하는 함수따라서 예를 들어, T=100, c=40, p=2, k=5 라고 가정해보자.
# 1. Linear Space의 시작점과 끝점을 먼저 계산함
start = (-c)**(1/p) # (-40)^(1/2)
end = (T-c)**(1/p) # (100-40)^(1/2) = (60)^(1/2)
# 2. Linear Space를 생성함
L = [-6.32, -2.80, 0.71, 4.23, 7.75] # k=5이므로, 5개로 균등하게 분할함
# 3. 각 지점에서 실제 Sampling Step을 계산함
I = [0, 40, 48, 58, 100] # ex. (-6.32)^2 + 40 ≈ 0
# 처리 순서
Step 0: 전체 추론 (캐시 생성)
Step 1: 부분 추론 (캐시 사용)
Step 2: 부분 추론 (캐시 사용)
...
Step 40: 전체 추론 (새로운 캐시 생성)
Step 41: 부분 추론 (캐시 사용)
Step 42: 부분 추론 (캐시 사용)
...
Step 48: 전체 추론 (새로운 캐시 생성)
Step 49: 부분 추론 (캐시 사용)
Step 50: 부분 추론 (캐시 사용)
이렇게 유사도가 낮은 step 40 근처 Sampling Step에서 더 오밀조밀하게 캐시를 재생성해서 사용함
본 논문에서 처음으로 이렇게 이전 단계와 유사도가 낮은 Sampling Step을 중심으로 그 근처에서 더욱 세밀하게 Sampling 할 수 있는 방법을 제시하고 있음
- 기존 Sampling 방법들
- Uniform Sampling : 균일하게 Sampling하는 방법
(거의 대부분 사용하고 있는 방법)- Exponential Sampling : 초기에는 촘촘하게, 나중으로 갈수록 간격이 지수적으로 증가하는 Sampling 방법
(Fast Sampling of Diffusion Models with Exponential Integrator,
Denoising 과정 중 초기 단계에서 더 중요한 변화가 일어나는 Diffusion 모델에 맞게 Sampling Step 방법을 고려한 논문)
하지만 본 논문에서는 p=2로 설정했을 때, 결과물이 잘 나오긴 하지만 이 방법 외에도 p의 값을 변경하거나 다른 분포를 사용해도 비슷하게 좋은 결과를 낼 수 있을 것이라고 얘기하고 있음
여기서 중요한 것은
유사도가 낮은 c를 중심으로 그 근처에서 조밀하게 Sampling을 진행해야한다는 아이디어고, 여기서 근처 분포값을 계산하는 건 다양할 수 있다는 것!
본 논문에서는 Deep Cache를 사용하면 Inference Speed가 얼마나 개선되는지 실험했음
Cache를 사용해서 일부만 Inference해서 사용하고 U-Net 구조에서 Skip Connection을 기준으로 일부 Layer를 제거해서 사용했더니 눈에 띄게 Inference Speed가 올라갔다고 함
여기서 skip branch를 정하는 기준을 설명할 예정임
이 그림은 Stable Diffusion과 DDPM의 각 Branch에서 발생하는 연산량에 대한 그래프임

이 그래프를 보면 각 모델에서 가장 연산량이 많은 branch를 확인할 수 있고, branch 간의 연산량 분포를 알 수 있음
이 그림에서 각 색깔 그래프가 의미하는 건 다음과 같음
먼저 DDPM의 MACs 그래프를 보면,
Stable Diffusion의 MACs 그래프를 보면,
따라서 이 그래프를 통해, 모델들마다 각자 다른 skip branch에서 연산량 분포가 다 다른 것을 볼 수 있음
그럼 연산량의 분포를 보는 것이 왜 중요하냐?
모델을 최적화할 때, 고려사항이 달라짐
Stable Diffusion
DDPM
따라서, 연산량의 분포에 따라 DeepCache를 이용한 가속화 성능의 이점을 받을 수 있을지 없을지 결정됨
(Skip Branch 수가 많을수록, 연산량 분포가 균일할수록 속도와 Output Quality의 trade-off 사이에서 결정할 수 있는 선택권이 많아짐 = 더 좋다~!)
본 논문에서는 RTX2080 GPU에서 각 모델들마다 다른 skip branch를 선택해서 실험했고, 각 모델의 처리량(throughput)과 MACs을 계산해서 평가했음
throughput : 시간당 처리량
FLOPs(FLoating point OPerations) : 초당 수행되는 부동 소수점의 연산량
- 곱셈, 나눗셈, 덧셈, 뺄셈등을 얼마나 많이 사용하는지 나타내는 지표
- FLOPs를 알면, 결과에 따라 모델의 성능을 높이고 최적화할 수 있음
FLOPS(Floating Point Operations per Second) : 초당 하드웨어가 처리할 수 있는 양
- 하드웨어가 얼마나 좋은 성능을 가지고 있는지 알려주는 지표
- FLOPS가 클수록, 초당 하드웨어가 처리할 수 있는 작업량이 많음 (= 추론 속도가 빠름)
FMA(Floating point Multiply and Add operation) : 그래픽 처리 장치(GPU)와 같은 하드웨어에서 고성능 연산을 수행하는 것
- A*x + B를 하나의 연산으로 처리함
MACs(Multiply–ACcumulates) : FMA(고성능 연산)가 모델에서 몇번 실행됐는지 계산하는 지표
- MACs는 곱셈과 덧셈 연산을 한번에 취급하기 때문에 Ax + B은 한번으로 치지만, FMA는 곱셈과 덧셈을 별개로 취급하기 때문에 Ax + B을 2번으로 계산함
- 따라서, FLOPs는 MACs * 2 임
(참고하면 좋을만한 사이트)
ImageNet(Dataset)을 이용해서 LDM-4-G(Model)을 실험한 결과임

그래프를 보면,
Speed와 Output Quality의 Trade-off
Uniform-N=5 : 4.1배 속도 향상했는데, FID 점수가 3.39에서 3.59로 소폭 증가함
가속화했을 때, 성능 저하가 매우 미미하다!
기존 방법들(pruning, distillation)과 비교
FID와 sFID 측면에서 본 논문 속 방법이 더 우수함
더 높은 가속률에도 불구하고 더 나은 품질 유지하고 있다!
Non-uniform 방법
N(caching intervals)이 커질수록 품질이 향상됨
Uniform보다 Non-uniform을 사용했을 때, 더 성능이 좋다!
CIFAR-10, LSUN-Bedroom, LSUN-Churches(Dataset)과 DDPM(Model)을 실험한 결과임

PartiPrompts, COCO2017(Dataset)과 Stable Diffusion을 실험한 결과임



Effectiveness of Cached Features

Positive Impact of Shallow Network Inference

Illustration of the increasing caching interval N

Diffusion의 모델 구조를 바꾸는게 아니라, 기존 모델에 DeepCache를 적용해서 가속화하기 때문에 Base가 되는 Diffusion 모델의 Skip Branch의 연산량 자체가 많아버리면 가속화하는데 한계가 있을 수 있음
그리고 Sampling Step 간격인 N을 정의할 때, 가속화하기 위해서 N을 너무 크게 잡아버리면 아무리 High-level Feature들이 일관적이라고 해도 그 간격 사이에서 중요한 정보를 놓칠 수 있기 때문에 성능이 떨어질 수 있음
기존 모델을 재학습하지 않고도 적용할 수 있는 가속화 방법
반복적으로 High-level Feature를 불필요하게 계산하는 문제를 해결함
U-Net의 독특한 구조적 특징을 활용함
계산 속도가 크게 개선됨