快捷鍵

委派偵錯

委派後端由於其定義行為的靈活性,是裝置端模型的重要組件。這種靈活性的副作用是它作為不透明的轉換運作。這模糊了豐富的關聯和突變,這些關聯和突變在後處理中非常重要。

  • 例如,如果兩個不同的運算子融合發生在委派中,後處理將無法分離這兩個轉換。

具體來說,它使得透過委派圖關聯運行時資訊(例如效能分析結果)變得困難。委派偵錯識別碼提供了一個框架,委派作者可以透過該框架傳播此資訊並將其用於運行後分析。

準備工作分為三個階段

  • 預先 (AOT):委派作者產生偵錯控制代碼對應

  • 執行階段 (Runtime):委派作者使用註冊於 Debug Handle Map (偵錯控制碼映射表) 中且 AOT (Ahead-of-Time,預先) 註冊的 Delegate Debug Identifiers (委派偵錯識別符) 進行記錄。

  • 反序列化 (Deserialization):委派作者為委派事件中的自訂元資料 (metadata) 提供剖析器 (parser)。

預先 (Ahead-of-Time) 整合

委派作者透過從後端實作傳回一個 Debug Handle Map (偵錯控制碼映射表),來傳播在降級的後端中發生的轉換。

產生偵錯控制碼映射表 (Debug Handle Map)

Debug Handle Maps (偵錯控制碼映射表) 透過將 Delegate Debug Identifiers (委派偵錯識別符) 映射到偵錯控制碼 (debug handles),來傳達在後端中發生的轉換。

Delegate Debug Identifiers (委派偵錯識別符) 是用於表示執行階段感興趣點的,由產生或使用者提供的識別符。回想一下,偵錯控制碼是模型圖中運算子實例的唯一識別符。

例如

  • { 0: (10, 11), 1: (11, 12) }: 執行階段中的識別符 0 和 1 分別對應於偵錯控制碼為 (10, 11) 和 (11, 12) 的運算子。

  • { “fused_op_1_2_3”: (11, 12, 15) }: 執行階段中的識別符 “fused_op_1_2_3” 對應於偵錯控制碼為 (11, 12, 15) 的運算子,其中 11、12、15 分別對應於運算子 1、運算子 2 和運算子 3。

注意

識別符是用於將執行階段結果連接到模型圖的手段;識別符的解釋由委派作者定義。

Debug Handle Maps (偵錯控制碼映射表) 是透過使用 DelegateMappingBuilder 建構的,並作為 PreprocessResult 的一部分傳回。

class PreprocessResult:
    processed_bytes: bytes = bytes()

    debug_handle_map: Optional[
        Union[Dict[int, Tuple[int]], Dict[str, Tuple[int]]]
    ] = None

PreprocessResult 的定義 在此

DelegateMappingBuilder

DelegateMappingBuilder 是一個用於管理和建構 Debug Handle Maps 的輔助類別。建構 PreprocessResult 時,應傳入建構器的結果。

DelegateMappingBuilder 的定義 在此

可以透過 2 種模式之一建構 DelegateMappingBuilder 實例:手動識別符或產生的識別符。

# Manual Identifiers, Default
builder = DelegateMappingBuilder(generated_identifiers=False)

# Generated Identifiers
builder = DelegateMappingBuilder(generated_identifiers=True)

使用手動識別符 (manual identifiers) 時,使用者在建立條目時傳入一個 Delegate Debug Identifier (委派偵錯識別符)。使用產生的識別符 (generated identifiers) 時,建構器將自動指派一個 Delegate Debug Identifier (委派偵錯識別符)

要將條目新增到 Debug Handle Map (偵錯控制碼映射表),請使用 insert_delegate_mapping_entry。 它將 fx.Node(s) 或偵錯控制碼 (debug handles) (來源於 node.meta[“debug_handle”]) 之一,與可選的 Delegate Debug Identifier (委派偵錯識別符) (用於手動識別符) 相關聯。 記錄的識別符會從呼叫中傳回。

def insert_delegate_mapping_entry(
    self,
    nodes: Optional[Union[Node, List[Node]]] = None,
    handles: Optional[Union[int, List[int]]] = None,
    identifier: Optional[Union[int, str]] = None,
) -> Union[int, str]:

