Unweight: how we compressed an LLM 22% without sacrificing quality
Quick Summary
Unweight는 LLM 가중치의 BF16 지수 바이트를 무손실로 압축하고 GPU 온칩 메모리에서 바로 복원해, 출력 품질을 유지하면서 모델 크기와 HBM 메모리 대역폭 부담을 줄이는 추론용 압축 시스템이다.
🖼️ 인포그래픽
🖼️ 4컷 인포그래픽
💡 한 줄 요약
Unweight는 LLM 가중치의 BF16 지수 바이트를 무손실로 압축하고 GPU 온칩 메모리에서 바로 복원해, 출력 품질을 유지하면서 모델 크기와 HBM 메모리 대역폭 부담을 줄이는 추론용 압축 시스템이다.
📌 핵심 요약
- Cloudflare는 전 세계 인터넷 연결 인구의 95%에 대해 50ms 이내 추론을 목표로 하며, 이를 위해 GPU 메모리 효율이 핵심 병목이라고 설명한다.
- LLM이 토큰 하나를 생성할 때마다 모든 모델 가중치를 GPU 메모리에서 읽어야 하므로, H100에서는 연산 능력보다 HBM 메모리 대역폭이 더 큰 제한 요소가 된다.
- Unweight는 특수 하드웨어 없이 모델 가중치를 최대 15~22% 줄이면서 비트 단위로 동일한 출력을 유지하는 무손실 압축 시스템으로 설계됐다.
- 핵심 아이디어는 BF16 가중치 중 예측 가능한 지수 바이트만 Huffman coding으로 압축하고, 복원된 가중치를 HBM에 다시 쓰지 않은 채 shared memory에서 tensor core로 직접 공급하는 것이다.
- Unweight는 전체 상황에 하나의 방식만 쓰지 않고, full decode, exponent-only decode, palette transcode, direct palette 등 여러 실행 경로를 배치 크기와 행렬 형태에 따라 선택한다.
🧩 주요 포인트
- Cloudflare는 전 세계 인터넷 연결 인구의 95%에 대해 50ms 이내 추론을 목표로 하며, 이를 위해 GPU 메모리 효율이 핵심 병목이라고 설명한다.
- LLM이 토큰 하나를 생성할 때마다 모든 모델 가중치를 GPU 메모리에서 읽어야 하므로, H100에서는 연산 능력보다 HBM 메모리 대역폭이 더 큰 제한 요소가 된다.
- Unweight는 특수 하드웨어 없이 모델 가중치를 최대 15~22% 줄이면서 비트 단위로 동일한 출력을 유지하는 무손실 압축 시스템으로 설계됐다.
- 핵심 아이디어는 BF16 가중치 중 예측 가능한 지수 바이트만 Huffman coding으로 압축하고, 복원된 가중치를 HBM에 다시 쓰지 않은 채 shared memory에서 tensor core로 직접 공급하는 것이다.
- Unweight는 전체 상황에 하나의 방식만 쓰지 않고, full decode, exponent-only decode, palette transcode, direct palette 등 여러 실행 경로를 배치 크기와 행렬 형태에 따라 선택한다.
🧠 상세 정리
1. 추론 플랫폼의 다음 병목은 모델 가중치
글은 Cloudflare가 전 세계 인터넷 연결 인구의 95%에 대해 50ms 안팎의 추론을 제공하려면 GPU 메모리를 극도로 효율적으로 써야 한다는 문제의식에서 출발한다. 이전에는 Rust 기반 추론 엔진 Infire로 메모리 활용률을 개선했고, 모델 스케줄링 플랫폼 Omni로 cold-start를 제거했다고 설명한다. 그러나 이제 남은 큰 병목은 모델 가중치 자체이며, LLM이 토큰 하나를 생성할 때마다 모든 가중치를 GPU 메모리에서 읽어야 한다는 점이 핵심 문제로 제시된다. H100 GPU에서는 tensor core의 처리 속도가 메모리가 데이터를 공급하는 속도보다 훨씬 빠르기 때문에, 연산량보다 메모리 버스를 오가는 바이트 수가 성능을 좌우한다.
2. Unweight의 목표와 기본 성과
Unweight는 모델 가중치를 더 작게 만들어 HBM에서 읽어야 하는 데이터량을 줄이되, 모델 출력은 비트 단위로 동일하게 유지하는 무손실 압축 시스템으로 소개된다. 글은 Unweight가 특수 하드웨어에 의존하지 않고, 가중치를 최대 15~22% 작게 만들 수 있다고 설명한다. 핵심은 느린 메인 메모리에 복원된 가중치를 다시 쓰지 않고, 빠른 온칩 shared memory에서 압축을 풀어 바로 tensor core에 공급하는 것이다. Llama-3.1-8B 초기 결과에서는 MLP 가중치만 약 30% 압축했고, 선택적으로 decoding에 쓰이는 파라미터에 적용함으로써 전체 모델 크기 15~22% 감소와 약 3GB VRAM 절감으로 이어졌다고 제시된다.
3. 양자화가 충분하지 않은 이유
글은 모델 압축 연구가 활발하지만, 프로덕션 추론에서는 단순히 크기만 줄이는 것보다 모델 동작을 그대로 보존하는 것이 중요하다고 강조한다. 가장 흔한 접근은 32비트 또는 16비트 부동소수점 값을 8비트나 4비트 정수로 바꾸는 양자화지만, 이는 서로 다른 원래 값이 같은 작은 정수로 변환될 수 있는 손실 압축이다. 이런 정확도 손실은 응답 품질에 예측하기 어려운 영향을 줄 수 있다. 다양한 사용 사례를 처리하는 서비스 환경에서는 품질 변화가 허용되지 않기 때문에, 글은 정확한 모델 동작을 보존하는 무손실 방식이 필요했다고 설명한다.
4. 기존 압축 시스템과의 차이
글은 Huff-LLM, ZipNN, ZipServ 같은 최근 시스템들이 LLM 가중치를 크게 압축할 수 있음을 보여주었지만, Cloudflare가 풀고자 한 문제와는 목표가 달랐다고 정리한다. ZipNN은 배포와 저장을 위한 압축에 초점을 두고 CPU에서 압축을 푸는 방식이며, Huff-LLM은 디코딩을 위한 맞춤형 하드웨어를 제안한다고 설명한다. ZipServ는 GPU 추론과 압축 해제를 결합하지만, Cloudflare가 사용하는 H100 GPU와 맞지 않는 소비자용 GPU를 대상으로 한다. 따라서 필요한 것은 Hopper GPU에서 동작하고 Rust 기반 추론 엔진에 통합되며, 추론 시점에 무손실로 압축을 푸는 방식이었다.
5. BF16 지수 바이트의 중복성 활용
Unweight가 압축하는 대상은 BF16 가중치 전체가 아니라 그중 지수 바이트다. BF16 값은 부호 1비트, 지수 8비트, 가수 7비트로 구성되는데, 글은 부호와 가수는 무작위 데이터처럼 보여 의미 있게 압축하기 어렵다고 설명한다. 반면 지수 값은 학습된 LLM에서 매우 편향된 분포를 보이며, 256개 가능한 값 중 소수의 값이 대부분을 차지한다. 일반적인 레이어에서는 상위 16개 지수 값이 전체 가중치의 99% 이상을 덮기 때문에, Unweight는 부호와 가수는 그대로 두고 지수 바이트만 Huffman coding으로 압축한다.
6. 드문 지수 값과 hot path 단순화
Unweight는 자주 등장하는 지수 값만 전제로 모든 원소를 매번 검사하지 않고, 드문 지수 값이 있는 경우를 별도로 처리한다. 구체적으로 64개 가중치로 이루어진 한 row 안에 top-16 palette 밖의 지수 값이 하나라도 있으면, 그 row 전체를 원문 그대로 저장한다. 이 방식은 압축률만 극대화하려는 접근은 아니지만, 실제 추론의 hot path에서 원소별 분기 처리를 없애는 데 유리하다. 매 가중치마다 예외 여부를 확인하는 대신 row 단위로 한 번 결정하므로, GPU 커널이 더 단순하고 예측 가능한 실행 흐름을 유지할 수 있다.
7. HBM과 shared memory 사이의 대역폭 병목
글은 H100 GPU의 관련 메모리를 크게 HBM과 shared memory로 나누어 설명한다. HBM은 모델 가중치가 저장되는 크고 상대적으로 느린 메모리이고, shared memory는 연산 직전에 데이터를 준비하는 작지만 매우 빠른 온칩 메모리다. 토큰 생성 중에는 전체 weight matrix를 HBM에서 읽어와야 하며, 병목은 수학 연산 자체가 아니라 HBM에서 shared memory로 데이터를 옮기는 메모리 버스다. 기존 방식처럼 압축된 weight matrix를 HBM에 다시 완전히 복원한 뒤 표준 matrix multiplication을 수행하면 저장 용량에는 도움이 되지만, 매 토큰마다 결국 압축 해제된 전체 행렬을 HBM에서 읽어야 하므로 대역폭 문제는 해결되지 않는다.
8. 네 가지 실행 파이프라인과 자동 선택
Unweight는 압축 가중치를 추론에 사용하는 방식이 하나로 고정될 수 없다고 보고, 네 가지 실행 파이프라인을 제공한다. full decode는 원래 BF16 가중치를 완전히 복원한 뒤 NVIDIA cuBLAS에 넘기는 단순한 방식이며, 작은 배치에서는 cuBLAS의 낮은 오버헤드 때문에 유리할 수 있다. exponent-only decode와 palette transcode는 중간 지점에 있는 방식으로, 복원에 필요한 메모리 쓰기량을 줄이면서 custom reconstructive matrix multiplication을 사용한다. direct palette는 전처리를 건너뛰고 4비트 palette index에서 즉석으로 BF16 값을 재구성하므로 전처리 비용은 없지만 커널이 원소마다 더 많은 일을 해야 하며, Unweight는 autotuning으로 행렬과 배치 크기별 최적 경로를 고른다.
9. reconstructive matmul의 역할 분담
네 가지 파이프라인 중 세 가지는 압축 해제와 matrix multiplication을 하나의 custom kernel 안에서 결합한다. 이 kernel은 HBM에서 압축 데이터를 읽고, shared memory에서 원래 BF16 값을 재구성한 뒤, 복원된 가중치를 메인 메모리에 두지 않고 곧바로 tensor core 연산에 공급한다. 내부적으로 producer 그룹은 TMA를 사용해 sign과 mantissa, 지수 데이터 또는 palette index, 드문 지수 row의 원문 데이터를 shared memory로 가져와 circular buffer를 채운다. consumer 그룹은 지수와 sign, mantissa를 결합해 BF16 값을 만들고 Hopper의 WGMMA tensor-core instruction에 즉시 넘기며, 이 구조 덕분에 MLP weight matrix에 대해 메모리 버스를 지나는 바이트를 줄일 수 있다.
🧾 핵심 주장 / 시사점
- 이 글의 핵심은 LLM 추론 최적화가 더 빠른 연산만의 문제가 아니라, 매 토큰마다 반드시 읽어야 하는 가중치 데이터를 얼마나 덜 움직이느냐의 문제라는 점이다.
- Unweight가 품질 저하 없는 압축을 선택한 이유는 프로덕션 추론에서 작은 정확도 변화도 사용 사례별로 예측하기 어려운 응답 차이를 만들 수 있기 때문이다.
- 하나의 압축·복원 전략을 고정하지 않고 배치 크기와 weight matrix별로 실행 방식을 고르는 설계는, GPU 성능 최적화가 평균적인 이론보다 실제 하드웨어와 workload 측정에 의존한다는 점을 보여준다.
✅ 액션 아이템
- HBM 대역폭이 병목인 환경을 가정해 Unweight 적용 전후 H100에서 토큰 생성당 메모리 읽기량과 지연을 정량 비교한다.
- BF16 지수 바이트만 Huffman 압축·복원해 비트 단위 동일 출력을 유지하는지 핵심 모델군으로 반복 재현해 15~22% 압축 효과를 검증한다.
- 배치 크기와 행렬 형태별로 full decode, exponent-only decode, palette transcode, direct palette 경로를 분기해 성능/메모리 조건을 비교한다.
❓ 열린 질문
- 배치 크기·행렬 형태가 바뀔 때 어떤 실행 경로가 지연 절감에 가장 유리한가?
- Cloudflare의 95% 사용자 대상 50ms 목표 기준에서 Unweight 도입 시 병목 완화 폭은 어느 정도인가?
- 특정 특화 하드웨어 없이 공용 GPU에서도 무손실 압축이 항상 bit-level 동일 출력 보장을 유지하는가?