闪退没由报错_秉承工匠精神,3步定位飞桨报错原因,你也来试试?
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                闪退没由报错_秉承工匠精神,3步定位飞桨报错原因,你也来试试?
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
                                點擊左上方藍(lán)字關(guān)注我們
【故事的開始…】小張是一名AI算法攻城獅,聽聞飛槳乃國產(chǎn)開源深度學(xué)習(xí)框架之光,心想炎黃子孫當(dāng)自強,用自己的深度學(xué)習(xí)框架,實現(xiàn)中國的AI夢……他嘗試在的筆記本上使用飛槳搭建線性回歸示例模型。噼里啪啦…噼里啪啦…鍵盤敲的熱血澎湃。跑下試試……然而,模型的打印結(jié)果讓小張滿懷期待的小心情頓時哇涼哇涼的。丹還沒煉成,爐咋就壞了呢?這鋪天蓋地的error,要怎么分析和處理?【故事的轉(zhuǎn)折…】同學(xué)且慢,經(jīng)官方鑒定,小張大概率使用的是較早版本的飛槳,飛槳開源框架1.7及之后版本斷然不會出現(xiàn)這么繁雜的報錯信息了。這是因為飛槳工程師們一直期望產(chǎn)品不但好用,而且易用,可以給開發(fā)者帶來一點點工作上的愉悅。報錯信息對調(diào)試分析至關(guān)重要,飛槳工程師也一直在持續(xù)地進(jìn)行改進(jìn)和優(yōu)化。
解讀最新的飛槳報錯信息
飛槳報錯信息總體上分為兩種:一種是直接在Python層攔截報出的錯誤,這種問題一般比較直觀,根據(jù)Python原生的報錯棧即可以定位程序中的問題,和大家使用Python寫程序報錯分析的流程一致;一種是飛槳的C++ core中的報錯,這種報錯包含的信息量較大。下面我們以此類報錯信息的為例,解讀分析過程。首先我們了解下目前飛槳最新版本報錯信息的結(jié)構(gòu),如下圖:報錯信息為四段式結(jié)構(gòu),由上至下依次為Python默認(rèn)錯誤信息棧、C++錯誤信息棧、飛槳Python錯誤信息棧(僅聲明式編程模式)、核心錯誤概要。- Python默認(rèn)錯誤信息棧:執(zhí)行Python程序默認(rèn)記錄的執(zhí)行路徑,對定位報錯位置很有幫助。這是Python本身特性,此處不展開介紹。
- C++錯誤信息棧:程序在Paddle C++ core中的錯誤路徑,即為模塊paddle.fluid.core中的程序執(zhí)行路徑,這部分信息對開發(fā)者幫助有限。但當(dāng)開發(fā)者通過Issue向飛槳開發(fā)人員提問時,提供C++報錯棧的信息將有助于開發(fā)人員快速定位問題。(目前C++錯誤信息棧僅支持Unix平臺,Windows平臺暫不支持)
- Paddle Python錯誤信息棧:為什么這里還有一個Paddle Python錯誤信息棧呢?因為在聲明式編程模式(靜態(tài)圖)下,模型編譯和執(zhí)行是分離的。執(zhí)行時報錯的路徑由Python默認(rèn)程序棧記錄,但這并不能告知用戶具體出錯的程序位置,因此對于算子類型的API,飛槳額外記錄了編譯時的執(zhí)行路徑,幫助開發(fā)者定位具體代碼出錯的位置,該部分信息對于調(diào)試具有較大意義。
- 核心錯誤概要:信息包含錯誤類型、錯誤特征、概要提示、出錯文件名與行號、出錯算子名等,這些信息不僅有助于開發(fā)者理解錯誤,也有助于迅速定位錯誤。
硬核來了,3步快速定位問題
當(dāng)使用飛槳遇到報錯提示時,定位流程是啥樣子的呢?請對應(yīng)上文提到的飛槳報錯信息結(jié)構(gòu)圖,按如下流程逐步分析。報錯信息分析流程下面結(jié)合示例,向大家講解飛槳的報錯信息的分析過程(示例使用飛槳2020年7月1日的develop版本)。飛槳支持兩種編程模式,聲明式編程模式(靜態(tài)圖)和命令式編程模式(動態(tài)圖),我們將逐一介紹。飛槳聲明式編程模式
(靜態(tài)圖)報錯解讀
執(zhí)行如下靜態(tài)圖示例代碼:import?paddle.fluid?as?fluidimport?numpy#?1.?網(wǎng)絡(luò)結(jié)構(gòu)定義
x?=?fluid.layers.data(name='X',?shape=[-1,?13],?dtype='float32')
y?=?fluid.layers.data(name='Y',?shape=[-1,?1],?dtype='float32')
predict?=?fluid.layers.fc(input=x,?size=1,?act=None)
loss?=?fluid.layers.square_error_cost(input=predict,?label=y)
avg_loss?=?fluid.layers.mean(loss)#?2.?優(yōu)化器配置
fluid.optimizer.SGD(learning_rate=0.01).minimize(avg_loss)#?3.?執(zhí)行環(huán)境準(zhǔn)備
place?=?fluid.CPUPlace()
exe?=?fluid.Executor(place)
exe.run(fluid.default_startup_program())#?4.?執(zhí)行網(wǎng)絡(luò)
x?=?numpy.random.random(size=(8,?12)).astype('float32')
y?=?numpy.random.random(size=(8,?1)).astype('float32')
loss_data,?=?exe.run(fluid.default_main_program(),?feed={'X':?x,?'Y':?y},?fetch_list=[avg_loss.name])代碼執(zhí)行后的報錯信息如下:Traceback?(most?recent?call?last):
??File?"paddle_error_case1.py",?line?24,?in?<module>
????loss_data,?=?exe.run(fluid.default_main_program(),?feed={'X':?x,?'Y':?y},?fetch_list=[avg_loss.name])
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/executor.py",?line?1079,?in?run
????six.reraise(*sys.exc_info())
??File?"/usr/local/lib/python3.5/dist-packages/six.py",?line?696,?in?reraise
????raise?value
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/executor.py",?line?1074,?in?run
????return_merged=return_merged)
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/executor.py",?line?1162,?in?_run_impl
????use_program_cache=use_program_cache)
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/executor.py",?line?1237,?in?_run_program
????fetch_var_name)
paddle.fluid.core_avx.EnforceNotMet:?
--------------------------------------------
C++?Call?Stacks?(More?useful?to?developers):
--------------------------------------------0???std::string?paddle::platform::GetTraceBackString<:string>(std::string?const&,?char?const*,?int)1???paddle::platform::EnforceNotMet::EnforceNotMet(std::string?const&,?char?const*,?int)2???paddle::operators::MulOp::InferShape(paddle::framework::InferShapeContext*)?const3???paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope?const&,?paddle::platform::Place?const&,?paddle::framework::RuntimeContext*)?const4???paddle::framework::OperatorWithKernel::RunImpl(paddle::framework::Scope?const&,?paddle::platform::Place?const&)?const5???paddle::framework::OperatorBase::Run(paddle::framework::Scope?const&,?paddle::platform::Place?const&)6???paddle::framework::Executor::RunPartialPreparedContext(paddle::framework::ExecutorPrepareContext*,?paddle::framework::Scope*,?long,?long,?bool,?bool,?bool)7???paddle::framework::Executor::RunPreparedContext(paddle::framework::ExecutorPrepareContext*,?paddle::framework::Scope*,?bool,?bool,?bool)8???paddle::framework::Executor::Run(paddle::framework::ProgramDesc?const&,?paddle::framework::Scope*,?int,?bool,?bool,?std::vector<:string>?>?const&,?bool,?bool)
------------------------------------------
Python?Call?Stacks?(More?useful?to?users):
------------------------------------------
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/framework.py",?line?2799,?in?append_op
????attrs=kwargs.get("attrs",?None))
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/layer_helper.py",?line?43,?in?append_opreturn?self.main_program.current_block().append_op(*args,?**kwargs)
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/layers/nn.py",?line?349,?in?fc"y_num_col_dims":?1})
??File?"paddle_error_case1.py",?line?9,?in?<module>
????predict?=?fluid.layers.fc(input=x,?size=1,?act=None)
----------------------
Error?Message?Summary:
----------------------InvalidArgumentError:?After?flatten?the?input?tensor?X?and?Y?to?2-D?dimensions?matrix?X1?and?Y1,?the?matrix?X1's?width?must?be?equal?with?matrix?Y1's?height.?But?received?X's?shape?=?[8,?12],?X1's?shape?=?[8,?12],?X1's?width?=?12;?Y's?shape?=?[13,?1],?Y1's?shape?=?[13,?1],?Y1's?height?=?13.
??[Hint:?Expected?x_mat_dims[1]?==?y_mat_dims[0],?but?received?x_mat_dims[1]:12?!=?y_mat_dims[0]:13.]?at?(/work/paddle/paddle/fluid/operators/mul_op.cc:83)
??[operator??error]參考飛槳報錯信息分析流程對這個錯誤示例進(jìn)行剖析。1. 首先分析代碼核心錯誤概要。依據(jù)統(tǒng)一的報錯結(jié)構(gòu),開發(fā)者可以快速的找到報錯原因。從示例中可獲得如下信息:這是一個參數(shù)錯誤;出錯的Op是mul;mul Op輸入的Tensor X矩陣的寬度,即第2維的大小需要和輸入Tensor Y矩陣的高度,即第一維的大小相等,才可以進(jìn)行正常的矩陣乘法;給出了具體的輸入X與Y的維度信息即出錯維度的值,有一處的維度寫錯了,可能是13誤寫成了12。目前飛槳有12種錯誤類型,更多介紹請查看《報錯信息文案書寫規(guī)范》,鏈接如下:https://github.com/PaddlePaddle/Paddle/wiki/Paddle-Error-Message-Writing-Specification2. 其次分析Paddle 編譯時Python錯誤信息棧,發(fā)現(xiàn)出錯的代碼位置如下:Paddle插入的Python錯誤信息棧為了和C++棧的調(diào)用順序保持一致,最下面的信息是用戶代碼的位置,這和原生python錯誤信息棧的順序有所區(qū)別。這里我們可以得知,是調(diào)用fc的時候出錯的,fc中包含一個乘法運算和一個加法運算,根據(jù)前面的信息可以得知是此處的乘法運算的輸入數(shù)據(jù)存在問題。至此,通過檢查代碼,可以找到錯誤位置:將代碼中的12改為13,即可解決該問題。3. (可選)通常出錯場景較為簡單時,C++錯誤信息棧可以不關(guān)心。但如果用戶在解決時遇到困難,需要飛槳開發(fā)人員協(xié)助解決時,需要反饋此信息,幫助開發(fā)人員快速得知底層的出錯執(zhí)行邏輯。例如在這個例子中,我們能夠得知程序的執(zhí)行路徑為Run -> RunPreParedContext -> Run -> RunImpl -> MulOp::InferShape,InferShape是檢查算子輸入輸出及參數(shù)維度的方法,由此可以推斷出,本錯誤是由于Mul算子的輸入?yún)?shù)維度出錯導(dǎo)致。
飛槳命令式編程模式
(動態(tài)圖)報錯解讀
動態(tài)圖不區(qū)分網(wǎng)絡(luò)模型的編譯期和執(zhí)行期,報錯信息中不需要再插入編譯時的python信息棧。執(zhí)行如下動態(tài)圖示例代碼:import?numpyimport?paddle.fluid?as?fluidplace?=?fluid.CPUPlace()
with?fluid.dygraph.guard(place):
????x?=?numpy.random.random(size=(10,?2)).astype('float32')
????linear?=?fluid.dygraph.Linear(1,?10)data?=?fluid.dygraph.to_variable(x)
????res?=?linear(data)代碼執(zhí)行后的報錯信息如下:/work/scripts?{master}?python?paddle_error_case2.py?
Traceback?(most?recent?call?last):
??File?"paddle_error_case2.py",?line?9,?in?<module>
????res?=?linear(data)
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/dygraph/layers.py",?line?600,?in?__call__
????outputs?=?self.forward(*inputs,?**kwargs)
??File?"/usr/local/lib/python3.5/dist-packages/paddle/fluid/dygraph/nn.py",?line?965,?in?forward'transpose_Y',?False,?"alpha",?1)
paddle.fluid.core_avx.EnforceNotMet:?
--------------------------------------------
C++?Call?Stacks?(More?useful?to?developers):
--------------------------------------------0???std::string?paddle::platform::GetTraceBackString<:string>(std::string?const&,?char?const*,?int)1???paddle::platform::EnforceNotMet::EnforceNotMet(std::string?const&,?char?const*,?int)2???paddle::operators::MatMulOp::InferShape(paddle::framework::InferShapeContext*)?const3???paddle::imperative::PreparedOp::Run(paddle::imperative::NameVarBaseMap?const&,?paddle::imperative::NameVarBaseMap?const&,?paddle::framework::AttributeMap?const&)4???paddle::imperative::Tracer::TraceOp(std::string?const&,?paddle::imperative::NameVarBaseMap?const&,?paddle::imperative::NameVarBaseMap?const&,?paddle::framework::AttributeMap,?paddle::platform::Place?const&,?bool)5???paddle::imperative::Tracer::TraceOp(std::string?const&,?paddle::imperative::NameVarBaseMap?const&,?paddle::imperative::NameVarBaseMap?const&,?paddle::framework::AttributeMap)
----------------------
Error?Message?Summary:
----------------------InvalidArgumentError:?Input?X's?width?should?be?equal?to?the?Y's?height,?but?received?X's?shape:?[10,?2],Y's?shape:?[1,?10].
??[Hint:?Expected?mat_dim_x.width_?==?mat_dim_y.height_,?but?received?mat_dim_x.width_:2?!=?mat_dim_y.height_:1.]?at?(/work/paddle/paddle/fluid/operators/matmul_op.cc:411)
??[operator??error]同樣,我們可以依據(jù)前面講述的步驟對報錯進(jìn)行分析。1. 先分析核心錯誤概要,該錯誤與前面的實例類似,也是輸入數(shù)據(jù)的維度和預(yù)期不一致,出錯的Op是matmul。2. 再分析Python報錯信息棧,可以得知出錯的代碼位置為:通過檢查代碼,也可以比較容易地定位到錯誤位置在:將代碼中的2改為1,即可解決該問題。【故事的尾聲…】報錯信息的有效性與框架的易用性息息相關(guān),飛槳團隊也仍然在持續(xù)地優(yōu)化報錯信息的質(zhì)量和友好度,希望能給文中的小張同學(xué)及廣大開發(fā)者帶來更好的產(chǎn)品體驗。如果大家發(fā)現(xiàn)報錯信息不準(zhǔn)確、不直接、不易讀等問題,也歡迎通過Issue及時反饋給我們。讓我們期待飛槳的易用性能夠進(jìn)一步提升,成為功能強大、令開發(fā)者工作愉悅的國產(chǎn)開源深度學(xué)習(xí)框架。如在使用過程中有問題,可加入飛槳官方QQ群進(jìn)行交流:1108045677。如果您想詳細(xì)了解更多飛槳的相關(guān)內(nèi)容,請參閱以下文檔。官網(wǎng)地址:https://www.paddlepaddle.org.cn飛槳開源框架項目地址:GitHub:https://github.com/PaddlePaddle/PaddleGitee:?https://gitee.com/paddlepaddle/Paddle
END
總結(jié)
以上是生活随笔為你收集整理的闪退没由报错_秉承工匠精神,3步定位飞桨报错原因,你也来试试?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 新疆有哪些好的食物?
- 下一篇: 煎烤炉烤肉倒多少油?
