惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
D
Docker
Last Week in AI
Last Week in AI
WordPress大学
WordPress大学
月光博客
月光博客
小众软件
小众软件
量子位
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
罗磊的独立博客
博客园 - 叶小钗
美团技术团队
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
博客园 - 司徒正美
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
GbyAI
GbyAI
C
Check Point Blog

Пусть этот камень будет более крепким, чем человек

【MLIR】Transform Dialect【0】保持计算结构 【MLIR】跟着Toy语言学习MLIR【6】支持复合结构类型 【MLIR】跟着Toy语言学习MLIR【5】降级到LLVM及CodeGen 【MLIR】跟着Toy语言学习MLIR【4】部分降级到低层方言 【MLIR】跟着Toy语言学习MLIR【3】通过接口实现通用转换 【MLIR】跟着Toy语言学习MLIR【2】pattern匹配和重写 【MLIR】跟着Toy语言学习MLIR【1】Toy语言和 Toy Dialect 【琐记】你的爱好能坚持多少年 【琐记】烟火与尘埃 【Triton】Triton实现矩阵乘 【LLM推理加速】FlashAttention 【LLM推理加速】PagedAttention 【LLM推理加速】Online Softmax LLM基础知识【1】 Transformer模型 【AI编译】LayerGroup Tiling Tile的疑惑和思考 【AI编译】深度优先的Tile调度,万事大吉? 【AI编译】多级流水线Tile调度策略 【CUDA C++】GPU内存使用【3】 【AI编译】Cache缓存地址映射 【CUDA C++】GPU存储【2】 【CUDA C++】GPU基本介绍【1】 【00】0序章-不受欢迎的来客 【转载】我来了——持续低熵 【Halide】调度优化【2】 【感想】写作进度报告5 【Halide】调度优化【1】 【转载】北大中文男足战报2 【BYOC】TVM切分子图 【转载】北大中文男足战报1
【量化】连续卷积层首尾量化的可行性
Post author: XianMu@Пусть этот камень будет более крепким, чем ч · 2025-01-03 · via Пусть этот камень будет более крепким, чем человек
#include"stdio.h"
#include"stdlib.h"
#include"math.h"
#include <string.h>
typedef struct conv_info{
    float weight[4];
    float bias[4];
    int weight_int8[4];
    int bias_int[4];
    float scale;
}conv_info;
typedef struct tensor_info{
    float data[4];
    int data_int8[4];
    float scale;
}tensor_info;
void init_tensor(struct tensor_info* tensor, float* data, int num){
    for(int i=0; i<num; i++){
        tensor->data[i] = data[i];
    }
}
void init_conv(struct conv_info* conv, float* weight, float* bias, int num){
    for(int i=0; i<num; i++){
        conv->weight[i] = weight[i];
        conv->bias[i] = bias[i];
    }
}
void CalculateConvScale(struct conv_info* conv, int num){
    float abs_max=0;
    float *data = conv->weight;
    for(int i=0; i<num; i++){
        if(fabs(data[i])>abs_max){
            abs_max = fabs(data[i]);
        }
    }
    conv->scale = abs_max/127.0;
    for(int i=0; i<num; i++){
        int temp = round(data[i]/(conv->scale));
        conv->weight_int8[i] = temp;
    }
}
void ClaculateConvBiasInt8(struct conv_info* conv,  struct tensor_info* tensor, int num){
    for(int i=0; i<num; i++){
        int temp = round(conv->bias[i]/(conv->scale*tensor->scale));
        conv->bias_int[i] = temp;
    }
}
void CalculateTensorScale(struct tensor_info* tensor, int num){
    float abs_max=0;
    float *data = tensor->data;
    for(int i=0; i<num; i++){
        if(fabs(data[i])>abs_max){
            abs_max = fabs(data[i]);
        }
    }
    tensor->scale = abs_max/127.0;    
}
void ConvFloat(struct tensor_info* input, struct conv_info* conv, struct tensor_info* output, int num){
    for(int i=0; i<num; i++){
        output->data[i] = input->data[i]*conv->weight[i]+conv->bias[i];
    }
}
void ConvInt(struct tensor_info* input, struct conv_info* conv, struct tensor_info* output, int num){
    
    for(int i=0; i<num; i++){
        
        int input_int8 = round(input->data[i] / input->scale);  
        
        int out_int8 = input_int8 * conv->weight_int8[i];
        
        int out_bias_int8 = out_int8 + conv->bias_int[i];
        
        output->data[i] = out_bias_int8 * input->scale * conv->scale;
    }
}
void updateBiasInt8(struct conv_info* conv, float scale, int num){
    for(int i=0; i<num; i++){
        int temp = round(conv->bias[i]/scale);
        conv->bias_int[i] = temp;
    }
}
void ConvFrontTial(struct tensor_info* input, struct conv_info* conv1, struct conv_info* conv2, struct conv_info* conv3, 
        struct tensor_info* output, int num){
    for(int i=0; i<num; i++){
        
        int input_int = round(input->data[i] / input->scale);
        
        int input_int_1 = input_int * conv1->weight_int8[i] + conv1->bias_int[i];
        
        int input_int_2 = input_int_1 * conv2->weight_int8[i] + conv2->bias_int[i];
        
        int input_int_3 = input_int_2 * conv3->weight_int8[i] + conv3->bias_int[i];
        
        output->data[i] = input_int_3 * input->scale * conv1->scale * conv2->scale * conv3->scale;
    }
}
int main(){
    tensor_info* input = (tensor_info*) malloc(sizeof(tensor_info));
    float input_data[4] = {0.24, -0.08, 0.16, -0.61};
    init_tensor(input, input_data, 4);
    conv_info* conv1 = (conv_info*) malloc(sizeof(conv_info));
    float weight_data1[4] = {0.02, 0.01, -0.04, 0.01} ;
    float bias1[4] = {11.4, -6.3, -57.2, 5.48};
    init_conv(conv1, weight_data1, bias1, 4);
    conv_info* conv2 = (conv_info*) malloc(sizeof(conv_info));
    float weight_data2[4] = {0.6, 0.25, -0.48, 0.69} ;
    float bias2[4] = {10.4, -6.3, -31.2, 5.48};
    init_conv(conv2, weight_data2, bias2, 4);
    conv_info* conv3 = (conv_info*) malloc(sizeof(conv_info));
    float weight_data3[4] = {-2.4, 6.4, 1.2, 0.69} ;
    float bias3[4] = {-5.4, 7.2, 26.3, 3.24};
    init_conv(conv3, weight_data3, bias3, 4);
    printf("\n 1  ********   float 推理   ********  \n");
    tensor_info* middle1 = (tensor_info*) malloc(sizeof(tensor_info));
    tensor_info* middle2 = (tensor_info*) malloc(sizeof(tensor_info)); 
    tensor_info* output_res = (tensor_info*) malloc(sizeof(tensor_info));
    ConvFloat(input, conv1, middle1, 4);
    ConvFloat(middle1, conv2, middle2, 4);
    ConvFloat(middle2, conv3, output_res, 4);
    for(int i=0; i<4; i++){
         printf("  %f ", output_res->data[i]);
    }
    printf("\n 2 ********   量化推理   ********  \n");
    CalculateConvScale(conv1, 4);
    CalculateConvScale(conv2, 4);
    CalculateConvScale(conv3, 4);
    CalculateTensorScale(input, 4);
    CalculateTensorScale(middle1, 4);
    CalculateTensorScale(middle2, 4);
    ClaculateConvBiasInt8(conv1, input, 4);
    ClaculateConvBiasInt8(conv2, middle1, 4);
    ClaculateConvBiasInt8(conv3, middle2, 4);
    ConvInt(input, conv1, middle1, 4);
    ConvInt(middle1, conv2, middle2, 4);
    ConvInt(middle2, conv3, output_res, 4);
    
    for(int i=0; i<4; i++){
        printf("  %f ", output_res->data[i]);
    }
    
    printf("\n 3 ********   首尾量化推理   ********  \n");
    updateBiasInt8(conv1, input->scale*conv1->scale, 4);
    updateBiasInt8(conv2, input->scale*conv1->scale*conv2->scale, 4);
    updateBiasInt8(conv3, input->scale*conv1->scale*conv2->scale*conv3->scale, 4);
    ConvFrontTial(input, conv1, conv2, conv3, output_res, 4);
    for(int i=0; i<4; i++){
        printf("  %f ", output_res->data[i]);
    }
    
    
    
    printf("\n【第一个卷积】  输入scale:%f   权重scale:%f  \n", input->scale, conv1->scale);
    for(int i=0; i<4; i++){
        printf("weight_scaled(int8):%d  bias_scaled(int32):%d  ",conv1->weight_int8[i], conv1->bias_int[i]);
    }
    printf("\n【第二个卷积】  输入scale:%f   权重scale:%f  \n", middle1->scale, conv2->scale);
    for(int i=0; i<4; i++){
        printf("weight_scaled(int8):%d  bias_scaled(int32):%d  ",conv2->weight_int8[i], conv2->bias_int[i]);
    }
    printf("\n【第三个卷积】  输入scale:%f   权重scale:%f  \n", middle2->scale, conv3->scale);
    for(int i=0; i<4; i++){
        printf("weight_scaled(int8):%d  bias_scaled(int32):%d  ",conv3->weight_int8[i], conv3->bias_int[i]);
    }
    return 0;
}