模型训练-分布式与GPU调度

模型训练 · 分布式与 GPU 调度

🏠 返回 README | ⬅️ 上一篇:特征平台 | ➡️ 下一篇:模型 Serving
风格说明 :本篇是 机制+操作型 ------从支付域 ML 训练(欺诈 XGBoost/深度排序/LLM 风控辅助)到分布式并行、GPU 调度、MFU 与 checkpoint。覆盖「单卡训不下 → 怎么分布式 → 怎么调度 GPU 集群」

前置阅读01-特征平台-Feature-Store设计.md(训练数据 PIT join);../ai-fundamentals/09-PyTorch与HF训练栈-架构师读码.md(训练循环 / checkpoint / DDP 读码)。

后续展开04-MLOps-CI-CD-CT流水线.md(CT 触发训练);06-Staff扩展-平台治理成本与可靠性.md(GPU FinOps)。


L1 是什么 · 支付 ML 训练平台定位

1.1 一句话定义

训练平台 = 把 Feature Store 产出的 版本化训练集可复现、可调度、可容错 的算力上跑成 Registry 中的模型 artifact ------支付域同时承载 日更 XGBoost(CPU/GPU)周更深度模型偶发 LLM 微调 三类 workload。

1.2 支付域训练 workload 矩阵

模型 频率 数据量 算力 训练时长
欺诈 XGBoost 日更/漂移触发 5e8 行 × 80 维 1× A10G 20~40min
路由 NN(MLP) 周更 2e9 行 × 120 维 4× A100 DP 2~4h
Chargeback 深度 月更 1e9 行 × 200 维 8× A100 FSDP 8~12h
LLM 风控辅助 季更 500k 对话 8× H100 TP+PP 1~3d

1.3 为什么需要分布式

复制代码
Chargeback 深度模型(Transformer encoder)估算:
  参数 BF16: 13B × 2B = 26 GB
  梯度: 26 GB
  Adam: 13B × 8B = 104 GB
  激活 (batch=32, seq=512): ~45 GB
  总计 ≈ 200 GB → 单卡 A100 80GB 不可能 → 至少 ZeRO-3 + 4 卡

#mermaid-svg-DMdGg3q3Jv1NNDp7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .error-icon{fill:#552222;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .marker.cross{stroke:#333333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 p{margin:0;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .cluster-label text{fill:#333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .cluster-label span{color:#333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .cluster-label span p{background-color:transparent;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .label text,#mermaid-svg-DMdGg3q3Jv1NNDp7 span{fill:#333;color:#333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .node rect,#mermaid-svg-DMdGg3q3Jv1NNDp7 .node circle,#mermaid-svg-DMdGg3q3Jv1NNDp7 .node ellipse,#mermaid-svg-DMdGg3q3Jv1NNDp7 .node polygon,#mermaid-svg-DMdGg3q3Jv1NNDp7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .rough-node .label text,#mermaid-svg-DMdGg3q3Jv1NNDp7 .node .label text,#mermaid-svg-DMdGg3q3Jv1NNDp7 .image-shape .label,#mermaid-svg-DMdGg3q3Jv1NNDp7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .rough-node .label,#mermaid-svg-DMdGg3q3Jv1NNDp7 .node .label,#mermaid-svg-DMdGg3q3Jv1NNDp7 .image-shape .label,#mermaid-svg-DMdGg3q3Jv1NNDp7 .icon-shape .label{text-align:center;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .node.clickable{cursor:pointer;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .arrowheadPath{fill:#333333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DMdGg3q3Jv1NNDp7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DMdGg3q3Jv1NNDp7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DMdGg3q3Jv1NNDp7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .cluster text{fill:#333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .cluster span{color:#333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DMdGg3q3Jv1NNDp7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .icon-shape,#mermaid-svg-DMdGg3q3Jv1NNDp7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .icon-shape p,#mermaid-svg-DMdGg3q3Jv1NNDp7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .icon-shape .label rect,#mermaid-svg-DMdGg3q3Jv1NNDp7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DMdGg3q3Jv1NNDp7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DMdGg3q3Jv1NNDp7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DMdGg3q3Jv1NNDp7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 分布式训练
Data Parallel

切 batch
Tensor Parallel

切矩阵 NVLink
Pipeline Parallel

