6.4 把缓存收益写进账本:月度成本报表实战 前三节把成本拆成了明账、回本账和隐性账,可到了月末财务要的是一张能对账的报表,不是三段推导。这一节给交付物:先把月度报表的字段和口径定死,再点破三个最容易让数字对不上的口径陷阱,然后演示怎么用第5章埋的点自动出表,最后说清楚给管理层的一页纸摘要该怎么写。这张表就是第7章拿去和量化、蒸馏、路由并肩比成本的统一卷面。 月末要对账,先定口径 一张能签字的月度推理成本报表,字段至少要覆盖这几列:请求量、token 明细(输入/输出/命中读/未命中写四档各自用量)、账面成本(实际付的)、理论无缓存成本(假设全价付的)、节省额、有效单价、命中率、回本进度。口径定不清,同一份日志能算出三个不同的"节省额",财务一对就拒。
前三节把成本拆成了明账、回本账和隐性账,可到了月末财务要的是一张能对账的报表,不是三段推导。这一节给交付物:先把月度报表的字段和口径定死,再点破三个最容易让数字对不上的口径陷阱,然后演示怎么用第5章埋的点自动出表,最后说清楚给管理层的一页纸摘要该怎么写。这张表就是第7章拿去和量化、蒸馏、路由并肩比成本的统一卷面。
一张能签字的月度推理成本报表,字段至少要覆盖这几列:请求量、token 明细(输入/输出/命中读/未命中写四档各自用量)、账面成本(实际付的)、理论无缓存成本(假设全价付的)、节省额、有效单价、命中率、回本进度。口径定不清,同一份日志能算出三个不同的"节省额",财务一对就拒。
最关键的两个派生数必须先讲明:节省额 = 理论无缓存成本 - 账面成本,它不是拍出来的,是四档用量各自乘单价后相减得到的;有效单价 = 账面成本 / 输出百万 token 量,它把命中率和写税都揉进一个可比数,方便跨月、跨模型比。回本进度则是累计节省额对累计改造投入的比值,单调上升才有说服力。
陷阱一:写溢价算不算节省的对冲项。有人算节省时只减输出常规价与读价之差,把写税当独立支出单列,结果节省额虚高。正确做法是有效单价公式里写税已经在分母里,节省额必须用它算,写税自然对冲,不能两头都算省。陷阱二:未命中但命中"平台缓存"的重复计算。部分请求虽未命中你的业务缓存,却命中了推理平台底层的复用缓存,这层节省既不属于你也不该你认领,报表里要单独剔除,否则节省额被平台红利撑大。陷阱三:多模型混部时分摊。不同模型单价、命中率、显存占用都不同,若用总量平均,小模型的高命中会被大模型拉平,报表失真。必须按模型维度先分组出小计,再汇总数,绝不能用一把均价抹平。
第5章的埋点数据已经有了每请求的命中标记、各档 token 计数、模型标识。下面先用一句聚合 SQL 把原始日志压成月粒度小计(表名与字段为教学示意),再用一段 Python 把小计折成报表字段。
-- 月度缓存成本报表聚合(教学示例,表名与字段为示意) SELECT DATE_TRUNC('month', req_time) AS month, model_id, COUNT(*) AS total_reqs, SUM(in_tokens) / 1e6 AS in_m, SUM(out_tokens) / 1e6 AS out_m, SUM(CASE WHEN cache_hit THEN out_tokens ELSE 0 END) / 1e6 AS out_hit_m, SUM(CASE WHEN NOT cache_hit THEN out_tokens ELSE 0 END) / 1e6 AS out_miss_m, SUM(CASE WHEN NOT cache_hit AND need_write THEN out_tokens ELSE 0 END) / 1e6 AS write_m FROM inference_log WHERE req_time >= '2026-01-01' AND req_time < '2026-02-01' GROUP BY model_id, 1 ORDER BY model_id;
聚合出的小计交给下面这段脚本,按模型算账面成本与节省额,再汇总。价目同样用假设数字,实际以官方价目为准。
# 月度报表折算脚本(教学示例,价目为假设值,实际以官方价目为准) PRICE = {"input": 10.0, "output": 30.0, "cache_read": 1.0, "cache_write": 10.0} def build_row(model_id, in_m, out_m, out_hit_m, out_miss_m, write_m): """把聚合小计折成一张报表行,返回字典""" book = (in_m * PRICE["input"] + out_miss_m * PRICE["output"] + out_hit_m * PRICE["cache_read"] + write_m * PRICE["cache_write"]) no_cache = (in_m * PRICE["input"] + out_m * PRICE["output"]) # 假设无缓存全价 saving = no_cache - book eff = book / out_m if out_m else 0 hit = out_hit_m / out_m if out_m else 0 return { "model": model_id, "book_cost": book, "no_cache_cost": no_cache, "saving": saving, "effective_price": eff, "hit_rate": hit, } if __name__ == "__main__": rows = [ build_row("model_a", in_m=6000, out_m=3000, out_hit_m=1800, out_miss_m=1200, write_m=720), build_row("model_b", in_m=2000, out_m=1000, out_hit_m=500, out_miss_m=500, write_m=300), ] tot_book = tot_nc = tot_sav = 0.0 for r in rows: tot_book += r["book_cost"]; tot_nc += r["no_cache_cost"]; tot_sav += r["saving"] print(f"{r['model']:8s} 账面{r['book_cost']:>9,.0f} 无缓存{r['no_cache_cost']:>9,.0f} " f"节省{r['saving']:>8,.0f} 有效单价{r['effective_price']:.2f} 命中{r['hit_rate']:.0%}") print(f"{'合计':8s} 账面{tot_book:>9,.0f} 无缓存{tot_nc:>9,.0f} 节省{tot_sav:>8,.0f}") print(f"整体节省率 {tot_sav / tot_nc:.1%}")
运行输出示例:
model_a 账面 45,000 无缓存 90,000 节省 45,000 有效单价 15.00 命中60% model_b 账面 18,000 无缓存 30,000 节省 12,000 有效单价 18.00 命中50% 合计 账面 63,000 无缓存 120,000 节省 57,000 整体节省率 47.5%
注意 model_b 命中率低、有效单价高,若不按模型拆分,整体会被 model_a 拉平,掩盖 model_b 的问题。这正是陷阱三的现实后果。
下面这张月报样例用上文脚本的同组数字,补上请求量与回本进度,字段口径与前述一致。改造累计投入假设二十万元,本月为改造后第四个月,累计节省已达约二十万出头,回本进度过百。
| 模型 | 请求量(百万) | 输入(百万) | 输出(百万) | 命中读(百万) | 未命中写(百万) | 账面成本(元) | 无缓存成本(元) | 节省额(元) | 有效单价 | 命中率 | 回本进度 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| model_a | 90 | 6000 | 3000 | 1800 | 720 | 45000 | 90000 | 45000 | 15.00 | 60% | 已回本 |
| model_b | 30 | 2000 | 1000 | 500 | 300 | 18000 | 30000 | 12000 | 18.00 | 50% | 已回本 |
| 合计 | 120 | 8000 | 4000 | 2300 | 1020 | 63000 | 120000 | 57000 | 15.75 | 57.5% | 累计回本 |
这张表每一列都能和原始日志对账:账面成本等于四档用量乘单价之和,节省额等于无缓存减账面,有效单价等于账面除输出量。财务拿它去翻底层日志,数字咬得住,才会认你的"缓存省了五万七"。
一页纸摘要第一句必须是结论,不是过程:"本月缓存净省五万七千元,整体命中率五成七,改造投入已全额回本。"之后才给支撑数字,且每个数字都要能在报表里对账,不能出现报表没有的口径。转化收益、延迟改善作单独一行"上行期权"列在结论后,明确标注"未计入硬回本"。最后留一个风险句:命中率若跌破五成或请求量缩半,回本安全垫收窄——这呼应 6.2 的敏感性表,让老板知道数不是死的。一页纸不堆过程、不秀公式、不掺水,结论、数字、风险三块就够,技术负责人念完它,预算会才接得住下一句"那四条降本路线比下来谁更值"。
把这张报表做成了例行产出,缓存就从技术优化变成了可审计的财务科目。第7章要拿量化、蒸馏、路由和它在同一个成本框架里并排比,比的正是这张表上"净省多少、多久回本、隐性账多大"三个数——本章立的卷面,就是下一章的发令枪。