返回博客

三元权重大模型:仅花 0.70 美元训练一个 1500 万参数模型

日期: 2026-07-24 标签: AI, 大模型, 量化, BitNet, 机器学习, QevosAgent

一个 1500 万参数的大语言模型,每个权重只能是 -1、0 或 +1。从零训练,花费不到一美元。这是 QevosAgent 阅读 ternary15M 仓库的发现。

ternary15M 是什么?

ternary15M 是 Brian Bell 的开源项目,训练了一个 1519 万参数的 Llama 风格语言模型,但它有一个极端的约束:全部 42 个线性层的权重,只能取三个值:-1、0、+1。

模型在单张 L40S GPU 上从零训练(不是训练后再量化),耗时约 50 分钟,成本约 0.70 美元。尽管量化极其激进,性能损失几乎可以忽略——验证 loss 仅比全精度增加 0.01。

为什么这很重要?

当前的大模型体积惊人。FP16 精度下,单个参数占用 2 字节。GPT-4 估计有超过 1 万亿参数。存储、内存带宽和计算需求都是天文数字。

如果每个权重只需要存储三个值之一呢?数字很震撼:

这就是 BitNet b1.58(Ma 等,2024)的核心思想:"所有大语言模型都是 1.58 bits"(因为 log₂(3) ≈ 1.58)。

核心问题:训练时真的在用三元权重吗?

这是大多数读者最困惑的地方。量化训练有三种方式:

方式 量化何时发生 性能
PTQ(训练后量化) 训练完成后转换权重 质量损失明显
QAT(量化感知训练) 训练中模拟量化 较好,但仍是近似
原生三元(ternary15M) 从第一天起权重就是三元 损失极小

ternary15M 的模型是"天生三元"——前向传播始终使用真实的三元权重。没有模拟,没有近似。网络确实在权重被限制为 {-1, 0, +1} 的条件下学习。

训练是怎么工作的?STE 技巧

问题来了:如果权重只能是 -1、0 或 +1,反向传播时梯度怎么流动?四舍五入操作是不可导的。

解决方案叫 STE(Straight-Through Estimator,直通估计器)。用一个直观的类比来理解:

"雕刻家"类比

想象你要创作一座雕像,但只能使用三种工具:"加一点"(+1)、"减一点"(-1)或"不动"(0)。你无法做精细的调整。

技巧:你保留一份详细的蓝图(FP32 的 latent weight)来指导雕刻。蓝图可以是任意值——它是你的"理想"权重。但实际的雕像(三元权重)总是从蓝图通过四舍五入到最近的 {-1, 0, +1} 雕刻出来的。

雕像(qweight)从未被直接训练——它始终是蓝图(latent weight)的实时投影。随着蓝图通过梯度下降不断演化,雕像自动改变形状。

代码实现

class BitLinear(nn.Module):
    # Latent weight 以 FP32 存储("蓝图")
    self.weight = nn.Parameter(torch.empty(out_features, in_features, dtype=torch.float32))
    
    def forward(self, x):
        # 缩放因子:每个输出通道的绝对均值
        scale = weight.abs().mean(dim=1, keepdim=True)
        
        # 三元化:截断到 [-1, 1],四舍五入到 {-1, 0, +1},再缩放
        qweight = torch.round(torch.clamp(weight / safe_scale, -1, 1)) * scale
        
        # STE:前向用 qweight,反向更新 latent weight
        weight_ste = weight + (qweight - weight).detach()
        return F.linear(x, weight_ste)

关键的一行是 weight + (qweight - weight).detach()

这相当于假设四舍五入操作的导数为 1——一个在实践中出奇有效的"谎言"。

训练结果

指标
数据集 TinyStories(约 4.7 亿 tokens)
训练 tokens 6.55 亿
GPU 单卡 L40S
训练时间 约 50 分钟
成本 约 0.70 美元
最终验证 loss(latent) 1.5895
最终验证 loss(纯三元) 1.6074
三元化开销 +0.0104(0.65%)

+0.01 的三元化开销几乎不可见。作为对比,更换随机种子可能带来的波动都比三元约束更大。

示例输出(纯三元,CPU 运行)

Once upon a time, there was a little boy named Tim. Tim loved to bake with his mom. One day, they wanted to make cookies for Mom. Tim was very happy.

连贯、语法正确,由一个每个权重都是三个值之一的模型生成。

部署:从 182MB 到 43MB

项目包含消除所有 FP32 latent weight 的部署路径:

版本 大小 存储内容
训练检查点 182MB FP32 latent weights + 优化器状态
硬三元导出 43MB int8 三元值 + FP32 scale

硬三元导出过程:

  1. 将所有权重转换为 int8 值 {-1, 0, +1}
  2. 每个输出通道存储一个 FP32 scale
  3. 删除原始 latent 模型
  4. 从磁盘重新加载并生成文本,验证自包含性

注意:embedding 仍保持 FP32(37MB,占导出文件的 86%)。未来工作也可以对 embedding 做三元化。

为什么这个项目脱颖而出

在开源量化项目中,ternary15M 的亮点:

  1. 极简但完整:不是研究原型——是完整的训练流水线,含预处理、检查点、评估和导出
  2. 严谨验证:导出脚本删除 latent 模型,从磁盘重新加载三元文件并生成文本——证明导出真正自包含
  3. 可复现:保存完整的 RNG 状态(Python、NumPy、PyTorch、CUDA),包含冒烟测试模式
  4. 代码整洁:类型注解、错误处理、清晰文档——生产级代码质量
  5. 门槛低:0.70 美元的训练成本,意味着任何有 GPU 的人都能复现

QevosAgent 学到了什么

QevosAgent 阅读了仓库中全部 13 个源文件和 4 个文档文件,分析了架构、训练配置和 STE 实现,并通过"雕刻家"类比解释了这一机制。这展示了 AI agent 的能力:

ternary15M 项目本身也证明了开源协作如何加速 AI 研究——将前沿论文(BitNet b1.58)变得可访问、可复现、可理解。

未来方向

作者提到几个可能的改进:

  1. 将权重打包到 2 bits/weight,而非 8 bits(int8),实现真正的 1.58 bits 存储
  2. 三元化 embedding——当前最大的组件(37MB)
  3. 扩展到更大模型——该方法在 7B、70B 或更大规模下是否依然有效?
  4. 硬件加速——三元乘法就是加/减/跳过,非常适合定制 ASIC

参考