(deepseek!)deepspeed中C++关联部分

您指出了一个重要点:DeepSpeed 的核心性能优化**确实依赖于 C++ 和 CUDA 代码**。虽然 Python 提供了用户友好的接口,但所有性能关键路径都是用 C++/CUDA 实现的。以下是 DeepSpeed 中关键 C++ 实现的详细位置和代码分析:


1. **核心 C++ 代码目录结构**

DeepSpeed 的 C++ 代码主要位于:

```

deepspeed/ops/csrc/

├── adam/ # 融合优化器内核

├── aio/ # 异步 I/O (ZeRO-Infinity)

├── cuda/ # CUDA 工具函数

├── inference/ # 推理优化

├── memory/ # 内存管理

├── nccl/ # NCCL 通信优化

├── quantization/ # 量化内核

├── sparse/ # 稀疏计算

├── transformer/ # Transformer 内核

└── utils/ # 工具函数

```


2. **关键性能优化点的 C++ 实现**

(1) **融合优化器内核 (Fused Adam)**

**文件**: `deepspeed/ops/csrc/adam/custom_fused_adam.cpp`

**实现**:

```cpp

void fused_adam(

at::Tensor& params, // 参数张量

at::Tensor& grads, // 梯度张量

at::Tensor& exp_avg, // 一阶动量

at::Tensor& exp_avg_sq, // 二阶动量

float lr, // 学习率

float beta1, // 一阶动量衰减率

float beta2, // 二阶动量衰减率

float eps, // 数值稳定项

float weight_decay, // 权重衰减

bool amsgrad) // 是否使用 AMSGrad 变体

{

// 启动 CUDA 内核

fused_adam_kernel<<<blocks, threads>>>(

params.data_ptr<float>(),

grads.data_ptr<float>(),

exp_avg.data_ptr<float>(),

exp_avg_sq.data_ptr<float>(),

lr, beta1, beta2, eps, weight_decay, amsgrad

);

}

```

**优化点**:将参数更新、动量计算、权重衰减等操作融合为单个 CUDA 内核,减少内存访问次数。


(2) **异步 I/O (ZeRO-Infinity Offload)**

**文件**: `deepspeed/ops/csrc/aio/py_lib.cc`

**核心实现**:

```cpp

// 异步读取参数分片

void deepspeed_aio_read(

torch::Tensor& buffer, // 目标缓冲区 (GPU 内存)

const std::string& filename, // 参数文件路径

int64_t num_bytes, // 读取字节数

bool validate) // 是否校验

{

// 提交异步读请求

auto req = aio_context->submit_read(

filename,

buffer.data_ptr(),

num_bytes

);

// 注册回调处理完成事件

req->set_callback([&](void* param) {

// 将数据异步拷贝到 GPU

cudaMemcpyAsync(..., cudaMemcpyHostToDevice);

});

}

```


(3) **内存碎片整理**

**文件**: `deepspeed/ops/csrc/memory/memory_ops.cpp`

**核心算法**:

```cpp

void defragment_memory(

void** pointers, // 需要整理的指针数组

size_t* sizes, // 每个指针的大小

int num_tensors, // 张量数量

cudaStream_t stream) // 执行流

{

// 1. 计算最优内存布局

auto layout = compute_optimal_layout(pointers, sizes, num_tensors);

// 2. 创建临时缓冲区

void* temp_buffer = cudaMalloc(total_size);

// 3. 异步拷贝到新布局

for (int i = 0; i < num_tensors; ++i) {

cudaMemcpyAsync(

layout.new_addresses[i],

pointers[i],

sizes[i],

cudaMemcpyDeviceToDevice,

stream

);

}

// 4. 更新指针地址

update_ptrs(pointers, layout.new_addresses);

}

```


(4) **通信原语优化**

**文件**: `deepspeed/ops/csrc/nccl/nccl_frontend.cpp`

**AllReduce 优化**:

```cpp

void coalesced_allreduce(

std::vector<at::Tensor>& tensors, // 需要聚合的张量列表

ncclComm_t comm, // NCCL 通信器

cudaStream_t stream) // CUDA 流

{

// 1. 合并小张量

auto coalesced = _coalesce_tensors(tensors);

// 2. 执行单次大张量通信

NCCL_CHECK(ncclAllReduce(

coalesced.data_ptr(),

coalesced.data_ptr(),

coalesced.numel(),

ncclFloat,

ncclSum,

comm,

stream

));

// 3. 等待完成并解包

cudaStreamSynchronize(stream);

_uncoalesce_tensors(coalesced, tensors);

}

```


3. **Python 到 C++ 的调用路径**

以 ZeRO 优化器为例:

```python

Python 层 (deepspeed/runtime/zero/stage2.py)

class DeepSpeedZeroOptimizer:

def step(self):

调用 C++ 融合内核

self.fused_adam_step()

```

