多模态模型的服务
本部分前几章把整套服务栈建立在一个假设之上:文本 token 的数量相对可控。分词器把一段提示词变成几百个整数,从那里开始,第 31 章 的成本模型便成立:预填充受算力约束,解码受显存带宽约束,键值缓存每多一个 token 就多一行。多模态服务在语言模型看到 token 之前就开始了。视觉编码器把原始像素转换成视觉 token,数量往往不是几百,而是几千,而且它早在调度器介入之前就已定下。这个数量决定预填充 FLOPs、键值缓存字节数与批大小。因此,分辨率设置就是服务成本决策,编码器放在哪里也是服务决策。这些流水线所服务的融合架构,即把像素变成语言模型能读的 token 的交叉注意力与投影连接器,见 第 15 章;这里关心的是把它们跑起来。
不是分词器产生的 token
在一个文本请求里,昂贵的对象是提示词,它的长度由用户决定。在一个多模态请求里,昂贵的对象是图像,它的长度由一个用户从未见过的模型决定。视觉编码器几乎总是一个 Vision Transformer(图像版的 Transformer,把自注意力施加在图块上,正如语言模型把它施加在 token 上,见 第 15 章),它把图像切成一格格固定大小的图块,每块产出一个嵌入(一个定长向量,用来代表那一块图块) (Dosovitskiy et al. 2021)。这张网格就决定了成本的全部。一个 CLIP 风格的编码器在 336 像素、图块大小 14 的设置下,产生一张 24 乘 24 的网格,单张图像就是 576 个 token。这 576 个 token 不是打比方。它们被拼接进主干的输入序列,从那一刻起便与文本 token 再无分别:它们占据位置,参与注意力、也被注意,并且在每一层都各占键值缓存里的一整行。
于是,一个关于截图的单句提问,进入模型时并不是一段短序列。它进入时是 576 个图像 token 加上寥寥几个文本 token,而如果产品允许高分辨率图像,这个数字便达到几千。服务上的后果随之而来。预填充本就受算力约束,如今要处理的 token 多了许多,而编码器 本身又是横在它前面的一道额外算力工序。键值缓存本就是 第 32 章 里约束批大小的瓶颈,如今被一批图像 token 填满,而这批 token 是在一次前向中一并生成 的,并非逐个解码出来。图像的代价全部在预填充时付清,随后便在缓存里驻留到请求结束,像一段没人键入的巨大前缀。
同处一条序列的三道工序
流水线有三道工序,把它们分开来看,成本才变得清晰。视觉编码器把像素变成视觉特征。投影器通常是一个小型多层感知机或一个重采样器,把这些特征映射进主干的嵌入空间, 也就是把它们整形成与语言模型自己的 token 向量同样宽度、同样格式的向量,好让它们与文本同坐一条序列。主干则是一个普通的解码器,把文本与视觉 token 一并处理。早期的桥接式设计冻结一个语言模型,用交叉注意力把视觉接上去,并让一个 Perceiver Resampler 在视觉特征抵达主干之前,把数量可变的特征压成一个固定的小预算,量级在 64 个 token 上下 (Alayrac et al. 2022)。后来成为标准的设计,则是把视觉特征直接投影进输入序列,并在指令数据上训练投影器,正是这套配方让开源多模态模型变得可行 (Liu et al. 2023)。这两种取舍设定了成本的上限:重采样器把视觉 token 预算固定下来,不论图像多大;而直接投影让预算随网格增长,以一份固定成本换取保真度。
直接投影尽管更贵却胜出,原因是分辨率。336 像素下固定的 576 token 网格,太粗,读不了一份密集的文档、一张图表或一张手机截图,而这些恰是让多模态模型在工作中有用的任务。 这个领域的回应是提高有效分辨率,而每一种提高分辨率的办法都在成倍放大 token 数量。
决定数量的三个参数
有三个参数决定一张图像变成多少 token,而一名服务工程师应当能从模型卡上把它们都读出来。
第一个参数是基础网格:输入分辨率除以图块大小,再平方。分辨率翻一倍,token 翻两番。第二个参数是切片。为了不重训编码器就够到高分辨率,AnyRes 风格的方案把一张大图切成 若干图块,每块按原生分辨率编码,再把结果拼起来,于是一张 1344 乘 1344 的图像变成一格格子图,其 token 数是每块的数量乘以图块数,往往达到数千。第三个参数是动态分辨率: 与其把每张图都压到一个固定尺寸,编码器可以按图像的原生长宽比来处理,产生数量可变的 token,并用一个多轴旋转位置编码携带位置信息,好让主干知道二维布局 (Wang et al. 2024)。动态分辨率让 token 数成为输入的函数,这固然如实,却把容量规划变成一个分布问题:同一个端点,相邻两个请求里可能一个是 256 token 的缩略图,一个是 16000 token 的整页扫描件。
下面这段可运行代码把这种爆炸具体化。token 数随图像面积增长,键值缓存的字节数则随它线性增长,于是一项支持更大图像的产品决策,其实是一项关于缓存压力与批大小的决策。 估算沿用 第 31 章 的公式,并按 Llama-3 级主干的分组查询注意力取值: 8 个键值头对 32 个查询头。
# 视觉词元数与键值缓存占用随分辨率的增长。
# 词元数 = (W/patch) * (H/patch);KV 字节数 ~ 词元数 * 层数 * 2 * (隐藏维/gqa) * dtype。
patch, layers, hidden, dtype = 14, 32, 4096, 2 # ViT patch 14;一个 7B 级骨干,fp16
gqa = 4 # n_head / n_kv:GQA 把 KV 字节数除以这个因子(8 个 KV 头对 32 个查询头)
for w, h in [(336, 336), (672, 672), (1008, 1008), (1344, 1344)]:
tokens = (w // patch) * (h // patch)
kv_mb = tokens * layers * 2 * (hidden // gqa) * dtype / 1e6
print(f"{w}x{h}: {tokens:5d} visual tokens, {kv_mb:6.1f} MB of KV cache")
# 单张高分辨率图像,可能比一段长文本对话消耗更多缓存。
视觉 token 的数量在模态层就被定下,由编码器的分辨率与切片策略决定,而它又主宰着 第 31 章 与 第 32 章 当作既定前提的那两个量。预填充的浮点运算量随 token 数增长,键值缓存的字节数随它线性增长,于是“支持 4K 截图”这项 产品决策,会一路向下传导,设定预填充预算与最大批大小。一项分辨率选择,就是一项服务成本选择。编码器坐在服务栈下面一层,早在 第 32 章 里的调度器 看到请求之前,就已经决定了每张图像有多贵。
把数量压回去
正因为数量驱动成本,多模态服务的大半工作,都花在如何为每张图像少用一些 token、又不丢掉要紧的像素上。这些办法,可以按它们在哪里减少 token 来区分。
有些在主干之前减少数量。Pixel-shuffle 以及类似的空间转通道折叠,把一小片相邻图块并成一个 token,把视觉 token 数除以四,代价是损失细微的空间细节,许多生产级编码器默认 就接受这项取舍 (Chen et al. 2024)。重采样器,也就是 Flamingo 的那种做法,走得更远,干脆把预算钉死,把一大批图块注意力压成一个恒定的小集合 (Alayrac et al. 2022)。 两者都在任何一层主干运行之前就定下数量,这让它们便宜又可预测,却也迫使这份损失在对提示词一无所知的情况下发生。
另一些则在主干内部减少数量,等模型已经开始读图之后再动手。驱动它们的观察是:视觉 token 的贡献很早就开始下降,过了头两层,对图像 token 的注意力便急剧衰减,于是大多数图像 token 都可以剪掉,对答案几无影响。FastV 在一个靠前的层之后剪掉视觉 token,并报告说过了第二 层,一张图像大约只值它一半的 token (Chen et al. 2024)。在主干内部剪枝可以是“感知提示词的”,留下提问真正会去看的那些 token,但它让服务路径变得复杂,因为被剪过的序列在 预填充中途改变了长度,键值缓存必须被压实,而不能只是往后追加。
- 连续嵌入,还是离散 token? 把连续的视觉特征投影进序列能保住保真度,却让视觉留在纯文本的下一 token 抽象之外;把图像量化成离散 token 能统一模型,代价是一道量化 悬崖(参见 第 16 章)。各家旗舰尚未收敛。
- 一张图像配得上多少 token? 一个固定的小预算便宜又可预测;原生动态分辨率忠实,却把容量规划变成一个分布问题。没有公认的答案,同一家实验室也会为文档和自然图像 发布不同的预算。
- 激进剪枝真的无代价吗? FastV 风格的剪枝报告说,平均而言能以极小的精度代价换来可观的节省,但平均值掩盖了密集文本与小目标的情形,那里被剪掉的 token 恰恰就是 答案。剪枝是否安全,取决于任务,而非一个全局开关。
编码器跑在哪里
编码器是文本服务栈从未有过的一道算力工序,它放在哪里,本身就是一项服务决策。把它与主干放在同一块加速器上最简单,也让视觉特征保持在本地,但这会让一阵图像密集的请求 潮把算力从解码循环里抢走,因为编码器与预填充如今争夺同一批矩阵运算单元。把它拆分出去,用一池编码器工作机算出视觉嵌入再经网络送给主干,则复刻了 第 32 章 里预填充与解码的拆分,理由也相同:把一道阵发的、受算力约束的工序,从一道对延迟敏感的工序旁隔离开来,代价是把嵌入搬过网线、再多管一支机队。这不再只是构想:编码器拆分已作为原生模式进入 vLLM(Encode-Prefill-Decode 分离,即 EPD,自 v0.11.1 起),编码器池按数据并行扩展,与主干的张量并行互不牵扯,多图工作负载上的有效吞吐量据报大约翻倍 (vLLM Multimodal Workstream 2025)。
图像前缀缓存在这里比在文本里更有用,因为图像会重复。一段反复指向同一份上传文档的对话,每一轮都把它重发一遍;一个给每个请求都缀上同一张品牌图的系统,每次都为它付费,除非编码器的 输出、或由它生成的键值条目被缓存下来复用。前缀缓存早已是共享文本前缀的标准做法,它自然延伸到位于开头的一张图像:对像素做哈希,命中时便把编码器与该图像的预填充一并跳过 (参见 第 32 章)。这里的经济账比文本缓存更划算,因为一张图像是一大块可供复用的 token。
视频是同一个问题,只是乘数更大。一段视频是一串帧,每帧是一张图像,每张图像是几百到几千个 token,于是几秒钟的视频按朴素的帧率算,问题还没附上就已经超过了上下文 窗口。因此每个视频模型都在时间上做池化,稀疏地采样帧,并在相邻帧之间合并 token,而池化率与图像分辨率是同一类控制参数:它拿时间保真度去换一个服务栈付得起的 token 预算。
服务生成:轮到模型产出像素
到目前为止,媒体一直被当作输入,被消费、被转成 第 31 章 的解码循环认得的 token。把箭头调转过来,服务问题也随之翻转。一个生成图像或视频的模型,几乎总是扩散模型,而扩散打破了自回归服务栈所依赖的每一条假设。这里没有KV 缓存(key-value cache),也没有逐词元的产出,因为在最后一步之前样本根本不存在:扩散模型从噪声出发,用许多趟把它去噪,每一趟都是对图像每一个潜变量元素的完整稠密前向,只有最后一趟才产出用户看得见的东西。所以没有什么可流式输出的。用户得到的是进度条,不是词元流;成本也不是每词元的字节数,而是每步 FLOPs 乘以步数,其中每步 FLOPs 随分辨率增长,对视频还随帧数增长。
这一条结构性事实重塑了整个服务层。自回归解码受限于显存带宽,把许多廉价的并发序列打进一个批次;一个扩散请求受限于算力,单张高分辨率样本就能独自占满一块加速器,于是服务形态是一个延迟以秒到分钟计的作业队列,而不是交互式的流 (Li et al. 2024)。它也让一类自回归侧没有对应物的优化成为可能。因为同一个网络要在步与步之间只缓慢变化的激活上跑很多遍,工作可以复用:特征图在相邻步之间缓存、只重算快速变化的部分 (Ma et al. 2024),或者靠容忍一步之差的图块边界把单张样本切到多张 GPU 上 (Li et al. 2024)。这里被缓存的是去噪器自己跨时间步的中间特征,不是跨请求的上下文,这种缓存在文本栈里叫「避免重算」,而非 KV 缓存。
既然成本是步数乘以每步 FLOPs,主导的杠杆就是把步数压下来,而这是一次训练时的干预,效果直接落在账单上。渐进式蒸馏每一轮把采样器的步数减半,把数千步降到个位数 (Salimans and Ho 2022);一致性模型把去噪轨迹上任意一点直接映射到结果,使一步生成成为可能 (Song et al. 2023);对抗式蒸馏把合成压到一到四步,好到足以实时使用 (Sauer et al. 2024)。定价紧跟着物理成本走:在某个图像 API 上,同一个流匹配架构的全采样器版与少步蒸馏版,都按百万像素计价,价差八倍,正对应步数之差 (Black Forest Labs 2024)。这张账单没有一处是按词元的;它是分辨率乘以一个质量档位,也就是把成本模型原样透传出去。下面的可运行单元仅凭 FLOPs 就重建了这道价差:砍掉步数,每张图的成本按比例下降。
# 一张图 = 步数 × 对每个潜变量词元的一次稠密前向;没有 KV 缓存,没有流式
P, TOK = 12e9, 4096 # 120 亿参数扩散 Transformer,每百万像素约 4096 个潜变量词元
tflops_per_step = 2 * P * TOK / 1e12 # 每百万像素每步约 98 TFLOPs
gpu_tflops, mfu, price_hr = 989, 0.40, 2.0 # H100 bf16 稠密算力、利用率、示意性的每 GPU 时价
def per_image(steps, mp=1.0):
secs = steps * tflops_per_step * mp / (gpu_tflops * mfu)
return secs, secs / 3600 * price_hr
for name, steps in [("基础采样器", 50), ("蒸馏版 ", 4), ("一步 ", 1)]:
s, usd = per_image(steps)
print(f"{name}: {s:5.2f} GPU 秒 ${usd:.4f}/张")
print("50 步降到 4 步便宜约 12 倍:步数就是定价旋钮")
视频把每一项都乘大。一个在时空图块上运行的扩散 Transformer (Brooks et al. 2024),要在一条长度随帧数与像素双双增长的序列上做注意力:某个生产级视频模型为十六秒高清画面维护七万三千词元的上下文,而单张百万像素图像约为四千个潜变量词元 (Polyak and others 2024);注意力成本还随这个长度的平方增长。因此单个视频样本就是一个长达数分钟、跨多张 GPU 的稠密作业,这正是产品形态为「提交-轮询-下载」、按额度或按输出秒数计价、而不是聊天流的原因。前沿如今正把这种批处理形态拉回流式:少步蒸馏结合因果生成,也就是以过去帧为条件从左到右生成帧,能以交互帧率流式输出视频,而为了做到这一点,这个领域又把它先前丢掉的 KV 缓存重新发明了一遍 (Yin et al. 2024)。实时交互式世界模型走得更远,把一个请求从作业变成一个有状态的、每用户的会话,帧截止时间以数十毫秒计,那是游戏服务器的经济学,而不是吞吐导向的服务 (Google DeepMind 2025)。
生成式媒体服务会不会与大模型服务栈合流,尚无定论,而且还在变动。合流的一面已经进入生产:统一引擎如今把扩散 Transformer 折进与语言模型同一个运行时,共享序列并行与无分类器引导并行、复用同一批内核,而因果视频这套做法又原封不动地把 KV 缓存与连续批处理搬了回来。分流的一面是,两种工作负载在运维上几乎毫无共同之处:稠密、受限于算力的数秒级内核对上受限于带宽的毫秒级迭代,队列与会话调度对上连续批处理,每样本的多 GPU 并行对上每词元的权重摊销,以及根本不存在的前缀缓存经济账。较可能的结局是,内核与引擎合流,而它们之上的那一层,调度器、SLO、计价单位,仍然分开,直到交互式生成把视频变得足够像解码,才会并到一处。
分辨率也是服务决策
多模态的能力,几乎都是用效率换来的。能力是真实的:读懂一张图表、一张截图、一份扫描表单,正是让模型在闲聊之外有用的东西。但每 一分视觉能力的增益,都是一分 token 的增加,而 token 就是预填充的浮点运算与键值缓存的字节,正是整套服务栈竭力要省下的那两个量。于是效率成了约束项,而那些工程,动态分辨率、 pixel-shuffle、重采样、感知提示词的剪枝、编码器拆分、图像前缀缓存,无一不是为了用最少的 token 仍让模型看得见。信任的风险则潜伏在剪枝之下,平均指标往往照不出它:一项在自然图像基准上 看似无代价的 token 缩减设置,可能悄悄丢掉密集文档或微小缺陷所在的那一块区域,因此稳妥的部署,会把任何激进的缩减都绑定到一项针对产品真正服务的密集细节任务的评测上(参见 第 52 章)。那条下层约束,是该带上栈去记住的教训:控制多模态服务成本最便宜的地方,是模态层上的分辨率策略,远在调度器看到请求之前。
延伸阅读
- Dosovitskiy et al., “An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale,” 2021. arXiv:2010.11929ViT 表明,将纯 Transformer 直接应用于图像块序列,在足够规模的预训练后,可在图像分类任务上达到或超越 CNN 的性能。
- Alayrac et al., “Flamingo: a Visual Language Model for Few-Shot Learning” (Perceiver Resampler 与固定的视觉 token 预算), 2022. arXiv:2204.14198
- Liu et al., “Visual Instruction Tuning” (直接投影进序列), 2023. arXiv:2304.08485
- Wang et al., “Qwen2-VL: Enhancing Vision-Language Model's Perception of the World at Any Resolution” (朴素动态分辨率与多模态旋转位置编码), 2024. arXiv:2409.12191
- Chen et al., “InternVL: Scaling up Vision Foundation Models and Aligning for Generic Visual-Linguistic Tasks” (pixel-shuffle token 缩减与动态高分辨率切片), 2024. arXiv:2312.14238
- Chen et al., “An Image is Worth 1/2 Tokens After Layer 2: Plug-and-Play Inference Acceleration for Large Vision-Language Models” (FastV), 2024. arXiv:2403.06764FastV 根据注意力分数在第 2 层后剪枝视觉语言模型中的视觉词元,在几乎不损失性能的情况下实现 45
- vLLM Multimodal Workstream, “Encoder Disaggregation for Scalable Multimodal Model Serving,” 2025. vllm.aivLLM 原生的编码/预填充/解码(EPD)分离自 v0.11.1 起可用,把视觉编码器放进独立的池运行,据报告多图工作负载的有效吞吐量约翻倍,P99 延迟降低 20
- Li et al., “DistriFusion: Distributed Parallel Inference for High-Resolution Diffusion Models” (靠容忍过时的图块上下文,把一张图切到多张 GPU 上), 2024. arXiv:2402.19481通过错位图块并行把单张高分辨率扩散样本切分到多张 GPU 上,复用上一步的特征图使各 worker 异步通信,延迟最多降低 6.1 倍且无质量损失。
- Ma et al., “DeepCache: Accelerating Diffusion Models for Free” (扩散版的 KV 缓存:特征在各步之间复用), 2024. arXiv:2312.00858一种免训练方法,在相邻去噪步之间缓存 U-Net 的高层特征、只重算快速变化的部分,加速 2 至 4 倍且质量损失可忽略。
- Salimans & Ho, “Progressive Distillation for Fast Sampling of Diffusion Models” (把数千步蒸馏到个位数步), 2022. arXiv:2202.00512反复把扩散采样器蒸馏成只需一半步数的学生模型,把生成从数千步降到最少四步,代价不超过原始训练。
- Song et al., “Consistency Models” (把轨迹上任意一点直接映射到结果:一步生成), 2023. arXiv:2303.01469把去噪轨迹上任意一点直接映射到其起点的模型,支持一步生成并可选多步细化,既可蒸馏训练也可从头训练。
- Sauer et al., “Adversarial Diffusion Distillation” (SDXL-Turbo 背后的方法:一到四步合成), 2024. arXiv:2311.17042把分数蒸馏与对抗损失结合,实现一到四步采样,是 SDXL-Turbo 背后的方法,四步之内即可达到与教师模型相当的实时合成。
- Black Forest Labs, “Announcing Black Forest Labs and the FLUX.1 Model Family” (全采样器与少步蒸馏版,按百万像素计价、相差八倍), 2024. bfl.aiFLUX.1 流匹配图像模型家族,其全采样器版与少步蒸馏版共用同一架构,却按百万像素计价、相差八倍,正对应二者的步数差距。
- Brooks et al., “Video generation models as world simulators” (在时空图块上运行的扩散 Transformer), 2024. openai.comSora 技术报告:在视频潜变量的时空图块上运行的扩散 Transformer,以算力为提升样本质量的坐标轴,可生成最长约一分钟的视频。
- Polyak & others, “Movie Gen: A Cast of Media Foundation Models” (十六秒高清视频对应 7.3 万词元的上下文), 2024. arXiv:2410.13720Meta 的媒体基础模型,其视频模型为十六秒高清画面维护 7.3 万词元的上下文,而单张百万像素图像约为四千个潜变量词元。
- Yin et al., “From Slow Bidirectional to Fast Autoregressive Video Diffusion Models” (视频生成重新发现了解码与 KV 缓存), 2024. arXiv:2412.07772把五十步的双向视频扩散模型蒸馏成四步的因果自回归生成器,用 KV 缓存流式生成视频,把大模型的服务经济学引入视频。
- Google DeepMind, “Genie 3: A New Frontier for World Models” (一个请求变成带帧截止时间的有状态每用户会话), 2025. deepmind.google一个实时交互式世界模型,以 24fps 生成 720p 画面并带短时视觉记忆,把请求从批处理作业变成带数十毫秒帧截止时间的有状态每用户会话。
评论
登录后评论