已合并
更正verl_npu文档 #716
humphrey0007创建于 2025年10月28日
更正verl_npu文档 #716
已合并
humphrey0007创建于 2025年10月28日
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. **无效果**: 检查目标变量是否是实际使用的对象