切层跨节点
FSDP/ZeRO

切参数/梯度/优化器
Expert Parallel

MoE 专家


L2 原理 · 并行策略与 GPU 调度

2.1 数据并行 (DP / DDP)

复制代码
每 GPU 持有完整模型副本
  → batch 切 N 份,各 GPU 前向+反向
  → Ring AllReduce 同步梯度
  → 各 GPU 更新(参数一致)

PyTorch DDP: 一行 torchrun,多节点标准做法
限制: 模型必须放得下单卡
维度 DataParallel (DP) DDP
通信 主 GPU 收集 Ring AllReduce
多节点
支付域 不推荐 XGBoost GPU + 小 NN 默认

2.2 ZeRO / FSDP(模型放不下单卡)

阶段 切分 显存节省 通信
ZeRO-1 优化器状态
ZeRO-2 +梯度
ZeRO-3 +参数

13B 模型,8× A100,ZeRO-3

复制代码
每 GPU 参数: 13B/8 × 2B = 3.25 GB
梯度: 3.25 GB
Adam: 13B/8 × 8B = 13 GB
激活 (checkpointing): ~15 GB
总计 ~35 GB/GPU → 单卡 80GB 宽裕
python 复制代码
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP

model = FSDP(
    model,
    sharding_strategy=ShardingStrategy.FULL_SHARD,
    mixed_precision=MixedPrecision(
        param_dtype=torch.bfloat16,
        reduce_dtype=torch.bfloat16,
    ),
    auto_wrap_policy=transformer_auto_wrap_policy,
)

2.3 张量并行 (TP) 与流水线并行 (PP)

TP :单层矩阵切分,每层 AllGather/ReduceScatter ,强依赖 NVLink → 单节点 8 卡内

PP :按层切 GPU,朴素流水线 GPU 利用率 1/N;micro-batch 填气泡:

复制代码
气泡率 ≈ (N-1)/(N-1+M),M= micro-batch 数
例: PP=4, M=32 → 气泡率 8.6%

2.4 3D 并行(大模型标准)

复制代码
例: LLM 风控微调 70B,128× H100
  TP = 8(节点内 NVLink)
  PP = 4(4 节点串接层)
  DP = 128 / (8×4) = 4

DeepSpeed 启动骨架:
  deepspeed --num_gpus 128 train.py \
    --tensor_model_parallel_size 8 \
    --pipeline_model_parallel_size 4

TensorParallel组 PipelineStage2 PipelineStage1 DataParallel组 TensorParallel组 PipelineStage2 PipelineStage1 DataParallel组 #mermaid-svg-z2naaQNrtSbvWr1R{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-z2naaQNrtSbvWr1R .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-z2naaQNrtSbvWr1R .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-z2naaQNrtSbvWr1R .error-icon{fill:#552222;}#mermaid-svg-z2naaQNrtSbvWr1R .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-z2naaQNrtSbvWr1R .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-z2naaQNrtSbvWr1R .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-z2naaQNrtSbvWr1R .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-z2naaQNrtSbvWr1R .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-z2naaQNrtSbvWr1R .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-z2naaQNrtSbvWr1R .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-z2naaQNrtSbvWr1R .marker{fill:#333333;stroke:#333333;}#mermaid-svg-z2naaQNrtSbvWr1R .marker.cross{stroke:#333333;}#mermaid-svg-z2naaQNrtSbvWr1R svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-z2naaQNrtSbvWr1R p{margin:0;}#mermaid-svg-z2naaQNrtSbvWr1R .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-z2naaQNrtSbvWr1R text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-z2naaQNrtSbvWr1R .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-z2naaQNrtSbvWr1R .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-z2naaQNrtSbvWr1R .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-z2naaQNrtSbvWr1R .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-z2naaQNrtSbvWr1R #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-z2naaQNrtSbvWr1R .sequenceNumber{fill:white;}#mermaid-svg-z2naaQNrtSbvWr1R #sequencenumber{fill:#333;}#mermaid-svg-z2naaQNrtSbvWr1R #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-z2naaQNrtSbvWr1R .messageText{fill:#333;stroke:none;}#mermaid-svg-z2naaQNrtSbvWr1R .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-z2naaQNrtSbvWr1R .labelText,#mermaid-svg-z2naaQNrtSbvWr1R .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-z2naaQNrtSbvWr1R .loopText,#mermaid-svg-z2naaQNrtSbvWr1R .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-z2naaQNrtSbvWr1R .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-z2naaQNrtSbvWr1R .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-z2naaQNrtSbvWr1R .noteText,#mermaid-svg-z2naaQNrtSbvWr1R .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-z2naaQNrtSbvWr1R .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-z2naaQNrtSbvWr1R .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-z2naaQNrtSbvWr1R .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-z2naaQNrtSbvWr1R .actorPopupMenu{position:absolute;}#mermaid-svg-z2naaQNrtSbvWr1R .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-z2naaQNrtSbvWr1R .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-z2naaQNrtSbvWr1R .actor-man circle,#mermaid-svg-z2naaQNrtSbvWr1R line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-z2naaQNrtSbvWr1R :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 反向传播对称 AllReduce micro-batch 1 层0-10 AllGather 激活传递 loss

