想象你开了家“智能厨房”:顾客发来一张4K高清美食照,后厨要“看懂”这张照片并给出点评。问题来了——照片被切成几万个小方块,每块都像一粒“食材块”,AI大模型处理每个食材块都要花费精力,还要让所有食材块两两“打招呼”。食材块越多,厨房越忙乱:灶台(显存)被塞爆,出餐(推理)慢如蜗牛。聪明的厨师长想出了三个妙招:划掉没人点的菜(剪枝)、把相似食材拼成拼盘(合并)、把一堆食材熬成浓缩高汤(学习型压缩)。这套“菜单精简术”,在AI领域就叫视觉token压缩。本文将用厨房比喻贯穿全程,带你理解多模态模型如何用更少的token,看懂更多的图片信息。

岗位关联

掌握视觉token压缩,等于掌握了多模态大模型推理成本的“开关旋钮”——无论做推理优化还是系统落地,都能精准地让模型跑得更快、花得更少。

目录
  1. 可视化演示
  2. 压缩缘起:图解token爆炸
  3. 注意力剪枝:低分Token淘汰赛
  4. 聚类合并:相似Token拼盘
  5. 学习型压缩:可训练的浓缩器
  6. 取舍之道:压缩率与信息保留
  7. 工程实践:落地压缩方案
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示视觉Token从压缩前到压缩后的流动过程,以及压缩率与信息保留的权衡关系

本节配有交互动效(进入视口后自动加载,约 3KB)。

视觉Token压缩流:密集→稀疏 压缩前:高分辨率图片产生大量视觉Token 压缩后:保留关键信息,Token数大幅减少 压缩率 = 1 - N_after / N_before 流动粒子表示Token在压缩模块中的变换过程

压缩缘起:图解token爆炸

王姐经营一家“智能厨房”。她新接了一套豪华业务:顾客传来一张 4K 高清美食照片,后厨要根据照片出菜。但照片进了后厨,先被切成密密麻麻的小方块——每一个小方块都是一个“食材块”,也就是 AI 术语里的视觉token。一张高清图轻松产生几千到几万个食材块。更麻烦的是,每次分析图片,后厨都要让所有食材块两两“打招呼”(自注意力计算)。几万个块互相打招呼,灶台(显存)瞬间被塞满,出餐(推理)慢如蜗牛王姐急需一套菜单精简方案。

专业地说,把图片编码成视觉token是大模型“看懂”图片的第一步,但token数量直接决定了后续 Transformer 层的计算量。设token数量为 N,自注意力的时间开销是 O(N²) 级别——N 翻倍,开销翻 4 倍。高分辨率图片带来的正是这种平方级灾难。这也是为什么“高清图+大模型”的组合在工程上如此昂贵:不是模型不想看细节,是计算量不允许。

为了量化问题,引入模型计算量的度量公式:

T(N)=O(N2×d)\displaystyle T(N) = O\left(N^{2} \times d\right)

其中 N 是视觉 token 数量,d 是每个 token 的特征维度。N 越大,计算与显存开销呈平方级膨胀——这就是必须对视觉 token 进行压缩的根本原因。

1. token 数量:N 表示图片被切块后生成的视觉 token 个数,相当于后厨的“食材块数量”。

N\displaystyle N

2. 平方膨胀:每个 token 都要与其余 token 计算相关性,总配对数是 N² 量级,所以计算量随 N 平方增长。

N2\displaystyle N^{2}

3. 维度开销:d 是每个 token 向量的维度,影响每次配对的运算量,维度越高单次越贵。

d\displaystyle d

理解了平方膨胀,就明白为什么“高清图+大模型”这么烧钱。压缩的终极目标,正是把公式里的 N 从几万降到几百,让后厨的灶台喘口气,同时保住菜品质量——这是后面所有压缩技法的共同出发点。

注意力剪枝:低分Token淘汰赛

王姐翻看一周的菜单记录:100 道菜里有 80 道从没人点过。把这些冷门菜划掉,后厨腾出大量空间,招牌菜照样受欢迎。AI 里也有一本类似的“点单记录”——注意力分数。

Transformer 计算时,每个 token 都会“看”其他 token 一眼,看的强度用注意力分数 α 表示。α 高表示这个 token 与全局语义关系密切,就像老客人常点的招牌菜;α 低表示它在当前上下文里几乎不被需要,就像无人问津的冷门菜。所有分数经 softmax 归一化后加起来等于 1,相当于一笔“注意力预算”。

