Skip to content

Commit 76d67b9

Browse files
committed
deepx:删除冗余仓库
1 parent e17e15f commit 76d67b9

File tree

24 files changed

+582
-22
lines changed

24 files changed

+582
-22
lines changed

.cursorrules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Always respond in 中文
2+
不要回答重复的内容(如我提问中的代码)
3+
此项目名为deepx,我的环境为ubuntu22,项目是c++17,使用cmake编译,项目路径为/home/lipeng/code/ai/deepx
4+
返回c++代码区分header和source文件
5+
由于作者是c++新手,请仔细检查指针和引用,对deepx这种密集计算任务,不要使用智能指针,但注意内存泄漏,函数返回对象等
6+
不要增加"假设Tensor类在这个路径下"这种一眼就被看出是AI写的注释,不要让我的代码看起来像AI生成

README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# DeepX
2+
3+
DeepX 是一个基于C++的深度学习框架,支持Python绑定。它旨在提供高性能的tensor计算和便捷的主流模型搭建能力,适用于研究和生产环境。
4+
5+
## 特性
6+
7+
+ 高效的tensor计算
8+
+ CPU加速:采用openmp与simd指令优化了大量算子
9+
+ GPU加速:采用cuda,cuDNN,cuBLAS等库优化了大量算子
10+
+ 内存管理
11+
+ 主机侧,采用jemalloc统一管理tensor
12+
+ TODO 显存侧,Unified Memory
13+
+ 主流的模型搭建
14+
+ 动态计算图支持
15+
+ TODO 图编译 JIT
16+
+ 支持主流的模型搭建,提供高性能常用层
17+
+ MLP: activation, dropout, linear, batch normalization, softmax
18+
+ CNN: convolution, pooling, padding, cropping
19+
+ RNN: LSTM, GRU, RNN
20+
+ [TODO] Transformer: attention, RoPE, layer normalization
21+
+ 并行计算 TODO
22+
+ 无需任何配置,自动实现并行
23+
+ TODO 自动tensor切分
24+
+ 内置计算调度器,异步流水线并行
25+
+ 分布式高可用计算
26+
+ 混合异构计算,支持CPU+不同GPU的混合计算
27+
+ 支持多机多卡计算
28+
+ 自动数据
29+
+ 自动反向传播
30+
+ 支持自动反向传播
31+
+ 并行
32+
+ 支持数据并行
33+
+ TODO 模型并行
34+
+ TODO 异步流水线并行
35+
36+
37+
## 构建
38+
39+
1. 安装依赖
40+
41+
```bash
42+
sudo apt-get install -y cmake g++ libopenblas-dev libopenblas-pthread-dev libjemalloc-dev libyaml-cpp-dev
43+
```
44+
45+
2. 构建
46+
47+
```bash
48+
mkdir build
49+
cd build
50+
cmake ..
51+
make -
52+
```
53+
54+
## 贡献指南
55+
56+
欢迎提交Issue和Pull Request。在提交PR之前,请确保:
57+
- 代码符合项目的编码规范
58+
- 添加了适当的单元测试
59+
- 更新了相关文档
60+
61+
## 许可证
62+
63+
本项目采用 [Apache 2.0](LICENSE) 许可证。

doc/broadcast.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
[i] broadcastto [4i,2i,i]
3+
4+
+ 不开启omp
5+
6+
| Size | Time (seconds) | mem |
7+
|------|------------------|--------|
8+
| 64 | 0.304582 | 8 MB |
9+
| 128 | 2.06795 | 64 MB |
10+
| 256 | 16.4505 | 512 MB |
11+
| 512 | 131.381 | 4 GB |
12+
13+
+ 开启omp
14+
15+
以下是整理后的表格,展示了不同大小的时间消耗:
16+
17+
| Size | Time (seconds) | mem |
18+
|------|------------------|--------|
19+
| 64 | 0.062084 | 8 MB |
20+
| 128 | 0.132792 | 64 MB |
21+
| 256 | 1.21183 | 512 MB |
22+
| 512 | 8.89442 | 4 GB |
23+

doc/deepx.jpg

60.9 KB
Loading

