quantization은 fp32 -> int8로 압축하는 과정이고, dequantizatino은 압축된 int8 -> fp32로 다시 복원하는 과정이다. 예상했다싶이, dequantization값과 원본은 완전히 같을 가능성이 매우 낮다.
기존 quantization 공식은 아래와 같다.
이를 역산해서 다시 X를 구하는 공식은 아래와 같다.
그렇다면, dequantization이 왜 필요할까?
cpu/gpu에서 연산을 수행할 때에는 실수 연산을 수행하기 때문이다. 그렇다면, 왜 실제 연산에서는 이득이 없고 오히려 int ->fp로 변환하는 과정이 추가되버린 것인데 비효율적인것 아닌가? 생각이 드는게 정상이다. llm에서는 연산 시간보다 메모리 이동이 훨씬 오래 걸린다. 그래서, int->fp로 변환하는 시간(=overhead)가 추가되더라도, 이동시간을 2배,4배 줄이는게 훨씬 이득이다.
근데, 어떻게 quantization하는게 더 이득인 모델인지 확인할 수 있는 방법은 없을까?
데이터 1바이트를 가져왔을 때, 몇번이나 사용하는지의 비율이다.
CNN의 경우, 하나의 필터를 가져오면 이미지 전체에 대해서 재사용하기 때문에 메모리 이동보다 연산 속도가 훨씬 중요하다.
반면, llm은 가중치 필터가 엄청 크고, 한단어를 생성할때 한번씩 곱하고 끝나기 때문에, 연산 속도보다 메모리 이동이 훨씬 중요하다.
이런식으로 모델에 따라 weight quantization이 유의미할 수도, 아닐수도 있는 것이다.
근데, 왜 int8연산을 하지 않고, fp로 다시 변환해서 연산하는 걸까?
2가지 문제가 있다.
먼저 정확도 문제이다. 가중치와 입력데이터(activation)까지 int8로 바꾸게 되면(=W8A8), 모델 성능이 떨어질 확률이 매우 높아지게 된다.
그리고, 입력 데이터는 계속 바뀌게 되는데 dynamic quantization 기술이 까다롭다.
그래서, 현재 llm은 가중치만 압축하고, 연산은 fp16으로 수행하는 W8A16을 주로 사용하고 있다.
dynamic quantization?
quantization 종류로는 3가지가 있다.
npu는 뭐지?
npu에서는 int연산만 수행한다. 그래서, quantization이 필수이고, dequantization을 수행하지 않는다! 그래서 메모리나, 속도나 다 효율적이라고 하는것이다
하지만, 실제로 llm은 npu에서 속도는 빠르지만, 정확도는 낮다..
손실을 줄이는 방법?
손실이 불가피하게 생기게 되는데, 이 손실을 줄이는 방법들이 있을까? 해결법은,, quantization을 잘하는 것이다ㅋㅋㅋ 모델전체에 대해서 S,Z를 구할때보다, 각 블럭별로 S,Z를 구하는 것이 더 오류가 적게나오는 것처럼, quantization을 잘하면 결국,, de-quantization 오류도 줄어들게된다.