从裸辞到重拾代码:我在上海出租屋里折腾机器学习部署的半年
去年十月的一个雨夜,我坐在浦东张江一间35平米的出租屋里,盯着笔记本屏幕上闪烁的光标,心里五味杂陈。窗外是陆家嘴模糊的霓虹,屋内是我和女友小雅合租的“梦想基地”——月租5800,一人2900,比我上一份大厂工资条上的房租补贴还多800块。
就在三个月前,我裸辞了。不是因为被优化,也不是因为躺平,而是实在受不了每天在“算法模型精度提升0.1%”和“线上服务QPS扛不住”之间反复横跳的窒息感。我原以为Gap半年能让我找回对技术的热情,结果前两个月刷LeetCode、看论文、打游戏,第三个月开始焦虑得睡不着觉——银行卡余额从6位数滑向5位数,而我的简历还在“待投递”状态里吃灰。
直到上周五晚上,小雅端着一碗泡面坐到我旁边,轻声说:“要不……我们试试接点外包?你不是一直说想搞搞模型部署那套东西吗?”
我愣了一下,看着她眼下的黑眼圈——她也在一家创业公司做前端,最近项目上线天天加班。那一刻,我突然意识到:Gap不是逃避,而是为了更清醒地出发。
于是,我决定用接下来一个月的时间,从零搭建一个端到端的机器学习部署系统,并写一篇真正“踩过坑”的技术总结。这篇文章,就是那段深夜coding、外卖盒堆成山、和小雅一起debug到凌晨三点的真实记录。
为什么部署比训练更让人头秃?
很多人以为,训练出一个高精度模型就万事大吉了。但现实是:模型跑通 ≠ 能上线。我在大厂时就见过太多“实验室英雄”——本地AUC 0.95,一上生产环境直接OOM(Out of Memory),或者延迟高到用户刷新三次页面都加载不出来。
这次我想做个简单的文本分类服务:输入一段评论,输出情感倾向(正面/负面)。模型本身不难,用BERT微调就行。但怎么让它稳定、高效、低成本地跑起来?这才是真正的战场。
我给自己定了三个目标:
- 低延迟:API响应 < 200ms
- 低成本:月成本控制在500元以内(毕竟现在是自由职业者)
- 可维护:别让我半夜被报警电话吵醒
技术选型:一场现实与理想的拉扯
第一关:推理框架选谁?
我首先对比了几个主流方案:
| 方案 | 优点 | 缺点 | 我的体验 |
|---|---|---|---|
| PyTorch + Flask | 简单直接,本地调试方便 | 内存占用高,QPS低 | 本地跑得飞起,一压测就崩 |
| TensorRT | NVIDIA亲儿子,推理快 | 只支持GPU,绑定CUDA生态 | 我的Mac M1 Pro哭了 |
| ONNX Runtime | 跨平台,支持CPU/GPU | 转换过程玄学,有些算子不支持 | 搞了半天报错Unsupported operator: LayerNorm |
| TorchServe | 官方出品,支持模型版本管理 | 配置复杂,文档像天书 | 看完文档只想躺平 |
最后我妥协了:用Hugging Face Transformers + FastAPI。虽然不是最高效的,但胜在生态成熟、社区活跃。而且FastAPI自动生成Swagger文档,对接前端超友好——这点对我这种现在要自己写前后端的人太重要了。
小插曲:有天凌晨两点,我正为序列化问题抓狂,突然想到Claude。打开Claude 3.5,输入:“如何把Hugging Face的pipeline打包成FastAPI服务,并支持batch inference?”
它不仅给了完整代码,还提醒我加@app.on_event("startup")预加载模型,避免每次请求都重新加载。那一刻,我真的想给Anthropic寄锦旗。
第二关:语言之争:Python 还是 Java?
我知道很多读者会问:“为啥不用Java?你们大厂不是都用Java微服务吗?”
说实话,在大厂时我确实天天和Java打交道。Spring Boot、Dubbo、ZooKeeper……一套组合拳下来,服务治理是稳了,但开发效率是真的慢。改个配置要重启,调个参数要走发布流程,连打印个日志都要等5分钟。
这次个人项目,我毫不犹豫选了Python。理由很简单:快速验证 > 完美架构。我可以用10行代码启动一个带OpenAPI文档的服务,而Java可能要写3个类+2个配置文件。
但我也理解Java的优势:JVM的稳定性、成熟的监控体系、线程模型对高并发更友好。如果这个服务未来要支撑百万DAU,我会毫不犹豫切Java + Quarkus(GraalVM原生编译,启动快、内存省)。不过目前嘛……先活下来再说。
和小雅聊天时她吐槽:“你以前在大厂不是天天说‘Java才是工业级语言’吗?”
我苦笑:“那是为了说服老板别用Node.js重构核心系统……现在我自己当老板,当然选让自己开心的。”
第三关:部署平台:云厂商 vs 新势力
预算有限,我排除了AWS SageMaker(贵)和阿里云PAI(配置复杂)。重点试了三个新选择:
1. Replit Agent + Replit Deploy
Replit最近推出的Agent功能简直离谱——你只要写注释,它就能生成代码。比如我写:
# TODO: create a FastAPI endpoint that takes text input and returns sentiment
它真的给我生成了完整endpoint!部署更是点一下按钮就完事,自带HTTPS和域名。
但问题也明显:冷启动严重。第一次请求要等8秒(模型加载),后续才快。而且免费版有CPU限制,高峰期直接降频。适合demo,不适合生产。
2. Vercel + Serverless Function
我把模型转成ONNX,用onnxruntime-web跑在Serverless函数里。优势是全球CDN加速,首尔、新加坡访问都很快。但ONNX转换后精度掉了2%,而且Vercel对函数执行时间限制10秒——我的模型推理就要3秒,容错空间太小。
3. 阿里云ECS + Docker
最终我选了最“土”的方案:2核4G的ECS(月付98元) + Docker容器化。虽然要自己配Nginx、写健康检查、设自动重启,但完全可控。而且配合Cloudflare做DDoS防护和缓存,实际体验比Serverless还稳。
关键决策时刻:我用Locust做了压测。Replit在50并发时错误率飙升到30%;Vercel超时频繁;而ECS+Docker在200并发下依然稳定。虽然多花了点时间运维,但换来的是安心睡觉。
算法不是终点,工程才是起点
很多人(包括曾经的我)总觉得“算法工程师”就该专注模型结构、损失函数、调参技巧。但现实是:90%的线上问题,都出在工程环节。
比如这次,我遇到的最大坑不是模型不准,而是:
- 内存泄漏:FastAPI没正确释放tokenizer句柄,跑一天内存涨到3GB
- 依赖冲突:transformers 4.30 和 torch 2.0 不兼容,导致Docker build失败
- 时区问题:日志时间全是UTC,排查问题时差点疯掉
这些和“算法”半毛钱关系没有,但决定了服务能不能活过第一个周末。
我甚至开始怀念大厂的日子——有SRE团队兜底,有监控大盘,有问题@一下就行。但现在,我得自己写Prometheus exporter,自己配Grafana面板,自己半夜爬起来看日志。
但奇怪的是,这种“全栈式痛苦”反而让我找回了编程的乐趣。当我看到自己的API被小雅的前端调用,返回正确的结果时,那种成就感,比在大厂拿到OKR超额完成邮件还强。
给同样在Gap或转型期的朋友几点建议
- 别追求完美架构:先跑起来,再优化。我见过太多人卡在“选型阶段”,半年没写出一行业务代码。
- 善用AI工具,但别依赖:Claude、GitHub Copilot能省80%的样板代码,但核心逻辑还得自己想清楚。
- 成本意识要强:现在每一分钱都是自己的。学会用Spot实例、Serverless、CDN缓存来省钱。
- 保持输出:写博客、发推、做开源。这不仅是记录,更是建立个人品牌——我这篇博客说不定就被哪家startup看到了呢?
写在最后:技术人的尊严不在工牌,而在解决问题的能力
裸辞这半年,我从焦虑到迷茫,再到重新找到节奏。最大的感悟是:工作可以暂停,但成长不能停止。
现在的我,虽然没有大厂title,没有股票期权,但每天醒来都知道自己在做什么、为什么做。昨天刚接到一个朋友的私信,说想用我的部署方案做他们的客服机器人——报价3000元,工期一周。这是Gap以来第一笔收入,不多,但足够支付下个月房租。
我和小雅商量好了:如果年底前能稳定月入1.5w,就不急着回大厂。技术人的价值,不该被钉死在工位上。
所以,如果你也在Gap,或者正考虑裸辞,请记住:世界不会因为你离开某个公司而停止转动,但你的代码可以继续跑下去。
就像今晚,我又在浦东的出租屋里敲下这行字。窗外雨停了,电脑风扇嗡嗡作响,Docker容器里的服务稳稳运行着。这一刻,我觉得自己比在大厂会议室里汇报PPT时,更像个真正的工程师。
共勉。

评论 0