ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SageMaker 批推理越并发越慢?我补机器学习基础后用分片策略提速 10 倍

2026/9/4 3:08:10 拓冰建站 浏览量
SageMaker 批推理越并发越慢?我补机器学习基础后用分片策略提速 10 倍 SageMaker 批推理越并发越慢?我补机器学习基础后用分片策略提速 10 倍周一上午,CTO 在项目群里 我:「线上评论摘要生成的批处理还没跑完?11 点例会我要看到结果。」我盯着后台那个还在慢吞吞串行推理的 Flask 进程,剩余时间预估还要 8 小时--那一刻我知道,再不动大手术项目就要崩了。当时我对批量推理的认知还停留在单机多线程,从没认真研究过 SageMaker 这种托管服务怎么分片并行。后来才后悔:如果早一点补完机器学习入门,把机器学习管道里的数据预处理和并行逻辑吃透,也不至于在 SageMaker 上连踩一礼拜坑。为什幺串行推理差点让我错过例会这次的任务是为电商评论区生成当日摘要,每天下午 2 点前必须产出结果。我们的模型是一个微调过的 FLAN-T5,部署在一台 g4dn.xlarge 上,用 Flask 包装了一个 HTTP 推理接口。一开始的设计很天真:把 20 万条评论按顺序 POST 过去,单进程一个个生成,然后写回 S3。实测下来,平均每条推理耗时 0.18 秒,加上网络开销和写入延迟,每分钟只能处理约 200 条。20 万条跑完就是将近 17 个小时,根本赶不上例会。我试过开多线程并发,但 GPU 显存被线程抢崩了,报 OOM 的频率比推理成功还高。当时我以为加机器就能搞定,于是开了 4 台 g4dn 一起分担负载。结果每台跑 5 万条,耗时确实降到 4 个多小时,但总成本一天烧掉 $22,一个月光推理环节就要 $660,CTO 直接否决了这个方案。这时有同事提醒我:“试试 SageMaker 的 Batch Transform,它能自动并行,你连集群都不用管。”于是我二话没说就把模型打包上传,准备切换。但这次匆忙上阵,为我后面一周的翻车埋下了种子。如果当时我系统学过 AWS机器学习,知道批量推理和实时端点的差别,至少能少踩一半的坑。第一次用 SageMaker Batch Transform 就翻车我照着文档把模型创建成 SageMaker 模型资源,又新建了一个 Batch Transform 任务,输入给了那个 20 万行的 JSON Lines 文件,输出指向另一个 S3 桶。关键参数MaxConcurrentTransforms我顺手填了个「10」,心想并发高自然就快。任务跑了 20 分钟后,我打开 CloudWatch 一看,傻眼了:吞吐量只有每分钟 500 条,比我单机还差。更恐怖的是成本页显示已经烧了近 $15,原来 Batch Transform 按实例小时收费,并发不够快、任务时间拖长,费用直接爆炸。我赶紧停了任务,对着 S3 里的输出文件检查,发现很多分片只处理了几百条,有的却堆了几万条--负载极不均衡,并发根本没发挥出来。这是我才意识到,自己对 SageMaker 的分片机制完全不了解,连 SplitType 的参数都没设。文档里写了很多关于 batch strategy 的说明,可我压根没去看,因为那些概念对我来说太陌生了。机器学习基础中有一整节讲数据分与管道并行,我要是早点看过,就不会把 20 万行全塞进一个文件里,还指望它自己均匀切。这次翻车让我不得不停下手里所有工作,系统地把机器学习入门和机器学习基础从头补了一遍。亚马逊云科技机器学习那套课程里,刚好有一个实战模块专门用 SageMaker 演示批量推理和数据预处理的关系,我花了一个周末把它完整跑完了。补机器学习入门:搞清楚分片和并发的原理学完机器学习入门后,我才真正看懂 SageMaker Batch Transform 的并行逻辑:它会把输入文件按某种策略(SplitType)切割成很多小分片,然后分配给不同的实例并发处理。如果SplitTypeLine,它会按行切分,但若输入文件就是一个巨大的 JSON Lines,切割后的分片大小完全取决于行与行的字节分布,很可能出现「一坨大、一坨小」。机器学习管道那一章还教了我一个关键知识点:数据预处理不只是清洗文本,还包括为分布式计算做“分桶”和“打散”,保证每个 worker 拿到的工作量相当。我照着这个思路,把原始的 20 万条评论重新做了数据预处理:先用split命令按行数均匀切成 100 个小文件,每个文件刚好 2000 行,再上传到 S3 并指定清单文件作为 Batch Transform 的输入。同时,特征工程部分让我理解了为什么不能把原始文本直接喂给模型:虽然我们做的是生成任务,但在生成之前对文本做长度截断和特殊字符清洗,能大幅减少模型推理时的无效计算,这在批量场景中对吞吐量的影响远比单条请求大。亚马逊云科技机器学习的动手实验里,我跟着做了一轮“清洗-分片-批量推理”的全流程,看到自己的任务从 8 小时降到 2 小时,信心瞬间涨回来。从 12 小时到 1 小时:并发的正确打开方式补完机器学习基础和机器学习入门后,我重新设计了整个批量推理流水线。下面是我最终用的 SageMaker Batch Transform 创建代码:import boto3 sm_client boto3.client(sagemaker) response sm_client.create_transform_job( TransformJobNamecomment-summary-final, ModelNameflan-t5-summary, MaxConcurrentTransforms50, # 根据账户实例配额设为 50 MaxPayloadInMB1, # 每条评论不超过 1KB,设小点可减少单次开销 BatchStrategyMultiRecord, TransformInput{ DataSource: { S3DataSource: { S3DataType: ManifestFile, S3Uri: s3://my-bucket/input-manifest.json } }, ContentType: application/jsonlines, SplitType: Line, # 按行分割,配合 Manifest 文件指向的 100 个均匀小文件 CompressionType: None }, TransformOutput{ S3OutputPath: s3://my-bucket/output/, AssembleWith: Line, Accept: application/jsonlines }, TransformResources{ InstanceType: ml.g4dn.xlarge, InstanceCount: 5 # 5 台实例,每台处理 10 个并发,总计 50 个并行度 } )注意这里的MaxConcurrentTransforms设为 50,是 5 台实例 × 每台 10 个并发,刚好把 100 个分片文件两轮就消化完。之前我踩坑的最大教训就是:并发数量必须和输入分片数量配套,而且要基于数据预处理的结果来设计,而不是拍脑袋填数字。为了验证分片是否均匀,我在上传前还用脚本检查了每个文件的体积:for f in part_*.jsonl; do wc -c $f done | sort -n | head -3 tail -3 # 确保最小和最大文件的字节数差距在 10% 以内最终跑完这个任务,时钟显示只用了 1 小时 12 分钟,成本比之前串行方案降低了约 60%。打开 S3 的输出文件,每个分片的结果数量都和预期一致,没有出现某个分片空转或过载的情况。给想用 SageMaker 批量推理的人 5 条建议从这次差点搞砸例会的惨痛经历里,我总结出几条可执行的原则:先补机器学习基础再碰 SageMaker:别像我一样连分片是什么都不知道就去调参数。机器学习基础课里把数据并行、模型并行、批量推理的调度逻辑讲得很清楚,花一个下午看完,能省下你一周的调试时间。数据预处理是并行的前提:均匀切割输入文件、清洗无关字符、合理设定MaxPayloadInMB,这三件事不做,就算 SageMaker 的调度再智能也帮不了你。数据预处理这个专题在机器学习入门里有详细演示,值得跟着练一遍。选对 SplitType:Text/Line/RecordIO 三种模式各有适用场景,JSON Lines 任务强烈建议用Line,并配合 Manifest 文件指向均匀分割的小文件,这样并发最可控。监控并发与队列深度:Batch Transform 可以实时看到 transform 队列中的 pending 数量,一旦发现队列堆积,立刻检查分片均匀度或增加实例数。AWS机器学习的监控模块专门有这部分最佳实践。用 Spot 实例降本但不降速:Batch Transform 支持使用 Spot 实例,在成本上可以再往下压 30-50%。前提是你的任务能容忍短暂的失败重试,这个就需要你真正理解机器学习管道的容错设计,以免重试带来额外的开销。现在回过头看,那次例会前 8 小时未完成的恐慌其实完全没必要。只要把亚马逊云科技机器学习的基础打牢,SageMaker 的批量推理不仅是提速利器,更是省钱良药。如果你也在为大量推理任务头疼,不妨先点开那几门入门课看看,它可能比盲目加机器更早让你看到 10 倍改善。