多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

KServe 多模型服务(MMS)基准测试全解析:从压力测试到延迟对比的实战数据指南

KServe 多模型服务(MMS)基准测试全解析:从压力测试到延迟对比的实战数据指南 模型推理服务云原生后端微服务MLOps人工智能【免费下载链接】kserveStandardized Distributed Generative and Predictive AI Inference Platform for Scalable, Multi-Framework Deployment on Kubernetes项目地址https://gitcode.com/gh_mirrors/ks/kserve点击查看免费下载导读本文基于 KServe 仓库官方基准测试文档 docs/samples/multimodelserving/benchmark/BENCHMARK.md系统还原了多模型服务Multi-Model Serving简称 MMS为验证模型部署可扩展性而执行的压测与性能测试全过程包括环境配置、模型规格、资源对比、QPS 与延迟分位数据并结合 MMS 设计指南 与 TrainedModel 控制器、Model Agent 等源码实现 解读数据背后的原理。读完本文你将掌握 KServe 多模型服务相较传统一模型一服务模式的资源收益与延迟代价的量化结论并理解如何设计自己的 MMS 压测方案。说明本基准测试执行于 KFServing v0.5.1 / Knative v0.17.0 / Istio v1.7.x 时期KFServing 即 KServe 前身文中数据均为该环境下的实测结果供当前版本部署时作为数量级参考。一、为什么需要多模型服务模型部署可扩展性问题KServe 的多模型服务MMS是为解决大规模模型部署的可扩展性瓶颈而设计的。传统设计下每个模型对应一个独立的 InferenceService这种一模型一服务器one model, one server的模式在大规模场景下会迅速触及 Kubernetes 集群的三类限制计算资源限制每个 InferenceService 因注入 sidecar 存在资源开销通常每个副本约增加 0.5 CPU 与 0.5G 内存。按 MMS 指南 的估算部署 10 个模型、每个 2 副本时纯 overhead 即为 10 CPU / 10 GB 内存而将多个模型加载进同一个 InferenceService 后每个模型的平均开销可降至约 0.1 CPU / 0.1 GB 内存。对 GPU 模型而言多个模型共享一个支持多模型的服务器如 Triton可显著减少 GPU 需求量。最大 Pod 数限制Kubelet 默认每节点最多 110 个 Pod官方建议不超过 100。若每个 InferenceService 平均占用 4 个 Pod两个 transformer 副本 两个 predictor 副本一个 50 节点的典型集群最多只能部署约 1000 个模型。最大 IP 地址限制每个 Pod 独立占用 IP。一个 4096 IP 的集群同样按每服务 4 Pod 估算最多只能部署约 1024 个模型。MMS 的解法是引入TrainedModel 自定义资源模型工件与宿主 InferenceService 解耦多个 TrainedModel 可加载进同一个 InferenceService。用户流程为先部署一个不带storageUri的宿主 InferenceService再部署多个 TrainedModel CR 将模型加载到该服务随后从 TrainedModel 的 status 中解析预测端点并调用详见 Triton 多模型服务示例。下述基准测试正是对这一方案的量化验证。二、压力测试Stress Test一台服务器究竟能装多少模型压力测试的目标是测定一个集群/一台模型服务器能够承载的最大模型数量。2.1 环境与集群限制项目配置软件版本kfserving v0.5.1、knative v0.17.0、istio v1.7.xIP 地址上限最大 2048 个 IP内存上限每工作节点最大 0.55 TiBKubernetes Service 上限约 2000 个受 Istio ingress gateway 限制Pod 上限660 个6 个工作节点 × 每节点最多 110 个 PodETCD 大小65 MiB2.2 InferenceService 与模型规格apiVersionserving.kserve.io/v1beta1concurrency1minReplicas1模型服务器Triton model serverqueue-proxyCPU 1、内存 500Mi传统单模型服务 Predictor 规格CPU 100m、内存 100Mi多模型服务 Predictor 规格CPU 10、内存 10Gi测试模型Triton 官方 simple_string 示例模型TensorFlow 框架大小 700B2.3 基线测试结果传统单模型服务成功部署了352 个 InferenceService多模型服务用6 个 InferenceService 部署了约 1 万个模型即多加载了 2800% 的模型多模型服务在部署更多模型的同时整体 CPU 与内存消耗反而更低传统方式总消耗387 CPU、211 GB多模型方式总消耗66 CPU、63 GB单看 queue-proxy 的消耗差异尤为显著传统方式的 queue-proxy352 CPU、176 GB多模型方式的 queue-proxy6 CPU、3 GB重要发现与警告在多模型服务中增删模型会持续生成新的 ConfigMap 版本ETCD 来不及清理旧版本。在部署数千个模型时这可能耗尽 ETCD 内存。因此官方建议考虑使用外部存储来保存模型而不是依赖 ConfigMap 承载海量模型配置。从源码看该机制印证了压力测试的观察TrainedModel 控制器将模型配置写入models.json形式的 ConfigMap见 pkg/modelconfig/configmap.go 中的Process与CreateEmptyModelConfig而 Model Agent 通过 fsnotify 监听 ConfigMap 挂载目录的..data符号链接变化来感知模型增删见 pkg/agent/watcher.go。每增删一次模型都会产生一次 ConfigMap 更新这正是 ETCD 版本堆积的根源。三、性能测试Performance Test延迟与吞吐的正面交锋性能测试的目标是对比传统单模型服务与多模型服务在相同负载下的延迟表现。3.1 测试环境与配置软件版本kfserving v0.5.1、knative v0.17.0、istio v1.7.xInferenceServiceapiVersionserving.kserve.io/v1beta1concurrency 1minReplicas 1Triton 模型服务器queue-proxy 为 1 CPU / 500MiSimple StringCPU 负载传统与多模型 Predictor 规格均为 CPU 1、内存 16GBBertGPU 负载传统与多模型 Predictor 规格均为 CPU 1、内存 16GB、GPU 1压测工具Vegeta loading test agentSimple StringCPU模型 700B每档压测 1 分钟QPS 档位为 5/10/20/30/40/50/100每秒BertGPU每档压测 1 分钟QPS 档位为 5/10/20/30/40每秒3.2 Simple String 测试CPU测试结论传统单模型服务5 个 InferenceService在不触发扩容的情况下可支撑高达2500 QPS多模型服务1 个 InferenceService 5 个 TrainedModel在500 QPS时开始触发扩容未触发扩容时两者的相对延迟基本可比多模型服务对自动扩缩容更为敏感一旦开始扩缩容延迟会急剧恶化因此压测在 500 QPS 后停止500 QPS 将进入 Pod 扩容阶段已超出延迟对比的关注范围。传统单模型服务5 个 InferenceService测试数据Client side QPSQPS per InferenceService (model)meanp50p90p95p99max2553.7633.6694.0894.2224.51143.87750103.783.5463.9364.0976.956220.716100203.5943.4963.8754.0084.43884.529150303.593.2943.6423.7446.191260.923200403.5083.1693.5353.6315.659205.389250503.8823.2883.5593.6429.411302.4925001004.2823.0863.4713.60452.807324.81510002006.2663.0623.4366.7116.774308.413150030010.3652.8285.90155.38183.41103920004009.3382.7834.28832.912178.8371058250050011.7962.7198.50964.447217.9111043多模型服务1 个 InferenceService 5 个 TrainedModel测试数据Client side QPSQPS per InferenceServiceQPS per TrainedModelmeanp50p90p95p99max252554.4533.854.1814.28226.465138.6715050104.0813.6763.9344.04811.653107.775100100205.0513.3043.6253.77272.291193.219150150304.4033.3993.6843.82346.981119.896200200406.0713.2963.638.58790.514203.785250250506.8463.2233.57523.825100.167351.26500500100260.2022.8461298202522412475上图直观展示了 500 QPS 场景的差异多模型服务在触发扩容后p90 以上延迟急剧抬升p90 约 1298ms、max 接近 2475ms而传统方式在该负载下仍保持毫秒级延迟。数据明确提示多模型服务在未扩容时延迟与传统方式相当但扩容瞬间的尾部延迟会显著放大。3.3 Bert 测试GPU测试结论传统单模型服务5 个 InferenceService在不触发扩容时可支撑200 QPS多模型服务1 个 InferenceService 5 个 TrainedModel在不触发扩容时可支撑40 QPS两者延迟相对接近同样地多模型服务对自动扩缩容更敏感。传统单模型服务5 个 InferenceService测试数据Client side QPSQPS per InferenceService (model)meanp50p90p95p99max5133.845ms32.986ms36.644ms41.596ms100.959ms131.195ms10234.212ms32.058ms42.791ms55.192ms89.832ms154.485ms20430.133ms31.262ms33.721ms35.142ms40.981ms102.801ms30630.726ms30.32ms33.607ms37.405ms64.624ms700.839ms40829.646ms29.785ms32.164ms32.856ms39.188ms792.061ms501029.458ms29.519ms32.725ms33.833ms44.221ms670.303ms1002026.844ms25.783ms31.322ms32.179ms39.265ms811.652ms2004051.627ms25.389ms107.946ms175.522ms321.154ms1.616s多模型服务1 个 InferenceService 5 个 TrainedModel测试数据Client side QPSQPS per InferenceServiceQPS per TrainedModelmeanp50p90p95p99max55130.978ms30.195ms32.435ms52.474ms59.936ms139.195ms1010231.903ms32.795ms35.105ms37.138ms48.254ms266.965ms2020429.782ms30.777ms34.452ms36.409ms46.074ms256.518ms3030624.929ms23.548ms30.218ms30.935ms49.506ms205.663ms4040834.087ms24.483ms50.588ms87.01ms155.853ms801.393ms上图显示GPU 场景下两者在 mean/p50 段几乎持平均在 30ms 量级但随着分位点升高p90/p95/p99多模型服务的尾部延迟显著放大p90 约 50ms、p95 约 87ms、p99 接近 156ms传统方式对应约 32ms/33ms/39ms说明共享 GPU 的模型服务器在高分位延迟上存在排队代价。四、数据背后的实现原理4.1 TrainedModel模型工件的标准载体TrainedModel CR 是 MMS 的核心抽象。其 API 定义位于 pkg/apis/serving/v1alpha1/trained_model.go关键结构如下TrainedModelSpecinferenceService指定的宿主 InferenceService 名称model模型规格ModelSpecstorageUri模型仓库地址、framework框架名如 tensorflow、pytorch、sklearn、onnx、xgboost 等由校验 webhook 校验是否被模型服务器支持、memory该模型预估的最大内存用于判定模型服务器是否有足够内存加载该模型TrainedModelList.TotalRequestedMemory()累加所有 TrainedModel 声明的内存供控制器校验其总和不超过宿主 InferenceService 的内存上限。实际部署时宿主 InferenceService 需预留足够内存。以 Triton 示例 为例宿主服务声明cpu: 1、memory: 2Gi随后分别部署cifar10pytorch、memory 1Gi与simple-stringtensorflow、memory 1Gi两个 TrainedModel同时须将 Triton 的multiModelServer标志置为 true 以启用该实验特性。4.2 Model Agent下载、加载、卸载的执行者模型的实际装载由随 predictor 一起运行的Model Agent完成源码位于 pkg/agent/watcher.go用 fsnotify 监听模型配置目录ConfigMap 更新..data符号链接的 CREATE 事件触发模型配置重新解析比对出新增/变更/删除的模型产生ModelOp事件puller.go每个模型一个独立的 model channel 与 worker实现按模型并发goroutine 并行下载与装载Add操作先调用Downloader.DownloadModel将模型从storageUri下载到本地模型目录再 POSThttp://localhost:8080/v2/repository/models/{name}/load调用模型服务器 V2 协议的 load 端点Remove操作先删除本地目录再 POST/v2/repository/models/{name}/unload。这解释了性能测试中多模型服务对扩缩容更敏感的现象扩容新 Pod 时Model Agent 需要重新下载并加载该 Pod 上的全部模型MMS 当前采用同构分配每个副本承载相同模型集合模型下载与加载完成前流量会积压导致延迟在扩容窗口内大幅抬升。4.3 模型配置的 ConfigMap 承载与 ETCD 压力控制器将模型清单以models.json形式写入 ConfigMap结构见 pkg/modelconfig/configmap.goModelConfig{modelName, modelSpec{storageUri, framework, memory}}由 agent 读取并解析。每次 TrainedModel 增删都会更新 ConfigMap产生新的 ConfigMap 版本并触发所有副本上的 agent 重新同步——这正是压力测试中观察到的ETCD 版本堆积问题来源。官方据此建议在数千级模型场景下应引入外部存储来承载模型而非依赖 ConfigMap 传递全部模型配置。4.4 同构分配与自动扩缩容的取舍如 Triton 示例 所强调当前 MMS 实现采用同构homogeneous分配即每个 InferenceService 副本持有相同的模型集合扩缩容基于该集合的聚合流量而非单个模型的请求量。单一模型的流量尖峰可能触发整个模型集合扩容即便集合内其他模型请求量很低——这对承载大型模型的 InferenceService 并不理想。备选方案是异构heterogeneous分配每个副本承载不同模型集合各模型按自身流量独立扩缩容资源利用率更高。五、结论与部署建议综合两组基准测试可得到如下可量化的结论维度传统单模型服务多模型服务MMS模型部署规模压测环境352 个 InferenceService6 个 InferenceService 承载约 1 万模型2800%总资源消耗387 CPU / 211 GB66 CPU / 63 GBqueue-proxy 消耗352 CPU / 176 GB6 CPU / 3 GBCPU 模型单服务不扩容吞吐上限2500 QPS5 isvc500 QPS 触发扩容GPU 模型单服务不扩容吞吐上限200 QPS5 isvc40 QPS 触发扩容未扩容时延迟基准与传统方式相当扩容/高负载下尾部延迟相对平缓p90 显著放大大规模部署隐患受 Pod/IP/资源限制ETCD 版本堆积建议外部存储部署建议基于本基准与官方指南按场景取舍模型数量大、单模型流量低、GPU 昂贵是 MMS 的理想场景新闻分类、按用户/按类目定制模型等对单模型高 QPS、延迟敏感的核心流量传统一模型一服务仍是更稳妥的选择。内存规划宿主 InferenceService 须预留足够内存以承载全部 TrainedModel 的memory总和校验逻辑由 TrainedModel webhook 与控制器共同完成。存储规划数千模型规模下务必评估外部模型存储方案避免 ConfigMap 更新压垮 ETCD。自建压测可直接复用仓库内的 Vegeta 压测 Job 模板perf.yaml通过vegeta attack -rateQPS/1s -duration时长 -targets配置文件复现本文档各 QPS 档位的压测并关注扩容窗口的尾部延迟指标p90/p95/p99。延伸阅读多模型服务设计指南MMS Guide可扩展性问题的完整推导与架构设计Triton 多模型服务实操示例宿主 InferenceService 与 TrainedModel 的完整 YAML 与部署流程TrainedModel API 定义CRD 结构与字段注释Model Agent 实现watcher / puller / downloader模型装载的底层机制模型配置 ConfigMap 生成逻辑models.json 的读写与版本更新赞分享模型推理服务云原生后端微服务MLOps人工智能【免费下载链接】kserveStandardized Distributed Generative and Predictive AI Inference Platform for Scalable, Multi-Framework Deployment on Kubernetes项目地址https://gitcode.com/gh_mirrors/ks/kserve点击查看免费下载相关推荐Siege基准测试模式终极无延迟高并发压力测试技巧Siege是一款强大的开源HTTP/FTP负载测试和基准测试工具能够模拟大量并发用户对Web服务器进行压力测试。对于开发者和系统管理员来说掌握Siege的基性能测试Claude Code Router性能基准测试各模型延迟与成本对比Claude Code Router性能基准测试各模型延迟与成本对比 ? 痛点直击你还在为LLM API成本与性能发愁吗 作为开发者你是否经常面临这样的后端API网关LLM 网关大模型libSQL性能测试终极指南从压力测试到基准对比的完整实践方案libSQL性能测试终极指南从压力测试到基准对比的完整实践方案 libSQL作为一款支持多数据库的高性能C数据库访问库其性能表现直接影响应用程序的响应速数据库关系型数据库嵌入式数据库后端数据同步上一篇AWS SDK for Kotlin 操作 Amazon ECS集群与服务全生命周期实战指南下一篇语义分割模型评估指南用unet-pytorch计算mIOU的3种方法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表