mlflow-triton 0.4.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.
- mlflow_triton-0.4.0/LICENSE +201 -0
- mlflow_triton-0.4.0/PKG-INFO +459 -0
- mlflow_triton-0.4.0/README.md +443 -0
- mlflow_triton-0.4.0/pyproject.toml +29 -0
- mlflow_triton-0.4.0/setup.cfg +4 -0
- mlflow_triton-0.4.0/src/mlflow_triton/__init__.py +1 -0
- mlflow_triton-0.4.0/src/mlflow_triton/_architecture.py +92 -0
- mlflow_triton-0.4.0/src/mlflow_triton/_logging.py +359 -0
- mlflow_triton-0.4.0/src/mlflow_triton/_pbtxt.py +59 -0
- mlflow_triton-0.4.0/src/mlflow_triton/_request.py +71 -0
- mlflow_triton-0.4.0/src/mlflow_triton/_runtime.py +272 -0
- mlflow_triton-0.4.0/src/mlflow_triton/_signature.py +166 -0
- mlflow_triton-0.4.0/src/mlflow_triton/py.typed +0 -0
- mlflow_triton-0.4.0/src/mlflow_triton/pytorch.py +57 -0
- mlflow_triton-0.4.0/src/mlflow_triton/sklearn.py +55 -0
- mlflow_triton-0.4.0/src/mlflow_triton/transformers.py +57 -0
- mlflow_triton-0.4.0/src/mlflow_triton/triton.py +97 -0
- mlflow_triton-0.4.0/src/mlflow_triton.egg-info/PKG-INFO +459 -0
- mlflow_triton-0.4.0/src/mlflow_triton.egg-info/SOURCES.txt +20 -0
- mlflow_triton-0.4.0/src/mlflow_triton.egg-info/dependency_links.txt +1 -0
- mlflow_triton-0.4.0/src/mlflow_triton.egg-info/requires.txt +2 -0
- mlflow_triton-0.4.0/src/mlflow_triton.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mlflow-triton
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: MLflow logging wrappers and portable Triton model repositories
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Project-URL: Homepage, https://github.com/ai-lab-tech/mlflow-plugin
|
|
7
|
+
Project-URL: Documentation, https://github.com/ai-lab-tech/mlflow-plugin/blob/main/packages/mlflow-triton/README.md
|
|
8
|
+
Project-URL: Repository, https://github.com/ai-lab-tech/mlflow-plugin
|
|
9
|
+
Project-URL: Issues, https://github.com/ai-lab-tech/mlflow-plugin/issues
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: mlflow<4,>=3.14
|
|
14
|
+
Requires-Dist: protobuf>=3.20.3
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# mlflow-triton
|
|
18
|
+
|
|
19
|
+
> **For demos and proofs of concept — not production-ready serving.**
|
|
20
|
+
>
|
|
21
|
+
> **Before production use, an ML Engineer must review, validate and optimize the
|
|
22
|
+
> serving implementation and, where needed, convert the model to a suitable
|
|
23
|
+
> production format/backend.** The generated Triton Python backend uses MLflow's
|
|
24
|
+
> prediction interface as a starting point. Successful example tests do not
|
|
25
|
+
> establish production readiness, throughput, latency or resource efficiency.
|
|
26
|
+
|
|
27
|
+
Core MLflow logging wrappers for sklearn, PyTorch and Hugging Face. Generate a
|
|
28
|
+
portable Triton repository for Data Scientist demos and PoCs, without requiring
|
|
29
|
+
Triton Control, deployment credentials or an LLM. Production optimization remains
|
|
30
|
+
a separate ML Engineering task.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install mlflow-triton
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Requires Python 3.10+ and MLflow >=3.14,<4. Install the framework dependencies
|
|
37
|
+
appropriate to your saved model separately. This package registers no deployment
|
|
38
|
+
entry point and makes no Triton Control API calls.
|
|
39
|
+
`config.pbtxt` is generated in Protobuf text format, using Protobuf string escaping.
|
|
40
|
+
|
|
41
|
+
## Log native models with a required example request
|
|
42
|
+
|
|
43
|
+
Use the plugin's framework module instead of `mlflow.<framework>.log_model`:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from mlflow_triton import sklearn, pytorch, transformers
|
|
47
|
+
|
|
48
|
+
# Already-fitted Pipeline, including its original preprocessing.
|
|
49
|
+
info = sklearn.log_model(
|
|
50
|
+
fitted_pipeline,
|
|
51
|
+
name="classifier",
|
|
52
|
+
input_example=example_dataframe,
|
|
53
|
+
registered_model_name="classifier",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Instantiated custom architecture with its saved trained weights loaded.
|
|
57
|
+
# Include inference-only class/helper modules, not a training entry point.
|
|
58
|
+
torch_info = pytorch.log_model(
|
|
59
|
+
loaded_model.eval(),
|
|
60
|
+
name="network",
|
|
61
|
+
input_example=example_numpy_array,
|
|
62
|
+
code_paths=["inference_architecture"],
|
|
63
|
+
pip_requirements=["torch==<your-version>", "numpy==<your-version>"],
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# A supported Transformers pipeline containing the model and tokenizer/processor.
|
|
67
|
+
hf_info = transformers.log_model(
|
|
68
|
+
loaded_pipeline,
|
|
69
|
+
name="text_model",
|
|
70
|
+
input_example=["Example input"],
|
|
71
|
+
model_config={"max_new_tokens": 32, "do_sample": False, "return_full_text": True},
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
print(info.model_uri)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`input_example` is a mandatory keyword argument even when `signature=` is supplied.
|
|
78
|
+
It is the model's prediction input (DataFrame, NumPy array, named tensor dictionary,
|
|
79
|
+
or supported Transformers task input), **not** a Triton HTTP request envelope.
|
|
80
|
+
MLflow stores the example with the model: use appropriate non-sensitive examples.
|
|
81
|
+
No training is run. By default, logging executes inference using the supplied
|
|
82
|
+
model on its current device, without reloading its weights or moving it to CPU.
|
|
83
|
+
Allow memory for example inference and native serialization. Set
|
|
84
|
+
`validate_saved_model=True` to instead reload the saved artifact on CPU for
|
|
85
|
+
validation; this requires memory for an additional model copy.
|
|
86
|
+
Framework packages such as torch/transformers remain optional plugin dependencies;
|
|
87
|
+
install the versions required by your model.
|
|
88
|
+
|
|
89
|
+
The wrappers preserve an explicit signature. Otherwise they infer one with MLflow
|
|
90
|
+
from the example and model prediction.
|
|
91
|
+
They reject missing/incompatible schemas before logging or registration. Native
|
|
92
|
+
flavor options such as `code_paths`, requirements, sklearn's `pyfunc_predict_fn`,
|
|
93
|
+
and Transformers' `task`, `processor` and `model_config` are forwarded to native
|
|
94
|
+
packaging. `name`, `registered_model_name`, `await_registration_for`, `run_id`,
|
|
95
|
+
`metadata`, `tags` and logging `params` are supported. Logging `params` are tracking
|
|
96
|
+
metadata, not generation parameters: use `model_config` for Transformers settings.
|
|
97
|
+
This is an explicit wrapper API; it does not monkey-patch MLflow or autologging.
|
|
98
|
+
|
|
99
|
+
The logged artifact contains the native MLflow flavors and an additional `triton`
|
|
100
|
+
flavor pointing to:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
model_repository/<name>/
|
|
104
|
+
config.pbtxt
|
|
105
|
+
requirements.txt
|
|
106
|
+
request.json
|
|
107
|
+
validation.json
|
|
108
|
+
1/
|
|
109
|
+
model.py
|
|
110
|
+
artifact/ # Complete local MLflow package, including code and assets
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Native `mlflow.pyfunc.load_model(info.model_uri)` and native framework loaders
|
|
114
|
+
remain usable. The embedded package is a separate copy so the Triton directory
|
|
115
|
+
can be deployed independently; this increases artifact storage size. Dependencies
|
|
116
|
+
are recorded, not installed into the running Triton server automatically. Build
|
|
117
|
+
an environment from `requirements.txt` with a Python version matching Triton's
|
|
118
|
+
Python backend stub; custom code dependencies must be included or installed.
|
|
119
|
+
|
|
120
|
+
The generated configuration uses `backend: "python"` and `max_batch_size: 0`.
|
|
121
|
+
Tensor shapes include their full batch dimension. Column schemas map to separate
|
|
122
|
+
rank-one tensors; tensor schemas retain their declared shapes. The `mlflow_contract` parameter in `config.pbtxt`
|
|
123
|
+
records mappings between original field names and Triton-safe tensor names.
|
|
124
|
+
Only dynamic axes already declared by the signature are retained; a single
|
|
125
|
+
example does not prove that other sequence/image dimensions are variable.
|
|
126
|
+
Supply an explicit signature when those dimensions need to be dynamic.
|
|
127
|
+
|
|
128
|
+
`device="cpu"` is the default. `device="gpu"` emits `KIND_GPU` for PyTorch or
|
|
129
|
+
Transformers; `model.py` uses the assigned Triton instance device when loading.
|
|
130
|
+
Default validation uses the supplied model's current device, independently of the
|
|
131
|
+
Triton target. Optional saved-artifact validation loads on CPU even for a GPU
|
|
132
|
+
target. Sharded/device-mapped models or tasks unsupported by MLflow pyfunc
|
|
133
|
+
need a separate adapter; the wrapper does not claim universal model support.
|
|
134
|
+
|
|
135
|
+
PyTorch uses Python/pickle packaging by default, **not** an implicit LibTorch/PT2
|
|
136
|
+
export. Supply required architecture modules with `code_paths` or dependencies.
|
|
137
|
+
Pre/postprocessing outside the supplied model/Pipeline is not captured. Transformers
|
|
138
|
+
packages preserve their saved tokenizer, chat template and model configuration,
|
|
139
|
+
and expose the MLflow task interface (which can differ from raw `forward()` or
|
|
140
|
+
pipeline outputs). Serving is unary prediction, not streaming or a dedicated
|
|
141
|
+
high-throughput LLM engine. No GGUF/Q4_K_M compatibility is implied.
|
|
142
|
+
|
|
143
|
+
Supported signatures contain NumPy-compatible numeric/string tensors or required
|
|
144
|
+
scalar DataFrame columns. Optional columns, nested/object schemas, datetime columns,
|
|
145
|
+
and scalar tensors require an explicit serving adapter and fail clearly rather than
|
|
146
|
+
being flattened or cast speculatively.
|
|
147
|
+
|
|
148
|
+
`validation.json` identifies in-memory or saved-artifact prediction validation,
|
|
149
|
+
records whether the saved artifact was checked, and distinguishes local mapping
|
|
150
|
+
validation from actual Triton validation. Logging does **not** launch Triton, deploy a service,
|
|
151
|
+
or establish GPU correctness. The direct `triton.log_model()` API below remains available. Deployment is a separate concern.
|
|
152
|
+
|
|
153
|
+
## Log API reference
|
|
154
|
+
|
|
155
|
+
The three framework wrappers have these public entry points (common keyword
|
|
156
|
+
options are abbreviated below; the Python signatures expose them explicitly):
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
sklearn.log_model(sk_model, *, input_example, **kwargs)
|
|
160
|
+
pytorch.log_model(pytorch_model, *, input_example, **kwargs)
|
|
161
|
+
transformers.log_model(transformers_model, *, input_example, **kwargs)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Pass the model positionally or by its exact parameter name. `input_example` and
|
|
165
|
+
all other options must be keyword arguments. The tables below describe the
|
|
166
|
+
options handled by this plugin and commonly used native packaging options.
|
|
167
|
+
|
|
168
|
+
### Required arguments
|
|
169
|
+
|
|
170
|
+
| Function | Model argument | Required `input_example` |
|
|
171
|
+
| --- | --- | --- |
|
|
172
|
+
| `sklearn.log_model` | `sk_model`: already-fitted estimator or complete preprocessing `Pipeline`. | A non-empty DataFrame or NumPy array accepted by the saved prediction interface. Preserve column names, order and dtypes. |
|
|
173
|
+
| `pytorch.log_model` | `pytorch_model`: instantiated `torch.nn.Module` with trained weights loaded; call `.eval()` first. A `state_dict` or filename alone is insufficient. | A non-empty NumPy input, or named tensor input supported by MLflow's PyTorch prediction interface. Match the model's input dtype and dimensions. |
|
|
174
|
+
| `transformers.log_model` | `transformers_model`: supported Transformers pipeline, or component dictionary such as `{"model": model, "tokenizer": tokenizer}`. Include the task's required tokenizer/processor assets. | A non-empty task input supported by MLflow pyfunc, such as a list of text strings or a DataFrame with the task's input fields. |
|
|
175
|
+
|
|
176
|
+
`input_example=None` and empty examples are rejected. The example remains
|
|
177
|
+
mandatory with an explicit signature. It is saved in the artifact and used for
|
|
178
|
+
prediction and tensor-mapping validation; it is not training data or a Triton
|
|
179
|
+
HTTP request. PyTorch models with any submodule still in training mode are rejected.
|
|
180
|
+
|
|
181
|
+
### Common optional arguments
|
|
182
|
+
|
|
183
|
+
These arguments are accepted by all three framework wrappers through `**kwargs`.
|
|
184
|
+
|
|
185
|
+
| Argument | Type / default | Meaning |
|
|
186
|
+
| --- | --- | --- |
|
|
187
|
+
| `name` | `str`, `"model"` | MLflow logged-model name. Also supplies the Triton model name unless `triton_model_name` is set. |
|
|
188
|
+
| `triton_model_name` | `str` or `None`, `None` | Triton directory and `config.pbtxt` model name. Defaults to `name`; must start with an ASCII letter or underscore, followed by ASCII letters, digits, `_` or `-`. |
|
|
189
|
+
| `device` | `"cpu"` or `"gpu"`, `"cpu"` | Target Triton instance kind. sklearn accepts only `"cpu"`; PyTorch and Transformers accept both. Default validation uses the supplied model's current device. This does not move the model, choose a GPU index or start Triton. |
|
|
190
|
+
| `validate_saved_model` | `bool`, `False` | By default, validate predictions and tensor mappings using the supplied model without reloading weights. Set `True` to instead reload the saved artifact on CPU and validate it, requiring memory for another copy. |
|
|
191
|
+
| `signature` | MLflow `ModelSignature` or `None`, `None` | Explicit input **and output** schemas, or inference from the model and example. Explicit schemas must be compatible with the generated tensor mapping. `False` is rejected. |
|
|
192
|
+
| `registered_model_name` | `str` or `None`, `None` | Create a version under this MLflow Registry name. Omit to log without registering. |
|
|
193
|
+
| `await_registration_for` | seconds, `300` | MLflow wait timeout for registration, when registration is requested. |
|
|
194
|
+
| `run_id` | `str` or `None`, `None` | Optional MLflow run association, forwarded to `Model.log`. Without it, MLflow applies its active-run/default behavior. |
|
|
195
|
+
| `metadata` | `dict` or `None`, `None` | Model metadata, passed to native packaging and MLflow logging. |
|
|
196
|
+
| `tags` | `dict` or `None`, `None` | Tags for the MLflow logged model. |
|
|
197
|
+
| `params` | `dict` or `None`, `None` | Parameters recorded with the MLflow logged model. These do not configure inference; use Transformers `model_config` for generation settings. |
|
|
198
|
+
|
|
199
|
+
The MLflow Registry version and Triton filesystem version are independent:
|
|
200
|
+
logging always generates `<triton_model_name>/1/`, even when the Registry creates
|
|
201
|
+
version 2 or higher. There is no `triton_version` argument.
|
|
202
|
+
|
|
203
|
+
### Native packaging arguments
|
|
204
|
+
|
|
205
|
+
Remaining keyword arguments are forwarded to **`mlflow.<framework>.save_model`**,
|
|
206
|
+
not to that framework's `log_model`. Availability and defaults therefore depend on
|
|
207
|
+
the installed MLflow version. This wrapper does not accept every argument exposed
|
|
208
|
+
by native `log_model`; for example, use `name`, not `artifact_path`. Unknown or
|
|
209
|
+
incompatible options fail during native packaging.
|
|
210
|
+
|
|
211
|
+
| Argument | Applies to | Default / purpose |
|
|
212
|
+
| --- | --- | --- |
|
|
213
|
+
| `code_paths` | All three | Native default `None`. List of local inference-code files/directories to package, e.g. custom architecture modules. Include their importable package structure; do not pass training entry points. |
|
|
214
|
+
| `pip_requirements` | All three | Default `None`: use native framework defaults without model-loading dependency inference. Supply a requirements list or requirements-file path for custom dependencies and a reproducible serving environment. With `validate_saved_model=True`, native dependency inference is also enabled when no explicit environment is supplied. |
|
|
215
|
+
| `extra_pip_requirements` | All three | Native default `None`. Add requirements to native defaults/inference. |
|
|
216
|
+
| `conda_env` | All three | Native default `None`. Explicit environment dictionary or environment-file path. Follow native MLflow restrictions on combining it with pip requirement arguments. |
|
|
217
|
+
| `pyfunc_predict_fn` | sklearn | `"predict"`. Select the estimator method used by the MLflow prediction interface, e.g. `"predict_proba"` when supported by the estimator and MLflow. This also determines the output used to infer the signature. |
|
|
218
|
+
| `serialization_format` | sklearn | Native MLflow default. Choose a format supported by the installed sklearn flavor. |
|
|
219
|
+
| `serialization_format` | PyTorch | Plugin default `"pickle"`. An explicit alternative must be supported by the installed native flavor and pass saved-model validation. The plugin does not automatically export or guarantee graph compatibility. |
|
|
220
|
+
| `pickle_module` | PyTorch | Native default `None`. Optional serialization module for native PyTorch packaging. |
|
|
221
|
+
| `task` | Transformers | Native default `None`. Task identifier such as `"text-classification"` or `"text-generation"`. Supply it when native packaging cannot infer the task, especially with custom models/component dictionaries. |
|
|
222
|
+
| `processor` | Transformers | Native default `None`. Task-specific processor where required; model/tokenizer components otherwise belong in the pipeline or component dictionary. |
|
|
223
|
+
| `model_config` | Transformers | Native default `None`. Saved inference configuration, e.g. `{"max_new_tokens": 32, "do_sample": False}`. Options must be supported by the task and MLflow prediction interface. |
|
|
224
|
+
| `save_pretrained` | Transformers | Native default `True`. Must not be `False`: Triton needs the model and tokenizer assets saved locally. |
|
|
225
|
+
|
|
226
|
+
Default logging skips MLflow's automatic dependency inference because it can
|
|
227
|
+
reload the saved model in a subprocess. Framework defaults may omit custom
|
|
228
|
+
dependencies; supply them with `pip_requirements` or `extra_pip_requirements`.
|
|
229
|
+
|
|
230
|
+
Custom architecture code and third-party dependencies must be available when the
|
|
231
|
+
saved artifact is reloaded. `code_paths` bundles local code; requirement arguments
|
|
232
|
+
record installable dependencies. Neither reconstructs a missing architecture.
|
|
233
|
+
External preprocessing must already be part of the supplied prediction interface.
|
|
234
|
+
|
|
235
|
+
### Examples with explicit options
|
|
236
|
+
|
|
237
|
+
The objects below are already loaded/fitted; these calls do not train them.
|
|
238
|
+
Configure the MLflow tracking URI/experiment using MLflow's normal API before
|
|
239
|
+
logging, if required for your environment.
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from mlflow_triton import sklearn, pytorch, transformers
|
|
243
|
+
|
|
244
|
+
# sklearn: named DataFrame columns and preprocessing travel with the Pipeline.
|
|
245
|
+
sk_info = sklearn.log_model(
|
|
246
|
+
sk_model=fitted_pipeline,
|
|
247
|
+
input_example=example_dataframe.iloc[:2],
|
|
248
|
+
name="classifier",
|
|
249
|
+
device="cpu",
|
|
250
|
+
pyfunc_predict_fn="predict_proba",
|
|
251
|
+
registered_model_name="demo-classifier",
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# PyTorch: custom architecture instance, trained weights already loaded.
|
|
255
|
+
pt_info = pytorch.log_model(
|
|
256
|
+
pytorch_model=loaded_model.eval(),
|
|
257
|
+
input_example=example_numpy_array[:2],
|
|
258
|
+
name="network",
|
|
259
|
+
device="gpu",
|
|
260
|
+
code_paths=["inference_architecture"],
|
|
261
|
+
pip_requirements="requirements-serving.txt",
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Hugging Face: a pipeline includes the tokenizer; use saved generation options.
|
|
265
|
+
hf_info = transformers.log_model(
|
|
266
|
+
transformers_model=loaded_generation_pipeline,
|
|
267
|
+
input_example=["Explain what a model signature describes."],
|
|
268
|
+
name="text-generator",
|
|
269
|
+
triton_model_name="text_generator",
|
|
270
|
+
device="gpu",
|
|
271
|
+
task="text-generation",
|
|
272
|
+
model_config={"max_new_tokens": 32, "do_sample": False},
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
print(hf_info.model_uri)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Logging has already generated and saved the Triton repository. If you need a local
|
|
279
|
+
directory to inspect or hand off to deployment tooling, optionally retrieve it:
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
from mlflow_triton import triton
|
|
283
|
+
|
|
284
|
+
repository = triton.load_model(hf_info.model_uri)
|
|
285
|
+
print(repository / "config.pbtxt")
|
|
286
|
+
print(repository / "1/model.py")
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Return value and validation
|
|
290
|
+
|
|
291
|
+
All three calls return MLflow `ModelInfo`. Use `info.model_uri` to load the saved
|
|
292
|
+
model or resolve its Triton repository, and `info.registered_model_version` when
|
|
293
|
+
registration was requested. `triton.load_model(info.model_uri)` returns a local
|
|
294
|
+
`pathlib.Path` to the model-name directory, downloading artifacts as necessary.
|
|
295
|
+
This optional call only retrieves the generated repository; it does not load model
|
|
296
|
+
weights, regenerate the repository or load it into a running Triton server.
|
|
297
|
+
|
|
298
|
+
Before logging/registration, the wrapper executes the example prediction using
|
|
299
|
+
MLflow's prediction adapter around the supplied model, derives/checks the signature,
|
|
300
|
+
saves the native model and validates the input/output tensor mapping. It reuses
|
|
301
|
+
the existing weights. Unsupported schemas, invalid devices or failed predictions
|
|
302
|
+
raise an exception. A successful default return does not establish that the saved
|
|
303
|
+
artifact can be reloaded in another environment.
|
|
304
|
+
|
|
305
|
+
Use `validate_saved_model=True` to instead validate a CPU reload of the saved
|
|
306
|
+
artifact, including whether its custom code can be imported locally. The original
|
|
307
|
+
model remains in memory during this check. `validation.json` records the selected
|
|
308
|
+
mode and validation device; actual Triton serving and GPU execution must be
|
|
309
|
+
tested separately. There are no `deploy`, `validate_triton`, `max_batch_size` or
|
|
310
|
+
GPU-index arguments in these wrappers.
|
|
311
|
+
|
|
312
|
+
## Log a Triton model in MLflow
|
|
313
|
+
|
|
314
|
+
Like NVIDIA's Triton MLflow plugin, this package provides a `triton` model
|
|
315
|
+
flavor for a complete Triton model directory. The directory must contain at
|
|
316
|
+
least one numbered version; `config.pbtxt` may be included at
|
|
317
|
+
its root. The MLflow Model contains an `MLmodel` file with a `triton` flavor
|
|
318
|
+
entry and a copy of the entire directory under `model/`.
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
from mlflow_triton import triton
|
|
322
|
+
|
|
323
|
+
model_info = triton.log_model(
|
|
324
|
+
triton_model_path="/tmp/model-repository/iris_classifier",
|
|
325
|
+
name="triton-model",
|
|
326
|
+
registered_model_name="iris-serving",
|
|
327
|
+
)
|
|
328
|
+
print(model_info.registered_model_version)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`triton.load_model("models:/iris-serving/1")` downloads the registered model
|
|
332
|
+
and returns the local Triton model directory. Omit `registered_model_name` to
|
|
333
|
+
save a model without creating a Registry version. This API is in the plugin
|
|
334
|
+
package, not in MLflow's `mlflow.triton` namespace.
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
### Arguments for an existing Triton model directory
|
|
338
|
+
|
|
339
|
+
This separate API packages an **existing** Triton model directory. It does not
|
|
340
|
+
create `model.py`, infer a signature or change its configuration.
|
|
341
|
+
|
|
342
|
+
```python
|
|
343
|
+
triton.log_model(
|
|
344
|
+
triton_model_path,
|
|
345
|
+
name="triton-model",
|
|
346
|
+
registered_model_name=None,
|
|
347
|
+
await_registration_for=300,
|
|
348
|
+
run_id=None,
|
|
349
|
+
metadata=None,
|
|
350
|
+
)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
| Argument | Required / default | Meaning |
|
|
354
|
+
| --- | --- | --- |
|
|
355
|
+
| `triton_model_path` | Required | Path to one model-name directory containing at least one positive numbered version directory. Symbolic links are rejected. Pass the model directory, not the parent repository containing multiple models. |
|
|
356
|
+
| `name` | `"triton-model"` | MLflow logged-model name. The existing Triton directory name and configuration are preserved. |
|
|
357
|
+
| `registered_model_name` | `None` | Optional MLflow Registry name. |
|
|
358
|
+
| `await_registration_for` | `300` | Registration wait timeout in seconds. |
|
|
359
|
+
| `run_id` | `None` | Optional MLflow run association. |
|
|
360
|
+
| `metadata` | `None` | Optional model metadata dictionary. |
|
|
361
|
+
|
|
362
|
+
Returns MLflow `ModelInfo`. This API has no `input_example`, `signature`, `device`,
|
|
363
|
+
`tags`, `params` or arbitrary `**kwargs` parameters. Configure serving directly in
|
|
364
|
+
the supplied Triton directory before logging it.
|
|
365
|
+
|
|
366
|
+
## Examples and optional deployment
|
|
367
|
+
|
|
368
|
+
See [shared examples and validation](https://github.com/ai-lab-tech/mlflow-plugin/blob/main/examples/README.md) and the
|
|
369
|
+
[repository overview](https://github.com/ai-lab-tech/mlflow-plugin/blob/main/README.md). CPU/GPU validation is performed by the
|
|
370
|
+
example runner, not by starting a server inside log_model().
|
|
371
|
+
|
|
372
|
+
For optional Triton Control deployment, install
|
|
373
|
+
[mlflow-triton-control](https://github.com/ai-lab-tech/mlflow-plugin/blob/main/packages/mlflow-triton-control/README.md). A complete Triton
|
|
374
|
+
model repository is the handoff to any chosen deployment tooling.
|
|
375
|
+
|
|
376
|
+
## Packaging and concurrent loading
|
|
377
|
+
|
|
378
|
+
Packaging checks the target name and device before saving or predicting. It builds
|
|
379
|
+
in a temporary sibling of the destination and renames the completed directory into
|
|
380
|
+
place, cleaning up staging on failure. The native artifact and independent serving
|
|
381
|
+
copy remain separate; intermediate full-package copies are avoided. MLflow may
|
|
382
|
+
still copy/upload the completed artifact during logging. `TMPDIR` selects the outer
|
|
383
|
+
logging workspace; choose a disk with enough room for both model copies and MLflow's
|
|
384
|
+
own temporary storage.
|
|
385
|
+
|
|
386
|
+
Calls through the runtime's `load_predictor` are serialized while MLflow device and
|
|
387
|
+
offline environment settings are temporarily applied, including restoration after
|
|
388
|
+
failure. This lock does not protect unrelated code that modifies `os.environ`,
|
|
389
|
+
direct MLflow loads, or separately imported runtime copies. Coordinate those callers
|
|
390
|
+
or use separate processes. Prediction requests are not serialized by this lock.
|
|
391
|
+
|
|
392
|
+
## MLflow mapping in Triton configuration
|
|
393
|
+
|
|
394
|
+
Generated repositories store the MLflow-specific mapping as JSON in the
|
|
395
|
+
`parameters.mlflow_contract.string_value` field of `config.pbtxt`. It contains a
|
|
396
|
+
mapping version, framework flavor, input/output structure (columns, single tensor
|
|
397
|
+
or named tensors), original field names and text/binary semantics. Tensor names
|
|
398
|
+
link mapping entries to the standard `input` and `output` configuration fields;
|
|
399
|
+
datatypes and shapes are read exclusively from those fields.
|
|
400
|
+
|
|
401
|
+
Triton passes the configuration to `model.py.initialize()` as `args["model_config"]`.
|
|
402
|
+
The runtime validates and reconstructs its tensor mapping from it. Device placement
|
|
403
|
+
still comes from Triton's assigned instance kind/device ID. No separate
|
|
404
|
+
`contract.json` is generated or read by the new runtime. Unsupported mapping
|
|
405
|
+
versions, missing tensor mappings and nonzero `max_batch_size` fail initialization.
|
|
406
|
+
|
|
407
|
+
Existing logged artifacts retain their original `model.py` and `contract.json`.
|
|
408
|
+
Re-log a model to produce the new layout; do not mix old generated runtime files
|
|
409
|
+
with new configuration. Editing a mapping or tensor schema must remain compatible
|
|
410
|
+
with the saved model's prediction interface and requires renewed validation.
|
|
411
|
+
|
|
412
|
+
## Ready-to-send inference example
|
|
413
|
+
|
|
414
|
+
Each framework wrapper generates one `request.json` beside `config.pbtxt`, using
|
|
415
|
+
values from `input_example`, concrete tensor shapes and all configured output names.
|
|
416
|
+
See the [central request instructions](https://github.com/ai-lab-tech/mlflow-plugin#send-an-example-request)
|
|
417
|
+
for curl commands. No per-model shell script or instruction file is generated.
|
|
418
|
+
Logging does not send a request.
|
|
419
|
+
|
|
420
|
+
For NaN/infinity or binary byte inputs, the example instead consists of
|
|
421
|
+
`request.bin` (complete HTTP body, including its JSON prefix) and `request.headers`
|
|
422
|
+
(the HTTP content type and JSON-prefix byte length). This uses
|
|
423
|
+
[Triton's binary tensor extension](https://docs.nvidia.com/deeplearning/triton-inference-server/user-guide/docs/protocol/extension_binary_data.html)
|
|
424
|
+
without changing input values. Outputs are requested as binary in that case.
|
|
425
|
+
|
|
426
|
+
Example files contain the supplied input values, just like MLflow's stored input
|
|
427
|
+
example; use non-sensitive examples. The direct `triton.log_model()` API for
|
|
428
|
+
pre-existing repositories does not generate requests because it takes no input example.
|
|
429
|
+
|
|
430
|
+
### Architecture information without loading weights
|
|
431
|
+
|
|
432
|
+
PyTorch and Transformers wrappers automatically include `architecture.json` in the
|
|
433
|
+
MLflow artifact and its self-contained Triton `1/artifact/` copy. Read this JSON
|
|
434
|
+
without importing custom model code or loading weights. It records the model class,
|
|
435
|
+
module classes, parameter/buffer shapes and dtypes (never tensor values), and relative
|
|
436
|
+
paths to packaged Python and configuration files. Transformers reports component
|
|
437
|
+
classes such as the tokenizer; its saved `config.json` contains model configuration.
|
|
438
|
+
|
|
439
|
+
| Argument | Required | Meaning |
|
|
440
|
+
| --- | --- | --- |
|
|
441
|
+
| `architecture_init_kwargs` | No | JSON object documenting constructor arguments, supplied by the caller. Defaults to unknown; never guessed or passed to the constructor. |
|
|
442
|
+
|
|
443
|
+
```python
|
|
444
|
+
mlflow_triton.pytorch.log_model(
|
|
445
|
+
model,
|
|
446
|
+
input_example=example,
|
|
447
|
+
code_paths=["custom_network.py"],
|
|
448
|
+
architecture_init_kwargs={"input_size": 16, "hidden_size": 32},
|
|
449
|
+
)
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
The same optional argument is supported by `mlflow_triton.transformers.log_model`.
|
|
453
|
+
Include only non-sensitive architecture settings, never credentials or training data.
|
|
454
|
+
This is documentation, not an automatic reconstruction recipe: module structure
|
|
455
|
+
cannot describe arbitrary `forward()` logic or preprocessing. Constructor settings
|
|
456
|
+
are caller-declared and are not verified against the model. Required custom code
|
|
457
|
+
must still be packaged with the native flavor's code options. Existing artifacts
|
|
458
|
+
are unchanged; the report is generated on subsequent logging. Serving inputs,
|
|
459
|
+
outputs, weights and `config.pbtxt` are unaffected.
|