2.5 GPU 调度(K8s / Slurm / Ray)

方案 适用 支付域场景
K8s + GPU Operator 云原生弹性 日更 XGBoost Job
Volcano / Kueue gang scheduling 多卡 LLM 微调
Slurm HPC 固定集群 私有 GPU 池
Ray Train ML 弹性容错 实验性训练

gang scheduling 要点 :8 卡 job 必须 同时调度 8 卡 ,否则占 2 卡空等 → 碎片浪费 30~50%

2.6 MFU 与利用率

复制代码
MFU = 实际训练 FLOPs / (GPU 理论峰值 FLOPs × 时间)

H100 BF16 峰值 ≈ 990 TFLOPS
70B @ 300 tokens/s/GPU → MFU ≈ 12%(差)
优化后 40~60% 为「好」

监控: nvidia-smi utilization, step time 方差, wall_clock_breakdown

2.7 DeepSpeed / Megatron 配置骨架(§7.3 精华)

json 复制代码
{
  "bf16": { "enabled": true },
  "zero_optimization": {
    "stage": 3,
    "overlap_comm": true,
    "reduce_bucket_size": 500000000
  },
  "activation_checkpointing": { "partition_activations": true },
  "wall_clock_breakdown": true
}

调参顺序:burn-in 500 step → OOM 先 checkpointing → 降 micro-batch → ZeRO-3/TP → NCCL 桶/网卡。

2.8 支付域 XGBoost GPU 训练(非深度学习但高频)

复制代码
日更 fraud XGBoost:
  数据: Feature Store PIT 导出 Parquet ~200GB
  资源: 1× A10G 或 4× CPU 128核
  训练: 5e8 行, depth=8, eta=0.1 → 30min
  产出: ONNX + MLflow registry

与 LLM 训练共享: 同一 K8s GPU queue,优先级 XGBoost < LLM

L3 边界陷阱 · Staff 才知道的坑

3.1 并行选型决策树

复制代码
模型放得下单卡?
  ├─ Yes → DDP(支付小 NN / XGBoost GPU)
  └─ No → ZeRO-3/FSDP
           仍 OOM? → TP(NVLink 内,≤8)
           仍 OOM? → PP(跨节点,加 micro-batch)
           MoE? → + EP

3.2 Checkpoint 风险

风险 实例 预防
异步写损坏 GPU 故障中断写入 md5 校验 + 保留 3 版本
间隔过长 128 卡 MTBF ~8 天 30min~1h 间隔
Spot 抢占 丢 6h 进度 5min 间隔 + 多副本 S3

3.3 多租户 GPU 碎片

支付 ML 平台典型:70% 小 job(1 卡)+ 30% 大 job(8~128 卡) → 碎片率 25%。

  • 装箱策略:大 job 优先占满节点
  • 预留池:生产 CT 专用 32 卡,实验共享 Spot
  • 指标$/effective_gpu_hour = 账单 / (GPU×利用率)

3.4 训练数据与 Feature Store 版本绑定

复制代码
Lineage 最小集:
  data_snapshot_id: iceberg.payment_features@20260520
  feature_view: user_velocity_v3.2
  git_sha: abc123
  seed: 42
  image_digest: sha256:...

无 feature_view pin → 重训结果不可比 → CT Gate 失败

L4 架构师视角 · 容量规划与 FinOps

4.1 GPU 数口算(训练)

