文章

VLM 图像输入管线生产实战:用分辨率分档、Token 预算与缓存稳住多模态成本

多模态模型上线后,图片尺寸、清晰度和缓存策略会直接影响成本、延迟与识别质量。本文从工程角度详解 VLM 图像输入管线的分辨率分档、Token 预算估算、多层缓存策略与上线检查清单,帮助团队稳住多模态成本。

VLM 图像输入管线生产实战:用分辨率分档、Token 预算与缓存稳住多模态成本

多模态模型上线后,图片尺寸、清晰度和缓存策略会直接影响成本、延迟与识别质量。本文从工程角度详解 VLM 图像输入管线的分辨率分档、Token 预算估算、多层缓存策略与上线检查清单,帮助团队稳住多模态成本。


背景:VLM 上线后,成本问题常常藏在图片里

文本大模型的成本治理通常从 prompt 长度、输出 token、缓存命中率和模型路由开始。但到了 VLM(Vision-Language Model) 场景,另一个更容易失控的变量会出现:图片

同一张业务图片,可能是 300KB 的商品图,也可能是 8MB 的手机截图;可能只需要判断”是否包含破损”,也可能需要读出截图中的小字、表格、坐标和层级关系。应用层如果把所有图片都原样传给模型,通常会遇到四类问题:

  1. 成本不可预测。不同供应商会用 patch、tile、视觉 token 或媒体分辨率参数来计量图片输入。图片尺寸、长宽比、分辨率档位和多图数量都会影响输入成本。
  2. 延迟不稳定。图片越大,预处理、上传、编码和模型推理时间越长。对于客服、审核、质检、网页自动化等在线任务,尾延迟比平均延迟更值得关注。
  3. 质量不可控。图片过大并不总是更好。服务端可能自动缩放;截图小字、旋转图片、密集文本、透明背景、超长图和拼接图都可能让识别结果波动。
  4. 缓存难做。文本 prompt 可以比较容易做 hash,但图片存在 EXIF、压缩质量、缩放版本、裁剪版本、透明背景填充、重复上传和 CDN URL 变化。如果没有标准化策略,同一张图很难命中缓存。

本文讨论的不是”哪个 VLM 更强”,而是一个更工程化的问题:如何设计一条可上线、可审计、可控成本的 VLM 图像输入管线


核心原理:图片不是字节,而是视觉 Token 预算

供应商图像计量方式对比

不同供应商对图片输入的计量逻辑差异显著,不能简单地用文件大小或像素数做统一成本模型。

供应商图像计量方式关键参数
OpenAI按 32×32 patch 或 512×512 tile 计算视觉 tokendetail(low / high / original)
Anthropic(Claude)按 28×28 像素 patch 计算,ceil(w/28) × ceil(h/28)建议不需要高保真时下采样
Google Gemini≤384px 单维度为 258 tokens;更大按 768×768 tile 切分,每 tile 258 tokensmedia_resolution(Gemini 3)

核心结论:VLM 图像成本不能只看文件大小,也不能只看分辨率,而要看模型侧如何把图片转换为视觉 token、patch 或 tile。这是一个预算问题,不是一个文件传输问题。


高分辨率不是默认正确答案

图像输入质量和成本之间不是线性关系

  • 低分辨率适用:“图片里有没有安全帽""商品主图是否模糊""票据类型是什么”——这类粗粒度任务低分辨率已经足够。
  • 高分辨率必要:“读取发票明细""理解网页截图布局""点击按钮坐标定位""比较两张设计稿差异”——低分辨率会丢失关键信息。

更重要的是,VLM 的视觉编码不是无损压缩。2026 年一篇关于 vision token 信息容量的论文(How Much Information Can a Vision Token Hold?)从视觉 token 作为有损通道的角度分析了密集文本图像的识别边界,指出当信息量持续增加时,模型表现可能从稳定阶段进入不稳定阶段,最终出现容量崩塌。这提醒我们:把大量小字、表格和密集内容压进固定视觉 token 预算,本身就是质量风险。

因此,生产系统应把图片输入当作一个有预算的资源,而不是一个透明附件。


工程落地:一条可控的图像输入管线

1. 标准化图片入口

第一步不是调模型,而是建立统一的 Image Intake 层。所有进入 VLM 的图片先经过标准化:

  • 校验 MIME 类型、文件大小、宽高、长宽比和帧数。
  • 去除不参与推理的元数据,例如 EXIF 和文件名依赖。
  • 对透明背景图片做确定性背景填充。
  • 修正旋转方向,避免模型误读倒置或横置文本。
  • 生成标准图片指纹,例如 sha256(normalized_bytes)