doc/deepx.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
> 摘要:本文提出了一种超大规模自动分布式训推一体化的开放计算调度框架。该框架前端实现了高可用计算,支持多语言 SDK 调用;调度面通过注册中心、元数据数据库、计算图编译器优化器和执行调度器等组件,实现高效的任务调度与管理;执行面完成算存、算子引擎和网络通信的注册。通过严格遵循存算控分离的思想,框架能够在超大规模场景下实现自动分布式训练与推理的一体化,有效应对掉卡、掉节点等异常情况,提高计算资源的利用率和系统的可靠性。
2+
通过开放式计算调度框架,可供不同背景的厂家、开发者,按统一协议,适配和开发自己的算子引擎、算存引擎、网络引擎等。
3+
4+
## 一、引言
5+
6+
随着深度学习技术的快速发展,模型的规模和复杂度不断增加,对计算资源的需求也呈指数级增长。在超大规模的深度学习训练和推理任务中,分布式计算成为解决计算瓶颈的关键技术。然而,现有的分布式深度学习框架在应对大规模计算时,仍然面临着高可用计算保障不足、训推一体化程度低、多语言支持不完善等问题。
7+
8+
本文旨在设计一种超大规模自动分布式并行训推一体化的深度学习框架,以解决上述问题。
9+
10+
开放式计算调度框架,可以让更多厂家、开发者参与进来,按统一接口标准,适配和开发自己的算子引擎、算存引擎、网络引擎等,整体加速AI的能力。
11+
12+
## 二、架构
13+
14+
### 存算控分离思想
15+
16+
存算控分离是一种架构设计思想,将存储、计算和控制三个层面进行解耦,以提高系统的灵活性、可扩展性和可维护性。在本框架中:
17+
18+
### 1. 存储分离
19+
- 将数据存储与计算分离,数据可以存储在显存、内存、高性能nvme、分布式文件、对象存储等系统
20+
- 存储高可用。对单次计算任务、单卡、单节点等故障,进行最小成本、最快恢复。
21+
22+
### 2. 计算分离
23+
- 计算节点可以独立扩展,支持异构计算资源(CPU/GPU/NPU等)
24+
- 算子引擎可插拔,支持不同的加速硬件(GPU/NPU/DSA/DSP/CPU等)
25+
- 计算任务可以灵活调度到不同节点
26+
27+
### 3. 控制分离
28+
- 调度控制与具体执行分离
29+
- 通过注册中心实现资源的统一管理
30+
- 支持故障恢复和负载均衡
31+
- 提供统一的任务调度和监控接口
32+
33+
存算控分离的优势:
34+
- 提高系统的可扩展性,各个组件可以独立演进
35+
- 增强系统的容错能力,单个组件故障不会影响整体
36+
- 便于系统维护和升级,可以分别对各个层面进行优化
37+
- 支持更灵活的部署方式,适应不同的应用场景
38+
39+
劣势
40+
- 计算与存储分离,需要额外进行数据传输,增加通信成本
41+
42+
解决方案
43+
44+
存算一体控分离思想
45+
46+
相比存算控分离,存算一体控分离,在计算与存储分离的基础上,增加了计算与存储的融合,减少了计算与存储的通信成本。
47+
48+
- 使用分级缓存。通过AI芯片的分级高速缓存,减少芯片的数据读写时间
49+
- 支持存算一体的GPU、AI加速卡等,减少数据传输
50+
51+
![架构图](./deepx.jpg)
52+
53+
## 三、框架前端设计
54+
55+
### 2.1多语言 SDK 支持
56+
57+
框架前端支持多语言(C/C++, Python, Go, Java, Lua, JavaScript)的 SDK 调用,以方便不同背景的开发者使用。每种语言的 SDK 都提供了统一的接口,用于描述数据与计算流。开发者可以根据自己的需求选择合适的语言进行开发,提高开发效率。
58+
59+
### 2.2 dashboard监控可视化
60+
dashboard可对任务、节点、卡、算子、网络、存储、计算图等进行监控,可视化展示。
61+
62+
## 三、调度面设计
63+
64+
### 3.1 注册中心
65+
66+
注册中心是调度面的核心组件之一,支持内存注册、算子注册、网络注册。内存注册记录了各个计算节点的内存资源使用情况,算子注册存储了框架中可用的算子信息,网络注册则记录了节点之间的网络连接信息。通过注册中心,调度器可以实时获取系统的资源状态,为任务调度提供依据。
67+
### 3.2 元数据数据库
68+
69+
元数据数据库中心存储该框架的一切元信息,包括模型结构、数据分布、任务配置等。这些元信息为计算图编译器优化器和执行调度器提供了必要的信息,帮助它们做出更合理的决策。
70+
### 3.3 计算图编译器优化器
71+
72+
计算图编译器优化器根据注册的内存、算子的上限与性能,自动拆分 tensor,生成详细执行图。在超大规模的深度学习任务中,tensor 的规模往往非常大,直接进行计算会导致内存不足和计算效率低下。计算图编译器优化器通过对 tensor 进行拆分,将大任务分解为多个小任务,提高内存利用率和计算效率。
73+
74+
### 3.4 执行调度器
75+
76+
执行调度器根据编译的执行计算图,进行任务分发,编排流水线与监控、debug,对失败或异常超时的任务进行漂移。执行调度器会根据计算节点的资源状态和任务的优先级,合理分配任务。同时,它会实时监控任务的执行情况,当发现任务失败或异常超时,会将任务重新分配到其他可用的节点上,保证任务的顺利执行。
77+
78+
#### 3.4.1 执行调度器与执行侧的通信
79+
80+
执行调度器与执行侧的通信,对延迟要求极高,优先采用可信低延迟的网络通信,其次采用非可信的网络通信。
81+
82+
通信包
83+
84+
> 发送
85+
86+
+ 大小 1472B或65536B 以内
87+
+ 格式:yaml
88+
+ 内容: 任务id、算子名称或注册算子ID、参数(地址、数)
89+
90+
> 返回
91+
+ 大小 1472B或65536B 以内
92+
+ 格式:yaml6
93+
+ 内容: 任务id
94+
95+
| 协议方式 | 可信网络 | 非可信网络 |
96+
|---------|---------|------------|
97+
| udp | localhost极低延迟 | 不可用 |
98+
| tcp | 低延迟 | |
99+
100+
#### 3.4.2 通信成本分析
101+
102+
+ 单一程序的直接调度,通信成本为0
103+
+ 在分布式计算中,通信成本,我们期望降低在10%以内。
104+
105+
意味着
106+
$$ \frac{T_{compute}}{T_{communication}} > 10 $$
107+
108+
op的计算时长/通信时长之比 需要大于10
109+
110+
因此,我们需要使用算子融合的方式,提升算子的总时长,降低调度带来的通信时长。
111+
112+
113+
114+
### 3.5 监控与 debug
115+
116+
监控与 debug 是框架的重要组成部分,它可以帮助用户实时监控任务的执行情况,及时发现并解决问题。监控与 debug 模块会收集任务的执行日志、性能数据等信息,并提供可视化界面,方便用户进行问题排查和性能优化。
117+
118+
## 四、执行面设计
119+
### 4.1 算存注册
120+
121+
算存注册记录了计算资源和存储资源的对应关系。通过算存注册,调度器可以根据数据的存储位置,合理分配计算任务,减少数据传输开销。
122+
### 4.2 算子引擎注册
123+
124+
算子引擎注册可以注册与算存绑定关系。不同的算子可能对计算资源和存储资源有不同的要求,通过算子引擎注册,可以将算子与合适的算存资源进行绑定,提高计算效率。
125+
### 4.3 网络通信注册
126+
127+
网络通信注册记录了节点之间的网络连接信息,包括带宽、延迟等。调度器可以根据网络通信注册信息,选择最优的网络路径进行数据传输,提高数据传输效率。
128+
## 五、实验与结果分析
129+
130+
为了验证本文提出的超大规模自动分布式训推一体化深度学习框架的性能,我们进行了一系列实验。实验环境包括多个计算节点,每个节点配备多个 GPU 卡。实验任务包括图像分类、目标检测等深度学习任务。
131+
132+
实验结果表明,该框架在高可用计算方面表现出色,能够有效应对掉卡、掉节点等异常情况,保证计算的连续性。同时,多语言 SDK 的支持使得开发者可以更方便地使用框架进行开发。在调度面和执行面的协同作用下,框架能够提高计算资源的利用率,减少任务执行时间,实现超大规模自动分布式训练与推理的一体化。
133+
## 六、结论
134+
135+
本文提出了一种超大规模自动分布式训推一体化的深度学习框架。通过前端的高可用计算和多语言 SDK 支持,调度面的注册中心、元数据数据库、计算图编译器优化器和执行调度器,以及执行面的算存注册、算子引擎注册和网络通信注册,框架能够在超大规模场景下实现高效的自动分布式训练与推理。实验结果验证了框架的有效性和优越性。未来的研究方向包括进一步优化框架的性能,支持更多的深度学习模型和任务,以及与云平台的深度集成。

