Skip to content
Snippets Groups Projects
Commit 01e6778c authored by Noam Zerah's avatar Noam Zerah
Browse files

Changes in MetaOps Name

parent 6d7bc3b4
No related branches found
No related tags found
2 merge requests!24Adding MulCompensation Nodes to the PTQ pipeline,!22Refactor: removing scaling nodes
......@@ -131,13 +131,13 @@ set_property(TARGET ${module_name} PROPERTY POSITION_INDEPENDENT_CODE ON)
# PYTHON BINDING
if (PYBIND)
generate_python_binding(${project} ${module_name})
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
# Handles Python + pybind11 headers dependencies
target_link_libraries(${module_name}
PUBLIC
pybind11::pybind11
PRIVATE
Python::Python
Python3::Python
)
endif()
......
......@@ -25,7 +25,7 @@
#include "aidge/graph/OpArgs.hpp" // Sequential
#include "aidge/operator/MetaOperator.hpp"
/// @brief ScalingMeta acts as a meta-operator to handle scaling operations in the PTQ, replacing the Scaling Operator.
/// @brief Quantizer acts as a meta-operator to handle scaling operations in the PTQ, replacing the Scaling Operator.
/// This operator is composed of a sequence of [Mul] -> [Clip] -> [Round] operations.
///
/// @param scalingFactor The scaling factor to apply to the input (essentially a scalar to multiply the input with).
......@@ -33,24 +33,28 @@
/// @param clip_max The maximum value for the clip operation.
/// @param name The name of the meta-operator node created.
/// @return A shared pointer to an instance of the meta-operator node.
std::shared_ptr<Aidge::Node> ScalingMeta(float scalingFactor, float clip_min,float clip_max,const std::string& name);
std::shared_ptr<Aidge::Node> Quantizer(float scalingFactor, float clip_min,float clip_max,const std::string& name);
/// @brief The purpose of MulPTQ is to encapsulate the Mul operator and tag it as a PTQ node rather than a regular Mul operator.
/// @brief The purpose of Scaling is to encapsulate the Mul operator and tag it as a PTQ node rather than a regular Mul operator.
/// Therefore, this meta-operator consists solely of a [Mul] operation.
///
/// @param scalingFactor The scaling factor to apply to the input (a scalar to multiply the input with).
/// @param name The name of the meta-operator node created.
/// @return A shared pointer to an instance of the MulPTQ node.
/// @return A shared pointer to an instance of the scaling node.
std::shared_ptr<Aidge::Node> MulPTQ(float scalingFactor,const std::string& name = "");
/// @brief Same as Scaling but used in the Insertion of Compensation Nodes
std::shared_ptr<Aidge::Node> MulCompensation(float scalingFactor,const std::string& name);
/// @brief Updates the scaling factor of a PTQ meta-operator node, allowing for dynamic adjustment of the scaling parameter.
/// This function sets a new scaling factor for a specified meta-operator node, modifying the scalar applied in the [Mul] operation.
/// The meta-operator node must be a PTQ-specific operator, such as a ScalingMeta or MulPTQ node.
/// The meta-operator node must be a PTQ-specific operator, such as a Quantizer or Scaling node.
///
/// @param MetaOpNode A shared pointer to the PTQ meta-operator node whose scaling factor will be updated.
/// @param newScalingFactor The new scaling factor to apply to the meta-operator node.
/// @return True if the scaling factor was successfully updated, false if the operation failed (e.g., if MetaOpNode is null or incompatible).
bool updatePTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, float newScalingFactor);
bool updateScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, float newScalingFactor);
/// @brief Retrieves the current scaling factor of a PTQ meta-operator node.
/// This function returns the scaling factor associated with the specified PTQ meta-operator node,
......@@ -58,17 +62,17 @@ bool updatePTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, floa
///
/// @param MetaOpNode A shared pointer to the PTQ meta-operator node whose scaling factor is being queried.
/// @return The scaling factor currently applied to the meta-operator node, or -1 if the operation fails (e.g., if MetaOpNode is null or incompatible).
float getPTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode);
float getScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode);
/// @brief Sets the clip range for an existing ScalingMeta node by specifying minimum and maximum clipping values.
/// This function modifies the clip range of a ScalingMeta node, allowing adjustment of the range within which values are clipped
/// in the [Clip] operation of the ScalingMeta sequence.
/// @brief Sets the clip range for an existing Quantizer node by specifying minimum and maximum clipping values.
/// This function modifies the clip range of a Quantizer node, allowing adjustment of the range within which values are clipped
/// in the [Clip] operation of the Quantizer sequence.
///
/// @param ScalingMetaNode A shared pointer to the ScalingMeta node whose clip range is being set.
/// This node should have been created using the ScalingMeta function.
/// @param QuantizerNode A shared pointer to the Quantizer node whose clip range is being set.
/// This node should have been created using the Quantizer function.
/// @param min The minimum value for the clip range. Values below this will be clipped to this minimum.
/// @param max The maximum value for the clip range. Values above this will be clipped to this maximum.
/// @return True if the clip range was successfully set, false if the operation failed (e.g., if ScalingMetaNode is null).
bool setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode, float min, float max);
/// @return True if the clip range was successfully set, false if the operation failed (e.g., if QuantizerNode is null).
bool setClipRange(std::shared_ptr<Aidge::Node> QuantizerNode, float min, float max);
#endif /* AIDGE_QUANTIZATION_PTQ_PTQMETAOPS_H_ */
......@@ -104,8 +104,8 @@ void init_PTQ(py::module &m) {
:type input_dataset: list of :py:class:`aidge_core.Tensor`
:param clipping_mode: Type of the clipping optimization. Can be either 'MAX', 'MSE', 'AA' or 'KL'.
:type clipping_mode: string
:param apply_rounding: Whether to apply the rounding operations or not.
:type apply_rounding: bool
:param no_quantization: Whether to truly quantize the network or not.
:type no_quantization: bool
:param optimize_signs: Whether to take account of the IO signs of the operators or not.
:type optimize_signs: bool
:param single_shift: Whether to convert the scaling factors into powers of two. If true the approximations are compensated using the previous nodes weights.
......
......@@ -396,8 +396,8 @@ void normalizeParameters(std::shared_ptr<GraphView> graphView)
std::shared_ptr<Node> scalingNode = getPreviousScalingNode(mergingNode);
float scaling_factor = getPTQMetaOpsScalingFactor(scalingNode);
updatePTQMetaOpsScalingFactor(scalingNode,scaling_factor / rescaling);
float scaling_factor = getScalingFactor(scalingNode);
updateScalingFactor(scalingNode,scaling_factor / rescaling);
accumulatedRatios[mergingNode->name()] /= rescaling; // optional ...
}
}
......@@ -554,8 +554,8 @@ void normalizeActivations(std::shared_ptr<GraphView> graphView, std::map<std::st
// ValueRanges must contains all the scaling nodes !!!
float scalingFactor = valueRanges[node->name()];
float scaling_factor = getPTQMetaOpsScalingFactor(node);
updatePTQMetaOpsScalingFactor(node, (scaling_factor) / (scalingFactor / prevScalingFactor));
float scaling_factor = getScalingFactor(node);
updateScalingFactor(node, (scaling_factor) / (scalingFactor / prevScalingFactor));
scalingFactors[node->name()] = scalingFactor;
......@@ -597,8 +597,8 @@ void normalizeActivations(std::shared_ptr<GraphView> graphView, std::map<std::st
std::shared_ptr<Node> scalingNode = getPreviousScalingNode(mergingNode);
//Log::info(" SCALING NODE : {} {}", scalingNode->type(), scalingNode->name());
float scaling_factor = getPTQMetaOpsScalingFactor(scalingNode);
updatePTQMetaOpsScalingFactor(scalingNode, scaling_factor * rescaling);
float scaling_factor = getScalingFactor(scalingNode);
updateScalingFactor(scalingNode, scaling_factor * rescaling);
}
}
}
......@@ -792,8 +792,8 @@ void quantizeNormalizedNetwork(std::shared_ptr<GraphView> graphView, std::uint8_
rescaling *= outputIsUnsigned ? unsignedMax : signedMax;
std::shared_ptr<Node> scalingNode = *(node->getChildren().begin()); // Assert if scalingNode is a Scaling ...
float scaling_factor = getPTQMetaOpsScalingFactor(scalingNode);
updatePTQMetaOpsScalingFactor(scalingNode, scaling_factor * rescaling);
float scaling_factor = getScalingFactor(scalingNode);
updateScalingFactor(scalingNode, scaling_factor * rescaling);
}
if (isMerging(node))
......@@ -809,8 +809,8 @@ void quantizeNormalizedNetwork(std::shared_ptr<GraphView> graphView, std::uint8_
std::shared_ptr<Node> scalingNode = *(node->getChildren().begin()); // Assert if scalingNode is a Scaling ...
float scaling_factor = getPTQMetaOpsScalingFactor(scalingNode);
updatePTQMetaOpsScalingFactor(scalingNode,scaling_factor * rescaling);
float scaling_factor = getScalingFactor(scalingNode);
updateScalingFactor(scalingNode,scaling_factor * rescaling);
}
// Handle the Scaling Nodes ...
......@@ -819,18 +819,18 @@ void quantizeNormalizedNetwork(std::shared_ptr<GraphView> graphView, std::uint8_
{
if (!noQuant)
{
//[!!] replacement of MulPTQ Node by ScalingMeta
float currentSF = getPTQMetaOpsScalingFactor(node);
//[!!] replacement of Scaling Node by Quantizer
float currentSF = getScalingFactor(node);
std::shared_ptr<Node> ScalingMetaNode = ScalingMeta(currentSF, - (signedMax + 1), signedMax, node->name());
ScalingMetaNode->getOperator()->setDataType(DataType::Float32);
ScalingMetaNode->getOperator()->setBackend("cpu");
std::set<Aidge::NodePtr> setNewScalingMetaNode;
setNewScalingMetaNode.insert(ScalingMetaNode);
std::shared_ptr<Node> QuantizerNode = Quantizer(currentSF, - (signedMax + 1), signedMax, node->name());
QuantizerNode->getOperator()->setDataType(DataType::Float32);
QuantizerNode->getOperator()->setBackend("cpu");
std::set<Aidge::NodePtr> setNewQuantizerNode;
setNewQuantizerNode.insert(QuantizerNode);
std::set<Aidge::NodePtr> setOldMulPTQNode;
setOldMulPTQNode.insert(node);
graphView->replace(setOldMulPTQNode,setNewScalingMetaNode);
std::set<Aidge::NodePtr> setOldScalingNode;
setOldScalingNode.insert(node);
graphView->replace(setOldScalingNode,setNewQuantizerNode);
if (optimizeSigns)
{
......@@ -842,13 +842,13 @@ void quantizeNormalizedNetwork(std::shared_ptr<GraphView> graphView, std::uint8_
rescaling /= inputIsUnsigned ? unsignedMax : signedMax;
rescaling *= outputIsUnsigned ? unsignedMax : signedMax;
float scalingFactor = getPTQMetaOpsScalingFactor(ScalingMetaNode);
updatePTQMetaOpsScalingFactor(ScalingMetaNode,scalingFactor * rescaling);
float scalingFactor = getScalingFactor(QuantizerNode);
updateScalingFactor(QuantizerNode,scalingFactor * rescaling);
// if outputIsUnsigned ... set (0 , unisgnedMax)
if(outputIsUnsigned)
{
setScalingMetaClipRange(ScalingMetaNode,0,unsignedMax);
setClipRange(QuantizerNode,0,unsignedMax);
}
}
}
......@@ -867,7 +867,7 @@ static void insertCompensationNodes(std::shared_ptr<GraphView> graphView, std::u
{
// A merging node is always followed by a scaling node at this point ...
if (node->type() == "Scaling")
if (node->type() == "Quantizer")
{
bool prevNodeIsForking = ((node->getParent(0))->getChildren().size() > 1);
bool prevNodeIsAffine = isAffine(node->getParent(0));
......@@ -901,8 +901,8 @@ static void insertCompensationNodes(std::shared_ptr<GraphView> graphView, std::u
// rescale the coeffs and edit scaling factor
fillTensor(coeffTensor, signedMax);
float sf =getPTQMetaOpsScalingFactor(node);
updatePTQMetaOpsScalingFactor(node,sf/signedMax);
float sf = getScalingFactor(node);
updateScalingFactor(node,sf/signedMax);
// TODO : double check this !!!
//std::cout << getTensorAbsoluteMax(coeffTensor) << std::endl;
......@@ -924,11 +924,11 @@ performSingleShiftApproximation(std::shared_ptr<GraphView> graphView, bool noQua
{
std::shared_ptr<Node> scalingNode = (*node->getChildren().begin());
float base = getPTQMetaOpsScalingFactor(scalingNode);
float base = getScalingFactor(scalingNode);
float approx = std::pow(2, std::ceil(std::log2(base)));
updatePTQMetaOpsScalingFactor(scalingNode,approx);
updateScalingFactor(scalingNode,approx);
float ratio = base / approx;
......@@ -942,7 +942,7 @@ performSingleShiftApproximation(std::shared_ptr<GraphView> graphView, bool noQua
std::shared_ptr<Tensor> biasTensor = getBiasTensor(node);
rescaleTensor(biasTensor, ratio);
if (!noQuant)
roundTensor(biasTensor);
roundTensor(biasTensor);
}
}
}
......@@ -954,7 +954,7 @@ static void printScalingFactors(std::shared_ptr<GraphView> graphView)
for (auto node : retrieveNodeVector(graphView))
if (node->type() == "Scaling")
{
float factor = getPTQMetaOpsScalingFactor(node);
float factor = getScalingFactor(node);
Log::info(" {:.6f} ({})", factor, node->name());
}
}
......
......@@ -28,22 +28,23 @@
#include "aidge/utils/Types.h"
#include "aidge/operator/Identity.hpp"
#include "aidge/data/Tensor.hpp"
std::shared_ptr<Aidge::Node> ScalingMeta(float scalingFactor, float clip_min,float clip_max,const std::string& name)
std::shared_ptr<Aidge::Node> Quantizer(float scalingFactor, float clip_min,float clip_max,const std::string& name)
{
std::shared_ptr<Aidge::Tensor> ScalingFactorTensorAttached = std::make_shared<Aidge::Tensor>(Aidge::Array1D<float, 1>{scalingFactor});
std::shared_ptr<Aidge::Node> mul_node = Aidge::Mul((!name.empty()) ? name + "_MulPTQ" : "");
std::shared_ptr<Aidge::Node> mul_node = Aidge::Mul((!name.empty()) ? name + "_MulQuant" : "");
std::shared_ptr<Aidge::Node> producer_scaling_factor = addProducer(mul_node,1,{1},"ScalingFactor");
producer_scaling_factor ->getOperator()->setOutput(0,ScalingFactorTensorAttached);
std::shared_ptr<Aidge::Node> clip_node = Aidge::Clip((!name.empty()) ? name + "_ClipQuant" : "",clip_min,clip_max);
std::shared_ptr<Aidge::GraphView> graph = Aidge::Sequential({
mul_node,
Aidge::Clip((!name.empty()) ? name + "_ClipPTQ" : "",clip_min,clip_max),
Aidge::Round((!name.empty()) ? name + "_RoundPTQ" : "")});
Aidge::Round((!name.empty()) ? name + "_RoundQuant" : ""),
clip_node});
std::shared_ptr<Aidge::GraphView> connectedGV = getConnectedGraphView(mul_node);
std::shared_ptr<Aidge::Node> metaopNode = MetaOperator("ScalingMeta",connectedGV,{},name);
std::shared_ptr<Aidge::Node> metaopNode = MetaOperator("Quantizer",connectedGV,{},name);
return metaopNode;
}
......@@ -51,7 +52,7 @@ std::shared_ptr<Aidge::Node> MulPTQ(float scalingFactor,const std::string& name)
{
std::shared_ptr<Aidge::Tensor> ScalingFactorTensorAttached = std::make_shared<Aidge::Tensor>(Aidge::Array1D<float, 1>{scalingFactor});
std::shared_ptr<Aidge::Node> mul_node = Aidge::Mul((!name.empty()) ? name + "_MulPTQ" : "");
std::shared_ptr<Aidge::Node> mul_node = Aidge::Mul((!name.empty()) ? name + "_Scaling" : "");
std::shared_ptr<Aidge::Node> producer_scaling_factor = addProducer(mul_node,1,{1},"ScalingFactor");
producer_scaling_factor->getOperator()->setOutput(0, ScalingFactorTensorAttached);
......@@ -60,10 +61,23 @@ std::shared_ptr<Aidge::Node> MulPTQ(float scalingFactor,const std::string& name)
Aidge::NodePtr metaopNode = MetaOperator("MulPTQ",connectedGV,{},name);
return metaopNode;
}
bool updatePTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, float newScalingFactor)
std::shared_ptr<Aidge::Node> MulCompensation(float scalingFactor,const std::string& name)
{
if(MetaOpNode->type() != "MulPTQ" && MetaOpNode->type() != "ScalingMeta")
std::shared_ptr<Aidge::Tensor> ScalingFactorTensorAttached = std::make_shared<Aidge::Tensor>(Aidge::Array1D<float, 1>{scalingFactor});
std::shared_ptr<Aidge::Node> mul_node = Aidge::Mul((!name.empty()) ? name + "_MulCompensation" : "");
std::shared_ptr<Aidge::Node> producer_scaling_factor = addProducer(mul_node,1,{1},"ScalingFactor");
producer_scaling_factor->getOperator()->setOutput(0, ScalingFactorTensorAttached);
std::shared_ptr<Aidge::GraphView> graph = Aidge::Sequential({mul_node});
std::shared_ptr<Aidge::GraphView> connectedGV = getConnectedGraphView(mul_node);
Aidge::NodePtr metaopNode = MetaOperator("MulCompensation",connectedGV,{},name);
return metaopNode;
}
//updateScalingFactor
bool updateScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, float newScalingFactor)
{
if(MetaOpNode->type() != "MulPTQ" && MetaOpNode->type() != "MulCompensation" && MetaOpNode->type() != "Quantizer")
{
AIDGE_ASSERT("Cannot use updatePTQMetaOpsScalingFactor on Node of type {}", MetaOpNode->type());
}
......@@ -81,10 +95,10 @@ bool updatePTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode, floa
AIDGE_ASSERT("Invalid PTQ MetaOperator, no Mul node found inside node of type {}",MetaOpNode->type());
return false;
}
float getPTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode)
//getScalingFactor
float getScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode)
{
if(MetaOpNode->type() != "MulPTQ" && MetaOpNode->type() != "ScalingMeta")
if(MetaOpNode->type() != "MulPTQ" && MetaOpNode->type() != "MulCompensation" && MetaOpNode->type() != "Quantizer")
{
AIDGE_ASSERT("Cannot use getPTQMetaOpsScalingFactor on Node of type {}",MetaOpNode->type());
return -1;
......@@ -103,16 +117,16 @@ float getPTQMetaOpsScalingFactor(std::shared_ptr<Aidge::Node> MetaOpNode)
AIDGE_ASSERT("Invalid PTQ MetaOperator, no Mul node found inside node of type {}",MetaOpNode->type());
return -1;
}
bool setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode,float min, float max)
// setClipRange
bool setClipRange(std::shared_ptr<Aidge::Node> QuantizerNode,float min, float max)
{
if(ScalingMetaNode->type() != "ScalingMeta")
if(QuantizerNode->type() != "Quantizer")
{
AIDGE_ASSERT("Cannot use setScalingMetaClipRange on Node of type {}",ScalingMetaNode->type());
AIDGE_ASSERT("Cannot use setQuantizerClipRange on Node of type {}",QuantizerNode->type());
return false;
}
std::shared_ptr<Aidge::MetaOperator_Op> MetaOp = std::static_pointer_cast<Aidge::MetaOperator_Op>(ScalingMetaNode->getOperator());
std::set<Aidge::NodePtr> Meta_Op_Node_List = MetaOp->getMicroGraph()->getNodes(); //List of Node inside MulPTQ Metaop Node
std::shared_ptr<Aidge::MetaOperator_Op> MetaOp = std::static_pointer_cast<Aidge::MetaOperator_Op>(QuantizerNode->getOperator());
std::set<Aidge::NodePtr> Meta_Op_Node_List = MetaOp->getMicroGraph()->getNodes(); //List of Node inside
for(std::shared_ptr<Aidge::Node> node : Meta_Op_Node_List)
{
if(node->type() == "Clip")
......@@ -123,6 +137,6 @@ bool setScalingMetaClipRange(std::shared_ptr<Aidge::Node> ScalingMetaNode,float
return true;
}
}
AIDGE_ASSERT("Invalid MetaOperator MulPTQ, no Mul node found inside Node of type {}",ScalingMetaNode->type());
AIDGE_ASSERT("Invalid MetaOperator Quantizer, no clip node found inside Node of type {}",QuantizerNode->type());
return false;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment