2、大模型部署基础:模型格式、推理引擎与部署形态
大模型从训练完成到真正对外提供服务,中间隔着一条“最后一公里”的鸿沟。这条鸿沟由三个核心要素填平:模型格式决定了模型如何被存储和加载,推理引擎决定了模型如何被高效计算,部署形态则决定了模型以何种方式接入业务。三者相互耦合,任何一层的选型失误都会在CI/CD流水线中放大为构建失败、启动超时或推理延迟飙升。本章从工程视角拆解这三层基础,并给出可落地的判断依据与实战案例。
上图展示了三层基础架构的耦合关系。模型格式是“存储契约”,推理引擎是“计算执行器”,部署形态是“服务边界”。在CI/CD流水线中,这三层分别对应构建阶段的格式转换、测试阶段的引擎基准、发布阶段的形态配置。下面逐一深入。
2.1 模型格式:从训练产物到部署产物的转换
核心原理
模型格式本质上是权重参数、网络结构、优化器状态(可选)的序列化编码方式。PyTorch原生格式(.bin或.safetensors)保存的是Python对象的张量字典,依赖Python运行时和torch库才能加载。ONNX(Open Neural Network Exchange)是一种跨框架的中间表示,将模型编译为计算图,每个节点对应一个算子,适合在不同推理后端间迁移。TensorRT格式则是NVIDIA针对GPU深度优化的引擎文件,将算子融合、精度校准、内核自动调优的结果固化到二进制中,只能在TensorRT运行时加载。
从CI/CD视角看,格式转换是构建阶段的关键步骤。一个常见的错误是直接在Dockerfile中加载PyTorch模型并启动服务,这会导致镜像体积膨胀(PyTorch依赖约2-3GB)、启动时间变长(动态图初始化开销大),且在生产环境暴露Python解释器风险。正确的做法是在CI流水线中增加“模型编译”阶段,将训练产物转换为部署格式,并生成对应的校验和(SHA256)以确保可追溯性。
判断方法或操作流程
选择模型格式时,建议按以下流程决策:
- 评估部署目标:如果目标环境是NVIDIA GPU且追求极致性能,优先考虑TensorRT;如果需要在CPU、GPU、ARM等多种硬件上运行,选择ONNX;如果只是内部快速验证,可暂时保留PyTorch格式。
- 检查算子兼容性:使用
onnxruntime.transformers或polygraphy工具扫描模型中是否有不支持的算子(如自定义Attention实现)。 - 验证精度差异:格式转换可能引入数值误差,特别是FP16或INT8量化。在CI中设置精度阈值(如余弦相似度>0.99),自动比对转换前后模型的输出。
- 固化转换脚本:将转换过程写成可重复执行的Python脚本或Makefile目标,纳入版本控制,确保每次构建使用相同参数。
| 格式 | 优点 | 缺点 | 典型场景 |
|---|---|---|---|
| PyTorch (.bin/.safetensors) | 调试方便、生态丰富、支持动态图 | 依赖Python运行时、加载慢、体积大 | 开发调试、快速原型 |
| ONNX (.onnx) | 跨平台、算子标准化、支持多种runtime | 部分算子转换失败、性能非最优 | CPU部署、边缘设备、多框架互通 |
| TensorRT (.engine) | GPU性能极致、显存优化好、延迟低 | 绑定NVIDIA GPU、构建时间长、可移植性差 | 生产环境GPU推理、高QPS服务 |
案例拆解:ONNX转换中的算子兼容性排障
某金融科技公司需要将一款基于BERT的意图识别模型部署到CPU服务器上,原始模型为PyTorch格式。CI流水线中执行torch.onnx.export时,报错Unsupported operator: aten::one_hot。分析发现,模型预处理层使用了torch.nn.functional.one_hot,该算子在ONNX opset 11中不支持。解决方法是:在模型定义中将one_hot替换为torch.where组合实现,或升级opset到17(部分算子已支持)。修改后重新导出,ONNX模型大小从420MB降至398MB(去除了冗余的梯度信息),在ONNX Runtime CPU上推理延迟从85ms降至62ms。复盘经验:格式转换前应先用torch.jit.trace或torch.export做静态化检查,提前暴露动态控制流问题。
safetensors格式替代.bin以避免恶意权重注入。
2.2 推理引擎:吞吐、延迟与显存效率的权衡
核心原理
推理引擎是模型格式与硬件之间的“翻译官”和“调度器”。vLLM的核心创新是PagedAttention,将KV Cache分页管理,显存利用率提升至接近100%,配合Continuous Batching实现高吞吐。TGI(Text Generation Inference)由Hugging Face维护,与transformers库无缝集成,支持模型并行和量化。TensorRT-LLM则是NVIDIA官方方案,将LLM编译为TensorRT引擎,通过算子融合和内核自动调优实现最低延迟。
在CI/CD中,引擎选型直接影响测试策略。vLLM适合压测吞吐(如每秒请求数),TGI适合功能验证(与HF生态兼容),TensorRT-LLM适合延迟敏感场景(如P99延迟<100ms)。引擎的版本升级可能改变算子行为,因此CI中必须锁定引擎版本,并对每次升级做回归测试。
判断方法或操作流程
选择推理引擎时,建议建立以下评估矩阵:
- 吞吐需求:如果业务需要高并发(如聊天机器人),优先vLLM;如果单请求延迟敏感(如实时翻译),优先TensorRT-LLM。
- 硬件约束:TensorRT-LLM仅支持NVIDIA GPU;vLLM和TGI支持CUDA和部分CPU(vLLM的CPU后端仍在完善)。
- 生态集成:如果团队已有HF pipeline代码,TGI迁移成本最低;如果从零搭建,vLLM的OpenAI兼容API更友好。
- 量化支持:TensorRT-LLM支持INT4/INT8权重量化且精度损失小;vLLM支持FP16和INT8,但INT4需额外配置。
# CI中引擎基准测试示例(伪代码)
def benchmark_engine(engine_name, model_path, input_prompts):
if engine_name == "vllm":
from vllm import LLM, SamplingParams
llm = LLM(model=model_path, tensor_parallel_size=2)
outputs = llm.generate(input_prompts, SamplingParams(max_tokens=128))
elif engine_name == "tensorrt_llm":
import tensorrt_llm
# 加载.engine文件并执行推理
# 记录吞吐、延迟、显存峰值
return metrics
案例拆解:vLLM与TensorRT-LLM的延迟对比
某电商平台需要部署一个7B参数的客服对话模型,要求P99延迟<200ms,同时支持200 QPS。初始使用vLLM(FP16),压测结果显示P99延迟为310ms,不达标。分析瓶颈:vLLM的Continuous Batching在长序列场景下会牺牲单请求延迟换取整体吞吐。切换到TensorRT-LLM,使用INT8量化并开启KV Cache复用,P99延迟降至145ms,但构建时间从5分钟增加到35分钟(TensorRT引擎编译耗时)。最终方案:在CI中设置两个构建任务——日常开发使用vLLM快速迭代,发布前执行TensorRT-LLM编译并自动比对精度。复盘经验:延迟与吞吐不可兼得,必须根据业务SLA明确优先级;TensorRT-LLM的构建时间应纳入CI超时预算。
2.3 部署形态:在线、离线与边缘的差异化策略
核心原理
部署形态决定了模型服务的SLA、资源弹性和运维复杂度。在线服务要求毫秒级响应,通常部署为常驻API服务,使用GPU集群和负载均衡,需要处理突发流量。离线批处理对延迟不敏感,但要求高吞吐和任务隔离,常用于数据标注、批量内容审核。边缘部署则受限于设备算力和功耗,需要模型压缩(量化、剪枝)和轻量运行时。
在CI/CD中,部署形态影响流水线的后段:在线服务需要配置健康检查、滚动更新和自动扩缩容;离线任务需要定义队列、超时和重试机制;边缘部署则需要生成OTA包并验证设备兼容性。
判断方法或操作流程
选择部署形态时,按以下维度决策:
- 响应时间要求:P95延迟<500ms选在线;可接受分钟级延迟选离线。
- 流量模式:流量波动大(如白天高、夜间低)选在线+弹性伸缩;流量平稳且任务可排队选离线。
- 数据隐私:数据不能出域(如医疗影像)选边缘;数据可上传云端选在线。
- 成本预算:在线GPU成本高,离线可用抢占式实例降低成本,边缘需一次性硬件投入。
| 形态 | 延迟要求 | 资源类型 | CI/CD关注点 |
|---|---|---|---|
| 在线服务 | P99<200ms | GPU集群、HPA | 滚动更新、金丝雀发布、健康检查 |
| 离线批处理 | 分钟~小时 | CPU/GPU队列、Spot实例 | 任务幂等、失败重试、资源配额 |
| 边缘部署 | 实时(本地) | Jetson、手机NPU | 模型压缩、OTA升级、离线缓存 |
案例拆解:混合部署形态的CI/CD设计
某安防公司需要部署一个视频分析模型,包含两个场景:实时告警(在线)和夜间批量录像分析(离线)。在线服务使用vLLM部署在GPU集群,离线任务使用TGI在CPU集群运行。CI/CD流水线设计如下:
- 构建阶段:将PyTorch模型分别转换为ONNX(用于CPU离线)和TensorRT(用于GPU在线),并生成两个镜像标签。
- 测试阶段:在线镜像执行延迟压测(P99<150ms),离线镜像执行吞吐测试(每分钟处理2000帧)。
- 发布阶段:在线服务使用金丝雀发布(先5%流量),离线任务使用CronJob定时触发。
运行一个月后发现,离线任务在Spot实例上频繁被回收,导致任务失败。解决方案:在离线任务中增加检查点(checkpoint)机制,每处理1000帧保存中间结果,任务重启后从最近检查点恢复。复盘经验:离线任务必须设计为幂等且可断点续跑,否则云厂商的实例回收会摧毁整个批处理流程。
deploy_config.yaml,显式声明格式、引擎、形态及其版本,流水线根据该配置自动选择构建和测试策略。任何一层的变更都应触发全链路回归,避免“改了一个格式,线上延迟翻倍”的隐性故障。