Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/code/issue1/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
CXX := g++
CXXFLAGS := -std=c++17 -O3 -Wall -Wextra
TARGET := sm_budget_model
TEST_TARGET := test_runner

SRCS := main.cpp sm_budget_model.cpp bandwidth_model.cpp
TEST_SRCS := ../../test/issue1/test.cpp sm_budget_model.cpp bandwidth_model.cpp

.PHONY: all clean test

all: $(TARGET)

$(TARGET): $(SRCS)
$(CXX) $(CXXFLAGS) -o $@ $^

test: $(TEST_TARGET)
./$(TEST_TARGET)

$(TEST_TARGET): $(TEST_SRCS)
$(CXX) $(CXXFLAGS) -I. -o $@ $^

clean:
rm -f $(TARGET) $(TEST_TARGET)
34 changes: 34 additions & 0 deletions src/code/issue1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Issue 1:分析式 SM/QP 预算模型

## 编译运行

```bash
cd src/code/issue1
make # 编译(g++,无需GPU)
./sm_budget_model --mode single # 单次计算
./sm_budget_model --mode sweep # SM扫描输出CSV
./sm_budget_model --mode compare # 与固定24SM对比
make test # 单元测试
```

## 参数

| 参数 | 默认 | 说明 |
|------|------|------|
| `--num-experts` | 288 | 总专家数 |
| `--num-topk` | 8 | 每token topk |
| `--num-scaleout-ranks` | 8 | 跨节点rank数 |
| `--num-scaleup-ranks` | 1 | 节点内rank数 |
| `--num-device-sms` | 132 | 设备SM总数 |
| `--rdma-gbs` | 0(自动50) | RDMA带宽 |
| `--nvlink-gbs` | 0(自动450) | NVLink带宽 |

## 结果

```
288专家/topk8/8节点 → 推荐4 SM,节省20 SM vs 固定24 SM,带宽不减
```

## 参考

DeepEP `deep_ep/buffers/elastic.py` — `get_theoretical_num_sms()` (行 729-853)
83 changes: 83 additions & 0 deletions src/code/issue1/bandwidth_model.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*************************************************************************
* Copyright (c) 2025, TENCENT CORPORATION. All rights reserved.
*
* See LICENSE.txt for license information
*
* Author: moningchen@tencent.com
* Content: 带宽模型实现 — SM扫描与带宽估算
************************************************************************/

#include "bandwidth_model.h"

#include <algorithm>
#include <cmath>
#include <sstream>
#include <iomanip>

double estimateBandwidthAtSM(const EPConfig& config, const BandwidthParams& bw, int num_sms) {
if (num_sms <= 0) return 0.0;

SMBudgetResult result = computeSMBudget(config, bw);

if (result.bounded_traffic <= 0.0 || result.bounded_gbs <= 0.0) {
return 1.0; // 无流量时带宽视为最大
}

// SM处理能力: 受限于读或写的较小值
double sm_read_cap = num_sms * bw.sm_read_gbs / result.sm_read_traffic;
double sm_write_cap = num_sms * bw.sm_write_gbs / result.sm_write_traffic;
double sm_cap = std::min(sm_read_cap, sm_write_cap);

// 链路瓶颈容量
double link_cap = result.bounded_gbs / result.bounded_traffic;

// 实际带宽 = min(SM能力, 链路容量)
double effective = std::min(sm_cap, link_cap);

// 归一化: 1.0 = 链路饱和
double bw_normalized = effective / link_cap;
return std::min(bw_normalized, 1.0);
}

std::vector<SweepDataPoint> generateSMSweep(const EPConfig& config, const BandwidthParams& bw, int max_sms) {
std::vector<SweepDataPoint> sweep;
SMBudgetResult result = computeSMBudget(config, bw);
int recommended_sm = result.num_sms;

for (int sm = 4; sm <= max_sms; sm += 2) {
SweepDataPoint pt;
pt.num_sms = sm;
pt.bandwidth = estimateBandwidthAtSM(config, bw, sm);
pt.is_recommended = (sm == recommended_sm);
sweep.push_back(pt);
}
return sweep;
}

int findOptimalSM(const std::vector<SweepDataPoint>& sweep) {
if (sweep.empty()) return 4;

// 达到峰值带宽95%所需的SM数即视为最优
double peak_bw = sweep.back().bandwidth;
int optimal_sm = sweep[0].num_sms;

for (size_t i = 0; i < sweep.size(); ++i) {
if (sweep[i].bandwidth >= peak_bw * 0.95) {
optimal_sm = sweep[i].num_sms;
break;
}
}
return optimal_sm;
}

std::string exportSweepCSV(const std::vector<SweepDataPoint>& sweep, int recommended_sm) {
std::ostringstream oss;
oss << std::fixed << std::setprecision(4);
oss << "num_sms,bandwidth,is_recommended\n";
for (const auto& pt : sweep) {
oss << pt.num_sms << ","
<< pt.bandwidth << ","
<< (pt.num_sms == recommended_sm ? "1" : "0") << "\n";
}
return oss.str();
}
39 changes: 39 additions & 0 deletions src/code/issue1/bandwidth_model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*************************************************************************
* Copyright (c) 2025, TENCENT CORPORATION. All rights reserved.
*
* See LICENSE.txt for license information
*
* Author: moningchen@tencent.com
* Content: 带宽模型头文件 — SM扫描与带宽估算
************************************************************************/

#pragma once

#include "sm_budget_model.h"

#include <vector>
#include <string>

/*
* 估算给定SM数时的通信带宽(归一化,1.0=链路饱和)
*
* 模型: 实际带宽 = min(SM处理能力, 链路容量)
* SM处理能力 = num_sms × 每SM带宽 / 流量需求(受限于读或写)
* 链路容量 = 瓶颈带宽 / 瓶颈流量
*/
double estimateBandwidthAtSM(const EPConfig& config, const BandwidthParams& bw, int num_sms);

/*
* 生成SM扫描数据 (从4到max_sms, 步长2)
* 标记模型推荐的SM数为 is_recommended
*/
std::vector<SweepDataPoint> generateSMSweep(const EPConfig& config, const BandwidthParams& bw, int max_sms);

/*
* 找到最优SM数: 边际带宽增益低于5%的拐点
* 即比峰值带宽低5%时对应的SM数
*/
int findOptimalSM(const std::vector<SweepDataPoint>& sweep);

// 导出扫描数据为CSV格式
std::string exportSweepCSV(const std::vector<SweepDataPoint>& sweep, int recommended_sm);
Loading