量化后的模型如何利用paddle本身加载并预测结果呢?
目前我已经执行以下指令完成INT8量化: paddleslim.quant.quant_post_static( executor=exe, model_dir='./', model_filename='fp32_inference_model.pdmodel', params_filename='fp32_inference_model.pdiparams', quantize_model_path='./quant_post_static_model2', sample_generator=paddle.dataset.mnist.test(), batch_nums=10) 我接下来想载入这个模型、参数,去验证是否量化成功,查看量化的权重有啥不同之类的,不知道如何去进行。网络结构是参考零基础课程中手写数字识别LeNet网络的代码 `def init(self): super(MNIST, self).init()
# 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2
self.conv1 = Conv2D(in_channels=1, out_channels=20, kernel_size=5, stride=1, padding=2)
# 定义池化层,池化核的大小kernel_size为2,池化步长为2
self.max_pool1 = MaxPool2D(kernel_size=2, stride=2)
# 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2
self.conv2 = Conv2D(in_channels=20, out_channels=20, kernel_size=5, stride=1)
# 定义池化层,池化核的大小kernel_size为2,池化步长为2
self.max_pool2 = MaxPool2D(kernel_size=2, stride=2)
# 定义一层全连接层,输出维度是10
self.fc1 = Linear(in_features=500, out_features=120)
self.fc2 = Linear(in_features=120, out_features=10)
#加入对每一层输入和输出的尺寸和数据内容的打印,根据check参数决策是否打印每层的参数和输出尺寸
# 卷积层激活函数使用Relu,全连接层激活函数使用softmax
def forward(self, inputs, label=None, check_shape=False, check_content=False):
# 给不同层的输出不同命名,方便调试
outputs1 = self.conv1(inputs)
outputs2 = F.relu(outputs1)
outputs3 = self.max_pool1(outputs2)
outputs4 = self.conv2(outputs3)
outputs5 = F.relu(outputs4)
outputs6 = self.max_pool2(outputs5)
outputs6 = paddle.reshape(outputs6, [outputs6.shape[0], -1])
outputs7 = self.fc1(outputs6)
outputs8 = self.fc2(outputs7)
outputs9 = F.softmax(outputs8)`
,但这个是动态图模型,而量化后的是静态图,接下来应该怎么干有点手足无措。该怎么把静态图的模型读成动态图的方式呢?
量化后的模型只能用PaddleInference或PaddleLite进行部署推理: PaddleInference: https://paddleinference.paddlepaddle.org.cn/product_introduction/summary.html PaddleLite: https://paddlelite.paddlepaddle.org.cn/introduction/tech_highlights.html
量化后的模型只能用PaddleInference或PaddleLite进行部署推理: PaddleInference: https://paddleinference.paddlepaddle.org.cn/product_introduction/summary.html PaddleLite: https://paddlelite.paddlepaddle.org.cn/introduction/tech_highlights.html
你好,想问一下。我使用PPSlim来对模型进行压缩,由于PPSlim量化完并不直接减少模型体积,需要用Lite转换。Lite转换的模型格式变为.nb或model+params。但是由于某些要求,希望格式仍为inference的.pdmodel和.pdiparams,这一块有什么转换的方法吗
可以将Lite转换逻辑集成到你的预测代码里,每次启动服务加载模型前读取.pdmodel和.pdiparams并做一次转换。
可以将Lite转换逻辑集成到你的预测代码里,每次启动服务加载模型前读取.pdmodel和.pdiparams并做一次转换。
可以提供转换的代码地址吗?lite没有专门这一块的说明
可以将Lite转换逻辑集成到你的预测代码里,每次启动服务加载模型前读取.pdmodel和.pdiparams并做一次转换。
哥,你的意思是用PaddleLITE把 离线量化后的FP32模型先给转成INT8(暂时达到缩小体积的目的), 然后要推理的时候,再把INT8的这个模型,转成FP32拿来推理是吗~?
可以用pickle load并修改.pdiparams文件到Int8数值格式,在预测时再用pickle load修改成fp32格式。 @Water2style paddle.save接口保存模型时,用的是pickle, 请参考: https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/save_cn.html#canshu
可以用pickle load并修改.pdiparams文件到Int8数值格式,在预测时再用pickle load修改成fp32格式。 @Water2style paddle.save接口保存模型时,用的是pickle, 请参考: https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/save_cn.html#canshu
感谢
可以用pickle load并修改.pdiparams文件到Int8数值格式,在预测时再用pickle load修改成fp32格式。 @Water2style paddle.save接口保存模型时,用的是pickle, 请参考: https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/save_cn.html#canshu
老哥,直接用pickle.load是会报错的.代码如下:
params_path = './quant_post_static_model/qpt.pdiparams' with open(params_path,'rb') as file: model = pickle.load(file) print(model)
报错: _pickle.UnpicklingError: invalid load key, '\x00'.
后来解决了: 先直接用 paddle.load(prefix_path),把dict给读上. 然后再paddle.save 才能用pickle.load来读取这个权重文件..... 就很奇怪,网上下载的pdiparams无法直接pickle.load. 只能load自己save的.....
#用paddle.load读取量化后模型. model = paddle.load("./quant_post_static_model/qpt")
#定义函数,把weights转为INT8保存 def model_fp32_to_int8(model): for weight_name in model: if "weights" in weight_name: weight_data_fp32 = model[weight_name] weight_data_int8 = weight_data_fp32.astype('int8') model[weight_name] = weight_data_int8 return model
#拿到INT8格式的模型 Int8_format_model = model_fp32_to_int8(model)
#用paddle.save和pickle分别两个方式保存INT8格式模型. #这里用paddle.save保存后,数据变为 paddle.int8格式. 后面再用 astype('float32)会报错 ppsave_int8_format_model = paddle.save(int8_format_model,'INT8_format_model.pdiparams')
import pickle with open('INT8_format_model.pkl','wb') as f: pickle.dump(int8_format_model,f)
#定义int8回到fp32模型 def model_int8_to_fp32(pkl_int8_format_model): for weight_name in pkl_int8_format_model: if "weights" in weight_name:
pkl_weight_data_int8 = pkl_int8_format_model[weight_name]
pkl_weight_data_fp32 = pkl_weight_data_int8.astype(np.float32)
pkl_int8_format_model[weight_name] = pkl_weight_data_fp32
return pkl_int8_format_model
#把INT8模型转回FP32 #这里输入的模型如果是使用paddle.save后的模型,会在astype处报错 #这个错误是: """ RuntimeError: (NotFound) Operator cast does not have kernel for data_type[int8_t]:data_layout[ANY_LAYOUT]:place[CUDAPlace(0)]:library_type[PLAIN]. [Hint: Expected kernel_iter != kernels.end(), but received kernel_iter == kernels.end().] (at /paddle/paddle/fluid/imperative/prepared_operator.cc:159) [operator < cast > error]
""" #所以这里用的是pkl保存下来的FP32模型: back_to_fp32_model = model_int8_to_fp32(pkl_int8_format_model) back_to_fp32_model
#然后我又把这个给save下来.
#放入paddle_inference尝试读取模型,创建predictor的时候报错:
"
Create CPU IR passes
--- Running analysis [ir_graph_build_pass]
Traceback (most recent call last):
File "load_test2.py", line 16, in
" 后来又试了一下用INT8模型.同样的错误,知识这个version具体的数值变了。 但是使用最初版本的 量化后的FP32模型就不会存在这个错误. FP32转INT8, INT8再转FP32,这两个模型会出错.
补充说明:
原版的,可以推理的.pdiparams模型,称为模型1. Paddle.load起来,再用paddle.save后的模型,(中间没有任何改动,loadl后就save)称为模型2.
问题所在:
用python的open和read()搭配,读出两个模型的二进制文件. 输出后发现两个模型的内容不同,并且使用 len()函数,发现len(模型1)比len(模型2)小,len(模型2)长了3000多. 2.load_inference_model出错主要在 反序列化参数这一步.即 deserialize_persistables(program, params_bytes, exe).
3.更详细的错误报告:
""" File "/home/xieyunyao/miniconda3/envs/PP22/lib/python3.8/site-packages/paddle/static/io.py", line 848, in load_inference_model deserialize_persistables(program, params_bytes, executor) File "/home/xieyunyao/miniconda3/envs/PP22/lib/python3.8/site-packages/decorator.py", line 232, in fun return caller(func, *(extras + args), **kw) File "/home/xieyunyao/miniconda3/envs/PP22/lib/python3.8/site-packages/paddle/fluid/wrapped_decorator.py", line 25, in impl return wrapped_func(*args, **kwargs) File "/home/xieyunyao/miniconda3/envs/PP22/lib/python3.8/site-packages/paddle/fluid/framework.py", line 238, in impl return func(*args, **kwargs) File "/home/xieyunyao/miniconda3/envs/PP22/lib/python3.8/site-packages/paddle/static/io.py", line 669, in deserialize_persistables load_block.append_op( File "/home/xieyunyao/miniconda3/envs/PP22/lib/python3.8/site-packages/paddle/fluid/framework.py", line 3178, in append_op op = Operator( File "/home/xieyunyao/miniconda3/envs/PP22/lib/python3.8/site-packages/paddle/fluid/framework.py", line 2224, in init for frame in traceback.extract_stack(): InvalidArgumentError: Deserialize to tensor failed, maybe the loaded file is not a paddle model(expected file format: 0, but 4254401664 found). [Hint: Expected version == 0U, but received version:4254401664 != 0U:0.] (at /paddle/paddle/fluid/framework/lod_tensor.cc:329) [operator < load_combine > error]
"""