BitNet 1.58-bit:微软如何用三个值就让大模型在 CPU 上飞奔
当所有人还在讨论「模型参数越大效果越好」时,微软已经悄悄把大模型的存储压缩了 20 倍——不是靠更好的架构,而是靠一个看似疯狂的想法:能不能只用一个比特来表示每个模型参数?答案是能,而且效果还不错。
背景:大模型的「内存焦虑」
每个程序员第一次跑大模型时,都会被那个数字震惊:7B 参数的模型,光权重文件就要 14GB。放到显存里,需要 28GB。这还没算 KV Cache、激活值、中间计算结果。
于是所有人在做同一件事:压缩。
- FP16 → 7B 模型 14GB
- INT8 → 7B 模型 7GB
- INT4 → 7B 模型 3.5GB
每次压缩,性能都在下降一点。精度损失,成了悬在头顶的剑。
BitNet 提出的问题是:能不能直接用 1 个比特(不是 4 个,不是 8 个,而是 1 个)来表示整个模型?
答案是:能,而且有 1.58-bit 就够了。
一、什么是 1.58-bit?
1.1 从 32-bit 到 1-bit 的压缩之路
传统 LLM 的权重是 FP32(32 位浮点数),每个参数用 32 个 bit 表示。
# FP32 权重示例
weight_fp32 = 0.123456789012345 # 32-bit float, 4 bytes
# 内存: 4 bytes = 32 bits per parameter
量化到 INT8 后:每个参数 8 个 bit,压缩 4 倍。
# INT8 量化
weight_int8 = int(weight_fp32 * 127) # 8-bit int, 1 byte
# 内存: 1 byte = 8 bits per parameter
量化到 INT4 后:每个参数 4 个 bit,压缩 8 倍。
# INT4 量化
weight_int4 = int(weight_fp32 * 7) # 4-bit int, 0.5 byte
# 内存: 0.5 byte = 4 bits per parameter
那 1-bit 呢?
# 1-bit: 只有 0 和 1(或者 -1 和 +1)
weight_bit = 1 if weight_fp32 > 0 else 0 # 1-bit, 0.125 byte
# 内存: 0.125 byte = 1 bit per parameter
32 倍压缩。7B 模型从 28GB 显存,变成 875MB。普通 CPU 就能跑。
1.2 为什么是 1.58 而不是 1?
如果你只允许两个值(-1 和 +1),每个参数确实是 1-bit。但 BitNet 用的是 三个值:-1、0、+1。
这就是 1.58-bit 的来源:
$$\text{平均比特数} = \log_2(3) \approx 1.585$$
为什么用三个值?因为 0 很重要。
- 权重为 0 时,不参与计算,节省算力
- 某些神经元本来就是「沉默」的,用 0 表示完全合理
- 三个值比两个值表达能力更强,精度损失更小
FP32: -3.14159... to +3.14159... (每次更新涉及32位浮点运算)
INT4: -8 to +7 (每次更新涉及4位整型运算)
1-bit: -1 or +1 (每次更新只涉及1位比较)
1.58-bit: -1, 0, or +1 (每次更新涉及1.58位,但有稀疏优化)
二、BitNet 的核心技术
2.1 权重二值化:SignRound 函数
BitNet 的权重不是通过「训练后量化」得到的,而是在 训练阶段就直接用二值权重。
import torch
import torch.nn as nn
def sign_round(x):
"""
BitNet 的核心:SignRound 函数
将 FP32 权重映射到 {-1, 0, +1}
原理:
- 如果权重 > +gamma(正阈值)→ +1
- 如果权重 < -gamma(负阈值)→ -1
- 介于两者之间 → 0
"""
gamma = 0.5 # 可学习的阈值
return torch.where(x > gamma, 1.0,
torch.where(x < -gamma, -1.0, 0.0))
class BitLinear(nn.Module):
"""
BitNet 的核心层:用二值权重替代 FP32 权重
"""
def __init__(self, in_features, out_features):
super().__init__()
# 权重始终是 {-1, 0, +1}
self.weight = nn.Parameter(
torch.randn(in_features, out_features)
)
# 缩放因子:弥补量化精度损失
self.alpha = nn.Parameter(torch.ones(1))
def forward(self, x):
# 权重二值化
w_binarized = sign_round(self.weight)
# 计算时用 INT8 激活 + 二值权重
# 不需要矩阵乘法,直接用位操作
output = x @ w_binarized.T * self.alpha
return output
关键设计:
# 对比:传统 Linear vs BitNet BitLinear
# 传统 Linear: y = x @ W
# FP32 乘法: O(n) 浮点运算
# BitNet BitLinear: y = x @ sign(W) * alpha
# 位操作: O(n) 比较运算 + O(1) 缩放
2.2 训练时量化 vs 训练后量化
这是 BitNet 最核心的创新。
传统量化的流程:
1. 训练 FP32 模型 → 达到满意精度
2. 后量化 → 转换为 INT8/INT4
3. 精度损失不可避免(PTQ, Post-Training Quantization)
BitNet 的流程:
1. 直接用二值权重训练(训练时量化)
2. 模型从一开始就是 {-1, 0, +1}
3. 精度损失极小(因为一直在用低精度训练)
# 传统 PTQ 量化(精度损失大)
def post_training_quantize(model):
for name, param in model.named_parameters():
# 先训练,再量化
quantized = torch.round(param / scale) # 精度损失发生在这里
# 损失无法通过训练恢复
# BitNet 训练时量化(精度损失小)
class BitNetModel(nn.Module):
def __init__(self):
self.weight = nn.Parameter(torch.randn(...))
def forward(self, x):
# 训练时直接用二值权重
# 梯度会更新原始 FP32 权重
# 但前向传播始终用 sign(W)
w_binary = sign_round(self.weight)
return x @ w_binary.T
为什么训练时量化精度损失小?
因为量化误差被纳入梯度计算中持续优化,而不是一次性「截断」。
# STE (Straight-Through Estimator)
# 用于解决二值化后梯度不可导的问题
def straight_through_estimator(x, x_quantized):
"""
前向:quantize
反向:直通(忽略量化误差,梯度 = 1)
"""
return (x_quantized - x).detach() + x
# 使用 STE 后,梯度可以正常回传
class BitLinearSTE(nn.Module):
def forward(self, x):
# 前向:二值化
w_bin = sign_round(self.weight)
# 反向:直通
w_ste = (w_bin - self.weight).detach() + self.weight
return x @ w_ste.T
2.3 1-bit 矩阵乘法:位运算加速
传统矩阵乘法需要大量浮点运算,而 BitNet 的核心运算是位操作。
# 传统矩阵乘法 O(n*m*k)
def naive_matmul(A, B):
# A: (batch, m, k)
# B: (k, n)
# O(batch * m * k * n) 浮点乘法
result = torch.zeros(batch, m, n)
for i in range(m):
for j in range(n):
result[:, i, j] = (A[:, i, :] * B[:, :, j]).sum(dim=-1)
return result
# BitNet: 利用二值权重的特殊性,用位运算替代乘法
def bitnet_matmul(A_int8, W_binary):
"""
BitNet 的核心:INT8 激活 × 二值权重
原理:二值矩阵乘法可以分解为:
1. 统计每列中 +1 的数量 (count_ones)
2. 统计每列中 -1 的数量 (count_minus_ones)
3. 结果 = (count_ones - count_minus_ones) * alpha
"""
batch_size, m, k = A_int8.shape
n = W_binary.shape[1]
result = torch.zeros(batch_size, m, n, device=A_int8.device)
for j in range(n):
# 提取第 j 列的权重
w_col = W_binary[:, j] # (k,)
# 分离 +1 和 -1 的索引
pos_mask = (w_col == 1)
neg_mask = (w_col == -1)
# 分别累加(都是整数运算,比乘法快很多)
pos_sum = A_int8[:, :, pos_mask].sum(dim=-1) # (batch, m)
neg_sum = A_int8[:, :, neg_mask].sum(dim=-1) # (batch, m)
result[:, :, j] = pos_sum - neg_sum
return result * alpha
更底层的实现,用位运算(B好):
// bitnet.cpp 的核心计算单元
// 使用 SIMD 指令集加速
void bitnet_matrix_multiply(
const int8_t* activations, // INT8 激活值
const int8_t* binary_weights, // 二值权重 (-1/0/+1 编码为 2-bit)
float* output,
int batch, int m, int k, int n
) {
// 按块处理,利用 CPU 缓存层次
const int BM = 64; // Batch blocking
const int BK = 128; // K blocking
for (int ii = 0; ii < m; ii += BM) {
for (int jj = 0; jj < n; jj += BK) {
// 对角线 +1 和 -1 计数
int popcnt_plus[BK] = {0};
int popcnt_minus[BK] = {0};
for (int kk = 0; kk < k; kk++) {
// 读取一块激活值
int8_t a_col = activations[ii * k + kk]; // INT8
// 读取二进制权重(打包为 8 个权重/字节)
// 用 popcnt (population count) 统计 1 的个数
uint8_t w_packed = binary_weights[jj * k + kk];
// 统计 +1 和 -1 的数量(位运算,CPU 原生支持)
int plus = __builtin_popcount(w_packed & 0x55); // +1 mask
int minus = __builtin_popcount(w_packed & 0xAA); // -1 mask
// 更新计数
for (int j = 0; j < BK; j++) {
popcnt_plus[j] += (plus >> j & 1) * a_col;
popcnt_minus[j] += (minus >> j & 1) * a_col;
}
}
// 输出 = (正和 - 负和) * alpha
for (int j = 0; j < BK; j++) {
output[ii * n + jj + j] = (popcnt_plus[j] - popcnt_minus[j]) * alpha;
}
}
}
}
三、bitnet.cpp:1-bit LLM 的高效推理引擎
微软配套推出了 bitnet.cpp,为 1-bit 模型提供 CPU 高效推理。
3.1 核心特性
| 特性 | 说明 |
|---|---|
| 零依赖 | 纯 C/C++ 实现,无外部库依赖 |
| 多架构支持 | x86_64、ARM64、Apple Silicon |
| SIMD 优化 | AVX2/AVX512/NEON 指令集 |
| 内存优化 | 2B 模型仅需 400MB 内存 |
| 延迟 | 29ms/token(x86_64 CPU) |
| 功耗 | 能耗降低 55%-82% |
3.2 安装与使用
# 克隆 bitnet.cpp
git clone https://github.com/microsoft/BitNet.git
cd BitNet
# 构建(x86_64 Linux)
mkdir build && cd build
cmake ..
make -j$(nproc)
# 下载 BitNet 1.58 模型
# microsoft/BitNet-b1.58-2B-4T
# GGUF 格式:bitnet-b1_58-2b-4t.gguf
# 运行推理
./bin/bitnet -m bitnet-b1_58-2b-4t.gguf \
-p "Write a Python function to reverse a linked list" \
-t 8 \
-c 4096
3.3 Python API
import subprocess
import json
def run_bitnet_inference(prompt, model_path="/models/bitnet-b1_58-2b-4t.gguf"):
"""
通过 bitnet.cpp 的 CLI 接口调用 BitNet 模型
Args:
prompt: 输入文本
model_path: 模型文件路径
Returns:
生成的文本响应
"""
cmd = [
"./bin/bitnet",
"-m", model_path,
"-p", prompt,
"-t", "4", # 线程数
"-c", "2048", # 上下文长度
"--log-disable" # 禁用日志
]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.stdout.strip()
# 示例
response = run_bitnet_inference(
"Explain the difference between binary search and linear search"
)
print(response)
3.4 WebUI 部署(Ollama 兼容)
# 用 Ollama 运行 BitNet(需要 Ollama 0.1.50+)
# 下载 GGUF 模型后,放入 ~/.ollama/models/
# 创建 Modelfile
echo 'FROM ./bitnet-b1_58-2b-4t.gguf' > Modelfile
# 导入模型
ollama create bitnet-1.58 -f Modelfile
# 运行
ollama run bitnet-1.58
# REST API
curl http://localhost:11434/api/generate -d '{
"model": "bitnet-1.58",
"prompt": "Write a hello world in Rust"
}'
3.5 性能对比
# bitnet.cpp 性能基准测试结果
benchmarks = {
# 模型精度 | 设备 | 内存占用 | 推理速度 | 能耗降低
"FP32": {"device": "GPU", "memory_gb": 28, "ms_per_token": 15, "power_reduction": "0%"},
"INT8": {"device": "CPU", "memory_gb": 7, "ms_per_token": 45, "power_reduction": "30%"},
"INT4": {"device": "CPU", "memory_gb": 3.5, "ms_per_token": 55, "power_reduction": "45%"},
"BitNet 1.58": {"device": "CPU", "memory_gb": 0.4, "ms_per_token": 29, "power_reduction": "71%"},
}
# 对比表格
print(f"{'精度':<12} {'设备':<8} {'内存':<12} {'速度':<12} {'能耗':<10}")
print("-" * 60)
for k, v in benchmarks.items():
print(f"{k:<12} {v['device']:<8} {f\"{v['memory_gb']}GB\":<12} {f\"{v['ms_per_token']}ms\":<12} {v['power_reduction']:<10}")
# 输出:
# 精度 设备 内存 速度 能耗
# ------------------------------------------------------------
# FP32 GPU 28GB 15ms 0%
# INT8 CPU 7GB 45ms 30%
# INT4 CPU 3.5GB 55ms 45%
# BitNet 1.58 CPU 0.4GB 29ms 71%
四、模型架构细节
4.1 BitNet b1.58-2B-4T 规格
| 参数 | 值 |
|---|---|
| 模型类型 | 1.58-bit 量化的 LLM |
| 参数量 | 2B (20亿参数) |
| 权重精度 | -1, 0, +1 (平均 1.58 bit) |
| 激活精度 | INT8 |
| 上下文长度 | 4096 tokens |
| 内存占用 | 约 400MB |
| 推理速度 | ~29ms/token (x86 CPU) |
| 训练数据 | 4T tokens |
| 开发机构 | 微软研究院 |
| 开源协议 | MIT |
4.2 架构设计
# BitNet 1.58 的层结构与标准 Transformer 相同
# 但每个 Linear 层都替换为 BitLinear
class BitNetConfig:
vocab_size = 100_288
hidden_size = 2048
num_layers = 24
num_heads = 16
intermediate_size = 5504
max_position_embeddings = 4096
class BitNetLayer(nn.Module):
def __init__(self):
self.attention = CausalAttention(
# Q/K/V/Output 全用 BitLinear
q_proj = BitLinear(2048, 2048),
k_proj = BitLinear(2048, 64),
v_proj = BitLinear(2048, 64),
o_proj = BitLinear(2048, 2048),
)
self.mlp = MLP(
# FFN 也用 BitLinear
gate_proj = BitLinear(2048, 5504),
up_proj = BitLinear(2048, 5504),
down_proj = BitLinear(5504, 2048),
)
# 每个 BitLinear 层替换后:
# - 参数存储从 FP32 → 1.58-bit(压缩 ~20倍)
# - 矩阵乘法从浮点 → 位运算(加速 ~4-8倍)
4.3 量化感知训练详解
class QuantizationAwareTraining:
"""
BitNet 的量化感知训练流程
核心思想:在训练阶段就模拟低精度推理
让模型「适应」量化带来的误差
"""
def __init__(self, model):
self.model = model
self.optimizer = torch.optim.AdamW(model.parameters())
def step(self, batch):
# 前向传播:使用二值权重
with torch.no_grad():
# 训练时强制二值化
for name, module in self.model.named_modules():
if isinstance(module, BitLinear):
module.weight.data = sign_round(module.weight)
# 计算损失
output = self.model(batch)
loss = output.loss
# 反向传播
loss.backward()
# 更新原始权重(不是二值权重)
self.optimizer.step()
self.optimizer.zero_grad()
# 关键:权重仍然是 FP32,只有前向时二值化
# 这保证了梯度更新的精度
def sign_round STE(x):
"""
带直通估计的二值化函数
前向(Forward):
- 强制二值化:{-1, 0, +1}
反向(Backward):
- 忽略量化,梯度直通
- 这样梯度可以正常回传到 FP32 权重
"""
# 前向
x_hard = torch.where(x > 0, 1.0, -1.0)
# 反向:用 detach() 截断反向路径
# 让梯度 = 1,实现「直通」
x_ste = (x_hard - x).detach() + x
return x_ste
五、实战:在本地 CPU 上跑起来
5.1 环境准备
# 要求
# - Linux/macOS/Windows (WSL2)
# - CMake 3.10+
# - C++ 编译器(gcc/clang)
# - 4GB+ RAM(BitNet 1.58 只需要 400MB)
5.2 构建 bitnet.cpp
# macOS (Apple Silicon)
git clone https://github.com/microsoft/BitNet.git
cd BitNet
# 使用 Apple Silicon 优化构建
mkdir build && cd build
cmake -DGGML_SYCL=ON -DGGML_ACCELERATE=ON ..
make -j$(sysctl -n hw.ncpu)
# 测试
./bin/bitnet --help
5.3 下载模型
# 方法一:Hugging Face Hub(推荐)
pip install huggingface_hub
python3 << 'PYEOF'
from huggingface_hub import hf_hub_download
model_path = hf_hub_download(
repo_id="microsoft/BitNet-b1.58-2B-4T-GGUF",
filename="bitnet-b1.58-2b-4t.Q4_K_M.gguf", # Q4 量化版本
local_dir="./models"
)
print(f"Model downloaded to: {model_path}")
PYEOF
# 方法二:直接下载
wget https://huggingface.co/microsoft/BitNet-b1.58-2B-4T-GGUF/resolve/main/bitnet-b1.58-2b-4t.Q4_K_M.gguf
5.4 推理脚本
#!/usr/bin/env python3
"""
BitNet 1.58 本地推理脚本
不需要 GPU,纯 CPU 运行
"""
import subprocess
import tempfile
import os
class BitNetRunner:
def __init__(self, bitnet_bin_path, model_path):
self.binary = bitnet_bin_path
self.model = model_path
def generate(self, prompt, max_tokens=256, temperature=0.7, threads=4):
"""
生成文本
Args:
prompt: 输入提示
max_tokens: 最大生成 token 数
temperature: 温度参数
threads: CPU 线程数
Returns:
生成的文本
"""
# 创建临时输入文件
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
f.write(prompt)
input_path = f.name
try:
cmd = [
self.binary,
"-m", self.model,
"-f", input_path,
"-t", str(threads),
"-c", "2048",
"--temp", str(temperature),
"-n", str(max_tokens),
"--log-disable"
]
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=60
)
if result.returncode != 0:
return f"Error: {result.stderr}"
return result.stdout.strip()
finally:
os.unlink(input_path)
def batch_generate(self, prompts, **kwargs):
"""批量生成"""
return [self.generate(p, **kwargs) for p in prompts]
# 使用示例
runner = BitNetRunner(
bitnet_bin_path="./bitnet",
model_path="./models/bitnet-b1.58-2b-4t.Q4_K_M.gguf"
)
# 单条生成
result = runner.generate(
prompt="Write a Python decorator that memoizes function calls:",
max_tokens=512,
temperature=0.8,
threads=4
)
print(result)
# 批量生成
prompts = [
"What is the time complexity of quicksort?",
"Explain the CAP theorem in distributed systems",
"How does a bloom filter work?",
]
for i, response in enumerate(runner.batch_generate(prompts, max_tokens=256)):
print(f"\n--- Response {i+1} ---")
print(response)
5.5 Docker 部署
# Dockerfile for BitNet 1.58
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
cmake gcc g++ wget \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# 克隆 bitnet.cpp
RUN git clone https://github.com/microsoft/BitNet.git
# 构建
RUN mkdir -p BitNet/build && \
cd BitNet/build && \
cmake .. && \
make -j$(nproc)
# 复制模型
COPY bitnet-b1.58-2b-4t.Q4_K_M.gguf /models/
# 运行
CMD ["/app/BitNet/build/bin/bitnet", "-m", "/models/bitnet-b1.58-2b-4t.Q4_K_M.gguf"]
# 构建并运行
docker build -t bitnet-158 .
docker run --rm -it \
-v $(pwd)/models:/models \
bitnet-158 \
./BitNet/build/bin/bitnet \
-m /models/bitnet-b1.58-2b-4t.Q4_K_M.gguf \
-p "Hello world"
六、与传统量化的深度对比
6.1 各量化方法一览
| 方法 | 精度 | 内存占用 | 速度 | 精度损失 | 适用场景 |
|---|---|---|---|---|---|
| FP32 | 32-bit | 基准 | 基准 | 0% | 服务器 |
| FP16 | 16-bit | 50% | 85% | <1% | 服务器 |
| BF16 | 16-bit | 50% | 80% | <1% | 服务器 |
| INT8 | 8-bit | 25% | 50% | 1-3% | 服务器/CPU |
| INT4 | 4-bit | 12.5% | 40% | 3-8% | 边缘设备 |
| INT2 | 2-bit | 6.25% | 30% | 8-15% | 极致边缘 |
| BitNet 1.58 | 1.58-bit | ~5% | 70% | <5% | 本地/嵌入式 |
6.2 为什么 1.58-bit 比 INT4 更好?
这是一个反直觉的结论:1.58-bit 的精度损失比 INT4 更小。
原因:
INT4:每个参数 4-bit,权重被「截断」到 16 个离散值
- 精度损失来自:截断误差
- 问题:某些重要的权重被「压」到了相近的值
BitNet 1.58:每个参数 1.58-bit,权重只有三个值
- 精度损失来自:二值化误差
- 但:由于训练时量化,模型学会了「适应」二值化
- 结果:模型学会了用少数几个值表达更多信息
# 实验数据(B好)
results = {
"task": ["ARC-Challenge", "HellaSwag", "MMLU", "TruthfulQA", "Winogrande"],
"FP32": [47.3, 79.7, 61.8, 50.4, 74.2],
"INT4": [45.1, 78.2, 59.3, 49.1, 72.8],
"BitNet1.58": [45.8, 79.1, 60.5, 49.8, 73.5],
}
# BitNet 1.58 在多个 benchmark 上表现优于 INT4
# 这就是「训练时量化」的优势
6.3 内存占用的革命
# 以 7B 模型为例,对比各量化方法的内存占用
model_params = 7_000_000_000 # 70亿参数
memory_fp32 = model_params * 4 / (1024**3) # 26GB
memory_fp16 = model_params * 2 / (1024**3) # 13GB
memory_int8 = model_params * 1 / (1024**3) # 6.5GB
memory_int4 = model_params * 0.5 / (1024**3) # 3.25GB
memory_1bit = model_params * 0.125 / (1024**3) # 0.81GB
print(f"FP32: {memory_fp32:.2f} GB")
print(f"FP16: {memory_fp16:.2f} GB")
print(f"INT8: {memory_int8:.2f} GB")
print(f"INT4: {memory_int4:.2f} GB")
print(f"1-bit: {memory_1bit:.2f} GB") # 可以在树莓派上跑了
七、应用场景与局限性
7.1 适合的场景
- 本地推理:没有 GPU 的开发者,想在笔记本上跑大模型
- 边缘部署:嵌入式设备、IoT(内存和算力都受限)
- 低功耗场景:电池供电设备,需要延长续航
- 服务端成本优化:大批量部署时,CPU 成本远低于 GPU
- 教育/演示:想让更多人以低成本接触 LLM
7.2 不适合的场景
- 高精度任务:需要极强数学能力或长上下文推理的任务
- 实时性要求极高的场景:虽然快,但 29ms/token 对某些场景还是不够
- 生成质量优先的场景:牺牲一点生成质量换取可运行性的场景
7.3 未来方向
微软的路线图显示:
- 更大参数模型:从 2B 到 7B、13B 的 1.58-bit 版本
- 多语言支持:扩展到非英语语种
- 更快的推理引擎:适配更多硬件平台
- 量化自动化:自动找到最优的量化参数
八、总结:从「大力出奇迹」到「精准压缩」
BitNet 1.58 给我们带来一个重要启示:大模型不一定需要大显存。
当行业还在追求更大的参数、更贵的 GPU 时,微软在探索一条相反的路:如何用最少的比特表达最多的智能。
这不是「更差」的模型,而是「更聪明」的压缩。用 {-1, 0, +1} 三个值,配合训练时量化、位运算加速、稀疏计算,让 2B 参数的模型只需要 400MB 内存、29ms/token 的推理速度,就能达到接近 INT4 的精度。
这不是终点,而是起点。 当 1.58-bit 被验证可行,下一步是什么?
- 更激进的 1-bit 纯二值化(只有 -1 和 +1)
- 混合精度:核心层用 FP32,边缘层用 1-bit
- 硬件级支持:CPU/GPU 原生支持 1-bit 矩阵运算
大模型的民主化,才刚刚开始。
相关资源:
- GitHub:https://github.com/microsoft/BitNet
- 官方文档:https://github.com/microsoft/BitNet/blob/main/README.md
- 模型下载:https://huggingface.co/microsoft/BitNet-b1.58-2B-4T-GGUF
- bitnet.cpp:https://github.com/microsoft/BitNet/tree/main/bitnet.cpp