商品短文本类目分类系统(模型轻量化)
从随机森林基线到 BERT 微调再到模型压缩的完整迭代——量化后准确率 93.97%,模型体积从 399MB 缩至 8MB,嵌入商品管理后台实现类目自动预测。
项目概览
| 要素 | 内容 |
|---|---|
| 项目周期 | 2024.08 - 2024.12 |
| 核心技术 | BERT / FastText / PyTorch / 模型压缩(量化/蒸馏/剪枝) |
| 角色 | 独立负责数据处理、模型选型、训练调优、压缩部署 |
| 核心成果 | 准确率 93.97% / 模型体积 399MB → 8MB / 上架效率数倍提升 |
项目背景
公司自营电商商品管理后台,运营人员上架商品时需手动从数百个叶子类目中选择对应类目。类目层级深(3~4 层)、叶子节点多,需要先读商品标题判断品类再逐层导航定位,新人运营经常选错需返工。上架一件商品全流程平均 3 分钟,类目选择是其中最耗时的环节。
核心挑战
- 商品标题短(10~30 字),信息密度低
- 多个核心类目需要平衡准确率与部署资源
- 公司服务器资源受限,需要模型轻量化
- 样本不均衡——热门类目样本多、冷门类目样本少
模型迭代路径
整个项目经历了从基线到重模型再到轻量化的完整迭代路径,不是一步到位上 BERT。
随机森林 + TF-IDF (80.31%)
↓
FastText 词级分词 → 字符级分词 (90.21% → 91.69%)
↓
BERT-wwm-base 微调 (93.61%)
↓
模型压缩(三路线对比)
├─ 量化:399MB → 149MB,93.97%(略升,正则化效应)
├─ 蒸馏:399MB → 8MB,89.04%(BERT → TextCNN)
└─ 剪枝:稀疏化,准确率降约2%迭代方法论:先快速建立基线了解问题边界,再逐步引入更强模型,最后做压缩部署。每一步都有明确的目标和评估标准。
各阶段技术细节
阶段一:基线(随机森林 + TF-IDF)
为什么先做基线:
- 一天就能跑出结果,快速知道"机器学习能做到什么水平"
- 暴露数据问题——哪些类目容易混淆、哪些特征重要、样本是否均衡
- 给后续优化定目标,避免一上来就堆大模型
结果:80.31% 准确率。这个基线很重要——它告诉团队 80% 是机器学习的下限,后续提升都是模型的价值。
阶段二:FastText 升级
从词级分词到字符级分词
初始版本:Jieba 词级分词 → 90.21%
切换到字符级分词后准确率提升到 91.69%。
原因是电商商品标题的特殊性:
- 很多商品名称包含品牌词、型号词,不在常规词典中
- Jieba 会把"iPhone15ProMax"错误切成"iPhone/15/Pro/Max",丢失品牌和型号信息
- 字符级分词把每个字符作为独立单位,不依赖词典,能保留完整的品牌型号信息
字符级分词的另一个优势:天然容错拼写变体和简写("手机壳" vs "手壳")。
自动参数搜索
通过网格搜索优化了学习率、epoch 数、维度大小等超参数。
阶段三:BERT 微调
为什么 BERT 比 FastText 高 2 个百分点:
- FastText 是词袋模型 + n-gram,捕捉的是词汇特征
- BERT 是多层 Self-Attention,能捕捉上下文语义关系和深层语义
- 在商品标题短文本场景,110M 的 BERT-wwm-base 已经足够
训练策略
- 学习率和批次大小调优
- 5 epoch 内收敛
- 过采样少数类 + 数据增强(同义词替换、随机删除、回译)
结果
准确率从 91.69% → 93.61%,提升约 2 个百分点。在十分类场景下 2% 意味着每 100 件商品少错 2~3 件,长期运营返工成本降低明显。
模型压缩:三路线对比
公司服务器资源有限,399MB 的 BERT 全量部署成本高。做了三种压缩路线的对比实验。
路线一:量化(主方案)
方法:PyTorch 量化,从 float32 → int8
结果:
- 模型体积:399MB → 149MB(缩减约 2/3)
- 准确率:93.61% → 93.97%(基本持平,略有提升)
为什么量化后准确率反而提升了?
更准确的说法是"基本持平,略有提升"——差异只有 0.36%,在统计波动范围内。但这个微小提升确实存在,原因是量化起到了隐式正则化效果:
- BERT 原始 float32 参数空间非常大,在 20 万条中等规模数据上容易轻微过拟合
- 量化把参数从 float32 降到 int8,参数精度降低相当于限制了表达能力,反而抑制了过拟合
- 这不是普遍现象——在百万级数据场景下,量化通常会轻微降低准确率。但在这个数据量级和任务复杂度下,正则化效果超过了精度损失
所以核心价值不是准确率提升,而是体积缩减 2/3 的同时准确率几乎无损。
路线二:蒸馏(备选方案)
方法:BERT(教师模型)→ TextCNN(学生模型)
结果:
- 模型体积:399MB → 8MB(减少 98%)
- 准确率:93.61% → 89.04%(下降约 4.6 个百分点)
为什么选 TextCNN 作为学生模型
- 结构简单、参数少:只有几层卷积+池化,天然轻量
- 短文本友好:商品标题 10~30 字,CNN 局部特征提取正好适配
- 推理速度极快:8MB 模型加载快、推理时间 < 1 秒
89% 的准确率够用吗
取决于场景:商品上架场景是"系统自动预测 + 运营确认",89% 意味着约 11% 需要运营修正——但运营只需确认/修正而非从数百个类目中手动查找,操作从逐层导航缩短到看一眼确认。
而且蒸馏模型部署成本极低,可以部署在资源受限的内部服务器上。
路线三:剪枝(补充探索)
基于 torch.nn.utils.prune 实现了两种剪枝:
- 非结构化剪枝:按权重绝对值剪掉最小的权重,稠密连接变稀疏。准确率降约 2%,但稀疏矩阵在 PyTorch 中不会真正加速(稀疏推理支持有限)
- 结构化剪枝:剪掉整个注意力头或整个神经元,模型物理变小。剪掉 20% 注意力头后准确率降约 1.5%,体积实际缩减约 15%
结论:剪枝作为备选方案记录,量化是主要压缩方案。
三路线对比总结
| 压缩方案 | 体积 | 准确率 | 部署难度 | 适用场景 |
|---|---|---|---|---|
| 原始 BERT | 399MB | 93.61% | 低 | 服务器资源充足 |
| 量化(int8) | 149MB | 93.97% | 低 | 主方案,精度优先 |
| 蒸馏(TextCNN) | 8MB | 89.04% | 低 | 资源受限场景 |
| 结构化剪枝 | ~340MB | ~92.1% | 中 | 仅作技术探索 |
最终选择量化作为生产部署方案——体积缩减 2/3,准确率基本无损,部署几乎无额外成本。
数据与工程
数据清洗流程
20 万条电商商品数据的清洗步骤:
- 去除无标题商品(约 5%)
- 去除标题过短(<5 字)和过长(>100 字)的异常商品
- 去除重复条目(同一 SKU 多次录入)
- 标准化类目标签(统一命名规范)
样本不均衡处理
样本分布:数码电子类约 30%,家居日用约 20%,其他类目 5%~10%。
| 阶段 | 处理方法 |
|---|---|
| FastText 阶段 | Focal Loss 让模型更关注少数类 |
| BERT 阶段 | 过采样少数类 + 数据增强(同义词替换/随机删除/回译) |
| 长期方案 | Badcase 分析后用爬虫/大模型生成补充少数类样本 |
部署方式
Flask 搭建服务端,POST 接口测试。当前项目是内部工具、低并发场景(运营上架时调用,不是面向用户的实时 API),Flask 足够且上手快。
(客服系统改用 FastAPI 是因为面向用户、需要高并发和异步支持。)
核心成果
| 指标 | 数值 |
|---|---|
| BERT 量化后准确率 | 93.97% |
| Precision | 0.9402 |
| 模型体积(量化后) | 399MB → 149MB |
| 模型体积(蒸馏后) | 399MB → 8MB(98% 缩减) |
| 类目选择耗时 | 从"逐层导航数分钟"→"一键确认几秒" |
| 分类系统 | 十个核心叶子类目 |
关键技术决策
为什么不直接用 BERT,要先做随机森林和 FastText
两个原因:
- 快速建立基线:随机森林+TF-IDF 一天就能出结果,80.31% 的基线让团队知道"机器学习能做到什么水平"
- 理解数据特性:基线阶段暴露数据问题——哪些类目容易混淆、哪些特征重要、样本是否均衡。这些洞察指导后续调参方向
工程实践中直接上大模型的风险:如果数据本身有问题(样本严重不均衡、类目定义模糊),BERT 也救不了,还浪费时间。基线让你快速发现数据问题,在投入重模型之前先解决数据层面的瓶颈。
为什么字符级分词比词级分词好(电商场景)
电商商品标题的特殊性决定的:
- 品牌词、型号词不在常规词典 → Jieba 切错丢失信息
- 拼写变体和简写多 → 字符级天然容错
- 标题短(10~30字)→ 字符级不会引入太多噪声
量化后准确率为什么反而提升
量化起到了隐式正则化效果:
- 20 万条数据 + 十分类任务,BERT 399M 参数有些"过配"
- float32 → int8 降低了参数精度,相当于"收窄"了参数表达空间
- 空间变小了,模型反而更"泛化"
这不是普遍规律。数据量更大的场景(百万级以上),量化通常会轻微降低准确率,因为模型需要高精度参数捕捉细微模式。但在这个特定数据量级下,正则化的收益 > 精度损失。
与类似方案的区别
vs 直接用 LLM 做分类(zero-shot/few-shot)
- LLM 分类延迟秒级,且每次 API 调用有成本
- 商品上架是高频低延迟场景——运营输入标题后需要实时返回类目预测
- BERT 量化后毫秒级响应、零 API 成本
- 通用 LLM zero-shot 在垂直电商类目上表现不稳定——边界品类容易混淆
- BERT 在 20 万条标注数据上微调过,类目边界更清晰
vs 关键词规则匹配
- 规则维护成本高——每加一个新类目就要写新规则
- 无法处理同义词和表述变体("手机壳"和"保护套"是同一类但关键词不重合)
- BERT 是语义理解,自动泛化
- 类目多了之后规则之间互相冲突,维护噩梦
vs FastText 等轻量模型
- FastText 快,但准确率有上限(91.69% vs 93.97%)
- 2% 的差距在十分类场景下意味着每 100 件多错 2~3 件
- BERT 量化版兼顾精度和部署效率——精度够、速度够、体积够小
- FastText 适合对精度要求不高的超轻量场景
核心结论:LLM 太重太慢、关键词太脆太蠢、FastText 精度有天花板。BERT 量化版是"刚好够用"的最优解。
项目价值与意义
这是入行第一个项目,从 NLP 基础开始,完整体验了从数据清洗 → 基线建立 → 模型选型 → 训练调优 → 压缩部署的全流程。
技术成长线:
- 理解了传统机器学习和深度学习在文本分类上的差异和各自适用场景
- 掌握了 BERT 微调的完整流程和调优技巧
- 学会了模型压缩的三种主流方法,理解了精度-体积-速度的 trade-off
- 体会了"数据质量比模型大小更重要"——5000 条高质量数据 + 110M BERT 优于 2000 条数据 + 340M BERT
业务价值:
- 类目自动预测让运营上架效率显著提升——从逐层导航数百个类目到一键确认
- 新人运营不再因为不熟悉类目体系而频繁选错返工
- 形成了可复用的短文本分类解决方案,后续其他分类场景可以快速套用