注意力分数的计算方式如下:

αij=softmax(QiKjTdk)=exp⁡(QiKjTdk)∑lexp⁡(QlKjTdk)\displaystyle \alpha_{ij} = \text{softmax}\left(\frac{Q_i K_j^T}{\sqrt{d_k}}\right) = \frac{\exp\left(\frac{Q_i K_j^T}{\sqrt{d_k}}\right)}{\sum_{l} \exp\left(\frac{Q_l K_j^T}{\sqrt{d_k}}\right)}

每个 token 的整体重要性 score(t_i) 可取它被其他 token 关注的平均分数。剪枝规则就是设定阈值 τ,低于阈值的 token 直接淘汰:

T^={ ti∣score(ti)>τ }\displaystyle \hat{T} = \{\, t_i \mid \text{score}(t_i) > \tau \,\}

1. 内积相关度:查询 Q_i 与键 K_j 的内积衡量两个 token 的相关程度,数值越大关联越强。

QiKjT\displaystyle Q_i K_j^T

2. 缩放稳定:除以 √d_k 防止内积过大导致 softmax 梯度消失,是一种数值稳定技巧。

dk\displaystyle \sqrt{d_k}

3. 归一化投票:softmax 保证每一行注意力权重和为 1,形成一张“注意力预算表”。

softmax(⋅)\displaystyle \text{softmax}\left(\cdot\right)

4. 阈值筛选:score 低于 τ 的 token 从序列中删除,剩下的 token 数量大幅减少。

τ\displaystyle \tau

注意力剪枝就像划菜单:速度快、无需额外训练,是工程上最常用的“第一刀”。但要注意划得太狠会连招牌菜的配菜一起划掉——注意力分数低的 token 未必真的没用,这是第五节要探讨的权衡。

聚类合并:相似Token拼盘

王姐发现厨房里有 6 道鸡肉菜口味相似,与其各备一份,不如合成一份“百鸡拼盘”——顾客尝到的是多重风味的融合,后厨却只准备一份食材。token 聚类合并就是在做这种拼盘。

比起直接删除,合并更温和。它先把语义相近的 token 归为一簇,再用一个代表向量替代整簇。总 token 数从 N 降到 K,而每簇的信息都保留了大头。最经典的实现是 K-Means 聚类,也可以用图结构或注意力关系来划分簇。

K-Means 的簇中心公式:

ck=1∣Sk∣∑ti∈Skti\displaystyle c_k = \frac{1}{|S_k|} \sum_{t_i \in S_k} t_i

更精细的做法是带注意力权重的融合,让重要 token 在代表向量里占更大话语权:

tnew=∑i∈Sαiti∑i∈Sαi\displaystyle t_{\text{new}} = \frac{\sum_{i \in S} \alpha_i t_i}{\sum_{i \in S} \alpha_i}

1. 簇集合:S_k 表示第 k 簇的 token 下标集合,来自聚类算法(如 K-Means)的划分结果。

Sk\displaystyle S_k

2. 平均代表:c_k 是簇内所有 token 向量取平均,作为这簇的“团宠代表”输出。

1∣Sk∣∑ti∈Skti\displaystyle \frac{1}{|S_k|} \sum_{t_i \in S_k} t_i

3. 注意力加权:比起等权平均,用 α 加权能让更重要的 token 在代表向量里有更大发言权。

∑i∈Sαiti∑i∈Sαi\displaystyle \frac{\sum_{i \in S} \alpha_i t_i}{\sum_{i \in S} \alpha_i}

4. 替代输出:合并后原 N 个 token 被 K 个代表向量替代,K 由预设的压缩目标决定。

K≪N\displaystyle K \ll N

聚类合并的优点是不太“挑食”——没有单独牺牲某个 token,而是把相似信息搅拌在一起,语义损失比硬剪枝更平缓。缺点是要预先定 K 值,就像拼盘的种类得提前设计,定得太粗容易串味。

学习型压缩:可训练的浓缩器

前面两种方法都是“从现有菜里减或拼”。王姐还想要一种更高级的招:像把几十公斤食材熬成一罐浓缩高汤宝——体积小到装进口袋,味道却浓缩了全部精华。学习型压缩模块就是这罐高汤宝。

