已合并
更正verl_npu文档 #716
humphrey0007创建于 2025年10月28日
更正verl_npu文档 #716
已合并
共 3 个文件变更+0-1299
Drl-plugin/docs/module_alias_feature.md+0-221
| @@ -1,221 +0,0 @@ | |||
| 1 | -# Module Alias 特性 | ||
| 2 | - | ||
| 3 | -Module Alias 是 NPU 插件框架的一个核心特性,提供了在运行时对注入模块别名alias替换的能力。该特性允许您将本地模块映射到外部包的命名空间中,使得上游包能够透明地访问您的本地实现,而无需修改其源代码。 | ||
| 4 | - | ||
| 5 | -## 特性概述 | ||
| 6 | - | ||
| 7 | -Module Alias 特性解决了在集成 NPU 支持时需要提供缺失模块或替换现有模块的问题。通过这个特性,您可以: | ||
| 8 | - | ||
| 9 | -- **透明模块替换**:将本地模块注入到外部包命名空间 | ||
| 10 | -- **依赖解耦**:避免修改上游包的导入语句 | ||
| 11 | -- **动态注入**:运行时决定模块映射关系 | ||
| 12 | -- **批量处理**:支持批量注入多个模块别名 | ||
| 13 | - | ||
| 14 | -## 核心组件 | ||
| 15 | - | ||
| 16 | -### 模块别名注入函数 | ||
| 17 | - | ||
| 18 | -```python | ||
| 19 | -from verl_npu.core import inject_module_alias | ||
| 20 | - | ||
| 21 | -# 注入单个模块别名 | ||
| 22 | -success = inject_module_alias( | ||
| 23 | - source_module_name="verl_npu.workers.custom_worker", | ||
| 24 | - target_module_name="verl.workers.custom_worker" | ||
| 25 | -) | ||
| 26 | -``` | ||
| 27 | - | ||
| 28 | -### 批量注入函数 | ||
| 29 | - | ||
| 30 | -```python | ||
| 31 | -from verl_npu.core import inject_module_aliases_batch | ||
| 32 | - | ||
| 33 | -# 批量注入多个模块别名 | ||
| 34 | -module_pairs = [ | ||
| 35 | - ("verl_npu.models.npu_model", "verl.models.npu_model"), | ||
| 36 | - ("verl_npu.optimizers.npu_optimizer", "verl.optimizers.npu_optimizer"), | ||
| 37 | -] | ||
| 38 | -inject_module_aliases_batch(module_pairs) | ||
| 39 | -``` | ||
| 40 | - | ||
| 41 | -### bootstrap函数 | ||
| 42 | - | ||
| 43 | -```python | ||
| 44 | -from verl_npu.core import bootstrap_default_aliases | ||
| 45 | - | ||
| 46 | -# 自动引导默认的模块别名 | ||
| 47 | -bootstrap_default_aliases() | ||
| 48 | -``` | ||
| 49 | - | ||
| 50 | -## 快速开始 | ||
| 51 | - | ||
| 52 | -### 基本用法 - 单个模块别名 | ||
| 53 | - | ||
| 54 | -```python | ||
| 55 | -from verl_npu.core import inject_module_alias | ||
| 56 | - | ||
| 57 | -# 场景:上游包期望 verl.workers.npu_worker 模块存在 | ||
| 58 | -# 但我们的实现在 verl_npu.workers.npu_worker | ||
| 59 | - | ||
| 60 | -# 注入模块别名 | ||
| 61 | -success = inject_module_alias( | ||
| 62 | - source_module_name="verl_npu.workers.npu_worker", | ||
| 63 | - target_module_name="verl.workers.npu_worker" | ||
| 64 | -) | ||
| 65 | - | ||
| 66 | -if success: | ||
| 67 | - print("Module alias injected successfully") | ||
| 68 | - | ||
| 69 | - # 现在上游包可以正常导入 | ||
| 70 | - from verl.workers.npu_worker import NPUWorker # 实际来自 verl_npu | ||
| 71 | - | ||
| 72 | - worker = NPUWorker() | ||
| 73 | - worker.start() | ||
| 74 | -``` | ||
| 75 | - | ||
| 76 | -### 批量模块别名注入 | ||
| 77 | - | ||
| 78 | -```python | ||
| 79 | -from verl_npu.core import inject_module_aliases_batch | ||
| 80 | - | ||
| 81 | -# 定义多个模块映射关系 | ||
| 82 | -module_mappings = [ | ||
| 83 | - # (源模块, 目标模块) | ||
| 84 | - ("verl_npu.workers.sharding_manager.hybrid_tp_config", | ||
| 85 | - "verl.workers.sharding_manager.hybrid_tp_config"), | ||
| 86 | - | ||
| 87 | - ("verl_npu.models.npu_models", | ||
| 88 | - "verl.models.npu_models"), | ||
| 89 | - | ||
| 90 | - ("verl_npu.optimizers.npu_optimizers", | ||
| 91 | - "verl.optimizers.npu_optimizers"), | ||
| 92 | - | ||
| 93 | - ("verl_npu.utils.npu_utils", | ||
| 94 | - "verl.utils.npu_utils"), | ||
| 95 | -] | ||
| 96 | - | ||
| 97 | -# 批量注入 | ||
| 98 | -try: | ||
| 99 | - inject_module_aliases_batch(module_mappings) | ||
| 100 | - print("All module aliases injected successfully") | ||
| 101 | -except RuntimeError as e: | ||
| 102 | - print(f"Failed to inject module aliases: {e}") | ||
| 103 | -``` | ||
| 104 | - | ||
| 105 | -## 如何进行别名替换 | ||
| 106 | - | ||
| 107 | -### 在`bootstrap_default_aliases`添加 | ||
| 108 | - | ||
| 109 | -```python | ||
| 110 | -# verl_npu/module_injection.py 中的实现 | ||
| 111 | -def bootstrap_default_aliases(): | ||
| 112 | - """引导默认的模块别名""" | ||
| 113 | - | ||
| 114 | - package_root = __name__.split('.')[0] # 'verl_npu' | ||
| 115 | - | ||
| 116 | - # 定义所有默认的模块别名对 | ||
| 117 | - module_pairs = [ | ||
| 118 | - # 核心工作组件 | ||
| 119 | - (f"{package_root}.workers.sharding_manager.hybrid_tp_config", | ||
| 120 | - "verl.workers.sharding_manager.hybrid_tp_config"), | ||
| 121 | - | ||
| 122 | - # NPU特定模块 | ||
| 123 | - (f"{package_root}.models.npu_models", | ||
| 124 | - "verl.models.npu_models"), | ||
| 125 | - | ||
| 126 | - # 添加更多默认映射... | ||
| 127 | - ] | ||
| 128 | - | ||
| 129 | - inject_module_aliases_batch(module_pairs) | ||
| 130 | -``` | ||
| 131 | - | ||
| 132 | -## 与插件系统集成 | ||
| 133 | - | ||
| 134 | -### 在`__init__`中提早初始化 | ||
| 135 | - | ||
| 136 | -```python | ||
| 137 | -# verl_npu/__init__.py | ||
| 138 | -from verl_npu.core import bootstrap_default_aliases | ||
| 139 | - | ||
| 140 | -def _initialize_npu_plugin(): | ||
| 141 | - """初始化NPU插件""" | ||
| 142 | - | ||
| 143 | - # 第一步:引导模块别名替换(必须最早执行) | ||
| 144 | - bootstrap_default_aliases() | ||
| 145 | - | ||
| 146 | - # 第二步:应用其他patch | ||
| 147 | - from verl_npu.plugin import apply_npu_plugin | ||
| 148 | - apply_npu_plugin() | ||
| 149 | - | ||
| 150 | -# 模块导入时立即初始化,防止patch模块加载的时候冲突 | ||
| 151 | -_initialize_npu_plugin() | ||
| 152 | -``` | ||
| 153 | - | ||
| 154 | -## 最佳实践 | ||
| 155 | - | ||
| 156 | -### 1. 命名约定 | ||
| 157 | - | ||
| 158 | -```python | ||
| 159 | -# 保持一致的命名模式 | ||
| 160 | -source_pattern = "verl_npu.{category}.{module_name}" | ||
| 161 | -target_pattern = "verl.{category}.{module_name}" | ||
| 162 | - | ||
| 163 | -# 例如: | ||
| 164 | -# verl_npu.models.transformer_model -> verl.models.transformer_model | ||
| 165 | -# verl_npu.workers.npu_worker -> verl.workers.npu_worker | ||
| 166 | -``` | ||
| 167 | - | ||
| 168 | -### 2. 模块组织 | ||
| 169 | - | ||
| 170 | -```python | ||
| 171 | -# 按功能分组模块别名 | ||
| 172 | -def setup_feature_based_aliases(): | ||
| 173 | - """按功能分组设置模块别名""" | ||
| 174 | - | ||
| 175 | - feature_groups = { | ||
| 176 | - "core": [ | ||
| 177 | - ("verl_npu.core.context", "verl.core.context"), | ||
| 178 | - ("verl_npu.core.device", "verl.core.device"), | ||
| 179 | - ], | ||
| 180 | - "models": [ | ||
| 181 | - ("verl_npu.models.base", "verl.models.base"), | ||
| 182 | - ("verl_npu.models.transformer", "verl.models.transformer"), | ||
| 183 | - ], | ||
| 184 | - "training": [ | ||
| 185 | - ("verl_npu.training.trainer", "verl.training.trainer"), | ||
| 186 | - ("verl_npu.training.optimizer", "verl.training.optimizer"), | ||
| 187 | - ] | ||
| 188 | - } | ||
| 189 | - | ||
| 190 | - for feature, modules in feature_groups.items(): | ||
| 191 | - print(f"Setting up {feature} module aliases...") | ||
| 192 | - try: | ||
| 193 | - inject_module_aliases_batch(modules) | ||
| 194 | - print(f"✓ {feature} aliases completed") | ||
| 195 | - except RuntimeError as e: | ||
| 196 | - print(f"✗ {feature} aliases failed: {e}") | ||
| 197 | -``` | ||
| 198 | - | ||
| 199 | -## 故障排除 | ||
| 200 | - | ||
| 201 | -### 常见问题 | ||
| 202 | - | ||
| 203 | -1. **模块已存在错误**: | ||
| 204 | -```python | ||
| 205 | -# 如果目标模块已存在,inject_module_alias 会直接返回 True | ||
| 206 | -# 这是正常行为,不是错误 | ||
| 207 | -``` | ||
| 208 | - | ||
| 209 | -2. **导入顺序问题**: | ||
| 210 | -```python | ||
| 211 | -# 确保在任何使用别名的导入之前注入别名 | ||
| 212 | -bootstrap_default_aliases() # 必须在这之前 | ||
| 213 | -from verl.workers.something import Something # 这之后 | ||
| 214 | -``` | ||
| 215 | - | ||
| 216 | -3. **符号不存在**: | ||
| 217 | -```python | ||
| 218 | -# 检查源模块是否真的包含指定的符号 | ||
| 219 | -import verl_npu.source_module | ||
| 220 | -print(dir(verl_npu.source_module)) # 查看可用符号 | ||
| 221 | -``` | ||
Drl-plugin/docs/module_patch_feature.md+0-511
| @@ -1,511 +0,0 @@ | |||
| 1 | -# Module Patch 特性 | ||
| 2 | - | ||
| 3 | -Module Patch 是 NPU 插件框架的一个核心特性,提供了一种干净的机制来动态扩展或修改现有的类和模块。该特性允许您在运行时向目标类或模块添加新的方法、属性和功能,而无需修改原始源代码。 | ||
| 4 | - | ||
| 5 | -## 特性概述 | ||
| 6 | - | ||
| 7 | -Module Patch 特性解决了在集成 NPU 支持时需要扩展外部类和模块功能的问题。通过这个特性,您可以: | ||
| 8 | - | ||
| 9 | -- **无侵入式扩展**:向现有类添加新方法和属性,无需修改原始代码 | ||
| 10 | -- **条件patch**:支持类级别和方法级别的条件装饰器 | ||
| 11 | -- **类型安全**:使用订阅语法指定目标,编译时类型检查 | ||
| 12 | -- **冲突检测**:自动检测重复patch,避免意外覆盖 | ||
| 13 | -- **完整追踪**:详细的patch摘要和日志记录 | ||
| 14 | -- **灵活应用**:支持类方法、静态方法、实例方法和属性 | ||
| 15 | - | ||
| 16 | -## 核心组件 | ||
| 17 | - | ||
| 18 | -### NPUPatchHelper 基类 | ||
| 19 | - | ||
| 20 | -```python | ||
| 21 | -from verl_npu.core import NPUPatchHelper | ||
| 22 | - | ||
| 23 | -class MyPatch(NPUPatchHelper[TargetClass]): | ||
| 24 | - # 添加新的属性和方法 | ||
| 25 | - new_field = "This will be added to TargetClass" | ||
| 26 | - | ||
| 27 | - def new_method(self): | ||
| 28 | - return "This method will be added to TargetClass" | ||
| 29 | - | ||
| 30 | - @classmethod | ||
| 31 | - def new_classmethod(cls): | ||
| 32 | - return "This classmethod will be added to TargetClass" | ||
| 33 | - | ||
| 34 | - @staticmethod | ||
| 35 | - def new_staticmethod(): | ||
| 36 | - return "This staticmethod will be added to TargetClass" | ||
| 37 | -``` | ||
| 38 | - | ||
| 39 | -### 条件patch装饰器 | ||
| 40 | - | ||
| 41 | -```python | ||
| 42 | -from verl_npu.core import conditional, is_torch_npu_available | ||
| 43 | - | ||
| 44 | -# 类级别条件patch | ||
| 45 | -@conditional(is_torch_npu_available) | ||
| 46 | -class NPUPatch(NPUPatchHelper[TargetClass]): | ||
| 47 | - def npu_method(self): | ||
| 48 | - return "Only patched when NPU is available" | ||
| 49 | - | ||
| 50 | -# 方法级别条件patch | ||
| 51 | -class MixedPatch(NPUPatchHelper[TargetClass]): | ||
| 52 | - def always_patched(self): | ||
| 53 | - return "Always patched" | ||
| 54 | - | ||
| 55 | - @conditional(lambda: os.environ.get("DEBUG", "0") == "1") | ||
| 56 | - def debug_method(self): | ||
| 57 | - return "Only patched in debug mode" | ||
| 58 | -``` | ||
| 59 | - | ||
| 60 | -## 快速开始 | ||
| 61 | - | ||
| 62 | -### 基本用法 - 扩展类 | ||
| 63 | - | ||
| 64 | -```python | ||
| 65 | -from verl_npu.core import NPUPatchHelper | ||
| 66 | - | ||
| 67 | -# 假设我们要扩展一个现有的模型类 | ||
| 68 | -from some_library import ModelClass | ||
| 69 | - | ||
| 70 | -class NPUModelPatch(NPUPatchHelper[ModelClass]): | ||
| 71 | - """为ModelClass添加NPU支持""" | ||
| 72 | - | ||
| 73 | - # 添加NPU相关属性 | ||
| 74 | - npu_enabled = True | ||
| 75 | - npu_device_count = 8 | ||
| 76 | - | ||
| 77 | - def enable_npu(self): | ||
| 78 | - """启用NPU加速""" | ||
| 79 | - self.npu_enabled = True | ||
| 80 | - print("NPU acceleration enabled") | ||
| 81 | - | ||
| 82 | - def get_npu_info(self): | ||
| 83 | - """获取NPU信息""" | ||
| 84 | - return { | ||
| 85 | - "enabled": self.npu_enabled, | ||
| 86 | - "device_count": self.npu_device_count | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | - @classmethod | ||
| 90 | - def create_npu_model(cls, config): | ||
| 91 | - """创建NPU优化的模型实例""" | ||
| 92 | - instance = cls(config) | ||
| 93 | - instance.enable_npu() | ||
| 94 | - return instance | ||
| 95 | - | ||
| 96 | -# 应用patch | ||
| 97 | -NPUModelPatch.apply_patch() | ||
| 98 | - | ||
| 99 | -# 现在可以使用新功能 | ||
| 100 | -model = ModelClass() | ||
| 101 | -model.enable_npu() # 新方法可用 | ||
| 102 | -print(model.get_npu_info()) # 新方法可用 | ||
| 103 | -npu_model = ModelClass.create_npu_model(config) # 新类方法可用 | ||
| 104 | -``` | ||
| 105 | - | ||
| 106 | -### 扩展模块 | ||
| 107 | - | ||
| 108 | -```python | ||
| 109 | -import some_module | ||
| 110 | -from verl_npu.core import NPUPatchHelper | ||
| 111 | - | ||
| 112 | -class NPUModulePatch(NPUPatchHelper[some_module]): | ||
| 113 | - """为模块添加NPU相关功能""" | ||
| 114 | - | ||
| 115 | - # 添加新常量 | ||
| 116 | - NPU_BACKEND = "ascend" | ||
| 117 | - NPU_PRECISION = "fp16" | ||
| 118 | - | ||
| 119 | - @staticmethod | ||
| 120 | - def get_npu_devices(): | ||
| 121 | - """获取可用的NPU设备""" | ||
| 122 | - return list(range(8)) # 假设有8个NPU设备 | ||
| 123 | - | ||
| 124 | - @staticmethod | ||
| 125 | - def init_npu_context(): | ||
| 126 | - """初始化NPU上下文""" | ||
| 127 | - print("Initializing NPU context...") | ||
| 128 | - return True | ||
| 129 | - | ||
| 130 | -# 应用patch | ||
| 131 | -NPUModulePatch.apply_patch() | ||
| 132 | - | ||
| 133 | -# 现在可以使用新功能 | ||
| 134 | -print(some_module.NPU_BACKEND) # 新常量可用 | ||
| 135 | -devices = some_module.get_npu_devices() # 新函数可用 | ||
| 136 | -some_module.init_npu_context() # 新函数可用 | ||
| 137 | -``` | ||
| 138 | - | ||
| 139 | -## 高级特性 | ||
| 140 | - | ||
| 141 | -### 1. 方法替换和扩展 | ||
| 142 | - | ||
| 143 | -```python | ||
| 144 | -class AdvancedPatch(NPUPatchHelper[TargetClass]): | ||
| 145 | - """高级patch示例:替换和扩展现有方法""" | ||
| 146 | - | ||
| 147 | - def __init__(self, *args, **kwargs): | ||
| 148 | - """扩展构造函数""" | ||
| 149 | - super().__init__(*args, **kwargs) | ||
| 150 | - self.npu_initialized = False | ||
| 151 | - | ||
| 152 | - def forward(self, x): | ||
| 153 | - """替换forward方法以支持NPU""" | ||
| 154 | - if hasattr(self, 'npu_enabled') and self.npu_enabled: | ||
| 155 | - # NPU加速的forward实现 | ||
| 156 | - return self._npu_forward(x) | ||
| 157 | - else: | ||
| 158 | - # 原始实现 | ||
| 159 | - return self._original_forward(x) | ||
| 160 | - | ||
| 161 | - def _npu_forward(self, x): | ||
| 162 | - """NPU优化的forward实现""" | ||
| 163 | - print("Using NPU accelerated forward") | ||
| 164 | - return x # 简化实现 | ||
| 165 | -``` | ||
| 166 | - | ||
| 167 | -### 2. 条件patch - 默认NPU检查 | ||
| 168 | - | ||
| 169 | -```python | ||
| 170 | -# NPUPatchHelper默认包含NPU可用性检查 | ||
| 171 | -class AutoNPUPatch(NPUPatchHelper[TargetClass]): | ||
| 172 | - """自动使用NPU可用性检查""" | ||
| 173 | - | ||
| 174 | - def enable_npu_training(self): | ||
| 175 | - """只有NPU可用时才会被patch""" | ||
| 176 | - return "NPU training enabled" | ||
| 177 | - | ||
| 178 | - def optimize_npu_memory(self): | ||
| 179 | - """NPU内存优化""" | ||
| 180 | - return "NPU memory optimized" | ||
| 181 | -``` | ||
| 182 | - | ||
| 183 | -### 3. 条件patch - 显式条件 | ||
| 184 | - | ||
| 185 | -```python | ||
| 186 | -from verl_npu.core import conditional, is_torch_npu_available | ||
| 187 | - | ||
| 188 | -@conditional(is_torch_npu_available) | ||
| 189 | -class ExplicitNPUPatch(NPUPatchHelper[TargetClass]): | ||
| 190 | - """显式指定NPU条件""" | ||
| 191 | - | ||
| 192 | - def advanced_npu_feature(self): | ||
| 193 | - return "Advanced NPU functionality" | ||
| 194 | - | ||
| 195 | -# 复杂条件组合 | ||
| 196 | -@conditional.all( | ||
| 197 | - is_torch_npu_available, | ||
| 198 | - lambda: os.environ.get("LARGE_MEMORY", "0") == "1" | ||
| 199 | -) | ||
| 200 | -class AdvancedNPUPatch(NPUPatchHelper[TargetClass]): | ||
| 201 | - """需要NPU可用且大内存""" | ||
| 202 | - | ||
| 203 | - def train_large_model(self): | ||
| 204 | - return "Training large model on NPU" | ||
| 205 | - | ||
| 206 | -# 方法级别条件 | ||
| 207 | -class MixedConditionalPatch(NPUPatchHelper[TargetClass]): | ||
| 208 | - """混合条件patch""" | ||
| 209 | - | ||
| 210 | - def basic_npu_method(self): | ||
| 211 | - """使用默认NPU条件""" | ||
| 212 | - return "Basic NPU method" | ||
| 213 | - | ||
| 214 | - @conditional(lambda: os.environ.get("EXPERIMENTAL", "0") == "1") | ||
| 215 | - def experimental_method(self): | ||
| 216 | - """实验性功能""" | ||
| 217 | - return "Experimental feature" | ||
| 218 | - | ||
| 219 | - @conditional(lambda: True) # 总是patch | ||
| 220 | - def always_available(self): | ||
| 221 | - """无条件patch""" | ||
| 222 | - return "Always available" | ||
| 223 | -``` | ||
| 224 | - | ||
| 225 | -## 条件patch特性 | ||
| 226 | - | ||
| 227 | -### 概述 | ||
| 228 | - | ||
| 229 | -条件patch允许您根据运行时条件决定是否应用patch,提供更灵活的NPU集成策略。 | ||
| 230 | - | ||
| 231 | -### 默认NPU条件 | ||
| 232 | - | ||
| 233 | -所有 `NPUPatchHelper` 子类默认包含NPU可用性检查: | ||
| 234 | - | ||
| 235 | -```python | ||
| 236 | -class AutoNPUPatch(NPUPatchHelper[TargetClass]): | ||
| 237 | - """默认只在NPU可用时应用""" | ||
| 238 | - | ||
| 239 | - def npu_method(self): | ||
| 240 | - return "NPU功能" | ||
| 241 | -``` | ||
| 242 | - | ||
| 243 | -### 条件装饰器语法 | ||
| 244 | - | ||
| 245 | -#### 1. 额外条件(默认行为) | ||
| 246 | - | ||
| 247 | -```python | ||
| 248 | -from verl_npu.core import conditional, is_torch_npu_available | ||
| 249 | - | ||
| 250 | -# 显式NPU条件 | ||
| 251 | -@conditional(is_torch_npu_available) | ||
| 252 | -class ExplicitNPUPatch(NPUPatchHelper[TargetClass]): | ||
| 253 | - """显式指定NPU条件 - NPU可用 AND 显式条件""" | ||
| 254 | - def npu_feature(self): | ||
| 255 | - return "NPU feature" | ||
| 256 | - | ||
| 257 | -# 自定义条件 | ||
| 258 | -@conditional(lambda: os.environ.get("ENABLE_EXPERIMENTAL", "0") == "1") | ||
| 259 | -class ExperimentalPatch(NPUPatchHelper[TargetClass]): | ||
| 260 | - """实验性功能 - NPU可用 AND 实验性功能启用""" | ||
| 261 | - def experimental_feature(self): | ||
| 262 | - return "Experimental feature" | ||
| 263 | - | ||
| 264 | -# 条件组合 | ||
| 265 | -@conditional.all( | ||
| 266 | - is_torch_npu_available, | ||
| 267 | - lambda: os.environ.get("LARGE_MEMORY", "0") == "1" | ||
| 268 | -) | ||
| 269 | -class AdvancedPatch(NPUPatchHelper[TargetClass]): | ||
| 270 | - """高级功能 - NPU可用 AND 大内存""" | ||
| 271 | - def advanced_feature(self): | ||
| 272 | - return "Advanced feature" | ||
| 273 | -``` | ||
| 274 | - | ||
| 275 | -#### 2. 替换默认条件 | ||
| 276 | - | ||
| 277 | -```python | ||
| 278 | -# 替换默认NPU条件,只用自定义条件 | ||
| 279 | -@conditional.only(lambda: os.environ.get("TEST_MODE", "0") == "1") | ||
| 280 | -class TestModePatch(NPUPatchHelper[TargetClass]): | ||
| 281 | - """测试模式patch - 替换默认NPU条件""" | ||
| 282 | - | ||
| 283 | - def test_method(self): | ||
| 284 | - return "Only added when TEST_MODE=1, ignoring NPU check" | ||
| 285 | - | ||
| 286 | - def mock_npu_method(self): | ||
| 287 | - return "Mock NPU method for testing" | ||
| 288 | - | ||
| 289 | -# 强制应用,忽略所有条件 | ||
| 290 | -@conditional.only(lambda: True) | ||
| 291 | -class ForceApplyPatch(NPUPatchHelper[TargetClass]): | ||
| 292 | - """强制应用,忽略所有条件""" | ||
| 293 | - | ||
| 294 | - def force_method(self): | ||
| 295 | - return "Always available, no conditions" | ||
| 296 | -``` | ||
| 297 | - | ||
| 298 | -#### 3. 条件类型对比 | ||
| 299 | - | ||
| 300 | -| 装饰器 | 检查逻辑 | 使用场景 | | ||
| 301 | -|--------|----------|----------| | ||
| 302 | -| 无装饰器 | 默认NPU条件 | 基本NPU依赖patch | | ||
| 303 | -| `@conditional` | 默认NPU条件 AND 额外条件 | 添加额外要求 | | ||
| 304 | -| `@conditional.only` | 只用自定义条件 | 替换NPU要求 | | ||
| 305 | - | ||
| 306 | -#### 方法级别条件 | ||
| 307 | - | ||
| 308 | -```python | ||
| 309 | -class MixedPatch(NPUPatchHelper[TargetClass]): | ||
| 310 | - """混合条件patch示例""" | ||
| 311 | - | ||
| 312 | - def default_npu_method(self): | ||
| 313 | - """使用默认NPU条件""" | ||
| 314 | - return "Default NPU method" | ||
| 315 | - | ||
| 316 | - @conditional(lambda: os.environ.get("DEBUG", "0") == "1") | ||
| 317 | - def debug_method(self): | ||
| 318 | - """调试模式专用""" | ||
| 319 | - return "Debug method" | ||
| 320 | - | ||
| 321 | - @conditional.any( | ||
| 322 | - lambda: os.environ.get("DEV", "0") == "1", | ||
| 323 | - lambda: os.environ.get("TEST", "0") == "1" | ||
| 324 | - ) | ||
| 325 | - def dev_test_method(self): | ||
| 326 | - """开发或测试环境""" | ||
| 327 | - return "Dev/Test method" | ||
| 328 | - | ||
| 329 | - @conditional.not_(lambda: os.environ.get("PRODUCTION", "0") == "1") | ||
| 330 | - def non_production_method(self): | ||
| 331 | - """非生产环境""" | ||
| 332 | - return "Non-production method" | ||
| 333 | - | ||
| 334 | - @conditional(lambda: True) # 总是应用 | ||
| 335 | - def always_method(self): | ||
| 336 | - """无条件应用""" | ||
| 337 | - return "Always available" | ||
| 338 | -``` | ||
| 339 | - | ||
| 340 | -### 条件组合语法 | ||
| 341 | - | ||
| 342 | -| 语法 | 说明 | 示例 | | ||
| 343 | -|------|------|------| | ||
| 344 | -| `@conditional(func)` | 单个额外条件 | `@conditional(is_torch_npu_available)` | | ||
| 345 | -| `@conditional.only(func)` | 替换默认条件 | `@conditional.only(test_mode)` | | ||
| 346 | -| `@conditional.all(f1, f2)` | 所有条件都满足 | `@conditional.all(npu_available, large_memory)` | | ||
| 347 | -| `@conditional.any(f1, f2)` | 任一条件满足 | `@conditional.any(debug_mode, test_mode)` | | ||
| 348 | -| `@conditional.not_(func)` | 条件不满足 | `@conditional.not_(production_mode)` | | ||
| 349 | -| `@conditional.only.all(f1, f2)` | 替换默认条件,所有条件满足 | `@conditional.only.all(test_mode, skip_npu)` | | ||
| 350 | - | ||
| 351 | -### 条件优先级 | ||
| 352 | - | ||
| 353 | -1. **方法级别条件** > **类级别条件** > **默认条件** | ||
| 354 | -2. 方法级别条件会覆盖类级别和默认条件 | ||
| 355 | -3. **`@conditional.only`** 会完全替换默认条件,而不是添加额外条件 | ||
| 356 | - | ||
| 357 | -### 条件patch日志 | ||
| 358 | - | ||
| 359 | -条件patch会在摘要中显示详细信息: | ||
| 360 | - | ||
| 361 | -```python | ||
| 362 | -from verl_npu.core import print_patch_summary | ||
| 363 | - | ||
| 364 | -print_patch_summary() | ||
| 365 | - | ||
| 366 | -# 输出示例: | ||
| 367 | -# ================ NPU Patch Summary ================ | ||
| 368 | -# 1. Target: some_library.ModelClass | ||
| 369 | -# Patch : MyConditionalPatch | ||
| 370 | -# Class Condition: ConditionalPatch.all(is_torch_npu_available, <lambda>) | ||
| 371 | -# Changes: | ||
| 372 | -# - added callable npu_method | ||
| 373 | -# - added callable advanced_feature | ||
| 374 | -# Skipped Methods: ['debug_method', 'experimental_method'] | ||
| 375 | -# =================================================== | ||
| 376 | -``` | ||
| 377 | - | ||
| 378 | -## Patch 摘要和日志 | ||
| 379 | - | ||
| 380 | -### 查看Patch摘要 | ||
| 381 | - | ||
| 382 | -```python | ||
| 383 | -from verl_npu.core import print_patch_summary, get_patch_summary | ||
| 384 | - | ||
| 385 | -# 应用所有patch后,查看摘要 | ||
| 386 | -print_patch_summary() | ||
| 387 | - | ||
| 388 | -# 输出示例: | ||
| 389 | -# ================ NPU Patch Summary ================ | ||
| 390 | -# 1. Target: some_library.ModelClass | ||
| 391 | -# Patch : __main__.NPUModelPatch | ||
| 392 | -# Changes: | ||
| 393 | -# - added attribute npu_enabled | ||
| 394 | -# - added callable enable_npu | ||
| 395 | -# - added callable get_npu_info | ||
| 396 | -# - added classmethod create_npu_model | ||
| 397 | -# =================================================== | ||
| 398 | -``` | ||
| 399 | - | ||
| 400 | - | ||
| 401 | -## 与插件系统集成 | ||
| 402 | - | ||
| 403 | -### 1. 创建Module Patch文件 | ||
| 404 | - | ||
| 405 | -```python | ||
| 406 | -# npu_model_patches.py | ||
| 407 | -from verl_npu.core import NPUPatchHelper | ||
| 408 | -from target_library import ModelClass, TrainerClass | ||
| 409 | - | ||
| 410 | -class ModelNPUPatch(NPUPatchHelper[ModelClass]): | ||
| 411 | - def enable_npu_acceleration(self): | ||
| 412 | - self.use_npu = True | ||
| 413 | - | ||
| 414 | -class TrainerNPUPatch(NPUPatchHelper[TrainerClass]): | ||
| 415 | - def setup_npu_training(self): | ||
| 416 | - print("Setting up NPU training environment") | ||
| 417 | -``` | ||
| 418 | - | ||
| 419 | -### 2. 在插件中注册 | ||
| 420 | - | ||
| 421 | -```python | ||
| 422 | -# verl_npu/plugin.py | ||
| 423 | -def apply_npu_plugin(): | ||
| 424 | - # 应用module patch | ||
| 425 | - from .npu_model_patches import ModelNPUPatch, TrainerNPUPatch | ||
| 426 | - | ||
| 427 | - ModelNPUPatch.apply_patch() | ||
| 428 | - TrainerNPUPatch.apply_patch() | ||
| 429 | -``` | ||
| 430 | - | ||
| 431 | -## 最佳实践 | ||
| 432 | - | ||
| 433 | -### 1. 命名约定 | ||
| 434 | - | ||
| 435 | -- Patch类使用描述性名称:`ModelNPUPatch`、`OptimizerNPUPatch` | ||
| 436 | -- 方法名使用清晰的前缀:`npu_*`、`enable_*`、`setup_*` | ||
| 437 | -- 避免与原有方法名冲突 | ||
| 438 | - | ||
| 439 | -### 2. 组织结构 | ||
| 440 | - | ||
| 441 | -```python | ||
| 442 | -# 按功能组织patch | ||
| 443 | -class BaseNPUPatch(NPUPatchHelper): | ||
| 444 | - """基础NPU功能""" | ||
| 445 | - | ||
| 446 | - def _init_npu_base(self): | ||
| 447 | - self.npu_initialized = True | ||
| 448 | - | ||
| 449 | -class ModelNPUPatch(BaseNPUPatch[ModelClass]): | ||
| 450 | - """模型特定的NPU功能""" | ||
| 451 | - | ||
| 452 | - def enable_model_npu(self): | ||
| 453 | - self._init_npu_base() | ||
| 454 | - # 模型特定的NPU初始化 | ||
| 455 | -``` | ||
| 456 | - | ||
| 457 | - | ||
| 458 | -### 4. 测试和验证 | ||
| 459 | - | ||
| 460 | -```python | ||
| 461 | -# 验证patch是否正确应用 | ||
| 462 | -def verify_patches(): | ||
| 463 | - from verl_npu.core import get_patch_summary | ||
| 464 | - | ||
| 465 | - summary = get_patch_summary() | ||
| 466 | - expected_patches = ["ModelNPUPatch", "TrainerNPUPatch"] | ||
| 467 | - | ||
| 468 | - applied_patches = [entry["patch_class"] for entry in summary] | ||
| 469 | - | ||
| 470 | - for expected in expected_patches: | ||
| 471 | - if not any(expected in patch for patch in applied_patches): | ||
| 472 | - print(f"Warning: {expected} not found in applied patches") | ||
| 473 | -``` | ||
| 474 | - | ||
| 475 | -## 故障排除 | ||
| 476 | - | ||
| 477 | -### 常见问题 | ||
| 478 | - | ||
| 479 | -1. **重复Patch错误**: | ||
| 480 | -```python | ||
| 481 | -# 错误:ValueError: TargetClass.method_name is already patched | ||
| 482 | -# 解决:检查是否重复应用patch或方法名冲突 | ||
| 483 | -``` | ||
| 484 | - | ||
| 485 | -2. **目标类型错误**: | ||
| 486 | -```python | ||
| 487 | -# 错误:TypeError: NPUPatchHelper can only target a class or module | ||
| 488 | -# 解决:确保目标是类或模块,不是实例 | ||
| 489 | -``` | ||
| 490 | - | ||
| 491 | -3. **导入顺序问题**: | ||
| 492 | -```python | ||
| 493 | -# 确保在使用前导入目标类 | ||
| 494 | -from target_library import TargetClass # 必须在patch定义前 | ||
| 495 | -class MyPatch(NPUPatchHelper[TargetClass]): | ||
| 496 | - pass | ||
| 497 | -``` | ||
| 498 | - | ||
| 499 | -## 总结 | ||
| 500 | - | ||
| 501 | -Module Patch 特性提供了一个安全的机制来扩展现有的类和模块。通过类型安全的语法、条件patch支持、自动冲突检测和详细的运行时summary报告,简化了各种修改场景和验证。 | ||
| 502 | - | ||
| 503 | -- ✅ **类型安全**:校验语法和编译时检查 | ||
| 504 | -- ✅ **条件patch**:支持类级别和方法级别的条件装饰器 | ||
| 505 | -- ✅ **默认NPU检查**:自动检查NPU可用性,避免无效patch | ||
| 506 | -- ✅ **灵活条件组合**:支持 all、any、not 逻辑组合 | ||
| 507 | -- ✅ **冲突防护**:自动检测重复patch | ||
| 508 | -- ✅ **完整追踪**:详细的patch摘要和日志,包含条件信息 | ||
| 509 | -- ✅ **灵活扩展**:支持各种类型的方法和属性 | ||
| 510 | -- ✅ **无侵入式**:不修改原始源代码,运行时自动注入 | ||
| 511 | -- ✅ **易于调试**:丰富的错误信息和调试工具 | ||
Drl-plugin/docs/variable_patch_feature.md+0-567
| @@ -1,567 +0,0 @@ | |||
| 1 | -# Variable Patch 特性 | ||
| 2 | - | ||
| 3 | -Variable Patch 是 NPU 插件框架的一个核心特性,提供了一种优雅且类型安全的方式来在运行时修改外部模块中的变量(字典和列表)。在用户需要的场景下,可以修改第三方库中的配置字典或模型列表。 | ||
| 4 | - | ||
| 5 | -## 特性概述 | ||
| 6 | - | ||
| 7 | -Variable Patch 特性解决了在集成 NPU 支持时需要动态修改外部库配置的问题。通过这个特性,您可以: | ||
| 8 | - | ||
| 9 | -- **无侵入式集成**:无需修改外部库源码即可添加 NPU 支持 | ||
| 10 | -- **条件patch支持**:支持类级别条件装饰器,默认检查NPU可用性 | ||
| 11 | -- **类型安全**:为字典和列表操作提供独立的 API 和 Enum 支持 | ||
| 12 | -- **变量推断**:自动推断变量名称,生成有意义的运行时修改日志信息 | ||
| 13 | -- **双重语法支持**:既支持简洁的运算符语法,也支持明确的方法调用 | ||
| 14 | - | ||
| 15 | -## 核心组件 | ||
| 16 | - | ||
| 17 | -### 操作模式 Enum | ||
| 18 | - | ||
| 19 | -```python | ||
| 20 | -from verl_npu.core import DictMode, ListMode | ||
| 21 | - | ||
| 22 | -# 字典操作模式 | ||
| 23 | -class DictMode(Enum): | ||
| 24 | - MERGE = "merge" # 合并所有key(覆盖已存在的) | ||
| 25 | - ADD = "add" # 只添加新key(跳过已存在的) | ||
| 26 | - UPDATE = "update" # 只更新已存在的key(跳过新的) | ||
| 27 | - DELETE = "delete" # 删除指定的key | ||
| 28 | - REPLACE = "replace" # 替换整个字典内容 | ||
| 29 | - | ||
| 30 | -# 列表操作模式 | ||
| 31 | -class ListMode(Enum): | ||
| 32 | - EXTEND = "extend" # 添加项目到末尾(最常用) | ||
| 33 | - APPEND = "append" # 追加项目到末尾(与extend相同) | ||
| 34 | - PREPEND = "prepend" # 添加项目到开头 | ||
| 35 | - INSERT = "insert" # 在指定位置插入 | ||
| 36 | - REMOVE = "remove" # 移除指定项目 | ||
| 37 | - REPLACE = "replace" # 替换整个列表内容 | ||
| 38 | -``` | ||
| 39 | - | ||
| 40 | -### Patch 构建器 | ||
| 41 | - | ||
| 42 | -```python | ||
| 43 | -from verl_npu.core import NPUVariablePatcher, D, L | ||
| 44 | - | ||
| 45 | -# D() - 字典patch构建器 | ||
| 46 | -# L() - 列表patch构建器 | ||
| 47 | -``` | ||
| 48 | - | ||
| 49 | -## 快速开始 | ||
| 50 | - | ||
| 51 | -### 基本用法 - 默认NPU条件 | ||
| 52 | - | ||
| 53 | -```python | ||
| 54 | -from verl_npu.core import NPUVariablePatcher, D, L | ||
| 55 | - | ||
| 56 | -# 从外部模块导入目标变量 | ||
| 57 | -from some_module import CONFIG_DICT, MODEL_LIST | ||
| 58 | - | ||
| 59 | -# 定义NPU数据 | ||
| 60 | -npu_config = {"npu_enabled": True, "device_count": 8} | ||
| 61 | -npu_models = ["qwen-npu", "deepseek-npu"] | ||
| 62 | - | ||
| 63 | -class MyNPUPatch(NPUVariablePatcher): | ||
| 64 | - """默认只在NPU可用时应用patch""" | ||
| 65 | - # 运算符语法 - 最简洁 | ||
| 66 | - D(npu_config) >> CONFIG_DICT # 合并字典 | ||
| 67 | - L(npu_models) >> MODEL_LIST # 扩展列表 | ||
| 68 | - | ||
| 69 | -# 应用patch(只有NPU可用时才会实际修改变量) | ||
| 70 | -MyNPUPatch.apply_patch() | ||
| 71 | -``` | ||
| 72 | - | ||
| 73 | -### 条件patch用法 | ||
| 74 | - | ||
| 75 | -```python | ||
| 76 | -from verl_npu.core import conditional, is_torch_npu_available | ||
| 77 | - | ||
| 78 | -# 显式NPU条件 | ||
| 79 | -@conditional(is_torch_npu_available) | ||
| 80 | -class ExplicitNPUPatch(NPUVariablePatcher): | ||
| 81 | - npu_config = {"advanced_npu": True} | ||
| 82 | - D(npu_config) >> CONFIG_DICT | ||
| 83 | - | ||
| 84 | -# 自定义条件 | ||
| 85 | -@conditional(lambda: os.environ.get("EXPERIMENTAL", "0") == "1") | ||
| 86 | -class ExperimentalPatch(NPUVariablePatcher): | ||
| 87 | - experimental_config = {"experimental_features": True} | ||
| 88 | - D(experimental_config) >> CONFIG_DICT | ||
| 89 | - | ||
| 90 | -# 复杂条件组合 | ||
| 91 | -@conditional.all( | ||
| 92 | - is_torch_npu_available, | ||
| 93 | - lambda: os.environ.get("LARGE_MEMORY", "0") == "1" | ||
| 94 | -) | ||
| 95 | -class AdvancedPatch(NPUVariablePatcher): | ||
| 96 | - advanced_config = {"large_model_support": True} | ||
| 97 | - D(advanced_config) >> CONFIG_DICT | ||
| 98 | -``` | ||
| 99 | - | ||
| 100 | -### 显式方法调用 | ||
| 101 | - | ||
| 102 | -```python | ||
| 103 | -class MyNPUPatch(NPUVariablePatcher): | ||
| 104 | - # 显式方法 - 更具描述性 | ||
| 105 | - D(npu_config, "NPU配置").merge_into(CONFIG_DICT) | ||
| 106 | - L(npu_models, "NPU模型").extend_to(MODEL_LIST) | ||
| 107 | -``` | ||
| 108 | - | ||
| 109 | -## API 参考 | ||
| 110 | - | ||
| 111 | -### 字典操作 | ||
| 112 | - | ||
| 113 | -| 方法 | 运算符 | Enum | 描述 | | ||
| 114 | -|------|--------|------|------| | ||
| 115 | -| `.merge_into(target)` | `>>` | `DictMode.MERGE` | 合并所有key(覆盖已存在的) | | ||
| 116 | -| `.add_to(target)` | `+` | `DictMode.ADD` | 只添加新key(跳过已存在的) | | ||
| 117 | -| `.update_in(target)` | `\|` | `DictMode.UPDATE` | 只更新已存在的key(跳过新的) | | ||
| 118 | -| `.replace_in(target)` | `<<` | `DictMode.REPLACE` | 替换整个字典内容 | | ||
| 119 | - | ||
| 120 | -### 列表操作 | ||
| 121 | - | ||
| 122 | -| 方法 | 运算符 | Enum | 描述 | | ||
| 123 | -|------|--------|------|------| | ||
| 124 | -| `.extend_to(target)` | `>>` | `ListMode.EXTEND` | 添加项目到末尾(最常用) | | ||
| 125 | -| `.append_to(target)` | `+` | `ListMode.APPEND` | 追加项目到末尾 | | ||
| 126 | -| `.prepend_to(target)` | `*` | `ListMode.PREPEND` | 添加项目到开头 | | ||
| 127 | -| `.insert_at(target, index)` | - | `ListMode.INSERT` | 在指定位置插入 | | ||
| 128 | -| `.remove_from(target)` | `-` | `ListMode.REMOVE` | 从列表中移除项目 | | ||
| 129 | -| `.replace_in(target)` | `<<` | `ListMode.REPLACE` | 替换整个列表内容 | | ||
| 130 | - | ||
| 131 | - | ||
| 132 | -## 高级特性 | ||
| 133 | - | ||
| 134 | -### 1. 链式操作 | ||
| 135 | - | ||
| 136 | -将相同数据应用到多个目标: | ||
| 137 | - | ||
| 138 | -```python | ||
| 139 | -class ChainedPatch(NPUVariablePatcher): | ||
| 140 | - base_config = {"use_npu": True} | ||
| 141 | - | ||
| 142 | - # 链式多个操作 | ||
| 143 | - D(base_config) \ | ||
| 144 | - .merge_into(CONFIG_DICT) \ | ||
| 145 | - .add_to(FEATURE_FLAGS) \ | ||
| 146 | - .update_in(OPTIMIZER_CONFIG) | ||
| 147 | -``` | ||
| 148 | - | ||
| 149 | -### 2. 类型安全的 Enum 使用 | ||
| 150 | - | ||
| 151 | -```python | ||
| 152 | -from verl_npu.core import DictMode, ListMode, PatchOperation | ||
| 153 | - | ||
| 154 | -# 直接使用Enum获得最佳类型安全 | ||
| 155 | -op = PatchOperation(npu_config, target_dict, DictMode.MERGE) | ||
| 156 | -op.apply() | ||
| 157 | -``` | ||
| 158 | - | ||
| 159 | -### 3. 智能变量名推断 | ||
| 160 | - | ||
| 161 | -Variable Patch 特性会自动推断变量名称并生成有意义的日志: | ||
| 162 | - | ||
| 163 | -```python | ||
| 164 | -npu_configuration = {"npu_enabled": True} | ||
| 165 | -model_list = ["qwen-npu"] | ||
| 166 | - | ||
| 167 | -class SmartPatch(NPUVariablePatcher): | ||
| 168 | - D(npu_configuration) >> DEFAULT_CONFIG | ||
| 169 | - L(model_list) >> SUPPORTED_MODELS | ||
| 170 | - | ||
| 171 | -# 自动生成的日志: | ||
| 172 | -# ✓ Merge npu_configuration -> DEFAULT_CONFIG | ||
| 173 | -# ✓ Extend model_list -> SUPPORTED_MODELS | ||
| 174 | -``` | ||
| 175 | - | ||
| 176 | -## 条件patch特性 | ||
| 177 | - | ||
| 178 | -### 概述 | ||
| 179 | - | ||
| 180 | -Variable Patch 支持类级别的条件patch,允许您根据运行时条件决定是否应用整个变量patch类。这为NPU集成提供了更灵活的策略。 | ||
| 181 | - | ||
| 182 | -### 默认NPU条件 | ||
| 183 | - | ||
| 184 | -所有 `NPUVariablePatcher` 子类默认包含NPU可用性检查: | ||
| 185 | - | ||
| 186 | -```python | ||
| 187 | -class AutoNPUPatch(NPUVariablePatcher): | ||
| 188 | - """默认只在NPU可用时应用""" | ||
| 189 | - | ||
| 190 | - npu_config = {"npu_enabled": True, "device_count": 8} | ||
| 191 | - npu_models = ["qwen2-npu", "deepseek-npu"] | ||
| 192 | - | ||
| 193 | - D(npu_config) >> CONFIG_DICT | ||
| 194 | - L(npu_models) >> MODEL_LIST | ||
| 195 | - | ||
| 196 | -# 只有NPU可用时才会应用这些变量修改 | ||
| 197 | -AutoNPUPatch.apply_patch() | ||
| 198 | -``` | ||
| 199 | - | ||
| 200 | -### 条件装饰器语法 | ||
| 201 | - | ||
| 202 | -#### 1. 额外条件(默认行为) | ||
| 203 | - | ||
| 204 | -```python | ||
| 205 | -from verl_npu.core import conditional, is_torch_npu_available | ||
| 206 | - | ||
| 207 | -@conditional(is_torch_npu_available) | ||
| 208 | -class ExplicitNPUPatch(NPUVariablePatcher): | ||
| 209 | - """显式指定NPU条件 - NPU可用 AND 显式条件""" | ||
| 210 | - | ||
| 211 | - advanced_npu_config = { | ||
| 212 | - "npu_optimization_level": 2, | ||
| 213 | - "npu_memory_pool": "large" | ||
| 214 | - } | ||
| 215 | - | ||
| 216 | - D(advanced_npu_config) >> CONFIG_DICT | ||
| 217 | -``` | ||
| 218 | - | ||
| 219 | -#### 2. 替换默认条件 | ||
| 220 | - | ||
| 221 | -```python | ||
| 222 | -@conditional.only(lambda: os.environ.get("TEST_MODE", "0") == "1") | ||
| 223 | -class TestModePatch(NPUVariablePatcher): | ||
| 224 | - """替换默认NPU条件 - 只用测试模式条件""" | ||
| 225 | - | ||
| 226 | - test_config = { | ||
| 227 | - "test_mode": True, | ||
| 228 | - "mock_npu": True, | ||
| 229 | - "skip_npu_check": True | ||
| 230 | - } | ||
| 231 | - | ||
| 232 | - D(test_config) >> CONFIG_DICT | ||
| 233 | -``` | ||
| 234 | - | ||
| 235 | -#### 3. 条件类型对比 | ||
| 236 | - | ||
| 237 | -| 装饰器 | 检查逻辑 | 使用场景 | | ||
| 238 | -|--------|----------|----------| | ||
| 239 | -| 无装饰器 | 默认NPU条件 | 基本NPU依赖patch | | ||
| 240 | -| `@conditional` | 默认NPU条件 AND 额外条件 | 添加额外要求 | | ||
| 241 | -| `@conditional.only` | 只用自定义条件 | 替换NPU要求 | | ||
| 242 | - | ||
| 243 | -#### 自定义条件 | ||
| 244 | - | ||
| 245 | -```python | ||
| 246 | -@conditional(lambda: os.environ.get("ENABLE_EXPERIMENTAL", "0") == "1") | ||
| 247 | -class ExperimentalPatch(NPUVariablePatcher): | ||
| 248 | - """实验性功能patch""" | ||
| 249 | - | ||
| 250 | - experimental_features = { | ||
| 251 | - "flash_attention": True, | ||
| 252 | - "gradient_checkpointing": True | ||
| 253 | - } | ||
| 254 | - | ||
| 255 | - experimental_models = ["experimental-model-v1", "beta-model"] | ||
| 256 | - | ||
| 257 | - D(experimental_features) >> CONFIG_DICT | ||
| 258 | - L(experimental_models) >> MODEL_LIST | ||
| 259 | -``` | ||
| 260 | - | ||
| 261 | -#### 条件组合 | ||
| 262 | - | ||
| 263 | -```python | ||
| 264 | -@conditional.all( | ||
| 265 | - is_torch_npu_available, | ||
| 266 | - lambda: os.environ.get("LARGE_MEMORY", "0") == "1" | ||
| 267 | -) | ||
| 268 | -class LargeModelPatch(NPUVariablePatcher): | ||
| 269 | - """大模型支持patch - 需要NPU且大内存""" | ||
| 270 | - | ||
| 271 | - large_model_config = { | ||
| 272 | - "model_parallel": True, | ||
| 273 | - "pipeline_parallel": True, | ||
| 274 | - "memory_efficient_attention": True | ||
| 275 | - } | ||
| 276 | - | ||
| 277 | - large_models = ["qwen2-72b-npu", "deepseek-67b-npu"] | ||
| 278 | - | ||
| 279 | - D(large_model_config) >> CONFIG_DICT | ||
| 280 | - L(large_models) >> MODEL_LIST | ||
| 281 | - | ||
| 282 | -@conditional.any( | ||
| 283 | - lambda: os.environ.get("DEBUG", "0") == "1", | ||
| 284 | - lambda: os.environ.get("DEV_MODE", "0") == "1" | ||
| 285 | -) | ||
| 286 | -class DevPatch(NPUVariablePatcher): | ||
| 287 | - """开发模式patch - NPU可用 AND (DEBUG=1 OR DEV_MODE=1)""" | ||
| 288 | - | ||
| 289 | - dev_config = { | ||
| 290 | - "debug_mode": True, | ||
| 291 | - "verbose_logging": True | ||
| 292 | - } | ||
| 293 | - | ||
| 294 | - D(dev_config) >> CONFIG_DICT | ||
| 295 | - | ||
| 296 | -# 替换默认条件的开发模式patch | ||
| 297 | -@conditional.only(lambda: os.environ.get("DEV_MODE", "0") == "1") | ||
| 298 | -class DevOnlyPatch(NPUVariablePatcher): | ||
| 299 | - """开发模式patch - 只用DEV_MODE条件,忽略NPU检查""" | ||
| 300 | - | ||
| 301 | - dev_only_config = { | ||
| 302 | - "dev_mode": True, | ||
| 303 | - "assume_npu_available": True, | ||
| 304 | - "skip_npu_check": True | ||
| 305 | - } | ||
| 306 | - | ||
| 307 | - D(dev_only_config) >> CONFIG_DICT | ||
| 308 | - | ||
| 309 | -@conditional.not_(lambda: os.environ.get("PRODUCTION", "0") == "1") | ||
| 310 | -class NonProductionPatch(NPUVariablePatcher): | ||
| 311 | - """非生产环境patch""" | ||
| 312 | - | ||
| 313 | - test_config = { | ||
| 314 | - "test_mode": True, | ||
| 315 | - "mock_data": True | ||
| 316 | - } | ||
| 317 | - | ||
| 318 | - D(test_config) >> CONFIG_DICT | ||
| 319 | -``` | ||
| 320 | - | ||
| 321 | -### 条件组合语法 | ||
| 322 | - | ||
| 323 | -| 语法 | 说明 | 示例 | | ||
| 324 | -|------|------|------| | ||
| 325 | -| `@conditional(func)` | 单个条件 | `@conditional(is_torch_npu_available)` | | ||
| 326 | -| `@conditional.all(f1, f2)` | 所有条件都满足 | `@conditional.all(npu_available, large_memory)` | | ||
| 327 | -| `@conditional.any(f1, f2)` | 任一条件满足 | `@conditional.any(debug_mode, dev_mode)` | | ||
| 328 | -| `@conditional.not_(func)` | 条件不满足 | `@conditional.not_(production_mode)` | | ||
| 329 | - | ||
| 330 | -### 替换默认条件 | ||
| 331 | - | ||
| 332 | -#### 使用 @conditional.only | ||
| 333 | - | ||
| 334 | -`@conditional.only` 允许您完全替换默认的NPU条件检查,而不是添加额外条件: | ||
| 335 | - | ||
| 336 | -```python | ||
| 337 | -# 替换默认NPU条件,只用自定义条件 | ||
| 338 | -@conditional.only(lambda: os.environ.get("TEST_MODE", "0") == "1") | ||
| 339 | -class TestModePatch(NPUVariablePatcher): | ||
| 340 | - """测试模式patch - 替换默认NPU条件""" | ||
| 341 | - | ||
| 342 | - test_config = { | ||
| 343 | - "test_mode": True, | ||
| 344 | - "mock_npu": True, | ||
| 345 | - "skip_npu_check": True | ||
| 346 | - } | ||
| 347 | - | ||
| 348 | - D(test_config) >> CONFIG_DICT | ||
| 349 | -``` | ||
| 350 | - | ||
| 351 | -#### 条件类型对比 | ||
| 352 | - | ||
| 353 | -| 装饰器 | 检查逻辑 | 使用场景 | | ||
| 354 | -|--------|----------|----------| | ||
| 355 | -| 无装饰器 | 默认NPU条件 | 基本NPU依赖patch | | ||
| 356 | -| `@conditional` | 默认NPU条件 AND 额外条件 | 添加额外要求 | | ||
| 357 | -| `@conditional.only` | 只用自定义条件 | 替换NPU要求 | | ||
| 358 | - | ||
| 359 | -#### 实际应用示例 | ||
| 360 | - | ||
| 361 | -```python | ||
| 362 | -# 1. 测试环境:替换NPU检查 | ||
| 363 | -@conditional.only(lambda: os.environ.get("TEST_MODE") == "1") | ||
| 364 | -class TestingNPUPatch(NPUVariablePatcher): | ||
| 365 | - """测试时替换NPU检查""" | ||
| 366 | - | ||
| 367 | - test_npu_config = { | ||
| 368 | - "npu_enabled": True, # 测试时模拟NPU可用 | ||
| 369 | - "npu_device_count": 1, # 测试环境使用较少设备 | ||
| 370 | - "test_mode": True | ||
| 371 | - } | ||
| 372 | - | ||
| 373 | - D(test_npu_config) >> CONFIG_DICT | ||
| 374 | - | ||
| 375 | -# 2. 开发环境:替换NPU检查 | ||
| 376 | -@conditional.only(lambda: os.environ.get("DEV_MODE") == "1") | ||
| 377 | -class DevelopmentNPUPatch(NPUVariablePatcher): | ||
| 378 | - """开发时替换NPU检查""" | ||
| 379 | - | ||
| 380 | - dev_npu_config = { | ||
| 381 | - "npu_enabled": True, # 开发时假设NPU可用 | ||
| 382 | - "dev_mode": True, | ||
| 383 | - "assume_npu_available": True | ||
| 384 | - } | ||
| 385 | - | ||
| 386 | - D(dev_npu_config) >> CONFIG_DICT | ||
| 387 | - | ||
| 388 | -# 3. 强制应用:总是应用 | ||
| 389 | -@conditional.only(lambda: True) | ||
| 390 | -class ForceApplyPatch(NPUVariablePatcher): | ||
| 391 | - """强制应用,忽略所有条件""" | ||
| 392 | - | ||
| 393 | - force_config = { | ||
| 394 | - "force_applied": True, | ||
| 395 | - "ignore_all_conditions": True | ||
| 396 | - } | ||
| 397 | - | ||
| 398 | - D(force_config) >> CONFIG_DICT | ||
| 399 | -``` | ||
| 400 | - | ||
| 401 | -#### 组合条件替换 | ||
| 402 | - | ||
| 403 | -```python | ||
| 404 | -# 替换默认条件,使用复杂条件组合 | ||
| 405 | -@conditional.only.all( | ||
| 406 | - lambda: os.environ.get("TEST_MODE") == "1", | ||
| 407 | - lambda: os.environ.get("SKIP_NPU_CHECK") == "1" | ||
| 408 | -) | ||
| 409 | -class ComplexTestPatch(NPUVariablePatcher): | ||
| 410 | - """复杂测试条件,替换默认NPU检查""" | ||
| 411 | - | ||
| 412 | - complex_config = { | ||
| 413 | - "test_mode": True, | ||
| 414 | - "skip_npu_check": True, | ||
| 415 | - "complex_condition": True | ||
| 416 | - } | ||
| 417 | - | ||
| 418 | - D(complex_config) >> CONFIG_DICT | ||
| 419 | -``` | ||
| 420 | - | ||
| 421 | -### 实际应用场景 | ||
| 422 | - | ||
| 423 | -#### 环境相关patch | ||
| 424 | - | ||
| 425 | -```python | ||
| 426 | -@conditional(lambda: os.environ.get("ENV", "") == "development") | ||
| 427 | -class DevelopmentPatch(NPUVariablePatcher): | ||
| 428 | - dev_config = {"debug_logging": True} | ||
| 429 | - D(dev_config) >> CONFIG_DICT | ||
| 430 | - | ||
| 431 | -@conditional(lambda: os.environ.get("ENV", "") == "production") | ||
| 432 | -class ProductionPatch(NPUVariablePatcher): | ||
| 433 | - prod_config = {"performance_monitoring": True} | ||
| 434 | - D(prod_config) >> CONFIG_DICT | ||
| 435 | -``` | ||
| 436 | - | ||
| 437 | -#### 功能开关patch | ||
| 438 | - | ||
| 439 | -```python | ||
| 440 | -class FeatureFlagPatch(NPUVariablePatcher): | ||
| 441 | - """基于功能开关的条件patch""" | ||
| 442 | - | ||
| 443 | - # 基础NPU配置(使用默认NPU条件) | ||
| 444 | - base_npu_config = {"npu_enabled": True} | ||
| 445 | - D(base_npu_config) >> CONFIG_DICT | ||
| 446 | - | ||
| 447 | -@conditional(lambda: os.environ.get("ENABLE_MIXED_PRECISION", "0") == "1") | ||
| 448 | -class MixedPrecisionPatch(NPUVariablePatcher): | ||
| 449 | - mixed_precision_config = {"mixed_precision": True} | ||
| 450 | - D(mixed_precision_config) >> CONFIG_DICT | ||
| 451 | - | ||
| 452 | -@conditional(lambda: os.environ.get("ENABLE_FLASH_ATTENTION", "0") == "1") | ||
| 453 | -class FlashAttentionPatch(NPUVariablePatcher): | ||
| 454 | - flash_attention_config = {"flash_attention": True} | ||
| 455 | - D(flash_attention_config) >> CONFIG_DICT | ||
| 456 | -``` | ||
| 457 | - | ||
| 458 | -### 条件patch日志 | ||
| 459 | - | ||
| 460 | -条件patch会提供清晰的日志输出: | ||
| 461 | - | ||
| 462 | -```python | ||
| 463 | -# NPU不可用时 | ||
| 464 | -MyNPUPatch.apply_patch() | ||
| 465 | -# 输出: ⚠️ Skipped MyNPUPatch (conditions not met) | ||
| 466 | - | ||
| 467 | -# NPU可用时 | ||
| 468 | -MyNPUPatch.apply_patch() | ||
| 469 | -# 输出: | ||
| 470 | -# Applying MyNPUPatch... | ||
| 471 | -# ✓ MyNPUPatch completed (2 operations) | ||
| 472 | -``` | ||
| 473 | - | ||
| 474 | -## 与插件系统集成 | ||
| 475 | - | ||
| 476 | -### 1. 创建 patch 文件 | ||
| 477 | - | ||
| 478 | -```python | ||
| 479 | -# my_npu_patch.py | ||
| 480 | -from verl_npu.core import NPUVariablePatcher, D, L | ||
| 481 | -from target_module import TARGET_CONFIG | ||
| 482 | - | ||
| 483 | -class MyNPUPatch(NPUVariablePatcher): | ||
| 484 | - npu_config = {"npu_enabled": True} | ||
| 485 | - D(npu_config) >> TARGET_CONFIG | ||
| 486 | -``` | ||
| 487 | - | ||
| 488 | -### 2. 在插件中注册 | ||
| 489 | - | ||
| 490 | -```python | ||
| 491 | -# verl_npu/plugin.py | ||
| 492 | -def apply_npu_plugin(): | ||
| 493 | - # 现有的模块级patch... | ||
| 494 | - | ||
| 495 | - # 应用variable patch特性 | ||
| 496 | - from .my_npu_patch import MyNPUPatch | ||
| 497 | - MyNPUPatch.apply_patch() | ||
| 498 | -``` | ||
| 499 | - | ||
| 500 | -## 运算符语义表 | ||
| 501 | - | ||
| 502 | -### 字典操作语义 | ||
| 503 | - | ||
| 504 | -```python | ||
| 505 | -# 合并操作(最常用) | ||
| 506 | -D({"new_key": "value"}) >> target_dict | ||
| 507 | -# 等同于: target_dict.update({"new_key": "value"}) | ||
| 508 | - | ||
| 509 | -# 添加新key(跳过已存在) | ||
| 510 | -D({"new_key": "value"}) + target_dict | ||
| 511 | -# 等同于: 只添加target_dict中不存在的key | ||
| 512 | - | ||
| 513 | -# 更新已存在key(跳过新的) | ||
| 514 | -D({"existing_key": "new_value"}) | target_dict | ||
| 515 | -# 等同于: 只更新target_dict中已存在的key | ||
| 516 | - | ||
| 517 | -# 完全替换 | ||
| 518 | -D({"replace": "all"}) << target_dict | ||
| 519 | -# 等同于: target_dict.clear(); target_dict.update(...) | ||
| 520 | -``` | ||
| 521 | - | ||
| 522 | -### 列表操作语义 | ||
| 523 | - | ||
| 524 | -```python | ||
| 525 | -# 扩展到末尾(最常用) | ||
| 526 | -L(["item1", "item2"]) >> target_list | ||
| 527 | -# 等同于: target_list.extend(["item1", "item2"]) | ||
| 528 | - | ||
| 529 | -# 追加到末尾 | ||
| 530 | -L(["item1", "item2"]) + target_list | ||
| 531 | -# 等同于: target_list.extend(["item1", "item2"]) | ||
| 532 | - | ||
| 533 | -# 添加到开头 | ||
| 534 | -L(["item1", "item2"]) * target_list | ||
| 535 | -# 等同于: target_list[:0] = ["item1", "item2"] | ||
| 536 | - | ||
| 537 | -# 从列表移除 | ||
| 538 | -L(["item1", "item2"]) - target_list | ||
| 539 | -# 等同于: 从target_list中移除所有匹配的项目 | ||
| 540 | -``` | ||
| 541 | - | ||
| 542 | -## 类型安全和 IDE 支持 | ||
| 543 | - | ||
| 544 | -### Enum 的优势 | ||
| 545 | - | ||
| 546 | -1. **编译时类型检查**:IDE 可以在开发时检查类型错误 | ||
| 547 | -2. **自动完成**:输入 `DictMode.` 后 IDE 显示所有可用选项 | ||
| 548 | -3. **重构安全**:重命名 enum 值时 IDE 可以自动更新引用 | ||
| 549 | -4. **自文档化**:每个 enum 值都有清晰的注释说明 | ||
| 550 | -5. **更好的错误信息**:显示所有有效的模式选项 | ||
| 551 | - | ||
| 552 | -### 向后兼容 | ||
| 553 | - | ||
| 554 | -```python | ||
| 555 | -# 字符串模式仍然有效(向后兼容) | ||
| 556 | -D(data) >> target # 内部使用 DictMode.MERGE | ||
| 557 | - | ||
| 558 | -# 新的 Enum 模式(更好的类型安全) | ||
| 559 | -from verl_npu.core import DictMode | ||
| 560 | -PatchOperation(data, target, DictMode.MERGE) | ||
| 561 | -``` | ||
| 562 | - | ||
| 563 | -## 常见问题 | ||
| 564 | - | ||
| 565 | -1. **导入错误**: 确保在 patch 之前导入目标模块 | ||
| 566 | -2. **类型错误**: 始终为字典使用 `D()`,为列表使用 `L()` | ||
| 567 | -3. **无效果**: 检查目标变量是否是实际使用的对象 | ||