图 1:本文封面,从权重文件到在线服务的四步流水线。
这个系列前一天有一篇真题解析,把 vLLM、TensorRT-LLM、TGI 三个推理框架的特性横向对比了一遍——那篇回答的是「选什么」。但面试和工作中更常见的后续问题是:选定框架之后,一个躺在磁盘上的模型文件,怎么变成别人能调用的在线 API?本文换个主轴,讲「怎么做」:把推理服务落地拆成五段工程链路,框架对比不再重复,每一段只说它要解决的问题和验收标准。
第一步:权重准备,先搞清楚自己拿到了什么。
一个可部署的模型目录通常是三件套:权重文件、分词器、模型配置。现在主流权重格式是 safetensors——按 Hugging Face 官方仓库的说明,它用「JSON 头部 + 原始字节」的结构存储张量,相对 pickle 格式不会执行任意代码、支持惰性加载,大模型可以只读需要的分片。这一步的验收标准是完整性校验:分片权重是否齐全、SHA 校验是否过、配置里的层数和隐藏维度与权重张量形状对不对得上。别小看这一步,下到一半的权重文件是部署事故的高发区。
第二步:格式转换与量化,先算账再动手。
训练侧产出的权重格式五花八门,进入推理引擎前可能要合并分片、统一格式。更重要的决策是量化:FP16 的每个参数占 2 字节,INT8 占 1 字节、INT4 占半个字节——7B 模型从 FP16 压到 INT4,权重从 14 GB 降到约 3.5 GB,显存立省四分之三,代价是精度损失需要用校准数据评估。量化不是必选项,是显存预算与质量之间的交换:显存够就 FP16 原样上,不够再逐级往下压。
第三步:推理引擎加载,把钱花在显存账本上。
引擎加载权重后,真正决定服务能力的是 KV Cache 的预算。以 vLLM 为例,它的 PagedAttention 论文(2023 年发表,arXiv:2309.06180)把操作系统的虚拟内存分页思想搬到 KV Cache 管理上,按需分配显存页、几乎消除碎片,再配合连续批处理按 token 步调度请求。但机制再省,总量账还是要自己算。用一个 7B 模型(32 层、隐藏维度 4096、FP16)算一遍(Node.js 22.15.0,node vram.js):
权重占用: 7B × 2 字节 = 14 GB
KV Cache 每 token: 2(K+V) × 32 层 × 4096 × 2 字节 = 524288 字节 ≈ 512 KB
上下文 2048:单请求 KV Cache ≈ 1.1 GB
上下文 8192:单请求 KV Cache ≈ 4.3 GB
上下文 32768:单请求 KV Cache ≈ 17.2 GB
80 GB 卡:预留10%后可用 58 GB 给 KV Cache
上下文 2048 时并发上限 ≈ 54 路
这张账本回答了运维最关心的两个问题:一张卡能开多少并发、能支持多长上下文。KV Cache 随并发数和上下文长度线性增长——上下文从 2048 拉到 32768,单请求的 KV Cache 从 1.1 GB 涨到 17.2 GB,比权重本身还大。显存预算就是在这里决定服务形态的。
第四步:服务封装,把引擎包成别人能用的接口。
引擎只负责算,对外的接口层要单独做。主流做法是提供 OpenAI 兼容 API:vLLM 官方文档列出 /v1/chat/completions 等端点,客户端改个 URL 就能接入;流式输出用 SSE 逐 token 推送,首字延迟体验全靠它。这一层还要处理引擎不管的事:鉴权、限流、超时、最大长度控制、请求校验。验收标准很具体——压测出 TTFT(首 token 延迟)、TPOT(逐 token 延迟)和吞吐三条基线,按显存账本定下并发上限。
第五步:网关与监控,上线只是开始。
多实例部署时前面挂网关做负载均衡;监控要盯三个指标:TTFT、吞吐、显存占用。vLLM 内置 Prometheus 兼容的 /metrics 端点,TGI 官方仓库也列出 Prometheus 指标和 OpenTelemetry 分布式追踪,直接接进现有监控体系即可。上线姿势用灰度:小流量先跑,指标正常再全量,异常可回滚。这五段走完,一个模型文件才真正变成了生产可用的在线服务。
图 2:五段链路、显存账本与上线检查单。
把五段串成一句话。
权重准备管「拿到的东西对不对」,格式与量化管「显存装不装得下」,引擎加载管「算得快不快、并发开多大」,服务封装管「别人怎么调」,网关监控管「出了问题能不能发现」。下次再被问「这个模型多久能上线」,别只答框架名——把五段链路各自的验收标准摆出来,才是工程答案。你部署推理服务时在哪一段踩过最深的坑?权重、量化、并发还是监控?欢迎分享。