大型模型平台系统建设

模型平台是连接数据与算法的工程基础设施。在金融风控、用户增长、推荐广告等场景下,一个完善的模型平台需要同时解决三个核心问题:如何高效地生产特征(特征平台)、如何稳定地训练模型(训练框架)、如何低延迟地提供预测服务(推理框架)。三者缺一不可,任何一环的短板都会成为整个 AI 工程链路的瓶颈。本文结合实际 JD 场景,系统梳理大型模型平台的全链路建设思路与关键技术决策。

整体架构

全链路分层视图

一个完整的模型平台可以分为五层,从底层数据到上层业务逐层递进:

  • 数据层:原始数据的接入与存储,包括用户行为日志(Kafka)、业务数据库(MySQL/HBase)、外部数据源。数据质量是整个平台的地基,脏数据会污染所有下游环节。
  • 特征层:批流一体的特征生产,将原始数据加工为模型可用的特征,并提供统一的特征存储与查询服务。特征平台是模型平台中最复杂、最容易被低估的部分。
  • 训练层:样本构建、模型训练、实验管理。支持离线批训练和在线增量训练,管理超参数调优和多版本实验对比。
  • 推理层:模型部署与在线服务,负责低延迟的特征实时查询、模型预测、结果后处理。是平台中对 SLA 要求最高的部分(P99 < 50ms)。
  • 管理层:模型仓库、A/B 测试、监控告警、数据隔离。保障平台的可观测性和多租户安全隔离。

核心数据流

一次完整的模型迭代流程如下:

  1. 业务事件(用户点击、交易、授信申请)产生原始日志,写入 Kafka
  2. Flink 实时消费 Kafka,计算实时特征(近 1 小时行为统计),写入 Redis/HBase
  3. Spark/Hive 批量计算历史特征(近 30 天统计),写入特征存储
  4. 样本构建服务从特征存储拼接样本,生成训练数据集
  5. 训练框架(PyTorch/TF)读取训练数据,完成模型训练,输出模型文件
  6. 模型推送到模型仓库,经过评估后灰度发布到推理服务
  7. 在线请求到达时,推理服务实时查询特征,调用模型,返回预测分
  8. 预测结果和真实标签回流,用于监控模型效果和触发下一轮训练

特征平台

特征平台是模型平台中投入最大、收益最持久的基础设施。它的核心价值不是计算特征,而是让特征可复用、训练与线上一致、生产过程可管理

批流一体特征生产

特征生产有两条路径,必须统一管理才能避免训练与线上特征不一致(Training-Serving Skew):

批量特征:用 Spark/Hive 计算历史窗口统计(近 7 天、近 30 天),结果写入 HBase 或 Redis。特点是数据量大、计算复杂、延迟高(T+1 或 T+几小时),适合用户长期行为特征、商品历史统计等变化缓慢的特征。

实时特征:用 Flink 消费 Kafka 事件流,计算近实时窗口统计(近 1 分钟、近 1 小时),结果写入 Redis。特点是延迟低(秒级),适合捕捉用户当前意图(刚刚浏览了什么、刚刚发生了什么交易)。

批流统一的关键是特征定义语言:用同一套 DSL 或配置描述特征的计算逻辑,由平台自动生成 Spark 批处理代码和 Flink 流处理代码,保证语义一致。

# 特征定义示例(DSL 配置)
feature:
  name: user_buy_cnt_7d
  description: 用户近7天购买次数
  entity: user_id
  source: order_events          # 事件源
  filter: event_type == 'buy'
  window: 7d
  aggregation: count
  # 平台自动生成:
  # - Spark SQL: SELECT user_id, COUNT(*) FROM orders WHERE dt >= date_sub(today,7) GROUP BY user_id
  # - Flink: keyBy(user_id).window(SlidingEventTimeWindows.of(7d,1h)).aggregate(CountAgg)

特征存储选型

不同特征有不同的读写模式,需要针对性地选择存储:

  • 实时特征(Redis):延迟要求极高(<1ms),数据量相对小(活跃用户),支持高频更新。用 Hash 结构存储用户的多个实时特征,Pipeline 批量读取减少 RTT。
  • 批量特征(HBase):数据量大(全量用户/商品),更新频率低(每天或每小时),支持按 RowKey 点查。RowKey 设计为 userIditemId,一行存储该实体的所有批量特征。
  • 离线特征(Hive/HDFS):用于训练样本拼接,不参与在线服务,追求高吞吐而非低延迟。
  • 向量特征(Faiss/Milvus):Embedding 向量的近似最近邻检索,用于召回阶段的向量相似度搜索。
