Data-Juicer开发者指南:从代码规范到自定义OP开发
前言
Data-Juicer是一个强大的数据处理工具,它提供了丰富的操作符(OP)来处理和优化数据集。本文将详细介绍如何为Data-Juicer项目贡献代码,包括代码规范、自定义OP开发以及配置系统使用指南。
代码规范与提交流程
在Data-Juicer项目中,我们使用pre-commit工具来确保代码质量的一致性。以下是设置和使用pre-commit的步骤:
- 首先安装pre-commit工具:
pip install pre-commit
- 在项目根目录下安装pre-commit钩子:
pre-commit install
- 在提交代码前运行检查:
git add .
pre-commit run --all-files
- 检查通过后提交代码:
git commit -m "你的提交信息"
这套机制会在代码提交前自动执行一系列检查,包括代码格式、语法规范等,确保代码库的一致性。
开发自定义操作符(OP)
Data-Juicer允许开发者创建自定义操作符来扩展其功能。下面我们以创建一个"文本长度过滤器"(TextLengthFilter)为例,详细介绍开发流程。
1. 定义统计键(可选)
如果新OP需要统计特定指标,可以在data_juicer/utils/constant.py
中添加对应的统计键:
class StatsKeys(object):
text_len = 'text_len' # 添加文本长度统计键
2. 创建OP类
在相应目录下创建新的OP文件,例如text_length_filter.py
:
from jsonargparse.typing import PositiveInt
from data_juicer.utils.constant import Fields, StatsKeys
from ..base_op import OPERATORS, Filter
@OPERATORS.register_module('text_length_filter')
class TextLengthFilter(Filter):
"""过滤文本长度在指定范围之外的样本"""
def __init__(self, min_len: PositiveInt = 10,
max_len: PositiveInt = sys.maxsize, *args, **kwargs):
super().__init__(*args, **kwargs)
self.min_len = min_len
self.max_len = max_len
def compute_stats(self, sample):
if StatsKeys.text_len not in sample[Fields.stats]:
sample[Fields.stats][StatsKeys.text_len] = len(sample[self.text_key])
return sample
def process(self, sample):
length = sample[Fields.stats][StatsKeys.text_len]
return self.min_len <= length <= self.max_len
3. 注册OP
在对应目录的__init__.py
中添加新OP的导入和注册:
from . import text_length_filter
from .text_length_filter import TextLengthFilter
__all__ = [..., 'text_length_filter']
4. 使用新OP
现在可以在配置文件中使用新创建的OP:
process:
- text_length_filter:
min_len: 10
max_len: 1000
5. 编写测试(强烈推荐)
为OP编写测试用例是保证质量的重要环节:
import unittest
from data_juicer.ops.filter.text_length_filter import TextLengthFilter
class TextLengthFilterTest(unittest.TestCase):
def test_length_filter(self):
# 测试用例实现
pass
6. 更新文档(强烈推荐)
为了让其他用户了解和使用你的OP,需要更新以下文档:
configs/config_all.yaml
- 添加OP及其参数说明docs/Operators.md
- 在对应类别中添加OP描述docs/Operators_ZH.md
- 更新中文文档
高级功能:OP融合
如果多个OP共享相同的计算过程,可以通过OP融合技术优化性能:
- 在
utils/constant.py
中定义中间变量:
class InterVars(object):
words = DEFAULT_PREFIX + 'words'
- 在
ops/op_fusion.py
中注册中间变量组:
INTER_WORDS = Registry(InterVars.words)
ALL_INTER_VARS = [..., INTER_WORDS]
- 在OP类上添加注册装饰器:
@OPERATORS.register_module('word_operation')
@INTER_WORDS.register_module('word_operation')
class WordOperation(Filter):
- 修改计算逻辑支持上下文共享:
words_key = f'{InterVars.words}-{self.model_key}'
if context and words_key in sample[Fields.context]:
words = sample[Fields.context][words_key]
else:
words = calculate_words(sample)
if context:
sample[Fields.context][words_key] = words
构建自定义配置
Data-Juicer使用jsonargparse实现灵活的配置系统,支持多种配置源:
- 硬编码默认值
- 配置文件(JSON/YAML/Jsonnet)
- 环境变量
- 命令行参数
配置支持类型提示和层级结构,可以通过点表示法定义复杂配置:
maximum_line_length_filter:
min: 10
max: 1000
系统会自动从操作符的docstring中提取帮助信息,可以通过--help
查看完整的配置帮助。
结语
本文详细介绍了在Data-Juicer项目中开发自定义操作符的完整流程,从代码规范到高级的OP融合技术。通过遵循这些指南,开发者可以有效地扩展Data-Juicer的功能,同时保持代码质量和性能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考