尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Transformers 导出器扩展机制:用 Patch 与 Fix 注册表为 Dynamo、ONNX 与 ExecuTorch 导出打补丁

Transformers 导出器扩展机制:用 Patch 与 Fix 注册表为 Dynamo、ONNX 与 ExecuTorch 导出打补丁 Transformers 导出器扩展机制用 Patch 与 Fix 注册表为 Dynamo、ONNX 与 ExecuTorch 导出打补丁【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers本篇指南基于 Transformers 仓库中的扩展文档 exporters_extend.md讲解其新版 exporters 框架DynamoExporter/OnnxExporter/ExecutorchExporter的扩展机制当模型中存在某个后端无法处理的 PyTorch 模式时如何用“注册一个工厂函数 一个装饰器”的方式在导出流水线中插入 workaround而不必修改模型代码。读完本文你将能够判断一个问题该用可逆的 Patch 还是不可逆的 Fix 解决、在哪个 Stage 注册扩展点并能按仓库现有约定写出并定位一个完整的 patch/fix。导出流水线trace 之后逐 Stage 转换Transformers 的导出路径是一条分阶段流水线torch.export先把模型 trace 成一张图后续阶段对这张图做变换最后一个阶段将其 lowering或发射到目标运行时。绝大多数模型可以原样通过整条流水线。只有当某个后端无法处理某个 PyTorch 模式时才需要在工作台插入 workaround——而且按设计约定workaround 应放在能够干净地表达它的最底层 Stage由导出器在对应阶段统一安装而不是去改 modeling 代码。从源码结构看这条流水线有三个后端实现全部位于 exporters 目录 下exporter_dynamo.py基础导出器把PreTrainedModel转成ExportedProgramexporter_onnx.py继承DynamoExporter在其外围加 5 个 Stage经torch.onnx.export产出ONNXProgramexporter_executorch.py围绕to_edge_transform_and_lower与to_executorch再加 5 个 Stage以 backend 准备为起点。三个导出器的配置分别由 configs.py 中的DynamoConfig、OnnxConfig、ExecutorchConfig数据类控制后者是前者的子类逐层继承dynamic、strict、dynamic_shapes等字段并叠加各自的后端参数。Patch 与 Fix两类 workaround 的区别一个 workaround 要么是patch要么是fix两者的本质区别在于能否回退PatchFix做什么在导出期间临时替换某个属性一个torch算子、一个 ExecuTorch 内部实现、或一个模型方法改写已 trace 出的图或 program可否回退可以导出结束后原属性会被恢复不可以它在下一阶段运行前就地修复产物注册方式register_patch(backend, *paths)register_fx_node_fix(backend)或register_fx_program_fix(backend)两类 workaround 都注册在 exporters/utils.py 中的注册表里导出器会在正确的 Stage 安装自己 backend 对应的全部条目。从源码看注册表就是一组按 backend 字符串分槽的字典见 utils.py 的 Patch and fix registries 段_PATCHES[backend]存(obj, attribute, factory)三元组通过上下文管理器apply_patches(backend)安装退出时逐一恢复原值即使中间抛异常也会还原_FX_NODE_FIXES[backend]存(gm, node) - bool形式的节点级修复函数apply_fx_node_fixes遍历GraphModule的每个call_function节点应用第一个命中的 fix随后统一跑一次死代码消除Graph.eliminate_dead_coderecompile_FX_PROGRAM_FIXES[backend]存需要整个 program 上下文的修复函数如range_constraints、graph_signature、state_dict由apply_fx_program_fixes原地应用到ExportedProgram上。register_patch的装饰器签名值得注意见 register_patch 实现它接收 backend 和任意多个点分 Python 路径右起第一段是要替换的属性其余部分是持有该属性的对象路径在装饰器执行时即模块 import 时就被解析成真实对象子模块按需 import解析失败例如对应后端没安装会被静默跳过保证模块本身仍可导入。如何选择当问题是某个单一后端的 lowering 缺陷——比如 ONNX 缺少某个算子的翻译、ONNX Runtime 的校验怪癖、或 FX 分解产生了一个死算子——用 patchworkaround 留在导出器里modeling 代码保持干净当这个模式在多个后端都挡住导出例如数据依赖的循环、Cache之外的有状态缓存、手写 split-loop attention应该反过来修模型因为在模型里修一次能惠及所有导出器。添加一个 Patch以 NLLB-MoE 为例文档给出的标准场景是某个模型方法做了torch.export无法 trace 的事。NLLB-MoE 的NllbMoeTop2Router._cast_classifier会把分类器权重 cast 成另一种 dtype这是不可 trace 的。做法是在导出期间把它换成 no-op。写法是写一个工厂函数参数是原始方法返回替换方法然后用register_patch把工厂注册到该方法完整点分路径上from transformers.exporters.utils import register_patch register_patch(dynamo, transformers.models.nllb_moe.modeling_nllb_moe.NllbMoeTop2Router._cast_classifier) def _patch_classifier_cast(_original): # 在导出期间用 no-op 替换不可 trace 的 dtype cast。 return lambda self, *args, **kwargs: None导出器在 trace 前把该方法换掉、trace 结束后恢复所以这个 patch 只影响导出本身。仓库中确实存在这条注册见 exporter_dynamo.py 中的 _patch_classifier_cast。几个变体用法共享一个工厂到多个调用点给register_patch传多个路径例如register_patch(dynamo, path_a, path_b)。仓库里典型的例子是 chunked vision attention 的 patch同一个_patch_chunked_vision_attention工厂一次性注册到 Qwen2-VL、Qwen2.5-VL/3-VL、GLM-4V、Kimi-K2.5 等约 19 个视觉/音频 attention 类的forward上Patch 一个torch算子把路径指向该算子即可例如register_patch(onnx, torch.where)。工厂收到的是真实算子所以替换实现内部可以调用它透传。exporter_onnx.py 的 Stage 1 里有现成示例_patch_where在调用torch.where前统一归一化 dtype 与标量_patch_unsqueeze对复数张量分别处理实部/虚部_patch_randperm用argsort(rand(n))替换没有 ONNX 分解的aten.randperm需要改写 trace 之后的图时写 fix 而不是 patch机制相同只是在对应的 fix 注册表上装饰函数register_fx_node_fix(onnx)或register_fx_program_fix(executorch)。各导出器的 Stage 参考每个导出器源码里都使用# ── Stage N: … ──注释块标注各 Stage文件内布局与下面的参考一一对应各 Stage 具体处理哪些算子和类可直接到文件里查。DynamoExporter一个 patch Stage 加四个辅助阶段基础导出器在DynamoExporter.export见 exporter_dynamo.py 的 export 方法内按顺序执行 1 个 patch Stage 和 4 个辅助阶段Forward 签名 patch把model.forward换成一个由 sample inputs 推导出的扁平显式签名避免torch.export把**kwargs展开成与dynamic_shapes对不上的combined_args大捆绑。这是内部契约不是扩展点。模型 patches在 trace 期间把不可 trace 的模型方法换成导出安全等价物对应_PATCHES[dynamo]通过apply_patches(dynamo)安装、退出时还原。扩展方式就是register_patch(dynamo, ...)。Pytree 注册为每种Cache子类和ModelOutput注册 flatten/unflatten hookregister_cache_pytrees_for_model见 exporter_dynamo.py让torch.export能展平并重建它们——通常自动发生。对通用属性遍历够不到的类型在_flatten_to_context/_unflatten_from_context中加一个分支即可。动态形状dynamicTrue时get_auto_dynamic_shapes会给每个张量和 cache 叶子赋Dim.AUTO需要更精细控制时用DynamoConfig.dynamic_shapes显式指定仓库注释也提醒这样做可以只对真正变化的轴建符号导出显著更快。状态清理reset_model_state把模型在forward内部写入、trace 后会残留为 FakeTensor 的张量属性先置空、结束后恢复需要跟踪新的此类属性时把属性名加进_STATEFUL_CACHE_ATTRS当前包含cached_rotary_positional_embedding、cached_sequence_length见 exporter_dynamo.py。OnnxExporter围绕 torch.onnx.export 的五个 StageOnnxExporter在torch.onnx.export外围增加五个 Stage见 exporter_onnx.py 的export方法。要列全该文件里的 patch可以直接grep -nE ^def (_patch_|_fix_|_aten_) src/transformers/exporters/exporter_onnx.py各 Stage 在文件中的位置与 exporter_onnx.py 的行号对应Stage 1 在 L175Stage 2 在 L553Stage 3 在 L588Stage 4 在 L852Stage 5 在 L1063。Torch patches在 trace 期间替换 ONNX 导出无法直接翻译的torch算子。扩展方式register_patch(onnx, ...)。ONNX patches在run_decompositions之后重跑一次节点修复使新引入的 shape-guard 节点在下 lowering 前就被修好走的是与 Stage 1 相同的register_patch(onnx, ...)注册表。FX node fixes改写 ONNX 无法 lower 的图节点如 alias 算子、in-place view、死 assert 等。扩展方式register_fx_node_fix(onnx)。ONNX translations为默认翻译缺失或有 bug 的 aten 算子提供自定义 lowering例如aten.index_put、aten._grouped_mm。做法是把_aten_*函数加进_ONNX_TRANSLATION_TABLE作为custom_translation_table传给torch.onnx.export。ONNX IR fixes导出完成后直接改写 ONNX program规避 ONNX Runtime 的 bug例如强制TopK(sortedTrue)。做法是把_fix_ir_*函数加进_IR_FIXES。ExecutorchExporter以 backend 准备为起点的五个 StageExecutorchExporter围绕to_edge_transform_and_lower与to_executorch增加五个 Stage见 exporter_executorch.pyBackend 准备把模型移到目标 device/dtype 并选定 partitionerprepare_for_xnnpack或prepare_for_cuda实现见 exporter_executorch.py 的 _BACKEND_PREPARE 表。要新增 backend实现prepare_for_name并注册进_BACKEND_PREPARE即可。Torch patches替换 ExecuTorch backend 不接受的torch算子如split_copy、chunk、topk(kdim)。扩展方式register_patch(executorch, ...)。ExecuTorch patches替换那些在合法动态形状图上会崩溃的 ExecuTorch 内部实现同样走register_patch(executorch, ...)注册表。FX program fixes修复需要整体 program 上下文的导出产物如放宽 range 约束、补全缺失的 placeholder 元数据。扩展方式register_fx_program_fix(executorch)。FX node fixes改写单个节点如把 Python sym 算子映射到executorch_prim.*、把pow改写为mul链。扩展方式register_fx_node_fix(executorch)。已知的上游 workaround导出器还会维护两份“与上游 bug 挂钩”的清单两者都在测试文件 tests/exporters/test_export.py 中定义且都设计为只收缩、不扩张。ONNX_DISABLE_OPTIMIZE见 test_export.py 中的定义少数模型类命中了onnxscript图优化器的已确认 bug例如SplitToSequence上常量折叠崩溃、FPN 的 initializer 被丢弃该清单对这些模型关闭onnxscript优化。每个条目都把对应的上游 issue 记录在模型名旁边新增条目必须引用一个具体的上游 bug而不是随意关闭优化。EXPORT_SKIPS见 test_export.py 中的定义当模型在现状下根本无法导出时无法向量化的数据依赖控制流、或被当作 forward 参数对待的模块把个别模型类整体移出导出扫描。每个条目都附带一个 reason写明模型侧需要做什么修改才能解除跳过。同样地这个列表预期只会变短。小结扩展点速查遇到的问题该用的扩展点注册方式某模型方法/torch算子在 trace 时不可用单后端问题Patchregister_patch(dynamo \| onnx \| executorch, *paths)Trace 后需要改写单个图节点FX node fixregister_fx_node_fix(backend)修复需要整个 ExportedProgram 上下文FX program fixregister_fx_program_fix(backend)需要新的 ONNX 算子翻译Translation向_ONNX_TRANSLATION_TABLE加_aten_*函数需要修最终 ONNX program 的 IRIR fix向_IR_FIXES加_fix_ir_*函数需要新的 ExecuTorch 后端Backend prepare实现prepare_for_name并注册进_BACKEND_PREPARE多后端共同被某模式挡住修模型在 modeling 代码中一次性修复惠及所有导出器核心原则始终如一workaround 放在能干净表达它的最底层 Stage能回退的尽量回退patch不能回退的fix要就地修好产物再交给下一阶段而跨后端的问题应回到模型代码里根治。【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表