Connect with us

๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ์˜ ์ถ”๋ก  ํ”„๋ ˆ์ž„์›Œํฌ, 1๋น„ํŠธ ๋Œ€ํ˜• ์–ธ์–ด ๋ชจ๋ธ์„ ๋กœ์ปฌ ์žฅ์น˜๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค

์ธ๊ณต์ง€๋Šฅ

๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ์˜ ์ถ”๋ก  ํ”„๋ ˆ์ž„์›Œํฌ, 1๋น„ํŠธ ๋Œ€ํ˜• ์–ธ์–ด ๋ชจ๋ธ์„ ๋กœ์ปฌ ์žฅ์น˜๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค

mm
Understanding 1-bit LLMs and Microsoft's BitNet.cpp Framework

2024년 10월 17일, 마이크로소프트는 BitNet.cpp를 발표했습니다. 이는 1비트 양자화된 대형 언어 모델(Large Language Models, LLM)을 실행하기 위한 추론 프레임워크입니다. BitNet.cpp는 제네릭 AI에서 중요한 발전으로, 1비트 LLM을 효율적으로 표준 CPU에서 실행할 수 있게 해주며, 비싼 GPU가 필요하지 않습니다. 이 개발은 LLM에 대한 접근을 민주화하여, 다양한 장치에서 이용할 수 있게 하고, 기기 내 AI 애플리케이션에 새로운 가능성을 열어줍니다.

1비트 대형 언어 모델 이해

대형 언어 모델(Large Language Models, LLM)은 일반적으로 모델 가중치를 위한 높은 정밀도 부동 소수점 숫자(通常 FP16 또는 BF16)를 사용하기 때문에 상당한 계산 리소스가 필요합니다. 이 필요성으로 인해 LLM을 배포하는 것이 비싸고 에너지 집약적이게 되었습니다.

1비트 LLM의 핵심은 극단적인 양자화 기법을 사용하여 모델 가중치를 -1, 0, 및 1의 세 가지 값만으로 표현하는 것입니다. 따라서 “1.58비트”라는 용어가 사용됩니다(세 가지 상태를 인코딩하는 데 약간 더 많은 비트가 필요하기 때문입니다).

3진 가중치 시스템

개념

BitNet.cpp의 1비트 양자화는 3진 가중치 시스템입니다. BitNet은 각 매개변수에 대해 세 가지 값만 사용합니다:

  • -1 (음수)
  • 0 (중립)
  • 1 (양수)

이로 인해 매개변수당 약 1.58비트의 저장 공간이 필요하게 되어, BitNet b1.58라는 이름이 붙게 됩니다. 매개변수 비트 너비의 급격한 감소는 대부분의 부동 소수점 곱셈이 단순한 덧셈과 뺄셈으로 대체되므로 메모리 사용량과 계산 복잡성이 크게 감소합니다.

수학적 기초

1비트 양자화에는 가중치와 활성화를 다음과 같은 단계를 통해 3진 표현으로 변환하는 것이 포함됩니다:

1. 가중치 이진화

가중치를 이진화하는 것은 가중치를 평균(α)을 기준으로 중앙화하는 것을 포함하며, 이는 3진 표현을 생성합니다. 이 변환은 수학적으로 다음과 같이 표현됩니다:

Wf=Sign(Wα)

여기서:

  • W는 원래 가중치 행렬입니다.
  • α는 가중치의 평균입니다.
  • Sign(x)x > 0인 경우 +1을 반환하며, 그렇지 않으면 -1을 반환합니다.

2. 활성화 양자화

활성화를 양자화하면 입력이 지정된 비트 너비로 제한됩니다:

여기서:

  • Qb = 2(b−1)2^{(b-1)}는 b비트 너비의 최대 양자화 수준입니다.
  • γx의 최대 절대값입니다(표기법: ∣∣x∣∣∞).
  • ε는 계산 중 오버플로를 방지하기 위한 작은 수입니다.

3. 비트 선형 연산

비트 선형 레이어는 전통적인 행렬 곱셈을 다음과 같은 간단한 연산으로 대체합니다:

y=Wf×x^e×(Qbβγ)

여기서:

  • β는 근사 오차를 최소화하기 위한 스케일링 인자입니다.
  • γ는 활성화를 스케일링합니다.
  • Q_b는 양자화 인자입니다.

이 변환은 효율적인 계산을 가능하게 하면서 모델 성능을 유지합니다.

성능 영향

