rapidfireai 0.0.1__py3-none-any.whl → 0.9.9__py3-none-any.whl
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.
Potentially problematic release.
This version of rapidfireai might be problematic. Click here for more details.
- rapidfireai/__init__.py +11 -5
- rapidfireai/automl/__init__.py +20 -0
- rapidfireai/automl/base.py +48 -0
- rapidfireai/automl/datatypes.py +42 -0
- rapidfireai/automl/grid_search.py +125 -0
- rapidfireai/automl/model_config.py +102 -0
- rapidfireai/automl/random_search.py +145 -0
- rapidfireai/backend/__init__.py +0 -0
- rapidfireai/backend/chunks.py +63 -0
- rapidfireai/backend/controller.py +637 -0
- rapidfireai/backend/scheduler.py +137 -0
- rapidfireai/backend/worker.py +272 -0
- rapidfireai/cli.py +380 -0
- rapidfireai/db/__init__.py +0 -0
- rapidfireai/db/db_interface.py +135 -0
- rapidfireai/db/rf_db.py +694 -0
- rapidfireai/db/tables.sql +64 -0
- rapidfireai/dispatcher/dispatcher.py +391 -0
- rapidfireai/dispatcher/gunicorn.conf.py +25 -0
- rapidfireai/experiment.py +168 -0
- rapidfireai/frontend/build/asset-manifest.json +276 -0
- rapidfireai/frontend/build/favicon.ico +0 -0
- rapidfireai/frontend/build/index.html +1 -0
- rapidfireai/frontend/build/manifest.json +15 -0
- rapidfireai/frontend/build/pdf.worker.js +1 -0
- rapidfireai/frontend/build/report.html +39 -0
- rapidfireai/frontend/build/static/css/1482.3b7bf531.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/2730.3f8937ff.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/318.0def90a7.css +7 -0
- rapidfireai/frontend/build/static/css/4762.9b7b71f7.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/4950.487ecc8b.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/5170.2574ce9d.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/6121.4d541986.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/6343.dd6979f2.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/6534.433c213f.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/6920.ffac4b2a.css +2 -0
- rapidfireai/frontend/build/static/css/7246.bf2f0c87.css +9 -0
- rapidfireai/frontend/build/static/css/7367.dd6979f2.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/8690.05d081e5.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/9531.d0910d3c.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/9780.363e4943.chunk.css +1 -0
- rapidfireai/frontend/build/static/css/main~d91a9049.c0be472c.css +1 -0
- rapidfireai/frontend/build/static/js/1000.e5ed264b.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1012.ac98ab59.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1079.6c13ac0d.js +1 -0
- rapidfireai/frontend/build/static/js/110.9059f3b8.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1142.872d0010.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1167.9a6da14c.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1248.60890b4f.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1262.83dc7673.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1273.56da3e13.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/1273.56da3e13.chunk.js.LICENSE.txt +9 -0
- rapidfireai/frontend/build/static/js/1303.7d19305c.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1351.45076ff3.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1355.b896a592.js +1 -0
- rapidfireai/frontend/build/static/js/1357.02c46a02.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1470.c51d60c6.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1482.23b74f50.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1500.19799d8d.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1648.d3b9edc7.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1860.7d96e3f9.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1909.5b1d9ff4.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/1928.44245110.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/1928.44245110.chunk.js.LICENSE.txt +11 -0
- rapidfireai/frontend/build/static/js/1933.deba26ca.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/21.aac92802.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2103.0ca12071.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2258.b3b8fab4.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2289.9ad51e87.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2323.7dd927d7.js +2 -0
- rapidfireai/frontend/build/static/js/2323.7dd927d7.js.LICENSE.txt +1 -0
- rapidfireai/frontend/build/static/js/2346.ed99ca72.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2386.0a660834.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2402.465048f9.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/243.5a83bbca.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2589.68571e16.js +1 -0
- rapidfireai/frontend/build/static/js/2647.65092bab.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2691.65d4a4e7.js +1 -0
- rapidfireai/frontend/build/static/js/2730.b38dd6f3.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2746.ef752da4.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2779.580d4491.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2799.fe5993b2.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2844.9708db79.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/2844.9708db79.chunk.js.LICENSE.txt +21 -0
- rapidfireai/frontend/build/static/js/2901.ee0c606b.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2932.7cc0689b.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/2932.7cc0689b.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/2956.a393c8cc.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2972.679bed05.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/2985.7e51cdfa.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/2985.7e51cdfa.chunk.js.LICENSE.txt +51 -0
- rapidfireai/frontend/build/static/js/3093.488df653.js +1 -0
- rapidfireai/frontend/build/static/js/3145.66ee61b9.js +1 -0
- rapidfireai/frontend/build/static/js/3170.a22f966a.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/3170.a22f966a.chunk.js.LICENSE.txt +21 -0
- rapidfireai/frontend/build/static/js/3307.f6fb258c.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3325.d5b03d65.js +1 -0
- rapidfireai/frontend/build/static/js/3334.2d6704df.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/3334.2d6704df.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/3387.bb8edad3.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3448.438e6579.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3460.735eea87.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3505.7fd3921a.js +2 -0
- rapidfireai/frontend/build/static/js/3505.7fd3921a.js.LICENSE.txt +9 -0
- rapidfireai/frontend/build/static/js/3510.cd167a00.js +2 -0
- rapidfireai/frontend/build/static/js/3510.cd167a00.js.LICENSE.txt +18 -0
- rapidfireai/frontend/build/static/js/3563.cc828e19.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/359.08960b84.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/359.08960b84.chunk.js.LICENSE.txt +4 -0
- rapidfireai/frontend/build/static/js/3608.403b4b79.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3652.cb8add7f.js +1 -0
- rapidfireai/frontend/build/static/js/3775.5230b157.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3817.53555d18.js +2 -0
- rapidfireai/frontend/build/static/js/3817.53555d18.js.LICENSE.txt +18 -0
- rapidfireai/frontend/build/static/js/3835.d9946ff9.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3964.874f0297.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3968.275cbc3d.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/3999.765cbd82.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4020.4452c046.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4138.2f6f6d9f.js +1 -0
- rapidfireai/frontend/build/static/js/4160.f424554c.js +1 -0
- rapidfireai/frontend/build/static/js/4180.50cea095.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4221.b0bba3f5.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4250.5bb49278.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4297.15777d8f.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4349.c965f2de.js +2 -0
- rapidfireai/frontend/build/static/js/4349.c965f2de.js.LICENSE.txt +1 -0
- rapidfireai/frontend/build/static/js/4484.4cbe5e7f.js +2 -0
- rapidfireai/frontend/build/static/js/4484.4cbe5e7f.js.LICENSE.txt +10 -0
- rapidfireai/frontend/build/static/js/4578.a8124588.js +1 -0
- rapidfireai/frontend/build/static/js/4596.89a97480.js +1 -0
- rapidfireai/frontend/build/static/js/4748.566f435a.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4762.928e8a90.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4768.7945be63.js +2 -0
- rapidfireai/frontend/build/static/js/4768.7945be63.js.LICENSE.txt +1 -0
- rapidfireai/frontend/build/static/js/4804.26b50dd4.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4850.62390a45.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4862.a0ccb221.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/491.5dc8ed40.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/492.9262f038.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/492.9262f038.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/4943.6d345fd3.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/4950.bc182e62.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5042.d4f0c65a.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/5042.d4f0c65a.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/5170.0065e96f.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5222.35c74a52.js +2 -0
- rapidfireai/frontend/build/static/js/5222.35c74a52.js.LICENSE.txt +10 -0
- rapidfireai/frontend/build/static/js/5223.3224f019.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/5223.3224f019.chunk.js.LICENSE.txt +3 -0
- rapidfireai/frontend/build/static/js/5229.7dd42316.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5286.4c1ad26b.js +1 -0
- rapidfireai/frontend/build/static/js/5486.21cff711.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5526.7b368956.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5605.1ee4d87b.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5682.40b42d8b.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5794.9433d867.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5826.38a56e8c.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/5826.38a56e8c.chunk.js.LICENSE.txt +1 -0
- rapidfireai/frontend/build/static/js/5862.50f42a0b.js +1 -0
- rapidfireai/frontend/build/static/js/5895.e26742f1.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/5919.edd4a5cf.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/598.a0e792ae.js +1 -0
- rapidfireai/frontend/build/static/js/6058.74162bf9.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/618.06051134.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/618.06051134.chunk.js.LICENSE.txt +21 -0
- rapidfireai/frontend/build/static/js/6335.9fca442d.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6336.e05e1154.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6343.2bcd28ff.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6363.a319b8f2.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6478.344abf25.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6504.1c004564.js +1 -0
- rapidfireai/frontend/build/static/js/6534.ec7e149b.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6715.55a5c19c.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6756.e6cb993c.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/6756.e6cb993c.chunk.js.LICENSE.txt +10 -0
- rapidfireai/frontend/build/static/js/6762.acfde9fd.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/6762.acfde9fd.chunk.js.LICENSE.txt +19 -0
- rapidfireai/frontend/build/static/js/6846.67103d0e.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6861.34cf0198.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/6899.0eaf36a8.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/6899.0eaf36a8.chunk.js.LICENSE.txt +5 -0
- rapidfireai/frontend/build/static/js/6933.8b564944.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/699.d0437920.js +1 -0
- rapidfireai/frontend/build/static/js/7076.4182f63a.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7186.42ad86d5.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7248.a46635fd.js +1 -0
- rapidfireai/frontend/build/static/js/725.6b15a14a.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7266.3575539d.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7270.0a1e84fc.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/7270.0a1e84fc.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/7367.7120474f.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7436.8e226055.js +1 -0
- rapidfireai/frontend/build/static/js/7504.ef223844.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7603.ee049fe3.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7670.2835b49a.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/7670.2835b49a.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/7721.7390b3cc.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7731.5796cced.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/775.660a5deb.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/775.660a5deb.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/7832.7976a3e4.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7844.72cc2e81.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/7948.48eab032.js +1 -0
- rapidfireai/frontend/build/static/js/7972.085079d4.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/7972.085079d4.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/8017.a9e7dc5a.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8023.75f1f3df.js +2 -0
- rapidfireai/frontend/build/static/js/8023.75f1f3df.js.LICENSE.txt +41 -0
- rapidfireai/frontend/build/static/js/8123.b69db974.js +1 -0
- rapidfireai/frontend/build/static/js/813.065a87e5.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/819.2056f122.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/819.2056f122.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/8262.04bc17d1.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8300.75adcc4f.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8336.b1d3e764.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8365.26cf64ea.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8398.8bca8e0e.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/8398.8bca8e0e.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/847.33ceed50.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/847.33ceed50.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/8486.8ec852a7.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8497.19378265.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8541.4c55c9f4.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8690.e305a804.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/8690.e305a804.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/8712.a9445fe6.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8763.61761e08.js +1 -0
- rapidfireai/frontend/build/static/js/8823.baf9bffd.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/8823.baf9bffd.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/8867.767462b7.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8953.c0f88dea.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/8960.357cb1eb.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/8960.357cb1eb.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/9.f4492795.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/9.f4492795.chunk.js.LICENSE.txt +12 -0
- rapidfireai/frontend/build/static/js/9079.88a8d2a3.js +1 -0
- rapidfireai/frontend/build/static/js/9082.37c40520.chunk.js +10 -0
- rapidfireai/frontend/build/static/js/9133.90ae330d.js +2 -0
- rapidfireai/frontend/build/static/js/9133.90ae330d.js.LICENSE.txt +8 -0
- rapidfireai/frontend/build/static/js/9151.1ac359d5.js +2 -0
- rapidfireai/frontend/build/static/js/9151.1ac359d5.js.LICENSE.txt +8 -0
- rapidfireai/frontend/build/static/js/9168.027bf2fd.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/9194.9c5cc548.chunk.js +10 -0
- rapidfireai/frontend/build/static/js/9244.026f4aee.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/936.2e02d037.js +2 -0
- rapidfireai/frontend/build/static/js/936.2e02d037.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/9369.7d1a0a1d.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/9427.7c8442e7.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/944.55948859.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/9499.c53a82da.js +2 -0
- rapidfireai/frontend/build/static/js/9499.c53a82da.js.LICENSE.txt +62 -0
- rapidfireai/frontend/build/static/js/9531.3ce05781.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/9547.92fac952.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/9547.92fac952.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/9620.b6e973a7.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/9645.6fddfa65.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/9669.d38dda6d.js +1 -0
- rapidfireai/frontend/build/static/js/9682.41b6b807.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/9720.19d5ae76.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/9720.19d5ae76.chunk.js.LICENSE.txt +23 -0
- rapidfireai/frontend/build/static/js/9723.d3c7fe9e.js +1 -0
- rapidfireai/frontend/build/static/js/9780.02a27630.chunk.js +10 -0
- rapidfireai/frontend/build/static/js/9808.d0ca9674.chunk.js +2 -0
- rapidfireai/frontend/build/static/js/9808.d0ca9674.chunk.js.LICENSE.txt +6 -0
- rapidfireai/frontend/build/static/js/9815.b8db3c5d.js +1 -0
- rapidfireai/frontend/build/static/js/9886.2940b53a.chunk.js +1 -0
- rapidfireai/frontend/build/static/js/main~1f912138.fa9d03b1.js +1 -0
- rapidfireai/frontend/build/static/js/main~43dd7041.2e00860d.js +1 -0
- rapidfireai/frontend/build/static/js/main~84781932.68deffff.js +1 -0
- rapidfireai/frontend/build/static/media/404-overflow.fad9a31861b0afba6f921ebb8e769688.svg +32 -0
- rapidfireai/frontend/build/static/media/RapidFire_Square_Bug.27ceb48296314a4bc0d4.png +0 -0
- rapidfireai/frontend/build/static/media/chart-bar.0fd4a63680fba840a7b69fbf07969f79.svg +7 -0
- rapidfireai/frontend/build/static/media/chart-contour.0d4b306f2669f3ad25375568935e3ce3.svg +5 -0
- rapidfireai/frontend/build/static/media/chart-difference.16174216d6f3b7c24f40e3541fe0ca2c.svg +20 -0
- rapidfireai/frontend/build/static/media/chart-image.cc434c4dc50780966344e2385a15f8fe.svg +6 -0
- rapidfireai/frontend/build/static/media/chart-line.0adaa2036bb4eb5956db6d0c7e925a3d.svg +4 -0
- rapidfireai/frontend/build/static/media/chart-parallel.da7dedf539b2af4b654d377c679173e4.svg +7 -0
- rapidfireai/frontend/build/static/media/chart-scatter.69118d0023a6ff3973f7fa913834ac47.svg +9 -0
- rapidfireai/frontend/build/static/media/default-error.f246ddf367c6fbd67942e5a13382a7f1.svg +26 -0
- rapidfireai/frontend/build/static/media/fontawesome-webfont.1e59d2330b4c6deb84b3.ttf +0 -0
- rapidfireai/frontend/build/static/media/fontawesome-webfont.20fd1704ea223900efa9.woff2 +0 -0
- rapidfireai/frontend/build/static/media/fontawesome-webfont.8b43027f47b20503057d.eot +0 -0
- rapidfireai/frontend/build/static/media/fontawesome-webfont.c1e38fd9e0e74ba58f7a.svg +2671 -0
- rapidfireai/frontend/build/static/media/fontawesome-webfont.f691f37e57f04c152e23.woff +0 -0
- rapidfireai/frontend/build/static/media/icon-visible-fill.8d34cd35303828fdfc15154f5536e63b.svg +7 -0
- rapidfireai/frontend/build/static/media/no-experiments.0e4f4a114ef73e7d81c09474aba64b6c.svg +22 -0
- rapidfireai/frontend/build/static/media/parallel-chart-placeholder.234ef0c5b220ef2a5a6fa5bafff173f7.svg +16 -0
- rapidfireai/frontend/build/static/media/permission-denied-lock.16036747d57cd663d7df223781a447b2.svg +14 -0
- rapidfireai/frontend/build/static/media/promo-modal-content.e3b2c6c568ac192b9bec54b838b54850.svg +30 -0
- rapidfireai/frontend/build/static/media/registered-model-grey-ok.8274b58d39504c8d1b8c358aa1c9aa35.svg +23 -0
- rapidfireai/frontend/build/static/media/warning.290a3b14118933547965e91ea61c5a61.svg +3 -0
- rapidfireai/frontend/proxy_middleware.py +233 -0
- rapidfireai/frontend/server.py +25 -0
- rapidfireai/ml/__init__.py +0 -0
- rapidfireai/ml/callbacks.py +176 -0
- rapidfireai/ml/checkpoint_utils.py +540 -0
- rapidfireai/ml/trainer.py +309 -0
- rapidfireai/start.sh +634 -0
- rapidfireai/utils/__init__.py +0 -0
- rapidfireai/utils/automl_utils.py +51 -0
- rapidfireai/utils/constants.py +141 -0
- rapidfireai/utils/datapaths.py +69 -0
- rapidfireai/utils/exceptions.py +82 -0
- rapidfireai/utils/experiment_utils.py +370 -0
- rapidfireai/utils/logging.py +87 -0
- rapidfireai/utils/mlflow_manager.py +121 -0
- rapidfireai/utils/serialize.py +15 -0
- rapidfireai/utils/shm_manager.py +469 -0
- rapidfireai/utils/trainer_config.py +23 -0
- rapidfireai/utils/worker_manager.py +219 -0
- rapidfireai/version.py +6 -0
- rapidfireai-0.9.9.dist-info/METADATA +242 -0
- rapidfireai-0.9.9.dist-info/RECORD +318 -0
- rapidfireai-0.9.9.dist-info/entry_points.txt +2 -0
- rapidfireai-0.0.1.dist-info/METADATA +0 -37
- rapidfireai-0.0.1.dist-info/RECORD +0 -6
- {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.9.dist-info}/WHEEL +0 -0
- {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.9.dist-info}/licenses/LICENSE +0 -0
- {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
MLFLOW_URL = "http://127.0.0.1:5002"
|
|
4
|
+
|
|
5
|
+
# Shared Memory Constants
|
|
6
|
+
SHM_WARN_THRESHOLD = 80
|
|
7
|
+
SHM_MIN_FREE_SPACE = 1.0
|
|
8
|
+
|
|
9
|
+
# Logging Constants
|
|
10
|
+
LOG_FILENAME = "rapidfire.log"
|
|
11
|
+
TRAINING_LOG_FILENAME = "training.log"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class LogType(Enum):
|
|
15
|
+
"""Enum class for log types"""
|
|
16
|
+
|
|
17
|
+
RF_LOG = "rf_log"
|
|
18
|
+
TRAINING_LOG = "training_log"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Dispatcher Constants
|
|
22
|
+
class DispatcherConfig:
|
|
23
|
+
"""Class to manage the dispatcher configuration"""
|
|
24
|
+
|
|
25
|
+
HOST: str = "127.0.0.1"
|
|
26
|
+
PORT: int = 8080
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Database Constants
|
|
30
|
+
class DBConfig:
|
|
31
|
+
"""Class to manage the database configuration for SQLite"""
|
|
32
|
+
|
|
33
|
+
# Use user's home directory for database path
|
|
34
|
+
import os
|
|
35
|
+
|
|
36
|
+
DB_PATH: str = os.path.expanduser("~/db/rapidfire.db")
|
|
37
|
+
|
|
38
|
+
# Connection settings
|
|
39
|
+
CONNECTION_TIMEOUT: float = 30.0
|
|
40
|
+
|
|
41
|
+
# Performance optimizations
|
|
42
|
+
CACHE_SIZE: int = 10000
|
|
43
|
+
MMAP_SIZE: int = 268435456 # 256MB
|
|
44
|
+
PAGE_SIZE: int = 4096
|
|
45
|
+
BUSY_TIMEOUT: int = 30000
|
|
46
|
+
|
|
47
|
+
# Retry settings
|
|
48
|
+
DEFAULT_MAX_RETRIES: int = 3
|
|
49
|
+
DEFAULT_BASE_DELAY: float = 0.1
|
|
50
|
+
DEFAULT_MAX_DELAY: float = 1.0
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Experiment Constants
|
|
54
|
+
class ExperimentTask(Enum):
|
|
55
|
+
"""Enum class for experiment tasks"""
|
|
56
|
+
|
|
57
|
+
IDLE = "Idle"
|
|
58
|
+
CREATE_MODELS = "Create Models"
|
|
59
|
+
IC_OPS = "Interactive Control Operations"
|
|
60
|
+
RUN_FIT = "Training and Validation"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ExperimentStatus(Enum):
|
|
64
|
+
"""Enum class for experiment status"""
|
|
65
|
+
|
|
66
|
+
RUNNING = "Running"
|
|
67
|
+
COMPLETED = "Completed"
|
|
68
|
+
FAILED = "Failed"
|
|
69
|
+
CANCELLED = "Cancelled"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Task Constants
|
|
73
|
+
class TaskStatus(Enum):
|
|
74
|
+
"""Enum class for task status"""
|
|
75
|
+
|
|
76
|
+
SCHEDULED = "Scheduled"
|
|
77
|
+
IN_PROGRESS = "In Progress"
|
|
78
|
+
COMPLETED = "Completed"
|
|
79
|
+
SKIPPED = "Skipped"
|
|
80
|
+
FAILED = "Failed"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class ControllerTask(Enum):
|
|
84
|
+
"""Enum class for ML controller tasks"""
|
|
85
|
+
|
|
86
|
+
RUN_FIT = "Run Fit"
|
|
87
|
+
CREATE_MODELS = "Create Models"
|
|
88
|
+
IC_DELETE = "Interactive Control Delete"
|
|
89
|
+
IC_STOP = "Interactive Control Stop"
|
|
90
|
+
IC_RESUME = "Interactive Control Resume"
|
|
91
|
+
IC_CLONE_MODIFY = "Interactive Control Clone Modify"
|
|
92
|
+
IC_CLONE_MODIFY_WARM = "Interactive Control Clone Modify with Warm-Start"
|
|
93
|
+
EPOCH_BOUNDARY = "Epoch Boundary Task"
|
|
94
|
+
GET_RUN_METRICS = "Get Run Metrics"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class WorkerTask(Enum):
|
|
98
|
+
"""Enum class for ML worker tasks"""
|
|
99
|
+
|
|
100
|
+
CREATE_MODELS = "Create Models"
|
|
101
|
+
TRAIN_VAL = "Train Validation"
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# Run Constants
|
|
105
|
+
class RunStatus(Enum):
|
|
106
|
+
"""Enum class for run status"""
|
|
107
|
+
|
|
108
|
+
NEW = "New"
|
|
109
|
+
ONGOING = "Ongoing"
|
|
110
|
+
STOPPED = "Stopped"
|
|
111
|
+
DELETED = "Deleted"
|
|
112
|
+
COMPLETED = "Completed"
|
|
113
|
+
FAILED = "Failed"
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class RunSource(Enum):
|
|
117
|
+
"""Enum class for how a run was created"""
|
|
118
|
+
|
|
119
|
+
SHA = "Successive Halving Algorithm"
|
|
120
|
+
INITIAL = "Initial"
|
|
121
|
+
INTERACTIVE_CONTROL = "Interactive Control"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class RunEndedBy(Enum):
|
|
125
|
+
"""Enum class for how a run was ended"""
|
|
126
|
+
|
|
127
|
+
SHA = "Successive Halving Algorithm"
|
|
128
|
+
EPOCH_COMPLETED = "Epoch Completed"
|
|
129
|
+
INTERACTIVE_CONTROL = "Interactive Control"
|
|
130
|
+
TOLERENCE = "Tolerence Threshold Met"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# SHM Model Type Constants
|
|
134
|
+
class SHMObjectType(Enum):
|
|
135
|
+
"""Enum class for model types in shared memory"""
|
|
136
|
+
|
|
137
|
+
BASE_MODEL = "base_model"
|
|
138
|
+
FULL_MODEL = "full_model"
|
|
139
|
+
REF_FULL_MODEL = "ref_full_model"
|
|
140
|
+
REF_STATE_DICT = "ref_state_dict"
|
|
141
|
+
CHECKPOINTS = "checkpoints"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the DatasetLocators class which encapsulates the filepaths for the datasets.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from rapidfireai.utils.exceptions import DataPathException
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DataPath:
|
|
11
|
+
"""Class to set the data paths for ML"""
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def initialize(cls, experiment_name: str, experiments_path: str) -> None:
|
|
15
|
+
"""Create directories for the ML paths"""
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
# set standard paths
|
|
19
|
+
cls.experiments_path: Path = Path(experiments_path) / f"{experiment_name}"
|
|
20
|
+
cls.user_code_path: Path = cls.experiments_path / "code"
|
|
21
|
+
cls.mlflow_path: Path = cls.experiments_path / "mlflow"
|
|
22
|
+
|
|
23
|
+
# create directories
|
|
24
|
+
Path.mkdir(cls.experiments_path, parents=True, exist_ok=True)
|
|
25
|
+
Path.mkdir(cls.user_code_path, parents=True, exist_ok=True)
|
|
26
|
+
Path.mkdir(cls.mlflow_path, parents=True, exist_ok=True)
|
|
27
|
+
except (PermissionError, OSError) as e:
|
|
28
|
+
raise DataPathException(f"Failed to create required DataPaths directories: {e}") from e
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def base_run_path(cls, run_id: str | int) -> Path:
|
|
32
|
+
"""Return the work directory path"""
|
|
33
|
+
return cls.experiments_path / "runs" / f"{run_id}"
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def dataset_path(cls) -> Path:
|
|
37
|
+
"""Return the dataset path"""
|
|
38
|
+
return cls.experiments_path / "datasets.dill"
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def work_dir_path(cls, base_run_path: Path) -> Path:
|
|
42
|
+
"""Return the work directory path"""
|
|
43
|
+
return base_run_path / "work_dir"
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def initial_checkpoint_path(cls, base_run_path: Path) -> Path:
|
|
47
|
+
"""Return the initial checkpoint path"""
|
|
48
|
+
return base_run_path / "checkpoints" / "initial_checkpoint"
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def final_checkpoint_path(cls, base_run_path: Path) -> Path:
|
|
52
|
+
"""Return the final checkpoint path"""
|
|
53
|
+
return base_run_path / "checkpoints" / "final_checkpoint"
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def intermediate_checkpoint_path(cls, base_run_path: Path) -> Path:
|
|
57
|
+
"""Return the intermediate checkpoint path"""
|
|
58
|
+
return base_run_path / "checkpoints" / "intermediate_checkpoints"
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def val_metrics_path(cls, base_run_path: Path) -> Path:
|
|
62
|
+
"""Return the validation metrics path"""
|
|
63
|
+
return cls.work_dir_path(base_run_path) / "val_metrics.csv"
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def ref_model_path(cls, base_run_path: Path) -> Path:
|
|
67
|
+
"""Return the reference model path for DPO training"""
|
|
68
|
+
return base_run_path / "ref_model"
|
|
69
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains custom exceptions for RapidFire.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ExperimentException(Exception):
|
|
7
|
+
"""Custom exception for experiment creation"""
|
|
8
|
+
|
|
9
|
+
def __init__(self, message: str):
|
|
10
|
+
super().__init__(message)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DispatcherException(Exception):
|
|
14
|
+
"""Custom exception for dispatcher"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, message: str):
|
|
17
|
+
self.message = message
|
|
18
|
+
super().__init__(self.message)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DBException(Exception):
|
|
22
|
+
"""Custom exception for database operations"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, message: str):
|
|
25
|
+
self.message = message
|
|
26
|
+
super().__init__(self.message)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DataPathException(Exception):
|
|
30
|
+
"""Custom exception for data path operations"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, message: str):
|
|
33
|
+
self.message = message
|
|
34
|
+
super().__init__(self.message)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class NoGPUsFoundException(Exception):
|
|
38
|
+
"""Custom exception for no GPUs found"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, message: str):
|
|
41
|
+
self.message = message
|
|
42
|
+
super().__init__(self.message)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class InitializeRunException(Exception):
|
|
46
|
+
"""Custom exception for initialize run"""
|
|
47
|
+
|
|
48
|
+
def __init__(self, message: str):
|
|
49
|
+
self.message = message
|
|
50
|
+
super().__init__(self.message)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ControllerException(Exception):
|
|
54
|
+
"""Custom exception for controller"""
|
|
55
|
+
|
|
56
|
+
def __init__(self, message: str):
|
|
57
|
+
self.message = message
|
|
58
|
+
super().__init__(self.message)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class WorkerException(Exception):
|
|
62
|
+
"""Custom exception for worker"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, message: str, traceback: str = None):
|
|
65
|
+
self.message = message
|
|
66
|
+
super().__init__(self.message)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class AutoMLException(Exception):
|
|
70
|
+
"""Custom exception for AutoML"""
|
|
71
|
+
|
|
72
|
+
def __init__(self, message: str):
|
|
73
|
+
self.message = message
|
|
74
|
+
super().__init__(self.message)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class InsufficientSharedMemoryException(Exception):
|
|
78
|
+
"""Custom exception for insufficient shared memory"""
|
|
79
|
+
|
|
80
|
+
def __init__(self, message: str):
|
|
81
|
+
self.message = message
|
|
82
|
+
super().__init__(self.message)
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"""This module contains utility functions for the experiment."""
|
|
2
|
+
|
|
3
|
+
import multiprocessing as mp
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import signal
|
|
7
|
+
import sys
|
|
8
|
+
import warnings
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import mlflow
|
|
12
|
+
import pandas as pd
|
|
13
|
+
import torch
|
|
14
|
+
from IPython.display import display
|
|
15
|
+
from tqdm import tqdm
|
|
16
|
+
from transformers import logging as transformers_logging
|
|
17
|
+
|
|
18
|
+
from rapidfireai.db.rf_db import RfDb
|
|
19
|
+
from rapidfireai.utils.constants import MLFLOW_URL, ExperimentStatus, ExperimentTask
|
|
20
|
+
from rapidfireai.utils.datapaths import DataPath
|
|
21
|
+
from rapidfireai.utils.exceptions import DBException, ExperimentException
|
|
22
|
+
from rapidfireai.utils.logging import RFLogger
|
|
23
|
+
from rapidfireai.utils.mlflow_manager import MLflowManager
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ExperimentUtils:
|
|
27
|
+
"""Class to contain utility functions for the experiment."""
|
|
28
|
+
|
|
29
|
+
def __init__(self) -> None:
|
|
30
|
+
# initialize database handler
|
|
31
|
+
self.db = RfDb()
|
|
32
|
+
|
|
33
|
+
def _disable_ml_warnings_display(self) -> None:
|
|
34
|
+
"""Disable notebook display"""
|
|
35
|
+
tqdm.disable = True
|
|
36
|
+
|
|
37
|
+
# Suppress the transformers logging
|
|
38
|
+
os.environ["TRANSFORMERS_VERBOSITY"] = "error"
|
|
39
|
+
transformers_logging.set_verbosity_error()
|
|
40
|
+
|
|
41
|
+
# Suppress the torch warnings
|
|
42
|
+
torch.set_warn_always(False)
|
|
43
|
+
|
|
44
|
+
# Suppress the FutureWarning
|
|
45
|
+
warnings.filterwarnings("ignore", message=".*torch.cuda.amp.autocast.*")
|
|
46
|
+
warnings.filterwarnings("ignore", message=".*generation flags are not valid.*")
|
|
47
|
+
warnings.filterwarnings("ignore", message=".*decoder-only architecture.*")
|
|
48
|
+
warnings.filterwarnings("ignore", message=".*attention mask is not set.*")
|
|
49
|
+
|
|
50
|
+
def setup_signal_handlers(
|
|
51
|
+
self,
|
|
52
|
+
worker_processes: list[mp.Process],
|
|
53
|
+
) -> None:
|
|
54
|
+
"""Setup signal handlers for graceful shutdown on the main process."""
|
|
55
|
+
|
|
56
|
+
def signal_handler(signum, frame):
|
|
57
|
+
"""Handle SIGINT and SIGTERM signals"""
|
|
58
|
+
signal_name = "SIGINT" if signum == signal.SIGINT else "SIGTERM"
|
|
59
|
+
print(f"\nReceived {signal_name}, shutting down gracefully...")
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
# Cancel current task if any
|
|
63
|
+
self.cancel_current()
|
|
64
|
+
|
|
65
|
+
self.shutdown_workers(worker_processes)
|
|
66
|
+
|
|
67
|
+
print("Graceful shutdown completed.")
|
|
68
|
+
sys.exit(0)
|
|
69
|
+
except Exception as e:
|
|
70
|
+
print(f"Error during graceful shutdown: {e}")
|
|
71
|
+
sys.exit(1)
|
|
72
|
+
|
|
73
|
+
# Register signal handlers
|
|
74
|
+
signal.signal(signal.SIGINT, signal_handler)
|
|
75
|
+
signal.signal(signal.SIGTERM, signal_handler)
|
|
76
|
+
|
|
77
|
+
def create_experiment(self, given_name: str, experiments_path: str) -> tuple[int, str, list[str]]:
|
|
78
|
+
"""Create a new experiment. Returns the experiment id, name, and log messages."""
|
|
79
|
+
log_messages: list[str] = []
|
|
80
|
+
|
|
81
|
+
# disable warnings from notebook
|
|
82
|
+
self._disable_ml_warnings_display()
|
|
83
|
+
|
|
84
|
+
# Clear any existing MLflow context before starting new experiment
|
|
85
|
+
try:
|
|
86
|
+
if mlflow.active_run():
|
|
87
|
+
print("Clearing existing MLflow context before starting new experiment")
|
|
88
|
+
mlflow.end_run()
|
|
89
|
+
except Exception as e:
|
|
90
|
+
print(f"Error clearing existing MLflow context: {e}")
|
|
91
|
+
|
|
92
|
+
# check if experiment is already running
|
|
93
|
+
running_experiment = None
|
|
94
|
+
try:
|
|
95
|
+
running_experiment = self.db.get_running_experiment()
|
|
96
|
+
except DBException:
|
|
97
|
+
pass
|
|
98
|
+
if running_experiment:
|
|
99
|
+
# check if the running experiment is the same as the new experiment
|
|
100
|
+
if given_name == running_experiment["experiment_name"]:
|
|
101
|
+
msg = (
|
|
102
|
+
f"Experiment {running_experiment['experiment_name']} is currently running."
|
|
103
|
+
" Returning the same experiment object."
|
|
104
|
+
)
|
|
105
|
+
print(msg)
|
|
106
|
+
log_messages.append(msg)
|
|
107
|
+
|
|
108
|
+
# check if the running experiment is also running a task
|
|
109
|
+
current_task = self.db.get_experiment_current_task()
|
|
110
|
+
if current_task != ExperimentTask.IDLE:
|
|
111
|
+
msg = f"Task {current_task.value} that was running has been cancelled."
|
|
112
|
+
print(msg)
|
|
113
|
+
log_messages.append(msg)
|
|
114
|
+
self.cancel_current(internal=True)
|
|
115
|
+
|
|
116
|
+
# get experiment id
|
|
117
|
+
experiment_id, experiment_name = (
|
|
118
|
+
running_experiment["experiment_id"],
|
|
119
|
+
running_experiment["experiment_name"],
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
self.end_experiment(internal=True)
|
|
123
|
+
experiment_id, experiment_name, mlflow_experiment_id = self._create_experiment_internal(
|
|
124
|
+
given_name,
|
|
125
|
+
experiments_path,
|
|
126
|
+
)
|
|
127
|
+
msg = (
|
|
128
|
+
f"The previously running experiment {running_experiment['experiment_name']} was forcibly ended."
|
|
129
|
+
f" Created a new experiment with name '{experiment_name}' with Experiment ID: {experiment_id}"
|
|
130
|
+
f" and MLFlow Experiment ID: {mlflow_experiment_id} saved at {experiments_path}/{experiment_name}"
|
|
131
|
+
)
|
|
132
|
+
print(msg)
|
|
133
|
+
log_messages.append(msg)
|
|
134
|
+
# check if experiment name already exists
|
|
135
|
+
elif given_name in self.db.get_all_experiment_names():
|
|
136
|
+
experiment_id, experiment_name, mlflow_experiment_id = self._create_experiment_internal(
|
|
137
|
+
given_name,
|
|
138
|
+
experiments_path,
|
|
139
|
+
)
|
|
140
|
+
msg = (
|
|
141
|
+
"An experiment with the same name already exists."
|
|
142
|
+
f" Created a new experiment with name '{experiment_name}' with Experiment ID: {experiment_id}"
|
|
143
|
+
f" and MLFlow Experiment ID: {mlflow_experiment_id} saved at {experiments_path}/{experiment_name}"
|
|
144
|
+
)
|
|
145
|
+
print(msg)
|
|
146
|
+
log_messages.append(msg)
|
|
147
|
+
else:
|
|
148
|
+
experiment_id, experiment_name, mlflow_experiment_id = self._create_experiment_internal(
|
|
149
|
+
given_name,
|
|
150
|
+
experiments_path,
|
|
151
|
+
)
|
|
152
|
+
msg = (
|
|
153
|
+
f"Experiment {experiment_name} created with Experiment ID: {experiment_id}"
|
|
154
|
+
f" and MLFlow Experiment ID: {mlflow_experiment_id} saved at {experiments_path}/{experiment_name}"
|
|
155
|
+
)
|
|
156
|
+
print(msg)
|
|
157
|
+
log_messages.append(msg)
|
|
158
|
+
|
|
159
|
+
# initialize the data paths and create directories
|
|
160
|
+
try:
|
|
161
|
+
DataPath.initialize(experiment_name, experiments_path)
|
|
162
|
+
except Exception as e:
|
|
163
|
+
raise ExperimentException(f"Failed to initialize data paths: {e}")
|
|
164
|
+
|
|
165
|
+
return experiment_id, experiment_name, log_messages
|
|
166
|
+
|
|
167
|
+
def end_experiment(self, internal: bool = False) -> None:
|
|
168
|
+
"""End the experiment"""
|
|
169
|
+
# check if experiment is running
|
|
170
|
+
try:
|
|
171
|
+
current_experiment = self.db.get_running_experiment()
|
|
172
|
+
except DBException:
|
|
173
|
+
if not internal:
|
|
174
|
+
print("No experiment is currently running. Nothing to end.")
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
# create logger
|
|
178
|
+
experiment_name = current_experiment["experiment_name"]
|
|
179
|
+
logger = RFLogger().create_logger(experiment_name)
|
|
180
|
+
|
|
181
|
+
# cancel current task if there's any
|
|
182
|
+
self.cancel_current(internal=True)
|
|
183
|
+
|
|
184
|
+
# reset DB states
|
|
185
|
+
self.db.set_experiment_status(current_experiment["experiment_id"], ExperimentStatus.COMPLETED)
|
|
186
|
+
self.db.reset_all_tables()
|
|
187
|
+
|
|
188
|
+
# Clear MLflow context
|
|
189
|
+
try:
|
|
190
|
+
if mlflow.active_run():
|
|
191
|
+
print("Ending active MLflow run before ending experiment")
|
|
192
|
+
mlflow.end_run()
|
|
193
|
+
|
|
194
|
+
# Also clear context through MLflowManager if available
|
|
195
|
+
try:
|
|
196
|
+
mlflow_manager = MLflowManager(MLFLOW_URL)
|
|
197
|
+
mlflow_manager.clear_context()
|
|
198
|
+
except Exception as e2:
|
|
199
|
+
print(f"[Error clearing MLflow context through MLflowManager: {e2}")
|
|
200
|
+
except Exception as e:
|
|
201
|
+
print(f"Error clearing MLflow context: {e}")
|
|
202
|
+
|
|
203
|
+
# print experiment ended message
|
|
204
|
+
msg = f"Experiment {experiment_name} ended"
|
|
205
|
+
if not internal:
|
|
206
|
+
print(msg)
|
|
207
|
+
logger.info(msg)
|
|
208
|
+
|
|
209
|
+
def cancel_current(self, internal: bool = False) -> None:
|
|
210
|
+
"""Cancel the current task"""
|
|
211
|
+
# check if experiment is running
|
|
212
|
+
try:
|
|
213
|
+
current_experiment = self.db.get_running_experiment()
|
|
214
|
+
except DBException:
|
|
215
|
+
if not internal:
|
|
216
|
+
print("No experiment is currently running. Nothing to cancel.")
|
|
217
|
+
return
|
|
218
|
+
|
|
219
|
+
# create logger
|
|
220
|
+
logger = RFLogger().create_logger(current_experiment["experiment_name"])
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
current_task = self.db.get_experiment_current_task()
|
|
224
|
+
except DBException:
|
|
225
|
+
msg = "No task is currently running. Nothing to cancel."
|
|
226
|
+
if not internal:
|
|
227
|
+
print(msg)
|
|
228
|
+
logger.info(msg)
|
|
229
|
+
return
|
|
230
|
+
|
|
231
|
+
# reset experiment states and set current task to idle
|
|
232
|
+
self.db.reset_experiment_states()
|
|
233
|
+
self.db.set_experiment_current_task(ExperimentTask.IDLE)
|
|
234
|
+
if current_task != ExperimentTask.IDLE:
|
|
235
|
+
msg = f"Task {current_task.value} cancelled"
|
|
236
|
+
print(msg)
|
|
237
|
+
logger.info(msg)
|
|
238
|
+
logger.debug("Reset experiment states and set current experiment task to idle")
|
|
239
|
+
|
|
240
|
+
def shutdown_workers(
|
|
241
|
+
self,
|
|
242
|
+
worker_processes: list[mp.Process],
|
|
243
|
+
) -> None:
|
|
244
|
+
"""Shutdown the workers"""
|
|
245
|
+
# stop workers
|
|
246
|
+
for worker_process in worker_processes:
|
|
247
|
+
worker_process.terminate()
|
|
248
|
+
print("Workers stopped")
|
|
249
|
+
|
|
250
|
+
def get_runs_info(self) -> pd.DataFrame:
|
|
251
|
+
"""Get the run info"""
|
|
252
|
+
try:
|
|
253
|
+
runs = self.db.get_all_runs()
|
|
254
|
+
runs_info = {}
|
|
255
|
+
for run_id, run_details in runs.items():
|
|
256
|
+
new_run_details = {k: v for k, v in run_details.items() if k not in ("flattened_config", "config_leaf")}
|
|
257
|
+
if "config_leaf" in run_details:
|
|
258
|
+
config_leaf = run_details["config_leaf"].copy()
|
|
259
|
+
config_leaf.pop("additional_kwargs", None)
|
|
260
|
+
new_run_details["config"] = config_leaf
|
|
261
|
+
|
|
262
|
+
runs_info[run_id] = new_run_details
|
|
263
|
+
|
|
264
|
+
if runs_info:
|
|
265
|
+
df = pd.DataFrame.from_dict(runs_info, orient="index")
|
|
266
|
+
df = df.reset_index().rename(columns={"index": "run_id"})
|
|
267
|
+
cols = ["run_id"] + [col for col in df.columns if col != "run_id"]
|
|
268
|
+
df = df[cols]
|
|
269
|
+
return df
|
|
270
|
+
else:
|
|
271
|
+
return pd.DataFrame(columns=["run_id"])
|
|
272
|
+
|
|
273
|
+
except DBException as e:
|
|
274
|
+
raise ExperimentException("Error getting runs info") from e
|
|
275
|
+
|
|
276
|
+
def _display_runs_info(self, runs_info: dict[int, dict[str, Any]]) -> pd.DataFrame:
|
|
277
|
+
"""Fetch runs info, display as a pandas DataFrame, and return the DataFrame.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
pd.DataFrame: A DataFrame containing all runs information with run_id as first column.
|
|
281
|
+
"""
|
|
282
|
+
try:
|
|
283
|
+
# Convert the runs info to a pandas DataFrame
|
|
284
|
+
df = pd.DataFrame.from_dict(runs_info, orient="index")
|
|
285
|
+
|
|
286
|
+
# Reset index to make run_id a regular column for better display
|
|
287
|
+
df = df.reset_index().rename(columns={"index": "run_id"})
|
|
288
|
+
|
|
289
|
+
# Reorder columns to put run_id first
|
|
290
|
+
cols = ["run_id"] + [col for col in df.columns if col != "run_id"]
|
|
291
|
+
df = df[cols]
|
|
292
|
+
|
|
293
|
+
# Set pandas display options for better notebook viewing
|
|
294
|
+
pd.set_option("display.max_columns", None)
|
|
295
|
+
pd.set_option("display.max_rows", None)
|
|
296
|
+
pd.set_option("display.width", None)
|
|
297
|
+
pd.set_option("display.max_colwidth", 50)
|
|
298
|
+
|
|
299
|
+
# Display the results
|
|
300
|
+
print(f"Total runs: {len(df)}")
|
|
301
|
+
print("\n" + "=" * 80)
|
|
302
|
+
|
|
303
|
+
try:
|
|
304
|
+
display(df) # For notebook environments
|
|
305
|
+
except NameError:
|
|
306
|
+
print(df.to_string()) # Fallback for non-notebook environments
|
|
307
|
+
|
|
308
|
+
return df
|
|
309
|
+
|
|
310
|
+
except ExperimentException as e:
|
|
311
|
+
print(f"Error displaying runs info: {e}")
|
|
312
|
+
raise
|
|
313
|
+
|
|
314
|
+
def _create_experiment_internal(self, given_name: str, experiments_path: str) -> tuple[int, str, str]:
|
|
315
|
+
"""Create new experiment -
|
|
316
|
+
if given_name already exists - increment suffix and create new experiment
|
|
317
|
+
if given_name is new - create new experiment with given name
|
|
318
|
+
"""
|
|
319
|
+
try:
|
|
320
|
+
given_name = given_name if given_name else "rf-exp"
|
|
321
|
+
experiment_name = self._generate_unique_experiment_name(given_name, self.db.get_all_experiment_names())
|
|
322
|
+
|
|
323
|
+
mlflow_manager = MLflowManager(MLFLOW_URL)
|
|
324
|
+
mlflow_experiment_id = mlflow_manager.create_experiment(experiment_name)
|
|
325
|
+
mlflow.tracing.disable_notebook_display()
|
|
326
|
+
|
|
327
|
+
# write new experiment details to database
|
|
328
|
+
experiment_id = self.db.create_experiment(
|
|
329
|
+
experiment_name,
|
|
330
|
+
mlflow_experiment_id,
|
|
331
|
+
config_options={"experiments_path": experiments_path},
|
|
332
|
+
)
|
|
333
|
+
return experiment_id, experiment_name, mlflow_experiment_id
|
|
334
|
+
except mlflow.exceptions.RestException as e: # pyright: ignore
|
|
335
|
+
raise ExperimentException(f"Error creating MLFlow experiment: {e}") from e
|
|
336
|
+
|
|
337
|
+
def _generate_unique_experiment_name(self, name: str, existing_names: list[str]) -> str:
|
|
338
|
+
"""Increment the suffix of the name after the last '_' till it is unique"""
|
|
339
|
+
if not name:
|
|
340
|
+
name = "rf-exp"
|
|
341
|
+
|
|
342
|
+
pattern = r"^(.+?)(_(\d+))?$"
|
|
343
|
+
max_attempts = 1000 # Prevent infinite loops
|
|
344
|
+
attempts = 0
|
|
345
|
+
|
|
346
|
+
new_name = name
|
|
347
|
+
while new_name in existing_names and attempts < max_attempts:
|
|
348
|
+
match = re.match(pattern, new_name)
|
|
349
|
+
|
|
350
|
+
if match:
|
|
351
|
+
base_name = match.group(1)
|
|
352
|
+
current_suffix = match.group(3)
|
|
353
|
+
if current_suffix:
|
|
354
|
+
try:
|
|
355
|
+
new_suffix = int(current_suffix) + 1
|
|
356
|
+
except ValueError:
|
|
357
|
+
# If suffix is not a valid integer, start from 1
|
|
358
|
+
new_suffix = 1
|
|
359
|
+
else:
|
|
360
|
+
new_suffix = 1
|
|
361
|
+
new_name = f"{base_name}_{new_suffix}"
|
|
362
|
+
else:
|
|
363
|
+
new_name = f"{new_name}_1"
|
|
364
|
+
|
|
365
|
+
attempts += 1
|
|
366
|
+
|
|
367
|
+
if attempts >= max_attempts:
|
|
368
|
+
raise ExperimentException("Could not generate unique experiment name")
|
|
369
|
+
|
|
370
|
+
return new_name
|