Series · Transfer Learning · Chapter 12

迁移学习(十二):工业应用与最佳实践

系列收官。把迁移学习推上生产线的实战指南:何时用、如何串成端到端管线、算力与美元的真实账单、四个标杆案例、A/B 测试、生产环境的分布漂移监控,以及 12 个月的 ROI 模型。

这是整个系列的最后一篇。前面十一篇讲的是机制——预训练、微调、域适应、小样本与零样本、蒸馏、多任务、多模态、参数高效方法、持续学习、跨语言迁移。这一篇要谈的,是 notebook 关掉之后才开始的那部分工作:判断该不该用迁移学习,怎么把它嵌进一条真实的生产管线,以及怎么在六个月之后还能确认它仍然在正常工作。

下面所有内容都是从一个要长期维护模型的团队的视角出发写的,不是从一个要发论文的团队的视角。两者的取舍方式很不一样。

你将学到

  • 一棵决定该不该用迁移学习的判断树
  • 端到端生产管线的六个阶段,每段属于谁、产出什么
  • 迁移学习在算力和美元上能省下的三到五个数量级
  • 四个标杆部署(Google Translate、ChatGPT、Tesla Autopilot、Copilot)背后的迁移谱系
  • 怎样以统计上严谨的方式 A/B 测试两个迁移学习候选模型
  • 怎样在生产环境监控分布漂移,并据此触发再训练
  • 一份可以套进自己提案的 12 个月 ROI 模型

前置知识

  • 本系列前面所有章节,特别是第 9 章(PEFT)、第 10 章(持续学习)、第 11 章(跨语言)
  • 基本的软件工程能力:API、可观测性、部署
  • 熟悉 PyTorch 训练循环

1. 到底什么时候才该用迁移学习

迁移学习并不是免费的。你要为一个比实际需要更大的骨干网络付出推理成本,要继承预训练语料里的偏见,还要把团队的命运绑在一个上游模型上——它的许可证和生命周期都不在你手里。在伸手去用之前,先把这棵树走一遍。

判断该不该用迁移学习的决策树

真正决定结果的四个问题:

  1. 这个模态有没有现成的预训练模型? 如果没有——一个小众传感器、一份专有的仪器日志——你就只能从零训,并且需要至少十万级的标注,或者一个像样的自监督任务。
  2. 手上至少有 100 个左右的标注样本吗? 低于这个量级,用一个前沿模型做提示工程通常打不过任何微调。任务越难,这个临界点越高。
  3. 业务领域和预训练语料贴近吗? 通用网文和放射科报告、法律合同、工业日志的重合度都很差。先做一轮领域自适应预训练(第 3 章),往往能把后面的微调成本一并赚回来。
  4. 是只服务一个任务,还是同时面向很多租户/任务? 如果许多租户共享一个骨干,LoRA / Adapter(第 9 章)让你为每个租户存几 KB 而不是几 GB。

绝大多数情况下,问题不是"用不用迁移",而是"用哪种迁移配方"。把图里底部那行启发式当起点,然后在两个候选方案之间做对照实验,比在纸上反复斟酌靠谱得多。


2. 端到端的生产管线

研究的 notebook 在 model.eval() 那一行就结束了。生产从那里才开始。下面这条管线是大多数团队踩过几次坑之后会收敛到的形态。

从基础模型到被监控的服务的生产管线

六个阶段,每个阶段都有明确的负责人和检查点产物:

阶段负责人产物常见坑
基础模型ML 平台冻结权重、tokenizer、评测套件静默地换了许可证
领域预训练研究组领域适配后的权重灾难性遗忘
任务微调业务团队Adapter 或全量权重、标签体系训推 tokenization 不一致
压缩与导出MLOpsINT8 / 4-bit 权重、ONNX / TensorRT 图算子覆盖不全
服务化平台 SRE容器、扩缩容配置、批处理策略冷启动导致的 P99 抬升
监控On-call漂移看板、评测金丝雀、告警路由在罕见切片上的静默失败

图里那条琥珀色的反馈箭头,是大多数团队最容易做得不到位的地方。**漂移检测如果不能自动开一个再训练工单,那就只是一张装饰用的看板。**正确的做法是把监控告警直接接进一条再训练管线,自动拉新数据加缓存数据,产出一个候选模型送进 A/B,而不是变成"下个 sprint 看一眼"。