要檢索 Debug Handle Map (偵錯控制碼映射表),請使用 get_delegate_mapping

def get_delegate_mapping(
    self,
) -> Union[Dict[int, Tuple[int]], Dict[str, Tuple[int]]]

可以在 此處 找到 AOT 映射的演示。

執行階段記錄 (Runtime Logging)

與 AOT 映射對應,執行階段接著定義透過其記錄這些事件的功能。

即時記錄 (Real-Time Logging)

ExecuTorch 允許您即時記錄。 當時間戳記在執行發生時可用時,即時記錄 (Real time Logging) 非常有用。 它提供的額外負擔 (overhead) 最小,並且對作者來說調用起來很直觀。

要即時記錄事件 (例如,明確表示分析開始和停止),使用 event_tracer_start_profiling_delegate 來建立 EventEntry,並使用 event_tracer_end_profiling_delegate 來結束提供的 EventTracerEventEntry

要使用 event_tracer_start_profiling_delegate 啟動 EventTracerEntryDelegate Debug Identifier (委派偵錯識別符) (AOT 提供給 debug_handle_map) 會作為名稱或 delegate_debug_id 引數傳遞,具體取決於 Delegate Debug Identifier (委派偵錯識別符) 的類型 (分別為字串和整數)。

EventTracerEntry event_tracer_start_profiling_delegate(
    EventTracer* event_tracer,
    const char* name,
    DebugHandle delegate_debug_id)

要結束 EventTracerEntry,只需向 event_tracer_end_profiling_delegate 提供原始的 EventTracerEntry

或者,也可以在此時記錄額外的執行階段 metadata

void event_tracer_end_profiling_delegate(
    EventTracer* event_tracer,
    EventTracerEntry event_tracer_entry,
    const void* metadata = nullptr,
    size_t metadata_len = 0)

事後記錄 (Post-Time Logging)

ExecuTorch 也允許您事後記錄。 一些執行階段設定在執行時無法存取時間戳記。 事後記錄 (Post-Time Logging) 使作者仍然能夠記錄這些事件。

要在事後記錄事件 (例如,同時記錄開始和結束時間),請使用即時記錄 API 中使用的引數組合和時間戳記來呼叫 event_tracer_log_profiling_delegate

void event_tracer_log_profiling_delegate(
    EventTracer* event_tracer,
    const char* name,
    DebugHandle delegate_debug_id,
    et_timestamp_t start_time,
    et_timestamp_t end_time,
    const void* metadata = nullptr,
    size_t metadata_len = 0)

可以在 此處 找到執行階段程式碼的演示。

從委派事件中浮現自訂元資料 (metadata)

如上述執行階段記錄 API 中所見,使用者可以記錄一個位元組陣列以及他們的委派分析事件。 我們透過 Inspector API (檢測器 API) 在後處理中為使用者提供此資料。

使用者可以在建立 Inspector 實例時傳遞元資料剖析器。 剖析器是一個可呼叫物件,它會反序列化資料並傳回字串清單或包含鍵值對的字典。 然後,反序列化的資料會新增回事件區塊中的相應事件,以供使用者使用。 以下是如何編寫此剖析器的範例

注意:反序列化器的輸入是一個清單,其中每個條目都是一系列位元組 (本質上每個條目都是一個不可變的位元組陣列)。 使用者應迭代此清單,反序列化每個條目,然後以預期的格式 (字串清單或字典) 傳回它。

Inspector(
    etdump_path=etdump_path,
    # Optional
    etrecord=etrecord_path,
    # Optional, only needed if debugging was enabled.
    buffer_path=buffer_path,
    delegate_metadata_parser=parse_delegate_metadata
)


def parse_delegate_metadata(delegate_metadatas: List[bytes]) -> Union[List[str], Dict[str, Any]]:
    metadata_str = []
    for metadata_bytes in delegate_metadatas:
        metadata_str += str(metadata_bytes)
    return metadata_str

文件

存取 PyTorch 的全面開發者文檔

查看文檔

教學課程

獲取針對初學者和高級開發人員的深入教程

查看教程

資源

查找開發資源並獲得解答

查看資源