doc/matmul.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## 矩阵乘法
2+
3+
平台 ubuntu 22.04
4+
cpu Intel(R) Core(TM) i9-14900K
5+
内存 64GB
6+
7+
| 矩阵大小 | 耗时(秒) | 内存占用 |
8+
|--------------|-----------|------------|
9+
| 64x64 | 0.000073 | 16 KB |
10+
| 128x128 | 0.007146 | 64 KB |
11+
| 256x256 | 0.002196 | 256 KB |
12+
| 512x512 | 0.007013 | 1 MB |
13+
| 1024x1024 | 0.027820 | 4 MB |
14+
| 2048x2048 | 0.058486 | 16 MB |
15+
| 4096x4096 | 0.249994 | 64 MB |
16+
| 8192x8192 | 1.973990 | 256 MB |
17+
| 16384x16384 | 14.712000 | 1 GB |
18+
| 32768x32768 | 111.222000| 4 GB |
19+
20+
再大会段错误,待优化

doc/node.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Node,计算图的设计思考
2+
3+
## 概念
4+
5+
pytorch的计算图是动态的,tensorflow早期的计算图是静态的。
6+
7+
pytorch在前向传播时,会构建一个计算图,在反向传播时,会根据计算图进行反向传播。
8+
9+
10+
## Graph结构
11+
12+
Node{
13+
froms []*Node
14+
tos []*Node
15+
}
16+
17+
Graph结构可以支持Residual的跳跃Node连接
18+
19+
## Tree结构
20+
21+
Tree{
22+
parent *Node
23+
children []*Node
24+
}
25+
26+
Tree结构需要特别的实现Residual的跳跃Node连接
27+
28+
Residual可以把跳跃连接的Node打平,都作为Residual的childs
29+
30+
## Deepx的设计实现
31+
优先考虑Tree这种静态图结构,如果需要支持Residual的跳跃Node连接,可以在forward和backward中特别的实现。