每个阶段都要打可复现性快照——模型权重、tokenizer、评测集、数据哈希、git SHA。这是 MLOps 里收益最高的一条纪律。没有它,“3 月 14 号在跑的那个模型"就会沦为团队里没人能复原的传说。


3. 经济账:三到五个数量级的差距

迁移学习能吃下整个领域,原因不只是准确率,更是成本。

从零训、继续预训练、LoRA、提示工程的算力与美元账单

以一个 7B 参数量级的语言模型为例:

  • 从零训: 约 18 万 A100·小时,光算力就是 45 万美元量级。
  • 继续预训练到一个领域语料:约 1.2 万小时,约 3 万美元。
  • 下游全量微调: 约 800 小时,约 2,000 美元。
  • rank=16 的 LoRA: 约 40 小时,约 100 美元。
  • 提示工程调 API:每次实验只要几美分。

具体数字会随硬件和软件浮动,但这种结构——从"建地基"到"贴任务"的五个数量级落差——在所有模态下都是稳的。对项目排期的含义很尖锐:**预算应该花在数据、评测和服务上,而不是训练算力上。**那些把 80% 的钱砸在微调一个还没有人验证过是否适合自己场景的模型上的团队,钱花错了地方。

还有一个微妙的点:提示工程单次实验便宜,但单次请求贵。临界点通常落在每天 10 到 1,000 次请求之间,过了这个点,一个微调过的小模型在摊销成本上就赢了。这件事一定要算明白——一张服务成本电子表格,胜过任何感觉。


4. 四个标杆部署

具体案例比任何分类法都更能磨砺直觉。下面四个例子,每一个都展示了一种不同形状的迁移。

标杆性的迁移学习部署

Google Translate(GNMT,2016 起)。 从"每个语言对一个 LSTM seq2seq"切换到"一个多语种 Transformer 编码器”,是多任务迁移最干净的一次工业级胜利:一个模型,覆盖 100 多个语言对,在训练时从未配对过的语言对之间也能做零样本翻译。教训:当任务之间共享结构时,共享表示几乎一定会赢过逐任务模型。

OpenAI ChatGPT(2022 起)。 GPT-3.5 和 GPT-4 本质上是 GPT-3 上面贴了两层适配——有监督的指令微调,再叠加 RLHF。基础模型完成了大部分重活,适配层把它变成可用的产品。这是现代的标准打法:一个小团队拿一个别人付钱训出来的大模型,用对的偏好数据微调,就能做出一个定义品类的体验。

Tesla Autopilot 的 HydraNet。 一个 ResNet 风格的骨干网络,喂给 48 个任务专用头——车道、信号灯状态、深度、占据格、交通标志识别等等。这是第 6 章的多任务学习放大到生产规模:新增一个头几乎零成本,共享特征意味着修一个任务的数据常常能顺带改善其他任务,推理成本被 48 个输出一次性摊薄。

GitHub Copilot(Codex)。 把预训练好的 GPT 在公开代码库上继续预训练,再为代码补全做微调。这就是第 3 章讲的领域自适应预训练,放到了星球级的尺度上。从通用 GPT 到代码特化的 Codex 之间的提升,足够大到定义了一个新品类。

四个案例的共同点不在于用了哪个模型,而在于:做产品的团队都没有自己去训那个基础模型。生产���境里的迁移学习,就是把别人的算力当杠杆来撬动。


5. 怎样 A/B 测试两个迁移学习候选

一个在离线评测上赢了的新模型,是一个假设,而不是一个上线决策。唯一诚实的答案来自生产环境里的随机对照。

两个迁移学习候选模型的 A/B 测试

图里的实验是一个典型设置。BERT-base 全量微调(对照)与 RoBERTa-large + LoRA(实验)按 50/50 分流,跑 14 天。每日转化率带 95% 置信带。第 9 天达到最小样本量,第 14 天的 Welch t 检验给出 $t = 3.42$、$p = 0.002$、转化率提升 $+6.5\%$,p99 延迟护栏不破,基础设施成本下降 18%。结论:全量上线。

经验里几条不会错的规矩:

  • 预先登记成功指标和护栏指标。 跑完之后再决定"哪个指标其实更重要",那是 p-hacking。
  • 用 Welch t 检验,不要用 Student t 检验。 两组的方差几乎从来都不相等。
  • 盯着异质性处理效应。 一个模型可能在总体上赢,却在某个关键用户切片上输。在批准全量之前,按语言、设备、租户切一下结果。
  • 至少跑满一个完整的业务周期。 工作日和周末的动力学差异足以翻转结论。
  • 就算上线之后也保留一个小流量对照组,这样在外界条件变化时还能发现回退。