# 在线特征查询示例(推理服务调用)
class FeatureStore:
    def get_features(self, user_id: str, item_id: str) -> dict:
        # 批量从多个存储并发查询,减少延迟
        with ThreadPoolExecutor() as executor:
            redis_future  = executor.submit(self._get_realtime_features, user_id)
            hbase_future  = executor.submit(self._get_batch_features, user_id, item_id)

        realtime = redis_future.result()   # 实时特征:近1小时行为
        batch    = hbase_future.result()   # 批量特征:近7天/30天统计

        return {**realtime, **batch}

    def _get_realtime_features(self, user_id: str) -> dict:
        # Redis Pipeline 批量获取,一次 RTT 取多个特征
        pipe = self.redis.pipeline()
        pipe.hgetall(f"user:realtime:{user_id}")
        results = pipe.execute()
        return results[0] or {}

特征一致性保障

Training-Serving Skew 是模型效果下降最隐蔽的原因之一。常见的不一致来源:

  • 训练时用 Hive 计算特征,线上用 Redis 查询,两者逻辑有细微差异
  • 训练数据的时间窗口定义(如"近7天"的边界)与线上不一致
  • 缺失值处理方式不同(训练填 0,线上填 -1)
  • 特征归一化参数(均值、标准差)训练时固定,线上用了不同的值

解决方案:Point-in-Time Correct 特征回填——训练样本拼接时,用事件发生时刻的特征值(而非当前特征值),重现模型在预测时刻看到的特征状态。同时,将特征计算逻辑抽象为统一的算子库,训练和推理共用同一套代码。

训练框架

样本构建

样本质量直接决定模型上限,样本构建是训练流水线中最容易出问题的环节。

正负样本构建:在金融风控场景,正样本(逾期/欺诈)通常极少(1:100 甚至 1:1000),需要负采样或过采样(SMOTE)。在增长场景(点击率预估),需要对曝光未点击样本进行随机负采样,并在模型推理时做校正(Calibration)。

样本穿越(Data Leakage)检测:训练样本中不能包含预测时刻之后才产生的特征。例如,预测用户是否会逾期,不能用逾期发生后的还款行为作为特征。平台需要自动检测特征时间戳是否晚于样本标签时间戳。

# 样本构建:Point-in-Time Correct 特征拼接
def build_sample(event_time: datetime, user_id: str, label: int) -> dict:
    # 查询事件发生时刻的特征快照(而非当前值)
    # 通过 HBase 的多版本特性,查询 timestamp <= event_time 的最新版本
    features = feature_store.get_features_at(
        user_id=user_id,
        timestamp=event_time   # Point-in-Time
    )
    return {"label": label, "event_time": event_time, **features}

训练任务管理

生产级训练平台需要管理大量并发的训练任务,核心能力包括:

资源调度:基于 Kubernetes 的 GPU 任务调度,支持 Gang Scheduling(所有 Worker 同时启动)、拓扑感知调度(同机架 GPU 优先)、抢占式调度(高优任务可抢占低优任务的资源)。

实验管理:每次训练记录超参数、数据集版本、代码版本、评估指标,支持实验对比和复现。MLflow 或 W&B 是常用选择。

自动超参调优:Optuna 或 Ray Tune 的贝叶斯优化,自动搜索学习率、网络结构、正则化系数等超参数空间,减少人工调参成本。

import optuna
import mlflow

def objective(trial):
    # 超参数搜索空间
    lr           = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
    batch_size   = trial.suggest_categorical("batch_size", [256, 512, 1024])
    hidden_units = trial.suggest_int("hidden_units", 64, 512, step=64)

    with mlflow.start_run():
        mlflow.log_params({"lr": lr, "batch_size": batch_size, "hidden_units": hidden_units})

        model = DeepFM(hidden_units=hidden_units)
        auc = train_and_evaluate(model, lr=lr, batch_size=batch_size)

        mlflow.log_metric("auc", auc)

    return auc

study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=50, n_jobs=4)  # 并行搜索

在线学习与增量训练

在增长场景(广告点击率、推荐)中,用户兴趣变化快,T+1 的离线训练无法及时捕捉最新趋势。在线学习(Online Learning)或增量训练(Incremental Training)是解决方案:

  • 增量训练:每隔 1-6 小时,用最新数据在现有模型基础上继续训练若干步,更新模型参数。成本低,但存在灾难性遗忘(Catastrophic Forgetting)风险,需要控制学习率和训练步数。
  • 流式训练(FTRL):用 Follow-The-Regularized-Leader 算法对每条样本实时更新模型,适合稀疏线性模型(LR + 特征交叉)。延迟可以降到分钟级,但模型复杂度受限。
  • 双塔模型分离更新:推荐系统中,用户塔每天全量更新,物品塔每小时增量更新,在效果和成本之间取得平衡。

