上线首日 OOM:我照着文档改参数,最后还是补了 AI 学习才止血发版日中午,我把优化了一周的推荐模型推到了 SageMaker 端点。监控面板的绿色指示灯刚亮了三分钟,CloudWatch 就炸出一串红色的 OutOfMemory 异常。 那一刻我才后悔:如果早一点把AI学习课程里「机器学习入门」的部署章节看完--它直接把生产环境内存排查的每一步拆解成了可落地的操作,我根本不会在线上硬扛这场翻车。发版日中午,模型刚上三分钟就 OOM我用的实例是 ml.m5.xlarge,4 核 16GB 内存,PyTorch 模型大约有 1.2 亿参数。离线压测时 QPS 过百,延迟稳在 120ms,我以为上线稳了。但流量一切进来,内存曲线直直往上飙:从初始的 2.1GB 一路涨到 14.3GB,然后容器直接被 kill。日志里只剩下「exit code 137」和几行来不及写全的报错。我当时还抱着一丝侥幸:八成是实例规格太小,升配就好了。后来我才明白,这种「升配万能论」正是没系统学过AI学习的人最常犯的错误。课程里专门有一节讲模型服务容量规划,教你怎么根据模型大小和请求模式计算内存基线,学完就能准确判断到底是配置问题还是内存泄漏。升配、降 Batch Size 都试了,内存照样泄露我把实例换成了 ml.m5.4xlarge,64GB 内存,以为这下稳了。结果内存照样一条斜线往上走,只是多活了二十多分钟,最终还是 OOM。接着我把 batch size 从 64 一路砍到 8,推理延迟直接涨到 580ms,用户体验雪崩,可内存泄漏依然存在。翻看容器里的进程,发现每次模型推理后,GPU 显存虽然回收了,但主机的 RSS 内存却越积越多。我在inference.py里是这样加载模型的:# 旧版推理入口--每收到一个请求都重新加载模型 import torch import os def handler(data, context): model torch.jit.load(os.path.join(/opt/ml/model, model.pt)) model.eval() with torch.no_grad(): result model(data) return result显然,每次调用都完整加载一次模型权重,而旧的实例根本不会被回收。这种错误我在AI学习的实践模块里其实看见过,但因为没认真看,愣是没往模型生命周期上想。深夜翻出 AI 学习课程:原来模型加载藏了这么多坑晚上十点,我还在对着 CloudWatch 的内存图发呆。最后干脆翻出之前草草报名、只看了前两章的AI学习课程,直接跳到「机器学习入门」里讲亚马逊云科技机器学习服务部署的那一讲。课程里的工程师用了一个非常接近我场景的案例:一个基于 PyTorch 的多模型端点,上线第一天同样频繁 OOM。讲师一步步拆解了 SageMaker 推理容器的模型加载机制,指出如果你在容器内全局持有一个模型对象而不利用 SageMaker 的按需加载,内存就会不断膨胀。这一集还花了一大段时间讲解 SAGEMAKER_MULTI_MODEL 环境变量、model_fn的标准写法以及MAX_CONCURRENT_TRANSFORMS的作用。这才是AI学习最值钱的地方--它不跟你空谈理论,而是把生产上真正会要命的配置细节掰开揉碎讲清楚。当时我就想,如果上线前看过这一节,就不用在这儿熬夜了。三行配置止血:SageMaker 多模型端点的正确打开方式按照课程里的指引,我把推理脚本彻底重写了:# 改造后的推理入口 import torch import os def model_fn(model_dir): # 利用 SageMaker 缓存,仅在需要时加载 device torch.device(cuda if torch.cuda.is_available() else cpu) model torch.jit.load(os.path.join(model_dir, model.pt), map_locationdevice) model.eval() return model def predict_fn(input_data, model): with torch.no_grad(): return model(input_data).numpy()同时在容器启动脚本里加上:export SAGEMAKER_MULTI_MODELtrue export MAX_CONCURRENT_TRANSFORMS2重新部署后,batch size 设为 16,并发控制在 2。内存占用稳定在 3.8GB 到 4.2GB 之间,再也没有出现泄漏。我还用深度学习入门中学到的 PyTorch 最佳实践,对输入张量做了显式.detach(),进一步减轻了内存拷贝。下面这张表是我在两种配置下的测试数据,一目了然:方案实例类型Batch Size并发数稳态内存结果旧版(全局模型加载)ml.m5.4xlarge644持续上涨至 OOM每隔 20 分钟重启新版(按需加载 限制并发)ml.m5.xlarge1624.2GB连续运行 72 小时无异常降了实例规格还稳住了内存,这完全是机器学习管道思维起作用了--把推理看作一个完整管道,而不只是一个算法调用。复盘:如果早点学完机器学习基础,这些坑本可以避免事情过去后我坐下来复盘,发现这次翻车根源并不只是「代码写错了」,而是我对模型的过拟合问题和推理资源规划之间的关联完全没概念。训练阶段,我们的混淆矩阵看起来很漂亮,但模型容量因此被撑得很大,推理时所需的内存也水涨船高。如果当时在机器学习基础这门课程里学过模型复杂度分析和推理性能预估的方法,早就该警惕这种上线风险。课程里还有一节专门讲数据预处理管道在推理中的落地方式,教你怎么把在线特征计算固化到管道里,既省内存又减少延迟。我在事故前自己做的那套预处理器,足足占了 600MB 常驻内存,而现在参考AI学习中的示例重写后,内存直接砍到了 80MB。这一下让我真切体会到,机器学习入门阶段的每一个基础概念,都能直接决定生产系统的稳定度。顺便说一句,后来我用深度学习基础中学到的 TorchScript 序列化技巧,把模型从 450MB 压缩到了 220MB,冷启动时间从 35 秒降到 12 秒。这些技能点,都是实打实从AI学习的不同模块里捡回来的。上线前的内存检查清单(建议收藏)经历了这趟事故,我给自己建了一条铁规矩:凡是没有完成 AI学习 相应章节的同学,一律不许碰生产模型配置。如果你也正在准备上线,下面这 5 条可以直接拿去用:先学完 AI学习 的部署章节再动手指--课程把模型加载机制、并发控制和内存回收策略都拆成了可验证的实验,比看文档高效得多。部署前用MAX_CONCURRENT_TRANSFORMS压测,找到你的实例在 OOM 之前的真实上限,而不是拍脑门定 batch size。使用model_fn而非全局变量加载模型,让 SageMaker 帮你管理模型生命周期--这个技巧在AI学习的机器学习基础模块里有详细的代码示例。把特征工程和推理预处理做成无状态管道,避免在线计算时产生不必要的内存拷贝。定期用 CloudWatch 的内存指标做回归测试,一旦发现基线偏移,立刻回顾AI学习中关于数据漂移和模型更新的章节,排查是不是模型文件被意外增大。如果你现在也正被上线 OOM 搞得焦头烂额,真的建议点开AI学习看一下--它不止能教你机器学习算法,更重要的是能让你搞清楚模型从训练到推理的整条链路该怎么设计,这才是最值回时间的部分。