NLP文本分类踩坑:BERT微调 vs RAG,我测了3个数据集,说点大实话

🔑 关键词:自然语言处理,文本分类,BERT微调,RAG,大模型

📖 摘要:一篇不太正经但很真实的NLP技术对比。用客服工单、新闻标题、医疗问诊三个数据集,对比BERT微调和RAG方案。有准确率、显存、成本、延迟的具体数字,也有我踩过的坑和最后的选择。

先交代背景:为什么我要折腾这个

图片

去年底接了个活,帮一家做SaaS客服的公司翻新他们的工单分类系统。原来的方案是TF-IDF + LinearSVC,准确率卡在78%上不去,而且新出现的工单类型经常分错。老板说想上大模型,预算给了两万块,问我能不能搞。我当时第一反应是:直接微调一个BERT呗,这玩意儿我熟。但后来发现事情没那么简单——他们有12万条历史工单,标注质量一般,而且业务方要求响应时间低于200ms,服务器只有一张T4显卡(16G显存)。这就很尴尬了。

我花了两个晚上查资料,发现现在网上有两种声音:一种说RAG是银弹,不用训练,接个API就行;另一种说微调才是王道,RAG效果不稳定。吵得不可开交。我决定自己测一遍,用真实数据说话。于是找了三个数据集:客服工单(12万条,18个类别)、新闻标题(THUCNews子集,5万条,10个类别)、医疗问诊(我自己爬的,8000条,6个类别)。分别跑BERT-base微调、RAG(用text-embedding-ada-002 + GPT-3.5-turbo)、以及一个混合方案。

图片

具体数字和踩坑记录

先看客服工单数据集。BERT-base微调:训练3个epoch,batch size 32,学习率2e-5,在T4上跑了大概47分钟。准确率从78%提到了91.3%,F1是0.89。显存占用峰值9.2G,推理延迟单条18ms(batch=1)。看着不错对吧?但问题来了:新类别出现时,必须重新标注数据再训练,一次至少两天。而且标注成本,一条工单平均要花1.5元,加一个新类别得标500条,就是750块,还不算我的人工。

RAG方案呢?我用LangChain搭了个pipeline:把训练集全部切成512token的chunk,用ada-002做embedding存到Chroma,检索top-5,然后拼prompt让GPT-3.5-turbo输出类别。准确率只有84.7%,比微调低了6.6个百分点。但好处是加新类别只需要往向量库里加几十条样本,5分钟搞定。延迟嘛,平均1.8秒,API成本每千次查询约0.12美元。老板一看延迟就摇头,说客服系统等不起。

图片

最坑的是医疗问诊数据集。BERT微调直接过拟合了,训练集准确率99%,验证集只有72%。后来发现是标注不一致,同一个症状被标了三个不同科室。RAG反而好一点,因为检索能带回相似的标注样本,准确率76%。但GPT-3.5-turbo有时候会“自作主张”编一个不存在的科室,比如“神经内科”写成“神经科”,害得我加了个后处理映射表。

我的独立观点:别站队,看约束条件

图片

测完这三个数据集,我最大的感受是:网上那些“RAG已死,微调当立”或者反过来的人,大概率没在真实生产环境里跑过。微调和RAG根本不是替代关系,它们解决的是不同维度的问题。微调是把知识“压”进模型参数里,适合类别固定、数据量大、对延迟和成本敏感的场景。RAG是把知识放在外部检索里,适合类别动态变化、标注数据少、能接受一定延迟的场景。但这里有个隐藏的坑:RAG的效果高度依赖embedding模型和检索策略,我试过用bge-large-zh替换ada-002,在中文客服数据上检索准确率从82%掉到74%,因为ada-002对中文短文本其实一般。换回bge后好了点,但API成本上去了。

另一个反直觉的发现:混合方案不一定比单一方案好。我试了“RAG检索+微调小模型做重排”,在客服数据集上准确率只比纯微调高了0.8%,但系统复杂度翻倍,维护成本增加。后来我干脆放弃了混合,直接上微调,然后加了一个规则引擎处理新类别——新类别出现时,先用RAG临时兜底,攒够200条标注再微调一次。这个“渐进式微调”的思路反而最实用。

图片

还有一个点:很多人忽略推理成本。BERT-base微调后,用ONNX Runtime优化,在T4上单条推理只要6ms,QPS能到800。而RAG每次都要调API,QPS受限于网络和OpenAI的速率限制,实际只能到5-10。如果你的业务量每天超过10万次调用,微调省下来的钱够买好几张显卡了。但如果你每天只有几百次调用,RAG的按量付费显然更划算。

给要上手的人几条实在建议

第一,先算账。把你的数据量、标注成本、GPU成本、API成本列个表。我见过一个团队,数据只有3000条,非要微调BERT,结果过拟合严重,还不如直接用RAG+few-shot。第二,不要迷信榜单。BERT-base在GLUE上分数高,不代表在你的垂直领域好。我试过用RoBERTa-wwm-ext,在医疗数据上比BERT-base高了3.2个点,但训练时间多了40%。第三,延迟是隐形杀手。RAG的1.8秒延迟在离线分析里无所谓,但在线客服系统里用户会直接关窗口。如果你必须用RAG,考虑加缓存或者用更小的embedding模型(比如text-embedding-3-small,延迟能降到800ms,但准确率掉2个点)。

图片

最后说个真实教训:我一开始图省事,直接用OpenAI的API做RAG,结果有一次OpenAI抽风,整个分类服务挂了半小时,被老板骂惨了。后来我加了个本地备用模型(ChatGLM3-6B),虽然准确率只有71%,但至少不会全挂。所以,如果你的业务不能接受停机,永远要有fallback方案。NLP这行,没有银弹,只有权衡。我现在给客户做方案,第一句话都是:“你先告诉我,你最不能接受的是什么?是准确率低一点,还是延迟高一点,还是成本超预算?”想清楚这个,选型就简单了。

(全文完)

🏷️ 标签: