AIOps/이론

양자화란 무엇인가

마늘냄새폴폴 2025. 12. 9. 22:27

4개월만에 블로그 포스팅을 재개하게 되었네요. 이런저런 난관도 있었고 새로운 직장에 안착해서 자리잡아야 했고 새로운 프로젝트에 투입되어 AIOps를 위해 개발하느라 포스팅이 늦어졌습니다. 이번 회사에서 제 커리어를 웹 백엔드에서 AIOps로 변경하게 되었는데 우선은 아직 새로운 것도 많고 공부할 것도 많아 바쁜 하루하루를 보내고 있었습니다. 

 

우선 이직과 관련된 내용이나 직종을 어떻게 변경하게 되었는지는 회고에서 더 자세히 풀도록 하고, 지금 제가 개발하는 AIOps에서 필요한 이론 공부를 요즘 중점적으로 하고 있습니다. 

 

이번 포스팅에선 LLM을 이용해 개발하는 사람들은 모두 들어봤을 양자화에 대해서 공부해보고 더 나아가 첫 포스팅인만큼 용어정리, 파인튜닝에 대한 간단한 개요까지 적어볼까합니다. 

 

부동소수점 아래 숫자 표현이란?

우리가 흔히 LLM 모델을 이야기할 때 fp32, fp16등의 표현을 사용하곤 합니다. 우선 양자화에 대해서 알아보기 전에 이 개념에 대해서 짚고 넘어가야합니다. 

 

fp32, fp16의 의미는 부동소수점 아래의 숫자를 어떻게 표현할 것인지에 대한 것으로 fp32는 부동소수점 아래를 32bit 즉 4byte로 표현하겠다는 의미, fp16은 부동소수점 아래를 16bit 즉 2byte로 표현하겠다는 의미입니다. 우리가 흔히 개인 컴퓨터에서 많이 사용하는 "4bit 양자화"라는 것은 다르게 표현하면 fp4라고 표현할 수 있습니다. 

 

우선 드는 문제점은 부동소수점이 갑자기 왜 나오느냐는 것인데 이 부동소수점은 간단하게 표현하자면 "확률"을 표현한 것입니다. 

 

흔히 transformer 기반의 LLM모델은 단어 뒤에 올 다음 단어를 "확률적"으로 계산해서 생성한다고 알려져있습니다. 이 때 사용하는 확률이 바로 이 부동소수점에 표현되는 것입니다. 

 

예를 들어서

 

사과는 (?)

뒤에 올 단어를 고른다면

 

  • 맛있다 -> 0.76543210
  • 빨갛다 -> 0.61234567
  • 자동차 -> 0.01234567

이렇게 다음 단어가 올 확률을 부동소수점 아래로 표현하는 것입니다. 이 때 가장 높은 확률을 기록한 것을 다음 단어로 사용하고 결과적으로 "사과는 맛있다"라는 문장이 완성되는 것입니다. 

 

물론 LLM은 단어 하나만 보고 다음 단어를 확률적으로 계산하는 것이 아니라 문장 전체를 보고 계산하기 때문에 이렇게 단순하게 계산하진 않지만 직관적인 예시를 위해 많은 부분을 생략했습니다. 

 

때문에 fp32는 부동소수점 아래 7~9자리까지 표현, fp16은 부동소수점 아래 4~5자리까지 표현, fp4는 부동소수점 아래 1~2자리까지 표현하므로

 

  • 맛있다
    • fp32 : 0.76543210
    • fp16 : 0.76543
    • fp4 : 0.76
  • 빨갛다
    • fp32 : 0.61234567
    • fp16 : 0.61234
    • fp4 : 0.61

이렇게 계산되기 때문에 양자화를 하더라도 LLM 모델에 대한 성능이 어느정도 방어가 되는 것입니다. 

 

이러한 이유 때문에 "작은 모델을 쓰는 것 보다 큰 모델을 양자화해서 사용하는 것이 성능적으로 더 도움이 된다"라는 이야기가 정설로 받아들여지는 것입니다. 

 

베이스 모델(fp32)과 가까우면 가까울수록 LLM 모델이 다음 단어를 선택하는 것이 더 정교해지고 그렇기에 더 성능이 좋아지는 것이죠. 

 