复制代码
欺诈 XGBoost 日更: 1× A10G × 0.5h = 0.5 GPU-hour/天
路由 NN 周更: 4× A100 × 3h / 7 = 1.7 GPU-hour/天
LLM 季更: 128× H100 × 48h / 90 = 68 GPU-hour/天

峰值(季更周): ~2000 GPU-hour/天
年成本 @ $3/GPU-hour: ~$2.2M(仅训练)

4.2 调度 SLO

Workload 排队 P95 运行 SLA 优先级
生产 CT XGBoost <30min 1h P0
实验训练 <4h 24h P2
LLM 微调 <24h 72h P1

#mermaid-svg-euNFcUyNnGTjefbx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-euNFcUyNnGTjefbx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-euNFcUyNnGTjefbx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-euNFcUyNnGTjefbx .error-icon{fill:#552222;}#mermaid-svg-euNFcUyNnGTjefbx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-euNFcUyNnGTjefbx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-euNFcUyNnGTjefbx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-euNFcUyNnGTjefbx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-euNFcUyNnGTjefbx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-euNFcUyNnGTjefbx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-euNFcUyNnGTjefbx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-euNFcUyNnGTjefbx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-euNFcUyNnGTjefbx .marker.cross{stroke:#333333;}#mermaid-svg-euNFcUyNnGTjefbx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-euNFcUyNnGTjefbx p{margin:0;}#mermaid-svg-euNFcUyNnGTjefbx defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-euNFcUyNnGTjefbx g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-euNFcUyNnGTjefbx g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-euNFcUyNnGTjefbx g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-euNFcUyNnGTjefbx g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-euNFcUyNnGTjefbx g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-euNFcUyNnGTjefbx .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-euNFcUyNnGTjefbx .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-euNFcUyNnGTjefbx .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-euNFcUyNnGTjefbx .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-euNFcUyNnGTjefbx .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-euNFcUyNnGTjefbx .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-euNFcUyNnGTjefbx .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-euNFcUyNnGTjefbx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-euNFcUyNnGTjefbx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-euNFcUyNnGTjefbx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-euNFcUyNnGTjefbx .edgeLabel .label text{fill:#333;}#mermaid-svg-euNFcUyNnGTjefbx .label div .edgeLabel{color:#333;}#mermaid-svg-euNFcUyNnGTjefbx .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-euNFcUyNnGTjefbx .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-euNFcUyNnGTjefbx .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-euNFcUyNnGTjefbx .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-euNFcUyNnGTjefbx .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-euNFcUyNnGTjefbx .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-euNFcUyNnGTjefbx .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-euNFcUyNnGTjefbx #statediagram-barbEnd{fill:#333333;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-euNFcUyNnGTjefbx .cluster-label,#mermaid-svg-euNFcUyNnGTjefbx .nodeLabel{color:#131300;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-euNFcUyNnGTjefbx .note-edge{stroke-dasharray:5;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-note text{fill:black;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram-note .nodeLabel{color:black;}#mermaid-svg-euNFcUyNnGTjefbx .statediagram .edgeLabel{color:red;}#mermaid-svg-euNFcUyNnGTjefbx #dependencyStart,#mermaid-svg-euNFcUyNnGTjefbx #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-euNFcUyNnGTjefbx .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-euNFcUyNnGTjefbx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 提交Job
gang调度成功
每30min
校验通过
GPU故障
从checkpoint恢复
注册Registry
3次重试失败
Queued
Running
Checkpointing
Failed
Completed

2.9 混合精度与 Loss Scaling(支付深度模型)

精度 范围 Loss Scaling 支付域选择
BF16 不需要 A100/H100 首选
FP16 需要 dynamic V100 legacy
FP32 最大 调试/小模型
INT8 推理 N/A Serving 量化,非训练
复制代码
BF16 训练 Chargeback Transformer:
  速度 +30~50% vs FP32
  KS 差异 <0.001(可接受)
  注意: 极小梯度层(如 LayerNorm)可 keep FP32 master weight

2.10 弹性训练(Spot / 抢占)

python 复制代码
# PyTorch Elastic 示意
torchrun --nnodes=4:8 --nproc_per_node=8 \
  --max_restarts=3 train.py

