양자화 기초부터 배우기

Quantization from the Ground Up

요약

양자화(Quantization) 기술을 통해 LLM을 4배 작게, 2배 빠르게 만들면서 5-10% 정도의 정확도 손실만으로 노트북에서도 강력한 모델을 실행할 수 있습니다. 이 글은 파라미터, 부동소수점 표현, 양자화 개념을 시각적으로 설명합니다.

핵심 포인트

  • LLM은 수십억 개의 파라미터로 구성되며, 이들은 주로 작은 값들로 이루어져 있음
  • 32비트 부동소수점은 넓은 범위와 정확도를 제공하지만 메모리 비효율적이므로, 양자화로 압축 가능

왜 중요한가

양자화의 원리를 이해하면 LLM 배포 시 메모리 효율성과 성능의 트레이드오프를 최적화할 수 있습니다.

📄 전문 번역

양자화로 LLM을 4배 작게, 2배 빠르게 만들기

Qwen-3-Coder-Next는 800억 개의 파라미터를 가진 모델인데, 용량이 159.4GB입니다. 이 정도면 실행하기 위해 필요한 RAM 양이 대략 그 정도라고 보면 됩니다. 여기에 긴 컨텍스트 윈도우까지 고려하면 더 필요하죠.

참고로 이 정도 크기는 큰 모델이 아닙니다. 최첨단 모델들은 1조 개 이상의 파라미터를 가지고 있다는 소문이 있는데, 그러려면 최소 2TB의 RAM이 필요합니다. 제 경험상 한 대의 머신에 그만큼의 RAM이 있는 걸 본 적이 없네요.

그런데 혹시 LLM을 4배 작게, 2배 빠르게 만들 수 있다면 어떨까요? 게다가 정확도는 고작 5~10% 정도만 떨어진다면요? 그게 바로 양자화(quantization)의 마법입니다.

이 글에서 배우게 될 내용들을 정리하면:

  • 파라미터가 뭔지
  • 부동소수점 수가 어떻게 저장되는지
  • 양자화가 어떻게 작동하는지

이미 파라미터와 부동소수점 저장 방식을 알고 있다면, 양자화 섹션으로 바로 넘어가셔도 됩니다.

파라미터란 뭘까요?

파라미터(가중치라고도 부름)는 LLM이 메모리나 디스크에 있을 때 차지하는 공간의 대부분입니다. 제가 이전에 쓴 프롬프트 캐싱 글에서 LLM을 "수십억 개의 정교하게 배열된 연산들로 이루어진 거대한 그래프"라고 표현했는데요. 이 그래프가 어떻게 생겼을까요?

가장 간단한 예부터 시작해봅시다. 입력 1개, 파라미터 1개, 출력 1개입니다.

별 거 아닌 것처럼 보이지만, 이게 현대 AI의 가장 기본적인 빌딩 블록입니다. 입력값 2.0을 파라미터 0.5로 곱하면 출력값 1.0을 얻죠.

하지만 LLM은 훨씬 더 큽니다. 실제로는 수십억 개의 파라미터를 가지고 있거든요. 이렇게 커질 수 있는 이유 중 하나가 "층(layer)"이라는 개념 때문입니다.

위 그림의 중간에 있는 두 노드가 한 층을 이룹니다. 둘 다 1.0으로 표시되는 이유는 두 연결 모두 파라미터값이 0.5이기 때문이고, 결과적으로 2.0 0.5 = 1.0이 됩니다. 두 노드 사이의 모든 연결이 하나의 파라미터이므로, 위 예제에서는 총 4개입니다. 같은 노드로 끝나는 연결이 여러 개일 때는 값들을 더합니다. 그래서 최종 출력값이 1.5가 되려면 1.0 1.0과 0.5 * 1.0을 더하면 되는 것이죠.

지금은 겨우 6개의 파라미터에 불과하니까, 현대 LLM의 수십억 개와는 거리가 멉니다. 아래 예제는 입력 2개, 층 3개, 출력 2개로 총 64개의 파라미터를 가지고 있습니다. 노드에 마우스를 올리거나 탭하면 각 파라미터를 확인할 수 있습니다.

