久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

TFLite算子注冊與Delegate接管機制:從FindOp到執(zhí)行計劃替換全解析

TFLite算子注冊與Delegate接管機制:從FindOp到執(zhí)行計劃替換全解析 如果你在移動端或者嵌入式設(shè)備上跑過 TensorFlow Lite大概率見過下面這類報錯Didnt find op for builtin opcode BATCH_MATMUL version 3或者遇到更費解的情況模型在 PC 上推理一切正常換到某個硬件板子上就提示 custom op 找不到再或者你興致勃勃接了一個硬件 delegate結(jié)果日志顯示一個算子都沒被接管推理速度紋絲不動。這些問題背后指向的是同一個機制TFLite 的算子注冊機制。你想真正定位這類問題就得順著FindOp這條路一直摸到Delegate。這篇文章我會從模型里算子的存放方式講起一路拆到OpResolver的查找邏輯再講清楚 delegate 接管執(zhí)行計劃時到底發(fā)生了什么最后給一個可以跑的最小 custom delegate 示例和一套排錯思路。內(nèi)容包括算子模型文件結(jié)構(gòu)、TfLiteRegistration內(nèi)核接口、FindOp查找路徑、版本匹配邏輯、BuiltinOpResolver與MutableOpResolver的使用場景、ReplaceNodeSubsetsWithDelegateKernels的執(zhí)行鏈以及手寫 delegate 的常見坑。適合在部署 TFLite 模型、接入 GPU/NPU 加速、或者要寫自定義算子的人看。1. 先明確“算子”在 TFLite 里的三個身份模型描述、運行時節(jié)點、執(zhí)行內(nèi)核很多人在排查算子問題時會卡住是因為沒分清楚“算子”這個詞在不同階段指的是不同東西。模型文件里有一個 operator加載進解釋器后它變成一個執(zhí)行節(jié)點真正運算時它又對應(yīng)一份內(nèi)核代碼。這三個身份是同一份數(shù)據(jù)在不同環(huán)節(jié)的投影理解它們的對應(yīng)關(guān)系后面所有問題都好辦了。1.1 模型文件里算子是怎么存放的TFLite 模型是 flatbuffer 格式。整個模型頂層有一張operator_codes表這張表可以理解為“算子字典”table OperatorCode { builtin_code: BuiltinOperator; custom_code: string; version: int; }每個 SubGraph 里有operators數(shù)組數(shù)組里每一個Operator都通過opcode_index指向operator_codes里的某一個條目同時記錄自己的輸入輸出張量索引table Operator { opcode_index: uint; inputs: [int]; outputs: [int]; }這種設(shè)計最直觀的意義是省空間一個模型里哪怕用了 50 次 ADDoperator_codes表里也只存一條 ADD 描述50 個算子節(jié)點都指向它。更關(guān)鍵的是版本信息只存一份——所有同類型算子在轉(zhuǎn)換時會被統(tǒng)一寫成一個版本號。這里有個容易忽略的點builtin_code是枚舉值custom_code是字符串。內(nèi)置算子走枚舉自定義算子走字符串TFLite 運行時查找這兩類算子的方式完全不同后面我會針對這一點展開。1.2 加載模型后每個節(jié)點都要“點名”當(dāng)你創(chuàng)建Interpreter時必須傳入一個OpResolvertflite::InterpreterBuilder(/* model */, resolver)(interpreter);這個 resolver 就是整本“算子花名冊”。Interpreter 在初始化階段會遍歷每個 subgraph 的每個 operator拿著模型文件里的算子描述去 resolver 里“點名”——找對應(yīng)的內(nèi)核注冊信息。點名失敗整個模型加載就會失敗錯誤信息形如Didnt find op for builtin opcode X version Y registration failed一個容易被忽視的細節(jié)是點名發(fā)生在Prepare階段之前。也就是說即使某個算子參數(shù)完全合法、輸入輸出形狀也配得上只要 resolver 里沒有它的注冊項模型就跑不起來。注冊表決定了解釋器“認識”哪些算子而不是“會算”哪些算子。1.3 TfLiteRegistration四個函數(shù)指針就是內(nèi)核的全部resolver 里查到的注冊信息類型是TfLiteRegistration。結(jié)構(gòu)主體是四個函數(shù)指針typedef struct TfLiteRegistration { void* (*init)(TfLiteContext* context, const char* buffer, size_t length); void (*free)(TfLiteContext* context, void* buffer); TfLiteStatus (*prepare)(TfLiteContext* context, TfLiteNode* node); TfLiteStatus (*invoke)(TfLiteContext* context, TfLiteNode* node); int32_t builtin_code; const char* custom_name; int version; } TfLiteRegistration;用生活化的方式理解這四個函數(shù)init給這個算子實例分配私有狀態(tài)相當(dāng)于入職時領(lǐng)取工位和電腦。free銷毀狀態(tài)相當(dāng)于離職時歸還設(shè)備。prepare根據(jù)輸入張量形狀推導(dǎo)輸出張量形狀為真正的計算排好班。invoke執(zhí)行實際計算相當(dāng)于正式干活。以 ADD 為例prepare會讀取輸入張量的 shape給輸出張量也分配同樣的 shapeinvoke才真正逐元素相加。模型里一條builtin_code kTfLiteBuiltinAdd的算子運行時對應(yīng)到這樣一份TfLiteRegistration四個函數(shù)指針指向 ADD 內(nèi)核的不同實現(xiàn)函數(shù)。所以在排查算子問題時我習(xí)慣先問一個問題問題出在“花名冊里沒這個人”還是“這個人能力不行 prepare 失敗”還是“干活時踩坑 invoke 出錯”三類問題的報錯位置和排查手段完全不同。搞清楚這一點比一頭扎進源碼里翻找有效得多。2. 順著 FindOp 走一遍內(nèi)置算子的數(shù)組表、自定義算子的哈希表、版本匹配邏輯點名動作的核心就是FindOp。它不是一個普通函數(shù)而是OpResolver基類里定義的兩個虛接口分別應(yīng)對內(nèi)置算子和自定義算子class OpResolver { public: virtual ~OpResolver() {} virtual const TfLiteRegistration* FindOp(BuiltinOperator op, int version) const 0; virtual const TfLiteRegistration* FindOp(const char* custom_op, int version) const 0; };注意這里有個容易誤解的點FindOp的返回值是一個注冊結(jié)構(gòu)體的指針。解釋器拿這個指針去調(diào)用對應(yīng)的函數(shù)而不是自己復(fù)制一份代碼。這也意味著如果 resolver 在運行期間生命周期提前結(jié)束指針懸空會導(dǎo)致崩潰。Android 的 JNI 封裝里如果沒有把 resolver 和 interpreter 綁定好經(jīng)常會出現(xiàn)這種“偶發(fā)段錯誤”。2.1 內(nèi)置算子的查找路徑builtin_code 當(dāng)數(shù)組下標(biāo)BuiltinOpResolver是使用頻率最高的 resolver 實現(xiàn)它的內(nèi)部組織方式很簡單粗暴——一張按BuiltinOperator枚舉值索引的靜態(tài)數(shù)組或者一組按枚舉值組織的注冊表。查找內(nèi)置算子時邏輯大致如下const TfLiteRegistration* BuiltinOpResolver::FindOp( BuiltinOperator op, int version) const { // 按枚舉值查表再校驗版本 const TfLiteRegistration* registration LookupBuiltin(op); if (!registration) return nullptr; if (registration-version ! version) return nullptr; return registration; }也就是說內(nèi)置算子查找的核心是兩個匹配條件builtin_code枚舉值相等version版本相等。這里分享一個實操經(jīng)驗不同 TFLite 版本的BuiltinOperator枚舉值不是穩(wěn)定的。舊版運行時拿到新版轉(zhuǎn)換器生成的模型很可能在枚舉值重排后指向了錯誤的注冊項或者直接查不到。所以我從不在生產(chǎn)環(huán)境里做“TFLite 運行時版本比模型轉(zhuǎn)換版本低一點點”這種將就——寧可升級依賴也不要賭枚舉值沒變。2.2 版本匹配為什么經(jīng)常被忽略O(shè)peratorCode里有version字段TfLiteRegistration里也有version字段。查找時解釋器會把模型文件里的版本號傳給FindOpresolver 內(nèi)部再做比對。同一個算子有多個版本通常意味著行為有細微差異。比如某些算子新版支持了廣播、或者補了精度問題、或者換了更優(yōu)的計算策略。模型轉(zhuǎn)換器會根據(jù)模型的實際使用方式選擇一個版本號寫進文件而運行時的注冊項也有自己的版本號。兩者對不上就報Didnt find op for builtin opcode MUL version 3這里的 “version 3” 指的是模型里期望的算子版本。報錯含義是resolver 里能找到kTfLiteBuiltinMul的注冊項但找不到version 3的那個。一個常被踩的坑是高版本 convert 出來的模型拿到低版本 TFLite 上運行。新版框架可能因為支持了新算子語義就把某個算子的默認版本號抬高了舊運行時沒注冊這個版本直接拒絕加載。排查這類問題最直接的辦法查一下當(dāng)前 TFLite 版本對應(yīng)的算子版本映射表或者干脆把tflite依賴升級到和模型轉(zhuǎn)換環(huán)境一致的版本。2.3 自定義算子為什么走字符串匹配自定義算子在模型文件里沒有枚舉值可用只能靠custom_code字符串標(biāo)識。FindOp(const char* custom_op, int version)的查找路徑本質(zhì)就是一次unordered_map的字符串查找auto it custom_ops_.find(std::string(custom_op)); if (it custom_ops_.end()) return nullptr; if (it-second.version ! version) return nullptr; return it-second;和內(nèi)置算子最大的區(qū)別在于字符串是精確匹配大小寫敏感猶豫一點都不行。轉(zhuǎn)換腳本里寫的名字是MyCustomOp注冊時寫的mycustomop結(jié)果就是找不到。很多人問為什么自定義算子的報錯信息里沒有給出版本不匹配的提示而是直接說 “Didnt find custom op”。因為unordered_map只按字符串找字符串都沒命中版本號自然沒機會參與比較。所以排查自定義算子問題時第一件事永遠是確認模型里的字符串和注冊時的字符串一字不差。另外注冊自定義算子用的接口通常是resolver.AddCustom(MyCustomOp, custom_registration, 1);第三個參數(shù)就是版本號。如果你后續(xù)改了自定義算子的實現(xiàn)并提升了版本號舊模型兼容性會立刻下降轉(zhuǎn)換新模型時也要注意保持寫進模型的版本和注冊版本一致。3. OpResolver 這套抽象的實際價值裁剪、替換和動態(tài)注冊看到這里你可能會問為什么 TFLite 不直接把所有算子都內(nèi)置到解釋器里非要繞一圈通過 resolver 去找答案藏在一個現(xiàn)實需求里TFLite 的目標(biāo)環(huán)境太碎了。從手機到單片機從幾百兆內(nèi)存到幾百 KB 內(nèi)存的 MCU全量算子對服務(wù)端框架沒問題對端側(cè)嵌入式環(huán)境就是災(zāi)難。注冊機制的價值在于把“解釋器核心”和“算子實現(xiàn)”解耦讓上層按需攜帶、按需替換。3.1 BuiltinOpResolver 和 MutableOpResolver 的差別BuiltinOpResolver就是前面說的“全量花名冊”所有 TFLite 內(nèi)置算子都注冊在里面。好處是省心壞處是二進制體積大——如果你只需要 MINIMAL 推理背上全套算子顯然吃虧。MutableOpResolver是運行時可變的 resolver支持AddBuiltin和AddCustom動態(tài)增加注冊項。兩者對比如下項目BuiltinOpResolverMutableOpResolver注冊范圍編譯期間全量內(nèi)置算子運行期按需添加自定義算子需要繼承后 override 或配合使用直接 AddCustom二進制體積較大只包含實際注冊的內(nèi)核適合場景原型驗證、通用部署裁剪包體、插件化架構(gòu)實際項目里我更多是組合使用先用BuiltinOpResolver兜底再額外AddCustom自己寫的算子。但如果是做嚴格裁剪的固件就會自己繼承OpResolver只暴露模型里真正出現(xiàn)的那幾個算子。3.2 裁剪二進制體積的實際姿勢假設(shè)你的模型只有 ADD、CONV_2D、RELU那完全可以寫一個精簡 resolverclass LiteResolver : public tflite::OpResolver { public: LiteResolver() { AddBuiltin(tflite::BuiltinOperator_ADD, tflite::ops::builtin::Register_ADD()); AddBuiltin(tflite::BuiltinOperator_CONV_2D, tflite::ops::builtin::Register_CONV_2D()); AddBuiltin(tflite::BuiltinOperator_RELU, tflite::ops::builtin::Register_RELU()); } const TfLiteRegistration* FindOp(BuiltinOperator op, int version) const override { return GetBuiltinRegistration(op, version); } const TfLiteRegistration* FindOp(const char* custom_op, int version) const override { return GetCustomRegistration(custom_op, version); } };這個思路再加一層編譯選項配合內(nèi)核源碼只編譯需要的目標(biāo)文件能明顯壓縮體積。關(guān)鍵是你要先知道模型里到底用了哪些算子——別靠猜直接寫個小腳本遍歷model.operator_codes打印出來就行。3.3 和 FlexDelegate 的配合算子在 TFLite 和 TensorFlow 之間銜接還有一種情況模型里混了 TensorFlow 算子和 TFLite 算子。TFLite 轉(zhuǎn)換器遇到不支持的標(biāo)準(zhǔn) TF 算子時如果打開了allow_custom_ops或經(jīng)過一定配置可能會把它保留成自定義算子名字通常帶Flex前綴。這些 Flex 算子不會被BuiltinOpResolver找到需要專門的FlexDelegate來接管。這個 delegate 本質(zhì)上還是一個通過自定義算子名注冊的機制——解釋器先通過 custom op 的字符串把它標(biāo)記出來再由 delegate 在運行時調(diào)用對應(yīng)的 TensorFlow Lite Flex 內(nèi)核。所以嚴格來說一個模型里可以有三種算子來源純內(nèi)置算子、純自定義算子、由 delegate 支持的算子。理解FindOp只能解決前兩種遇到第三種時要看 delegate 的接管路徑這正是下一節(jié)的重點。4. Delegate 接管執(zhí)行計劃的完整邏輯ModifyGraphWithDelegate 到節(jié)點替換Delegate是 TFLite 里被誤解最多的機制之一。很多人以為 delegate 是“繞過 FindOp 直接走硬件”這個說法不準(zhǔn)確。準(zhǔn)確的理解是delegate 在 FindOp 之后把已經(jīng)解析好的節(jié)點子圖從執(zhí)行計劃里摘出來交給另一個內(nèi)核執(zhí)行。4.1 從 ModifyGraphWithDelegate 開始的調(diào)用鏈常規(guī)接入 delegate 的代碼長這樣TfLiteDelegate* delegate CreateMyDelegate(); interpreter-ModifyGraphWithDelegate(delegate);ModifyGraphWithDelegate內(nèi)部會按順序做幾件事遍歷當(dāng)前執(zhí)行計劃里的所有節(jié)點。調(diào)用 delegate 的Prepare回調(diào)。Prepare內(nèi)部決定要接管哪些節(jié)點并調(diào)用核心替換函數(shù)。TFLite 把被接管節(jié)點重構(gòu)成一個或多個 delegate kernel 節(jié)點。后續(xù)執(zhí)行時遇到 delegate kernel 節(jié)點就調(diào)用 delegate 內(nèi)核的invoke。這里的“執(zhí)行計劃”可不是模型文件里的算子順序。TFLite 在內(nèi)部會做張量生命周期優(yōu)化、內(nèi)存復(fù)用、節(jié)點重排GetExecutionPlan拿到的節(jié)點順序可能和模型里的 operator 順序不一致。寫過 delegate 的人多半都踩過這個坑你按模型里的 operator 順序去對接管節(jié)點結(jié)果發(fā)現(xiàn)執(zhí)行計劃里的節(jié)點編號完全對不上。4.2 TfLiteDelegate 和 Prepare 回調(diào)delegate 本身是一個結(jié)構(gòu)體關(guān)鍵字段和函數(shù)指針如下略去平臺相關(guān)字段typedef struct TfLiteDelegate { void* data_; TfLiteStatus (*Prepare)(TfLiteContext* context, TfLiteDelegate* delegate); // ... buffer handle 相關(guān)函數(shù)指針 } TfLiteDelegate;Prepare是整個 delegate 的靈魂。TFLite 執(zhí)行ModifyGraphWithDelegate時會回調(diào)它而它要做兩件事決定接管哪些節(jié)點、調(diào)用替換函數(shù)把節(jié)點子圖換掉。TfLiteContext提供了兩個關(guān)鍵接口用于遍歷節(jié)點TF_LITE_ENSURE_STATUS(context-GetExecutionPlan(context, execution_plan)); TF_LITE_ENSURE_STATUS(context-GetNodeAndRegistration( context, node_index, node, registration));拿到node和registration之后registration-builtin_code或registration-custom_name就是判斷是否該接管的依據(jù)。比如想接管 ADD就判斷registration-builtin_code kTfLiteBuiltinAdd。4.3 ReplaceNodeSubsetsWithDelegateKernels 是真正的開關(guān)判定完節(jié)點后最核心的一步是調(diào)用context-ReplaceNodeSubsetsWithDelegateKernels( context, delegate_kernel_registration, nodes_to_replace, delegate);nodes_to_replace是一個整數(shù)數(shù)組元素是執(zhí)行計劃里的節(jié)點下標(biāo)。這個函數(shù)做的事情可以理解為TFLite 拿著這份名單把節(jié)點集合重新組合成一個或多個連通的子圖然后每個子圖變成一個“delegate kernel”節(jié)點插入執(zhí)行計劃。被替換之后原算子的TfLiteRegistration不會被銷毀它的 inputs、outputs、原始注冊信息仍然保留在模型運行時數(shù)據(jù)結(jié)構(gòu)里。但它的invoke不會在 CPU 內(nèi)核路徑上被調(diào)用了——執(zhí)行計劃已經(jīng)指向 delegate kernel 的注冊信息后續(xù)跑的是你傳入的delegate_kernel_registration.invoke。這里有個容易誤會的點delegate kernel 的invoke不是逐算子調(diào)用的而是按子圖調(diào)用的。如果你接管的子圖里有 10 個算子你的invoke會被調(diào)用一次內(nèi)部需要負責(zé)把這 10 個算子的計算統(tǒng)一調(diào)度到硬件后端。這也是為什么 delegate 能跨算子做融合優(yōu)化——它看到了整塊子圖可以做算子融合、緩沖區(qū)復(fù)用而不只是把單個算子搬到別的硬件上執(zhí)行。4.4 真實項目里 delegate 的常規(guī)用法最常見的三個 delegate正好代表了三種不同的接入方式Delegate覆蓋范圍典型用法NNAPIAndroid 上的 CPU/GPU/DSP/NPUtflite::StatefulNnapiDelegate delegate(options);GPU delegateiOS/Android 上浮點模型整圖加速TfLiteGpuDelegateV2Create(options);XNNPACK浮點算子的 CPU 優(yōu)化通過 interpreter options 自動啟用以 NNAPI 為例簡單接入是這樣#include tensorflow/lite/delegates/nnapi/nnapi_delegate.h tflite::StatefulNnapiDelegate::Options options; tflite::StatefulNnapiDelegate delegate tflite::StatefulNnapiDelegate(options); interpreter-ModifyGraphWithDelegate(delegate);而從 TFLite 2.x 之后的版本開始XNNPACK delegate 往往在創(chuàng)建 interpreter 時通過experimental_op_resolver_type或默認設(shè)置就參與進來了甚至不需要手動創(chuàng)建 delegate 對象。這些成熟 delegate 能加速跑通底層依賴的就是 4.2 和 4.3 說的這套機制。理解透替換鏈路后你會明白兩個關(guān)鍵結(jié)論FindOp 不決定 delegate 能否接管某個算子。delegate 判斷的依據(jù)是TfLiteRegistration.builtin_code/custom_name即使 CPU 內(nèi)核根本不存在delegate 也能在 Prepare 階段把它接管走前提是你的 delegate 后端真的能執(zhí)行它。找得到的算子不一定走 CPU找不到的算子也不一定會加載失敗。這和“resolver 里有沒有注冊”是兩套獨立邏輯只是在實際執(zhí)行計劃里交織在一起。4.5 delegate Prepare 失敗后的策略如果 delegate 在Prepare階段遇到不支持的節(jié)點組合策略TFLite 的處理方式取決于 delegate 自己。有的 delegate 會在內(nèi)部做回退把部分節(jié)點留在 CPU 執(zhí)行有的干脆整體失敗讓解釋器進入錯誤狀態(tài)。實際項目中我見過最典型的場景模型里混了 float 和 quantized 算子GPU delegate 只支持其中一部分如果設(shè)置成嚴格模式strictPrepare 階段直接失敗設(shè)置成寬松模式就能部分接管剩下回落到 CPU。這也是為什么“接入了 delegate 但速度沒提升”不一定是你代碼寫錯可能只是你允許了 delegate 部分接管。這個判斷點很重要在動代碼之前先確認 delegate 的 options 配置。5. 手寫一個最小 custom delegate把 ADD 算子從 CPU 內(nèi)核手里接過來理論鋪墊夠了現(xiàn)在做一個能跑的最小 demo寫一個只接管 ADD 算子的 custom delegate。這個 demo 的執(zhí)行邏輯其實就是用 C 代碼逐元素相加本質(zhì)上和 CPU 內(nèi)置內(nèi)核做的事一樣價值在于讓你完整看到“節(jié)點匹配、子圖替換、后端調(diào)度”三段流程長什么樣。5.1 定義 delegate 和 Prepare 回調(diào)// demo_delegate.h #ifndef DEMO_DELEGATE_H_ #define DEMO_DELEGATE_H_ #include tensorflow/lite/c/c_api.h #include tensorflow/lite/c/common.h namespace demo { bool IsAddNode(const TfLiteNode* node, const TfLiteRegistration* registration) { return registration-builtin_code kTfLiteBuiltinAdd; } TfLiteStatus DemoDelegatePrepare(TfLiteContext* context, TfLiteDelegate* delegate) { TfLiteIntArray* execution_plan nullptr; TF_LITE_ENSURE_STATUS(context-GetExecutionPlan(context, execution_plan)); TfLiteIntArray* nodes_to_replace TfLiteIntArrayCreate(execution_plan-size); int num_selected 0; for (int i 0; i execution_plan-size; i) { int node_index execution_plan-data[i]; TfLiteNode* node nullptr; TfLiteRegistration* registration nullptr; TF_LITE_ENSURE_STATUS(context-GetNodeAndRegistration( context, node_index, node, registration)); if (IsAddNode(node, registration)) { nodes_to_replace-data[num_selected] node_index; } } if (num_selected 0) { TfLiteIntArrayFree(nodes_to_replace); return kTfLiteOk; } TfLiteIntArray* selected_nodes TfLiteIntArrayCreate(num_selected); for (int i 0; i num_selected; i) { selected_nodes-data[i] nodes_to_replace-data[i]; } TfLiteIntArrayFree(nodes_to_replace); TfLiteRegistration delegate_kernel_registration {0}; delegate_kernel_registration.init DemoDelegateKernelInit; delegate_kernel_registration.free DemoDelegateKernelFree; delegate_kernel_registration.prepare DemoDelegateKernelPrepare; delegate_kernel_registration.invoke DemoDelegateKernelInvoke; TF_LITE_ENSURE_STATUS(context-ReplaceNodeSubsetsWithDelegateKernels( context, delegate_kernel_registration, selected_nodes, delegate)); TfLiteIntArrayFree(selected_nodes); return kTfLiteOk; } } // namespace demo #endif // DEMO_DELEGATE_H_注意這里冒出了一個實踐細節(jié)nodes_to_replace一開始按execution_plan-size分配但實際選出來的節(jié)點數(shù)量可能遠小于它。真正傳給ReplaceNodeSubsetsWithDelegateKernels的數(shù)組必須精確保留“連續(xù)的前 num_selected 個元素”所以我復(fù)制了一個緊湊數(shù)組。直接傳原數(shù)組會讓 TFLite 誤以為尾部那些 0 值也是有效節(jié)點下標(biāo)輕則接管數(shù)量不對重則在節(jié)點索引校驗時直接崩掉。這個坑在成熟 delegate 源碼里一般不會顯眼地寫出來因為官方實現(xiàn)的寫法往往更簡潔但新手照著精簡代碼抄非常容易踩。5.2 DemoDelegateKernel 的三件套被替換后的 delegate kernel 也逃不開 init / free / prepare / invoke 四個函數(shù)。我的 demo 里 init 只用來創(chuàng)建一塊私有狀態(tài)void* DemoDelegateKernelInit(TfLiteContext* context, const char* buffer, size_t length) { return new int(0); // 實際上不需要狀態(tài)只是演示 } void DemoDelegateKernelFree(TfLiteContext* context, void* buffer) { delete static_castint*(buffer); } TfLiteStatus DemoDelegateKernelPrepare(TfLiteContext* context, TfLiteNode* node) { return kTfLiteOk; } TfLiteStatus DemoDelegateKernelInvoke(TfLiteContext* context, TfLiteNode* node) { const TfLiteTensor* input context-GetTensor(context, node-inputs-data[0]); const TfLiteTensor* input2 context-GetTensor(context, node-inputs-data[1]); TfLiteTensor* output context-GetTensor(context, node-outputs-data[0]); const float* a static_castconst float*(input-data.data); const float* b static_castconst float*(input2-data.data); float* out static_castfloat*(output-data.data); int num_elements 1; for (int i 0; i output-dims-size; i) { num_elements * output-dims-data[i]; } for (int i 0; i num_elements; i) { out[i] a[i] b[i]; } return kTfLiteOk; }嚴格來說prepare在這里什么都不做是不對的——正規(guī)實現(xiàn)應(yīng)該根據(jù)輸入推導(dǎo)輸出 shape但 ADD 的內(nèi)核行為已經(jīng)保證輸入輸出 shape 一致所以 demo 里偷懶可以跑真實項目中至少要做 shape 一致性校驗。要提醒的是node-inputs-data[0]和node-inputs-data[1]是張量索引要用context-GetTensor(context, index)拿到實際的TfLiteTensor指針。有些 kernel 實現(xiàn)里會用context-GetMutableTensor等變體取決于你是否要寫數(shù)據(jù)。不要直接在node上解引用張量結(jié)構(gòu)那只是索引數(shù)組。5.3 接入 Interpreter 并驗證delegate 定義好之后接入方式非常直接TfLiteDelegate my_delegate {0}; my_delegate.data_ nullptr; my_delegate.Prepare demo::DemoDelegatePrepare; // 創(chuàng)建一個帶 ADD 的模型然后 tflite::InterpreterBuilder(model, resolver)(interpreter); interpreter-ModifyGraphWithDelegate(my_delegate); interpreter-Invoke();驗證是否接管成功最實用的手段是看執(zhí)行計劃。你可以在DemoDelegatePrepare里打印num_selected或者在DemoDelegateKernelInvoke里打日志。如果 Invoke 時打印了你的日志說明這條鏈路是真的通了—— delegate kernel 進入了執(zhí)行計劃并且被執(zhí)行器調(diào)度到了。有一點必須說清楚工業(yè)級 delegate 的 invoke 絕不會像我這個 demo 一樣逐個元素算。真實接力場景里delegate 的 Prepare 已經(jīng)在本后端申請好內(nèi)存、建立好設(shè)備句柄invoke 階段直接把這些節(jié)點打包成一次硬件提交比如一次性把整塊 tensor 數(shù)據(jù)拷到 GPU再提交一個 command buffer。這個 demo 的價值在于鏈路演示直接拿去生產(chǎn)環(huán)境一定會遇到性能反噬因為單算子切換帶來的設(shè)備調(diào)度開銷遠超一個 ADD 本身的計算開銷。5.4 這個 demo 里最容易栽的三個坑沒設(shè)置delegate.data_或者Prepare函數(shù)指針沒填對調(diào)用ModifyGraphWithDelegate時可能直接段錯誤。這些字段是 POD 結(jié)構(gòu)體里的函數(shù)指針漏一個就是調(diào)用空函數(shù)nullptr排查起來很隱蔽。匹配節(jié)點時用了模型 operator 序號而不是執(zhí)行計劃節(jié)點序號。請務(wù)必從context-GetExecutionPlan遍歷不要自己去模型文件里數(shù) operators。注冊了 delegate 但沒有一個節(jié)點被接管時ReplaceNodeSubsetsWithDelegateKernels傳空數(shù)組。這個 demo 里我做了num_selected 0的保護真實項目里也要處理這種情況。否則有的 TFLite 版本里會觸發(fā)斷言。我自己第一次寫的時候在第二個坑上耗了一個晚上。原因是模型文件里 ADD 是第 3 個算子執(zhí)行計劃里它排在第 17 位中間插入了若干張量記憶化優(yōu)化帶來的重排。后來我老老實實打了節(jié)點下標(biāo)映射關(guān)系才發(fā)現(xiàn)自己一直在按錯誤編號匹配。6. 從報錯信息倒推排查注冊鏈路的斷點在哪個環(huán)節(jié)最后分享一套排錯思路。每次遇到算子相關(guān)的問題我習(xí)慣先從報錯信息判斷斷點位置再往下挖。畢竟 TFLite 的報錯文本通常已經(jīng)很明確地告訴了你該看哪里。6.1 “Didnt find op” 類報錯的排查清單報錯內(nèi)容排查方向驗證手段Didnt find op for builtin opcode X version Ybuiltin_code 枚舉值不匹配或版本不匹配檢查 TFLite 運行時版本確認 converter 版本與運行時一致Didnt find op for custom op Foo自定義算子字符串不匹配dump 模型 operator_codes逐字節(jié)對比注冊名Custom op Foo is not supported模型轉(zhuǎn)換時未保留該算子轉(zhuǎn)換時打開 allow_custom_ops如果確實需要保留Node number N failed to prepareFindOp 已成功但 prepare 階段出錯查看該算子內(nèi)核實現(xiàn)的 prepare 邏輯遇到 BuiltinOperator 相關(guān)報錯時我建議先在本地寫個三行腳本打印模型operator_codes的builtin_code和version枚舉值再對照builtin_op_resolver源碼里注冊的版本范圍。這一步能排除掉 80% 的“版本不匹配”問題。6.2 一個真實場景同一份模型在不同設(shè)備上的奇偶問題之前有位同學(xué)在項目里遇到的現(xiàn)象是同一個 SSD MobileNet 模型在開發(fā)板 A 上跑得好好的換到板子 B 上就報Didnt find op for builtin opcode VERSION something兩個板子跑的是同一個二進制版本唯一區(qū)別是板子 B 的系統(tǒng)庫里意外帶了一個更舊版本的libtensorflowlite.so于是動態(tài)鏈接時加載到了舊實現(xiàn)。這類問題用文本日志排查很容易被忽略因為沒有編譯錯誤——鏈接時符號存在只是行為不一致。解決方式無非兩點不用動態(tài)庫版本管理依賴或者把模型轉(zhuǎn)換與運行時版本做成 CI 校驗。6.3 delegate 一個算子都沒接管的排查順序如果你已經(jīng)接入了 delegate但推理速度沒有變化需要排查下面幾步確認 delegate 的 Prepare 真的被調(diào)用了。在 Prepare 函數(shù)頭尾打日志確認不是你的代碼里根本沒創(chuàng)建 delegate 對象或用錯實例。確認 target 節(jié)點真的存在。打印執(zhí)行計劃里的節(jié)點數(shù)、每個節(jié)點的 builtin_code 列表和你的匹配條件逐一比對。特別檢查 quantized 算子很多 delegate 只接管 float 算子模型是 quantized 時自然一個都不中。確認 ReplaceNodeSubsetsWithDelegateKernels 的返回狀態(tài)。如果返回kTfLiteError后續(xù)就不會有 delegate kernel 節(jié)點。確認 delegate kernel 的 invoke 真的被調(diào)了。在最外層 invoke 打日志如果沒日志說明執(zhí)行計劃里根本不存在你的 delegate kernel。確認沒有其他 delegate 搶先接管了同一批節(jié)點。多個 delegate 疊加時先執(zhí)行的 delegate 可能已經(jīng)把 ADD 節(jié)點替換掉了后注冊的 delegate 自然匹配不到。這套順序看起來簡單但執(zhí)行的時候一定要借助日志而不是靠“我感覺”。TFLite 編譯時如果開了 verbose log會在ModifyGraphWithDelegate階段打印節(jié)點替換的詳細信息沒開日志時自己在 Prepare 和 kernel 函數(shù)里埋 printf 是最快的。另一個有價值的經(jīng)驗是delegate 接管率高不等于端到端延遲一定更低。如果被接管節(jié)點夾在大量 CPU 節(jié)點之間tensor 數(shù)據(jù)反復(fù)在 CPU 和硬件后端之間拷貝開銷可能抵消掉加速收益。所以做 delegate 優(yōu)化時我會把執(zhí)行計劃畫出來重點看能形成多大塊的連續(xù)子圖而不是追求接管的節(jié)點數(shù)量。這也是為什么前面強調(diào)ReplaceNodeSubsetsWithDelegateKernels是按子圖接管——它給了 delegate 做整塊調(diào)度的機會而這個機會需要你在 Prepare 里主動用好。最后說一句我自己的感受。注冊機制看懂了之后TFLite 的很多“玄學(xué)”問題會變得特別直白模型文件里的算子描述是一回事解釋器里的內(nèi)核注冊是另一回事delegate 又是在執(zhí)行計劃層面的第三回事。三層之間通過FindOp和ReplaceNodeSubsetsWithDelegateKernels這兩個關(guān)鍵點串聯(lián)起來。以后再遇到“明明注冊了為什么沒生效”“delegate 接了為什么沒加速”這類問題順著報錯信息回到這一層層的鏈路里去定位多半就會豁然開朗。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
欧美变态激情网| 亚洲欧美碰碰| 日本αv| 国产成久久综合片| 日本网色| 日日嗨AV一区二区夜夜| 国产日韩无码一区二区三区久久区| 久久精品国产亚洲AV片多多| 二级久久网| 欲香欲色| 欧美亚洲日本激情在线| 亚洲人妻精品一区二区| 麻豆国产96在线| 大香伊人在线一区| 亚洲AV麻豆Aⅴ无码电影一| 国内精品伊人久久久久影院会| 成人综合视频久久| 97超碰磁| 97免费在线视频在线观看| 色噜噜国产精品视频一区二区| 欧美国产伊人久久久久| 久久久蜜桃一区二区三区| 欧美日韩大香蕉| 五月丁香色综合| 97欧美色| 无遮挡猛进视频免费无限观看| 后入式在线免费观看60秒| 天天夜躁日日躁狠狠2002| 超碰公开久久网| 好爽视频在线观看视频| 人妻夜夜爽天天爽麻豆三区网站 | 香蕉欧美| 丰满搜索结果 -第18页- 久久高清无码| 久久精品一区二区三区四区五区| 97久久精品亚洲| 大香蕉懂9| 婷婷精品视频| 免费视频97| 91|九色|国产熟女| 麻豆 美女 丝袜 人妻 中文| 人妻加勒比东京热| 伊人网免费视频| 日韩内射视频| 淫荡熟女乱伦网| 中文字幕av乱伦| 夜夜嗨一区二区三区三州加勒比| 午夜精品探花| 快播电影网日韩新片| 午夜免费福利视频一区| 99re免费视频精品全部| 女同性恋久久| 久久久久网站-538在线视频-欧美永久乱码| 国产99999久久精品| 男人天堂网站| 国产精品视频| 国产v片在线免费观看| 91 丝袜在线| 亚洲成人日韩小说| 欧美性爱一区二区三区四区 | 色香在线| 99精品网| 日本操色导航| 亚洲成人ab| 久久这里只精品99re66图| 精品人妻久久久久一区二区三区| 国产乱伦性爱区| 日本韩国一本产品小视频日本韩国一本产品久久久产品小视频日本韩国一本产品久 | 日韩欧亚太美不卡| 人妻少妇久久中文字幕一区二区 麻豆| 日本中文字幕在线电影| 五月天伊人| 久久精品日韩专区免费观看| 国产精品无码av在线| 国产成人主播| 夜夜中出国产| A片大香蕉在线| 啊啊啊在线看| 久久婷婷亚洲| 中国少妇啪啪视频| 美女让帅哥通她小鸡鸡| 日本精品人妻少妇一区二区| 久久久精品国产亚洲伊人| 一类无码操逼视频| 看日韩黄片| 国产9区| 日本天天干天天搞一区| 亚洲天堂中文字| 美女性91| 国产suv精品一区二六| 欧美熟爽综合| av网页一区二区三区| 超碰天天操| 五月综合激情网| 免费自拍三级综合| 欧洲大香蕉| 天堂日本亚洲欧美| 亚洲人妻中文高清| 亚洲第一精品在线视频| 亚洲精品白浆高清久久久久久| 日韩精品一区二区人人人| 丰满人妻一区二区三区| 午夜精品探花| 国产熟女一区二区| 亚洲中文sv| 97超色| 久久草草欧美精品| 国产精品黑人一区二区三区| 欧在线一二区| 一本一道久久综合久久| 国产亚洲欧洲在线观看| 91殴美大片| 在线综合色| 99久久网站| 天堂亚洲欧美| 亚洲精品欧洲精品| 综合色播| 第四色奇米影视777| 成人天天爽| 婷婷香网站| 久久欲| 激情五月天中文字幕色| 人妻熟女一区二区| 欧美Ⅴ性爱| 欧美亚洲AN| 99视频自拍| 麻豆国产免费影片| 五月天丁香| 人妻啊啊人妻啊| 草草影院最新网址| 在线观看日韩av不卡| 日韩成人性爱AV| 人人摸人人叼| 99综合免费视频| AA级电影三区| 啊啊啊好多水| 少妇熟女一区二区三区| 国产乱子伦一区二区三区在线观看| 日韩无码服务区| 欧美人妻熟女在线| 国产亚洲精品农村妇女| 噜噜噜亚洲精品| 亚洲揄拍网| 天天干夜夜肏| 国产久久男人天堂| 欧美夜夜| 久草福利在线资源站| 三级三级三级日本99| 97色色色综合网站| 电家庭影院午夜69久久夜色精品国产69乱| 日韩大香蕉| 亚欧免费| 97福利视频| 久久久久久亚洲精品不卡人乳| 有码免费观看| 九九九九九精品十六| 美女黄色91| 少妇高潮喷水无套久久久久久| 校园春色第一页| 成人无码在线超碰网| 精品久久人妻成人网| 啪啪91| 久久久久久人妻| 精品久热| 熟女在线视频| 91激情网| 欧美淫乱视频| 国产第12页| 亚洲欧洲综合av在线| 色婷婷成人| 伊人影院中文字幕| 国产精品久久久久久夜夜夜| 美女AV一区二区| 97伊人| 淫荡少妇免费| 亚洲色婷婷综合久久久久中文| 蜜桃精品一区二区三区久在线| 精品高潮| 国产高潮AA片免费看| 91九九| 裸体美女久久久| 激情五月天中文字幕色| 成人资源中文字幕在线观看天天| 久久久精| 99久久99久久免费精品蜜臀| 熟女乱伦二区| 精品二区三四区五电影 | 操逼片国产| www.久久最新地址| 97资源制服丝袜| 91色综| 99热导航| 欧美丝袜亚洲| 操逼网站地址| 欧美日韩久久精品爱爱| 婷婷五月激情综合| 丰满搜索结果 -第18页- 久久高清无码 | 欧美一级特黄淫片在线观看| 日韩一级二级| 亚洲视频精选| 91久久免费视频互動交流| 国产亚洲美日韩Aⅴ中文字幕无码成人| 日本日逼高清| 破苞ⅩXXX性无码动漫无码| 日韩人妻制服丝袜av| 91九久| 麻豆尤物视频网| 翔田千里无码中出中文字幕| 婷婷五月天丁香花| 国产AV天美传媒一区二区三区 | 蜜桃天美传媒AV一区二区三区| 大香蕉中文网| 日本999精品视频| 天天综合亚洲综合| 偷拍 精品 另类 四区| 国产情色第一第二页在线观看| 97久操| 国产69精品久久久久99尤物| 好吊爽好吊爽在线视频,中文字幕精品一区二区日本,国产良妇出轨视频在线观看, | 国产60区。| 电家庭影院午夜69久久夜色精品国产69乱 | 91最新综合| a片 xxxx受爽视频| 激情专区综合| 中文字幕在线观| 熟女在线视频| 性色生活片久久毛片婬片免费放女人一级毛片 | 青青草大香蕉视频| 国产亚州高清国产拍精| 日韩射图| 天天看片天天爽| 麻豆色约约| 婷婷丁香五月综合| 日本人妻丰满熟妇久久久久久| 极品尤物在线观看| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 久久精品福利影院| 亚洲综合888| 欧美日韩国产黄色片| 中文久久96| 自拍鲍鱼一区在线高清观看免费| 亚州,欧美在线| 六月婷婷激情| 户外裸露刺激视频第一区| 97久久久久| 成人丁香五月| 亚洲熟女诱惑| 蜜桃久久久久久久久久久久| 丁香五月性| 欧洲特黄毛片免费看欧洲毛片| 欧美色日本| 国产二区视频在线观看电影| 日本不卡二区| 久久9亚洲| 嗯啊抽插大香蕉网页| jiujiujiujingpin| 蜜臀久久99精品久久综合| 国产一区免费午夜视频| 亚洲资源站| 蜜桃一区二区三区| 激情六月天| 久久久久久人妻一区精品色欧美| 亚洲婷婷丁香在线| 亚洲资源吧| 熟女一区二区三区| 国产suv精品一区二区四| 激情久久久| 国产精品乱码久久久久久久久| 97色色国产视频| 成人亚欧免费视频| 老司机香蕉久久久久| 水野优香在线观看| 精品黑人一区二区| 大香蕉www.超碰| 中文久久久| 家庭乱伦麻豆| 校园春色 欧美| 蜜桃臀一区二区三区久久| 日韩/97| 91黑丝露脚| 欧美操人视频| 欧美小说区视频区| 97国产综合欧美| 国产精品久久久久久久免牛肉蒲团 | 亚洲a色| 99热免费| 欧美日韩高潮喷水91| 蜜乳成人AV| 亚洲精品九九九| 久久久一区二区三区麻豆| 国产精品午夜福利视频| 久久国语| 偷拍片久久| 在线亚洲丝袜视频网站| 欧色性第一页| 麻豆a'v电影| 高清肉丝中文无码| 桃色人妻在线视频| 啊啊啊啊,啊啊好多水| 男人天堂网手机版婷婷| 干美女人妻| 四虎免费在线播放| 久久风骚城市人| 97操碰| 国产农村妇女毛片精品久久| 91亚洲黄色网| 国产青青综合伊人| 日韩精品一区二区人人人| 亚洲日产专区婷婷| 91总综合网| 欧美一二在线| 色婷婷一区二区三区久久午夜成人不| 操91| 易易A毛视频| 伊人91| 91天天综合日韩欧美| 老鸭窝成人免费毛片视频 | 高树玛利亚无码流出| 青青草日逼视频| 69AV女优男人的天堂| 久久啊哟| 日韩精品9999| 国产精品久久久久久9999| 国产丸一视频| 欧美色图电影| 亚洲精品成人动漫在线| 粉嫩av在线一区二区| 曰韩av中文字幕专区| 五月丁香六月激情| 中文字幕91综合| 天天影视射综合网| 色眯眯av| 久久久久亚洲| 女人喷水视频在线观看| 丁香六月婷婷久久综合| 日本精品性生活久久久| 精品少妇一区二区三区| 日韩精品国产一区二区| 60秒免费小视频| 碰人碰碰人人开房人肉| 三级色影综合网| 欧美日韩国产另类综合| 亚洲精品视频在线播放| 欧州激情视频在线一区二区| 日韩精品人妻中文字幕不卡乱码| 日韩黄片影院| 91neishe| 人妻天天爽夜夜爽2| 九九碰九九爱97超碰| 亚洲字幕一区二区| 亚洲AV无码成人精品久久| 97操97色| 屁股久久久久久久久| 日韩精品-原创伙伴| 成人一二| 曰韩精品九九无码| 91丝袜激情在线| 国产日本顶级一区二区三区| 色一射色一射| 乱理日韩中文| 91美女片在线| a v网站在线播放| 美女人妻色网站| 蜜桃精品视频一区二区三区| 日韩日本欧美在线观看| 一个人免费HD91视频| 精品人妻1237| 亚洲97资源| 人妻丰满熟妇一区二区三| 九九性视频| 嗯嗯啊啊好大好爽| 人人操 欧美| 婷婷99狠狠| 欧美在线中M| 久久久久亚洲| 狠狠躁AV| 欧美变态激情网| 69视频入口| 久草五月| 国产精品久久久久久久久久二区三区| 久久精品国产AV一区二区三区| 亚洲成av人片色午夜乱码| 亚州九九九精品视频| 亚洲中文字幕熟女| 欧美日韩国产中文超碰| 青青草好吊色| 丁香五月电影| 一区二区三区高清| 婷婷尹人大香蕉免费| 伊人久大| av天堂手机版追回| 日韩特一级久久| 国产精品久久久无码AV网站| www.99热在线只有精品| 影音先锋每日最新资源在线观看 | 国产操逼逼网| 夜夜嗨一区二区三区三州加勒比| 国产精品999zyz| 久久久久久中文版| 国产人妖视频一区在线观看| 蜜臀99久久| 一本久道久久综合狠狠爱| 极品出轨视频网站| 无码免费一区二区三区啪啪| 久久一二三四| 91大神电影天堂| 国产肏逼网站| 午夜欧美神马久久久久| 性爱乱伦视频免费| 超碰日韩美妻| 另类专区在线观看| 国产深喉视频一区二区| ′ !γ}丶。。久久精品欧美一区二区三区| 丁香五月天激情综合| 欧洲站一级二级三级h| 国产一区二区三区精品观看啪| 夜夜福利| 国产情侣自拍在线播放| 9Ⅰ超碰| 91狠婷| 日本高清视频xxxx| 精品二区三四区五电影 | 国产成人91一区二区三区| 97超碰国产亚洲精品资源| 欧美天天性| 精品人妻一区二区免费蜜桃| 日本国产高清色www视频在线| 天天综合在线4| 久久午夜鲁丝片| 激情小说亚洲图片| 四虎AV在线观看| 欧美视频一| 国产视频大全| 人妻熟女一区在| 超碰日韩人妻| 啊啊啊男女| 日韩亚洲美女一区久久| 国内精品a| 久久精品国产97欧美精品亚洲 | 亚洲精品乱码线路中文字幕| 天天日熟妇| 午夜激情床戏激情| 97人人操人人摸人人爱| 97超碰碰| 少妇精品久久久八区九区| 98色网| 中日韩久久久| 夜夜精品视频一区二区| 久久久精品无码亚免费| 91日产桃蜜| 国产丰满熟夫69mpp| 国产成人无码网站在线视频| 69精品少妇一区二区三区蜜桃| 精品综合久久久久久五月天| 日产成人久久| 国产有码一区| 色噜噜狠狠色综合日日| 日韩A优精品在线观看| 97超碰欧美手机| 操老熟女AV| 欧美色图片91| 一二三区在线| 99色色网| 艹少妇网站| 91成人高清在线观看| 91 丝袜在线播放| 人人澡人人澡人人| 好爽免费视频,| 综合色图,成人综合网| 国模精品一区二区三区苹果色戒 | 久久久久精| 久久美女福利是上海美女| 色黄污美女啪啪啪免费网站| 探花精品 一区二区| 亚洲精品蜜桃久久久| 乱欲性色| 亚洲涩涩| 青娱乐手机日韩在线视频| 好爽,再快点啊哈嗯嗯嗯嗯| 婷婷久久网| 欧美特大黄一级片片免费| 亚洲无码太久| gogogo免费高清看中国国语| 1769一区| 伊人热综合| 啊啊啊想要| 少妇激情一区二区三区视频| 伊人在线大香蕉视频久久| 999综合色| 久久亚码| 欧美最大综合网| 久久九操在线观看| 9ⅰ久久久天天| 亚洲色情在线影视| 好爽要喷了| 美国三级日本三级久久99| 欧美综合传媒| 加勒比色99999| 久久久精品,3| 九九久久玖玖| 加勒比海色香蕉婷婷| 久久夜夜| 影视综合无码少妇| 岛国免费黄色网址| 久久鲁干| 激情四射五月天| 免费看毛片操穴| www鬼畜国产男人的天堂| 国产按摩一区二区三区| 欧洲中文字幕| 欧美亚洲涩涩| 91男人综合| 日本久久超碰| 日韩中文字幕视频| 欧美另类综合久久| 日韩性爱网址| 日韩99神马视频播放片在线播放| 抽插无码高清一区| 婷婷色在线| 日本人体九九九九九九| 亚洲码和欧洲精品激情系列| 久久精品99久久久久久| 97丝袜亚洲在线播放| 国产精品粉嫩福利在线| 囯产精品久久久久久久久久二区三区| 热99这里有精品综合久久 | 欧美第38页| 亚洲 另类 丝袜 自拍 动漫| 自拍啪啪视频| 欧成人精品一区二区三区| 91社区伊人| 中国乱伦一区二区| 91久久久久免| 91国内外在线| 欧美色吧综合| 国产精品人妻无码久久久老鸭窝| 伊人网综合在线视频| 操逼日韩无码 | 亚洲国产ⅴ高清在线观看| 五月色网| 97免费视频网| 97视频免费在线观看| 午夜激情成人在线观看| 欧美另类色图片| 亚洲国产中文字幕| 国产偷人伦激情在线观看| 在线观看岛国有码| 久久久精品国产亚洲AV无码| 伊人网在线观看| 97欧美日韩综合| 亚洲伊人a线观看视频| 久久久九97| 日本不卡一区二区三区| 尤物av网站免费在线播放| 麻豆国产96在线| 超硑97精品| 成人怡红院| AV综合中文字幕干| 亚洲男人天堂2016| 精品日韩人妻视频| 首页亚洲国产高跟丝袜诱惑视频| 狠狠爱AV| 色欲无码人妻日韩欧美精品| 人妻夜夜爽天天爽麻豆三区网站| 蜜桃视频一区二区三区| 人伦四五区| 成人a大片在线观看| 黄色小说亚洲| 久久久久少妇| 曰韩精品九九无码| 麻豆成人AV| 日本不卡高清视频| 亚州中文字幕超碰97| 99精品国产户外露出| 九九av| 人妻少妇久久| 91天堂色男人的天堂| 久久 亚洲 日韩 人妻| 国产成人欧美精品在线| 久久婷婷一区二| 欧美少妇高潮| 亚洲激情在线| 色狠狠一区二区三区香蕉| 国产精品自拍欧美在线| 亚洲午夜蜜臀| 国产又粗又长又爽又色| 久久久9 9 9精品| 亚洲成?V人片在线观看福利| 高清肉丝中文无码| 操逼操网| 人人操超碰在线| 伊人久久大香大香线蕉中文| 人妻激情视频| 亚洲国产欧美中文永久| 91激情国产| 久久美女福利是上海美女| 天天综合站| 综合久| 97超碰9| 这里只有精品视频| 超碰色综合| 熟啊v色欧美热| 精品成人无码| 少妇熟女视频一区二区三区| 女人爽到高潮潮喷18禁网站| 麻豆一区二区三区在线看 | 天天综合网网欲色| 99啪啪| 熟女精品va中文字幕| 任我爽在线视频免费观看| 久久久精品成人国产| 99热在线只有精品| 欧美三级一级| 欧美操逼熟女| 欧美少妇高潮视频| 久久欧美1卡2卡3| 免费一级黄色录像影片| 欧美日韩97在线| 九九色综合| 不卡中文字幕aⅴ在线| 中国小夫妻勾搭露脸淫荡对白| 久久社区一区二区三区| 新怡红院| 天天综合欧美综合| 色综合色欲色综合色综合色综合| 日逼97| 高潮综合网| 婷婷五月成人| 欧亚无码视频| 好色美女九七第一页| 亚洲一区中文字幕久久,果冻传媒一区二区天美传媒| 97色冈| 国产日韩区| 久久视频,这里只有精品| 日本熟妇一区二区三区| 成人a大片在线观看| 久久亚洲日韩熟女精品| 欧美性爱一区二区三区四区| 婷婷五月天色| 操逼大黄片| 日韩97在线| 96国产污污污丝袜| 这里都是精品在线观看| 欧美人与动性人交a| 激情文学小说一区二区| 九月色婷婷| 韩国黄片aaaa| 100啪啪视频大全| 久久久一区二区三区麻豆| 精品十三区| 成人五月香网在线| 亚洲九月丁香| 亚洲国产91精品一区二区久久| 大逼色网站| 狠狠躁日日躁夜夜躁A| 老熟女91av| 婷婷久久五月天| 97精品熟女少妇一区| yiqicaoav| 久久99九九九九6666免费观看软件| 久久超碰亚洲人| 国产女人高潮视频| 久久精品国产欧美日韩亚洲欧美日韩中文久久国产一区 | 婷婷激情四射| 久久春色| 麻豆色约约| 天天爽天天爽| 欧美日韩操逼嗦吊| 国产精品一区二区校花| 另类亚洲一区二区三区| 麻豆成人影音在线| 爱爱久久| 97视频7| 九九在线精品| 大香蕉乱伦视频网| 亚洲国产精品无码AV在线| 大香蕉伊人75| 综合欧美色图| 我爱操| 亚洲精品国产熟女久久久| 青青草啪啪网| 大乔未久88一区| 91色图片| 91最新综合| 嗯嗯啊啊用力视频免费| 国产不卡片| 久久久99久9| 97中文天堂| 夂久色| 久久免费老司机精品| 亚洲一区二区麻豆影院| 又黑又大又粗| 天天透伊人| 色婷婷色99国产综合精品| 无码日韩网站| 久久五月天婷婷| 96精品在线| 日本超碰在线国产一区| 欧美日韩99精品麻豆传媒| 久草五月| 成年女人一区| 男人天堂站| 天天日天天射天天干| 日本不卡二三区| 欧美亚洲美少妇一区二区| 欧美久久婷婷| 天堂网 主播 亚洲| 蜜桃网熟妇| 国产精品久久久久久久久久久久久久吹 | 日本色色色视频| 乱伦系列一区二区| 欧美色婷婷| 这里是精品| 国内操逼视频二区| 国产专区路线| 久久一二三四不卡 | 极品白嫩福利在线| 欧美中文狠| 日本欧美m v精品网站加| 视频二区美腿制服人妻欧美| 九月伊人中文字幕| 人人操人人摸人人看人人插| 综合欧美激情网| 欧美黄色大香蕉一区二区| 少妇一线天久久久久久| 啊啊啊好湿久久| 久9久9久9久9久9久9| 大香蕉日韩| 翔田千里AⅤHD无码| 在线视频免费播放一区| 婷婷视频网| 久久精品老司| 99超碰网| 国产又黄又粗的视频| 日本Xx性爱| 97婷婷色| 欧美日韩国产电影| 超碰吊日色| 99视频这有这里有精品| 亚洲第一在线视频| 精品网站99999| 99久久99九九99九九九| 国产成年精品高清在线观看91| 精品人妻美妇91job| 国产又黄又猛又粗又爽的网站| 久操视频免费观看| 国产剧情在线| 秋霞曰韩R级| 你草精品在线视频| 免费在线视频97| 一区二区三区黄片免费观看| 91黑丝在线播放| 日本最新1区2区3区| 麻豆三极片| 人人扣人人操| 一本一首道人妻少妇免费久久| 99av| 男人a天堂手机在线版| 东京热激情视频一二三区| 加勒比av中文| 婷婷婷婷婷婷久久久久| 大香蕉伊人久久| 久久一二三四五六七八九区区| 97免费视频在线| 亚洲二区精品在线观看| 久久9 9 9精品| 久久婷婷成人综合色怡春院| 乱论91| 动漫区日韩区欧美区| 日本大片日本一区二区免费高清 | 日韩熟女精品无码专区一区二区 | 综合情欲网| 久久97视频| 91老熟女视频| 久热伊人| 久久婷婷视频| 91综合天天| 日韩成人大片在线观看| 欧美 亚洲 91| 成人乱人伦一区二区| 热久久99999| 免费精品国偷自产在线在线| 婷婷综合| 国产嫩草精品A88AV| 日本色色色色色视频| 骚人妻少妇视频| 九月丁香婷婷色| 97超碰这里只有精品| 国产日产精品久久快鸭的功能介绍| 精品美女在线视频| 无码不卡亚洲成?人片| 偷拍 精品另类 凸凹了四区| 国产精品丝袜在线| 欧美亚洲第一页| 久久久久9| 乱伦av麻豆| 久久久久96| 欧美日韩性爱视屏免费看了| 国产嫩草精品A88AV| 91一起操| 九九九九热| 女一区二区| 日本十八禁免费看污网站| 亚洲精品骚逼| 一区二区视频在线播放| 人妻少妇久久| 97超碰国产亚洲精品资源| 99热在线播放| 一本正道久久熟女| 国产女人和拘做爰视频| 加勒比人妻综合| 久久HD| 亚洲日韩天堂| 天天天天做夜夜夜夜做| 91艹B视频| 色欲蜜臀AV| 色色色综合网| 97操综合| 中文精品一区二去| 亚洲操逼网| 夜夜高潮夜夜爽夜夜爱爱一区| 啪啪视频mP4| 草草影院最新网址| 后入人妻无码| 欧洲熟妇xxXx欧美老妇裸体| 久久久新亚洲AV| 日韩人妻精品中文字幕| 日本网色| 久久精品国产亚洲AV先锋| 日本男人插女人的逼黄色| 久久久免费的精品| 无码人妻精品酒店| 高潮综合网| 大香蕉碰碰| 亚洲国产ⅴ高清在线观看| 亚洲干B| 密臀在线免费观看| 亚洲黄网在哪免费看| 蜜臀久久99精品久久久久久| 神马久久69| 天天做天天爱| 国产AV毛片| 中文久久久| 日韩大香蕉精品在线视频| 99热综合| 日韩熟女乱伦中出| 国产白丝网站| 成年女人一区| 国产一区二区视频在线播放| 中文字幕乱妇免费视频| 九九九久久久久| 97色干| 色色色欧美| 97色97干| 国产精品另类| 综合色拍| 麻豆黄四叶草网站| 九九亚洲视频| 精品v1区| 日韩三级在线观看网站| 亚洲永久永久永久永久一级一级一级精品 | 射欧美综合| 男人的天堂2019AV| 温婉少妇玩3p| 亚欧免费| 秋霞Av理论一级在线| 啊啊啊男女| 乱欲性色| 少妇人妻精品| 99精品免费| 久久久18| 超碰成人最新最好看| 亚瑟国产精品久久无码| 一级二级在线观看| 69精品| 亚洲第一页综合在线| 麻豆精品天美| 在线 亚洲 网爆 自拍| 激情自拍 校园春色| 亚欧性爱在线无码| 国产色呦呦| 蜜乳AV.COM| 狠狠色伊人亚洲综合网站色| 超碰九7| 91精品人妻一区二区三区蜜桃| 亚洲区限制级 99| 欧美91精彩| AV丝袜少妇| 国产精品欧美激在线| 日韩丝袜人妻AV| 日韩99神马视频播放片在线播放| 婷婷亚洲综合| 麻豆天美国美国产AV| 久久久网站| 99热这里只有精| 亚洲欧美日韩综合在线尤物| 亚洲偷拍自拍在线视频| 色乱二区| av资源在线播放天堂| 国产精品久久久久亚洲av| 91精品微拍福利| 欧美精品三区| 亚欧洲一区二区视频| 亚洲日本激情| 啊啊啊操死我| 人人妻人人色一区二区三区| 亚洲精品色| 成人国产视频在线观看| 国产强奸乱伦第1页| 国产肏逼网站| 亚洲精品免费中文字幕| 看大黄色大片原件| 日韩综合无码色欲vv| 强奸乱伦中文字幕AV| 国内毛片国产专区二| 成人片在线播放| 五月天婷婷影院| 大香蕉免| 亚洲欧美国产中文字幕| 九七毛片九九毛片| 神马久久免费电影观看| 青草一区二区| 亚洲无码视频免费在线观看网址! J?P?NESEHD熟女熟妇伦 | 国产成人免费观看在线视频| 玖玖玖玖精品国产剧情| 久久婷婷色| 91网亚洲| 韩日巨乳美女免费视频在线观看| 亚洲欧美变态| 99999亚洲| 八戒午夜福利理论片| 家庭乱伦性爱av| 五月丁香婷婷色| 麻豆天美国美国产| 色综合超碰超| 91天美免费| 国产av激情无码久久天堂| 国产精品999zyz| 日韩无码专区| 精品久久久久瑟瑟| 亚洲自拍青操视频| 激情婷婷丁香网| 日本影视久久免费| 亚洲中文日韩欧美大香蕉视频| 99热欧美| 农村妇女精品一区二区| 久久伊人东京热| 性色一线| 欧美大片天天看| 欧美亚洲91| 9 1超碰九色| 久久久久9999妇女| 天天看片麻豆| 岛国不卡超碰护士AV在线播放| 大奶啊啊好爽| 自拍偷拍草一草| 操碰91| 亚洲影院小综合| 亚洲a色| 国产不良强奸视频免费看| 久热婷婷| 天美传媒在线一区| 爱爱啊啊啊| 中国国国产一级特黄毛片| 九九九综合精品| 欧美亚洲韩国视频十五区| 国产亚洲精品A在线观看下载| 久久九九视频九九视频| 亚洲精品819| 日韩大香蕉AV影片| 99re公开精品免费视频| 久久天天摸| 久久久免费高清中文视频| 国产精品网址| 综合色图,成人综合网| 日本幼女18+| 91久久久亚洲| 天天操夜夜操| 色噜噜人妻av中文字幕| 国产乱伦亚洲| 人人超碰在线观看黄| 男人天堂新在线| 超碰在线成人| 欧美色图人妻| 亚洲小电影免费涩涩成人在线高清 | 精品天堂| 黄片直播三级黄片两女一男| 色香在线| 色综合91好| 五月天婷婷基地| 欧美午夜熟妇黑人精品91| 久久久久久日韩| 大香蕉欧美日韩| 思思热国产高清| 啊啊啊啊视频免费| 99999国产| 99综合视频一体| 久久线上视频免费看| 可以在线观看AV的网站| 99只有精品| 欧美的性爱网站免费| 亚洲日韩av专区无码| 欧美综合国产精品久久丁香| 狠狠色丁香| 欧美一区二区在线资源| 99蜜月精品久久| 国产成久久综合片| 欧美成人黄网色网站| 欧美亚洲丝袜美女电影| 热热色AV| 粉嫩av久久一区二区三区| 狠狠久久亚洲欧美专区| 欧美情色贴图| 亚洲春色一区二区三区| 性爱av在线免费观看| 目产99999久久999| 久久精品久久久久久久| 每日更新AV| 国产精品久久久久久久久久久久久久久久| 高清孕妇孕交| 国产精品成人无码av| 在线视频一区二区传媒| 亚洲美女精品九九视频| 国产一级不卡在线观看| 欧州激情视频在线一区二区| 1240青青草一区二区三区视频天爱 | 久久香蕉影院| 91美女高潮| 国内毛片婷婷六月色| 超碰 另类 欧美| 在线97视频| 久热大香蕉| 99热在线只有精品| 蜜乳视频网站| 欧美 青青草| 性夜影院爽黄A爽免费动漫| 激情无码日韩| 男人的天堂VA在线| 日语五十路和六十路亚洲国产精品| 五月色综合| 欧美96在线|欧| 国产色呦呦| 啊灬啊灬啊灬啊灬高潮奶出了免费视 | 国产免费内射视频| 精品成人av一区二区三区在线| 久久久久久久综合,国产| 国产精品欧美日韩久久| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 99久久久久| 超碰夫妻97| 伊人久久综合精品欧美| 九一综合网| 日韩免费在线视频观看| 久久婷婷亚洲欧| 婷婷色色五月天福利| 午夜性| 国产中文大片资源中文字幕| 欧美人妻色| 图片区小说区| 亚洲宗合网| 中文字幕免费看大片| 五月天久久人妻| 日韩成人精品中文字幕| 九九九九九九视频免费| 99热网站| 亚洲一区二区三区春色| 欧美婷婷久久| 久久久久久日韩| 欧美,亚洲,日韩,v,天堂,手机在线观看| 亚洲资源一区| 无码自拍SM| 国产91 丝袜在线播放00-百度| 成人夜夜爽| 91露脸熟女专区| AV天堂电影网| 韩国成人精品久久久免费看| 一区二区无码视频| www.色婷婷| av无线看| 亚洲 欧美 第一页| 日韩国产品视频中文字| 亚洲色图尤物视频| 无码操逼天堂| 亚洲高潮少妇| 亚洲 日本 国产 综合| 青青草久久| 玖色AV| 2017av无码免费无线播| www.av家庭乱伦| 欧美日动态视频| 国内三级自拍小视频在线观看| 黑人综合网| 骚女高跟AV在线| 色综合久久久久| 欧美日韩午夜精品一区二区三区 | 国产v亚洲v日韩v欧美v片另类| 亚洲国成人情色好看电影| 天天看,天天做| 美日韩男女操屄视频| 爱妻综合网| 一区二区三区 丝袜 高跟 美腿| 超碰国产精品无码| 婷婷午夜清品久久久久久久性色视频观| 成人福利视频网| 蜜屁av| 东京热熟女亚洲视频网站| 男人的天堂亚洲| 51久久夜色精品国产麻豆| 理论久久婷婷网8| 日本一片一区| 伊人AAA| 亚洲精品亚洲人成在线麻豆| 射综合网| 午夜操一视频一区| 情侣操 逼视频99| 校园春色美腿丝袜 | 9久久精品| 在线播放成人网站| 国产又爽又黄| 思思99热| 欧美熟女少妇| 丁香六月婷婷久久综合| 91九九| 亚洲精品男人的天堂| 99热91| 久久精品欧美一区蜜桃| 中文字幕在线观看AV| 国产不卡片| 中文字幕人妻色偷偷久久皮| 一区| 中文字幕综合人妻| 亚洲青青草| 综合网少妇| 日韩一级二级三级| 亚洲婷婷丁香在线| 天天综合欧美| 日韩电影在线观看网址| 久久无码一区二区二三区性色| 97天天日| 日韩精品资源专区二区| 成人乱人伦一区二区| 欧美日本中字另类在线| 女同性恋久久| 日韩另类色图| 白丝1区2区3区| 97精品第3页| 深爱伊人影院| 亚洲国产日韩精品久久久| 富女玩鸭子一级毛片| 亚洲精品天堂久久A∨51成人漫 | 91亚洲人| AA级电影三区| 五月天丁香婷婷综合网站| 婷婷亚洲天堂| 欧美性战999| 97视频900| 熟人人妻少妇精品久久| 视频国产成人精品日本亚洲18| 日韩国语字幕| 久久久9视频| 大奶尤物鲍汁淫荡欧美视频粉嫩夜夜骚|