timmx 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- timmx-0.1.0/PKG-INFO +344 -0
- timmx-0.1.0/README.md +322 -0
- timmx-0.1.0/pyproject.toml +54 -0
- timmx-0.1.0/src/timmx/__init__.py +6 -0
- timmx-0.1.0/src/timmx/__main__.py +3 -0
- timmx-0.1.0/src/timmx/cli.py +124 -0
- timmx-0.1.0/src/timmx/console.py +3 -0
- timmx-0.1.0/src/timmx/errors.py +10 -0
- timmx-0.1.0/src/timmx/export/__init__.py +4 -0
- timmx-0.1.0/src/timmx/export/base.py +33 -0
- timmx-0.1.0/src/timmx/export/calibration.py +106 -0
- timmx-0.1.0/src/timmx/export/common.py +160 -0
- timmx-0.1.0/src/timmx/export/coreml_backend.py +190 -0
- timmx-0.1.0/src/timmx/export/executorch_backend.py +382 -0
- timmx-0.1.0/src/timmx/export/litert_backend.py +253 -0
- timmx-0.1.0/src/timmx/export/ncnn_backend.py +116 -0
- timmx-0.1.0/src/timmx/export/onnx_backend.py +114 -0
- timmx-0.1.0/src/timmx/export/registry.py +48 -0
- timmx-0.1.0/src/timmx/export/tensorrt_backend.py +345 -0
- timmx-0.1.0/src/timmx/export/torch_export_backend.py +94 -0
- timmx-0.1.0/src/timmx/export/torchscript_backend.py +90 -0
- timmx-0.1.0/src/timmx/export/types.py +6 -0
- timmx-0.1.0/src/timmx/py.typed +1 -0
timmx-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: timmx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Extensible CLI and Python package for exporting timm models.
|
|
5
|
+
Requires-Dist: rich
|
|
6
|
+
Requires-Dist: timm
|
|
7
|
+
Requires-Dist: torch>=2.5.0
|
|
8
|
+
Requires-Dist: typer
|
|
9
|
+
Requires-Dist: coremltools>=9.0 ; extra == 'coreml'
|
|
10
|
+
Requires-Dist: executorch>=1.1.0 ; extra == 'executorch'
|
|
11
|
+
Requires-Dist: litert-torch>=0.8.0 ; extra == 'litert'
|
|
12
|
+
Requires-Dist: pnnx ; extra == 'ncnn'
|
|
13
|
+
Requires-Dist: onnx>=1.16 ; extra == 'onnx'
|
|
14
|
+
Requires-Dist: onnxscript ; extra == 'onnx'
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Provides-Extra: coreml
|
|
17
|
+
Provides-Extra: executorch
|
|
18
|
+
Provides-Extra: litert
|
|
19
|
+
Provides-Extra: ncnn
|
|
20
|
+
Provides-Extra: onnx
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# timmx
|
|
24
|
+
|
|
25
|
+
An extensible CLI and Python package for exporting [timm](https://github.com/huggingface/pytorch-image-models) models to various deployment formats. Born out of having too many one-off export scripts for fine-tuned timm models — `timmx` unifies them behind a single command-line interface with a plugin-based backend system.
|
|
26
|
+
|
|
27
|
+
## Supported Formats
|
|
28
|
+
|
|
29
|
+
| Format | Command | Output |
|
|
30
|
+
|--------|---------|--------|
|
|
31
|
+
| ONNX | `timmx export onnx` | `.onnx` |
|
|
32
|
+
| Core ML | `timmx export coreml` | `.mlpackage` / `.mlmodel` |
|
|
33
|
+
| LiteRT / TFLite | `timmx export litert` | `.tflite` |
|
|
34
|
+
| ncnn | `timmx export ncnn` | directory (`.param` + `.bin`) |
|
|
35
|
+
| TensorRT | `timmx export tensorrt` | `.engine` |
|
|
36
|
+
| ExecuTorch | `timmx export executorch` | `.pte` |
|
|
37
|
+
| torch.export | `timmx export torch-export` | `.pt2` |
|
|
38
|
+
| TorchScript | `timmx export torchscript` | `.pt` |
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
- Python `>=3.11`
|
|
43
|
+
- [`uv`](https://docs.astral.sh/uv/)
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
Core install (includes `timm`, `torch`, `typer`, `rich`):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install timmx
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Install with specific backend extras:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install 'timmx[onnx]' # ONNX export
|
|
57
|
+
pip install 'timmx[coreml]' # Core ML export
|
|
58
|
+
pip install 'timmx[litert]' # LiteRT/TFLite export
|
|
59
|
+
pip install 'timmx[ncnn]' # ncnn export (via pnnx)
|
|
60
|
+
pip install 'timmx[executorch]' # ExecuTorch export (XNNPack, CoreML delegates)
|
|
61
|
+
pip install 'timmx[onnx,coreml]' # multiple backends
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
TensorRT requires CUDA and must be installed separately:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install tensorrt # Linux/Windows with CUDA only
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> **Note:** The `executorch` and `litert` extras have conflicting torch version
|
|
71
|
+
> requirements (`executorch` needs `torch>=2.10.0`, `litert` needs `torch<2.10.0`)
|
|
72
|
+
> and cannot be installed in the same environment.
|
|
73
|
+
|
|
74
|
+
Check which backends are available:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
timmx doctor
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Quick Start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
uv sync --extra onnx --extra coreml --extra ncnn --group dev
|
|
84
|
+
uv run timmx doctor
|
|
85
|
+
uv run timmx --help
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage Examples
|
|
89
|
+
|
|
90
|
+
### ONNX
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv run timmx export onnx resnet18 --pretrained --output ./artifacts/resnet18.onnx
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Export a fine-tuned checkpoint with dynamic batching:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv run timmx export onnx resnet18 \
|
|
100
|
+
--checkpoint ./checkpoints/model.pth \
|
|
101
|
+
--input-size 3 224 224 \
|
|
102
|
+
--dynamic-batch \
|
|
103
|
+
--output ./artifacts/resnet18_finetuned.onnx
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Core ML
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv run timmx export coreml resnet18 \
|
|
110
|
+
--pretrained \
|
|
111
|
+
--convert-to mlprogram \
|
|
112
|
+
--compute-precision float16 \
|
|
113
|
+
--output ./artifacts/resnet18.mlpackage
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Flexible batch size:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
uv run timmx export coreml resnet18 \
|
|
120
|
+
--dynamic-batch \
|
|
121
|
+
--batch-size 2 \
|
|
122
|
+
--batch-upper-bound 8 \
|
|
123
|
+
--output ./artifacts/resnet18_dynamic.mlpackage
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### LiteRT / TFLite
|
|
127
|
+
|
|
128
|
+
Supported modes: `fp32`, `fp16`, `dynamic-int8`, `int8`.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
uv run timmx export litert resnet18 \
|
|
132
|
+
--mode fp16 \
|
|
133
|
+
--output ./artifacts/resnet18_fp16.tflite
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
INT8 with calibration data:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# generate a calibration tensor
|
|
140
|
+
uv run python -c "import torch; torch.save(torch.randn(64, 3, 224, 224), 'calibration.pt')"
|
|
141
|
+
|
|
142
|
+
uv run timmx export litert resnet18 \
|
|
143
|
+
--mode int8 \
|
|
144
|
+
--calibration-data ./calibration.pt \
|
|
145
|
+
--calibration-steps 8 \
|
|
146
|
+
--output ./artifacts/resnet18_int8.tflite
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
NHWC input layout:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
uv run timmx export litert resnet18 \
|
|
153
|
+
--mode fp32 \
|
|
154
|
+
--nhwc-input \
|
|
155
|
+
--output ./artifacts/resnet18_nhwc.tflite
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### ncnn
|
|
159
|
+
|
|
160
|
+
Exports via [pnnx](https://github.com/pnnx/pnnx) and writes a deployment-ready ncnn model directory containing `model.ncnn.param`, `model.ncnn.bin`, and `model_ncnn.py`. pnnx intermediate files are removed automatically.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
uv run timmx export ncnn resnet18 \
|
|
164
|
+
--pretrained \
|
|
165
|
+
--output ./artifacts/resnet18_ncnn
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Export without fp16 weight quantization:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
uv run timmx export ncnn resnet18 \
|
|
172
|
+
--pretrained \
|
|
173
|
+
--no-fp16 \
|
|
174
|
+
--output ./artifacts/resnet18_ncnn_fp32
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### TensorRT
|
|
178
|
+
|
|
179
|
+
Requires an NVIDIA GPU with CUDA and the `tensorrt` package (`pip install tensorrt`).
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
uv run timmx export tensorrt resnet18 \
|
|
183
|
+
--pretrained \
|
|
184
|
+
--mode fp16 \
|
|
185
|
+
--output ./artifacts/resnet18_fp16.engine
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
INT8 with calibration:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
uv run timmx export tensorrt resnet18 \
|
|
192
|
+
--pretrained \
|
|
193
|
+
--mode int8 \
|
|
194
|
+
--calibration-data ./calibration.pt \
|
|
195
|
+
--calibration-steps 8 \
|
|
196
|
+
--output ./artifacts/resnet18_int8.engine
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Dynamic batch size:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
uv run timmx export tensorrt resnet18 \
|
|
203
|
+
--pretrained \
|
|
204
|
+
--dynamic-batch \
|
|
205
|
+
--batch-size 4 \
|
|
206
|
+
--batch-min 1 \
|
|
207
|
+
--batch-max 32 \
|
|
208
|
+
--output ./artifacts/resnet18_dynamic.engine
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### ExecuTorch
|
|
212
|
+
|
|
213
|
+
Export with XNNPack delegation (default, runs on CPU across all platforms):
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
uv run timmx export executorch resnet18 \
|
|
217
|
+
--pretrained \
|
|
218
|
+
--output ./artifacts/resnet18.pte
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
CoreML delegation (macOS — targets Apple Neural Engine / GPU / CPU):
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
uv run timmx export executorch resnet18 \
|
|
225
|
+
--pretrained \
|
|
226
|
+
--delegate coreml \
|
|
227
|
+
--output ./artifacts/resnet18_coreml.pte
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
CoreML with explicit fp32 compute precision (default is fp16):
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
uv run timmx export executorch resnet18 \
|
|
234
|
+
--pretrained \
|
|
235
|
+
--delegate coreml \
|
|
236
|
+
--compute-precision float32 \
|
|
237
|
+
--output ./artifacts/resnet18_coreml_fp32.pte
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
INT8 quantized with XNNPack:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
uv run timmx export executorch resnet18 \
|
|
244
|
+
--pretrained \
|
|
245
|
+
--mode int8 \
|
|
246
|
+
--calibration-data ./calibration.pt \
|
|
247
|
+
--calibration-steps 8 \
|
|
248
|
+
--output ./artifacts/resnet18_int8.pte
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
INT8 quantized with CoreML:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
uv run timmx export executorch resnet18 \
|
|
255
|
+
--pretrained \
|
|
256
|
+
--delegate coreml \
|
|
257
|
+
--mode int8 \
|
|
258
|
+
--output ./artifacts/resnet18_coreml_int8.pte
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Dynamic batch size:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
uv run timmx export executorch resnet18 \
|
|
265
|
+
--pretrained \
|
|
266
|
+
--dynamic-batch \
|
|
267
|
+
--batch-size 2 \
|
|
268
|
+
--output ./artifacts/resnet18_dynamic.pte
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### torch.export
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
uv run timmx export torch-export resnet18 \
|
|
275
|
+
--pretrained \
|
|
276
|
+
--dynamic-batch \
|
|
277
|
+
--batch-size 2 \
|
|
278
|
+
--output ./artifacts/resnet18.pt2
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
> When using `--dynamic-batch`, set `--batch-size` to at least `2` so PyTorch can capture a symbolic batch dimension.
|
|
282
|
+
|
|
283
|
+
### TorchScript
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
uv run timmx export torchscript resnet18 \
|
|
287
|
+
--pretrained \
|
|
288
|
+
--output ./artifacts/resnet18.pt
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Use `torch.jit.script` instead of the default `trace`:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
uv run timmx export torchscript resnet18 \
|
|
295
|
+
--pretrained \
|
|
296
|
+
--method script \
|
|
297
|
+
--output ./artifacts/resnet18_scripted.pt
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Diagnostics
|
|
301
|
+
|
|
302
|
+
Run `timmx doctor` to check your installation and see which backends are available:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
timmx doctor
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
This shows the timmx version, Python/torch versions, and a table of backend availability with install hints for any missing dependencies.
|
|
309
|
+
|
|
310
|
+
## Roadmap
|
|
311
|
+
|
|
312
|
+
- [x] ONNX
|
|
313
|
+
- [x] Core ML
|
|
314
|
+
- [x] LiteRT / TFLite
|
|
315
|
+
- [x] ncnn
|
|
316
|
+
- [x] torch.export
|
|
317
|
+
- [x] TensorRT
|
|
318
|
+
- [x] TorchScript
|
|
319
|
+
- [x] ExecuTorch (XNNPack + CoreML delegates)
|
|
320
|
+
- [ ] OpenVINO
|
|
321
|
+
- [ ] TensorFlow (SavedModel / .pb)
|
|
322
|
+
- [ ] TensorFlow.js
|
|
323
|
+
- [ ] TFLite Edge TPU
|
|
324
|
+
- [ ] RKNN
|
|
325
|
+
- [ ] MNN
|
|
326
|
+
- [ ] PaddlePaddle
|
|
327
|
+
|
|
328
|
+
## Development
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
uv sync --extra onnx --extra coreml --extra ncnn --group dev # install extras + pytest
|
|
332
|
+
uvx ruff format . # format
|
|
333
|
+
uvx ruff check . # lint
|
|
334
|
+
uv run pytest # test
|
|
335
|
+
uv build # build
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Adding a New Backend
|
|
339
|
+
|
|
340
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for a step-by-step guide on implementing and registering a new export backend.
|
|
341
|
+
|
|
342
|
+
## AI Disclaimer
|
|
343
|
+
|
|
344
|
+
This project is developed with the assistance of AI tools. The original export logic comes from various standalone scripts I wrote for exporting fine-tuned timm models to different deployment formats. The process of consolidating these scripts into a unified CLI tool has been aided by AI, with my oversight at every step, reviewing generated code, manually fixing issues during backend porting, and validating that exports produce correct results.
|
timmx-0.1.0/README.md
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# timmx
|
|
2
|
+
|
|
3
|
+
An extensible CLI and Python package for exporting [timm](https://github.com/huggingface/pytorch-image-models) models to various deployment formats. Born out of having too many one-off export scripts for fine-tuned timm models — `timmx` unifies them behind a single command-line interface with a plugin-based backend system.
|
|
4
|
+
|
|
5
|
+
## Supported Formats
|
|
6
|
+
|
|
7
|
+
| Format | Command | Output |
|
|
8
|
+
|--------|---------|--------|
|
|
9
|
+
| ONNX | `timmx export onnx` | `.onnx` |
|
|
10
|
+
| Core ML | `timmx export coreml` | `.mlpackage` / `.mlmodel` |
|
|
11
|
+
| LiteRT / TFLite | `timmx export litert` | `.tflite` |
|
|
12
|
+
| ncnn | `timmx export ncnn` | directory (`.param` + `.bin`) |
|
|
13
|
+
| TensorRT | `timmx export tensorrt` | `.engine` |
|
|
14
|
+
| ExecuTorch | `timmx export executorch` | `.pte` |
|
|
15
|
+
| torch.export | `timmx export torch-export` | `.pt2` |
|
|
16
|
+
| TorchScript | `timmx export torchscript` | `.pt` |
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- Python `>=3.11`
|
|
21
|
+
- [`uv`](https://docs.astral.sh/uv/)
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
Core install (includes `timm`, `torch`, `typer`, `rich`):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install timmx
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Install with specific backend extras:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install 'timmx[onnx]' # ONNX export
|
|
35
|
+
pip install 'timmx[coreml]' # Core ML export
|
|
36
|
+
pip install 'timmx[litert]' # LiteRT/TFLite export
|
|
37
|
+
pip install 'timmx[ncnn]' # ncnn export (via pnnx)
|
|
38
|
+
pip install 'timmx[executorch]' # ExecuTorch export (XNNPack, CoreML delegates)
|
|
39
|
+
pip install 'timmx[onnx,coreml]' # multiple backends
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
TensorRT requires CUDA and must be installed separately:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install tensorrt # Linux/Windows with CUDA only
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
> **Note:** The `executorch` and `litert` extras have conflicting torch version
|
|
49
|
+
> requirements (`executorch` needs `torch>=2.10.0`, `litert` needs `torch<2.10.0`)
|
|
50
|
+
> and cannot be installed in the same environment.
|
|
51
|
+
|
|
52
|
+
Check which backends are available:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
timmx doctor
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv sync --extra onnx --extra coreml --extra ncnn --group dev
|
|
62
|
+
uv run timmx doctor
|
|
63
|
+
uv run timmx --help
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage Examples
|
|
67
|
+
|
|
68
|
+
### ONNX
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
uv run timmx export onnx resnet18 --pretrained --output ./artifacts/resnet18.onnx
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Export a fine-tuned checkpoint with dynamic batching:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
uv run timmx export onnx resnet18 \
|
|
78
|
+
--checkpoint ./checkpoints/model.pth \
|
|
79
|
+
--input-size 3 224 224 \
|
|
80
|
+
--dynamic-batch \
|
|
81
|
+
--output ./artifacts/resnet18_finetuned.onnx
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Core ML
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv run timmx export coreml resnet18 \
|
|
88
|
+
--pretrained \
|
|
89
|
+
--convert-to mlprogram \
|
|
90
|
+
--compute-precision float16 \
|
|
91
|
+
--output ./artifacts/resnet18.mlpackage
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Flexible batch size:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
uv run timmx export coreml resnet18 \
|
|
98
|
+
--dynamic-batch \
|
|
99
|
+
--batch-size 2 \
|
|
100
|
+
--batch-upper-bound 8 \
|
|
101
|
+
--output ./artifacts/resnet18_dynamic.mlpackage
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### LiteRT / TFLite
|
|
105
|
+
|
|
106
|
+
Supported modes: `fp32`, `fp16`, `dynamic-int8`, `int8`.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv run timmx export litert resnet18 \
|
|
110
|
+
--mode fp16 \
|
|
111
|
+
--output ./artifacts/resnet18_fp16.tflite
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
INT8 with calibration data:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# generate a calibration tensor
|
|
118
|
+
uv run python -c "import torch; torch.save(torch.randn(64, 3, 224, 224), 'calibration.pt')"
|
|
119
|
+
|
|
120
|
+
uv run timmx export litert resnet18 \
|
|
121
|
+
--mode int8 \
|
|
122
|
+
--calibration-data ./calibration.pt \
|
|
123
|
+
--calibration-steps 8 \
|
|
124
|
+
--output ./artifacts/resnet18_int8.tflite
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
NHWC input layout:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
uv run timmx export litert resnet18 \
|
|
131
|
+
--mode fp32 \
|
|
132
|
+
--nhwc-input \
|
|
133
|
+
--output ./artifacts/resnet18_nhwc.tflite
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### ncnn
|
|
137
|
+
|
|
138
|
+
Exports via [pnnx](https://github.com/pnnx/pnnx) and writes a deployment-ready ncnn model directory containing `model.ncnn.param`, `model.ncnn.bin`, and `model_ncnn.py`. pnnx intermediate files are removed automatically.
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
uv run timmx export ncnn resnet18 \
|
|
142
|
+
--pretrained \
|
|
143
|
+
--output ./artifacts/resnet18_ncnn
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Export without fp16 weight quantization:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
uv run timmx export ncnn resnet18 \
|
|
150
|
+
--pretrained \
|
|
151
|
+
--no-fp16 \
|
|
152
|
+
--output ./artifacts/resnet18_ncnn_fp32
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### TensorRT
|
|
156
|
+
|
|
157
|
+
Requires an NVIDIA GPU with CUDA and the `tensorrt` package (`pip install tensorrt`).
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
uv run timmx export tensorrt resnet18 \
|
|
161
|
+
--pretrained \
|
|
162
|
+
--mode fp16 \
|
|
163
|
+
--output ./artifacts/resnet18_fp16.engine
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
INT8 with calibration:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
uv run timmx export tensorrt resnet18 \
|
|
170
|
+
--pretrained \
|
|
171
|
+
--mode int8 \
|
|
172
|
+
--calibration-data ./calibration.pt \
|
|
173
|
+
--calibration-steps 8 \
|
|
174
|
+
--output ./artifacts/resnet18_int8.engine
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Dynamic batch size:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
uv run timmx export tensorrt resnet18 \
|
|
181
|
+
--pretrained \
|
|
182
|
+
--dynamic-batch \
|
|
183
|
+
--batch-size 4 \
|
|
184
|
+
--batch-min 1 \
|
|
185
|
+
--batch-max 32 \
|
|
186
|
+
--output ./artifacts/resnet18_dynamic.engine
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### ExecuTorch
|
|
190
|
+
|
|
191
|
+
Export with XNNPack delegation (default, runs on CPU across all platforms):
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
uv run timmx export executorch resnet18 \
|
|
195
|
+
--pretrained \
|
|
196
|
+
--output ./artifacts/resnet18.pte
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
CoreML delegation (macOS — targets Apple Neural Engine / GPU / CPU):
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
uv run timmx export executorch resnet18 \
|
|
203
|
+
--pretrained \
|
|
204
|
+
--delegate coreml \
|
|
205
|
+
--output ./artifacts/resnet18_coreml.pte
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
CoreML with explicit fp32 compute precision (default is fp16):
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
uv run timmx export executorch resnet18 \
|
|
212
|
+
--pretrained \
|
|
213
|
+
--delegate coreml \
|
|
214
|
+
--compute-precision float32 \
|
|
215
|
+
--output ./artifacts/resnet18_coreml_fp32.pte
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
INT8 quantized with XNNPack:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
uv run timmx export executorch resnet18 \
|
|
222
|
+
--pretrained \
|
|
223
|
+
--mode int8 \
|
|
224
|
+
--calibration-data ./calibration.pt \
|
|
225
|
+
--calibration-steps 8 \
|
|
226
|
+
--output ./artifacts/resnet18_int8.pte
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
INT8 quantized with CoreML:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
uv run timmx export executorch resnet18 \
|
|
233
|
+
--pretrained \
|
|
234
|
+
--delegate coreml \
|
|
235
|
+
--mode int8 \
|
|
236
|
+
--output ./artifacts/resnet18_coreml_int8.pte
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Dynamic batch size:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
uv run timmx export executorch resnet18 \
|
|
243
|
+
--pretrained \
|
|
244
|
+
--dynamic-batch \
|
|
245
|
+
--batch-size 2 \
|
|
246
|
+
--output ./artifacts/resnet18_dynamic.pte
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### torch.export
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
uv run timmx export torch-export resnet18 \
|
|
253
|
+
--pretrained \
|
|
254
|
+
--dynamic-batch \
|
|
255
|
+
--batch-size 2 \
|
|
256
|
+
--output ./artifacts/resnet18.pt2
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
> When using `--dynamic-batch`, set `--batch-size` to at least `2` so PyTorch can capture a symbolic batch dimension.
|
|
260
|
+
|
|
261
|
+
### TorchScript
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
uv run timmx export torchscript resnet18 \
|
|
265
|
+
--pretrained \
|
|
266
|
+
--output ./artifacts/resnet18.pt
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Use `torch.jit.script` instead of the default `trace`:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
uv run timmx export torchscript resnet18 \
|
|
273
|
+
--pretrained \
|
|
274
|
+
--method script \
|
|
275
|
+
--output ./artifacts/resnet18_scripted.pt
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Diagnostics
|
|
279
|
+
|
|
280
|
+
Run `timmx doctor` to check your installation and see which backends are available:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
timmx doctor
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
This shows the timmx version, Python/torch versions, and a table of backend availability with install hints for any missing dependencies.
|
|
287
|
+
|
|
288
|
+
## Roadmap
|
|
289
|
+
|
|
290
|
+
- [x] ONNX
|
|
291
|
+
- [x] Core ML
|
|
292
|
+
- [x] LiteRT / TFLite
|
|
293
|
+
- [x] ncnn
|
|
294
|
+
- [x] torch.export
|
|
295
|
+
- [x] TensorRT
|
|
296
|
+
- [x] TorchScript
|
|
297
|
+
- [x] ExecuTorch (XNNPack + CoreML delegates)
|
|
298
|
+
- [ ] OpenVINO
|
|
299
|
+
- [ ] TensorFlow (SavedModel / .pb)
|
|
300
|
+
- [ ] TensorFlow.js
|
|
301
|
+
- [ ] TFLite Edge TPU
|
|
302
|
+
- [ ] RKNN
|
|
303
|
+
- [ ] MNN
|
|
304
|
+
- [ ] PaddlePaddle
|
|
305
|
+
|
|
306
|
+
## Development
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
uv sync --extra onnx --extra coreml --extra ncnn --group dev # install extras + pytest
|
|
310
|
+
uvx ruff format . # format
|
|
311
|
+
uvx ruff check . # lint
|
|
312
|
+
uv run pytest # test
|
|
313
|
+
uv build # build
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Adding a New Backend
|
|
317
|
+
|
|
318
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for a step-by-step guide on implementing and registering a new export backend.
|
|
319
|
+
|
|
320
|
+
## AI Disclaimer
|
|
321
|
+
|
|
322
|
+
This project is developed with the assistance of AI tools. The original export logic comes from various standalone scripts I wrote for exporting fine-tuned timm models to different deployment formats. The process of consolidating these scripts into a unified CLI tool has been aided by AI, with my oversight at every step, reviewing generated code, manually fixing issues during backend porting, and validating that exports produce correct results.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "timmx"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Extensible CLI and Python package for exporting timm models."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"rich",
|
|
9
|
+
"timm",
|
|
10
|
+
"torch>=2.5.0",
|
|
11
|
+
"typer",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[project.optional-dependencies]
|
|
15
|
+
coreml = ["coremltools>=9.0"]
|
|
16
|
+
executorch = ["executorch>=1.1.0"]
|
|
17
|
+
litert = ["litert-torch>=0.8.0"]
|
|
18
|
+
ncnn = ["pnnx"]
|
|
19
|
+
onnx = ["onnx>=1.16", "onnxscript"]
|
|
20
|
+
|
|
21
|
+
[project.scripts]
|
|
22
|
+
timmx = "timmx.cli:main"
|
|
23
|
+
|
|
24
|
+
[dependency-groups]
|
|
25
|
+
dev = [
|
|
26
|
+
"pytest>=8.3.4",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["uv_build>=0.10.0,<0.11.0"]
|
|
31
|
+
build-backend = "uv_build"
|
|
32
|
+
|
|
33
|
+
[tool.uv.build-backend]
|
|
34
|
+
module-name = "timmx"
|
|
35
|
+
module-root = "src"
|
|
36
|
+
|
|
37
|
+
[tool.uv]
|
|
38
|
+
conflicts = [
|
|
39
|
+
[
|
|
40
|
+
{ extra = "executorch" },
|
|
41
|
+
{ extra = "litert" },
|
|
42
|
+
],
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[tool.ruff]
|
|
46
|
+
target-version = "py311"
|
|
47
|
+
line-length = 100
|
|
48
|
+
|
|
49
|
+
[tool.ruff.lint]
|
|
50
|
+
extend-select = ["I"]
|
|
51
|
+
|
|
52
|
+
[tool.pytest.ini_options]
|
|
53
|
+
testpaths = ["tests"]
|
|
54
|
+
addopts = "-q"
|