# Spot 被抢占 → 从 checkpoint 恢复 → world size 可缩
# 支付 CT 生产 job: 不用 Spot
# 实验/LLM 微调: Spot 省 65%,checkpoint 5min

RPO 口算checkpoint_interval × step_time = 30min × 2s = 900 steps 可丢。


5. 真实面试现场题(5 道带公司风格标记)

5.1 🟦 字节:70B 模型怎么训?

(1) 标准答案

3D 并行 + ZeRO-3 :TP=8 NVLink 域内切 attention/FFN;PP=4 跨节点均分层;剩余 DP 扩 batch。BF16 + activation checkpointing + 梯度累积。MFU 目标 40~60%,每 500~1000 step 异步 checkpoint。

(2) 原理 walk

复制代码
显存: 70B BF16 参数 140GB → 单卡不可能
8× A100 ZeRO-3: 每卡参数 17.5GB + Adam 70GB + 激活 30GB ≈ 120GB → 需 checkpointing 或 16 卡
拓扑: 128 = 8(TP) × 4(PP) × 4(DP)

(3) 权衡与量化

配置 tokens/s/GPU MFU 训练 1T tokens
仅 DP 8卡 OOM - -
ZeRO-3 32卡 280 35% 14d
3D 128卡 420 52% 4d

(4) 落地清单

  • wall_clock_breakdown=true
  • checkpoint 30min + S3 三副本
  • burn-in 1k step 再全量

(5) 追问

  • Q:通信瓶颈? A:overlap_comm + 调 bucket;机间查 IB/RoCE。
  • Q:Spot? A:可以,checkpoint 5min + 弹性 world size。

5.2 🟧 阿里:FSDP vs DDP?

(1) 标准答案

DDP 每卡完整模型,适合 <单卡显存 (13B 以下 A100、XGBoost)。FSDP=ZeRO-3 切参/梯/优化器,显存 ÷N,通信增 AllGather。支付路由 MLP 10M 参数 → DDP;Chargeback Transformer 13B → FSDP。

(2) 原理 walk

复制代码
DDP 通信: 反向 AllReduce 梯度,O(模型大小)
FSDP 通信: 每层前向 AllGather 参数 + 反向 ReduceScatter,O(模型大小 × 层数) 但内存 ÷N

(3) 权衡:13B 在 4× A100:DDP OOM;FSDP 每卡 ~35GB ✅

(4) 落地ShardingStrategy.FULL_SHARD + BF16

(5) 追问:FSDP 与 DeepSpeed ZeRO-3 等价,PyTorch 原生更易集成。

5.3 🟪 蚂蚁:分布式容错?

(1) 标准答案

三层:Checkpoint (30min 异步 + md5)、弹性训练 (PyTorch Elastic 缩 world size)、硬件冗余(128 卡 ~8 天 1 次 GPU 故障 → checkpoint 间隔 < 最大丢失容忍)。

(2) 原理 walk

复制代码
MTBF_GPU ≈ 1000 GPU-days
128 卡集群: 1000/128 ≈ 8 天一次故障
RPO = checkpoint_interval × step_time
30min × 2s/step = 900 steps 可丢

(3) 量化 :3 天训练白费事故 → 改用三副本 + 校验,RPO 30min

(4) 落地torchrun --max_restarts=3;S3 版本化 checkpoint

(5) 追问:FSDP checkpoint 与 world size 解耦需 resharding 工具。

5.4 🔵 Google:MFU 优化?

(1) 标准答案

MFU = 实际 FLOPs / 理论峰值。优化:通信-计算重叠 、增大 batch、FlashAttention、减 PP 气泡、优化 DataLoader(num_workers=8, pin_memory)。

(2) walk

复制代码
H100 990 TFLOPS BF16
70B, 300 tok/s/GPU, 6×70B FLOPs/tok → 126 TFLOPS → MFU 12.7%
FlashAttn + overlap → 420 tok/s → MFU 45%

(3) 落地:Nsight 看 comm/comp 占比;目标 comm <30%

(5) 追问:数据加载瓶颈 → 合并小 Parquet 文件,Feature Store 导出 fewer larger files。

5.5 🟢 AWS:GPU 实例选型(支付 ML)

(1) 标准答案

