mlflow-triton-control
MLflow deployment target for models that already exist in a Triton S3 model repository. Install this Python package in the environment running the MLflow CLI or Python API. Triton Control creates the Kubernetes deployment and resolves the selected user-owned S3 profile.
Requires Python 3.10+ and MLflow >=3.14,<4. Automatic CI tests the version
pinned in charts/triton-control/values.yaml
on triton-control/main. CI reads that version on every run, including the
weekly scheduled run. Manual runs can test an additional MLflow version.
python -m build
python -m pip install dist/mlflow_triton_control-*.whl
mlflow deployments help -t triton-control
From this directory, run the tests after installing the wheel:
python -m pip install hypothesis-jsonschema jsonschema
python -m pip check
python -m unittest discover -s tests -v
The smoke tests verify installed plugin discovery, deployment requests with a mock HTTP transport, and real model logging, registration, and retrieval with a temporary SQLite tracking database.
Smoke tests
Run from the repository root; each command uses a fresh temporary environment:
# Test a specific MLflow version
bash smoke-latest.sh 3.14.0
# Test the latest supported MLflow version
bash smoke-latest.sh
Replace 3.14.0 with the version to test. No live Kubernetes cluster is needed.
Manual CI runs accept an additional version through mlflow_version.
How MLflow finds the plugin
mlflow deployments create is a command provided by MLflow. This package
registers the deployment target through its Python package metadata:
[project.entry-points."mlflow.deployments"]
triton-control = "mlflow_triton_control.deployment_client"
For --target triton-control://triton-control:8000, MLflow looks up the
triton-control entry point among installed packages, loads this module, and
calls TritonControlDeploymentClient.create_deployment(). That class inherits
from MLflow's BaseDeploymentClient and sends the deployment request to the
Triton Control API. MLflow reads entry-point metadata; it does not search
through every package's source files. The package must be installed in the
same Python environment as the mlflow CLI.
The short hostname works when the client runs in the Service's namespace.
For another namespace, use triton-control://<service>.<namespace>.svc.cluster.local:8000,
for example triton-control://triton-control.blabla.svc.cluster.local:8000.
Use the actual Service name created by your Helm release.
Log training artifacts
Capture the training source and installed Python packages in an active MLflow run, before a Triton repository exists:
import mlflow
from mlflow_triton_control import triton
with mlflow.start_run():
artifacts = triton.log_training_artifacts(training_code_path="/workspace/source")
# Start training here.
The plugin runs pip freeze with the current Python interpreter automatically.
It logs the source directory recursively under training-artifacts/code/ and the
captured environment under training-artifacts/requirements.txt. Keep training
data outside the source directory. The source directory is not modified.
These requirements describe the installed training environment; they are not
minimized for serving.
Use artifact_path to change the default training-artifacts location. The return
value contains run-relative paths under code and requirements. No Triton
repository or Model Registry entry is created by this function. Once a repository
has been generated, use triton.log_model() to log it.
Log a Triton model in MLflow
Like NVIDIA's Triton MLflow plugin, this package provides a triton model
flavor for a complete Triton model directory. The directory must contain at
least one numbered version; config.pbtxt may be included at
its root. The MLflow Model contains an MLmodel file with a triton flavor
entry and a copy of the entire directory under model/.
from mlflow_triton_control import triton
model_info = triton.log_model(
triton_model_path="/tmp/model-repository/iris_classifier",
name="triton-model",
registered_model_name="iris-serving",
)
print(model_info.registered_model_version)
triton.load_model("models:/iris-serving/1") downloads the registered model
and returns the local Triton model directory. Omit registered_model_name to
save a model without creating a Registry version. This API is in the plugin
package, not in MLflow's mlflow.triton namespace.
triton.log_model() automatically sets the triton_model_uri version tag to
the concrete S3 repository URI when registering a model in an S3-backed artifact
store. It still returns MLflow's ModelInfo; use model_info.model_uri directly
with the deployment client. Local artifact stores remain supported for logging
and loading, but S3-backed storage is required for deployment.
The deployment client accepts models:/<model-id>, registered model references
such as models:/iris-serving/1 or models:/iris-serving@candidate, runs:/
model references, and existing s3:// repository URIs. MLflow references must
have the triton flavor. The plugin resolves their artifact location and the
flavor's model directory before calling Triton Control. Proxy artifact storage
is resolved using Triton Control's MLflow artifact-store endpoint and the current
MLflow tracking credentials.
The selected S3 profile must have read access to the MLflow artifact bucket and endpoint. This uses the repository already stored by MLflow; it does not copy it to a different bucket or profile prefix.
Argo Workflows
Submit the workflow through Triton Control's authenticated Argo proxy. Mark the deployment template with these Workflow annotations:
metadata:
name: train-iris
annotations:
triton-control.ai/mlflow-deploy-template: deploy
triton-control.ai/mlflow-deployment-name: iris-classifier
triton-control.ai/mlflow-s3-profile-name: workflow-training
The backend resolves the profile name and its linked Argo artifact repository
for the submitting user. It sets spec.artifactRepositoryRef and injects
TRITON_CONTROL_TOKEN, TRITON_CONTROL_S3_PROFILE_ID, and
TRITON_CONTROL_S3_BUCKET into the named script or container template.
Use the injected ID with -C s3_profile_id="$TRITON_CONTROL_S3_PROFILE_ID".
The token is valid for 60 minutes and limited
to the specified deployment and S3 profile. The Workflow receives a five-minute
completion TTL unless it already defines one, and the Secret receives a
Workflow owner reference for garbage collection.
The opted-in Workflow must have a fixed metadata.name and run in the Triton
Control namespace. Direct submissions to Argo bypass this token injection.
S3 deployment of logged models (0.3.1)
The Triton flavor stores data under model/<original-model-name>/ inside the
MLflow Model. Pass ModelInfo.model_uri directly to the deployment plugin;
S3-backed registered versions receive the concrete repository URI in their
triton_model_uri tag automatically. The selected S3 profile must be able to
read the artifact bucket. Existing models using data: model remain loadable.
See the Iris auto-deployment workflow for the complete example.
Publishing
Publish manually from the repository root, using a fresh output directory for each release:
python -m pip install --upgrade build twine
python -m build --outdir dist/mlflow-triton-control-0.3.1
python -m twine check dist/mlflow-triton-control-0.3.1/*
python -m twine upload dist/mlflow-triton-control-0.3.1/*
When prompted, enter __token__ as the username and a PyPI API token scoped to
mlflow-triton-control as the password.
Contract tests
CI checks out triton-control/main and exports the deployment router's OpenAPI
contract without starting the server or its lifespan. Backend dependencies are
installed in a separate environment. Plugin HTTP requests are validated against
those routes and request schemas; POST and DELETE mock responses are generated
from their current response schemas using hypothesis-jsonschema.
The GET endpoints currently declare free-form dictionaries, so OpenAPI cannot
describe their fields. For those responses the exporter calls the upstream
describe serializer with a synthetic model record and simulated Triton
readiness. The response fields and readiness values come from backend code,
not a duplicated response dictionary in this repository.
To run locally, install the backend dependencies in a separate virtual environment, then export and run (replace the backend Python and checkout paths):
DATABASE_URL=sqlite:// PYTHONPATH=../triton-control/triton-backend \
/path/to/backend-venv/bin/python tests/export_contract.py /tmp/triton-contract.json
python -m pip install hypothesis-jsonschema jsonschema
TRITON_CONTROL_CONTRACT=/tmp/triton-contract.json python -m unittest discover -s tests -v
The contract test is skipped when TRITON_CONTROL_CONTRACT is unset. CI always
sets it; missing or invalid exports fail the job. These tests exercise API shapes
and plugin behavior, not backend authentication or real deployment execution.
Metadata
Release files for mlflow-triton-control 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mlflow_triton_control-0.3.1.tar.gz | 21.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mlflow_triton_control-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.2 kB
Release files / mlflow_triton_control-0.3.1.tar.gz
| Download URL | mlflow_triton_control-0.3.1.tar.gz |
|---|---|
| Size | 21.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
943355ecb0e764f99e1d3e33bd4cd149f0d817b8f18667baff999128adb3ad70
|
|
BLAKE2b-256 checksum How to use checksums |
ceaebd84017397701f44a002e4804b39f272f1ba305945f252b5d1b7e6aade81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / mlflow_triton_control-0.3.1-py3-none-any.whl
| Download URL | mlflow_triton_control-0.3.1-py3-none-any.whl |
|---|---|
| Size | 15.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
de2e46895a1ad057eab6fd3077bbfea2704e5ea3356efb696ec725f6834b8375
|
|
BLAKE2b-256 checksum How to use checksums |
53829b7ce14446cbfd0c1fdcea208f098b7a62fe9ff4c686907de68a7038cc1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for mlflow-triton-control 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.