| 51 | # 对于更为复杂的模式匹配,你可以参考 ppq.quantization.optim.refine.SwishFusionPass |
| 52 | # ------------------------------------------------------------ |
| 53 | class MyFusion(QuantizationOptimizationPass): |
| 54 | def optimize(self, graph: BaseGraph, dataloader: Iterable, |
| 55 | collate_fn: Callable, executor: TorchExecutor, **kwargs) -> None: |
| 56 | |
| 57 | # 图融合过程往往由图模式匹配开始,让我们建立一个模式匹配引擎 |
| 58 | search_engine = SearchableGraph(graph=graph) |
| 59 | for pattern in search_engine.pattern_matching(patterns=['Conv', 'Clip'], edges=[[0, 1]], exclusive=True): |
| 60 | conv, relu = pattern |
| 61 | |
| 62 | # 匹配到图中的 conv - relu 对,接下来关闭不必要的量化点 |
| 63 | # 首先我们检查 conv - relu 是否都是量化算子,是否处于同一平台 |
| 64 | is_quantable = isinstance(conv, QuantableOperation) and isinstance(relu, QuantableOperation) |
| 65 | is_same_plat = conv.platform == relu.platform |
| 66 | |
| 67 | if is_quantable and is_same_plat: |
| 68 | # 将 relu 输入输出的量化全部指向 conv 输出 |
| 69 | # 一旦调用 dominated_by 完成赋值,则调用 dominated_by 的同时 |
| 70 | # PPQ 会将 relu.input_quant_config[0] 与 relu.output_quant_config[0] 的状态置为 OVERLAPPED |
| 71 | # 在后续运算中,它们所对应的量化不再起作用 |
| 72 | relu.input_quant_config[0].dominated_by = conv.output_quant_config[0] |
| 73 | relu.output_quant_config[0].dominated_by = conv.output_quant_config[0] |
| 74 | |
| 75 | # ------------------------------------------------------------ |
| 76 | # 自定义图融合的过程将会干预量化器逻辑,我们需要新建量化器 |
no outgoing calls
no test coverage detected