场景 实例 理由
欺诈 XGBoost 日更 g5.xlarge (A10G) 便宜 $1/h
路由 NN 训练 p4d (8× A100) NVLink
LLM 微调 70B p5 (8× H100) NVSwitch
实验 Spot p4d 省 60%,需 checkpoint

(2) 量化 :Spot 省 65%;生产 CT 用 On-Demand 保底

(3) 落地:Reserved 1 年 p4d 省 40%;Spot 仅非 P0 job

(5) 追问:跨 AZ 训练 → 机间 IB 带宽降 50%,避免。


6. 真实事故复盘(电商交易场景 · STAR-M-P)

6.1 「Checkpoint 损坏导致 70B 预训练丢失 3 天进度」

  • S (Situation) :跨境支付 LLM 风控辅助模型预训练,128× A100,已跑 5 天,完成 40% tokens。
  • T (Trigger) :GPU #47 硬件故障 → job 中断 → 恢复时最新 checkpoint md5 失败(异步写入中断)。
  • A (Approach)
    1. 尝试 N-1 checkpoint → 亦损坏(同一批异步写入窗口)
    2. 回退 N-2(2 天前)→ 可用
    3. 排查:异步 writer 无 fsync + 故障窗口重叠
    4. 评估:重跑 3 天 ≈ $180k 算力 + 发布延期 1 周
  • R (Resolution)
    • 止血:从 N-2 恢复,调 checkpoint 间隔 15min→30min 平衡 IO
    • 根治:写入后 md5;保留 3 版本;完成标记后才删旧;S3 跨区域复制
  • M (Metrics) :丢失 3 天 进度;修复后 6 个月零损坏;RPO 30min
  • P (Prevention):Checkpoint 纳入 CT SLO;P0 job 禁止无校验异步写

6.2 「Spot 抢占导致日更 XGBoost 未产出模型」

字段 内容
S 欺诈 XGBoost 日更 CT 跑在 Spot 池,早高峰被云厂商回收。
T 当日 无新模型 部署,仍用昨日 vN-1;午后漂移告警。
A 紧急改 On-Demand 保底 2 节点;Spot 仅作 burst;checkpoint 每 5min。
R 当日补跑完成;次日 KS 恢复。
M Spot 节省 ~60% 训练成本;日更 SLA 100% 恢复。
P 生产 CT 关键路径禁止纯 Spot;Spot 仅实验/重训。

7. 支付域 XGBoost 日更流水线 [L3]

#mermaid-svg-pMUQk2QhrPilDZga{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-pMUQk2QhrPilDZga .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pMUQk2QhrPilDZga .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pMUQk2QhrPilDZga .error-icon{fill:#552222;}#mermaid-svg-pMUQk2QhrPilDZga .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pMUQk2QhrPilDZga .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pMUQk2QhrPilDZga .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pMUQk2QhrPilDZga .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pMUQk2QhrPilDZga .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pMUQk2QhrPilDZga .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pMUQk2QhrPilDZga .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pMUQk2QhrPilDZga .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pMUQk2QhrPilDZga .marker.cross{stroke:#333333;}#mermaid-svg-pMUQk2QhrPilDZga svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pMUQk2QhrPilDZga p{margin:0;}#mermaid-svg-pMUQk2QhrPilDZga .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pMUQk2QhrPilDZga .cluster-label text{fill:#333;}#mermaid-svg-pMUQk2QhrPilDZga .cluster-label span{color:#333;}#mermaid-svg-pMUQk2QhrPilDZga .cluster-label span p{background-color:transparent;}#mermaid-svg-pMUQk2QhrPilDZga .label text,#mermaid-svg-pMUQk2QhrPilDZga span{fill:#333;color:#333;}#mermaid-svg-pMUQk2QhrPilDZga .node rect,#mermaid-svg-pMUQk2QhrPilDZga .node circle,#mermaid-svg-pMUQk2QhrPilDZga .node ellipse,#mermaid-svg-pMUQk2QhrPilDZga .node polygon,#mermaid-svg-pMUQk2QhrPilDZga .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pMUQk2QhrPilDZga .rough-node .label text,#mermaid-svg-pMUQk2QhrPilDZga .node .label text,#mermaid-svg-pMUQk2QhrPilDZga .image-shape .label,#mermaid-svg-pMUQk2QhrPilDZga .icon-shape .label{text-anchor:middle;}#mermaid-svg-pMUQk2QhrPilDZga .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-pMUQk2QhrPilDZga .rough-node .label,#mermaid-svg-pMUQk2QhrPilDZga .node .label,#mermaid-svg-pMUQk2QhrPilDZga .image-shape .label,#mermaid-svg-pMUQk2QhrPilDZga .icon-shape .label{text-align:center;}#mermaid-svg-pMUQk2QhrPilDZga .node.clickable{cursor:pointer;}#mermaid-svg-pMUQk2QhrPilDZga .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-pMUQk2QhrPilDZga .arrowheadPath{fill:#333333;}#mermaid-svg-pMUQk2QhrPilDZga .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pMUQk2QhrPilDZga .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pMUQk2QhrPilDZga .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pMUQk2QhrPilDZga .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-pMUQk2QhrPilDZga .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pMUQk2QhrPilDZga .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-pMUQk2QhrPilDZga .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pMUQk2QhrPilDZga .cluster text{fill:#333;}#mermaid-svg-pMUQk2QhrPilDZga .cluster span{color:#333;}#mermaid-svg-pMUQk2QhrPilDZga div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pMUQk2QhrPilDZga .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-pMUQk2QhrPilDZga rect.text{fill:none;stroke-width:0;}#mermaid-svg-pMUQk2QhrPilDZga .icon-shape,#mermaid-svg-pMUQk2QhrPilDZga .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pMUQk2QhrPilDZga .icon-shape p,#mermaid-svg-pMUQk2QhrPilDZga .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-pMUQk2QhrPilDZga .icon-shape .label rect,#mermaid-svg-pMUQk2QhrPilDZga .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pMUQk2QhrPilDZga .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-pMUQk2QhrPilDZga .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-pMUQk2QhrPilDZga :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Feature Store

