ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PEFT 测试套件完全指南:组织结构、公共测试矩阵与贡献规范(tests/README.md 深度解析)

PEFT 测试套件完全指南:组织结构、公共测试矩阵与贡献规范(tests/README.md 深度解析) PEFT 测试套件完全指南组织结构、公共测试矩阵与贡献规范tests/README.md 深度解析【免费下载链接】peft PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.项目地址: https://gitcode.com/gh_mirrors/pe/peft本篇指南以 PEFT 仓库中 tests/README.md 为核心骨架系统讲解 PEFT 测试套件的组织方式、PeftCommonTester公共测试矩阵的运行机制、GPU/量化测试与特殊套件的边界划分以及新增测试、新增 PEFT 方法时应遵循的放置规范与基础设施约定。读完本文你将掌握在 PEFT 中哪个测试该放哪里、如何复用共享基础设施、怎样保证测试在 CI 与本地都能快速稳定通过的完整方法论并能结合源码确认每个结论的落地位置。一、测试套件总览分层、矩阵与共享父类PEFT 的测试策略不是每个方法各写一套测试而是构建了一个共享测试矩阵common test matrix绝大多数覆盖率来自PeftCommonTester这个父类它位于 tests/testing_common.py其中所有以_test_*开头的方法检查的是每个 PEFT 方法都必须支持的通用行为。从源码看PeftCommonTestertesting_common.py定义了两个类属性torch_device通过infer_device()推断运行设备和transformers_class被测试的 Transformers 模型类并要求子类实现prepare_inputs_for_common()。其_test_*方法覆盖的行为包括但不限于模型与适配器属性_test_model_attr验证save_pretrained、from_pretrained、push_to_hub三个接口存在testing_common.py保存与加载_test_save_pretrained、_test_save_pretrained_selected_adapters、_test_save_pretrained_adapter_name_substring、_test_inference_safetensors分别位于 testing_common.py、testing_common.py、testing_common.py、testing_common.py合并merging_test_merge_layers、_test_merge_layers_fp16、_test_merge_layers_nan、_test_merge_layers_multi、_test_merge_layers_is_idempotenttesting_common.py训练_test_training、_test_training_layer_indexing、_test_training_gradient_checkpointing、_test_training_prompt_learning_taskstesting_common.py生成与推理_test_generate、_test_generate_pos_args、_test_generate_half_prec、_test_generate_with_mixed_adapter_batches_and_beam_search[testing_common.py](https://link.gitcode.com/i/d855c1648e9d41aa2818ceeda86cbafd#L983-L1108。以_test_generate为例testing_common.py其模式非常典型在hub_online_once(model_id)上下文中加载模型 → 用config_cls构建配置 →get_peft_model包装 → 移到self.torch_device→ 喂入prepare_inputs_for_testing()的输入并调用model.generate(**inputs)只要不抛异常即视为通过。这套统一模板正是整个矩阵能覆盖几十种 PEFT 方法而代码不爆炸的原因。这些矩阵由多个文件实例化每个文件针对一种模型类型内部维护模型 配置类 配置 kwargs的用例列表并用测试类参数化后委托给PeftCommonTester文件覆盖的模型类型特点tests/test_custom_models.py手工构造的小型torch.nn模型MLP、卷积网、RNN覆盖面最广、运行最快是新方法加入测试的第一站tests/test_decoder_models.py微型仅解码器Decoder-onlyTransformers 模型覆盖因果语言模型架构tests/test_encoder_decoder_models.py微型编码器-解码器模型覆盖 seq2seq 架构tests/test_feature_extraction_models.py微型特征提取模型覆盖嵌入/特征抽取场景tests/test_seq_classifier.py微型序列分类模型覆盖分类头场景从 test_custom_models.py 可以看到TEST_CASES的真实形态每个用例是(名称, 模型类型, 配置类, 配置kwargs)四元组例如(Vanilla MLP 1 LoRA, MLP, LoraConfig, {target_modules: lin0})、(Vanilla MLP 5 LoRA, MLP, LoraConfig, {target_modules: [lin0], modules_to_save: [lin1]})同一个模型会用不同的target_modules、lora_alpha、lora_dropout组合反复测试以覆盖参数解析的边界情况。关键结论凡是涉及所有方法共有的行为例如合并、保存相关的修复或新特性应修改PeftCommonTester让每个方法都接受该行为的回归验证。二、跨方法Cross-cutting特性测试按功能切分的独立文件不属于单一方法、而是横切整个库的功能各自拥有独立的测试文件。文档中给出的示例在仓库中全部可以找到tests/test_config.py所有方法的配置类往返序列化round-trippingtests/test_initialization.pyPEFT 模型初始化、适配器注入、模型校验tests/test_tuners_utils.py目标模块匹配target module matching逻辑tests/test_low_level_api.py底层 APItests/test_hub_features.pyHub 相关特性上传、下载、模型卡片。此外仓库中还有更多同类文件test_auto.pyAuto 类、test_mapping.py方法映射、test_helpers.py工具函数、test_mixed.py混合适配器、test_lora_conversion.py、test_arrow.py、test_incremental_pca.py、test_bufferdict.py、test_osf.py、test_torch_compile.py等。判断依据简单直接这个测试验证的是某个库功能而非某个方法就放进对应的跨切面文件只有确实无法归入现有文件时才新建文件。三、方法专属测试test_method.py的边界命名为test_method.py例如 tests/test_vera.py、tests/test_lora_variants.py、tests/test_bdlora.py的文件用于存放仅属于某一方法、无法用公共矩阵表达的行为典型如算法性质数学性质、初始化方式、参数生效条件。仓库中此类文件非常丰富test_adaption_prompt.py、test_boft.py、test_cartridge.py、test_cpt.py、test_deft.py、test_frod.py、test_lora_ga.py、test_lora_intruders.py、test_lora_megatron.py、test_lorafa.py、test_loraplus.py、test_randlora.py、test_riemannian_lora.py、test_shadow.py、test_shira.py、test_supertuning.py、test_unilora.py、test_vblora.py、test_velora.py、test_pvera.py、test_poly.py、test_multitask_prompt_tuning.py、test_trainable_tokens.py、test_adamss_asa.py、test_target_parameters.py等。注意文档给出的纪律只有在确认新测试无法放入现有测试之后才添加新的test_method.py文件。优先寻找结构相似的旧测试例如先前类似的 bug 修复把新测试放在它旁边。四、GPU 与量化测试硬件边界与标记体系需要加速器accelerator的测试被严格隔离避免破坏默认 CItests/test_gpu_examples.py端到端训练场景7200 余行的规模说明其覆盖面之大从导入可见它覆盖 QLoRA、LoftQ、HotSwap、EVA、Arrow、RoAD、VeRA、AdaGaLoRA 等多种方法以及 Whisper 等模型tests/test_common_gpu.py公共 GPU 测试tests/test_quantization.py使用通用 PEFT 量化后端的量化集成测试通过require_*装饰器门控。它们使用pytest.mark.single_gpu_tests或pytest.mark.multi_gpu_tests标记。这些测试不在 PR 的默认 CI 中运行而是在带 GPU runner 的 nightly 运行中执行。规则明确绝不要把需要 GPU 的测试放进 CPU 测试文件否则会拖垮常规 CI。三条硬性编写规范文档明确要求CPU 测试在加速器硬件上也应通过即 CPU 测试不能写死 CPU 特有假设GPU 测试应写成硬件无关hardware agnostic不要依赖 CUDA 专属特性仓库同样支持 XPU见 testing_utils.py 的require_non_xpu多 GPU 测试按恰好 2 张 GPU设计但在更多 GPU 时也不能失败。在 tests/testing_utils.py 中有一个DEVICE_MAP_MAP字典正是为满足第 3 条准备的为facebook/opt-6.7b、peft-internal-testing/opt-125m、google/flan-t5-base等模型显式指定 device map确保模型按层被加载到两个设备上例如model.decoder.layers.16到31被映射到设备 1并处理了lm_head与embed_tokens权重绑定的细节注释# tied with embed_tokens。Makefile 中可以看到这些测试的实际调度方式Makefiletests_examples_multi_gpu: python -m pytest -m multi_gpu_tests tests/test_gpu_examples.py tests_examples_single_gpu: python -m pytest -m single_gpu_tests tests/test_gpu_examples.py tests_core_multi_gpu: python -m pytest -m multi_gpu_tests tests/test_common_gpu.py tests_common_gpu: python -m pytest tests/test_decoder_models.py -k not gemma ...还提供了与 bitsandbytes 组合的变体-m multi_gpu_tests and bitsandbytes用于专门的 bnb runner。五、特殊套件回归测试与多进程训练测试两个目录用途特殊、单独运行绝大多数贡献者无需触碰regression/跨版本回归测试tests/regression/test_regression.py 用于验证旧版 PEFT 产出的 checkpoint 在当前版本下仍返回相同数值。运行方式为pytest tests/regression/test_regression.py -s --regression--regression是 tests/conftest.py 中通过pytest_addoption注册的自定义命令行选项配合pytest_collection_modifyitemsconftest.py不传--regression时所有带regression标记的测试会被自动跳过。创建新的回归测试时需要 Hub token 且会主动失败以保护制品完整性两个失败条件git worktree 是脏的当前 git commit 没有 tag。命令为HF_TOKENtoken REGRESSION_CREATION_MODETrue pytest tests/regression/test_regression.py -s --regression该模式下每个测试会在tests/regression/TEST_NAME/PEFT_VERSION/生成一个目录内含保存的适配器与该版本下的模型输出普通测试模式下则加载目录中每个版本的制品与当前输出对比。强制绕过检查可用REGRESSION_FORCE_MODETrue。建议先git checkout v0.x.x再运行确保制品对应某个已发布版本。4-bit 测试在 XPU 上运行时需设置PEFT_USE_XPUTrue。training/DeepSpeed / FSDP 多进程训练测试tests/training/ 下的多进程训练测试不经由 pytest 运行而是通过 Makefile 目标用accelerate launch启动相关配置包括deepspeed_config.yaml、fsdp_config.yaml、fsdp2_config.yaml、tp_config.yaml。tests/training/training.py 是一个 QLoRA 训练示例支持--quant 4bit/8bit、--target_modules、--target_parameters等参数并通过is_fsdp FSDP_VERSION in os.environ感知 FSDP 环境。Makefile 中的tests_training目标Makefile串起了完整矩阵tests_training: accelerate launch --config_file tests/training/deepspeed_config.yaml tests/training/training.py accelerate launch --config_file tests/training/deepspeed_config.yaml tests/training/training.py --quant 4bit accelerate launch --config_file tests/training/deepspeed_config.yaml tests/training/training.py --quant 8bit accelerate launch --config_file tests/training/fsdp_config.yaml tests/training/training.py accelerate launch --config_file tests/training/fsdp2_config.yaml tests/training/training.py --quant 4bit ... accelerate launch --config_file tests/training/tp_config.yaml tests/training/lora_tp.py此外tests_regression、tests_torch_compile等 Makefile 目标分别对应回归套件与 tests/test_torch_compile.py。六、新测试放哪里五步决策流程文档给出了清晰的决策树这里逐条落地测试的是所有或许多方法共有的行为→ 在PeftCommonTester中添加_test_*方法并在矩阵文件test_custom_models.py等中补充对应的参数化用例或扩展现有 battery 测试只属于某一个方法→ 放进test_method.py必要时新建文件涉及库级功能configs、保存、注入……→ 扩展对应的跨切面文件test_config.py、test_initialization.py等需要 GPU 或量化后端→ 放入test_gpu_examples.py/test_common_gpu.py/test_quantization.py并加上正确的 marker 或装饰器扩展现有测试类→ 放在同类测试方法旁边例如新的合并测试应跟在已有合并测试之后若没有相似方法则放在测试类末尾。同时有三条纪律不要添加矩阵已覆盖的独立测试脚本或新文件不确定时先搜索相似旧测试贡献者若修改 PEFT应优先遵循这些规则而非另起炉灶。新 PEFT 方法的完整测试路径当为 PEFT 添加一个新方法时覆盖率意味着加入现有矩阵而不是写独立套件顺序如下先在 tests/test_custom_models.py 的TEST_CASES与MULTIPLE_ACTIVE_ADAPTERS_TEST_CASES中加入用例——这一步覆盖大部分 PEFT 功能且迭代最快按方法的 task type 适用性向test_decoder_models.py、test_encoder_decoder_models.py、test_feature_extraction_models.py、test_seq_classifier.py等架构文件添加条目把配置类加入 tests/test_config.py 的ALL_CONFIG_CLASSES并在适用的地方加入 tests/test_initialization.py 的用例若方法支持量化扩展 tests/test_quantization.py只有真正方法专属的行为才写test_method.py。实用建议文档 Tip参考最近合并的、新增了 PEFT 方法的 PR以其中添加的测试作为最佳模板——仓库中test_adamss_asa.py、test_bdlora.py、test_cartridge.py、test_shira.py、test_supertuning.py等新近文件正是这类模板的体现。值得注意的是矩阵中并非所有方法都能一键全测。例如 testing_common.py 的_skip_if_merging_not_supported显示Prompt Learning、OSF、Lily、ShadowPEFT 等因不实现合并而跳过合并测试_skip_if_adding_weighted_adapters_not_supported表明只有 IA3 和 LoRA 支持带权适配器叠加Conv1D 类层仅 IA3/LoHa/LoKr/LoRA 支持testing_common.py。这些 skip 逻辑本身就是方法能力矩阵的活文档新方法接入矩阵时必须同步考虑。七、共享基础设施与约定testing_utils.py 深度拆解tests/testing_utils.py 是共享工具的集中地逐项说明如下hub_online_once让 CI 不打爆 HF Hubhub_online_once(model_id)testing_utils.py是一个上下文管理器允许某个模型 id 第一次联网下载之后强制进入离线模式从而捕获对同一模型的重复 Hub 访问避免 CI 反复请求 Hub。其实现要点通过全局字典_HUB_MODEL_ACCESSES记录每个 model id 的访问次数首次访问设计数为 0 并保持在线再次访问时通过mock.patch.dict(os.environ, {HF_HUB_OFFLINE: 1})与环境变量双保险同时 patchhuggingface_hub.constants.HF_HUB_OFFLINE以及 Transformers 侧的is_offline_mode按is_transformers_ge_v5区分新旧 API异常路径下会回滚计数避免把未真正缓存的访问误记为已缓存。务必把模型加载包在hub_online_once里。若测试同时加载 tokenizer需要扩展缓存键如hub_online_once(model_id _tokenizer)否则 tokenizer 的加载会与仅加载模型的测试共享缓存池导致离线模式下 tokenizer 拉取失败。文档还提醒避免在yieldfixture 中使用它相当于把整个测试都包进离线上下文产生意外的HF_HUB_OFFLINE行为。require_* 系列装饰器硬件与可选依赖门控装饰器族在 testing_utils.py 中成批定义全部基于pytest.mark.skipif实现缺硬件或缺库时跳过而非报错装饰器跳过条件require_non_cpu当前后端是 CPU无加速器require_non_xpu当前后端是 XPUrequire_torch_gputorch.cuda.is_available()为 Falserequire_torch_multi_gpu无 CUDA 或设备数 2require_torch_multi_acceleratorCPU 后端或设备数 2require_bitsandbytes未安装 bitsandbytes同时打bitsandbytesmarker供-m … and bitsandbytes过滤require_gptqmodel/require_aqlm/require_hqq/require_eetq/require_optimum/require_torchao对应库不可用经由peft.import_utils的is_*_available判定require_deterministic_for_xpu非 XPU 时原样执行XPU 上临时开启确定性算法后执行再恢复规范优先使用这些装饰器而不是自己写 ad hoc skip 逻辑。数据加载与确定性load_dataset_english_quotes()与load_cat_image()testing_utils.py是基于lru_cache的缓存数据加载器分别加载ybelkada/english_quotes_copy文本数据集与huggingface/cats-image图像供需要真实输入的测试复用注释说明因存在 unittest 风格测试而暂不能改用 pytest fixturetemp_seed(seed)testing_utils.py临时设置 Python numpy 与 PyTorch含 CUDA随机种子退出时恢复原状态用于保证局部确定性。set_init_weights_false让适配器真正改变输出set_init_weights_false(config_cls, kwargs)testing_utils.py解决一个微妙的测试需求很多 battery 测试要求适配器改变模型输出这要求init_weightsFalse或方法等价参数。该辅助函数按配置类分发正确的参数名PromptLearningConfig子类、LNTuningConfig、VBLoRAConfig原样返回无需设置MissConfig且init_weights bat不覆盖保留 bat 初始化以便真正测试它LoraConfig/AdaLoraConfig设init_lora_weights FalseIA3Config设init_ia3_weights FalseTinyLoraConfig设init_weights uniform其余方法设init_weights False。顺带一提get_state_dicttesting_utils.py会先解包 torch.compile 产生的_orig_mod再取 state dict避免编译包装干扰。八、conftest.pyCI 纪律的守门人tests/conftest.py 不只是普通 fixture 容器它承载了三项关键 CI 纪律--regression选项注册与回归测试自动跳过前文已述Transformers 弃用警告升级为错误conftest.pypytest_configure中为transformerslogger 挂上一个自定义ErrorOnDeprecationhandler凡消息含 deprecat 或 future 的 WARNING 记录都会抛AssertionError两个白名单例外torch_dtype相关与已知的 BPE 警告。因此一个因弃用消息失败的测试是有意为之需要修复代码而非绕过测试macOS x86 runner 的定向 xfailconftest.py通过pytest_runtest_makereporthookwrapper将 macOS 上因旧版 torch 触发torch.load漏洞报错的用例从 failure 转为 skiprep.outcome skippedrep.wasxfail说明原因保证 MacOS x86 上使用 torch 2.6 的 CI 保持绿色待 PyTorch 2.2 支持结束后该 hook 可删除。九、CI 矩阵与编写约定速查CI 覆盖范围常规 CI 在Ubuntu 与 Windows上运行测试仍受维护的 4 个最老 Python 版本非 EOL常规 CI 一般使用PyTorch、Transformers、Diffusers、Accelerate 等的最新 releasenightly 测试运行在 Transformers 与 Accelerate 的 main 分支上GPU 测试test_gpu_examples.py/test_common_gpu.py不在 PR 默认 CI 中执行而是 nightly 的 GPU runner见 Makefile 的目标拆分。模型使用规范测试 Transformers 或 Diffusers 模型时只使用 tiny random 模型通常来自hf-internal-testing或peft-internal-testing组织仓库中可见peft-internal-testing/opt-125m等测试必须在 CPU 上数秒内完成尽量复用套件中已有的模型若缺少所需架构的 tiny random 变体通知维护者创建并上传文档原文提醒需确保模型被正确上传绝不使用 HF Hub 上随机上传者发布的模型或数据集。编写风格约定尽量复用自定义nn.Module定义与 pytest fixture避免重复造轮子使用pytest 风格纯assert、pytest.mark.parametrize、fixture不使用unittest.TestCase数值容差要考虑到其他设备跨硬件精确相等几乎不成立测试名或上下文不足以说明意图时添加注释测试代码中的非平凡选择要注释解释注释应自洽不引用 PR 讨论必要时链接到相关讨论单个测试在 CPU 上要快。如果某个测试需要数秒以上尤其是会被参数化重复运行数十次时必须优化运行时间除非测试确实需要如加载 checkpoint避免磁盘读写。十、速查清单为 PEFT 添加或修改测试场景动作依据文件所有方法共有的行为扩展PeftCommonTester._test_* 矩阵文件用例tests/testing_common.py单一方法专属行为放入 / 新建test_method.py如 tests/test_vera.py库级功能扩展跨切面文件tests/test_config.py、tests/test_initialization.py需要 GPUtest_gpu_examples.py/test_common_gpu.pysingle_gpu_tests/multi_gpu_testsmarkertests/test_gpu_examples.py、Makefile量化集成test_quantization.pyrequire_*装饰器tests/testing_utils.py跨版本兼容tests/regression/--regressiontests/regression/test_regression.py多进程训练tests/training/ Makefiletests_trainingtests/training/training.py、Makefile本地全量运行测试的入口是 Makefile 的test目标Makefilepython -m pytest -n 3 tests/-n 3为并行数CI 下追加--report-log。结合本文所述的结构化规则新增测试即可精确落位到矩阵、跨切面、方法专属或硬件门控的对应位置既保证覆盖率又不拖慢 CI 与本地迭代。【免费下载链接】peft PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.项目地址: https://gitcode.com/gh_mirrors/pe/peft创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表