低流量服务可以用序贯检验(比如 mSPRT)提前停止而不抬高假阳性率。高风险变更则应当先跑一段影子模式,让新模型只静默打分、只记录日志。


6. 监控分布漂移

模型不会高声地坏掉。它们会漂移——训练时假设的世界悄悄移动,准确率每天掉一点点,等到某次季度复盘里有人察觉,你已经默默地少了三个月的业绩。

分布漂移监控:KL 散度与准确率联动

标准做法是把一个无监督的分布指标和一个有监督的准确率金丝雀配对使用:

  • 分布指标。 在滚动窗口上每天计算生产端特征分布与训练端分布的 KL 散度(或 PSI、KS 统计量)。KL 用起来方便,因为解读上比较直观——在归一化特征上读数高于约 $0.15$ 就值得关注。具体阈值要按服务调。
  • 有监督金丝雀。 一个小的 holdout 集,最好每周补充一批新鲜的人工标注,对线上模型打分。这能抓到那种"输入分布看起来没变、但标签分布变了"的情况。

图里两个信号在第 24 天前后一起越线——KL 翻过 0.15、准确率掉破 85% 的 SLO。再训练管线被自动触发。这就是一个能让系统在野外存活下来的闭环。

一个常见陷阱:只盯分布指标、不配标注金丝雀。KL 完全可能因为某种良性的变化(一个新产品上线、流量构成变了)而上升,而准确率毫发无损。每次 KL 抖动就告警,会训练团队对告警麻木。分布漂移与准确率下降同时发生,才是高精度的触发器。


7. ROI:把商业账算明白

工程师之所以总是低估迁移学习项目的价值,是因为只把 GPU 账单计入了成本。如果把价值放在同一张坐标轴上,画面立刻清晰得多。

一个迁移学习项目 12 个月的 ROI 曲线

一个有代表性的单模型项目:

  • 建设成本(工程、初始领域预训练、数据标注):约 8 万美元。
  • 持续成本(服务、监控、On-call):约每月 6,000 美元。
  • 价值(替换规则引擎、节省外采、追回转化):从第 1 个月的 5,000 美元爬升,第 6 个月稳定在每月 50,000 美元左右。
  • 盈亏平衡点落在第 5 个月;第一年的 ROI 大致在 $+150\%$ 量级。

即使把价值预估打个对折,曲线的形状也不会变。真正杀死这类项目的不是曲线太平,而是团队上线之后就放着不管,价值平台期被漂移侵蚀,根本撑不到盈亏平衡点。ROI 的论证和监控的论证,本质上是同一个论证。

提一个新的迁移学习项目时,递三份材料过去:

  1. 第 1 节那棵决策树的判断结论。
  2. 第 3 节针对显而易见的替代方案的成本对比。
  3. 这条 12 个月曲线,假设要保守,并写明监控闭环的负责人是谁。

这套材料能直接答完一个有思考的赞助人会提的所有问题。


8. 最小可用的生产配方

把一切剥到一屏代码以内,一个生产级迁移学习服务的第一版长这样。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
"""最小可用的生产迁移学习配方。"""
import torch
from transformers import (AutoModelForSequenceClassification,
                          AutoTokenizer, get_linear_schedule_with_warmup)

# 1. 按"数据量 + 延迟预算"挑骨干(参见第 1 节的决策树)
model_name = "roberta-base"
model = AutoModelForSequenceClassification.from_pretrained(
    model_name, num_labels=NUM_CLASSES)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 2. 逐层学习率:浅层比顶层动得慢
def layerwise_params(model, base_lr=2e-5, decay=0.95):
    named = list(model.named_parameters())
    L = len(named)
    return [{"params": p, "lr": base_lr * decay ** (L - i)}
            for i, (_, p) in enumerate(named)]

optimizer = torch.optim.AdamW(layerwise_params(model), weight_decay=0.01)
scheduler = get_linear_schedule_with_warmup(
    optimizer, num_warmup_steps=int(0.1 * total_steps),
    num_training_steps=total_steps)

# 3. 早停 + 完整快照:模型、tokenizer、评测集、git SHA 一起持久化
#    可复现性是非可选项
best_val = float("inf"); patience = 3; bad = 0
for epoch in range(MAX_EPOCHS):
    train_one_epoch(model, train_loader, optimizer, scheduler)
    val_loss = evaluate(model, val_loader)
    if val_loss < best_val:
        best_val, bad = val_loss, 0
        save_checkpoint(model, tokenizer, EVAL_SET, GIT_SHA)
    else:
        bad += 1
        if bad >= patience:
            break

