rapidfireai 0.0.1__py3-none-any.whl → 0.9.10__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.10.dist-info/METADATA +247 -0
- rapidfireai-0.9.10.dist-info/RECORD +318 -0
- rapidfireai-0.9.10.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.10.dist-info}/WHEEL +0 -0
- {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.10.dist-info}/licenses/LICENSE +0 -0
- {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.10.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
-- Experiments table
|
|
2
|
+
CREATE TABLE IF NOT EXISTS experiments (
|
|
3
|
+
experiment_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
4
|
+
experiment_name TEXT NOT NULL,
|
|
5
|
+
mlflow_experiment_id TEXT NOT NULL,
|
|
6
|
+
config_options TEXT NOT NULL,
|
|
7
|
+
status TEXT NOT NULL,
|
|
8
|
+
current_task TEXT NOT NULL,
|
|
9
|
+
error TEXT DEFAULT ''
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
-- Runs table
|
|
13
|
+
CREATE TABLE IF NOT EXISTS runs (
|
|
14
|
+
run_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
15
|
+
status TEXT NOT NULL,
|
|
16
|
+
mlflow_run_id TEXT,
|
|
17
|
+
flattened_config TEXT DEFAULT '{}',
|
|
18
|
+
config_leaf TEXT DEFAULT '{}',
|
|
19
|
+
completed_steps INTEGER DEFAULT 0,
|
|
20
|
+
total_steps INTEGER DEFAULT 0,
|
|
21
|
+
start_chunk_id INTEGER DEFAULT 0,
|
|
22
|
+
num_chunks_visited_curr_epoch INTEGER DEFAULT 0,
|
|
23
|
+
num_epochs_completed INTEGER DEFAULT 0,
|
|
24
|
+
error TEXT DEFAULT '',
|
|
25
|
+
source TEXT DEFAULT '',
|
|
26
|
+
ended_by TEXT DEFAULT '',
|
|
27
|
+
warm_started_from INTEGER DEFAULT NULL
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
-- Interactive Control table
|
|
31
|
+
CREATE TABLE IF NOT EXISTS interactive_control (
|
|
32
|
+
task_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
33
|
+
run_id INTEGER NOT NULL,
|
|
34
|
+
ic_op TEXT NOT NULL,
|
|
35
|
+
config_leaf TEXT DEFAULT '{}',
|
|
36
|
+
status TEXT NOT NULL,
|
|
37
|
+
FOREIGN KEY (run_id) REFERENCES runs (run_id)
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
-- Worker Task table
|
|
41
|
+
CREATE TABLE IF NOT EXISTS worker_task (
|
|
42
|
+
task_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
43
|
+
worker_id INTEGER NOT NULL,
|
|
44
|
+
task_type TEXT NOT NULL,
|
|
45
|
+
status TEXT NOT NULL,
|
|
46
|
+
run_id INTEGER NOT NULL,
|
|
47
|
+
chunk_id INTEGER NOT NULL,
|
|
48
|
+
config_options TEXT DEFAULT '{}',
|
|
49
|
+
FOREIGN KEY (run_id) REFERENCES runs (run_id)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
-- Controller Progress table
|
|
53
|
+
CREATE TABLE IF NOT EXISTS controller_progress (
|
|
54
|
+
run_id INTEGER PRIMARY KEY,
|
|
55
|
+
progress REAL DEFAULT 0.0,
|
|
56
|
+
FOREIGN KEY (run_id) REFERENCES runs (run_id)
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
-- Worker Progress table
|
|
60
|
+
CREATE TABLE IF NOT EXISTS worker_progress (
|
|
61
|
+
run_id INTEGER PRIMARY KEY,
|
|
62
|
+
subchunk_progress REAL DEFAULT 0.0,
|
|
63
|
+
FOREIGN KEY (run_id) REFERENCES runs (run_id)
|
|
64
|
+
);
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
"""This module contains functions for the dispatcher module."""
|
|
2
|
+
|
|
3
|
+
import traceback
|
|
4
|
+
from logging import Logger
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from flask import Flask, Response, jsonify, request
|
|
8
|
+
from flask_cors import CORS
|
|
9
|
+
|
|
10
|
+
from rapidfireai.db.rf_db import RfDb
|
|
11
|
+
from rapidfireai.utils.constants import LOG_FILENAME, ControllerTask, DispatcherConfig
|
|
12
|
+
from rapidfireai.utils.exceptions import DispatcherException
|
|
13
|
+
from rapidfireai.utils.logging import RFLogger
|
|
14
|
+
|
|
15
|
+
CORS_ALLOWED_ORIGINS = ["http://localhost:3000", "http://localhost"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Dispatcher:
|
|
19
|
+
"""Class to co-ordinate the flow of tasks between the user and Controllers"""
|
|
20
|
+
|
|
21
|
+
def __init__(self) -> None:
|
|
22
|
+
# initialize loggers
|
|
23
|
+
self.logger_experiment_name: str | None = None
|
|
24
|
+
self.logger: Logger | None = None
|
|
25
|
+
|
|
26
|
+
# create Db handle
|
|
27
|
+
self.db: RfDb = RfDb()
|
|
28
|
+
|
|
29
|
+
# create Flask app
|
|
30
|
+
self.app: Flask = Flask(__name__)
|
|
31
|
+
|
|
32
|
+
# Enable CORS for all routes
|
|
33
|
+
_ = CORS(self.app, resources={r"/*": {"origins": CORS_ALLOWED_ORIGINS}})
|
|
34
|
+
|
|
35
|
+
# register routes
|
|
36
|
+
self.register_routes()
|
|
37
|
+
|
|
38
|
+
def _get_logger(self) -> Logger | None:
|
|
39
|
+
"""Get the latest logger for the dispatcher"""
|
|
40
|
+
current_experiment_name = self.db.get_running_experiment()["experiment_name"]
|
|
41
|
+
if self.logger is None or self.logger_experiment_name != current_experiment_name:
|
|
42
|
+
self.logger = RFLogger().create_logger("dispatcher")
|
|
43
|
+
self.logger_experiment_name = current_experiment_name
|
|
44
|
+
return self.logger
|
|
45
|
+
|
|
46
|
+
def register_routes(self) -> None:
|
|
47
|
+
"""Register the routes for the dispatcher"""
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
route_prefix = "/dispatcher"
|
|
51
|
+
|
|
52
|
+
# health check route
|
|
53
|
+
self.app.add_url_rule(f"{route_prefix}/health-check", "health_check", self.health_check, methods=["GET"])
|
|
54
|
+
|
|
55
|
+
# UI routes
|
|
56
|
+
self.app.add_url_rule(f"{route_prefix}/get-all-runs", "get_all_runs", self.get_all_runs, methods=["GET"])
|
|
57
|
+
self.app.add_url_rule(f"{route_prefix}/get-run", "get_run", self.get_run, methods=["POST"])
|
|
58
|
+
self.app.add_url_rule(
|
|
59
|
+
f"{route_prefix}/get-all-experiment-names",
|
|
60
|
+
"get_all_experiment_names",
|
|
61
|
+
self.get_all_experiment_names,
|
|
62
|
+
methods=["GET"],
|
|
63
|
+
)
|
|
64
|
+
self.app.add_url_rule(
|
|
65
|
+
f"{route_prefix}/get-running-experiment",
|
|
66
|
+
"get_running_experiment",
|
|
67
|
+
self.get_running_experiment,
|
|
68
|
+
methods=["GET"],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Interactive Control routes
|
|
72
|
+
self.app.add_url_rule(
|
|
73
|
+
f"{route_prefix}/clone-modify-run", "clone_modify_run", self.clone_modify_run, methods=["POST"]
|
|
74
|
+
)
|
|
75
|
+
self.app.add_url_rule(f"{route_prefix}/stop-run", "stop_run", self.stop_run, methods=["POST"])
|
|
76
|
+
self.app.add_url_rule(f"{route_prefix}/resume-run", "resume_run", self.resume_run, methods=["POST"])
|
|
77
|
+
self.app.add_url_rule(f"{route_prefix}/delete-run", "delete_run", self.delete_run, methods=["POST"])
|
|
78
|
+
self.app.add_url_rule(
|
|
79
|
+
f"{route_prefix}/get-ic-logs", "get_ic_ops_logs", self.get_ic_ops_logs, methods=["POST"]
|
|
80
|
+
)
|
|
81
|
+
self.app.add_url_rule(
|
|
82
|
+
f"{route_prefix}/get-experiment-logs", "get_experiment_logs", self.get_experiment_logs, methods=["POST"]
|
|
83
|
+
)
|
|
84
|
+
except Exception as e:
|
|
85
|
+
raise DispatcherException(f"Error while registering routes: {e}") from e
|
|
86
|
+
|
|
87
|
+
# Misc routes
|
|
88
|
+
def health_check(self) -> tuple[Response, int]:
|
|
89
|
+
"""Health check route"""
|
|
90
|
+
try:
|
|
91
|
+
return jsonify("Dispatcher is up and running"), 200
|
|
92
|
+
except Exception as e:
|
|
93
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
94
|
+
|
|
95
|
+
# UI routes
|
|
96
|
+
def get_all_runs(self) -> tuple[Response, int]:
|
|
97
|
+
"""Get all the runs for the UI"""
|
|
98
|
+
try:
|
|
99
|
+
results = self.db.get_all_runs()
|
|
100
|
+
safe_results: list[dict[str, Any]] = []
|
|
101
|
+
for run_id, result in results.items():
|
|
102
|
+
# remove additional_kwargs from config_leaf
|
|
103
|
+
result["config_leaf"].pop("additional_kwargs", None)
|
|
104
|
+
|
|
105
|
+
# remove peft_params.task_type if it exists
|
|
106
|
+
if "peft_params" in result["config_leaf"]:
|
|
107
|
+
result["config_leaf"]["peft_params"].pop("task_type", None)
|
|
108
|
+
|
|
109
|
+
# remove model_kwargs.torch_dtype if it exists
|
|
110
|
+
if "model_kwargs" in result["config_leaf"]:
|
|
111
|
+
result["config_leaf"]["model_kwargs"].pop("torch_dtype", None)
|
|
112
|
+
|
|
113
|
+
if "reward_funcs" in result["config_leaf"]:
|
|
114
|
+
result["config_leaf"].pop("reward_funcs", None)
|
|
115
|
+
|
|
116
|
+
safe_results.append(
|
|
117
|
+
{
|
|
118
|
+
"run_id": run_id,
|
|
119
|
+
"status": result["status"].value,
|
|
120
|
+
"mlflow_run_id": result["mlflow_run_id"],
|
|
121
|
+
"config": result["config_leaf"],
|
|
122
|
+
"flattened_config": result["flattened_config"],
|
|
123
|
+
"completed_steps": result["completed_steps"],
|
|
124
|
+
"total_steps": result["total_steps"],
|
|
125
|
+
"num_epochs_completed": result["num_epochs_completed"],
|
|
126
|
+
"error": result["error"],
|
|
127
|
+
"source": result["source"].value if result["source"] else None,
|
|
128
|
+
"ended_by": result["ended_by"].value if result["ended_by"] else None,
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
return jsonify(safe_results), 200
|
|
132
|
+
except Exception as e:
|
|
133
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
134
|
+
|
|
135
|
+
def get_run(self) -> tuple[Response, int]:
|
|
136
|
+
"""Get a run for the UI"""
|
|
137
|
+
try:
|
|
138
|
+
data = request.get_json()
|
|
139
|
+
result = self.db.get_run(data["run_id"])
|
|
140
|
+
if not result:
|
|
141
|
+
return jsonify({"error": "Run not found"}), 404
|
|
142
|
+
|
|
143
|
+
# remove additional_kwargs from config_leaf
|
|
144
|
+
result["config_leaf"].pop("additional_kwargs", None)
|
|
145
|
+
|
|
146
|
+
# remove peft_params.task_type if it exists
|
|
147
|
+
if "peft_params" in result["config_leaf"]:
|
|
148
|
+
result["config_leaf"]["peft_params"].pop("task_type", None)
|
|
149
|
+
|
|
150
|
+
# remove model_kwargs.torch_dtype if it exists
|
|
151
|
+
if "model_kwargs" in result["config_leaf"]:
|
|
152
|
+
result["config_leaf"]["model_kwargs"].pop("torch_dtype", None)
|
|
153
|
+
|
|
154
|
+
if "reward_funcs" in result["config_leaf"]:
|
|
155
|
+
result["config_leaf"].pop("reward_funcs", None)
|
|
156
|
+
|
|
157
|
+
safe_result = {
|
|
158
|
+
"run_id": data["run_id"],
|
|
159
|
+
"status": result["status"].value,
|
|
160
|
+
"mlflow_run_id": result["mlflow_run_id"],
|
|
161
|
+
"config": result["config_leaf"],
|
|
162
|
+
"flattened_config": result["flattened_config"],
|
|
163
|
+
"completed_steps": result["completed_steps"],
|
|
164
|
+
"total_steps": result["total_steps"],
|
|
165
|
+
"num_epochs_completed": result["num_epochs_completed"],
|
|
166
|
+
"error": result["error"],
|
|
167
|
+
"source": result["source"].value if result["source"] else None,
|
|
168
|
+
"ended_by": result["ended_by"].value if result["ended_by"] else None,
|
|
169
|
+
}
|
|
170
|
+
return jsonify(safe_result), 200
|
|
171
|
+
except Exception as e:
|
|
172
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
173
|
+
|
|
174
|
+
def get_all_experiment_names(self) -> tuple[Response, int]:
|
|
175
|
+
"""Get all the experiment names for the UI"""
|
|
176
|
+
try:
|
|
177
|
+
results = self.db.get_all_experiment_names()
|
|
178
|
+
return jsonify(results), 200
|
|
179
|
+
except Exception as e:
|
|
180
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
181
|
+
|
|
182
|
+
def get_running_experiment(self) -> tuple[Response, int]:
|
|
183
|
+
"""Get the running experiment for the UI"""
|
|
184
|
+
try:
|
|
185
|
+
result = self.db.get_running_experiment()
|
|
186
|
+
return jsonify(result), 200
|
|
187
|
+
except Exception as e:
|
|
188
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
189
|
+
|
|
190
|
+
# Interactive Control routes
|
|
191
|
+
def clone_modify_run(self) -> tuple[Response, int]:
|
|
192
|
+
"""Clone and modify a run"""
|
|
193
|
+
try:
|
|
194
|
+
data = request.get_json()
|
|
195
|
+
if not data:
|
|
196
|
+
return jsonify({"error": "No JSON data received"}), 400
|
|
197
|
+
|
|
198
|
+
run_id = data["run_id"]
|
|
199
|
+
if not run_id:
|
|
200
|
+
return jsonify({"error": "run_id is required"}), 400
|
|
201
|
+
|
|
202
|
+
if "config" not in data or not data["config"]:
|
|
203
|
+
return jsonify({"error": "config is required"}), 400
|
|
204
|
+
|
|
205
|
+
# validate and parse the ML config text
|
|
206
|
+
# TODO: Implement validate_config
|
|
207
|
+
# status = validate_config(data["config"])
|
|
208
|
+
|
|
209
|
+
# get the ML config
|
|
210
|
+
config = data["config"]
|
|
211
|
+
|
|
212
|
+
# Validate the ML config text
|
|
213
|
+
# data["warm_start"]: bool indicating if the run should be warm started
|
|
214
|
+
task = ControllerTask.IC_CLONE_MODIFY_WARM if data["warm_start"] else ControllerTask.IC_CLONE_MODIFY
|
|
215
|
+
|
|
216
|
+
# set create models subtask
|
|
217
|
+
_ = self.db.create_ic_ops_task(
|
|
218
|
+
run_id=run_id,
|
|
219
|
+
ic_op=task,
|
|
220
|
+
config_leaf=config,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# log the task
|
|
224
|
+
logger = self._get_logger()
|
|
225
|
+
if logger:
|
|
226
|
+
logger.info(f"Received clone-modify task with warm start {data['warm_start']} for run_id {run_id}")
|
|
227
|
+
return jsonify({}), 200
|
|
228
|
+
except ValueError as ve:
|
|
229
|
+
logger = self._get_logger()
|
|
230
|
+
if logger:
|
|
231
|
+
logger.opt(exception=True).error(f"ValueError in clone_modify_run: {ve}")
|
|
232
|
+
return jsonify({"error": str(ve)}), 400
|
|
233
|
+
except TypeError as te:
|
|
234
|
+
logger = self._get_logger()
|
|
235
|
+
if logger:
|
|
236
|
+
logger.opt(exception=True).error(f"TypeError in clone_modify_run: {te}")
|
|
237
|
+
return jsonify({"error": str(te)}), 400
|
|
238
|
+
except Exception as e:
|
|
239
|
+
logger = self._get_logger()
|
|
240
|
+
if logger:
|
|
241
|
+
logger.opt(exception=True).error(f"Unexpected error in clone_modify_run: {e}", exc_info=True)
|
|
242
|
+
return jsonify({"error": "An unexpected error occurred", "details": str(e)}), 500
|
|
243
|
+
|
|
244
|
+
def stop_run(self) -> tuple[Response, int]:
|
|
245
|
+
"""Stop the run"""
|
|
246
|
+
try:
|
|
247
|
+
data = request.get_json()
|
|
248
|
+
run_id = data["run_id"]
|
|
249
|
+
task = ControllerTask.IC_STOP
|
|
250
|
+
|
|
251
|
+
# get ml config from db
|
|
252
|
+
config_leaf = self.db.get_run(run_id)["config_leaf"]
|
|
253
|
+
|
|
254
|
+
# create ic ops task
|
|
255
|
+
_ = self.db.create_ic_ops_task(run_id, task, config_leaf)
|
|
256
|
+
|
|
257
|
+
# log the task
|
|
258
|
+
logger = self._get_logger()
|
|
259
|
+
if logger:
|
|
260
|
+
logger.info(f"Received stop task for run_id: {run_id}")
|
|
261
|
+
return jsonify({}), 200
|
|
262
|
+
except Exception as e:
|
|
263
|
+
logger = self._get_logger()
|
|
264
|
+
if logger:
|
|
265
|
+
logger.opt(exception=True).error(f"Error in stop_run: {e}", exc_info=True)
|
|
266
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
267
|
+
|
|
268
|
+
def resume_run(self) -> tuple[Response, int]:
|
|
269
|
+
"""Resume the run"""
|
|
270
|
+
try:
|
|
271
|
+
data = request.get_json()
|
|
272
|
+
run_id = data["run_id"]
|
|
273
|
+
task = ControllerTask.IC_RESUME
|
|
274
|
+
|
|
275
|
+
# get ml config from db
|
|
276
|
+
config_leaf = self.db.get_run(run_id)["config_leaf"]
|
|
277
|
+
|
|
278
|
+
# set resume run task
|
|
279
|
+
_ = self.db.create_ic_ops_task(
|
|
280
|
+
run_id=run_id,
|
|
281
|
+
ic_op=task,
|
|
282
|
+
config_leaf=config_leaf,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# log the task
|
|
286
|
+
logger = self._get_logger()
|
|
287
|
+
if logger:
|
|
288
|
+
logger.info(f"Received resume task for run_id: {run_id}")
|
|
289
|
+
return jsonify({}), 200
|
|
290
|
+
except Exception as e:
|
|
291
|
+
logger = self._get_logger()
|
|
292
|
+
if logger:
|
|
293
|
+
logger.opt(exception=True).error(f"Error in resume_run: {e}", exc_info=True)
|
|
294
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
295
|
+
|
|
296
|
+
def delete_run(self) -> tuple[Response, int]:
|
|
297
|
+
"""Delete the run"""
|
|
298
|
+
try:
|
|
299
|
+
data = request.get_json()
|
|
300
|
+
run_id = data["run_id"]
|
|
301
|
+
task = ControllerTask.IC_DELETE
|
|
302
|
+
|
|
303
|
+
# get ml config from db
|
|
304
|
+
config_leaf = self.db.get_run(run_id)["config_leaf"]
|
|
305
|
+
|
|
306
|
+
# set delete run task
|
|
307
|
+
_ = self.db.create_ic_ops_task(
|
|
308
|
+
run_id=run_id,
|
|
309
|
+
ic_op=task,
|
|
310
|
+
config_leaf=config_leaf,
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
# log the task
|
|
314
|
+
logger = self._get_logger()
|
|
315
|
+
if logger:
|
|
316
|
+
logger.info(f"Received delete task for run_id: {run_id}")
|
|
317
|
+
return jsonify({}), 200
|
|
318
|
+
except Exception as e:
|
|
319
|
+
logger = self._get_logger()
|
|
320
|
+
if logger:
|
|
321
|
+
logger.opt(exception=True).error(f"Error in delete_run: {e}", exc_info=True)
|
|
322
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
323
|
+
|
|
324
|
+
def get_ic_ops_logs(self) -> tuple[Response, int]:
|
|
325
|
+
"""Get the IC ops logs for the given experiment"""
|
|
326
|
+
try:
|
|
327
|
+
experiment_name = None
|
|
328
|
+
if request.is_json:
|
|
329
|
+
data = request.get_json()
|
|
330
|
+
if data and data.get("experiment_name"):
|
|
331
|
+
experiment_name = data["experiment_name"]
|
|
332
|
+
|
|
333
|
+
if not experiment_name:
|
|
334
|
+
experiment_name = self.db.get_running_experiment()["experiment_name"]
|
|
335
|
+
|
|
336
|
+
log_file_path = self.db.get_experiments_path(experiment_name) / LOG_FILENAME
|
|
337
|
+
|
|
338
|
+
# Check if the log file exists
|
|
339
|
+
if not log_file_path.exists():
|
|
340
|
+
return jsonify({"error": f"Log file not found for experiment: {experiment_name}"}), 404
|
|
341
|
+
|
|
342
|
+
# Read and filter logs for interactive-control entries
|
|
343
|
+
interactive_control_logs = []
|
|
344
|
+
with open(log_file_path) as f:
|
|
345
|
+
for line in f:
|
|
346
|
+
if f"| {experiment_name} | interactive-control |" in line:
|
|
347
|
+
interactive_control_logs.append(line.strip())
|
|
348
|
+
|
|
349
|
+
return jsonify(interactive_control_logs), 200
|
|
350
|
+
except Exception as e:
|
|
351
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
352
|
+
|
|
353
|
+
def get_experiment_logs(self) -> tuple[Response, int]:
|
|
354
|
+
"""Get all the logs for the given experiment"""
|
|
355
|
+
# TODO: find a way to optimize this, instead of reading the entire log file, we can read the last N lines
|
|
356
|
+
try:
|
|
357
|
+
experiment_name = None
|
|
358
|
+
if request.is_json:
|
|
359
|
+
data = request.get_json()
|
|
360
|
+
if data and data.get("experiment_name"):
|
|
361
|
+
experiment_name = data["experiment_name"]
|
|
362
|
+
|
|
363
|
+
if not experiment_name:
|
|
364
|
+
experiment_name = self.db.get_running_experiment()["experiment_name"]
|
|
365
|
+
|
|
366
|
+
log_file_path = self.db.get_experiments_path(experiment_name) / LOG_FILENAME
|
|
367
|
+
|
|
368
|
+
experiment_logs = []
|
|
369
|
+
with open(log_file_path) as f:
|
|
370
|
+
for line in f:
|
|
371
|
+
if f"| {experiment_name} |" in line:
|
|
372
|
+
experiment_logs.append(line.strip())
|
|
373
|
+
return jsonify(experiment_logs), 200
|
|
374
|
+
except Exception as e:
|
|
375
|
+
return jsonify({"error": str(e) + " " + str(traceback.format_exc())}), 500
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def serve_forever() -> Flask:
|
|
379
|
+
"""start the Dispatcher via Gunicorn"""
|
|
380
|
+
return Dispatcher().app
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
if __name__ == "__main__":
|
|
384
|
+
# initialize the database tables
|
|
385
|
+
rf_db = RfDb()
|
|
386
|
+
rf_db.create_tables()
|
|
387
|
+
print("Database tables initialized successfully")
|
|
388
|
+
|
|
389
|
+
# start the Dispatcher on local via Flask
|
|
390
|
+
dispatcher = Dispatcher()
|
|
391
|
+
dispatcher.app.run(host=DispatcherConfig.HOST, port=DispatcherConfig.PORT)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Gunicorn configuration file for the RapidFire dispatcher"""
|
|
2
|
+
|
|
3
|
+
from rapidfireai.db.rf_db import RfDb
|
|
4
|
+
from rapidfireai.utils.constants import DispatcherConfig
|
|
5
|
+
|
|
6
|
+
# Other Gunicorn settings...
|
|
7
|
+
bind = f"{DispatcherConfig.HOST}:{DispatcherConfig.PORT}"
|
|
8
|
+
workers = 2
|
|
9
|
+
|
|
10
|
+
wsgi_app = "rapidfireai.dispatcher.dispatcher:serve_forever()"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def on_starting(server):
|
|
14
|
+
"""
|
|
15
|
+
This function is called once before the master process is initialized.
|
|
16
|
+
We use it to create tables, ensuring this happens only once.
|
|
17
|
+
"""
|
|
18
|
+
print("Initializing database tables...")
|
|
19
|
+
try:
|
|
20
|
+
rf_db = RfDb()
|
|
21
|
+
rf_db.create_tables()
|
|
22
|
+
print("Database tables initialized successfully")
|
|
23
|
+
except Exception as e:
|
|
24
|
+
print(f"Error initializing database tables: {e}")
|
|
25
|
+
raise
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the Experiment class which manages the entire experiment lifecycle.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import multiprocessing as mp
|
|
6
|
+
import os
|
|
7
|
+
import traceback
|
|
8
|
+
from typing import Any, Callable
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
from torch.utils.data import Dataset
|
|
12
|
+
|
|
13
|
+
from rapidfireai.backend.controller import Controller
|
|
14
|
+
from rapidfireai.db.rf_db import RfDb
|
|
15
|
+
from rapidfireai.utils.constants import MLFLOW_URL
|
|
16
|
+
from rapidfireai.utils.exceptions import ExperimentException
|
|
17
|
+
from rapidfireai.utils.experiment_utils import ExperimentUtils
|
|
18
|
+
from rapidfireai.utils.logging import RFLogger
|
|
19
|
+
from rapidfireai.utils.mlflow_manager import MLflowManager
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Experiment:
|
|
23
|
+
"""Class to manage the entire experiment lifecycle."""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
experiment_name: str,
|
|
28
|
+
experiments_path: str = os.getenv("RF_EXPERIMENT_PATH", "./rapidfire_experiments"),
|
|
29
|
+
) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Args:
|
|
32
|
+
experiment_name: The name of the experiment.
|
|
33
|
+
experiments_path: The base path to the experiments directory.
|
|
34
|
+
"""
|
|
35
|
+
# initialize experiment variables
|
|
36
|
+
self.experiment_name: str = experiment_name
|
|
37
|
+
self.experiment_id: int | None = None
|
|
38
|
+
self.log_server_process: mp.Process | None = None
|
|
39
|
+
self.worker_processes: list[mp.Process] = []
|
|
40
|
+
|
|
41
|
+
# create db tables
|
|
42
|
+
try:
|
|
43
|
+
RfDb().create_tables()
|
|
44
|
+
except Exception as e:
|
|
45
|
+
raise ExperimentException(f"Error creating db tables: {e}, traceback: {traceback.format_exc()}") from e
|
|
46
|
+
|
|
47
|
+
# create experiment utils object
|
|
48
|
+
self.experiment_utils = ExperimentUtils()
|
|
49
|
+
|
|
50
|
+
# create experiment
|
|
51
|
+
try:
|
|
52
|
+
self.experiment_id, self.experiment_name, log_messages = self.experiment_utils.create_experiment(
|
|
53
|
+
given_name=self.experiment_name,
|
|
54
|
+
experiments_path=os.path.abspath(experiments_path),
|
|
55
|
+
)
|
|
56
|
+
except Exception as e:
|
|
57
|
+
raise ExperimentException(f"Error creating experiment: {e}, traceback: {traceback.format_exc()}") from e
|
|
58
|
+
|
|
59
|
+
# create logger
|
|
60
|
+
try:
|
|
61
|
+
self.logger = RFLogger().create_logger("experiment")
|
|
62
|
+
for msg in log_messages:
|
|
63
|
+
self.logger.info(msg)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
raise ExperimentException(f"Error creating logger: {e}, traceback: {traceback.format_exc()}") from e
|
|
66
|
+
|
|
67
|
+
# setup signal handlers for graceful shutdown
|
|
68
|
+
try:
|
|
69
|
+
self.experiment_utils.setup_signal_handlers(self.worker_processes)
|
|
70
|
+
except Exception as e:
|
|
71
|
+
if hasattr(self, "logger"):
|
|
72
|
+
self.logger.opt(exception=True).error(f"Error setting up signal handlers: {e}")
|
|
73
|
+
raise ExperimentException(
|
|
74
|
+
f"Error setting up signal handlers: {e}, traceback: {traceback.format_exc()}"
|
|
75
|
+
) from e
|
|
76
|
+
|
|
77
|
+
def run_fit(
|
|
78
|
+
self,
|
|
79
|
+
param_config: Any,
|
|
80
|
+
create_model_fn: Callable,
|
|
81
|
+
train_dataset: Dataset,
|
|
82
|
+
eval_dataset: Dataset,
|
|
83
|
+
num_chunks: int,
|
|
84
|
+
seed: int = 42,
|
|
85
|
+
) -> None:
|
|
86
|
+
"""Run the fit"""
|
|
87
|
+
try:
|
|
88
|
+
controller = Controller(self.experiment_id, self.experiment_name)
|
|
89
|
+
controller.run_fit(param_config, create_model_fn, train_dataset, eval_dataset, num_chunks, seed)
|
|
90
|
+
except Exception as e:
|
|
91
|
+
if hasattr(self, "logger"):
|
|
92
|
+
self.logger.opt(exception=True).error(f"Error running fit: {e}")
|
|
93
|
+
raise ExperimentException(f"Error running fit: {e}, traceback: {traceback.format_exc()}") from e
|
|
94
|
+
|
|
95
|
+
def get_results(self) -> pd.DataFrame:
|
|
96
|
+
"""
|
|
97
|
+
Get the MLflow training metrics for all runs in the experiment.
|
|
98
|
+
"""
|
|
99
|
+
try:
|
|
100
|
+
runs_info_df = self.experiment_utils.get_runs_info()
|
|
101
|
+
mlflow_manager = MLflowManager(MLFLOW_URL)
|
|
102
|
+
|
|
103
|
+
metrics_data = []
|
|
104
|
+
|
|
105
|
+
for _, run_row in runs_info_df.iterrows():
|
|
106
|
+
run_id = run_row["run_id"]
|
|
107
|
+
mlflow_run_id = run_row.get("mlflow_run_id")
|
|
108
|
+
|
|
109
|
+
if not mlflow_run_id:
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
run_metrics = mlflow_manager.get_run_metrics(mlflow_run_id)
|
|
113
|
+
|
|
114
|
+
step_metrics = {}
|
|
115
|
+
for metric_name, metric_values in run_metrics.items():
|
|
116
|
+
for step, value in metric_values:
|
|
117
|
+
if step not in step_metrics:
|
|
118
|
+
step_metrics[step] = {"run_id": run_id, "step": step}
|
|
119
|
+
step_metrics[step][metric_name] = value
|
|
120
|
+
|
|
121
|
+
metrics_data.extend(step_metrics.values())
|
|
122
|
+
|
|
123
|
+
if metrics_data:
|
|
124
|
+
return pd.DataFrame(metrics_data).sort_values(["run_id", "step"])
|
|
125
|
+
else:
|
|
126
|
+
return pd.DataFrame(columns=["run_id", "step"])
|
|
127
|
+
|
|
128
|
+
except Exception as e:
|
|
129
|
+
if hasattr(self, "logger"):
|
|
130
|
+
self.logger.opt(exception=True).error(f"Error getting results: {e}")
|
|
131
|
+
raise ExperimentException(f"Error getting results: {e}, traceback: {traceback.format_exc()}") from e
|
|
132
|
+
|
|
133
|
+
def cancel_current(self) -> None:
|
|
134
|
+
"""Cancel the current task"""
|
|
135
|
+
try:
|
|
136
|
+
self.experiment_utils.cancel_current(internal=False)
|
|
137
|
+
except Exception as e:
|
|
138
|
+
if hasattr(self, "logger"):
|
|
139
|
+
self.logger.opt(exception=True).error(f"Error canceling current task: {e}")
|
|
140
|
+
raise ExperimentException(f"Error canceling current task: {e}, traceback: {traceback.format_exc()}") from e
|
|
141
|
+
|
|
142
|
+
def get_runs_info(self) -> pd.DataFrame:
|
|
143
|
+
"""Get the run info"""
|
|
144
|
+
try:
|
|
145
|
+
return self.experiment_utils.get_runs_info()
|
|
146
|
+
except Exception as e:
|
|
147
|
+
if hasattr(self, "logger"):
|
|
148
|
+
self.logger.opt(exception=True).error(f"Error getting run info: {e}")
|
|
149
|
+
raise ExperimentException(f"Error getting run info: {e}, traceback: {traceback.format_exc()}") from e
|
|
150
|
+
|
|
151
|
+
def end(self) -> None:
|
|
152
|
+
"""End the experiment"""
|
|
153
|
+
try:
|
|
154
|
+
self.experiment_utils.end_experiment(internal=False)
|
|
155
|
+
except Exception as e:
|
|
156
|
+
if hasattr(self, "logger"):
|
|
157
|
+
self.logger.opt(exception=True).error(f"Error ending experiment: {e}")
|
|
158
|
+
raise ExperimentException(f"Error ending experiment: {e}, traceback: {traceback.format_exc()}") from e
|
|
159
|
+
|
|
160
|
+
# shutdown all child processes
|
|
161
|
+
try:
|
|
162
|
+
self.experiment_utils.shutdown_workers(self.worker_processes)
|
|
163
|
+
except Exception as e:
|
|
164
|
+
if hasattr(self, "logger"):
|
|
165
|
+
self.logger.opt(exception=True).error(f"Error shutting down RapidFire processes: {e}")
|
|
166
|
+
raise ExperimentException(
|
|
167
|
+
f"Error shutting down RapidFire processes: {e}, traceback: {traceback.format_exc()}"
|
|
168
|
+
) from e
|