2021寒武紀TensorFlow融合模式用戶手冊_第1頁
2021寒武紀TensorFlow融合模式用戶手冊_第2頁
2021寒武紀TensorFlow融合模式用戶手冊_第3頁
2021寒武紀TensorFlow融合模式用戶手冊_第4頁
2021寒武紀TensorFlow融合模式用戶手冊_第5頁
已閱讀5頁,還剩65頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

版本2021年05月06 插圖目 表格目 離線模式(AheadOf INT量 修改BUILD文 tensordump功能以及誤差計算工 融合段tensordump功 MLU內(nèi)存越界檢 使用FP16精 使用frozen 增大batch 開啟FirstConv優(yōu) 設(shè)置首層Conv2D的補齊方 使用SessionConfig的配置參 Python接 C++接 設(shè)置 設(shè)置 Python接口使 C++接口使 插圖目錄TensorFlow融合模式圖編譯器示意 插圖目錄ResNet50v1原始計算圖(融合前 ResNet50v1融合計算圖(融合后 表格目錄 表格目錄 支持的 11((或保證本文件所且寒武紀不承擔(dān)因應(yīng)用或使用任何產(chǎn)品或服務(wù)而產(chǎn)生的任何責(zé)任。寒武紀不應(yīng)對因下列原因產(chǎn)生的任何12客戶產(chǎn)品設(shè)計。本指南列出的性能測試和等級要使用特定芯片或計算機系統(tǒng)或組件來測量。經(jīng)該等測試,本指南所示結(jié)果反映了寒武紀產(chǎn)品的大概性能。系統(tǒng)硬件或軟件設(shè)計或配置的任何不同會影響實際性能。如上所述,寒武紀不代表、擔(dān)保或保證本指南所述產(chǎn)品將適用于任何特定用途。寒武紀不代表或擔(dān)保測試每種產(chǎn)品以期避免應(yīng)用程序或產(chǎn)品的默認情況??蛻舢a(chǎn)品設(shè)計的脆弱性會影響寒武紀產(chǎn)品的質(zhì)量和可靠性并導(dǎo)致超出本指南范圍的額外或不同的情況和/或要求。 ?2021222.1:寒武紀TensorFlowV20210506更新時間:20210201–33CambrionensorFlw內(nèi)建了基于CNML(CambrionNeuaeMachinearnin,寒武紀機器學(xué)習(xí)庫的融合模式CambrionensorFlwMUusionOCNML進行深度優(yōu)化,消除不必要的中間結(jié)果,生成更高效率、更具硬件親和性的MUernel。以下以ResNet50v.可以發(fā)現(xiàn),整個ResNet50v1網(wǎng)絡(luò)被融合為一個MLUFusionOP 目前CambriconTensorFlowNative(逐層)模式。如果想使用融合模式需要將環(huán)境變量MLU_STATIC_NODE_FUSION設(shè)置為true。exportexport融合模式可分為在線模式(JustInTime)和離線模式(AheadOfTime在線模式(JustIn在線模式下,用戶無需對自己的網(wǎng)絡(luò)進行修改適配,CambriconTensorFlowCNML支持的算子劃分進融合段。通常情況下,用戶無需關(guān)心CNML計算庫支持哪些TensorFlow算子。CNML不支持的算子,依會在CPU上運行。離線模式(AheadOf融合模式還有一種特殊的運行模式:離線模式。用戶可以通過CambrionensorFlw提供的離線模型生成工具,將ensorFlw計算圖轉(zhuǎn)化為寒武紀離線模型。生成的離線模型可以脫離ensorFlw框架,使用CN(CambrionNeuaeRuntime由于離線模式不依賴TensorFlow,所以計算圖中不能包含CNML如果計算圖中包含CNML對于CNML計算庫支持的TensorFlow算子,參見支持算子列表在主機端使用離線模型生成工具將TensorFlow在部署端,用戶可以脫離TensorFlow,使用CNRT44使用CambriconTensorFlow融合模式時只需正常安裝CambriconTensorFlow,不需要額外安裝依賴編譯CambriconTensorFlow加載TensorFlow##-*-coding:UTF-8-importtensorflowastfimportosinput_data=np.random.rand(2,1234)配置Sessionconfig,確保可以進入TensorFlowconfigconfig=tf.ConfigProto()config.graph_options.rewrite_options.min_graph_nodes=-1融合模式依賴TensorFlowTensorFlow44Sessionconfig=tf.ConfigProto()config.graph_options.rewrite_options.min_graph_nodes=-1withtf.Session(config=config)assess:withwithtf.Session(config=config)as#input=tf.placeholder(dtype=tf.float32,shape=(2,1234))weight=tf.constant(weight_data,dtype=tf.float32)matmul=tf.matmul(input,weight)#mlu_result=sess.run(["MatMul:0"],#CPUcpu_result=np.matmul(input_data,#打印MLU和CPU計算結(jié)果print("mlu_result:",mlu_result)print("cpu_result:",?→0addedforsegment0consistingof1nodes('mlu_result:',[array([[314.6094,309.8875],[305.2355,305.2257]],dtype=float32)])('cpu_result:',array([[314.55574484,309.93644877],[305.27366373,305.3328487]]))支持以INT8和INT16模式進行計算。例如,Conv2D、MatMul。一般情況下,INT8的性能比INT16的性能更優(yōu)。如果INT8INT8INT式的詳細使用,參見INT。支持以float32(FP32)float16(FP16)Relu、MaxPool。一般情況下,float16開啟float16keyMLUFusionOp在第二次迭代時,如果MLUFusionOpINT量化算子要使用INT模式進行計算需要先進行量化,CambriconTensorFlow提供了兩種量化模式,在2在線量化方式時,量化算子默認使用INT8通過設(shè)置環(huán)境變量的方式進行離線量化,使用起來相對比較簡單,且理論上可以支持TensorFlow通過量化工具進行離線量化,使用起來相對比較復(fù)雜,且只支持pb量化階段。主要是計算量化算子的量化參數(shù)scale#量化位寬,8filter_channel_quant:true#可選參數(shù):分通道量化,根據(jù)需求設(shè)置true/false,默認為igeqnm#量化模式,目前支持naive模式和igeqnm模式,當naive###node_name/input:input_scale bit_width、quant_mode、filter_channel_quant和convfirst_param的值需要在量化前設(shè)定,其中優(yōu)化時配置,關(guān)于FirstConvFirstConv優(yōu)化。scale_map入的,并且是以追加的方式寫入,也就是說如果量化前scale_mapMLU_QUANT_PARAMMLU_RUNNING_MODE:用于指定是量化階段還是運行階段。0為量化階段,1為運行階段,默認值為1。加載TensorFlowimportimporttensorflowastfimportoswithopen(quant_param_file,'w')asf:f.write('bit_width:8\n')f.write('quant_mode:naive\n')osos.environ['MLU_QUANT_PARAM']=屏蔽所有MLU設(shè)備。離線量化必須在CPU上進行。osos.environ['MLU_VISIBLE_DEVICES']=osos.environ['MLU_RUNNING_MODE']=input_data=np.random.rand(2,1234)配置Sessionconfig,確保可以進入TensorFlowconfigconfig=tf.ConfigProto()config.graph_options.rewrite_options.min_graph_nodes=-1withwithtf.Session(config=config)asinput=tf.placeholder(dtype=tf.float32,shape=(2,1234))weight=tf.constant(weight_data,dtype=tf.float32)matmul=tf.matmul(input,weight)result=sess.run(["MatMul:0"],打開network_quant_param.txt文件,查看scale_map中是否有值,如下所示:如果scale_map–量化階段依賴TensorFlow的圖優(yōu)化機制,但是TensorFlow44Sessionconfig。configconfig=tf.ConfigProto()config.graph_options.rewrite_options.min_graph_nodes=-1withtf.Session(config=config)assess:–如果使用的是Keras件是在SessionKeras內(nèi)部的Sessionfromfromtensorflow.python.kerasimportbackendsession=backend.get_session()–Sessionwith語法自動管理SessionSessionclose加載TensorFlowimportimporttensorflowastfimportososos.environ['MLU_QUANT_PARAM']=MLU_RUNNING_MODE默認值為1osos.environ['MLU_RUNNING_MODE']=input_data=np.random.rand(2,1234)配置Sessionconfig,確保可以進入TensorFlowconfigconfig=tf.ConfigProto()config.graph_options.rewrite_options.min_graph_nodes=-1withwithtf.Session(config=config)asinput=tf.placeholder(dtype=tf.float32,shape=(2,1234))weight=tf.constant(weight_data,dtype=tf.float32)matmul=tf.matmul(input,weight)mlu_result=sess.run(["MatMul:0"],cpu_result=np.matmul(input_data,weight_data)print("mlu_result:",mlu_result)print("cpu_result:",cpu_result)[305.23404,305.2287]],dtype=float32)])('cpu_result:',array([[314.55574484,309.93644877],[305.27366373,305.3328487]]))我們提供了量化工具fppb_to_intpb來量化模型,工具位于TensorFlow根目錄下tensorflow/cambricon_examples/tools/fppb_to_intpb/中。下面以ResNet50v1pythonpythonfppb_to_intpb.py其中,resnet50_v1_naive_int8.inidata_path= ;batch_size= ;每次運行的num_runs= ;batch_size=?→runs=10data_path20= ;meanfile=./mean.txt ;h*w行每std= ;color_mode= ;rgb、bgr、crop=224,224 ;224*224大calibration=default_preprocess_cali ;校準數(shù)據(jù)讀取及前處理的方式,可以根據(jù)需求進行自定義,[preprocess]和[data]中定義的參數(shù)均為calibration的輸入original_models_path=path/to/resnet50_v1/resnet50_v1.pb;輸入pbsave_model_path= ;輸出input_tensor_names=input:0 ;Tensor的名稱,可以是多個,以逗output_tensor_names=resnet_v1_50/predictions/Softmax:0 ;輸出Tensor的名稱,可以是多個,以逗 quantization_type=int_op_listConv2D,MatMul,LRN,Conv2DBackpropInputuse_convfirst=True;int8;要量化的layerthreshold_search。naive為基礎(chǔ)模式,threshold_searchactivation_quantization_alg=;輸入量化模式,可選naive;是否使用FirstConvthreshold_search。naive為基礎(chǔ)模式,threshold_searchweight_quantization_alg=;權(quán)值量化模式,可選naivedevice_mode=clean clean、mluorigin。建議使用channel_quantization=fuse_filter_scales_to_bn=;;當channel_quantization為True關(guān)于如果color_mode是grey(即灰度圖模式,則meantheshold_sach閾值搜索模式用于處理存在異常值的待量化數(shù)據(jù)集,該模式能夠過濾部分異常值,是對于不存在異常值,數(shù)據(jù)分布緊湊的情況,比如網(wǎng)絡(luò)權(quán)值的量化,不建議使用theshold_sach閾值搜索模式。關(guān)于mlu:將輸出pb的所有節(jié)點的device設(shè)置為MLUclean:將輸出pbdeviceorigin:使用輸入pb(在int_op_list。mean與meanfile當前處理需要減去的均值為h*w*3(h,w分別為輸入圖片的高度和寬度)時,可使用meanfile。meanfile文件按h*wr/g/bmeanvaluemeanfilemeanfile_default_preprocess_cali關(guān)于calibration來定義前處理。meanfile下面以ResNet50v1ResNet50graph在ini文件中添加calibration的名稱及其需要的參數(shù)。ini文件中的[data]和[preprocess]兩個section下可以自定義calibrationResNet50batch_size、preprocessed_h和preprocessed_wimage_list,也可以指定為數(shù)據(jù)集的路徑,只要在preprocess_cali類里面能根據(jù)data_path;data_pathbatch_size=num_runs= ;num_runspreprocessed_w=224 calibration= ;calibrationsave_model_path=./pbs/resnet50_v1/resnet50_v1_int8.pbinput_tensor_names=input:0quantization_type=use_convfirst=Falseactivation_quantization_alg=naiveweight_quantization_alg=naivechannel_quantization=Falsedevice_mode=上面提到的da_th為./image_list_imagenet,在這個例子中imae_lit_imaent內(nèi)容如下:(下頁繼續(xù)據(jù)的方式能和這里定義的data_path添加resnet50_v1_preprocess_cali在tensorflow/cambricon_examples/tools/fppb_to_intpb/calibrate_data.py文件中添加為esNt50v1網(wǎng)絡(luò)提供校準數(shù)據(jù)的類esnt50_v1_pepoess_alinit方法和nt方法的參數(shù)列表必須是init(sel,aams)和nt(self),ini文件中[da]和[pepoess]下定義的參數(shù)都會通過init的aams參數(shù)傳入到這個類中,nt方法的返回值必須是網(wǎng)絡(luò)的eed_di(Session.run的eed_di。比如為esNt50v1添加了下列代碼:importdefread_image_batch(file_list,batch_size,ifbatch_size>raiseValueError("batch_sizemustbelessequalthanfile_listsize.")batch_data=[]start=iters*ifstart<end=start+batch_sizeif(start+batch_size)<len(file_list)elseforpathinfile_list[start:end]:print("Warning:batch_size*num_runs>file_listforpathinfile_list[-batch_size:]:returnbatch_datadefwithopen(input_image_list,"r")asimages_path=[line.strip()forlinein

returnclassdefinit(self,"""Getallnecessaryparametersfromself.iter=-self.file_list=read_file(params['data_path'])self.batch_size=int(params['batch_size'])self.out_h=int(params['preprocessed_h'])self.out_w=int(params['preprocessed_w'])self.input_tensor_names= #params[preprocess]和[data]下的參數(shù),還會加入[model]下的def"""Readnextbatchinputsandpreprocessthem.Returnaself.iter+=batch_data=read_image_batch(self.file_list,self.batch_size,self.iter)batch_data=[self.resnet50_v1_preprocess(image)forimageinbatch_data]batch_data=np.asarray(batch_data)iflen(batch_data.shape)=="ifbatch_sizeisgreaterthan1.")return{self.input_tensor_names[0]:defresnet50_v1_preprocess(self,resize_side_min=ifresize_side_min<min(self.out_h,raiseValueError("resnet50_v1_preprocessresize_side_minmustbegreaterequal"{}vs.{}".format(resize_side_min,min(self.out_h,self.out_w)))image_h=image.shape[0]image_w=#scale=resize_side_min/min(image_h,image_w)resize_h=int(round(image_h*scale))resize_w=int(round(image_w*resized_image=cv2.resize(image.astype(np.float32),(resize_w, #offset_h=(resize_h-self.out_h)/2offset_w=(resize_w-self.out_w)/2croped_image=resized_image[offset_h:offset_h+self.out_h,last_image=croped_image-[mean_r,mean_g,returnresnet50_v1_preprocess_caliinitparams讀取和前處理相關(guān)的參數(shù)以供nextparamsini[preprocess][data]的是paramsnext函數(shù)主要是進行輸入數(shù)據(jù)的讀取和前處理。需要注意的是如果網(wǎng)絡(luò)的前處理包含在graph是一個字典,形式和session.run的feed_dictpreprocess_caliinit函數(shù)和next最后在tensorflow/cambricon_examples/tools/fppb_to_intpb/calibrate_data.py文件的get_calibrate_data函數(shù)的calibrate_data_mapdefdefget_calibrate_data(params,name="default_preprocess_cali"):print("calibrate_data:",name)calibrate_data_map={"no_preprocess_cali":no_preprocess_cali,"default_preprocess_cali":[preprocess]下面定義的名稱,valuereturn"resnet50_v1_preprocess_cali":resnet50_v1_preprocess_cali,#keyini目前calibrate_data.py文件提供一些前處理的demo以供參考。關(guān)于FirstConvFirstConvTrue。關(guān)于FirstConv息,參見FirstConv。55CambriconTensorFlowC++支持的數(shù)[05][05][04][05][44][44]5.1–C++支持的數(shù)[05][05][05][04][44][05][05][05][05][05][05]C++支持的數(shù)[05][04][04][05][05][44][33][44][44]C++支持的數(shù)[11][05][05][05][05][05][05][05][25][34][22][05][05][05]5.1–C++支持的數(shù)[05][44][0,[44][44][05][44][44][05][05][44][05][05]C++支持的數(shù)[05][05][04][05][0,[05][44][44][0,[05][05][05][05]5.1–C++支持的數(shù)[0,[05][05][04][05][05][0,[0,[05][05][04][05][05]C++支持的數(shù)[05][44][44][05][05][05][04][05][05][05][05][05][05]C++支持的數(shù)[05][05][05][04][05]66本章以添加自定義激活算子Relu20為例,說明如何在CambriconTensorFlow注冊O(shè)P在tensorflow/core/user_ops/mlu_special_ops.cc文件中,類比其他已有的自定義算子利用REGISTER_OP的宏注冊Relu20.Input("features:.Output("activations:.Attr("T:{half,在REGISTER_OP根據(jù)算子的實際情況,可以先檢查已封裝的形狀推斷函數(shù)是否滿足條件(在tensorflow/core/framework/common_shape_fns.h中,比如本例中Relu20指定的UnchangedShape)。如果不滿足條件,需要自定義形狀推斷函數(shù)(形狀推斷的相關(guān)函數(shù)可以在tensorflow/core/framework/shape_inference.h找到,也可以參考其他自定義形狀推斷函數(shù)。以上就完成了Relu20注冊O(shè)pKernelOpernel即注冊的OpOpernel(M、CP。在tensorflow/core/kernels/mlu_kernels文件夾下,創(chuàng)建新文件relu20_op.cc。在該文件中利用REGISTER_KERNEL_BUILDER宏進行注冊。使用該宏時,保證Name中的字符串和步驟1中REGITER_OP中的算子名稱相同。通過調(diào)用TF_CALL_MLU_FLOAT_TYPES向REGISTER_MLUhalffloat(這里,#define#define #undef添加自定義算子時,除了注冊MLUKernel,最好同時注冊CPUKernel。如果缺乏CPU以下為注冊CPUKernel在tensorflow/compiler/tf2mlu/convert/convert_nodes.cc的op_types_map(以op_name為key,data_typevalue)中加入新添加的算子及允許進入融合段的數(shù)據(jù)類型。constconstOpTypesMapop_types_map={"Abs",{{"T",{DT_FLOAT,//{"Relu20",{{"T",{DT_FLOAT,{"Relu20",{}}, 注冊融合用的OpKernel(OpConverterstaticvoidRegisterValidatableOpConverters(std::unordered_mapstaticvoidRegisterValidatableOpConverters(std::unordered_map<string,OpConverter>*registration){(*registration)["ArgMax"]=//(*registration)["Relu20"]=之后添加對應(yīng)Op的convert(具體實現(xiàn),見后面的步驟:MLURelu20Layerlayer;在fp16 gtl::FlatSet<string>WhiteList()中加入staticstaticgtl::FlatSet<string>WhiteList()//autolist=gtl::FlatSet<string>//return在tensorflow/compiler/tf2mlu/convert/nodes文件夾下,創(chuàng)建新文件relu20.h現(xiàn)一個MLURelu20Layer類:////Copyright[2020]#define#includenamespacetensorflow{namespacemlu_fusion{namespaceconvert{classMLURule20LayerexplicitMLURelu20Layer(OpConverterContext*ctx)voidconvert(OpConverterContext*ctx)//添加必要的參數(shù)檢查(可選if(!ctx->ValidateInputsAreSameShape(ctx))//ctxconstTensor&input=ctx-//添加必要的零元素檢查(可選CONVERT_REQUIRES_NON_ZERO_ELEMENT(ctx,//添加輸出//common_inc.hCONVERT_REQUIRES_OK(ctx,}//namespace}//namespace}//namespace#endif//之后需要在tensorflow/compiler/tf2mlu/convert/nodes/layers.h中加入新創(chuàng)建的頭文件 relu20.h 在tensorflow/compiler/tf2mlu/convert/nodes/common_inc.h中有一個公共接口StatusStatusRelu20(OpConverterContext*ctx)returnCommonFusionImpl會默認使用OpConverterContext中的inputtensortensorflow/compiler/tf2mlu/convert/nodes/add_stride.h3.添加MLURelu20首先在tensorflow/stream_executor/mlu/mlu_api/ops/mlu_ops.h中聲明之后在tensorflow/stream_executor/mlu/mlu_api/ops/中創(chuàng)建新文件relu20.cc,用于實現(xiàn)classMLURelu20的CreateMLUOp方法:#include#include"tensorflow/stream_executor/mlu/mlu_api/lib_ops/mlu_lib_ops.h"#include"tensorflow/stream_executor/mlu/mlu_api/ops/mlu_ops.h"#include"tensorflow/stream_executor/mlu/mlu_api/tf_mlu_intf.h"namespacemludoubleRelu20(doublex)return(x<0)?0:((x<20)?x:std::vector<cnmlTensor*>&outputs,void*param){TF_PARAMS_CHECK(inputs.size()>0,"Missinginput");TF_PARAMS_CHECK(outputs.size()>0,"Missingoutput");cnmlBaseOp*customized_active_op_ptr=nullptr;cnmlTensor*input=inputs.at(0);MLULOG(3)<<"Create<<",inputshape:"<<<<",outputshape:"<<double(*active_func_ptr)(double)=Relu20;reinterpret_cast<void*>(active_func_ptr),input,return}//namespace}//namespace}//namespace其中,lib::CreateCustomizedActiveOp實現(xiàn)在tensorflow/stream_executor/mlu/mlu_api/lib_ops/mlu_lib_ops.cc中,只是對底層接口的簡單封裝,根據(jù)實際需求添加即可。.修改BUILD4.添加OpKernel由于本章是介紹如何添加融合自定義算子,默認用戶只有運行融合模式的需求。對于原生的OpKernel,只需添加一個空的實現(xiàn)即可。更多內(nèi)容,參見《寒武紀TensorFlowclassMLURelu20Op:publicOpKernelexplicitMLURelu20Op(OpKernelConstruction*context):OpKernel(context){LOG(FATAL)<<"Relu20:noimplemented.";voidCompute(OpKernelContext*ctx)overrideclassCPURelu20Op:publicOpKernelexplicitCPURelu20Op(OpKernelConstruction*context):OpKernel(context)voidCompute(OpKernelContext*ctx)override{constTensor&input=ctx->input(0);Tensor*output=nullptr;OP_REQUIRES_OK(ctx,ctx->allocate_output(0,input.shape(),此處的CPURelu20Op這個Kerneloutput_shape修改BUILD在添加新算子過程中,只需要修改BUILDtensorflow/core/kernels/mlu_kernels/BUILD該文件主要完成以下內(nèi)容:他targetmlu_core_kernelsrelu20_op作為新的依賴項,從而能夠編譯進整個TensorFlow在生成mlu_core_kernels目標函數(shù)的deps域中,添加一行":relu20_op"name=srcs=["relu20_op.cc"],deps=[#Publicsupportdeps=[...//在PythonAPI和C++API中分別通過調(diào)用Relu20和gen_user_ops.relu20importimportimportnumpyasnpimporttensorflowastffromtensorflow.python.opsimportconfig=tf.ConfigProto(log_device_placement=False)config.mlu_options.core_num=1config.graph_options.rewrite_options.constant_folding=2config.graph_options.rewrite_options.arithmetic_optimization=config.graph_options.rewrite_options.remapping=2sess=tf.Session(config=config)(下頁繼續(xù)deftest(x_shape,x_val=np.random.randint(-10,30,x=tf.placeholder(dtype=tf.float32,withres_mlu=gen_user_ops.relu20(x,mlu=sess.run(res_mlu,defmain():(16,(16,4,6,fori,shapeintest(shape,ifname=="main77tensordump使用tensordump功能將網(wǎng)絡(luò)中各節(jié)點輸出tensordump到指定文件夾,后使用誤差計算工具輸出將以下內(nèi)容寫入配置文件fusion_dump_config.iniexportTF_MLU_FUSION_DUMP_TENSOR=trueexport#.TENSORDUMP運行結(jié)束后,融合段的中間tensordumpPath所指定的文件夾中。dump出來的例如:2_resnet50.conv_1.conv2d_output_0_mlufusion_5其中,execution_times:該tensor被第幾次dump(這個節(jié)點被第幾次運行。此例中為2node_name:節(jié)點名稱。此例中為resnet50.conv_1.conv2d。原本名稱應(yīng)為“/output_port:此文件是這個node0execution_order_in_fusion:此tensordump5如果開啟了tensordump功能,每次運行前,必須清空fusion_dump_dir融合模式會有WarmUp的過程。如果運行網(wǎng)絡(luò)的程序中存在使用假數(shù)據(jù)WarmUp預(yù)編譯的代碼,會導(dǎo)致dump使用tensordump因此,在使用tensordump功能進行精度調(diào)試時,需移除使用假數(shù)據(jù)WarmUp的代碼。關(guān)于該工具的更多內(nèi)容,參見《寒武紀TensorFlow在MLU上以融合模式運行并dumptensor將以下內(nèi)容寫入配置文件fusion_dump_config.iniexportTF_MLU_FUSION_DUMP_TENSOR=trueexport //在MLU上以nativedumptensorunsetunsetexportexport //cdcd(下頁繼續(xù).MLU打開output_wrong.txt文件找到第一個誤差大于閾值的節(jié)點。打開output_abnormal.txt文件找到第一個出現(xiàn)異常的節(jié)點。MLU中。內(nèi)存越界的bug(出現(xiàn)的時機和出錯的現(xiàn)象都是隨機的,很難定位。別插入header和footer,在deallocate時拷回到host端檢查之前插入的header和master打開MLU內(nèi)存越界檢查之后,程序會進入同步模式。計算圖運行模式和默認不同,運行速度會變慢,有遇到日志中有[cnrtError]、mluunfinished這些關(guān)鍵字時,執(zhí)行exportTF_MLU_DEBUG_MEMORY_OVERSTEP=true打開內(nèi)存越界檢查。如果出現(xiàn)coredump并且日志中有Footermaskhasbeenoverwritten或者Headermaskhasbeenoverwritten類似內(nèi)容,說明存在20212021-01-1810:50:48.701641:[cnrtError][186985][Card:0]Erroroccurredin2021-01-1810:50:48.701678:[cnrtError][186985][Card:0]Returnvalueis230,?→CHECKfailed.Function:MLUCnrtMemcpyAsync@line:221returnedcode632046:Unknownerror.?→errordetected,forceterminating...Aborted(coredumped)若log[cnrtError],設(shè)置exportTF_MLU_DEBUG_MEMORY_OVERSTEP=true20212021-01-1811:15:05.364044:E?→cc:141][230845]i=0mask=0xcdcdcdcdcdcdcdcd2021-01-1811:15:05.364053:E?→cc:141][230845]i=1mask=0xcdcdcdcdcdcdcdcd2021-01-1811:15:05.364059:E?→cc:229][230845]Footermaskhasbeenoverwritten,ptr=2021-01-1811:15:05.364067:E?→cc:235][230845]wasallocated2021-01-1811:15:05.364238:I?→cc:101][230845]call可以看出,新生成的logFootermaskhasbeenoverwritten遇到精度問題(比如,在CPU上運行結(jié)果正確,在MLU運行誤差較大)一般需要先定位出哪個節(jié)點異常導(dǎo)致的,這就需要使用tensordump功能和誤差計算工具。如果定位到的異常節(jié)點的算子是ConvMatMul為了進一步確認問題,可編寫單算子測試,使用上一個節(jié)點dump出的output試CPU與MLU的結(jié)果。總之,無論是什么類型的精度異常,都可以優(yōu)先通過dump功能找出異常節(jié)點,后處理該節(jié)點對應(yīng)的以YOLOv4tensordump功能和誤差計算工具定位精度問題節(jié)點。在執(zhí)行以下步驟前,確保已安裝CambriconTensorFlowcdcd$TENSORFLOW_BENCHMARK_HOME/benchmarks/cn_benchmarks/YOLO/Keras-./run_evaluate.sh111執(zhí)行成功后,會在當前目錄下生成量化參數(shù)文件yolov4_quant_param_int16.txt本例中,將import/conv2d_27/convolution/input1331.080.1YOLOv4predictsessionrun:一次編譯,另一次真正執(zhí)行。如果不注釋掉會dump兩次tensor,浪費時間。vivi$TENSORFLOW_BENCHMARK_HOME/models/third_party/Keras-注釋掉predict3defpredict(self,#if(self.cur_iter==-self.cur_iter+=start=self.input_ph:dumpCPU上的運算結(jié)果作為真值。mkdirmkdirexportexportexport./run_evaluate.sh111dumpMLU上的運算結(jié)果用于比對。mkdirmkdirexportexportexportexportexport(下頁繼續(xù)export./run_evaluate.sh111對比結(jié)果:使用誤差計算工具對比CPU和MLUlnln-s$TENSORFLOW_HOME/tensorflow/cambricon_examples/tools/debug_tool/?→dumps_mlu--output_wrong.txt、output_all.txt````output_wrong.txt文件,第一個節(jié)點就是異常節(jié)點,節(jié)點import.conv2d_27.convolution即為模擬異常步驟中修改的節(jié)點。truth_value_file:import.conv2d_27.convolution_output_0_740test_value_file:1_import.conv2d_27.convolution_output_0_mlufusion_86tensor_name:import/conv2d_27/convolution:0iteration:error_rate:is_same_size:truth_value_file:import.batch_normalization_27.FusedBatchNorm_1_output_0_741iteration:error_rate:is_same_size:有時可能無法設(shè)置一個合適的threshold恰好過濾出異常節(jié)點,可以通過查看output_all.txt文件點的error_rateerror_rate的節(jié)點由于可能會受到異常節(jié)點的影響,其error_rate本例中可以看出import.conv2d_27.convolutiontruth_value_file:import.mish_25_output_0_738test_value_file:1_import.mish_25_output_0_mlufusion_84tensor_name:import/mish_25:0iteration:error_rate:mse:is_same_size:truth_value_file:import.add_6.add_output_0_739test_value_file:1_import.add_6.add_output_0_mlufusion_85tensor_name:import/add_6/add:0iteration:error_rate:mse:is_same_size:truth_value_file:import.conv2d_27.convolution_output_0_740test_value_file:1_import.conv2d_27.convolution_output_0_mlufusion_86tensor_name:import/conv2d_27/convolution:0iteration:error_rate:mse:is_same_size:88在使用CambriconTensorFlow運行網(wǎng)絡(luò)之前先進行離線量化。相比在線量化,離線量化的性能更好。關(guān)于離線量化的更多內(nèi)容,參見離線量化。使用FP16運行網(wǎng)絡(luò)時設(shè)置環(huán)境變量TF_MLU_FP16_OPTIMIZATION_LEVEL1以開啟FP16模式。在FP16足網(wǎng)絡(luò)精度的情況下,相比于FP32,F(xiàn)P161、4、16。使用Pythonconfigconfig=tf.ConfigProto()withtf.Session(config=config)assess:result=sess.run(...)使用CC++SessionOptionsSessionOptionsoptions;std::unique_ptr<Session>session(NewSession(options));.使用FROZEN使用frozen融合模式理論上支持TensorFlowfrozengraph格式的模型,建議先轉(zhuǎn)換為frozengraph,后再運行融合模式。以下介紹如何將SavedModel和ckpt轉(zhuǎn)換為frozengraph將SavedModel轉(zhuǎn)換成frozenwithwithtf.Session()assess:frozen_graph=tf.graph_util.convert_variables_to_constants(output_node_names=['logits','classes'])將ckptfrozenwithwithtf.Session()as#Firstcreatea`Saver`object(forsavingandrebuilding#model)andimportyour`MetaGraphDef`protocolbufferintoit:saver=tf.train.import_meta_graph("/path/to/your/model.ckpt.meta")#Thenrestoreyourtrainingdatafromcheckpointfiles:saver.restore(sess,"/path/to/your/model.ckpt")#Finally,freezethefrozen_graph=tf.graph_util.convert_variables_to_constants(output_node_names=['logits','classes'])增大batch當batchsizebatchsizebatchsize1416minimum_sgment_si被替換成MUusionO1替換為MUusionO。如果在調(diào)試中遇到某個融合段有功能問題(比如出現(xiàn)crash)或者性能問題時,可將最小分段數(shù)設(shè)置為exportexportFirstConv優(yōu)化是底層CNML庫針對網(wǎng)絡(luò)的首層Conv2DConv2DFirstConv輸入的CCNMLFirstConvConv2DC13。inputimagemeanstd其中,input表示網(wǎng)絡(luò)首層Conv2Dimagemean和std細介紹,參見離線模式簡介。.FIRSTCONV使用環(huán)境變量量化時,如果要使用FirstConv優(yōu)化,需要在量化階段配置量化參數(shù)文件時,增加convfirst_param#Conv2D###meanfilestd和color_mode,還需要將use_convfirst的值設(shè)為True。如下所示:mean=123.68,116.78,;每行依次為mean_r、mean_g、mean_b,以逗號隔開,與meanmeanfile=;h*wstd=color_mode=;rgb、bgr、;use_convfirst=Conv2D當使用FirstConv優(yōu)化時,如果將首層Conv2D的輸入的C4,可以進一步提升首層Conv2D算子的性能。但是,由于補齊操作會額外引入其他開銷,影響整體性能,因此默如果是離線部署,而且CPU算力足夠,可以在生成離線模型時執(zhí)行補齊操作并且放到CPU上運行,這樣可以獲得更優(yōu)的全局性能。關(guān)于離線模式的詳細介紹,參見離線模式簡介。CambriconTensorFlow提供環(huán)境變量TF_MLU_ADD_STRIDE來控制是否執(zhí)行補齊操作以及補齊操作運行成離線模型時設(shè)置相應(yīng)的值即可,例如,執(zhí)行exportTF_MLU_ADD_STRIDE=1。99TensorFlow框架基于CNML(CambriconNeuwareMachineLearning,寒武紀機器學(xué)習(xí)庫)在線構(gòu)建融合模型,并將編譯過程中生成的MLU指令、數(shù)據(jù)等寫入到文件,該文件稱為離線模型。離線模型包含模型版本、MLU指令、權(quán)值數(shù)據(jù)、輸入輸出數(shù)據(jù)規(guī)模、參數(shù)信息等。用戶通過CNRT(CambriconNeuwareRuntimeLibrary,寒武紀運行時庫)API加載離線模型并驅(qū)動MLU完成計算的運行模式稱為離線模式可免去編譯過程所產(chǎn)生的開銷,減少了運行依賴,也避免了對TensorFlow框架和CNML等的不是所有在TensorFlow關(guān)于如何查看網(wǎng)絡(luò)是否為單段的更多信息,參見FAQTensorFlowpb_to_cambricon和使用SessionConfigpb_to_cambricon為單獨使用的工具,僅依賴獨立編譯的二進制文件;SessionConfig使用時需依賴TensorFlowdemo。pb_to_cambricon工具除MLUCPUMLU270或者MLU220SessionConfigMLU離線模型生成工具pb_to_cambricon為C++cdcd若當前目錄下生成pb_to_cambricon.host如果僅想使用離線功能,無需整體編譯TensorFlow,編譯build_host.sh即可 --------??gap:需要轉(zhuǎn)換成離線模型的pb文件。使用離線工具前,要確保pb在線模式可以單段運行成功,如舊量化模式下的MU量化模型作為輸入,亦或在新量化模式下設(shè)置好在線運行環(huán)境變量和量化文件,將與其對應(yīng)的原生pb模型作為輸入。??mlu_core_version:目標支持的MLU卡。目前支持MLU270、MLU220、1M70、1M20??oe_nuMUMU270oe_num可設(shè)置為1416MU220oe_num可設(shè)置為1、4;對于1M70和1M20,oe_num僅可設(shè)置為1。不同核數(shù)對應(yīng)的離線文件不同。用“,”分隔。目前支持的keys支持的option_keys。 input_nodes指定模型的Session::Run指定Session::Run信息數(shù)字n表示輸入節(jié)點的個數(shù),“xxxx名稱dim_size(0)dim_size(n?Shapedim_size(0)模型輸入的batch_size注:模4指定Session::Runn以ResNet50v1和SSD(下頁繼續(xù)9.2:支持的對于保存離線模型的參數(shù),要在創(chuàng)建SessionConfigPythonC++賴的環(huán)境為安裝CambriconTensorFlow的環(huán)境。有關(guān)安裝CambriconTensorFlow《寒武紀TensorFlowoffline_model_name:指定離線模型的名稱。string類型,默認為offline_model configconfig=**config.mlu_options.save_offline_model=withtf.Session(graph=graph,config=config)asC++SessionOptionsSessionOptionsoptions;**session_config.mutable_mlu_options()-std::unique_ptr<tensorflow::Session>session(tensorflow::NewSession(options));session->Run(...在TensorFlow中,提供基于ImageNetcd/tensorflow_srcsourceenv.shcdcd/tensorflow_srcsourceenv.shcdcd./classify_offlinecd./classify_offline--offline_model=${offline_model}--images_file=${file_list_

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論