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

纯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.xdnf.cn/news/16223.html

相关文章:

  • 刷完jetpack后无法打开安装的浏览器的解决办法useful
  • Linux dd命令 数据备份、转换与磁盘操作的终极工具
  • 分布式任务调度实战:XXL-JOB与Elastic-Job深度解析
  • OpenLayers 快速入门(六)Interaction 对象
  • 模拟实现消息队列项目
  • 7月23日星期三今日早报简报微语报早读
  • C基础 07_综合案例《猜拳游戏》
  • Android NDK与JNI深度解析
  • HarmonyOS Flutter Boost完全接入手册:爬完所有坑的实战指南
  • 双写缓冲区 Redo Log
  • C++缺省参数
  • React项目运行环境与执行顺序及动态路由等使用注意点
  • 数据结构系列之AVL树
  • 1、黑马点评复盘(短信登录-Session或Redis实现)
  • 不同地区的主要搜索引擎工具
  • 嵌入式linux下的NES游戏显示效果优化方案:infoNES显示效果优化
  • GaussDB view视图的用法
  • now能减少mysql的压力吗
  • 重写 与 重载
  • OpenCV(02)图像颜色处理,灰度化,二值化,仿射变换
  • 优化 Elasticsearch JVM 参数配置指南
  • 浙大Fast Lab:融合3D激光雷达与强化学习的「端到端导航」,让无人机“飞”在点云上!
  • 【Linux-云原生-笔记】keepalived相关
  • OSPF路由协议——上
  • Android MediaCodec 的使用和源码实现分析
  • VSCode 开发 STM32 - clangd 带来的极致补全体验
  • Zipformer
  • ZKmall开源商城微服务架构实战:Java 商城系统的模块化拆分与通信之道
  • 小白做投资测算,如何快速上手?
  • 反向传播及优化器