Skip to main content

Machine Learning for Hardware Triggers

Documentation PyPI version

triggerflow takes a trained Keras model plus a numpy preprocessing function and exports them as a single alkaid HLS kernel for FPGA deployment in the CMS Level-1 trigger:

  • one traced graph: input quantization, preprocessing and the network are all part of the exported kernel, so training and firmware evaluate the same numbers,
  • a CMSSW-ready artifact: emulator/<name>/<name>.so (hls4mlEmulator ABI) inside a self-describing TriggerModel workspace whose metadata.json records the fixed object/feature order the producer uses to assemble the model input,
  • parity tooling: software vs. firmware predictions event by event, from Python or from a CMSSW dump.

TriggerModel also supports the hls4ml (Keras) and conifer (XGBoost) compiler backends - alkaid is the one with the full e2e CMSSW deployment path. MLflow utilities are shipped for logging, versioning and loading of trigger models.

Installation

pip install triggerflow
# training extras (tensorflow, scikit-learn, matplotlib):
pip install triggerflow[train]
# compiler backends next to alkaid:
pip install triggerflow[hls4ml]   # hls4ml (Keras)
pip install triggerflow[conifer]  # conifer (XGBoost)

Usage

import numpy as np
from triggerflow.core import TriggerModel
from my_project.preprocessing import preprocess   # standard numpy ops

trigger_model = TriggerModel(
    config="triggermodel_config.yaml",   # compiler + deployment spec
    native_model=model,                  # trained Keras model
    preprocess=preprocess,               # traced into the kernel
)
trigger_model()                          # export workspace with the .so (needs make/g++)

output_software = trigger_model.software_predict(x_preprocessed)
output_firmware = trigger_model.firmware_predict(x_raw)   # raw ABI inputs

trigger_model.save("triggermodel.tar.xz")

# in a separate session:
from triggerflow.core import TriggerModel
reloaded = TriggerModel.load("triggermodel.tar.xz", overwrite=True)
output_firmware = reloaded.firmware_predict(x_raw)

The model config

compiler:
  name: "my_model"
  ml_backend: "keras"
  compiler: "alkaid"
  n_outputs: 1
  clock_period: 5.0
  # ABI quantization of the graph as [sign, integer, fraction] bits:
  # [1, 22, 0] -> ap_fixed<23,23> raw GT hardware integers
  in_kif: [1, 22, 0]
  out_kif: [1, 6, 10]
  weight_frac_bits: 10          # snap weights to a 2**-10 grid
  input_shape: [14]             # raw feature count (preprocessed width is implicit)

# Single source of truth for the fixed object/feature order - stored in the
# workspace metadata.json at export; the CMSSW producer cfi mirrors it.
deployment:
  inputs:
    - tag: [l1tGTProducer, CL2JetsSC4]
      n_objects: 4
      features: [pT, eta, phi]
      sort: "pT:desc"
    - tag: [l1tGTProducer, CL2EtSum]
      n_objects: 1
      features: [pT, phi]
  decision:
    threshold: 0.0
    pass_above: true
    trigger_types: 1

Quantization and precision are not configured behind your back: the values above become quantize() calls inside the traced graph. Preprocessing rules that keep the traced bit widths small: keep constants dyadic (or quantize right after them) and quantize before every LUT op.

Logging with MLflow

import mlflow
from triggerflow.mlflow_wrapper import log_model

mlflow.set_tracking_uri("https://ngt.cern.ch/models")   # or omit for ./mlruns
experiment_id = mlflow.create_experiment("example-experiment")

with mlflow.start_run(run_name="trial-v1", experiment_id=experiment_id):
    log_model(trigger_model, registered_model_name="TriggerModel")

log_model archives the TriggerModel, logs it as a PyFunc model and registers it in the Model Registry; see the MLflow docs for loading models back and CI integration (setup_mlflow).

Kedro starter

The package ships a cookiecutter starter with a minimal working Alkaid example (5 pipelines: load_data -> data_processing -> model_training -> model_validation -> compile, bundled test data):

triggerflow new demo_pipeline
cd demo_pipeline
conda env update -n demo_pipeline --file environment.yml --prune
conda activate demo_pipeline
kedro run

The compile pipeline writes data/06_compile/ (predictions, model_aucs.json, the triggermodel.tar.xz archive) and triggermodel/ (the workspace: .so + metadata.json). Its pipelines are tracked with MLflow (hyperparameters, metrics, and a Model Registry version of the exported TriggerModel); by default everything goes to the project-local ./mlruns store - set MLFLOW_TRACKING_URI to track on a server instead.

For a full CMSSW deployment round trip (L1 ntuples, L1GTScoreProducer, bit-exact parity) see examples/example_pipeline/.

Development

pip install -e .[dev,train]
pytest tests/test_core.py                      # fast unit tests
pytest tests                    # full suite (includes the starter e2e)
ruff check src tests

Note: this package does not install a training environment; projects declare

their own dependencies via the starter's environment.yml.

Metadata

Release files for triggerflow 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for triggerflow 0.5.0
File Size Uploaded Provenance
triggerflow-0.5.0.tar.gz 11.1 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for triggerflow 0.5.0
File Interpreter ABI Platform
triggerflow-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.1 MB

Release files / triggerflow-0.5.0.tar.gz

Download URL triggerflow-0.5.0.tar.gz
Size 11.1 MB
Tags Source
SHA-256 checksum
How to use checksums
9b41234b2dbffe325f5aa9efef2a64bfa0969e95f6ad8b7ed24799e616f0b695
BLAKE2b-256 checksum
How to use checksums
1658c14a88195d512fb60f5015d34444319395223ea3d460885421fb6d031799
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Release files / triggerflow-0.5.0-py3-none-any.whl

Download URL triggerflow-0.5.0-py3-none-any.whl
Size 11.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
616b1e8e3c38641c75dc4a1b82ccba70e06da0ea2a1b5e291229b3048084079b
BLAKE2b-256 checksum
How to use checksums
a348efda41e2499b048f0c3d2bfecb940a49917f60bfcf44b757afbf6e36c9ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Security for triggerflow 0.5.0

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page