# 4. 服务化前的压缩。INT8 动态量化是最便宜的胜利;
#    剪枝和蒸馏可以稍后再说
model_int8 = torch.quantization.quantize_dynamic(
    model, {torch.nn.Linear}, dtype=torch.qint8)
torch.onnx.export(model_int8, dummy_input, "model.onnx",
                  dynamic_axes={"input_ids": {0: "batch", 1: "seq"}})

# 5. 用一个薄 API 包起来,并从第一天就埋好延迟、漂移、准确率的指标
#    监控代码是部署的一部分,不是后续工单

让这段脚本变成一个系统,需要再补四块东西:每周刷新一次的标注 holdout、带 On-call 路由的漂移看板、A/B 测试框架、看板能直接触发的再训练管线。按这个顺序去搭。


9. 实操问答

Q1:用闭源 API 还是自托管开源模型? 原型期、低流量、或者前沿模型在指标上确实大幅领先的任务,用 API。日活流量越过成本临界点、有数据驻留要求、或者延迟 SLA 在 200 毫秒以下时,自托管。很多团队最后两边都做。

Q2:微调到底要多少数据? 有一个像样的预训练骨干在手,每类 100 到 1,000 个标注样本通常已经能打过任何精心调过的提示。低于这个量级,用前沿模型做提示工程一般都更划算。

Q3:生产环境里全量微调还是 LoRA? 多租户或者多任务共享一个底座,用 LoRA——每个租户只多几 KB 适配权重。单一高风险任务、又承担得起完整模型,全量微调。只有当部署目标连 LoRA 方案都装不下时,才考虑蒸馏。

Q4:什么时候该再训练? “分布漂移 AND 标注金丝雀准确率下降"同时触发的时候。不要按日历表再训,世界不按 cron 走。

Q5:再训练时怎么避免灾难性遗忘? 把一部分老分布数据混进新训练集;或者用 EWC、LoRA + replay(第 10 章)。务必把上一版测试集作为护栏一起评——一个在新数据上涨了 3 分、却在老数据上掉了 5 分的模型,是一次回退,不是升级。

Q6:离线评测的提升上线没复现,为什么? 几乎一定是训推不一致、标签泄露,或者评测集和真实流量之间的人群分布差异。这是一个运维问题,不是算法问题:把预处理对齐到完全一致,审一遍评测集的构成,再重跑 A/B。


10. 整个系列,用一段话回顾

我们从迁移学习的"为什么"和形式化定义起步(第 1 章),走过经典的"先预训练再微调"配方(第 2 章);第 3 章和第 11 章处理域漂移和语言漂移;第 4 章和第 7 章覆盖小样本与零数据的极端情形;第 5 章讲怎么把已有的收益压缩进小模型;第 6 章把范式推广到多任务;第 8 章推到多模态;第 9 章给出今天驱动绝大多数生产微调的参数高效方法;第 10 章解决"持续更新模型而不忘记过去"的问题。这最后一章想说的是:上面所有这些都是必要条件,但不是充分条件——把迁移学习真正推上线,意味着你要同时拥有判断、管线、经济账、实验、监控、ROI 这六样东西的所有权。把这六块都搭起来,剩下的就是工程问题。


参考文献

  • Howard, J., & Ruder, S. (2018). Universal language model fine-tuning for text classification. ACL.
  • Wei, J., & Zou, K. (2019). EDA: Easy data augmentation. EMNLP.
  • Yun, S., et al. (2019). CutMix: Regularization strategy. ICCV.
  • Wu, Y., et al. (2016). Google’s neural machine translation system. arXiv:1609.08144.
  • Ouyang, L., et al. (2022). Training language models to follow instructions with human feedback. NeurIPS.
  • Chen, M., et al. (2021). Evaluating large language models trained on code. arXiv:2107.03374.
  • Sculley, D., et al. (2015). Hidden technical debt in machine learning systems. NeurIPS.

系列导航

部分主题
1基础与核心概念
2预训练与微调
3域适应
4小样本学习
5知识蒸馏
6多任务学习
7零样本学习
8多模态迁移
9参数高效微调
10持续学习
11跨语言迁移
12工业应用与最佳实践(本文)

Liked this piece?

Follow on GitHub for the next one — usually one a week.

GitHub