学习型压缩不直接保留或平均现有 token,而是训练一组“可学习的查询向量”,让它去原始 token 集合里“打探”信息,再输出一组全新的、更少的压缩 token。典型结构包括 Perceiver、Q-Former、Query-based Pooling。整个过程端到端可微,优化器直接告诉压缩器:哪些信息值得留。

核心计算是交叉注意力:

Tc=Transformer(Qlearnable,Tsrc)\displaystyle T_c = \text{Transformer}\left(Q_{\text{learnable}}, T_{\text{src}}\right)

其中 Q_learnable 是 M 个可学习查询向量,T_src 是原始 N 个视觉 token,输出 T_c 是 M 个压缩 token,且 M 远小于 N。

1. 可学习查询:Q_learnable 是模型自己学出来的 M 个查询向量,相当于 M 个“高汤配方”。

Qlearnable\displaystyle Q_{\text{learnable}}

2. 交叉注意力:用查询向量与源 token 做交叉注意力,让每个查询决定“从哪些食材取多少味”。

Attention(Qlearnable,Tsrc)\displaystyle \text{Attention}\left(Q_{\text{learnable}}, T_{\text{src}}\right)

3. 输出压缩:输出 M 个压缩 token,M 远小于 N,随后送入 LLM 参与后续计算。

M≪N\displaystyle M \ll N

4. 端到端训练:压缩器与整个多模态模型一起反向传播,自动学会保留什么、舍弃什么。

∇θLtask\displaystyle \nabla_{\theta} \mathcal{L}_{\text{task}}

高汤宝的妙处在于通用——炒菜、煮面、煲汤都能放。学习型压缩输出的 token 同样可以喂给 LLM 的任何层,灵活性远超“删几道菜”,代价是需要训练,成本更高。

取舍之道:压缩率与信息保留

王姐试了几轮:把菜单砍到只剩 5 道菜,出餐飞快,但老顾客抱怨“想吃的菜没了”;保留 50 道,菜齐了,灶台又忙不过来。压缩率与信息保留就是这么一对跷跷板。

压缩率 R 量化“砍了多少”:

R=1−NoutNin\displaystyle R = 1 - \frac{N_{\text{out}}}{N_{\text{in}}}

R = 0.75 表示从 100 个 token 压到 25 个。压缩率越高计算越省,但 token 越少细节越容易失真——一张图里的小猫、路牌文字、医疗器械上的刻度,都可能被当成“低分 token”旋掉。不同任务容忍度天差地别:闲聊场景压缩 90% 依然流畅;细粒度视觉问答压缩 50% 就开始掉准确率。

1. 原始数量:N_in 为压缩前视觉 token 总数,即压缩器的“输入食材块数”。

Nin\displaystyle N_{\text{in}}

2. 输出数量:N_out 为压缩后 token 总数,即压缩器的“输出食材块数”。

Nout\displaystyle N_{\text{out}}

3. 比例换算:1 减去两者比值,得到“被砍掉的比例”,结果在 0 到 1 之间。

1−NoutNin\displaystyle 1 - \frac{N_{\text{out}}}{N_{\text{in}}}

4. 压缩率解读:0.5 表示砍掉一半;0.9 表示砍掉九成,接近极限压缩。

R=0.9\displaystyle R = 0.9

压缩率是“省了多少”的仪表盘,信息保留是“顾客还满意吗”的评分表,两者要一起看。工程上不是一味追求最大压缩率,而是先画一条“速度-准确率”曲线:测出基准延迟与准确率,再逐步加大压缩率,找到准确率跌幅可接受的最大压缩点——这就是王姐的“甜点压缩率”。

工程实践:落地压缩方案

王姐筹备“压缩厨房”时发现,纸上谈兵与真火烹饪之间隔着无数细节。把剪枝、合并、学习压缩组装成生产线,需要注意选设备、定标准、避坑。

工程落地有三条主线。第一,位置选择:压缩模块一般放在视觉编码器之后、进入 LLM 之前,这样能同时削减自注意力计算与 KV cache 内存;部分方案也在 LLM 浅层做渐进压缩。第二,硬件适配:剪枝产生稀疏矩阵,若没有配套 kernel 优化,实际推理并不会变快甚至更慢——“理论省了,硬件没省”。第三,恢复训练:压缩后的模型通常要做轻量微调或知识蒸馏,把压缩带来的语义损失“补回来”。

