optimize env conflicts
This commit is contained in:
parent
dd9e377ed8
commit
1f9374e9df
|
|
@ -589,35 +589,22 @@ struct ggml_backend_cann_context {
|
|||
#endif
|
||||
|
||||
// Read environment variables for multi-stream and operator fusion
|
||||
bool env_multi_stream = parse_bool(get_env_as_lowercase("GGML_CANN_MULTI_STREAM").value_or(""));
|
||||
bool env_operator_fusion = parse_bool(get_env_as_lowercase("GGML_CANN_OPERATOR_FUSION").value_or(""));
|
||||
multi_stream_enabled = parse_bool(get_env_as_lowercase("GGML_CANN_MULTI_STREAM").value_or(""));
|
||||
operator_fusion_enabled = parse_bool(get_env_as_lowercase("GGML_CANN_OPERATOR_FUSION").value_or(""));
|
||||
|
||||
// Handle conflicts and set final values
|
||||
#ifdef USE_ACL_GRAPH
|
||||
if (acl_graph_mode && env_multi_stream) {
|
||||
if (acl_graph_mode && multi_stream_enabled) {
|
||||
// ACL graph has higher performance, disable multi-stream
|
||||
multi_stream_enabled = false;
|
||||
operator_fusion_enabled = env_operator_fusion;
|
||||
GGML_LOG_INFO("%s: device %d multi-stream disabled (ACL graph mode has higher performance)\n",
|
||||
GGML_LOG_WARN("%s: device %d multi-stream disabled when ACL graph mode is enabled\n",
|
||||
__func__, device);
|
||||
} else
|
||||
#endif
|
||||
if (env_multi_stream) {
|
||||
if (multi_stream_enabled && operator_fusion_enabled) {
|
||||
// Multi-stream enabled, disable operator fusion (fusion has low benefit with multi-stream)
|
||||
multi_stream_enabled = true;
|
||||
operator_fusion_enabled = false;
|
||||
if (env_operator_fusion) {
|
||||
GGML_LOG_INFO("%s: device %d operator fusion disabled (low benefit with multi-stream enabled)\n",
|
||||
__func__, device);
|
||||
}
|
||||
GGML_LOG_INFO("%s: device %d multi-stream execution enabled\n", __func__, device);
|
||||
} else {
|
||||
// Default single-stream mode
|
||||
multi_stream_enabled = false;
|
||||
operator_fusion_enabled = env_operator_fusion;
|
||||
if (env_operator_fusion) {
|
||||
GGML_LOG_INFO("%s: device %d operator fusion enabled\n", __func__, device);
|
||||
}
|
||||
GGML_LOG_WARN("%s: device %d operator fusion is not supported in multi-stream mode\n",
|
||||
__func__, device);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,191 +0,0 @@
|
|||
# CANN Backend Multi-Stream Parallel Implementation
|
||||
|
||||
## 思考过程记录
|
||||
|
||||
### 1. 分析Vulkan后端的多流并行实现
|
||||
|
||||
通过分析PR #15489 和 #15850,我了解到Vulkan后端的多流并行实现包含以下两个关键部分:
|
||||
|
||||
#### 1.1 PR #15489: 重写同步机制,允许节点之间的重叠执行
|
||||
|
||||
**核心思想**:
|
||||
- 追踪需要同步的节点列表
|
||||
- 只有当新节点依赖于未完成的节点时才进行同步
|
||||
- 这允许一些重叠执行,从而提高性能
|
||||
|
||||
**关键实现**:
|
||||
- 使用内存范围(地址)来判断依赖关系,而不是直接查看图结构
|
||||
- 每个预分配的临时缓冲区(如dequantization或split_k)都有一个bool标记,指示它们是否被使用过并需要同步
|
||||
- 性能提升:在RTX 5090上,部分模型性能提升约5-8%
|
||||
|
||||
#### 1.2 PR #15850: 图排序优化,允许更多的并行执行
|
||||
|
||||
**核心思想**:
|
||||
- 添加backend proc(`graph_optimize`)允许后端修改计算图
|
||||
- Vulkan实现会分析哪些节点相互依赖,并贪婪地重排序它们
|
||||
- 将不相互依赖的节点分组在一起
|
||||
|
||||
**关键实现**:
|
||||
- `ggml_vk_graph_optimize`函数实现图优化
|
||||
- 保留特定的fusion pattern不被重排序(如RMS_NORM + MUL)
|
||||
- 使用两遍扫描:第一遍抓取"real"节点,第二遍抓取view节点
|
||||
- 最多检查接下来的20个节点是否可以提前执行
|
||||
|
||||
### 2. CANN后端当前状态分析
|
||||
|
||||
**现有基础设施**:
|
||||
- 已有stream管理(`cann_ctx->stream()`)
|
||||
- 支持ACL Graph模式
|
||||
- 已有同步机制(`aclrtSynchronizeStream`)
|
||||
- 后端接口中 `graph_optimize` 目前为NULL
|
||||
|
||||
**需要添加的功能**:
|
||||
1. 实现 `ggml_backend_cann_graph_optimize` 函数
|
||||
2. 可能需要添加多流支持
|
||||
3. 添加环境变量控制开关
|
||||
|
||||
### 3. 设计方案
|
||||
|
||||
#### 3.1 实现 `graph_optimize` 函数
|
||||
|
||||
参考Vulkan的实现,我们需要:
|
||||
|
||||
```cpp
|
||||
static void ggml_backend_cann_graph_optimize(ggml_backend_t backend, struct ggml_cgraph * graph);
|
||||
```
|
||||
|
||||
**核心逻辑**:
|
||||
1. 判断是否禁用优化(环境变量控制)
|
||||
2. 定义辅助函数判断节点是否为"空"(VIEW, RESHAPE等)
|
||||
3. 定义辅助函数判断节点依赖关系
|
||||
4. 重排序算法:
|
||||
- 遍历所有未使用的节点
|
||||
- 找到可以与当前节点并行执行的节点(不相互依赖)
|
||||
- 保留fusion pattern
|
||||
- 更新节点顺序
|
||||
|
||||
#### 3.2 环境变量
|
||||
|
||||
- `GGML_CANN_DISABLE_GRAPH_OPTIMIZE`: 禁用图优化
|
||||
|
||||
### 4. 实现计划
|
||||
|
||||
1. 在 `ggml-cann.cpp` 中实现 `ggml_backend_cann_graph_optimize`
|
||||
2. 在 `ggml_backend_cann_interface` 中注册该函数
|
||||
3. 编译验证
|
||||
4. 使用Qwen 0.5B模型验证功能正确性
|
||||
|
||||
### 5. 预期收益
|
||||
|
||||
根据Vulkan后端的测试结果,图优化可以带来:
|
||||
- 小模型(1B参数):约5-8%的性能提升
|
||||
- 中等模型(8B参数):约3-4%的性能提升
|
||||
- MoE模型:约6-7%的性能提升
|
||||
|
||||
这些收益来自于减少同步次数,允许更多操作并行执行。
|
||||
|
||||
## 实现代码
|
||||
|
||||
### 修改文件
|
||||
|
||||
`ggml/src/ggml-cann/ggml-cann.cpp`
|
||||
|
||||
### 主要更改
|
||||
|
||||
1. **添加头文件**:
|
||||
- `<algorithm>` - 用于 `std::find`
|
||||
- `<set>` - 用于 `std::set`
|
||||
- `<vector>` - 用于 `std::vector`
|
||||
|
||||
2. **实现 `ggml_backend_cann_graph_optimize` 函数**:
|
||||
- 位于 `ggml_backend_cann_event_wait` 函数之后
|
||||
- 约250行代码
|
||||
- 参考Vulkan后端的实现
|
||||
|
||||
3. **注册到backend interface**:
|
||||
- 修改 `ggml_backend_cann_interface` 结构体
|
||||
- 将 `graph_optimize` 从 `NULL` 改为 `ggml_backend_cann_graph_optimize`
|
||||
|
||||
### 关键算法
|
||||
|
||||
```cpp
|
||||
// 核心优化算法伪代码
|
||||
while (还有未处理的节点) {
|
||||
current_set = [下一个未处理的节点]
|
||||
|
||||
// 保留fusion pattern
|
||||
if (match_pattern(ADD + RMS_NORM)) {
|
||||
keep_pattern_together()
|
||||
continue
|
||||
}
|
||||
|
||||
// 第一遍:抓取可并行执行的"real"节点
|
||||
for (接下来的20个节点) {
|
||||
if (节点不依赖于未处理的节点) {
|
||||
if (支持fusion pattern) {
|
||||
add_to_current_set()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 第二遍:抓取view节点
|
||||
for (接下来的20个节点) {
|
||||
if (is_empty(节点) && 依赖已满足) {
|
||||
add_to_current_set()
|
||||
}
|
||||
}
|
||||
|
||||
// 更新节点顺序
|
||||
new_order.append(current_set)
|
||||
}
|
||||
```
|
||||
|
||||
### 支持的Fusion Pattern
|
||||
|
||||
- RMS_NORM + MUL
|
||||
- MUL_MAT + ADD
|
||||
- MUL_MAT_ID + ADD
|
||||
- ADD + ADD
|
||||
- ADD + RMS_NORM(CANN特有)
|
||||
- ROPE + VIEW + SET_ROWS
|
||||
|
||||
## 测试结果
|
||||
|
||||
### 测试环境
|
||||
- 模型:Qwen 2.5 0.5B Instruct FP16
|
||||
- 设备:4x Ascend 910B4
|
||||
- 测试命令:`llama-cli -m qwen2.5:0.5b-instruct-fp16 -n 50 -ngl 99`
|
||||
|
||||
### 测试输出
|
||||
```
|
||||
> Hello, how are you?
|
||||
|
||||
Hello! I'm Qwen, an AI developed by Alibaba Cloud. I'm here to answer any questions you may have and help with anything else you need help with. How can I assist you today?
|
||||
|
||||
[ Prompt: 1346.4 t/s | Generation: 142.8 t/s ]
|
||||
```
|
||||
|
||||
### 结论
|
||||
- ✅ 编译通过
|
||||
- ✅ 模型加载成功
|
||||
- ✅ 推理输出正确
|
||||
- ✅ 正常退出
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 启用图优化(默认)
|
||||
```bash
|
||||
./llama-cli -m model.gguf -ngl 99
|
||||
```
|
||||
|
||||
### 禁用图优化
|
||||
```bash
|
||||
GGML_CANN_DISABLE_GRAPH_OPTIMIZE=1 ./llama-cli -m model.gguf -ngl 99
|
||||
```
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. **添加性能测试**:使用llama-bench进行before/after性能对比
|
||||
2. **多流支持**:进一步实现真正的多流并行,利用CANN的多stream能力
|
||||
3. **更多fusion pattern**:根据CANN的特性添加更多融合优化
|
||||
4. **环境变量调优**:添加更细粒度的控制参数
|
||||
Loading…
Reference in New Issue