여기서 다음으로 넘어가기 위해서는 LLM 모델의 직접적인 성능으로 표현되는 "파라미터"에 대해서 짚고 넘어가야합니다. 

 

파라미터란?

파라미터는 모델이 얼마나 세상을 다채롭게 보는지와 관련된 지표입니다. 즉, LLM이 얼마나 깊이있게 생각할 수 있는지에 대한 척도라고 보시면 됩니다. 

 

예시를 들자면, 파라미터가 작은 모델은 "키가 크면 몸무게가 많이 나간다"와 같이 단순하게 사고하는 반면, 큰 모델은 "키가 크더라도 마른 체형이라면 몸무게가 적을 수 있고, 근육질이라면 더 많이 나갈 수 있다."와 같이 복잡한 현실을 더 완벽하게 묘사한다는 특징이 있습니다.

 

이 파라미터는 흔히 7B, 20B 등의 숫자로 나타내고 각각 70억개, 200억개의 파라미터를 학습시킨 것으로 표현합니다.

 

파라미터는 쉽게 표현하면 모델이 얼마나 많은 차원(매개변수)을 가지고 있냐에 대한 척도이고 보통 y = ax + b라고 적은 것을 1차함수 즉, 매개변수가 1개있는 함수라고 이야기합니다. 

 

이 매개변수가 70억개 있다는 이야기인데 각 차원은 이 세상에 존재하는 것들에 대한 기준을 나타냅니다. 첫번째 매개변수는 성별, 두번째 매개변수는 색깔, 세번째 매개변수는 지위, 네번째 매개변수는 크기 등등..

 

만약 70억개라면 세상을 보는 기준이 70억개라는 것이고 200억개라면 세상을 보는 기준이 200억개라는 이야기이니 크기가 큰 모델일수록 세상을 다채롭게 보는 것입니다. 

 

양자화란?

양자화는 fp32의 베이스 모델을 fp16, fp4로 대충 뭉텅이로 표현하는 것입니다. 앞서 부동소수점을 말씀드리면서 대충 이야기한 내용입니다. 다만 양자화 기법은 이 소수점을 대충 표현하는 것을 어떻게 대충 표현할 것인지를 나타내는 것으로써 다양한 기법이 있고 이번 포스팅에선 그 중에서 가장 대표적인 세가지 기법을 소개하려고자 합니다. 

 

GPTQ

현재 GPU환경에서 널리 사용되고 있는 범용 양자화 기법입니다. 베이스 모델인 fp32를 fp16, fp4등으로 깎아낼 때 단순히 반올림해서 깎아내는 것이 아니라 두번 미분한 값을 가지고 양자화를 하기 때문에 오차가 매우 적어 최적화를 할 수 있다는 장점이 있습니다. 

 

때문에, 단순히 자르는 방식보다 성능 보존율이 높아 저점 방어가 확실히 되는 편이며, 양자화를 적용할 때에도 생태계가 성숙하여 지원하는 라이브러리가 많고 추론 속도가 매우 빨라진다는 특징이 있습니다. 

 

다만, 양자화 변환 과정이 다소 느리고 무겁다는 단점과 주로 가중치만 양자화하고 활성화 값은 다루지 않는다는 단점이 있습니다. 

 

cf) 여기서 잠깐! 가중치와 활성화 값이란?

가중치는 모델이 학습을 통해 배운 지식 그 자체입니다. 학습이 끝나면 이 과정은 고정되고, 이 값이 클수록 해당 정보가 중요하다는 뜻입니다. 

 

맞습니다. 방금 전 이야기한 파라미터와 같은 말입니다. 즉, 가중치 == 파라미터라고 이해해도 전혀 무방합니다. 

 

활성화 값이란 입력값 x 가중치를 계산한 뒤 "활성화 함수"를 거쳐 나온 결괏값입니다. 이 값이 특정 기준을 넘어야 다음 단계로 정보가 전달됩니다. 활성화 함수는 작년 노벨물리학상을 받은 제프리 힌튼 교수님의 1986년에 작성한 논문에서부터 나온 근본 개념입니다. 제프리 힌튼 교수님은 이 논문을 기점으로 활섬 함수, 역전파 등의 개념을 만든 장본인입니다. 

 

