Ternary LLM의 1.58-bit 장벽 깨기: BITCOS 가중치 레이아웃
Breaking the 1.58-bit Barrier for Ternary LLMs
TL;DR Highlight
0이 51.5%인 점을 이용해 ternary 가중치를 1.485bit로 저장, 속도 최대 1.27배
Who Should Read
온디바이스·엣지 환경에서 ternary(3값) 양자화 LLM을 돌리며 메모리와 디코딩 속도가 고민인 추론 엔지니어
Core Mechanics
- ternary 모델은 1.625bit씩 쓰고 있었다
- ternary LLM은 가중치를 {-1,0,+1} 세 값 중 하나로 저장한다.
- 정보 이론상 하한은 log2(3)≈1.585bit이다.
- 현재 배포 형식은 5개 가중치를 1바이트에 담는 five-trit packing이고, 실제로는 1.625bit가 된다.
- 세 값이 똑같이 나온다는 가정이 틀렸다
- 29개 ternary LLM의 실제 값 분포를 쟀더니 0이 전체 가중치의 최대 51.5%였다.
- 기존 방식은 -1, 0, +1이 동일 확률이라고 보고 저장한다.
- BITCOS는 비트맵 + 부호 벡터 구조다
- 가중치마다 0이 아닌지 표시하는 presence bitmap(유무 표시표)을 촘촘하게 둔다.
- 0이 아닌 값의 부호만 따로 모아 sign vector로 저장한다.
- 0 비율이 z일 때 가중치당 2−z bit가 든다.
- 29개 중 26개에서 더 작아졌다
- five-trit packing보다 더 작게 저장되는 모델이 26개였다.
- 가장 0이 많은 모델은 가중치당 1.485bit까지 내려갔다.
- 풀어 쓰는 코드도 최적화했다
Community Reactions
- 0 비율을 활용하는 게 당연하다고 생각했다는 반응
- 원래 이렇게 동작하는 줄 알고 친구에게도 그렇게 설명했다는 경험이 있었다.
- 처음부터 적응형으로 설계하지 않은 이유가 궁금하다는 의견이다.
- 메모리에서도 쓸 수 있는지 의문이라는 의견
- 메모리에서는 5 trit/byte 형태로 풀어야 하니 파일 포맷에만 의미 있는 것 아니냐는 질문이 나왔다.
- 가변 길이 인코딩을 메모리 포맷으로 직접 쓸 수 있다는 점이 놀랍다는 반응도 있었다.
- ternary 양자화 자체에 회의적인 의견
- PTQ(학습 후 양자화)에는 vector quantization이나 trellis 기반 방법이 더 낫다는 주장이다.
- 반대로 ASIC에 넣으면 온디바이스 전력 효율에 잘 맞겠다는 기대도 나왔다.
- 대안 인코딩 제안과 엣지 활용 후기
- 산술 부호화(arithmetic coding)로 조금 더 줄일 수 있겠다는 의견이 있었다.
- 6개 trit를 8bit LUT(조회표)로 인코딩하자는 제안도 있었다.
- 제한된 RAM의 엣지에서 LLM을 돌려 보는 사람은 실용적이라고 평가했고, 16GB VRAM에 최신 양자화 모델을 넣으려던 사람도 관심을 보였다.
How to Apply
- 내 ternary 모델의 0 비율부터 재기
- 쓰는 ternary 체크포인트의 가중치 텐서를 읽어 -1, 0, +1 개수를 센다.
- 0 비율 z로 2−z bit와 1.625bit를 비교해 이득이 있는지 계산한다.
- z가 높은 모델 위주로 도입 후보 고르기
- 원문에서 26/29개가 five-trit보다 작아졌으니 z가 0.375보다 큰지부터 확인한다.
- 후보 모델이 정해지면 자기 하드웨어가 AVX-512, AVX2, Xe2 중 무엇인지 확인한다.
- 타깃 하드웨어별 기대 속도 가늠하기
- CPU는 디코드 최대 1.18배, GPU는 최대 1.27배를 기준선으로 잡는다.
- 이 수치는 논문의 5개 플랫폼 기준이므로 자기 환경에서 디코드 처리량을 직접 재서 비교한다.
Try It
# Python (numpy, pip install numpy) - 내 ternary 가중치의 0 비율과 BITCOS 비트수 계산
import numpy as np
# {{w}}: -1, 0, +1 로 이루어진 가중치 배열로 바꿔 넣기 (여기서는 예시용 랜덤 데이터)
w = np.random.choice([-1, 0, 1], size=1_000_000, p=[0.245, 0.51, 0.245])
z = float((w == 0).mean())
print(f"zero density z = {z:.3f}")
print(f"BITCOS: {2 - z:.3f} bit/weight")
print("five-trit: 1.625 bit/weight")
print("BITCOS가 더 작음" if 2 - z < 1.625 else "five-trit가 더 작음")
# 이어서 해 볼 것: 실제 체크포인트의 레이어별 z를 구해 보기Terminology
관련 논문
Mercury 3: 규모를 키운 diffusion LLM, 초당 1,000토큰 이상
Diffusion LLM을 40배 키웠더니 속도 4~8배, 품질은 속도 특화 모델 수준
Timestral: Mistral의 시계열 파운데이션 모델
209M 파라미터 시계열 모델이 3대 벤치마크 1위, CPU에서도 돌아간다
DeepSeek V4.1 Flash 1017 (Max) 성능·속도·가격 분석
DeepSeek V4.1 Flash 1017 Max는 지능 지수 45에 211 tok/s, 입력 $0.30
LLM 프록시를 직접 안 돌리면 무슨 일이 벌어지는지 어떻게 아나
자체 LLM 프록시를 세웠더니 키·모델·캐시 미스를 직접 볼 수 있다
DeepSeek V4.1 Flash 1017: 싼 가격에 1M 컨텍스트를 주는 에이전트용 모델
DeepSeek V4.1 Flash 1017은 입력 $0.05/M, 1M 컨텍스트의 에이전트용 모델
DeepSeek-V4.1-Flash-1017 공개: 더 짧게 생각하고 더 빠르게 일하는 에이전트용 모델
DeepSeek V4.1 Flash 마이너 업데이트로 코딩·에이전트 벤치 점수↑, 실행 시간·출력 길이↓
Llmspeed: 로컬 LLM 속도를 하드웨어 구매 전에 체감해 보는 시뮬레이터
GPU·모델을 고르면 로컬 LLM 속도를 미리 체감하게 해 주는 시뮬레이터