加速效果可以用压缩比估算:

Speedup≈(NinNout)2\displaystyle \text{Speedup} \approx \left(\frac{N_{\text{in}}}{N_{\text{out}}}\right)^{2}

当 token 从 N 减到 N/4,理论计算加速约 16 倍,显存占用降为 1/4——前提是硬件能用满。

1. 压缩倍数:N_in 除以 N_out 得到 token 缩减倍率,比如 4 倍。

NinNout\displaystyle \frac{N_{\text{in}}}{N_{\text{out}}}

2. 平方加速:自注意力计算量随 token 个数平方级下降,所以加速比是倍率的平方。

(NinNout)2\displaystyle \left(\frac{N_{\text{in}}}{N_{\text{out}}}\right)^{2}

3. 显存变化:KV cache 与 token 数成线性关系,token 减半则显存占用也近似减半。

Memory∝Ntokens\displaystyle \text{Memory} \propto N_{\text{tokens}}

4. 理论 vs 实际:最终收益要乘以硬件稀疏计算利用率,实际落地需实测验证。

Speedupreal≤Speeduptheory\displaystyle \text{Speedup}_{\text{real}} \le \text{Speedup}_{\text{theory}}

王姐的最终厨房是这样的:剪枝负责“清冷菜”,合并负责“拼盘”,学习压缩负责“熬高汤”,三者按任务需求组装,再用基准测试校准“甜点区”。这样的压缩厨房,出餐又快,顾客还挑不出毛病。

AI 应用场景

高分辨率文档解析加速

阶段:推理优化

解决的问题:税务、法律 PDF 扫描件动辄几千乘几千像素,切块后 token 上万,多模态大模型逐页解析要数秒到数十秒,根本无法支撑批量归档。传统做法是整图喂入,延迟和成本都不可控。

具体案例:某文档智能平台用“注意力剪枝 + 聚类合并”组合:OCR 后的 token 减到 1/4,页均解析时间从 8 秒降到 1.8 秒,关键表格与印章信息保留率达 99.2%,批量归档成本大幅下降。

医疗影像辅助诊断

阶段:压缩器设计 + 微调

解决的问题:CT、MRI 图像信息密度高,盲目剪枝可能把病灶边缘当成噪声丢掉,医生无法接受这种风险。传统方案要么牺牲分辨率,要么牺牲推理速度。

具体案例:医院 AI 团队用学习型压缩模块(Q-Former 结构)加少量临床样本微调,将每张影像的 token 从 4800 压到 300,肺结节检测召回率仅下滑 0.8%,推理延迟从 4.2 秒降至 0.9 秒,实时阅片辅助成为可能。

视频流式理解

阶段:在线推理

解决的问题:视频每秒 24 帧,逐帧转 token 会瞬间击穿显存。传统做法是抽帧,但抽帧会丢掉关键动作信息。

具体案例:安防厂商对相邻帧做聚类合并,把相似画面聚成“镜头 token”,再结合时间维剪枝,输入 LLM 的 token 量减少 70%,在边缘服务器上实现了实时异常行为检测和自然语言报警描述。

Python 演示