doc/range.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# range
2+
3+
range函数是shape类中的一个函数,用于根据shape对tensor进行遍历。
4+
5+
由于非常多的算子,调用到了range函数,所以range函数需要不同类型的参数
6+
7+
| func | omp并行 | omp线程local局部对象 | 调用场景 |
8+
| ---- | ---- | ------ | ---------- |
9+
| | N | | print |
10+
| 函数 || 0 | 不需要并行 |
11+
| 函数 || 0 | 需要并行 |
12+
| 函数 || 0 | 不需要并行 |
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#ifndef DEEPX_OP_CUDA_NEW_HPP
2+
#define DEEPX_OP_CUDA_NEW_HPP
3+
4+
#include <cuda_runtime.h>
5+
#include <stdexcept>
6+
#include "deepx/tensor.hpp"
7+
8+
9+
// 具体的张量类
10+
namespace deepx::op::cuda
11+
{
12+
template <typename T>
13+
static T* dataNew(int size)
14+
{
15+
T* data;
16+
cudaError_t err = cudaMallocManaged(&data, size * sizeof(T));
17+
if (err != cudaSuccess) {
18+
throw std::runtime_error("Failed to allocate Unified Memory");
19+
}
20+
return data;
21+
}
22+
23+
template <typename T>
24+
static void dataFree(T *data)
25+
{
26+
cudaFree(data);
27+
}
28+
29+
template <typename T>
30+
static void dataCopy(T *data, T *data2, int size)
31+
{
32+
cudaMemcpy(data2, data, size * sizeof(T), cudaMemcpyDefault);
33+
}
34+
35+
template <typename T>
36+
Tensor<T> New(const std::vector<int> &shapedata, T *data = nullptr)
37+
{
38+
Shape shape(shapedata);
39+
Tensor<T> tensor(shape);
40+
tensor.device = CUDA; // 使用 CUDA 设备
41+
tensor.deleter = dataFree<T>;
42+
tensor.copyer = dataCopy<T>;
43+
tensor.newer = dataNew<T>;
44+
45+
if (data != nullptr) {
46+
tensor.data = data;
47+
} else {
48+
tensor.data = dataNew<T>(shape.size);
49+
}
50+
return tensor;
51+
}
52+
53+
template <typename T>
54+
Tensor<T> New(const std::initializer_list<int> &shapedata, T *data = nullptr)
55+
{
56+
Shape shape(shapedata);
57+
Tensor<T> tensor(shape);
58+
tensor.device = CUDA; // 使用 CUDA 设备
59+
tensor.deleter = dataFree<T>;
60+
tensor.copyer = dataCopy<T>;
61+
tensor.newer = dataNew<T>;
62+
63+
if (data != nullptr) {
64+
tensor.data = data;
65+
} else {
66+
tensor.data = dataNew<T>(shape.size);
67+
}
68+
return tensor;
69+
}
70+
71+
template <typename T>
72+
Tensor<T> clone(const Tensor<T> &tensor)
73+
{
74+
Tensor<T> result = New<T>(tensor.shape.shape);
75+
tensor.copyer(tensor.data, result.data, tensor.shape.size);
76+
return result;
77+
}
78+
}
79+
#endif // DEEPX_OP_CUDA_NEW_HPP

0 commit comments

Comments
 (0)