[论文品鉴] 1-bit LLM

今天看了一篇4月最新论文 <BitNet b1.58 2B4T Technical Report>,觉得有点意思,决定写点东西沉淀一下。

1-bit LLM

首先要整明白的就是1-bit LLM,这年头都在搞量化,但从没听说过能量化到1-bit,翻了一下arxiv才发现也不是啥新东西,24年的论文 <The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits> 就有过相关的论证,下面简单介绍下。

1-bit LLM的实现,主要靠的是极致的量化新的架构设计,把传统浮点参数量化为极致的bit表示,如三值 { − 1 , 0 , 1 } \{-1,0,1\} {101}

说到这肯定有会疑问,1 bit怎么可能表示3个值?

正常情况下1 bit就是 { 0 , 1 } \{0,1\} {0,1},这是底层操作系统二进制决定的,所以如果想要表示3个值,那么理论上至少需要 l o g 2 3 ≈ 1.58 b i t s log_23 ≈ 1.58 bits log231.58bits 才行。因为本质上三值法并没有创建新的底层系统,还是二进制,也就只有 { 0 , 1 } \{0,1\} {0,1},所以k 个 bit 可以表示出 2 k 2^k 2k 种组合,那么对于3种数值就是 2 k = 3 2^k=3 2k=3 得出 k = l o g 2 3 ≈ 1.58 k=log_23≈1.58 k=log231.58 它是个平均值。

掩码存储

另一方面,三值在底层存储的时候,采用了两种方式实现:

  • 将多个参数打包到整数中,例如8个bit存5个值
  • 特殊编码和掩码

这里详细讲解一下有趣的特殊编码和掩码设计:

  • 特殊编码:1 bit 用于存储符号,所以通过这1 bit可以表示出三值中的两个,也就是 { − 1 , + 1 } \{-1,+1\} {1,+1}
  • 掩码:还剩的那个 0 0 0 咋整,这也正是1 bit LLM实现的关键, 0 0 0 靠的正是掩码实现的,而非存储实际数值。

整体上分三步走:

  1. 三值量化:例如对于4个参数 [ + 1 , 2 , 0 , − 0.8 , 0 ] [+1,2,0,-0.8,0] [+1,2,0,0.8,0] ,首先三值离散量化为 [ + 1 , 0 , − 1 , 0 ] [+1,0,-1,0] [+1,0,1,0]
  2. 生成掩码:这一步只需要标记出非零位置,算是一种位置编码 B i t m a s k = [ 1 , 0 , 1 , 0 ] Bitmask=[1,0,1,0] Bitmask=[1,0,1,0],底层存储二进制 1010 1010 1010
  3. 符号存储:这一步只需要存储非零元素的符号 S y m b o l s = [ 1 , 0 ] Symbols=[1,0] Symbols=[1,0],其中 + 1 +1 +1的符号表示为 1 1 1 − 1 -1 1的符号表示为 0 0 0,底层存储二进制 10 10 10

所以通过以上新的存储设计,实现了4个参数6bit存储,也就是对于 N N N个参数,需要 N N N个位置编码与 0.5 N 0.5N 0.5N个符号编码(这里假设50%是0)那么就有 1.5 N 1.5N 1.5N,所以每个参数平均需要 1.5 N N = 1.5   b i t s \frac{1.5N}{N}=1.5\ bits N1.5N=1.5 bits

量化函数

W q u a n t = S i g n ( W ) ⋅ γ + ϵ W_{quant} = Sign(W)·γ + ϵ Wquant=Sign(W)γ+ϵ ,动态缩放因子和残差项不必说,只需要关注 s i g n ( ) sign() sign()

因为三值离散量化,也就是把浮点数W量化为 [ + 1 , 0 , − 1 , 0 ] [+1,0,-1,0] [+1,0,1,0] ,那么对于一个阈值Δ,则有: W q u a n t = { + 1 if w > Δ 0 if -Δ ≤ w ≤ Δ − 1 if w < -Δ W_{quant}= \begin{cases} +1& \text{if w > Δ}\\ 0& \text{if -Δ ≤ w ≤ Δ} \\ -1& \text{if w < -Δ} \end{cases} Wquant= +101if w > Δif -Δ ≤ w ≤ Δif w < -Δ
正好 S i g n ( ) Sign() Sign()完美符合条件,对于小于0的数结果为-1,大于0的数结果为1,0的结果为0。

BitNet b1.58 2B-4T

上面说的都是理论,微软基于此开源了,通过4 trillon个token训练出来的2B模型 BitNet b1.58 2B4T的LLM,Hugging face上已经可以看到了,它主要有2点核心设计:

  1. BitLinear线性层 替代了全精度线性层:也就是三值量化
  2. 硬件优化:有专用的推理框架bitnet.cpp,通过查表法和smid加速了推理

使用方式的选择也比较全:python、cpp、docker等,同时支持cpu、gpu

import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' # vpn慢可以换成国内镜像

!pip install git+https://github.com/shumingma/transformers.git # 亲测,目前还必须使用这个版本的库

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "microsoft/bitnet-b1.58-2B-4T"

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    torch_dtype=torch.bfloat16
)

messages = [
    {"role": "system", "content": "You are a helpful AI assistant."},
    {"role": "user", "content": "How are you?"},
]
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
chat_input = tokenizer(prompt, return_tensors="pt").to(model.device)

chat_outputs = model.generate(**chat_input, max_new_tokens=50)
response = tokenizer.decode(chat_outputs[0][chat_input['input_ids'].shape[-1]:], skip_special_tokens=True) # Decode only the response part
print("\nAssistant Response:", response)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值