python42 行
import numpy as npfrom sklearn.cluster import KMeans  def compute_attention_scores(q, k):    """计算每个 token 的平均注意力分数"""    d = q.shape[-1]    scores = np.exp(q @ k.T / np.sqrt(d))    scores = scores / scores.sum(axis=-1, keepdims=True)    return scores.mean(axis=0)  def prune_tokens(T, tau):    """阈值剪枝:删除注意力分数低于 tau 的 token"""    scores = compute_attention_scores(T, T)    keep_idx = np.where(scores >= tau)[0]    return T[keep_idx], keep_idx  def merge_tokens(T, n_clusters):    """聚类合并:用簇中心替代原 token"""    km = KMeans(n_clusters=n_clusters, n_init=10, random_state=42)    labels = km.fit_predict(T)    centers = np.array([T[labels == c].mean(axis=0) for c in range(n_clusters)])    return centers, labels  def compress_pipeline(q, tau=0.5, keep_ratio=0.5):    """全流程:剪枝 + 聚类合并"""    T_pruned, kept = prune_tokens(q, tau)    n_out = max(1, int(len(T_pruned) * keep_ratio))    T_merged, labels = merge_tokens(T_pruned, n_out)    return T_merged, len(q), len(T_merged)  if __name__ == "__main__":    np.random.seed(42)    N, d = 200, 64    tokens = np.random.randn(N, d)    merged, n_in, n_out = compress_pipeline(tokens, tau=0.5, keep_ratio=0.4)    rate = 1 - n_out / n_in    print(f"原始 token: {n_in} -> 压缩后: {n_out}, 压缩率: {rate:.2f}")
目的:用 numpy 和 sklearn 实现一个简化版视觉 token 压缩器,完整演示“注意力剪枝 + 聚类合并”两步流水线。
  1. q @ k.T / np.sqrt(d)计算所有 token 两两之间的缩放内积,衡量相关度。
  2. scores.mean(axis=0)对每列取平均,得到每个 token 被其他 token 关注的平均分数。
  3. keep_idx = np.where(scores >= tau)[0]阈值剪枝:只保留分数不低于 τ 的 token。
  4. km.fit_predict(T)用 K-Means 对保留的 token 做语义聚类。
  5. T[labels == c].mean(axis=0)每个簇取平均向量作为簇中心,替代整簇 token。
  6. n_out = max(1, int(len(T_pruned) * keep_ratio))根据保留比例确定压缩后的目标 token 数。
  7. rate = 1 - n_out / n_in打印压缩率,即被削减的 token 占比。

常见误区

误区很多人以为视觉 token 压缩就是把图片模糊化或缩小分辨率,就像手机相册压缩照片一样,直接把图片变小变糊。

正解其实 token 压缩发生在“特征空间”——token 不是像素,而是带有语义的小方块。压缩是在保留重要语义的前提下减少冗余块,和像素级缩放完全是两码事。就像做拼盘不是把菜捣碎,而是把口味相似的菜合并成一份,顾客依然能尝到多重风味。

为何常见:因为“压缩”这个词大家最熟悉的含义就是图片体积压缩,容易把图片压缩的直觉迁移到 token 压缩上。

误区压缩率拉满,token 越少模型跑得越快,那肯定压缩率越高越好,直接压到 10% 不是更香吗?

正解压缩率太高会丢失小物体、文字、边缘等关键细节,导致视觉问答准确率断崖式下跌。实践中要根据任务找“甜点压缩率”——通常在 50%~75% 区间性能代价可控,超过 85% 后多数细粒度任务会明显劣化。

为何常见:推理延迟随 token 数急剧上升,让人本能地想拼命压低 token 数,而忽略了信息保留这一端。

误区注意力分数就是 token 重要性的唯一标尺,分数低的都是噪声,直接删掉肯定没问题。

正解注意力分数低不代表信息无用。有些 token 在当前层不重要,但在后续层与其他 token 配合后会产生关键语义;而且分数逐层变化,一层被剪的 token 换个层可能很重要。因此剪枝要谨慎,多层渐进剪枝比单层一刀切更安全。

为何常见:注意力分数直观易懂,既有数值又有可视化热力图,很容易被过度解读成“重要性排名”。

误区一套压缩配置走天下,OCR、医疗、视频都用同样的剪枝阈值和合并比例。

正解OCR 任务需要保留文字和边缘细节,医疗图像需要保护病灶区域,自然场景图则可以大刀阔斧地剪。压缩策略要跟着任务的数据分布和下游指标走,每个场景都要单独做基准测试。

为何常见:简化思维作祟,觉得压缩是通用工具,忽略了不同任务的 token 分布和对细节的敏感度差异巨大。

面试题

Q1. 视觉 token 是怎么产生的?

单选题 · easy

  • A.图片像素直接按行排列
  • B.图片切块经编码器嵌入← 正确答案
  • C.LLM 内部随机生成
  • D.文本分词器处理图片

答案:B。视觉 token 由图片切成 patch(小方块)后,经视觉编码器(如 ViT)嵌入得到向量,类似把食材切成小块再编号入库。像素按行排列只是原始数据,未经编码不构成 token;随机生成和文本分词器都与视觉无关。

Q2. 自注意力计算量随 token 数如何增长?

单选题 · easy

  • A.随 token 数线性增长
  • B.呈平方级爆炸式增长← 正确答案
  • C.与 token 数完全无关
  • D.仅受 batch 大小影响