在线推理框架

推理服务架构

在线推理是模型平台中延迟最敏感的环节,金融风控场景通常要求 P99 < 100ms,推荐广告场景要求 P99 < 50ms。推理服务的关键路径:

  1. 接收请求(用户 ID、物品 ID、上下文信息)
  2. 并发查询特征存储(Redis + HBase),合并特征向量
  3. 特征预处理(归一化、离散化、Embedding Lookup)
  4. 模型前向推理(TensorFlow Serving / TorchServe / Triton)
  5. 结果后处理(校正、阈值判断、业务规则过滤)
  6. 返回预测分,记录请求日志(用于后续样本回流)

推理性能优化

模型量化(Quantization):将模型参数从 FP32 转为 INT8 或 FP16,减少显存占用和推理计算量。INT8 量化通常能将推理速度提升 2-4x,精度损失 <0.5% AUC。

# PyTorch 动态量化(适合 Embedding 密集的推荐模型)
import torch.quantization

model = DeepFM.load("model.pt")
quantized_model = torch.quantization.quantize_dynamic(
    model,
    {torch.nn.Linear, torch.nn.Embedding},
    dtype=torch.qint8
)
# 推理速度提升约 2x,模型体积减小约 75%

模型蒸馏(Knowledge Distillation):用大模型(Teacher)的软标签训练小模型(Student),在保持大部分效果的同时大幅降低推理延迟。适合将复杂的 Transformer 模型蒸馏为轻量 MLP 用于在线服务。

特征缓存:对变化缓慢的特征(用户长期画像、商品属性)在推理服务内缓存,避免每次请求都查 HBase/Redis。本地缓存(Caffeine)+ 异步刷新,命中率可达 80-90%,将特征查询延迟从 5ms 降到 0.1ms。

批量推理(Batching):将多个请求合并为一个 Batch 送入 GPU,提升 GPU 利用率。Triton Inference Server 支持动态 Batching,自动在延迟和吞吐之间取得平衡。

模型版本管理与灰度发布

生产环境不能直接全量切换新模型,需要灰度验证:

# 推理服务路由配置(金丝雀发布)
model_routing:
  - model: deepfm_v3
    weight: 90    # 90% 流量走旧模型
    version: "2026-04-20"
  - model: deepfm_v4
    weight: 10    # 10% 流量走新模型(灰度)
    version: "2026-04-25"

# 灰度期间对比两个模型的:
# - 业务指标(点击率、转化率、逾期率)
# - 技术指标(P99延迟、QPS、错误率)
# 确认新模型稳定后,逐步调整 weight 到 100%

数据隔离与多租户

在金融场景中,不同业务线(消费金融、财富管理、保险)的数据有严格的隔离要求,模型平台必须支持多租户隔离:

数据隔离层次

  • 存储隔离:不同业务线的特征存储在独立的 HBase 表或 Redis Cluster,避免数据混用。Hive 用库级别隔离,每个业务线有独立的数据库和权限控制。
  • 计算隔离:Kubernetes Namespace + ResourceQuota 限制每个业务线的 CPU/GPU/内存配额,防止一个业务线的训练任务影响其他业务线的在线推理。
  • 模型隔离:模型仓库按业务线分区,不同业务线的模型互不可见。推理服务按业务线部署独立实例,避免共享推理服务的故障级联。
  • 访问控制:基于 RBAC 的权限管理,数据科学家只能访问自己业务线的数据和模型,平台管理员有全局视图。

数据血缘与审计

金融场景有强监管要求,需要完整的数据血缘追踪:每个特征的来源(哪张原始表、哪个字段)、每个模型的训练数据(哪个时间段、哪个版本的特征)、每次预测的输入特征值(用于事后审计和解释)。Apache Atlas 或自建血缘系统可以满足这一需求。

监控与告警

三层监控体系

模型平台的监控分为三个层次,每层关注不同的问题:

系统监控(基础设施层):

  • 推理服务:QPS、P50/P99 延迟、错误率、GPU 利用率
  • 特征存储:Redis 命中率、HBase 读延迟、Kafka 消费延迟
  • 训练任务:GPU 利用率(MFU)、训练速度(samples/sec)、显存使用率