메모리 효율성

3진 가중치 시스템은 메모리 요구 사항을 크게 줄입니다:

  • 전통적인 LLM: 가중치당 16비트
  • BitNet.cpp: 가중치당 1.58비트

이 감소는 16비트 모델과 비교하여 약 90%의 메모리 절약을 의미하며, 더 큰 모델을 동일한 하드웨어 제약 조건에서 실행할 수 있게 합니다.

์—๋„ˆ์ง€ ํšจ์œจ์„ฑ

추론 속도, 에너지 효율성 (Apple M2)

 

์ถ”๋ก  ์†๋„: ๋‘ CPU ๋ชจ๋‘์—์„œ ๋” ๋น ๋ฆ„

추론 속도, 에너지 효율성 (i7-13700H)

1. 추론 속도: 두 CPU 모두에서 더 빠름

추론 속도는 초당 처리되는 토큰 수로 표시됩니다. 다음은 관찰 결과의 요약입니다:

  • Apple M2 Ultra에서: BitNet.cpp는 30B 모델을 위해 Llama.cpp와 비교하여 최대 5.07배의 속도 향상을 달성하며, 125M 모델을 위해 593.43 토큰/초의 피크 속도를 달성합니다. 이는 1.37배의 속도 향상입니다. 3.8B 및 7B와 같은 더 큰 모델에서는 BitNet.cpp가 84.77 토큰/초 이상의 속도를 유지하여 모든 규모에서 효율성을 보여줍니다.
  • Intel i7-13700H에서: BitNet.cpp는 훨씬 더 극적인 속도 향상을 달성합니다. 7B 모델 크기에서 BitNet.cpp는 Llama.cpp와 비교하여 5.68배의 속도 향상을 달성합니다. 125M과 같은 더 작은 모델에서는 389.08 토큰/초를 처리하며, 이는 Llama.cpp보다 2.37배 더 빠릅니다.

2. 에너지 효율성: 에지 디바이스를 위한 게임 체인저

제공된 그래프는 또한 에너지 비용 비교를 보여주며, 토큰당 에너지 소비가 크게 줄어든 것을 나타냅니다:

  • Apple M2 Ultra에서: BitNet.cpp의 에너지 절약은 상당합니다. 700M 모델의 경우 BitNet.cpp는 Llama.cpp와 비교하여 토큰당 55.4% 적은 에너지를 소비하며, 0.314에서 0.140으로 떨어집니다. 이 추세는 더 큰 모델에서도 계속되며, 70B 모델은 70.0%의 에너지 소비 감소를 보여줍니다.
  • Intel i7-13700H에서: BitNet.cpp는 700M 모델을 위해 71.9%의 에너지 절약을 달성하며, 소비를 1.367에서 0.384로 낮춥니다. 70B 모델의 Llama.cpp에 대한 에너지 데이터는 사용할 수 없지만, BitNet.cpp는 여전히 효율적이며, 70B 모델을 위해 17.33의 에너지 소비를 나타냅니다.

3. 인간 읽기 속도 벤치마크를 넘어서기

이 그래프에서 가장 흥미로운 통찰 중 하나는 인간 읽기 속도를 나타내는 빨간 선입니다. 이는 5-7 토큰/초로 표시됩니다. 두 구현체, 특히 BitNet.cpp는 가장 큰 모델을 위해 인간 읽기 속도를 쉽게 초과할 수 있음을 보여줍니다:

  • Apple M2 Ultra에서 BitNet.cpp는 모든 모델 크기에서 인간 읽기 속도를 넘어섭니다. 70B 모델을 위한 최저 속도는 8.67 토큰/초입니다.
  • Intel i7-13700H에서 100B 모델은 1.70 토큰/초를 달성하며, 이는 인간 읽기 속도의 하위 범위에 거의 도달합니다. 더 작은 모델은 모두 이 벤치마크를 넘어섭니다.

학습 고려 사항

직접 전달 추정기(Straight-Through Estimator, STE)

1비트 양자화는 비미분 함수를 도입하므로, 학습에는 특수한 기술인 직접 전달 추정기(Straight-Through Estimator, STE)가 필요합니다. 이 접근법에서, 기울기는 비미분점을 통해 변경되지 않고 흐릅니다. 다음은 Python에서 간단한 구현입니다:

class StraightThroughEstimator(Function):
@staticmethod
def forward(ctx, input):
return input.sign()

@staticmethod
def backward(ctx, grad_output):
return grad_output