答案:B。每个 token 都要与其他 token 计算两两相关性,配对总数是 N² 量级,所以计算量随 token 数平方增长。这就像后厨每新增一个食材块,都要和所有其他食材块打一次招呼,招呼次数是平方级上升。

Q3. 视觉 token 压缩的主要收益是什么?

单选题 · easy

  • A.降低推理延迟和显存占用← 正确答案
  • B.提升图片的分辨率画质
  • C.增加模型参数量
  • D.减少训练数据的噪声

答案:A。压缩 token 直接减小自注意力的 N² 计算量,同时缩减 KV cache 显存,是最核心的收益。分辨率画质是输入侧的事,压缩不会提升画质,反而可能损失细节;参数量与压缩无关。

Q4. 注意力剪枝时,token 去留的判断依据是什么?

单选题 · mid

  • A.token 对应的注意力分数← 正确答案
  • B.token 在图片中的坐标
  • C.token 的 RGB 像素值
  • D.token 的文本标签

答案:A。剪枝看的是注意力分数——token 被其他 token 关注的平均强度,类似菜单上菜品的真实点单热度。坐标、像素值、文本标签都不是注意力机制产出的重要性依据。

Q5. 压缩率 R = 1 - N_out/N_in,当 R = 0.75 时表示什么?

单选题 · mid

  • A.保留了原有 75% 的 token
  • B.删除了原有 75% 的 token← 正确答案
  • C.token 数量减少了 75 倍
  • D.token 数量增加了 4 倍

答案:B。R 是“被砍掉的比例”,0.75 表示从 100 个 token 压到 25 个,删掉了四分之三。注意区分“压缩率”和“保留率”——保留率才是 N_out/N_in = 0.25。

Q6. 下面哪些属于 token 合并的典型做法?

多选题 · mid

  • A.K-Means 簇中心替代← 正确答案
  • B.注意力加权融合← 正确答案
  • C.随机删除一半 token
  • D.按坐标横平竖直切图

答案:AB。K-Means 聚类和注意力加权融合都属于“合并”,把多个 token 的信息聚合成一个代表。随机删除属于剪枝而非合并;按坐标切图只是空间裁剪,不涉及语义融合。

Q7. 压缩模块通常可以加在哪些位置?

多选题 · mid

  • A.视觉编码器输出之后← 正确答案
  • B.LLM 各层之间← 正确答案
  • C.训练数据加载阶段
  • D.像素解码写入阶段

答案:AB。压缩 token 的本质是减少进入或流经 LLM 的 token 数,因此加在编码器输出后或 LLM 层间都有效。数据加载和像素解码阶段 token 还没生成,压缩无从谈起。

Q8. 为什么剪枝后实际推理可能没有变快?

单选题 · hard

  • A.稀疏矩阵未获 kernel 优化← 正确答案
  • B.剪枝算法本身存在 bug
  • C.被剪 token 数量过少
  • D.压缩只影响显存不影响速度

答案:A。剪枝产生的是稀疏矩阵,如果底层硬件 kernel 不支持稀疏加速,矩阵仍会被填充成稠密格式计算,理论节省无法兑现。就像菜单划掉了几道菜,但后厨还是把所有食材按老流程过一遍,自然快不起来。

Q9. 关于压缩率与信息保留的权衡,下列说法正确的是?

多选题 · hard

  • A.压缩率越高推理越快← 正确答案
  • B.压缩率越高信息丢失越多← 正确答案
  • C.不同任务容忍度不同← 正确答案
  • D.压缩对模型效果无影响

答案:ABC。压缩率与信息保留是跷跷板:压缩率升高带来速度收益,同时加大信息丢失风险,且任务越细粒度越敏感。D 明显错误——压缩必然改变信息量,只是影响大小因任务而异。

Q10. 为什么压缩一般放在视觉编码器之后、进入 LLM 之前,而非只在 LLM 内部做?

单选题 · extreme

  • A.提前压缩同时降低两类开销← 正确答案
  • B.LLM 内部不支持压缩操作
  • C.视觉编码器输出无需压缩
  • D.压缩过程只能执行一次

答案:A。在进入 LLM 前压缩,既能减少每层自注意力的 N² 计算量,又能缩减 KV cache 显存——一处压缩,全链路受益。若只在 LLM 内部压缩,前面的层已经按原始 token 数白算了一遍。B、C、D 均不符合实际。