PIT snapshot
Great Expectations
XGBoost GPU/CPU
相对 KS Gate
Model Registry
Triton deploy

环节 要点
数据 feature_view pin + as_of 时间戳防穿越
训练 5e8 行可 GPU hist分布式 Dask
验证 相对 prod KS,非绝对阈值
产物 ONNX + manifest(特征列表 hash)

与 LLM 隔离 :XGBoost job 独立队列(CPU/单卡),不与 8×H100 抢占 gang。


8. 训练排障与 MFU 提升 [L3]

8.1 MFU 低常见原因

原因 现象 手段
数据 loader 慢 GPU 等 CPU 多 worker + prefetch
通信瓶颈 多节点 DP 慢 梯度压缩 / ZeRO
小 batch util 低 累积梯度
未用 FlashAttn LLM MFU <20% FA2 + bf16

8.2 3D 并行选型口诀

  1. 单卡能放下激活 → DDP 即可。
  2. 放不下参数 → FSDP / ZeRO-3。
  3. 仍放不下 → TP(NVLink 域内)+ PP(跨节点)。
  4. 口算卡数TP × PP × DP = world_size

9. 大厂面试题 · 深度追问答 [L5]

9.1 字节:「DDP 和 FSDP 怎么选?」

结论小模型 DDP大模型 FSDP/ZeRO-3 ;再大加 TP 绑 NVLink

展开:DDP 复制全参数,通信 AllReduce;FSDP 分片参数降显存;支付欺诈 MLP 常用 DDP 4--8 卡;Chargeback Transformer 用 FSDP+TP。

9.2 阿里:「训练数据穿越怎么防?」

结论 :Feature Store PIT join + 训练 manifest 锁 as_of

展开 :标签窗口与特征时间戳分离;离线集导出走 统一 snapshot id;上线 Gate 对比 prod 特征分布 PSI。

9.3 蚂蚁:「GPU 集群多租户公平?」

结论配额 + 优先级 + gang scheduling ;生产 CT 最高优

展开 :Volcano/Kueue 队列;实验 job 限卡时限;抢占仅允许 非生产 namespace。


10. 90 秒面试口述脚本

起手 :「支付 ML 训练三类 workload:日更 XGBoost、周更 NN、季更 LLM。分布式解决 单卡放不下训太慢。」

并行 :「小模型 DDP 切 batch;大模型 FSDP/ZeRO-3 切参数;再大加 TP 绑 NVLink 8 卡内,PP 跨节点填 micro-batch。口算 128=8×4×4。」

