当前位置: 首页 > news >正文

纯CPU场景下C++的分布式模型训练框架设计思路

0. 参数分配

  • 稠密参数MPI 集合通信(All-Reduce / Broadcast / Reduce-Scatter)。
  • 稀疏参数brpc Parameter Server 异步推拉。
    完全去掉 NCCL/GPU 相关部分。

1. 整体拓扑

┌----------------┐         ┌----------------┐
│ Worker-0       │         │ PS-0           │
│ Worker-1       │◄------► │ PS-1           │
│ ...            │  brpc   │ ...            │
│ Worker-N       │         │ PS-M           │
└----------------┘         └----------------┘▲│MPI(TCP/InfiniBand)▼
MPI_COMM_WORLD(稠密参数)
  • 稠密梯度:通过 MPI 标准集合操作(MPI_AllreduceMPI_Bcast 等)实现同步。
  • 稀疏参数:Worker 与 PS 之间用 brpc + protobuf 通信,异步推拉。

2. 关键模块(C++)

cpu_dist/
├── common/
│   ├── tensor.h            // 纯 CPU 张量(FP32/FP64)
│   └── mpi_context.h       // MPI_Init / Finalize 封装
├── dense/
│   ├── mpi_allreduce.h     // MPI All-Reduce 封装
│   └── optimizer.h         // 本地 SGD / AdamW
├── sparse/
│   ├── ps_server.h/cc      // brpc Parameter Server
│   ├── ps_client.h/cc      // brpc Client
│   └── table.h             // 稀疏表(unordered_map + 锁)
├── proto/
│   └── message.proto       // protobuf 消息
└── launcher.cc             // 主进程入口

3. MPI 通信层(稠密参数)

3.1 封装 MPI All-Reduce

// dense/mpi_allreduce.h
class MPIAllReduce {public:explicit MPIAllReduce(MPI_Comm comm) : comm_(comm) {}template <typename T>void AllReduceSum(std::vector<T>& buf) {std::vector<T> recv(buf.size());MPI_Allreduce(buf.data(), recv.data(), buf.size(),GetMPIType<T>(), MPI_SUM, comm_);buf.swap(recv);}private:MPI_Comm comm_;
};
  • 支持 float / double / int
  • 支持 In-place All-ReduceMPI_IN_PLACE)。

4. brpc Parameter Server(稀疏参数)

与之前设计一致,仅通信后端为 brpc

  • proto 定义不变(PullRequest, PushRequest)。
  • PS 端 实现 brpc::Service,用 brpc::Server 启动。
  • Worker 端brpc::Channel 连接 PS,支持 轮询/一致性哈希 负载均衡。

5. 主进程结构(launcher.cc)

int main(int argc, char* argv[]) {MPI_Init(&argc, &argv);int rank, size;MPI_Comm_rank(MPI_COMM_WORLD, &rank);MPI_Comm_size(MPI_COMM_WORLD, &size);bool is_ps = (rank >= FLAGS_worker_num);if (!is_ps) {// WorkerMPIAllReduce ar(MPI_COMM_WORLD);PSClient ps(FLAGS_ps_list);WorkerLoop(ar, ps);} else {// Parameter ServerPSServer server;server.Start(FLAGS_ps_port);}MPI_Finalize();
}

6. Worker 主循环

void WorkerLoop(MPIAllReduce& ar, PSClient& ps) {Model model;DataLoader dl(FLAGS_data_path);for (int step = 0; step < FLAGS_max_step; ++step) {auto batch = dl.Next();std::vector<float> dense_grad;std::vector<int64_t> sparse_keys;std::vector<float> sparse_grad;// 前向 & 反向model.Backward(batch, &dense_grad, &sparse_keys, &sparse_grad);// 1. 稠密梯度 MPI All-Reducear.AllReduceSum(dense_grad);// 2. 稀疏梯度异步 Pushps.PushAsync(0, sparse_keys, sparse_grad);// 3. 稀疏参数 Pullstd::vector<float> sparse_emb;ps.Pull(0, sparse_keys, &sparse_emb);// 4. 参数更新model.Update(dense_grad, sparse_emb);}
}

7. 部署与运行

7.1 启动脚本(OpenMPI)

# 4 worker + 2 ps
mpirun -np 6 \-x LD_LIBRARY_PATH \./launcher \--worker_num 4 \--ps_list "0.0.0.0:8000,0.0.0.0:8001"
  • worker_numrank 0~3 为 Worker,后 rank 4~5 为 PS。
  • MPI 负责稠密通信,brpc 负责稀疏通信,两者互不干扰。

8. 性能调优

建议
MPI使用 OpenMPI 4.xIntel MPI(CPU 亲和、NUMA 优化)。
brpc配置 轮询 + 批处理(64~256 key/RPC),开启 8bit 量化压缩
线程MPI 与 brpc 线程分离,brpc 用 bthread,避免与 MPI 线程冲突。

至此,“CPU + MPI(稠密) + brpc Parameter Server(稀疏)” 的完整框架已就绪。

http://www.lryc.cn/news/597606.html

相关文章:

  • 18.设备虚拟化
  • LeetCode 407:接雨水 II
  • SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法
  • SparkSQL 聚合函数 MAX 对 NULL 值的处理
  • 基于多种机器学习的水质污染及安全预测分析系统的设计与实现【随机森林、XGBoost、LightGBM、SMOTE、贝叶斯优化】
  • 小白做投资测算,如何快速上手?
  • 网安-SQL注入-sqli-labs
  • OpenLayers 快速入门(七)矢量数据
  • Centos7.9多网卡绑定做链路聚合
  • 回顾 Palantir:八年之旅的反思
  • 《P4092 [HEOI2016/TJOI2016] 树》
  • 线段树学习笔记 - 练习题(1)
  • UniApp X 网络请求避坑指南:从 JS 到 UTS 的 JSON 数据处理全解析
  • Neo4j 框架 初步简单使用(基础增删改查)
  • OpenEuler系统架构下编译redis的RPM包
  • 【基于OpenCV的图像处理】图像预处理之图像色彩空间转换以及图像灰度化处理
  • 【web页面接入Apple/google/facebook三方登录】
  • SQL基础⑥ | 聚合函数
  • Java项目中定时任务三方工具和技术的深度应用指南
  • Kubernetes 日志收集
  • biji 1
  • 事务与索引:数据库核心机制详解
  • 解析云蝠智能 VoiceAgent 的技术架构与应用实践
  • Linux第三天Linux基础命令(二)
  • 不同地区的主要搜索引擎工具
  • 原创-基于 PHP 和 MySQL 的证书管理系统 第三版
  • Windows 用 Python3 快速搭建 HTTP 服务器
  • 网络基础DAY18-动态路由协议基础
  • 观影《长安的荔枝》有感:SwiftUI 中像“荔枝转运”的关键技术及启示
  • Linux文件fd