{"id":24763576,"url":"https://github.com/thesps/conifer","last_synced_at":"2025-04-05T13:05:50.075Z","repository":{"id":38314263,"uuid":"257309105","full_name":"thesps/conifer","owner":"thesps","description":"Fast inference of Boosted Decision Trees in FPGAs","archived":false,"fork":false,"pushed_at":"2025-03-20T15:06:46.000Z","size":62230,"stargazers_count":52,"open_issues_count":26,"forks_count":27,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-29T12:05:31.902Z","etag":null,"topics":["boosted-decision-trees","fpga","low-latency","machine-learning"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thesps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-20T14:37:01.000Z","updated_at":"2025-02-21T09:16:03.000Z","dependencies_parsed_at":"2023-02-19T10:16:05.159Z","dependency_job_id":"2c983ec3-a155-4861-a1aa-c1b4763b5a9b","html_url":"https://github.com/thesps/conifer","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesps%2Fconifer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesps%2Fconifer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesps%2Fconifer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesps%2Fconifer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thesps","download_url":"https://codeload.github.com/thesps/conifer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339155,"owners_count":20923014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boosted-decision-trees","fpga","low-latency","machine-learning"],"created_at":"2025-01-28T20:34:35.646Z","updated_at":"2025-04-05T13:05:50.033Z","avatar_url":"https://github.com/thesps.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://github.com/thesps/conifer/raw/master/conifer_v1.png\" width=\"250\" alt=\"conifer\"\u003e\n\nConifer translates trained Boosted Decision Trees to FPGA firmware for extreme low latency inference. \n\n# Installation\nConifer is on the Python Package Index, so install it like:\n```\npip install conifer\n```\n\nBuilding FPGA firmware requires tools from Xilinx - a High Level Synthesis tool and Vivado, depending on the choice of backend. We recommend the most recent version Vivado ML and Vitis HLS 2022.2.\n\nUsing the C++ backends requires JSON header files from [here](https://github.com/nlohmann/json). Clone or download the repository, and set the environment variable `JSON_ROOT` to the JSON include path. Xilinx's arbitrary precision header files (e.g. `ap_fixed.h`) are required to use these type for emulation. They are automatically found if you have source the Xilinx HLS toolchain, but you can also find them [here](https://github.com/Xilinx/HLS_arbitrary_Precision_Types). If using the C++ backend without a Vivado installation, clone or download Xilinx's repository, and set the environment variable `XILINX_HLS` to the include path.\n\n# About\nConifer converts from popular BDT training frameworks, and can emit code projects in different FPGA languages.\n\n\nAvailable converters:\n- scikit-learn\n- xgboost\n- ONNX - giving access to other training libraries such as lightGBM and CatBoost with ONNXMLTools\n- TMVA\n- Tensorflow Decision Forest (tf_df)\n\nAvailable backends:\n- Xilinx HLS - for best results use latest Vitis HLS, but Vivado HLS is also supported (conifer uses whichever is on your `$PATH`)\n- VHDL - a direct-to-VHDL implementation, deeply pipelined for high clock frequencies\n- FPU - Forest Processing Unit reusable IP core for flexible BDT inference\n- C++ - intended for bit-accurate emulation on CPU with a single include header file\n- Python - intended for validation of model conversion and to allow inspection of a model without a configuration\n\nSee our paper in JINST: \"[Fast inference of Boosted Decision Trees in FPGAs for particle physics](https://iopscience.iop.org/article/10.1088/1748-0221/15/05/P05026)\".\n\nConifer originated as a development for [hls4ml](https://fastmachinelearning.org/hls4ml/), and is developed under the [Fast Machine Learning Lab](https://fastmachinelearning.org/).\n\n# Usage\n\nView the API reference at the [conifer homepage](https://ssummers.web.cern.ch/conifer/)\n\n```\nfrom sklearn.ensemble import GradientBoostingClassifier\n# Train a BDT\nclf = GradientBoostingClassifier().fit(X_train, y_train)\n\n# Create a conifer config dictionary\ncfg = conifer.backends.xilinxhls.auto_config()\n# Change the bit precision (print the config to see everything modifiable)\ncfg['Precision'] = 'ap_fixed\u003c12,4\u003e' \n\n# Convert the sklearn model to a conifer model\nmodel = conifer.converters.convert_from_sklearn(clf, cfg)\n# Write the HLS project and compile the C++-Python bridge                      \nmodel.compile()\n\n# Run bit-accurate prediction on the CPU\ny_hls = model.decision_function(X)\ny_skl = clf.decision_function(X)\n\n# Synthesize the model for the target FPGA\nmodel.build()\n```\n\nCheck the examples directory for examples to get started with, and the BDT part of the [hls4ml tutorial](https://github.com/fastmachinelearning/hls4ml-tutorial).\n\n# Forest Processing Unit\nThe conifer Forest Processing Unit (FPU) is a flexible IP for fast BDT inference on FPGAs. One FPU can be configured to perform inference of different BDTs without rebuilding the IP or bitstream.\n\n\u003cdetails\u003e\n\n    \u003csummary\u003eMore information\u003c/summary\u003e\n\nFPUs comprise multiple Tree Engines (TEs) that operate in parallel. Each TE navigates a Decision Tree from root to leaf and outputs the leaf score. A summing network then combines the class scores to make the BDT prediction. TEs are programmed by the conifer compiler, allowing you to map different BDTs - for example with different numbers of nodes and maximum tree depth - onto the same FPU.\n\n## Downloading the FPU\nPremade binaries for select boards are available for [download here](https://ssummers.web.cern.ch/ssummers/conifer/). Navigate to the conifer version, board and configuration and download the bitfile.\n\n## Building the FPU\nIf you would like to build the FPU yourself, for example if you need a custom configuration or to target a different board, you can use the `FPUBuilder`s in `conifer.backends.fpu`. Check the `build_fpu.py` example for ideas. You can change the number of tree engines, the number of nodes per engine, as well as the bitwidth allocated to each variable. All of this configuration is carried out through a configuration dictionary.\n\n## Running the FPU\nThe conifer `fpu` backend maps your trained BDT onto a specific FPU configuration, and provides the driver to interact with the FPU - to load (and read) a BDT, and to perform inference.\n\nFor a pynq-z2 board the first step is to copy the `fpu_driver.py` and bitstream to the pynq-z2 SD card, then load it like this:\n\n```\nfrom fpu_driver import ZynqDriver\nfpu = ZynqDriver('fpu.bit')\n```\n\nThe FPU stores the configuration settings it was built with, which we can query like this:\n```\nprint(fpu.get_info())\n```\n\n```\n# model = json.load(open('prj_fpu_.../nodes.json'))\n# fpu.load(model['nodes'], model['scales'])\n# X = np.zeros(16, dtype='int32')\n# fpu.predict(X)\n```\n\n\n\u003c/details\u003e\n\n# Development\n1. Clone the github repository: `git clone https://github.com/thesps/conifer`\n1. Install the dependencies listed in the *Installation* section. For instance:\n    - Clone nlohmann json: `git clone https://github.com/nlohmann/json`\n    - Clone Arbitrary Precision: `git clone https://github.com/Xilinx/HLS_arbitrary_Precision_Types`\n    - Set the env variables `JSON_ROOT` and `XILINX_AP_INCLUDE` as the `include` directory in them respectively e.g.\n    ```shell\n    export XILINX_AP_INCLUDE=$(pwd)/HLS_arbitrary_Precision_Types/include\n    export JSON_ROOT=$(pwd)/json/include\n    ```\n1. Go into the Conifer project directory: `cd conifer`\n1. Install the python development dependencies: `pip install -r dev_requirements.txt`\n1. Run an example: `export PYTHONPATH=\"$(pwd):${PYTHONPATH}\" \u0026\u0026 python examples/sklearn_to_cpp.py`\n1. Run a single unit test: `pytest tests/test_multiclass.py`\n1. Run all the unit tests: `pytest`\n\n# Use Cases\n\nThe following are some applications using `conifer` either in production or R\u0026D. If you think your own use case should be featured here, please get in touch.\n\n## ATLAS Calorimeter Tau Trigger\n\nThe ATLAS experiment at CERN's Large Hadron Collider is currently using `conifer` to better reconstruct events with tau leptons. See [this talk](https://indico.cern.ch/event/1283970/contributions/5554387/) at the Fast Machine Learning 2023 workshop.\n\n- Domain: particle physics\n- Frontend: `xgboost`\n- Backend: `Vitis HLS`\n- Target Device: AMD Virtex 7 FPGA\n\n## Tracking detector frontend data reduction\n\nJ. Gonski _et al_, Embedded FPGA Developments in 130nm and 28nm CMOS for Machine Learning in Particle Detector Readout, 2024, [arXiv:2404.17701v1](https://arxiv.org/pdf/2404.17701)\n\nA team from Stanford and SLAC have shown that a tiny Decision Tree model running in an eFPGA at the periphery of a particle tracking detector frontend ASIC can be used to filter data from pile-up events.\n\n- Domain: particle physics\n- Frontend: `scikit-learn`\n- Backend: `HLS`\n- Target Device: eFPGA from [FABulous](https://doi.org/10.1145/3431920.3439302)\n\n## Enhancing blood vessel segmentation\n\nAlsharari M _et al_. Efficient Implementation of AI Algorithms on an FPGA-based System for Enhancing Blood Vessel Segmentation.  [doi:10.21203/rs.3.rs-4351485/v1](https://doi.org/10.21203/rs.3.rs-4351485/v1).\n\nThe authors demonstrate methods to perform performing image segmentation to identify blood vessels in a proposed surgical imaging device. A GBDT, deployed to a Kria SoM with `conifer`, achieved the best FPS with segmentation performance competitive with U-Net models.\n\n- Domain: medical devices\n- Frontend: `ONNX` (`catboost`)\n- Backend: `Vitis HLS`\n- Target Device: AMD Kria KV260\n\n\n# License\nApart from the source code and binaries of the Forest Processing Unit (FPU), `conifer` is licensed under *Apache v2*. The FPU source code and binaries are licensed under the [*CERN-OHL-P v2*](https://cern.ch/cern-ohl) or later.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthesps%2Fconifer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthesps%2Fconifer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthesps%2Fconifer/lists"}