Preprocessing (A prompt to AI Code Generation)
HexagonDiff is a C++ tool for differential verification of deep neural networks (DNNs) on Hexagon DSPs. It compares the outputs of two DNN implementations to identify discrepancies and ensure correctness.
Basics
Use onnx library to parse the ONNX models of the two DNN implementations. Extract the computational graph, input/output tensors, and parameters for each layer.
Write your own parser to read the VNNLIB specification file. Assume that the input specifications are in the form of , where and are the lower and upper bounds of the input, respectively.
Write most of your operation in torch. For operations doesn't exist in torch, write your own implementation using triton for GPU acceleration.
Differential Network
We assume that two DNN implementations are only different in certain layers, such as affine layers and token pruning layers, which means we can construct a differential network. The differential network has the same structure as the original network, except the following differences:
- All non-linear operators (e.g., ReLU, MaxPool) remained the same as in the original two DNNs.
- If the two networks have different weight and bias in a certain affine layer, in the differential network, we keep weights and biases from both the DNNs: as the affine operator in the differential network.
- We denote each edge of the network as different types of tensors. During the verification of the network, these different type will be bounded differently. At the current stage, we only consider the following types of tensors:
- represents that the two DNNs have the exact same value at this point. Later, we will bound and using the same bounds: .
- represents that the two DNNs have different values but same shape at this point. Later, we will bound and separately: and , and with a differential bound: .
- represents that the one vector (tensor) of the differential network is truncated from the other. Later, we will bound the common part of and using the same bounds as , and bound the truncated part of using a single bound of : .
- represents that the one vector (tensor) of the differential network is truncated from the other, and the truncated part is merged into the last vector (tensor). In addition to , we also need to bound the bounds between every value (tensor) in the truncated part and the merged value (tensor). For example, if vector is truncated from vector , we need to bound and using bounds, and bound the difference between the last element of and every element in the truncated part of using bounds.
- For token pruning of transformers, we use special operators like and to represent the token pruning operations, which generates and types.
Conversion to the Differential Network
The following changes has to be made to convert the original two DNNs into the differential network:
- LayerNorm's division needs to be removed, since this part will be difficult for verification.
- Integer tensor operations need to be fused into operators like and , which will generate and types.
After making these changes, we can construct the differential network by merging the two DNNs together. The two DNNs will share the same non-linear operators, and have different weights and biases for affine layers. The types in the differential network are then deduced based on the structure of the network and the differences between the two DNNs.