数据监控(特征层):

  • 特征缺失率:某个特征的缺失比例突然升高,通常意味着上游数据管道故障
  • 特征分布漂移:特征的均值、方差、分位数与历史基线偏差过大(PSI 检验)
  • 特征时效性:实时特征的更新延迟,超过阈值触发告警

模型监控(效果层):

  • 预测分分布:模型输出的分数分布发生偏移(Score Distribution Shift),通常是特征分布漂移的信号
  • 业务指标:点击率、转化率、逾期率等业务 KPI 的实时监控
  • 模型性能指标:AUC、KS、Gini 系数的定期评估(需要等待标签回流,有延迟)
# 特征分布漂移检测(PSI - Population Stability Index)
def calculate_psi(baseline: np.ndarray, current: np.ndarray, bins: int = 10) -> float:
    """
    PSI < 0.1:分布稳定,无需关注
    0.1 <= PSI < 0.2:轻微漂移,需要关注
    PSI >= 0.2:显著漂移,需要重新训练模型
    """
    baseline_pct, _ = np.histogram(baseline, bins=bins, density=True)
    current_pct, _  = np.histogram(current,  bins=bins, density=True)

    # 避免除零
    baseline_pct = np.where(baseline_pct == 0, 1e-6, baseline_pct)
    current_pct  = np.where(current_pct  == 0, 1e-6, current_pct)

    psi = np.sum((current_pct - baseline_pct) * np.log(current_pct / baseline_pct))
    return psi

自动化再训练触发

模型不是训练一次就永久有效的,需要根据监控信号自动触发再训练:

  • 定时触发:每天/每周定时重新训练,适合变化较慢的场景(金融风控)
  • 漂移触发:当特征 PSI 超过阈值或预测分分布偏移超过阈值时自动触发
  • 效果触发:当线上 AUC 下降超过 N% 时触发(需要标签回流,有延迟)
  • 数据量触发:当新增训练样本超过一定数量时触发增量训练

技术选型总结

基于上述 JD 场景(金融 + 增长,Java/Scala/Go/Python 技术栈),推荐以下技术选型:

  • 实时特征计算:Flink(Java/Scala),状态管理成熟,与 Kafka 集成完善,适合金融场景的精确一次语义
  • 批量特征计算:Spark(Scala/Python),生态丰富,与 Hive/HDFS 集成好,支持大规模数据处理
  • 实时特征存储:Redis Cluster,低延迟,支持 Hash 结构批量读取
  • 批量特征存储:HBase,海量数据随机读写,与 Hadoop 生态集成
  • 离线数据仓库:Hive + HDFS,成熟稳定,适合 T+1 的批量计算
  • 流批一体数据湖:Hudi(支持 Upsert 和增量查询,解决流批数据统一问题)
  • OLAP 分析:ClickHouse,亿级数据的秒级聚合查询,适合特征统计分析
  • 训练框架:PyTorch(研究灵活性)+ DeepSpeed/FSDP(大模型分布式训练)
  • 推理框架:Triton Inference Server(GPU 推理)+ TorchServe(CPU 推理),Go 实现的推理网关负责特征查询和路由
  • 实验管理:MLflow(开源,自托管,与 Python 生态集成好)
  • 任务调度:Kubernetes + Argo Workflow,支持 DAG 任务依赖和重试
  • 消息队列:Kafka,高吞吐,与 Flink 深度集成

总结

大型模型平台的建设是一个长期工程,没有一步到位的方案。从工程实践角度,建议按以下优先级推进:

  1. 先打通链路,再优化性能:优先建立从数据到预测的完整闭环,哪怕初期用简单的方案(单机 Spark、Redis 直连),再逐步替换为高性能组件
  2. 特征平台优先于模型优化:特征质量和一致性比模型架构更重要,80% 的模型效果来自于特征工程
  3. 可观测性与数据质量是地基:没有监控的平台是黑盒,特征漂移和样本穿越问题会悄无声息地侵蚀模型效果
  4. 标准化降低协作成本:统一的特征定义 DSL、统一的模型接口规范、统一的实验管理,让算法工程师和平台工程师能高效协作

在金融场景中,稳定性和可解释性的优先级高于模型性能——一个稳定运行的简单模型,远比一个偶尔出问题的复杂模型更有价值。在增长场景中,迭代速度是核心竞争力,平台的价值在于让算法工程师能以最低的工程成本快速验证新想法。两种场景对平台的要求不同,但底层基础设施(特征平台、数据管道、监控体系)是共通的。