三、迁移策略分类体系:同构/异构、离线/在线、水平/垂直
做算法迁移,最怕什么?
不是技术难,而是你选错了策略。
我见过太多团队,一上来就闷头做异构迁移。结果搞了三个月,发现数据格式对不上,模型怎么调都跑不动。白白浪费了时间。
所以这一章,咱们先把策略分类搞清楚。说白了,就是把你要走的路先看明白。路选对了,后面的事就好办。
3.1 同构迁移 vs 异构迁移
这是最基础的一对分类。看名字就知道,关键在于“构”字——也就是计算平台的架构。
同构迁移
什么是同构?说白了,源平台和目标平台用的是同一套指令集,或者说是同一个生态体系。比如从 x86 的服务器 A 迁到 x86 的服务器 B,或者从 NVIDIA 的 GPU 卡升级到新一代 NVIDIA 卡。
这类迁移,我个人的经验是:最简单的部分通常是代码改动小,最难的部分反而是性能调优。因为底层架构没变,算法逻辑基本不用改,但新硬件的特性可能完全不一样。
我的一个教训:曾经在迁移一个 CV 模型时,从 V100 迁移到 A100。本以为直接跑就行,结果发现 A100 的 Tensor Core 版本不同,矩阵乘法的精度设置需要手动调整。嗯,所以说同构不等于无脑迁移。
异构迁移
这个就复杂多了。异构意味着从一套体系换到另一套体系。比如从 CPU 迁到 GPU,或者从 PyTorch 迁到 TensorFlow,再比如从 x86 迁到 ARM。
你想想看,指令集不同、内存模型不同、甚至数据类型都可能不同。这种迁移,说白了就是“重写”代码。我建议至少留出 50% 以上的研发时间给测试验证,千万别抱有“能直接跑”的幻想。
| 对比维度 | 同构迁移 | 异构迁移 |
|---|---|---|
| 代码改动量 | 通常 < 10% | 通常 > 50% |
| 核心风险 | 精度漂移、性能退化 | 数据不兼容、算子缺失 |
| 调试难度 | 中等 | 高 |
| 典型场景 | GPU 升级、库版本升级 | CPU→GPU、云→边缘 |
我曾经踩过的坑:有一次做异构迁移,从 OpenCV 的 DNN 模块迁到 TensorRT。模型的算子没有任何问题,结果在推理时发现图像预处理(归一化、通道顺序)的写法不一样。一个 BGR 一个 RGB,调了我一整天。
3.2 离线迁移 vs 在线迁移
这对分类按的是执行时机——算法是在不停服务的情况下迁,还是先停掉再迁。
离线迁移
这个好理解。先停服务,做迁移,测试通过,再上线。流程简单,风险可控。
但问题是,为啥不能一直用离线?因为有些场景不允许停服务。比如推荐系统、风控系统,停了就是钱。
在线迁移
在线迁移才真正考验功力。你得让新旧系统同时运行,逐步把流量切过去。常用的有几种模式:
- 影子测试: 新系统跑一遍,但不影响线上结果,只做对比。
- 流量灰度: 先切 1% 的流量到新系统,没问题再逐步加。
- 回滚预案: 在线迁移必须准备好一键回滚。我习惯在每个迁移步骤后,保留 24 小时的观察窗口。
选型建议: 如果你的业务允许 30 分钟以内的停服,我强烈建议选离线迁移。在线迁移的复杂度,不是多花几天就能解决的。说白了,能用离线解决的问题,别上线折腾。
3.3 水平迁移 vs 垂直迁移
水平还是垂直?这个分类看的是数据范围。
水平迁移
水平迁移,指的是数据分片式的迁移。比如你有 100 个用户的模型,先迁 50 个用户,再迁剩下 50 个。或者按时间段来,先迁 1 月份的数据,再迁 2 月份的。
我遇到过的一个实际案例:一个时序预测模型,需要从旧平台迁出。我们按“城市”维度做水平切分,先迁移北京、上海两个节点的数据做验证,确认无误后再迁移全国其他城市。这样可以随时回退,不影响整体业务。
垂直迁移
垂直迁移则是对功能模块的拆分。比如你的推荐系统有三个模块:召回、排序、重排。你先单独迁移召回模块,测试没问题再迁排序模块。
这里有个潜在问题:模块之间可能有强依赖。如果你只迁了召回模块,但排序和重排还在旧系统,接口协议必须做好兼容。我建议在迁移前,先画一张完整的依赖图,不然很容易出现“牵一发而动全身”的尴尬局面。
| 维度 | 水平迁移 | 垂直迁移 |
|---|---|---|
| 切分方式 | 按数据/用户/时间 | 按功能/模块/层 |
| 优势 | 回退粒度细,风险可控 | 每个模块独立验证 |
| 劣势 | 数据一致性难保证 | 模块接口需额外兼容 |
| 典型的组合 | 服务升级、数据迁移 | 模型重构、算法替换 |
避坑指南: 垂直迁移时,我曾经把一个“特征工程”模块先迁出去了,结果发现排序模型的输入特征名变了。旧系统用的特征名是 user_age,新系统改成了 age。两边数据源不匹配,查了一整天才找到原因。所以,垂直迁移一定要先对齐接口契约。
3.4 三种分类怎么组合使用?
在实际项目中,很少只用到一种分类。往往是组合拳。
我举个例子你就明白了:
- 场景: 公司要把推荐算法从 CPU 集群迁到 GPU 集群。
- 环境: 异构迁移(x86 CPU → NVIDIA GPU)。
- 时机: 在线迁移(业务 7x24,不能停)。
- 数据: 先做水平迁移(按用户灰度 1% 流量),再做垂直迁移(先迁召回,再迁排序,最后迁重排)。
你想想看,这种组合是不是比单纯用一种分类要清晰得多?每个维度都有自己的选择逻辑,组合起来就是一个完整的迁移方案。
我的原则: 能同构不异构,能离线不在线,能水平不垂直。除非业务有硬性要求,否则优先选择最简单的链路。
为什么会这样?因为每叠加一种策略,复杂度就翻一倍。在线 + 异构 + 垂直,这种组合我一般不会轻易答应。除非……甲方加钱。