From 1f9374e9dfc3e83096dd5a2aacb5d04f24be6859 Mon Sep 17 00:00:00 2001 From: hipudding Date: Fri, 6 Feb 2026 02:51:43 +0000 Subject: [PATCH] optimize env conflicts --- ggml/src/ggml-cann/common.h | 27 +-- skills/cann_multi_stream_implementation.md | 191 --------------------- 2 files changed, 7 insertions(+), 211 deletions(-) delete mode 100644 skills/cann_multi_stream_implementation.md diff --git a/ggml/src/ggml-cann/common.h b/ggml/src/ggml-cann/common.h index ca4bf35b75..f998a03763 100644 --- a/ggml/src/ggml-cann/common.h +++ b/ggml/src/ggml-cann/common.h @@ -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); } } diff --git a/skills/cann_multi_stream_implementation.md b/skills/cann_multi_stream_implementation.md deleted file mode 100644 index f481167156..0000000000 --- a/skills/cann_multi_stream_implementation.md +++ /dev/null @@ -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. **添加头文件**: - - `` - 用于 `std::find` - - `` - 用于 `std::set` - - `` - 用于 `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. **环境变量调优**:添加更细粒度的控制参数