Package: pymlup
PyMLupIntroductionIt's library for easy and fast run ML in production.All you need is to deliver the model file and config to the server (in fact, the config is not necessary) 🙃PyMLup is a modern way to run machine learning models in production. The market time has been reduced to a minimum. This library eliminates the need to write your own web applications with machine learning models and copy application code. It is enough to have a machine learning model to launch a web application with one command.It's library learning only clean python;Use FastApi in web app backend;Work tested with machine learning model frameworks (links to tests):scikit-learn>=1.2.0,<1.3.0tensorflow>=2.0.0,<3.0.0lightgbm>=4.0.0,<5.0.0torch>=2.0.0,<3.0.0onnx>=1.0.0,<2.0.0onnxruntime>=1.0.0,<2.0.0Support and tested with machine learning libraries:numpy>=1.0.0,<2.0.0pandas>=2.0.0,<3.0.0joblib>=1.2.0,<1.3.0tf2onnx>=1.0.0,<2.0.0skl2onnx>=1.0.0,<2.0.0jupyter==1.0.0The easiest way to try:pipinstallpymlup
mluprun-m/path/to/my/model.onnxUseful linksDocs;Examples;Tests models;How it's workYou are making your machine learning model. Optional: you are making mlup config for your model.You deliver your model to server. Optional: you deliver your config to server.Installing pymlup to your server and libraries for model.Run web app from your model or your config 🙃RequirementsPython 3.7+PyMLup stands on the shoulders of giants FastAPI for the web parts.Additionally, you need to install the libraries that your model uses.InstallationpipinstallpymlupYou will also can install with ml backend library:pipinstall"pymlup[scikit-learn]"# For scikit-learnpipinstall"pymlup[lightgbm]"# For microsoft lightgbmpipinstall"pymlup[tensorflow]"# For tensorflowpipinstall"pymlup[torch]"# For torchpipinstall"pymlup[onnx]"# For onnx models: torch, tensorflow, sklearn, etc...ExamplesExamples codeimportmlupclassMyAnyModelForExample:defpredict(self,X):returnXml_model=MyAnyModelForExample()up=mlup.UP(ml_model=ml_model)# Need call up.ml.load(), for analyze your modelup.ml.load()# If you want testing your web app, you can run in daemon mode# You can open browser http://localhost:8009/docsup.run_web_app(daemon=True)importrequestsresponse=requests.post('http://0.0.0.0:8009/predict',json={'X':[[1,2,3],[4,5,6]]})print(response.json())up.stop_web_app()You can check work model by config, without web application.predict- Get model predict as inner arguments as in web app.predict_from- Aspredictmethod, but not use data transformer before call model predict.async_predict- Asynchronous version of thepredictmethod.importmlupimportnumpyclassMyAnyModelForExample:defpredict(self,X):returnXml_model=MyAnyModelForExample()up=mlup.UP(ml_model=ml_model)up.ml.load()up.predict(X=[[1,2,3],[4,5,6]])up.predict_from(X=numpy.array([[1,2,3],[4,5,6]]))awaitup.async_predict(X=[[1,2,3],[4,5,6]])Save ready application to diskMake default configIf path endswith to json, make json config, else yaml config.importmlupmlup.generate_default_config('path_to_yaml_config.yaml')From configYou can save ready config to disk, but you need set local storage and path to model file in server.
In folder can there are many files, mask need for filter exactly our model fileimportmlupfrommlup.ml.emptyimportEmptyModel# This stub classfrommlupimportconstantsup=mlup.UP(ml_model=EmptyModel())up.conf.storage_type=constants.StorageType.diskup.conf.storage_kwargs={'path_to_files':'path/to/model/file/in/model_name.modelextension','file_mask':'model_name.modelextension',}up.to_yaml("path_to_yaml_config.yaml")up.to_json("path_to_json_config.json")# After in serverup=mlup.UP.load_from_yaml("path_to_yaml_config.yaml",load_model=True)up.run_web_app()From pickleIf you make pickle/joblib file your mlup with model, don't need to change storage type, because your model there is in your pickle/joblib file.importpickleimportmlupfrommlup.ml.emptyimportEmptyModel# This stub classup=mlup.UP(ml_model=EmptyModel())# You can create pickle filewithopen('path_to_pickle_file.pckl','wb')asf:pickle.dump(up,f)# After in serverwithopen('path_to_pickle_file.pckl','rb')asf:up=pickle.load(f)up.ml.load()up.run_web_app()Change configIf you can change model settings (SeeDescription of the application life cycle), need callup.ml.load_model_settings().importmlupclassMyAnyModelForExample:defpredict(self,X):returnXml_model=MyAnyModelForExample()up=mlup.UP(ml_model=ml_model,conf=mlup.Config(port=8011))up.ml.load()up.conf.auto_detect_predict_params=Falseup.ml.load_model_settings()Examples server commandsmlup runYou can run web application from model, config, pickle up object. Bash command mlup run making this.Seemlup run --helporDescription of the bash commandsfor full docs.From modelmluprun-m/path/to/your/model.extensionThis will run code something like this:importmlupfrommlupimportconstantsup=mlup.UP(conf=mlup.Config(storage_type=constants.StorageType.disk,storage_kwargs={'path_to_files':'/path/to/your/model.extension','files_mask':r'.+',},))up.ml.load()up.run_web_app()You change config attributes in this mode. For this, you can add arguments--up.<config_attribute_name>=new_value.
(For more examples seemlup run --helporDescription of the bash commands).From configmluprun-c/path/to/your/config.yaml# or mlup run -ct json -c /path/to/your/config.jsonThis will run code something like this:importmlupup=mlup.UP.load_from_yaml(conf_path='/path/to/your/config.yaml',load_model=True)up.run_web_app()From mlup.UP pickle/joblib objectmluprun-b/path/to/your/up_object.pckl# or mlup run -bt joblib -b /path/to/your/up_object.joblibThis will run code something like this:importpicklewithopen('/path/to/your/up_object.pckl','rb')asf:up=pickle.load(f)up.run_web_app()mlup make-appThis command making.pyfile with mlup web application and your model, config, pickle up object or with default settings.Seemlup make-app --helporDescription of the bash commandsfor full docs.With default settingsmlupmake-appexample_without_data_app.pyThis command is making something like this:# example_without_data_app.pyimportmlup# You can load the model yourself and pass it to the "ml_model" argument.# up = mlup.UP(ml_model=my_model, conf=mlup.Config())up=mlup.UP(conf=mlup.Config(# Set your config, for work model and get model.# You can use storage_type and storage_kwargs for auto_load model from storage.))up.ml.load()up.web.load()# If you want to run the application yourself, or add something else to it, use this variable.# Example with uvicorn: uvicorn example_app:app --host 0.0.0.0 --port 80app=up.web.appif__name__=='__main__':up.run_web_app()And you can write your settings and run web application:python3example_without_data_app.pyWith only modelmlupmake-app-ms/path/to/my/model.onnxexample_without_data_app.pyThis command is making something like this:# example_without_data_app.pyimportmlupfrommlupimportconstantsup=mlup.UP(conf=mlup.Config(# Set your config, for work model and get model.storage_type=constants.StorageType.disk,storage_kwargs={'path_to_files':'/path/to/my/model.onnx','files_mask':'model.onnx',},))up.ml.load()up.web.load()# If you want to run the application yourself, or add something else to it, use this variable.# Example with uvicorn: uvicorn example_app:app --host 0.0.0.0 --port 80app=up.web.appif__name__=='__main__':up.run_web_app()And you can run web application:python3example_without_data_app.pyWith only configmlupmake-app-cs/path/to/my/config.yamlexample_without_data_app.pyThis command is making something like this:# example_without_data_app.pyimportmlupup=mlup.UP.load_from_yaml('/path/to/my/config.yaml',load_model=False)up.ml.load()up.web.load()# If you want to run the application yourself, or add something else to it, use this variable.# Example with uvicorn: uvicorn example_app:app --host 0.0.0.0 --port 80app=up.web.appif__name__=='__main__':up.run_web_app()And you can run web application:python3example_without_data_app.pyWith only binary UP objectmlupmake-app-bs/path/to/my/up.pickleexample_without_data_app.pyThis command is making something like this:# example_without_data_app.pyimportpicklewithopen('/path/to/my/up.pickle','rb')asf:up=pickle.load(f)ifnotup.ml.loaded:up.ml.load()up.web.load()# If you want to run the application yourself, or add something else to it, use this variable.# Example with uvicorn: uvicorn example_app:app --host 0.0.0.0 --port 80app=up.web.appif__name__=='__main__':up.run_web_app()And you can run web application:python3example_without_data_app.pymlup validate-configThis command use for validation your config. This command have alpha version and need finalize.Seemlup validate-config --helporDescription of the bash commandsfor full docs.mlupvalidate-config/path/to/my/conf.yamlWeb application interfaceBy default, web application starting onhttp://localhost:8009and have api docs.SeeWeb app APIfor more details.Interactive API docsNow go tohttp://localhost:8009/docs.You will see the automatic interactive API documentation (provided bySwagger UI):Api points/healthUse for check health web application.HTTP's methods: HEAD, OPTIONS, GETReturn JSON{'status': 200}and status code is 200./infoUse for get model and application information. If set debug=True in config, return full config.HTTP's methods: GETReturn JSON:{"model_info":{"name":"MyFirstMLupModel","version":"1.0.0.0","type":"sklearn","columns":null},"web_app_info":{"version":"1.0.0.0",}}If set in configdebug=True, return another json, almost complete config. But no sensitive data.{"web_app_config":{"host":"localhost","port":8009,"web_app_version":"1.0.0.0","column_validation":false,"custom_column_pydantic_model":null,"mode":"mlup.web.architecture.directly_to_predict.DirectlyToPredictArchitecture","max_queue_size":100,"ttl_predicted_data":60,"ttl_client_wait":30.0,"min_batch_len":10,"batch_worker_timeout":1.0,"is_long_predict":false,"show_docs":true,"debug":true,"throttling_max_requests":null,"throttling_max_request_len":null,"timeout_for_shutdown_daemon":3.0,"item_id_col_name":"mlup_item_id"},"model_config":{"name":"MyFirstMLupModel","version":"1.0.0.0","type":"sklearn","columns":null,"predict_method_name":"predict","auto_detect_predict_params":true,"storage_type":"mlup.ml.storage.memory.MemoryStorage","binarization_type":"auto","use_thread_loop":true,"max_thread_loop_workers":true,"data_transformer_for_predict":"mlup.ml.data_transformers.numpy_data_transformer.NumpyDataTransformer","data_transformer_for_predicted":"mlup.ml.data_transformers.numpy_data_transformer.NumpyDataTransformer","dtype_for_predict":null}}/predictUse for call predict in model.HTTP's methods: POSTRequests body data:{"data_for_predict":["input_data_for_obj_1","input_data_for_obj_2","input_data_for_obj_3"]}Keydata_for_predictis default key for inner data. In config by default set paramauto_detect_predict_paramsis True.
This param activate analyze model predict method, get arguments from and generate API by params.
Ifauto_detect_predict_paramsfound params, he changesdata_for_predictto finding keys and change API docs.Example forscikit-learnmodels:{"X":["input_data_for_obj_1","input_data_for_obj_2","input_data_for_obj_3"]}input_data_for_obj_1maybe any valid JSON data. These data are run through data transformers from configdata_transformer_for_predict.By default, this param ismlup.ml.data_transformers.numpy_data_transformer.NumpyDataTransformer.Return JSON:{"predict_result":["predict_result_for_obj_1","predict_result_for_obj_2","predict_result_for_obj_3"]}predict_result_for_obj_1will be valid JSON data. These data, after being predicted by the model, are run through data transformers from configdata_transformer_for_predicted.By default, this param ismlup.ml.data_transformers.numpy_data_transformer.NumpyDataTransformer.ValidationThis method have validation for inner request data. It's making from configcolumnsand flagcolumn_validation.Web application modesSeeWeb app architecturesfor more details.Web application have three works modes:directly_to_predict- is Default. User request send directly to model.worker_and_queue- ml model starts in thread worker and take data for predict from queue.
Web application new user requests send to queue and wait result from results queue.batching- ml model start in thread worker and take data for predict from queue.
But not for one request, but combines data from several requests and sends it in one large array to the model.
Web application new user requests send to queue and wait result from results queue.This param is namingmode.importmlupfrommlup.ml.emptyimportEmptyModelfrommlupimportconstantsup=mlup.UP(ml_model=EmptyModel(),conf=mlup.Config(mode=constants.WebAppArchitecture.worker_and_queue,))If your model is light, or you hae many CPU/GPU/RAM, you can run many processes:importmlupfrommlup.ml.emptyimportEmptyModelfrommlupimportconstantsup=mlup.UP(ml_model=EmptyModel(),conf=mlup.Config(mode=constants.WebAppArchitecture.worker_and_queue,uvicorn_kwargs={'workers':4},))MetricsMLup PyPi download statistics:https://pepy.tech/project/pymlup