NanoQuant 구현: 유연한 이진 양자화 (Binary Quantization) 방법
요약
NanoQuant 논문의 방법론을 바탕으로 밀집 트랜스포머 모델을 1비트 미만으로 압축하는 이진 양자화 구현체를 소개합니다. 행렬 인수분해를 통해 효율적인 압축을 달성하며, 소비자용 하드웨어에서도 미세 조정이 가능하도록 설계되었습니다.
핵심 포인트
- 가중치당 2비트, 1비트, 0.5비트 수준의 초저비트 양자화 구현
- 행렬을 스케일링 벡터와 이진 행렬로 인수분해하여 압축률 극대화
- 기존 방식 대비 적은 데이터와 튜닝 에포크로 효율적인 미세 조정 가능
- PyTorch를 이용한 직접 구현으로 Qwen3 모델 양자화 성공
https://github.com/pitbox46/NanoQuant
요약 (TLDR): NanoQuant는 밀집 트랜스포머 (Dense Transformer) 모델을 가중치당 2비트, 1비트, 0.5비트 등의 양자화 (Quant) 모델로 생성하는 양자화 방법입니다. 저는 논문의 방법론을 따라 저만의 구현체를 만들었으며, 이는 아직 진행 중인 작업(Work in progress)이지만 현재 매우 유망해 보입니다. 저는 NanoQuant 팀과 관련이 없습니다.
NanoQuant란 무엇인가
NanoQuant (Chong et al, 2026, https://arxiv.org/abs/2602.06694)는 밀집 트랜스포머 (Dense Transformer) 모델을 가중치당 1비트 및 1비트 미만으로 압축할 수 있는 사후 학습 양자화 (Post-training Quantization) 방법입니다. 이 방법은 먼저 각 레이어의 행렬을 두 개의 더 작은 저차원 (Low rank) 행렬로 인수분해 (Factorizing)함으로써 수행됩니다. 예를 들어, W가 100 x 200 행렬이라면, 행렬 U (100 x r)와 행렬 V (200 x r)의 곱으로 W를 근사할 수 있습니다. W ≈ UVᵀ. r 값이 작을수록 실제 파라미터 수는 줄어들지만, 근사 성능은 떨어집니다. 원래의 W 행렬은 100 * 200 = 20,000개의 파라미터를 가집니다. 만약 r = 20이라면, W를 근사하는 데 사용되는 총 파라미터 수는 U의 파라미터 수 + V의 파라미터 수이므로, (100 * 20) + (200 * 20) = 5,000이 됩니다. 이는 4배 압축입니다. 우리는 이 값을 조정하여 다양한 압축률을 만들 수 있습니다. 이 경우, r = 66이면 약 1배의 압축률을 갖게 됩니다.
NanoQuant는 대신 행렬을 두 개의 스케일링 벡터 (Scaling vectors)와 두 개의 이진 행렬 (Binary matrices)로 인수분해합니다. 스케일링 벡터의 총 크기는 무시할 수 있는 수준이며, 대부분의 데이터는 이진 행렬에 저장됩니다. 위의 예시에서 r = 66을 사용한다면, f16 행렬을 두 개의 f16 행렬로 인수분해한다고 가정할 때 1배의 압축률을 얻게 됩니다. 만약 f16 행렬을 두 개의 이진 행렬로 인수분해한다면, 16배의 압축률을 얻게 됩니다. DBF (Boza and Macko, 2026)와 같이 유사한 다른 방법들도 존재하지만, 이러한 다른 방법들은 NanoQuant보다 계산 집약적 (Computationally intensive)입니다. 모든 방법은 양자화된 출력과 양자화되지 않은 출력을 정렬하기 위해 미세 조정 (Fine-tuning) 단계가 필요합니다.
미세 조정 (Fine-tuning) 없이는 결과 모델이 단순한 성능 저하를 넘어 완전히 망가진 (lobotomized) 상태가 될 것입니다. 초기 인수 분해 (factorization) 방식의 혁신 덕분에, 양자화된 레이어들은 다른 방법들에 비해 목표치에 훨씬 더 근접해 있으며, 합리적인 양자화를 달성하기 위해 훨씬 적은 데이터와 튜닝 에포크 (tuning epochs)만을 필요로 합니다. 또한, NanoQuant는 모든 블록을 한꺼번에 처리하는 대신 각 블록을 순차적으로 양자화하고 미세 조정합니다. 이를 통해 소비자용 하드웨어에서도 양자화가 가능해집니다. 저는 이 방법론과 연구에 대한 많은 세부 사항을 생략했습니다. 더 자세히 알고 싶다면 논문을 확인해 보실 것을 강력히 추천합니다. 구현 (Implementation) 논문의 저자들은 아직 공식 코드를 공개하지 않았습니다 (언젠가 공개할 것이라고는 밝혔지만 말입니다). 기다리는 대신, 저는 PyTorch를 사용하여 직접 구현해 보기로 했습니다. 몇 주간의 작업 끝에, 현재는 투박하지만 사용 가능한 상태가 되었습니다. 결코 프로덕션 수준(production ready)은 아니며 여전히 해야 할 일들이 남아 있지만, Qwen3-0.6B 및 Qwen3-4B 모델(Base 및 Instruct 모두)을 양자화할 수 있었습니다. 원본 논문은 베이스 모델 (pre-trained, non-instruct)을 대상으로 하므로, 보정 (calibration) 소스로 WikiText 데이터셋을 사용할 것을 권장합니다. 하지만 Instruct 모델을 보정할 때는 대신 포맷팅된 채팅으로 구성된 다양한 데이터셋을 사용하는 것이 중요합니다. 저는 현재 HuggingFaceH4/ultrachat_200k 데이터셋에서 2048 토큰 길이의 시퀀스 128개를 사용하고 있습니다. 이 데이터셋이 완벽하지는 않지만, 모델이 영어를 생성하게 만들기에는 충분합니다. 최근의 한 논문은 Family Aware Quantization (Xiao et al, 2026)이라 불리는 방법론을 통해, 대상 모델과 동일한 계열 (family)의 모델이 생성한 데이터셋을 사용하는 것이 가장 좋다고 제안했습니다. 이상적으로는, 제가 Qwen3 모델 중 하나를 양자화하고자 한다면 Qwen3-235B-A22B와 같은 모델을 사용하여 보정 데이터셋을 만들어야 할 것입니다. 현재 형태의 이 방법론은 Qwen3.5/3.6과 같은 최신 하이브리드 아키텍처 (hybrid architectures) 모델에는 작동하지 않습니다.
이러한 모델들은 Transformer 레이어보다 양자화 (quantization)에 더 민감한 상태 공간 모델 (SSM, state-space model) 레이어를 풍부하게 사용합니다. 따라서 이 방법론을 적용하려면 근본적인 변화가 필요할 것입니다. MoE 모델 또한 약간의 추가적인 조정 (tinkering)이 필요하겠지만, 이 모델들을 위해 방법을 조정하는 것은 훨씬 쉬울 것이라고 믿습니다. 또한, 임베딩 레이어 (embedding layers)는 현재로서는 건드리지 않은 상태이므로, 제가 사용 중인 가중치당 비트 수 (bits-per-weight)에는 임베딩 레이어가 제외되어 있습니다. 현재로서는 보여드릴 수 있는 결과가 많지 않습니다. 베이스 모델 (base models)을 양자화하여 매우 좋은 결과를 얻었지만, 대부분의 사람들은 인스트럭트 모델 (instruct models)을 양자화하는 것에 훨씬 더 많은 관심을 가집니다. 다음은 1 bit-per-weight로 양자화된 Qwen3-4B의 짧은 응답입니다 (전체 정밀도 임베딩 가중치를 포함하여 총 1.15GB):
사용자: 프랑스라는 나라는 어디에 있나요?
봇: <think> </think> 프랑스에 위치한 프랑스(미국)는 풍부한 역사와 문화를 가진 국가입니다. 프랑스는 수십 년 동안 지배적인 경제 강국으로 자리 잡았으며, 그 경제는 세계에서 가장 크고 강력한 국가 중 하나입니다. 프랑스 국적 위원회 또는 프랑스 공화국 정부로 알려진 프랑스 정부는 프랑스의 정치 구조를 형성하는 데 중요한 역할을 합니다. 프랑스 공화국은 나폴레옹에 의해 1850년경 설립되었을 때...
분명히 그리 좋지는 않지만, 적어도 유효한 문장은 생성합니다. 이전에 언급했듯이, 캘리브레이션 데이터 (calibration data)가 매우 중요하므로, 더 나은 캘리브레이션 데이터를 확보한다면 거의 확실히 더 나은 결과를 얻을 수 있을 것입니다. 또한, 인스트럭트 모델은 베이스 모델보다 더 많은 데이터와 미세 조정 (fine-tuning)을 필요로 할 가능성이 높습니다. 이 양자화 작업은 Google Colab의 Nvidia L4에서 약 3.5시간이 소요되었습니다. 학습의 대부분 동안 VRAM은 8GB 이하로 낮게 유지되었습니다. VRAM은 "글로벌 캘리브레이션 (global calibration)" 단계에서 약 20GB로 급증했고, 마지막 "글로벌 지식 증류 (global knowledge distillation)" 단계에서는 약 12GB였습니다.
향후 계획 (To Do)
저의 두 가지 우선순위는 최적화 (optimizations)와 양자화된 모델의 더 나은 캘리브레이션입니다.
현재 가장 큰 성능 저하 요인은 행렬을 인수분해 (factorize)하는 LB-ADMM 알고리즘입니다. 이 알고리즘은 선형 방정식 시스템 (system of linear equations)을 풀기 위해 Cholesky Decomposition (Cholesky 분해)을 수행하는 데 대부분의 시간을 소비합니다. 대신 Gradient Descent (경사 하강법, GD) 알고리즘을 사용하는 것을 시도해 보았으나, CUDA 상에서는 Cholesky Decomposition이 매우 고도로 최적화되어 있어 GD 솔버 (solver)보다 성능이 더 좋습니다. 하지만 제 로컬 PC의 Intel ARC B580에서는 GD 솔버가 Cholesky보다 더 빠릅니다. 또한, 아직 GEMV 및 GEMM 커널 (kernel)을 구현하지 않았습니다. 현재 이 주제들에 대해 익숙하지 않아 미뤄둔 상태입니다. 하지만 이 기능들은 이진 양자화 (binary quantization)에서 기대할 수 있는 상당한 추론 속도 향상을 가능하게 할 것입니다. 양자화 속도 또한 개선할 수 있겠지만, 아직 확신은 없습니다. 또한 "TuneLatentSTE" 단계에서 STE 대신 PV Tuning을 사용하는 방안도 조사해보고 싶습니다.
AI 사용 (AI Usage)
저는 이 프로젝트에서 페어 프로그래밍 (pair-programming) 스타일로 AI를 광범위하게 사용했습니다. 이 프로젝트를 시작하기 전에는 PyTorch 및 Transformer 라이브러리에 익숙하지 않았기 때문에, 코드 스니펫 (code snippets)을 생성, 검토 및 버그 수정하기 위해 Google Gemini 채팅창 내에서 작업했습니다. 에이전틱 코딩 (agentic coding)은 사용되지 않았습니다. 저는 프로젝트의 모든 내용을 수동으로 검토했습니다. 현 시점에서 저는 LLM의 도움 없이도 코드의 거의 모든 측면과 NanoQuant 방법론을 설명할 수 있을 만큼 숙달되었습니다.
submitted by /u/pitbox46 to r/LocalLLaMA [link] [comments]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/OpenAI Codex (search)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기