游乐游手机版
首页/AI热点日报/热点详情

从零开始学大模型瘦身:向量化压缩实战指南

类型:热点整理2026-06-12
你在Hugging Face或GitHub上浏览大模型时,一定见过这样的介绍页:同一个模型,列出了FP32、FP16、INT8、INT4好几个版本。后面往往还跟着一张表格,告诉你每个版本需要多少显存。FP32号称要A100、H100这类专业卡才能跑,INT8呢,普通2080的6G显存就搞定了。它们之

你在Hugging Face或GitHub上浏览大模型时,一定见过这样的介绍页:同一个模型,列出了FP32、FP16、INT8、INT4好几个版本。后面往往还跟着一张表格,告诉你每个版本需要多少显存。FP32号称要A100、H100这类专业卡才能跑,INT8呢,普通2080的6G显存就搞定了。它们之间到底差在哪儿?大模型量化这个听起来有点唬人的词,背后的逻辑其实并不复杂。

计算机里如何表示浮点数

先简单回顾一下浮点数在计算机里是怎么存的。这里的“FP”,就是Float Point(浮点)的缩写。计算机里所有数据归根结底都是二进制,浮点数也不例外。目前通用的标准是IEEE 754,它定义了单精度(32位)和双精度(64位)两种主流格式。拿双精度来说,64位被拆成三部分:1位符号位(0正1负),11位阶码(决定数值的范围),52位尾数(存放有效数字的小数部分)。双精度能表达的范围和精度,都比单精度高出一大截。

不管是CPU还是GPU,干活之前都得先把数据搬到内存或显存里。精度越高,每个数字占用的空间就越大。对大模型而言,量化等级越高,参数能记住的细节就越丰富,模型对训练数据的“记忆”就越准确,代价就是内存需求直线上升。反过来,量化等级越低,参数精度打折了,内存需求也就降下来了。

什么是量化?

我们今天聊的量化,跟股票市场里那种高频交易的量化完全是两码事。不过精神上倒有那么一点相通——都是想“用更少的资源撬动更多的东西”。只不过这里撬动的,是模型的计算和存储成本。

简单说,模型量化就是把模型里的参数(权重、偏置这些),从高精度的浮点数(比如32位)换成低精度的整数(比如8位)来表示。这是一种压缩模型大小的技术,目的是让推理跑得更快,对硬件的要求更低。低精度运算在很多硬件上天生就比高精度快。举个例子,FP32格式下每个浮点数要占32位(实际上是1位符号+8位阶码+23位尾数)。大模型动辄几十亿甚至上千亿参数,光参数本身就能吃掉几十GB内存——比如一个10亿参数的模型,用FP32存大概要29.8GB。所以即使是4090这种消费级旗舰,想跑真正的大模型也是有心无力。企业级部署也不便宜。量化正是降低模型部署成本的手段之一。

量化是怎么把规模降下来的?

量化过程大致分几步:首先得选策略——是训练完再静态量化,还是推理时动态量化;然后为每个要量化的元素确定合适的范围和精度;接着就是关键步骤——把浮点数的参数和激活值转成选定精度的整数;有时候为了补偿精度损失,还会再加一轮“量化感知训练”来微调权重。

我们直接拿一个实际例子来看。就用Hugging Face上的GPT-2模型,先看看量化前的内存占用:

model_name = "./models/gpt2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# fix dtype post quantization to "pretend" to be fp32
def get_float32_dtype(self):
    return torch.float32
GPT2Model.dtype = property(get_float32_dtype)

# This will return the memory footprint of the current model in bytes
model.get_memory_footprint() # 510342192 => 0.47GB

接下来我们用zero-point量化方案,把参数的精度降下来。说白了就是把高精度浮点数映射到低精度的整数空间里。计算过程很直观:

  1. 计算数据范围:找出待量化数据的最小值和最大值。
    r_min = min(x_1, x_2, ..., x_n)
    r_max = max(x_1, x_2, ..., x_n)
  2. 计算缩放因子:决定浮点范围如何映射到整数范围。
    s = (r_max - r_min) / (q_max - q_min)
    其中 q_max、q_min 是整数范围,比如127和-128。
  3. 计算零点:把浮点里的0映射到整数里的某个值。
    z = q_min - r_min / s
  4. 执行量化
    q = round(x / s + z)

代码实现大致长这样:

def quantize(t):
    # obtain range of values in the tensor to map between 0 and 255
    min_val, max_val = t.min(), t.max()

    # determine the "zero-point", or value in the tensor to map to 0
    scale = (max_val - min_val) / 255
    zero_point = min_val

    # quantize and clamp to ensure we're in [0, 255]
    t_quant = (t - zero_point) / scale
    t_quant = torch.clamp(t_quant, min=0, max=255)

    # keep track of scale and zero_point for reversing quantization
    state = (scale, zero_point)

    # cast to uint8 and return
    t_quant = t_quant.type(torch.uint8)
    return t_quant, state

quant_model, states = quantize_model(model)
quant_model.get_memory_footprint() # 137022768 => 0.12G

结果很直观:量化后内存从0.47GB降到了0.12GB,节省了大约74%。当然代价是参数的精度打了折扣,模型可能会出现一定程度的精度损失。这就是部署时需要在性能与资源之间做的权衡——特别是在移动设备、嵌入式系统这类资源受限的环境里,模型量化几乎是必选项。

来源:https://www.53ai.com/news/qianyanjishu/864.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。