这一层的目标是让同一张业务图片在不同请求、不同上传路径和不同用户端之间得到稳定的输入表达

type NormalizedImage = {
  imageId: string;           // sha256 of normalized bytes
  mimeType: "image/jpeg" | "image/png" | "image/webp";
  width: number;
  height: number;
  bytes: number;
  orientationFixed: boolean;
  hasAlpha: boolean;
  normalizedUri: string;
  preprocessVersion: string;
};

2. 建立分辨率分档,而不是到处写 if-else

建议把图片处理分成明确档位,而不是在业务代码里临时判断。

vision_profiles:
  low:
    max_short_edge: 512
    use_cases:
      - 粗粒度分类
      - 商品图描述
      - 简单质检
    target: low_cost

  standard:
    max_long_edge: 1536
    use_cases:
      - 一般截图理解
      - 简单 OCR
      - 单图问答
    target: balanced

  high_detail:
    max_long_edge: 2048
    use_cases:
      - 小字识别
      - 表格截图
      - UI 布局理解
      - 多对象定位
    target: quality

  original_sensitive:
    max_long_edge: 6000
    use_cases:
      - computer-use 坐标定位
      - 高密度工程图
      - 法务或审计截图
    target: fidelity

业务方只选择 profile,不直接控制像素参数。模型适配层再把 profile 映射到具体供应商参数——例如 OpenAI 的 detail、Gemini 的 media_resolution、自建 vLLM 服务的 limit_mm_per_prompt 和多模态缓存配置。

3. 先估算预算,再调用模型

VLM 请求在发送前要做预算估算。预算不一定精确等于供应商最终计费,但必须足够用于准入控制、日志归因和告警。

type VisionBudgetEstimate = {
  provider: "openai" | "anthropic" | "gemini" | "self_hosted";
  model: string;
  profile: "low" | "standard" | "high_detail" | "original_sensitive";
  imageCount: number;
  estimatedVisionTokens: number;
  estimatedTextTokens: number;
  estimatedInputCostUsd?: number;
  riskFlags: string[];
};

function estimateVisionTokens(
  img: NormalizedImage,
  profile: string
): number {
  const resized = simulateResize(img.width, img.height, profile);
  const patch = 32;
  return Math.ceil(resized.width / patch) * Math.ceil(resized.height / patch);
}

预算估算必须进入请求日志。否则账单上涨后只能看到”某个模型输入 token 增加”,看不到是哪些图片、哪个业务、哪个分辨率档位、哪类任务导致的。

4. 多图请求必须显式标号

多图输入在生产中很常见:设计稿对比、商品主图与详情图对比、事故照片组、网页操作前后截图。Anthropic 文档建议多图请求用 Image 1:Image 2: 这类短文本标签引入图片,便于模型和后续对话引用。

工程上应把图片标签作为协议字段,而不是让 prompt 作者自由发挥。

{
  "task": "compare_images",
  "images": [
    { "label": "Image 1", "image_id": "img_01", "profile": "standard" },
    { "label": "Image 2", "image_id": "img_02", "profile": "standard" }
  ],
  "instruction": "Compare Image 1 and Image 2. Return only changed UI regions."
}

这样做有三个好处:日志能追踪每张图片,回放测试能稳定复现,模型输出也更容易解析。

5. 缓存标准化图片和多模态处理结果

图像缓存至少有三层:

