三、迁移策略分类体系:同构/异构、离线/在线、水平/垂直

做算法迁移,最怕什么?

不是技术难,而是你选错了策略。

我见过太多团队,一上来就闷头做异构迁移。结果搞了三个月,发现数据格式对不上,模型怎么调都跑不动。白白浪费了时间。

所以这一章,咱们先把策略分类搞清楚。说白了,就是把你要走的路先看明白。路选对了,后面的事就好办。

算法迁移策略分类体系总图 算法迁移策略 维度一:计算环境 同构迁移 (Homogeneous) 异构迁移 (Heterogeneous) 同构 → 跨平台/版本 维度二:执行时机 离线迁移 (Offline) 在线迁移 (Online) 维度三:数据维度 水平迁移 (Horizontal) 垂直迁移 (Vertical) 关键点:实际项目中往往同时涉及多个维度。比如“从PyTorch迁移到TensorFlow” 就是异构 + 离线 + 水平迁移的组合。

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% 流量),再做垂直迁移(先迁召回,再迁排序,最后迁重排)。

你想想看,这种组合是不是比单纯用一种分类要清晰得多?每个维度都有自己的选择逻辑,组合起来就是一个完整的迁移方案。

我的原则: 能同构不异构,能离线不在线,能水平不垂直。除非业务有硬性要求,否则优先选择最简单的链路。

为什么会这样?因为每叠加一种策略,复杂度就翻一倍。在线 + 异构 + 垂直,这种组合我一般不会轻易答应。除非……甲方加钱。