활성함수

 

 

AWQ

GPTQ의 강력한 경쟁자로, "모든 가중치가 똑같이 중요하지는 않다"라는 점에서 착안한 기술입니다. AWQ는 GPTQ가 손대지 않는 활성화 값을 분석해 중요한 1%의 가중치는 손대지 않고 덜 중요한 가중치만 4bit로 과감하게 압축하는 방법입니다. 이렇게 하면 전체적인 성능 하락을 막을 수 있다는 장점이 있습니다. 

 

또한, GPTQ에 비해 과적합 문제가 발생하지 않고 다양한 작업에서 GPTQ보다 족므 더 나은 성능을 보여주는 경우가 많습니다. 또한, 현재 고속 추론 엔진인 vLLM이 밀고 있는 양자화 기법이라는 점에서 떠오르는 초신성같은 강력한 기술입니다. 

 

하지만, 변환 과정이 GPTQ보다 족므 더 복잡하고 지원하는 도구가 GPTQ에 비해 방대하지 않으나 vLLM이 밀고 있기 때문에 생태계가 빠르게 발전하고 있습니다. 

 

아마 과적합 문제가 발생하지 않는 것이 가중치가 세밀하게 조정되어 한 곳에 몰릴 가능성이 있는 GPTQ에 비해 중요하지 않은 가중치는 4bit로 과감하게 자르기 때문에 가중치가 덜 발생하는 것이 아닐까 생각이 듭니다. 

 

GGUF

CPU에서 LLM을 돌려야 하거나 애플 실리콘에서 LLM을 돌릴 때의 사실상의 표준 포맷인 GGUF는 엄밀히 말하자면 양자화 알고리즘이 아닌 파일 포맷에 가깝고 주로 LLama CPP의 양자화 방식을 포함합니다. 

 

다른 양자화 기법들은 보통 NVIDIA 그래픽카드에 최적화 되어있거나 모든 LLM 리소스들이 VRAM에 정상적으로 올라와야 (공유메모리를 사용하지 않아야) 최대 성능을 내도록 설계되어 있기 때문에 VRAM이 부족하거나 NVIDIA 그래픽카드가 아닌 경우에 GPTQ나 AWQ를 사용하면 OOM이 발생할 가능성이 매우 높습니다. 

 

하지만 GGUF는 CPU에 올려서 돌릴 수 있도록 설계되어있기 때문에 VRAM이 부족하면 CPU 메모리인 DRAM을 사용해 조금 느리긴 하지만 동작은 가능하게끔 한다는 장점이 있습니다. 

 

또한, 모델이 단일 파일로 저장되기 때문에 가중치를 하나의 파일에 담아 관리하기가 편하다는 장점이 있고, mmap을 사용해 모델을 메모리에 로드하는 속도가 매우 빠르다는 장점이 있습니다. 

 

마치며

이번 포스팅에선 파라미터와 가중치, 활성화 함수, 양자화 등을 소개해드렸습니다. 이번 포스팅을 기점으로 당분간은 AIOps에 대한 내용을 주로 포스팅할 예정이고 이론과 더불어 실전에서 어떻게 AIOps를 활용해 레이턴시와 처리량을 늘릴 것인지 백엔드의 관점까지 녹여내 포스팅해보도록 하겠습니다. 

 

이번 포스팅의 결론은 순수 NVIDIA GPU 서버 환경에서는 GPTQ나 AWQ를, CPU에서 LLM을 돌려야하거나 애플 실리콘에서 돌려야하는 경우에는 GGUF를 사용해야한다는 것입니다. 

 

지금 사내에서 새로운 프로젝트를 진행하면서 배운 여러가지 개념들을 실전에 녹여보면서 공부한 다양한 내용들이 기다리고 있으니 많은 기대 부탁드립니다. 

 

거의 4개월만에 다시 포스팅 작성에 대한 시동을 걸고 본격적으로 공부해보면서 열심히 작성해보겠습니다. 

 

긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요!