혼합 정밀도 학습

학습 중 안정성을 유지하기 위해 혼합 정밀도가 사용됩니다:

  • 가중치 및 활성화: 1비트 정밀도로 양자화됩니다.
  • 기울기 및 최적화 상태: 더 높은 정밀도로 저장됩니다.
  • 잠재 가중치: 높은 정밀도로 유지되어 학습 중 정확한 업데이트를 허용합니다.

대형 학습률 전략

1비트 모델과 관련된 고유한 도전은 작은 업데이트가 이진화된 가중치를 영향을 주지 않을 수 있다는 것입니다. 이를 완화하기 위해, 학습률을 증가시켜 더 빠른 수렴과 전통적인 접근법보다 나은 최적화를 보장합니다.

그룹 양자화 및 정규화

BitNet.cpp는 모델 병렬성을 향상시키기 위해 그룹 양자화 및 정규화를 도입합니다. 가중치와 활성화를 전체 가중치 행렬에 대해 계산하는 대신, BitNet은 가중치와 활성화를 여러 그룹(G)으로 나눕니다.

이 그룹화는 추가적인 그룹 간 통신 없이 효율적인 병렬 처리를 허용하여 대규모 모델 학습 및 추론을 가능하게 합니다.

구현 노트 및 최적화

CPU 최적화

BitNet.cpp는 최고의 CPU 성능을 달성하기 위해 여러 저수준 최적화를 활용합니다:

  • 벡터화된 연산: SIMD 명령어를 사용하여 비트 조작을 효율적으로 수행합니다.
  • 캐시 친화적 메모리 접근: 데이터를 캐시 미스를 최소화하도록 구조화합니다.
  • 병렬 처리: 작업을 여러 CPU 코어에 효과적으로 분산합니다.

다음은 BitNet의 핵심 함수의 예시입니다. 이는 양자화 및 추론을 구현합니다:

def bitlinear_forward(input, weight, scale):
# 입력을 절대최대 양자화로 양자화
input_q = quantize(input)

# 이진 행렬 곱셈 수행
output = binary_matmul(input_q, weight)

# 출력을 원래 정밀도로 스케일링
return output * scale

def quantize(x):
# 절대최대 양자화 수행
scale = torch.max(torch.abs(x))
return torch.clamp(x / scale, -1, 1) * scale

지원 모델

BitNet.cpp의 현재 릴리즈는 다음 Hugging Face의 1비트 LLM을 지원합니다:

  • bitnet_b1_58-large (0.7B 파라미터)
  • bitnet_b1_58-3B (3.3B 파라미터)
  • Llama3-8B-1.58-100B-tokens (8.0B 파라미터)

이러한 모델은 프레임워크의 추론 기능을 보여주기 위해 공개적으로 제공됩니다. 비록 공식적으로 마이크로소프트에서 훈련하거나 릴리즈되지 않았지만, 프레임워크의 다용성을 보여줍니다.

설치 가이드

BitNet.cpp를 시작하려면 다음 단계를 따르세요:

사전 요구 사항

  1. Python >= 3.9
  2. CMake >= 3.22
  3. Clang >= 18
  4. Conda (강력하게 추천)

Windows 사용자의 경우, 다음 구성 요소를 사용하여 Visual Studio를 설치해야 합니다:

  • 데스크톱 개발 with C++
  • C++-CMake Tools for Windows
  • Git for Windows
  • C++-Clang Compiler for Windows
  • MS-Build Support for LLVM Toolset (Clang)

Debian/Ubuntu 사용자의 경우, 자동 설치 스크립트가 제공됩니다:

bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"

단계별 설치

  1. 리포지토리 클론:
    git clone --recursive https://github.com/microsoft/BitNet.git

    cd BitNet
  2. 의존성 설치:
    # 새로운 Conda 환경을 생성(추천)
    conda create -n bitnet-cpp python=3.9
    conda activate bitnet-cpp


    pip install -r requirements.txt
  3. 프로젝트 빌드 및 준비: Hugging Face에서 모델을 직접 다운로드하여 양자화된 형식으로 변환할 수 있습니다:
    python setup_env.py --hf-repo HF1BitLLM/Llama3-8B-1.58-100B-tokens -q i2_s

    또는 모델을 수동으로 다운로드하여 변환할 수 있습니다:

    huggingface-cli download HF1BitLLM/Llama3-8B-1.58-100B-tokens --local-dir models/Llama3-8B-1.58-100B-tokens

    python setup_env.py -md models/Llama3-8B-1.58-100B-tokens -q i2_s

