2026-10-27 · 深度笔记

AI 图片生成的存储与带宽账:一次生成到底吃多少字节

算了一笔 AI 绘图服务的存储和流量账:一张图在磁盘上多大、用户看一次要拉多少、哪些环节最容易失控,以及我最后怎么配的。

云主机AI工程存储带宽CDN

给图片生成服务做预算的时候,我一开始只算了 GPU 成本,后来发现账单出来的时候,GPU 只占三分之一,剩下的全是存储和出站流量。

这篇是我把账重新算了一遍之后的结果。

一次生成留下多少字节

先看最直观的:一张 1024×1024 的图,各种格式存下来多大。

格式单张体积说明
PNG1.5-2.5MB无损,AI 生成图里最费空间
JPEG q90200-400KB有损,通用
JPEG q80100-200KB有损,画质损失可接受
WebP q85150-300KB比 JPEG 略小,兼容性要确认
AVIF q6080-150KB最小,但转码吃 CPU
原图(模型直出)2-4MB通常是 PNG 或带元数据的格式

这个表里最刺眼的是第一行和最后一行的差距:同一张图,PNG 存是 WebP 的十倍。

我的服务一开始把模型直出的原始 PNG 直接落盘,然后原样返回给前端。一张图 2MB,用户看十张就是 20MB。移动端弱网下,那个加载条能转半分钟。

反直觉的一点:用户要的不是原图

我的用户(一个做海报生成的小团队)最初的要求是"给我最高画质",我照做了。

结果发现他们真正会做的操作是:生成 → 缩小到海报尺寸 → 排版。生成时的 1024×1024 原图,在他们的工作流里几乎从来不是最终交付物。

于是我加了一条规则:原图存起来,但对外只发缩放过的版本。

原图(1024×1024 PNG)  → 对象存储,加密,只给创作台用
展示图(512×512 WebP)  → CDN,对外
缩略图(160×160 WebP)  → CDN,对外,用于列表

一次生成留三份,磁盘占用没怎么涨(缩略图极小),但对外流量降到了原来的五分之一。

关键在于展示图的尺寸要按实际场景定。我一开始把展示图也做成 1024,后来看访问日志,一半的请求其实只需要列表里那个小方块。

带宽账:按访问模式算,不按生成量算

这是最容易搞错的地方。直觉上"生成得多 = 流量大",但实际上:

出站流量 ≈ 生成量 × 平均每次生成的访问次数 × 展示图体积

我用自己站点的一个月数据算:

场景月生成量月展示访问展示图体积月出站流量
内部工具,几乎没人看20005000200KB1GB
小众产品,有人看500040000200KB8GB
有分享功能的8000300000200KB60GB

你看,同一个生成量,因为访问模式不同,出站流量差了 60 倍。流量是访问量的函数,不是生成量的函数。

所以预算的时候我不看"我打算生成多少张",我看"每个生成结果会被看几次"。带分享功能的产品,光是分享出去的图片被反复打开,就能吃掉大半预算。

存储的坑:元数据比图片还能塞

有一件事我是在账单里看出来的——对象存储的请求次数比数据量还贵。

因为我的实现里,每张图生成完要写一次元数据、算一次缩略图、算一个校验和,这些全是独立的对象操作。生成一张图可能对应七八次存储请求。

后来改成:原始文件一次 PUT,中间的处理在内存里做完,最后合并成一次批量写。请求次数降下来了。

还有一个更隐蔽的:我给每张图生成的路径里带了时间戳和随机 ID。

# 改之前
key = f"images/{timestamp}_{uuid}.png"

# 改之后
key = f"images/{content_hash}.png"

用内容哈希做 key 有两个好处。一是重复上传自动去重——用户重试同一张图不会存两遍。二是 CDN 缓存能命中,因为 URL 稳定。

原来的时间戳 URL 每次请求都是新地址,CDN 完全没法缓存,所有流量都回源。改完之后,CDN 命中率从 20% 涨到 95% 以上。

CDN 上的三个配置

第一,缓存头要长。 图片内容不可变(key 是内容哈希),缓存时间直接设一年:

Cache-Control: public, max-age=31536000, immutable

第二,回源带宽要做限制。 我在源站前面加了一层限流,避免缓存失效瞬间(比如批量刷新)把源站打挂。

第三,过期之后主动刷新。 内容哈希理论上不会变,但如果我后来改了压缩参数、想让老图用新编码,得让 CDN 重新拉。做法是保留一个"生成参数版本"字段,参数变了就在 key 里带上版本号:

key = f"images/{content_hash}_v{encoder_version}.webp"

版本号一变 URL 就变,CDN 自然回源重新拉。用户拿到的是新图,老 URL 依然有效。

转码放在哪儿

有一段时间我把 WebP 转换放在云主机上做,结果 CPU 打满,图片展示接口响应变慢。

后来挪到了对象存储的事件通知上:图片写完触发一个函数去转码,转完再写展示图,CDN 指向转好的那份。

这样做的代价是用户第一次请求时可能拿到 404(转码还没完成)。我的处理方式是:原图的 URL 也保留一个,几秒后自动切到转码后的地址。

如果你的场景要求严格不能有 404,那就得在上传接口里同步完成转码——那就要给转码服务留出足够的 CPU 核数,别让它和 Web 服务抢。

一份我现在用的检查清单

价格这块我不写具体数字,各家计费口径差得挺远(按量、按请求次数、流量阶梯都不一样),以官方页面为准。上面的体积和流量量级是我自己站上的实测,换个分辨率和编码参数会明显不一样。

接着读