调度:「K8s+Volcano gang 调度;生产 CT 优先;Spot 省 65% 要 5min checkpoint。」

MFU:「H100 理论 990T,实际 12% 差,FlashAttn+overlap 到 45% 好。」

收尾:「Checkpoint 是生命线------我们丢过 3 天,现在 md5+三副本,RPO 30min。」


11. 本篇知识点自检清单

  • DP/TP/PP/ZeRO-1·2·3 各解决什么、通信形态
  • 单卡放不下:先 ZeRO-3 再 TP/PP 决策树
  • 3D 并行口算 TP×PP×DP=总卡数
  • MFU 定义 + 4 条提升手段
  • Checkpoint 同步/异步、校验、Spot 关系
  • gang 调度、碎片、多租户配额
  • DeepSpeed 桶、wall_clock_breakdown
  • 支付 XGBoost 日更 vs LLM 微调资源隔离
  • Feature Store 版本与训练 Lineage 绑定

12. 关联文件 + 一句话速记

文件 速记
01-特征平台 PIT 训练集导出
04-MLOps CT 触发训练与 Gate
06-Staff扩展 GPU FinOps

一句话 :分布式 = DP+TP+PP+ZeRO;支付域 XGBoost 日更 CPU/GPU,大模型 3D 并行;Checkpoint 校验是生命线。


13. 训练产物 manifest(与 Serving 对齐)[L3]

上线 Gate 与 Triton 加载依赖 同一份 manifest,避免「训推特征不一致」。

yaml 复制代码
model_id: fraud_xgb_v20260528
artifact:
  format: onnx
  path: s3://ml-artifacts/fraud_xgb/v20260528/model.onnx
  sha256: "..."
training:
  git_sha: "a1b2c3d"
  feature_view: fraud_v12
  data_snapshot_id: "snap_20260527_0200"
  framework: xgboost-2.0.3
metrics:
  ks_val: 0.831
  ks_prod_baseline: 0.828
  gate: "relative_delta>=0.005"
字段 Serving 用途
feature_view online get 列对齐
sha256 防篡改、回滚比对
data_snapshot_id 事故追溯穿越
gate 审计「为何放行」

面试一句 :训练结束不是 save(),而是 manifest 签核 后才进 Registry。


🧭 章节导航

# 文件 风格
01 01-特征平台-Feature-Store设计.md 设计
02 本篇 · 模型训练-分布式与 GPU 调度 机制+操作
03 03-模型Serving-推理优化与缓存.md 操作
04 04-MLOps-CI-CD-CT流水线.md 设计
05 05-实验平台-AB测试与效果归因.md 设计
06 06-Staff扩展-平台治理成本与可靠性.md 横切治理
98 98-面试高频题满分答与Checklist.md 冲刺

官方文档与源码(一级依据)

See registry · 正文机制应来自下方 官方文档(L1)官方源码仓库(L2)

禁止用教程站/博客充当机制依据。本章 QPS/延迟/STAR 为面试示意。

写作规范:docs/official-sources-registry.md §0

L1 · 官方文档

相关推荐
大模型码小白20 小时前
Milvus 架构设计:从向量索引到分布式检索,AI 原生存储引擎的内部机制
java·大数据·人工智能·分布式·深度学习·milvus
不羁的木木1 天前
HarmonyOS技术精讲-Connectivity Kit:实战——多屏协同与文件快传应用
华为·wpf·harmonyos
liulilittle1 天前
论分布式系统的半开闭问题
服务器·网络·分布式·系统架构·竞态
豆瓣鸡1 天前
XXL-JOB 定时任务——从 Docker 部署到分片广播,分布式任务调度落地
spring boot·分布式·docker·定时任务
liulilittle2 天前
论双机热备:分布式
服务器·网络·分布式·通信·竞态
liulilittle2 天前
论无知:分布式
服务器·网络·分布式·并发·通信·竞态
某不知名網友2 天前
C++ 从零实现负载均衡式在线 OJ 判题系统|分布式沙箱判题实战
wpf
脱胎换骨-军哥2 天前
C++ 与 Go 生成质量比拼,谁是分布式主力语言
c++·分布式·golang
fogota2 天前
【AI】C# .NET8 WPF 第三方DLL引用配置(编译不丢失、不自动删除)
c#·.net·wpf·dll