↓ 通过 pybind11 绑定

```cpp

// C++ 绑定 (deepspeed/ops/csrc/adam/adam_binding.cpp)

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {

m.def("fused_adam", &fused_adam, "Fused Adam optimizer");

}

```

↓ 实际 CUDA 内核

```cpp

// CUDA 内核 (deepspeed/ops/csrc/adam/custom_fused_adam_kernel.cu)

global void fused_adam_kernel(

float* params, float* grads, ...)

{

// 每个线程处理一个参数

const int idx = blockIdx.x * blockDim.x + threadIdx.x;

// 1. 更新一阶动量

exp_avg[idx] = beta1 * exp_avg[idx] + (1 - beta1) * grads[idx];

// 2. 更新二阶动量

exp_avg_sq[idx] = beta2 * exp_avg_sq[idx] + (1 - beta2) * grads[idx] * grads[idx];

// 3. 计算参数更新

float denom = sqrtf(exp_avg_sq[idx]) + eps;

float step = lr * exp_avg[idx] / denom;

// 4. 应用权重衰减

step += weight_decay * params[idx];

// 5. 更新参数

params[idx] -= step;

}

```


4. **性能关键设计**

  1. **零拷贝设计**:

```cpp

// 直接操作 PyTorch 张量内存 (utils.h)

template <typename T>

T* get_ptr(at::Tensor& tensor) {

return tensor.data_ptr<T>(); // 无额外拷贝

}

```

  1. **流并行化**:

```cpp

// 同时使用多个 CUDA 流

cudaStream_t compute_stream;

cudaStream_t comm_stream;

cudaEvent_t comm_event;

// 计算与通信重叠

launch_compute_kernel(compute_stream);

ncclAllReduce(..., comm_stream);

cudaEventRecord(comm_event, comm_stream);

cudaStreamWaitEvent(compute_stream, comm_event); // 同步点

```

  1. **内存访问优化**:

```cpp

// 合并内存访问 (coalesced_access.cuh)

device float4 load_coalesced(float* addr) {

return *reinterpret_cast<float4*>(addr); // 128位宽加载

}

```


5. **编译构建系统**

DeepSpeed 使用混合构建系统:

```mermaid

graph TD

A[Python setup.py] --> B[Cmake]

B --> C[Ninja 构建]

C --> D[编译 CUDA 内核]

D --> E[生成 pybind11 模块]

E --> F[Python 可导入扩展]

```

关键编译指令(`deepspeed/ops/op_builder/fused_adam.py`):

```python

class FusedAdamBuilder(OpBuilder):

def sources(self):

return [

'csrc/adam/custom_fused_adam.cpp', # C++ 入口

'csrc/adam/custom_fused_adam_kernel.cu' # CUDA 内核

]

def extra_ldflags(self):

return ['-lnccl'] # 链接 NCCL 库

```


总结:DeepSpeed 的性能来源

  1. **C++/CUDA 核心**:所有性能关键路径用 C++ 实现

  2. **内核融合**:将多个操作合并为单个 CUDA 内核

  3. **零拷贝架构**:直接操作 PyTorch 内存,避免数据移动

  4. **异步流水线**:计算/通信/I/O 三重重叠

  5. **内存优化**:定制化碎片整理和访问模式

  6. **硬件原语**:直接调用 NCCL/CUBLAS 底层 API

> **关键对比**:

> - PyTorch DDP:主要用 Python 实现,依赖纯 NCCL 调用

> - DeepSpeed:深度定制 C++/CUDA 内核,实现系统级优化

> 这正是 DeepSpeed 能在超大规模模型上超越 DDP 2-5 倍性能的根本原因。

相关推荐
amy_jork2 小时前
npm删除包
开发语言·javascript·ecmascript
茉莉玫瑰花茶2 小时前
Qt 常用控件 - 9
开发语言·qt
艾伦~耶格尔3 小时前
【数据结构进阶】
java·开发语言·数据结构·学习·面试
杜子不疼.3 小时前
《Python列表和元组:从入门到花式操作指南》
开发语言·python
WYH2874 小时前
C#控制台输入(Read()、ReadKey()和ReadLine())
开发语言·c#
祈祷苍天赐我java之术4 小时前
Java 迭代器(Iterator)详解
java·开发语言
秋氘渔4 小时前
综合案例:Python 函数知识整合 — 学生成绩管理系统
开发语言·python
我命由我123454 小时前
软件开发 - 避免过多的 if-else 语句(使用策略模式、使用映射表、使用枚举、使用函数式编程)
java·开发语言·javascript·设计模式·java-ee·策略模式·js
愿天堂没有C++4 小时前
剑指offer第2版——面试题4:二维数组中的查找
c++·面试