|
| 1 | +# `.ptd` file format |
| 2 | + |
| 3 | +ExecuTorch `.ptd` files are serialized as modified binary flatbuffer |
| 4 | +files with data segments appended. They provide a way to store named data using |
| 5 | +the FlatTensor format. Named data can be tensors or opaque blob data (usually for backends that do not expose data format). |
| 6 | + |
| 7 | +Code related to the PTD file format is in the `//executorch/extension/flat_tensor/` directory. |
| 8 | + |
| 9 | +``` |
| 10 | + ┌───────────────────────────────────┐ |
| 11 | + │Standard flatbuffer header │ |
| 12 | + ├───────────────────────────────────┤ |
| 13 | + │ExecuTorch extended header │ |
| 14 | + ├───────────────────────────────────┤ |
| 15 | + │Flatbuffer-serialized metadata │ |
| 16 | + │(FlatTensor) │ |
| 17 | + │ │ |
| 18 | + ┌─ ├───────────────────────────────────┤ |
| 19 | + │ │Padding │ |
| 20 | + │ ├───────────────────────────────────┤ |
| 21 | + │ │Data segment │ |
| 22 | + │ │ │ |
| 23 | + │ │ │ |
| 24 | + │ ├───────────────────────────────────┤ |
| 25 | + │ │Padding │ |
| 26 | + Blobs ─┤ ├───────────────────────────────────┤ |
| 27 | + │ │Data segment │ |
| 28 | + │ │ │ |
| 29 | + │ │ │ |
| 30 | + │ ├───────────────────────────────────┤ |
| 31 | + │ │Padding │ |
| 32 | + │ ├───────────────────────────────────┤ |
| 33 | + │ │... │ |
| 34 | + └─ └───────────────────────────────────┘ |
| 35 | +``` |
| 36 | + |
| 37 | +## Compatibility |
| 38 | + |
| 39 | +PTD files are designed for storing named data that can be loaded by ExecuTorch |
| 40 | +models. |
| 41 | + |
| 42 | +## Headers |
| 43 | + |
| 44 | +PTD files can be recognized by the magic string at byte offset 4, beginning with `FT` |
| 45 | +and followed by two ASCII decimal digits (file identifier from the FlatBuffers schema). |
| 46 | + |
| 47 | +PTD files have an extended header at byte offset 8, recognized by the magic string |
| 48 | +`FH01`. This header includes the size and offset information for both the |
| 49 | +flatbuffer-serialized metadata and the data segments that follow. |
| 50 | + |
| 51 | +Note that this header is ExecuTorch-specific, but even when present it does not |
| 52 | +upset most flatbuffer-parsing code (apart from the rarely-used |
| 53 | +`GetBufferStartFromRootPointer()`). |
| 54 | + |
| 55 | +All numbers are little-endian, regardless of the host system. |
| 56 | + |
| 57 | +Header layout: |
| 58 | +``` |
| 59 | +[0..3] uint32_t byte offset to the beginning of the flatbuffer root table. |
| 60 | +[4..7] File magic bytes: "FT" followed by two ASCII decimal digits. The digits |
| 61 | + correspond to the FlatBuffers file identifier. |
| 62 | +Extended header (always present): |
| 63 | +| [8..11] Extended header magic bytes: "FH01" - FlatTensor Header version 01. |
| 64 | +| [12..15] uint32_t size of this extended header in bytes, including the magic |
| 65 | +| header and this size field. Currently fixed at 40 bytes. |
| 66 | +| [16..23] uint64_t offset (from byte offset zero) to the start of the |
| 67 | +| flatbuffer data. |
| 68 | +| [24..31] uint64_t size of the flatbuffer-encoded tensor metadata in bytes. |
| 69 | +| [32..39] uint64_t offset (from byte offset zero) to the start of the first |
| 70 | +| data segment. |
| 71 | +| [40..47] uint64_t total size of all data segments in bytes. |
| 72 | +End of extended header. |
| 73 | +``` |
| 74 | + |
| 75 | +Example: |
| 76 | +``` |
| 77 | + Offset to flatbuffer root (0x44) |
| 78 | + | File magic ("FT01") |
| 79 | + | | Extended header magic ("FH01") |
| 80 | + | | | Extended header size (0x28) |
| 81 | + vvvvvvvvvvv vvvvvvvvvvv vvvvvvvvvvv vvvvvvvvvvv |
| 82 | +0x0000 44 00 00 00 46 54 30 31 46 48 30 31 28 00 00 00 |
| 83 | +0x0010 30 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 |
| 84 | +0x0020 30 01 00 00 00 00 00 00 20 00 00 00 00 00 00 00 |
| 85 | + ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 86 | + | | Flatbuffer size (0x100) |
| 87 | + | | Segment data size (0x20) |
| 88 | + Segment base offset (0x130) |
| 89 | +``` |
| 90 | +Note: this example comes from inspecting the ModuleAddMul.ptd file. |
| 91 | +``` |
| 92 | +python -m test.models.export_program --modules "ModuleAddMul" --external-constants --outdir . |
| 93 | +
|
| 94 | +xxd -l 64 ModuleAddMulProgram.ptd |
| 95 | +``` |
| 96 | + |
| 97 | +## FlatTensor |
| 98 | + |
| 99 | +See `//executorch/extension/flat_tensor/serialize/flat_tensor.fbs` for the |
| 100 | +FlatTensor flatbuffer schema. |
| 101 | + |
| 102 | +The flatbuffer-encoded metadata follows the headers and contains: |
| 103 | + |
| 104 | +- **Schema version**: Version information for compatibility. |
| 105 | +- **Data segments**: List of segment descriptors with offset and size information. |
| 106 | +- **Named data**: List of named data entries, each containing: |
| 107 | + - **Key**: String identifier for the data blob. |
| 108 | + - **Segment index**: Reference to the data segment containing the blob. |
| 109 | + - **Tensor layout**: Optional metadata including scalar type, sizes and dim order, if the data segment contains a tensor. |
| 110 | + |
| 111 | +### Tensor Layout |
| 112 | + |
| 113 | +If a data segment contains a canonical tensor, it may have associated layout information: |
| 114 | +- **Scalar type**: Data type (float32, int32, etc.) using ExecutorTorch scalar types. |
| 115 | +- **Sizes**: Dimensions of the tensor. |
| 116 | +- **Dim order**: Memory layout order specifying how dimensions are arranged in memory. |
| 117 | + |
| 118 | +## Data segments |
| 119 | + |
| 120 | +The `FlatTensor.segments` list in the metadata contains offset and size |
| 121 | +information about each data segment. Offsets in this list are relative to |
| 122 | +the segment base offset specified in the extended header. |
| 123 | + |
| 124 | +Each segment contains: |
| 125 | +- **Offset**: Relative offset from the segment base offset. |
| 126 | +- **Size**: Size of the valid data in bytes (may be followed by padding). |
| 127 | + |
| 128 | +## Named data access |
| 129 | + |
| 130 | +Tensors are accessed by string keys through the `named_data` list. Each entry |
| 131 | +maps a string key to: |
| 132 | +1. A segment index pointing to the raw data. |
| 133 | +2. Optional tensor layout metadata, if the data segment contains a tensor. |
| 134 | + |
| 135 | +This design allows: |
| 136 | +- Multiple named data blobs to reference the same data segment. |
| 137 | +- Access to tensor layout data without loading the entire blob. |
| 138 | + |
| 139 | +## Usage |
| 140 | + |
| 141 | +PTD files are used to store data outside of the PTE file. Some use-cases: |
| 142 | +- On-device training: checkpointing for model weights. |
| 143 | +- Deduplication: sharing model weights between multiple executable PTE files. |
| 144 | +- Flexible deployment: allow async updates between program and data. |
0 commit comments