BitNet.cpp로 추론 실행

프레임워크를 사용하여 추론을 실행하려면 다음 명령을 사용합니다:

python run_inference.py -m models/Llama3-8B-1.58-100B-tokens/ggml-model-i2_s.gguf -p "Sandra journeyed to the kitchen. Where is Sandra?" -n 6 -temp 0.7

설명:

  • -m은 모델 파일 경로를 지정합니다.
  • -p는 프롬프트 텍스트를 정의합니다.
  • -n은 예측할 토큰 수를 설정합니다.
  • -temp는 추론 중 샘플링 난도(온도)를 조정합니다.

출력 예시

Sandra journeyed to the kitchen. Where is Sandra?

Answer: Sandra is in the kitchen.

BitNet.cpp의 기술적 세부 사항

비트 선형 레이어

BitNet.cpp는 수정된 트랜스포머 아키텍처를 구현하며, 표준 행렬 곱셈을 BitLinear 연산으로 대체합니다. 이 접근법은 가중치를 0을 기준으로 중앙화하고, 스케일링하여 근사 오차를 줄입니다. 핵심 변환 함수는 다음과 같습니다:


# 1비트 가중치의 이진화 함수
def binarize_weights(W):
alpha = W.mean()
W_binarized = np.sign(W - alpha)
return W_binarized

중앙화된 가중치와 스케일링의 조합은 양자화 오차가 최소화되므로 성능을 유지합니다.

산업 영향

BitNet.cpp는 LLM의 배포에 далеко 갈 수 있는 영향을 미칠 수 있습니다:

  • 접근성: LLM을 표준 장치에서 실행할 수 있게 해주어, 강력한 AI에 대한 접근을 민주화합니다.
  • 비용 효율성: 비싼 GPU가 필요하지 않으므로, 도입 장벽을 낮춥니다.
  • 에너지 효율성: 표준 CPU 기반 추론을 활용하여 에너지를 절약합니다.
  • 혁신: 클라우드 의존성 없이 실시간 언어 번역, 음성 조작자 및 개인 정보 보호 중심 애플리케이션과 같은 기기 내 AI에 대한 새로운 가능성을 열어줍니다.

도전 과제 및 미래 방향

1비트 LLM이 약속하는 것에도 불구하고, 몇 가지 도전 과제가 남아 있습니다. 이는 다양한 작업을 위한 강력한 1비트 모델의 개발, 1비트 계산을 위한 하드웨어 최적화 및 개발자가 이 새로운 패러다임을 채택하는 것을 포함합니다. 또한, 컴퓨터 비전 또는 오디오 작업을 위한 1비트 양자화를 탐색하는 것은 흥미로운 미래 방향입니다.

결론

마이크로소프트의 BitNet.cpp 출시로, 이는 중요한 발전입니다. 표준 CPU에서 1비트 효율적인 추론을 가능하게 함으로써, BitNet.cpp는 AI의 접근성과 지속 가능성을 만듭니다. 이 프레임워크는 더 이동성이 있고, 비용 효율적인 LLM을 위한舞台를 설정하며, 기기 내 AI의 가능성을 더 넓히는 데 기여합니다.

์ง€๋‚œ 5๋…„ ๋™์•ˆ็งใฏ Machine Learning๊ณผ Deep Learning์˜ ๋งค๋ ฅ์ ์ธ ์„ธ๊ณ„์— ๋ชฐ๋‘ํ•ด ์™”์Šต๋‹ˆ๋‹ค.็งใฎๆƒ…็†ฑใจๅฐ‚้–€็Ÿฅ่ญ˜ใฏใ€AI/ML์— ์ค‘์ ์„ ๋‘” 50๊ฐœ ์ด์ƒ์˜ ๋‹ค์–‘ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ์—”์ง€๋‹ˆ์–ด๋ง ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค.็งใฎ็ถ™็ถš็š„ใช ํ˜ธ๊ธฐ์‹ฌ์€ ๋˜ํ•œ ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ ๋ถ„์•ผ๋กœ็งใฎ ๊ด€์‹ฌ์„ ๋Œ์—ˆ๊ณ , ๋” ๊นŠ์ด ํƒ๊ตฌํ•˜๊ณ  ์‹ถ์€ ๋ถ„์•ผ์ž…๋‹ˆ๋‹ค.