4-bit 量化正在把大模型的推理成本拉到一个新量级:权重和激活同时压到 4-bit,显存占用直接砍半,单机部署的边界被大幅前推。4sapi(https://4sapi.com)持续跟进这类量化模型的接入与路由,把降本思路从云端延伸到本地,把 FP4 与 INT4 的区别、混合架构模型的量化坑、以及本地与云端混合接入的落地路径一次讲清楚。

一、开篇痛点:推理成本为什么一直降不下来

大模型的单次调用价格在持续下降,但总量在涨。业务一旦接入,调用量通常按月翻倍:长上下文文档处理、批量知识抽取、Agent 的多轮工具调用,每一路都在烧 token。纯按量付费模式下,成本曲线跟着调用量线性上涨,能做的优化只有换更便宜的模型、加缓存、或者砍功能。

另一个痛点是私有化。数据不能出内网的场景(企业内部知识库、医疗、金融),模型必须跑在自己的机器上。一个 27B 参数的模型,fp16 权重就要 54GB,加上 KV Cache 和激活,通常需要两块 A100 级别的卡,显存门槛直接决定了硬件采购单。

4-bit 量化同时缓解这两件事:显存占用降到原来的四分之一左右,单张 24GB 消费卡就能跑 27B 模型;更小的权重意味着更少的内存带宽占用,而解码速度恰好受显存带宽限制,于是单 token 延迟和吞吐都跟着改善。这也是我把 4-bit 当成当前降本主线的原因。

二、原理速览:W4A4 到底在量化什么

量化的对象主要是权重(W)和激活(A)。W8A8 表示权重和激活都是 8-bit,W4A16 表示权重 4-bit、激活保持 fp16,W4A4 则是权重和激活都压到 4-bit,是目前最激进的组合。

方案 权重 激活 显存节省 精度风险 适用场景
W8A8 8-bit 8-bit 中等 通用生产
W4A16 4-bit fp16 较高 较低 权重主导的场景
W4A4 4-bit 4-bit 最高 较高 显存/带宽受限

激活参与量化意味着每个 token 的前向计算都在 4-bit 下进行,精度损失不再只来自权重压缩,还来自每层输出的量化误差。这就是 W4A4 比 W4A16 难一个量级的原因。

一次请求在量化模型上的流动大致如下:

应用请求
   |
   v
本地推理服务(vLLM / llama.cpp,加载 4-bit 权重)
   |
   v
逐层前向:块级缩放 -> FP4/INT4 矩阵乘 -> 反量化到 bf16 累加
   |
   v
KV Cache(可进一步量化为 8-bit 或 4-bit)
   |
   v
采样输出,流式返回

三、FP4 与 INT4:同样 4-bit,两种数值世界观

4-bit 量化并不是只有一种做法。FP4 和 INT4 是两条完全不同的数值路线。

INT4 是均匀网格:16 个等距的整数档位,配合 per-channel 或 per-block 的 scale 与 zero point,把目标数值范围映射到网格上。它的前提是数值分布接近均匀,遇到离群值要依赖更大范围的 scale,代价是中间值精度下降。

FP4 是浮点格式,最常用的是 E2M1:1 bit 符号、2 bit 指数、1 bit 尾数。尾数只有一位,意味着有效数值只有 1.0 和 1.5 两档乘以 2 的幂,量化值呈稀疏的幂次分布;指数只有 2 bit,可表示的幅度范围大约只有 0.5 到 6,非常窄。

维度 FP4 (E2M1) INT4
表示方式 符号 + 指数 + 尾数 均匀网格 + scale/zero point
幅度范围 窄(约 0.5~6) 由 scale 决定
尾数精度 1 bit,仅 1.0/1.5 两档 16 档等距
硬件支持 NVIDIA Blackwell 系列原生支持 更早世代即可用
典型问题 数值溢出 / 下溢 离群值拉低整体精度

四、E2M1 的窄幅度问题:FP4 预训练为什么难

如果只是推理时把训练好的权重压到 4-bit,问题相对可控;但要让模型从头就用 FP4 训练,E2M1 的窄幅度就成了拦路虎。

训练时,不同层、不同位置的激活和梯度幅度可以相差多个数量级。E2M1 只能覆盖约 0.5 到 6 的范围,任何一个超出范围的数值都会被饱和成最大值,任何一个小于 0.5 的数值都会塌缩成 0 或最小档位。梯度一旦大面积塌缩,深层网络就拿不到有效的学习信号,训练发散或停滞是常态。

早期尝试 FP4 预训练时,主流补救办法是三件套:每个张量动态缩放(current tensor scaling),把张量整体拉到可表示范围;随机 Hadamard 变换,把离群值"旋转"摊平,降低张量的最大值,让更多数值落入可表示区间;最后一层保留 bf16,防止输出端误差被放大。NVIDIA Transformer Engine 走的就是这条路线。三件套能压住训练稳定性,但每一层都要多做一次 Hadamard 变换和缩放计算,训练吞吐打了折扣,实现复杂度也高。

五、UE5M3 块级缩放:新的稳定路径

新思路是改变尺度信息的存放位置:不把整张量塞进一个 scale,而是按块给尺度。

具体做法是块级缩放(block scaling):把张量切成小块,每块配一个独立 scale,块内的 4-bit 载荷只负责表示相对大小,块与块之间的幅度差异由 scale 承担。尺度本身用 UE5M3 编码——5 bit 指数加 3 bit 尾数,指数位足够宽,能覆盖跨块几个数量级的幅度变化,不需要 Hadamard 变换来压缩范围,也不需要把整个末层留在 bf16。

块级缩放把"一个窄范围装下整个张量"的难题,拆成"窄范围装下块内数值 + 宽范围装下块间差异"。梯度信号在块内保持相对精度,块间的差异交给指数宽的 scale,训练稳定性不再完全依赖那套复杂配方,计算开销也低于逐层做 Hadamard 变换。

六、混合架构模型的量化坑:Gated DeltaNet

另一类难啃的骨头是混合架构模型。这类模型把 softmax attention 层和线性注意力层(典型代表是 Gated DeltaNet,GDN)堆在一起:attention 层处理全局依赖,GDN 层用循环状态压缩历史信息,兼顾长上下文和推理效率。

混合模型量化时有一个流传很广的直觉担忧:循环状态会跨 token 累积误差。GDN 的隐藏状态在序列上不断更新,每一步的量化误差都会写进状态并被后续步骤继承,误差随序列长度累积,最终输出发生漂移。

这个担忧在早期社区量化 27B 级混合模型(48 个 GDN 层 + 16 个 softmax attention 层)时变成了现实:只量化 attention 块,GDN 块留在 8-bit 或 16-bit,结果显存只省下一半,另一半始终下不去。问题的本质和 FP4 预训练一样,还是数值范围:循环状态向量里的元素幅度差异巨大,块内窄网格根本装不下,误差自然一路累积。

七、新进展:混合 27B 整体压到 W4A4

块级缩放同样解开了循环状态的结。最近的新进展是:Gated DeltaNet 在 NVFP4 的 W4A4 下也能稳定工作,混合 27B 模型可以整体压到 4-bit,不再需要把 GDN 块单独留在高精度。

关键是循环状态也按块缩放:状态更新矩阵(A、B、C 投影和门控)的量化误差被块级 scale 约束在可控范围内,单步误差不再随序列长度线性放大。实测下来,长序列任务的质量保持在可接受区间,而显存占用从"只量化一半"变成"全量 4-bit",27B 模型的权重部分只需 13.5GB 左右。

这直接改变了部署决策:以前混合架构模型"量化不干净",要么放弃本地、要么接受高显存;现在 27B 混合模型可以放进单张 24GB 消费卡,本地部署的候选名单一下子变宽了。

八、本地部署成本到底怎么算

本地部署不是没有成本,它只是把按量付费换成了前置投入。一张 24GB 显存的卡(含整机)大约相当于多少 token 费用,取决于任务的调用密度。

假设一个场景每天产生 500 万 token 的推理量,其中 80% 是短文本分类、意图识别这类简单任务,20% 是长文生成。简单任务用本地 4-bit 小模型,复杂任务走云端大模型:

方案 前期投入 边际成本 显存门槛 主要风险
纯云端 API 随 token 线性增长 长期成本随用量膨胀
纯本地部署 硬件 + 运维 电费和折旧 需要大显存卡 模型质量、硬件利用率
本地 + 云端混合 中等 大部分走本地,云端兜底 一张卡即可起步 路由策略与工程复杂度

混合方案的成本结构最健康:高频低价值的 token 用接近零的边际成本消化,低频高价值的请求才花云端的钱。盈亏平衡点用一条简单公式估算:硬件月摊销 /(云端每 token 单价 × 每月转移到本地的 token 数),比值小于 1 就说明混合方案更划算。

九、混合接入方案:本地小模型 + 云端大模型

落地形态是一套两级路由:本地跑 4-bit 量化的小模型处理简单高频任务,云端 API 处理复杂生成,中间用一个统一网关做分发。

业务请求
   |
   v
4sapi 统一网关(任务类型识别 + 成本/延迟路由)
   |
   +--> 简单任务 -> 本地推理服务(4-bit 量化小模型,零边际成本)
   |
   +--> 复杂任务 -> 云端大模型(经 4sapi 统一鉴权、限流、计费)
   |
   +--> 兜底/降级 -> 本地小模型快速响应,云端排队
   |
   v
统一格式返回给业务

网关层承担三件事:按任务类型选模型、统计每个任务的 token 消耗与成本、在云端不可用时降级到本地。业务侧只需要面对一个 OpenAI 兼容的接口,模型的切换对上层透明。

十、4sapi 统一网关接入示例(Python)

先用 vLLM 把量化模型起成本地服务,4-bit 权重按 NVFP4 加载:

python -m vllm.entrypoints.openai.api_server \
  --model qwen3-27b-fp4 \
  --quantization fp4 \
  --max-model-len 32768 \
  --port 8000

然后写一个统一客户端,本地与云端共用同一套 OpenAI 兼容协议:

import os
import time
from openai import OpenAI

LOCAL_BASE = os.getenv("LOCAL_BASE", "http://127.0.0.1:8000/v1")
CLOUD_BASE = os.getenv("4SAPI_BASE", "https://4sapi.com/v1")  # 4sapi 统一接入
CLOUD_KEY = os.getenv("4SAPI_KEY", "")

local = OpenAI(base_url=LOCAL_BASE, api_key="local-key")
cloud = OpenAI(base_url=CLOUD_BASE, api_key=CLOUD_KEY)

# 路由表:任务 -> (模型, 是否走本地, 最大输出 token)
ROUTES = {
    "classify": ("qwen3-7b-int4", True, 128),     # 高频简单任务,本地
    "extract":  ("qwen3-7b-int4", True, 512),     # 高频结构化抽取,本地
    "chat":     ("qwen3-27b-fp4", True, 2048),    # 本地 27B 4-bit
    "deep":     ("deepseek-chat", False, 8192),   # 复杂生成,云端
}

def unified_chat(task: str, messages: list):
    model, use_local, max_tokens = ROUTES[task]
    client = local if use_local else cloud
    deadline = time.monotonic() + 60
    while time.monotonic() < deadline:
        try:
            resp = client.chat.completions.create(
                model=model,
                messages=messages,
                max_tokens=max_tokens,
                temperature=0.2 if task != "chat" else 0.7,
            )
            return resp.choices[0].message.content, model
        except Exception:
            if not use_local:
                # 云端不稳时降级到本地小模型,保证可用性
                resp = local.chat.completions.create(
                    model="qwen3-7b-int4",
                    messages=messages,
                    max_tokens=min(max_tokens, 1024),
                )
                return resp.choices[0].message.content, "qwen3-7b-int4(fallback)"
            time.sleep(1)
    raise TimeoutError(f"task={task} timeout")

# 调用示例:分类走本地,深度分析走云端
text = "这笔订单的退货原因是什么?"
print(unified_chat("classify", [{"role": "user", "content": text}]))
print(unified_chat("deep", [{"role": "user", "content": "分析退货率上升的五个可能原因"}]))

把调用量统计挂到网关层,每天对账:本地跑了多少 token、云端跑了多少 token、单位成本是多少。路由规则只改配置不动代码,先小流量切一部分简单任务到本地验证质量,再逐步扩大比例。

十一、量化部署的验收清单

上线前按以下清单逐项验收:

  1. 量化前后用相同 seed 和相同评测集跑一遍,记录困惑度与下游任务得分差距;
  2. 校准数据必须覆盖真实分布(中文、代码、长文档、多轮对话),不能只用英文通用语料;
  3. 检查首层与末层的处理方式,末层是否保留 bf16、首层 scale 是否溢出;
  4. 确认 KV Cache 量化开关与精度,长序列任务要单独测试;
  5. 对混合架构模型做长序列压力测试,观察循环状态误差在 8K/32K/128K 长度下的漂移;
  6. 实测显存峰值、首 token 延迟与吞吐,和 fp16 基线对比;
  7. 准备好回滚路径:量化权重版本化,出问题一键切回 W4A16 或云端 API。

十二、成本与风险提示

4-bit 不是免费的午餐,收益和风险要一起看:

总结

FP4 与 INT4 是两种数值路线,E2M1 的窄幅度让 FP4 预训练依赖复杂配方,UE5M3 块级缩放把尺度信息从载荷中剥离,同时解开了 FP4 训练与混合架构模型(Gated DeltaNet)循环状态量化的死结,27B 混合模型整体压到 W4A4 已经成为现实。落地路径上,本地部署与云端 API 不是二选一,混合接入(本地 4-bit 小模型 + 云端大模型)的成本结构最健康,统一网关负责路由、降级与计费统计,云端部分可以交给 4sapi(https://4sapi.com)统一鉴权、限流与计费。欢迎在评论区发表想法,聊聊各自的量化部署实测数据。