현대 LLM은 수십만 개의 입출력을 가지고 있습니다. 몇십 개의 층이 있고, 각 층마다 수천 개의 노드가 있으며, 모두가 촘촘하게 연결되어 있죠. 이 모든 게 곱해지면 결국 수십억 개, 때로는 수조 개의 파라미터가 나오는 겁니다.

컴퓨터는 수를 어떻게 저장할까요?

컴퓨터는 1과 0(비트)로 작동합니다. 여기 정수가 비트로 저장되는 모습을 보여줄게요.

슬라이더를 움직이면 값이 변합니다. 개별 비트를 탭해서 바꿀 수도 있어요.

각 비트는 2의 거듭제곱을 나타내고, 이들을 모두 합하면 최종 값이 됩니다.

정수는 다루기 좋습니다. 이산적이기 때문이죠. 1과 3 사이에는 정확히 2라는 수가 하나 있습니다. 컴퓨터도 이런 이산적인 값들은 문제없이 표현할 수 있습니다.

소수점은 문제가 된다

소수점이 들어가면 얘기가 달라집니다. 1과 3 사이에 몇 개의 소수가 있을까요? 무한 개입니다. 이건 컴퓨터 입장에서는 곤란합니다. 무한 개의 것을 표현할 수 없거든요.

그래서 컴퓨터는 타협합니다. 정확도를 일정한 유효숫자까지만 보장하고, 그 이후는 최선을 다하는 방식으로 처리하는 거죠.

예를 들어 32비트 부동소수점 수는 ±3.40×10³⁸의 범위를 가지면서 7자리의 유효숫자 정확도를 제공합니다. 32비트를 3부분으로 나누는 방식으로 이를 구현합니다. 부호 비트 1개, 지수 비트 8개, 유효숫자 비트 23개입니다. 지수 비트가 많을수록 더 넓은 범위를 표현할 수 있고, 유효숫자 비트가 많을수록 더 정확한 값을 나타낼 수 있습니다.

아래 예제를 가지고 놀아보세요. 좌우로 슬라이더를 움직이면 전체 범위의 값들을 탐색할 수 있습니다. 위의 더하기, 빼기 버튼은 다음으로 표현 가능한 더 높은 값이나 낮은 값으로 이동합니다. 정확하다고 보장되는 7자리 유효숫자는 밑줄이 그어져 있습니다. 리셋을 누르면 기본값 1.5로 돌아갑니다.

더하기를 누를 때마다 다음으로 높은 표현 가능한 값으로 이동합니다. 밑줄 이후의 자리수를 주의 깊게 보세요. 가끔 어떤 수를 건너뛸 겁니다. 이게 바로 정밀도 타협을 실제로 보여주는 거예요.

매우 작은 값에서 더하기를 누르면 조금씩 앞으로 이동합니다. 반면 매우 큰 값에서 누르면 더 큰 폭으로 이동하죠. 어디에 있는지에 따라 점프의 크기가 달라집니다. 값들이 균등하게 분포된 게 아니거든요.

이를 더 잘 이해하기 위해 아래 히스토그램을 봐보세요. 각 막대는 32비트 부동소수점 범위의 일부를 보여줍니다. -0.5와 0.5 사이에는 20억 개가 넘는 고유한 값들이 표현 가능합니다.

음수 10과 10 사이의 float32 표현 가능 값들의 히스토그램입니다. 대부분의 유한 값들이 0 근처에 몰려 있네요. 아래 컨트롤로 y축을 선형 또는 로그 스케일로 전환하거나, 절대값 또는 백분율로 볼 수 있습니다.

표현 가능한 32비트 부동소수점 수의 대부분이 작은 값들입니다. 이건 LLM에게 정말 좋은 소식인데요. 파라미터들도 대체로 작은 값이거든요. 작은 파라미터들이 모델이 이전에 본 적 없는 문제에 더 잘 일반화되도록 한다는 것이 밝혀졌으니까요.