缓存层内容解决的问题
Normalized Image Cache标准化后的图片字节和派生缩略图重复上传、URL 改变、EXIF 差异
Profile Variant Cache不同 profile 下的缩放版本(如 img_abc@standard@preprocess_v3.jpg同一图片在不同业务中重复缩放
Multimodal Processor Cache视觉编码或多模态处理结果(自建服务)跨请求复用媒体处理结果

vLLM 文档说明,多模态输入通常会按媒体内容做 hash 来支持跨请求缓存,也允许通过 multi_modal_uuids 提供稳定 ID。缓存 key 必须包含模型、profile、预处理版本和供应商参数,不能只用图片 hash:

vision-cache-key = sha256(
  model_id + provider + image_id + profile +
  preprocess_version + detail_or_media_resolution + prompt_image_role
)

否则,一张图在 low 档和 high_detail 档可能错误复用结果,导致质量问题很难排查。


适用场景

这套管线适合三类系统:

场景类型典型用例关键指标推荐策略
在线多模态问答客服截图理解、商品图问答、工单图片分析P95 延迟、单请求成本默认 low/standard,少数升级 high_detail
文档/票据/表格解析发票识别、网页截图布局、结构化输出小字识别、布局保持准入阶段识别密度,密集内容提档
Computer-Use / 自动化浏览器自动化、UI 测试、坐标定位坐标精度、状态变化保留高分辨率,trace 记录截图版本与缩放比

不适合直接套用的场景:专业医学影像、法律证据原件、工业缺陷检测、遥感图像等高风险场景,不能只依赖通用 VLM 的低成本分档,需要独立的模型评测、人工复核和合规流程。


常见误区

误区一:文件越小,成本一定越低

JPEG 压缩可以降低传输字节,但模型侧视觉 token 常常由尺寸、tile、patch 或分辨率档位决定。一个压缩到很小的 4000×4000 图片,仍可能触发较高视觉处理成本。

误区二:所有截图都用高分辨率

截图包含大量空白、重复 UI 和非关键区域。很多任务只需要理解页面类型、按钮状态或主区域内容。先用 standard 档,再对失败样本、低置信样本或小字区域局部裁剪升级,通常比全图高分辨率更稳定。

误区三:缓存图片 URL 就够了

图片 URL 不等于图片内容。CDN 参数、临时签名、压缩版本和重上传都会改变 URL。生产缓存应以标准化后的内容 hash 和业务图片 ID 为主,URL 只能作为来源字段。

误区四:模型会自动处理旋转和小字

模型可能能处理一部分旋转、模糊和小字,但这不应成为生产依赖。OpenAI 文档也提示,旋转、倒置、小字、非拉丁文本和服务端 resizing 都可能影响识别。入口层应尽量把方向、清晰度和有效区域处理好。


上线检查清单

输入准入

  • 是否限制最大文件大小、最大宽高、最大图片数和最大请求 payload?
  • 是否支持 PNG、JPEG、WebP 等业务需要的格式,并拒绝不支持格式?
  • 是否修正旋转方向、透明背景和异常长宽比?
  • 是否对多图请求设置图片数量上限和单图标签?

成本与预算

  • 是否在调用前估算视觉 token 或 tile 数?
  • 是否按租户、业务、模型、profile 记录成本归因?
  • 是否对高分辨率请求设置配额和审批策略?
  • 是否能区分文本 token、视觉 token 和输出 token?

质量与回放

  • 是否有不同 profile 的黄金样本集?
  • 是否记录原图 ID、标准化版本、缩放版本、模型版本和 prompt 版本?
  • 是否支持把失败请求完整回放到相同模型和相同 profile?
  • 是否对 OCR、截图理解、对象定位分别设置质量指标?

缓存与失效

  • 是否缓存标准化图片和 profile 派生图?
  • 是否为自建推理启用多模态处理缓存或稳定 UUID?
  • cache key 是否包含模型、profile、预处理版本和供应商参数?
  • 模型升级、预处理逻辑变化或 profile 变更时是否会自动失效?

FAQ

Q: VLM 图像输入应该默认 low 还是 high?

默认档位应由任务决定,而不是由模型能力决定。粗粒度分类、简单描述和明显目标检测可以默认 low 或 standard;密集文本、表格、截图、坐标定位和细节比对应进入 high_detail 或 original_sensitive。更好的策略是:默认低档,低置信或失败时自动升级

Q: 图片压缩会不会影响模型理解?

会。轻度压缩通常能降低传输成本和存储压力,但过度压缩会让小字、边缘、图标和表格线条变差。生产系统应对压缩质量、缩放尺寸和任务准确率做离线评测,而不是只按文件大小优化。

Q: 为什么需要记录 preprocess_version?

因为图片预处理会改变模型看到的内容。一次背景填充策略、缩放算法、裁剪规则或旋转修正的变化,都可能影响结果。没有 preprocess_version,模型输出漂移时无法判断是模型变了、prompt 变了,还是图片处理链路变了。


参考资料

常见问题

VLM 图像输入为什么不能直接上传原图?
因为视觉模型通常会按 patch、tile 或视觉 token 对图片计费和处理,原图过大可能增加 token、延迟和失败率,也可能在服务端被自动缩放,导致小字和细节不可控。
低分辨率会不会明显降低识别质量?
取决于任务。分类、粗粒度描述和简单质检通常可以先走低分辨率;OCR、截图理解、表格、坐标定位和细节比对应进入高分辨率或原始分辨率通道。
多模态缓存应该缓存图片文件还是视觉特征?
生产系统通常先缓存标准化后的图片版本和稳定 ID;自建推理服务还可以缓存多模态处理结果或 embedding,但必须绑定模型、分辨率策略和预处理版本。