从外包到甲方:我在光谷用Transformers和Google ADK踩过的那些坑
最近半年在技术探索上栽了三个跟头,分别和 Transformers、C、Google ADK 有关。不是教科书式讲解,就是真实踩坑记录。
从一次模型推理优化说起
三月份接手知识库问答系统优化,用Transformers跑BERT-base做语义检索,P99飙到800ms。没GPU,只能CPU推理。用py-spy做火焰图发现tokenization占35%耗时。
坑点一:别在请求路径上重复初始化tokenizer。 之前代码每次请求都AutoTokenizer.from_pretrained(),从磁盘加载要两三百毫秒。改成全局单例后P99降了约200ms。
真正的硬骨头是attention计算。试了ONNX Runtime量化、OpenVINO,最后最狠的一招——用C写扩展。
当Python不够快,C就是最后的尊严
用Cython把矩阵乘法和softmax用C重写。第一个版本写naive三重循环,比PyTorch还慢三倍。后来链接OpenBLAS的cblas_sgemm,速度翻了四倍。
坑点二:C扩展里的内存管理。 在C函数里malloc了缓冲区返回给Python层,忘了释放。上线三天内存从4G涨到14G,被OOM killer干掉。后来用Cython的cython.view.array管理内存,让Python GC统一回收。
这段经历让我体会到:技术探索不是追新潮,而是哪里痛打哪里。需要极致性能时,底层还得回到C。
Google ADK:光鲜文档背后的连环坑
六月份做智能客服Agent,调研后选了Google刚发布的ADK 1.0,主打"开箱即用的多Agent编排"。
结果第一天就崩了。按官方QuickStart写了个LlmAgent配ToolContext调天气API,第一轮正常,第二轮把工具返回的JSON当用户输入重新理解。最后在GitHub issue区找到原因:ADK 1.0.0的SessionService默认内存存储,多轮对话上下文注入有bug,需手动在before_model_callback里拼回历史消息。官方文档只字未提。
坑点三:不要对"官方发布"抱有不切实际的信任。 ADK更新太快,文档迅速过时,抽象层厚,出了问题极难定位。Agent调工具超时报错堆栈全是async_runner内部调用,花了一整个周末才搞明白是ToolContext的timeout默认只有10秒,而天气API高峰期要15秒才响应。
最讽刺的是,ADK底层其实还是调Vertex AI SDK,直接用它很多问题根本不会出现。但当时选了看起来"更高级"的ADK,被坑得头破血流。
这些坑教会了我什么
从外包到甲方,不只是薪资涨了。在外包只需按需求写代码,能不能跑通是唯一标准;到了甲方,你得对性能和稳定性负责,一个坑影响的是真实用户体验。
深度比广度重要,但深度不是靠看文档看出来的,是靠踩坑踩出来的。 Transformers源码读两遍,不如一次火焰图分析来得深刻。C语言大学考61分,不如一次内存泄漏排查让我真正理解指针。ADK文档翻烂了,不如一个GitHub issue让我看清本质。
我的建议:别怕踩坑,但踩完了一定要写下来。每解决一个诡异问题就在Notion里记一笔,已攒四十多条。这些记录比任何技术博客都值钱,因为它们是自己的血泪史。

评论 0