From 63a45989f4992c105e9f9902b459410de6cab4fd Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 9 Jul 2022 23:10:21 +0200 Subject: [PATCH] Improve documentation --- .vscode/tasks.json | 4 +- README.md | 16 +- docs/README.md | 16 - docs/explanation.md | 7 + docs/great_ai_example-main/.dockerignore | 6 - docs/great_ai_example-main/.gitignore | 10 - .../.vscode/settings.json | 10 - docs/great_ai_example-main/.vscode/tasks.json | 21 -- docs/great_ai_example-main/Dockerfile | 11 - docs/great_ai_example-main/README.md | 23 -- docs/great_ai_example-main/format.sh | 31 -- docs/great_ai_example-main/requirements.txt | 4 - docs/great_ai_example-main/src/mongo.ini | 2 - .../index.md} | 0 docs/how-to-guides/scraping.ipynb | 29 ++ docs/ideas.drawio | 230 ------------- docs/index.md | 45 +-- docs/media/favicon.ico | Bin 0 -> 15086 bytes docs/media/logo.png | Bin 0 -> 86546 bytes docs/{ => media}/scope-data.drawio.svg | 40 +-- .../diagrams => media}/scope-data.svg | 0 .../diagrams => media}/scope-deploy.svg | 0 docs/{ => media}/scope-simple.drawio.svg | 0 .../diagrams => media}/scope-train.svg | 0 .../diagrams => media}/scope.svg | 0 docs/media/scoutinscience-white.svg | 122 +++++++ docs/media/scoutinscience.svg | 121 +++++++ .../src => simple}/data.ipynb | 0 .../src => simple}/deploy.ipynb | 5 +- .../src => simple}/train.ipynb | 0 .../{simple-mag/mag => tutorial/data}/dev.txt | 0 .../mag => tutorial/data}/test.txt | 0 .../mag => tutorial/data}/train.txt | 0 docs/tutorial/deploy.ipynb | 214 ++++++++++++ docs/tutorial/index.md | 70 ++++ docs/tutorial/train.ipynb | 318 ++++++++++++++++++ docs/tutorials.md | 0 mkdocs.yaml | 19 +- .../large_file/data}/example_secrets.ini | 0 tests/large_file/test_large_file.py | 2 +- 40 files changed, 956 insertions(+), 420 deletions(-) delete mode 100644 docs/README.md delete mode 100644 docs/great_ai_example-main/.dockerignore delete mode 100644 docs/great_ai_example-main/.gitignore delete mode 100644 docs/great_ai_example-main/.vscode/settings.json delete mode 100644 docs/great_ai_example-main/.vscode/tasks.json delete mode 100644 docs/great_ai_example-main/Dockerfile delete mode 100644 docs/great_ai_example-main/README.md delete mode 100755 docs/great_ai_example-main/format.sh delete mode 100644 docs/great_ai_example-main/requirements.txt delete mode 100644 docs/great_ai_example-main/src/mongo.ini rename docs/{how-to-guides.md => how-to-guides/index.md} (100%) create mode 100644 docs/how-to-guides/scraping.ipynb delete mode 100644 docs/ideas.drawio create mode 100644 docs/media/favicon.ico create mode 100644 docs/media/logo.png rename docs/{ => media}/scope-data.drawio.svg (83%) rename docs/{great_ai_example-main/diagrams => media}/scope-data.svg (100%) rename docs/{great_ai_example-main/diagrams => media}/scope-deploy.svg (100%) rename docs/{ => media}/scope-simple.drawio.svg (100%) rename docs/{great_ai_example-main/diagrams => media}/scope-train.svg (100%) rename docs/{great_ai_example-main/diagrams => media}/scope.svg (100%) create mode 100644 docs/media/scoutinscience-white.svg create mode 100644 docs/media/scoutinscience.svg rename docs/{great_ai_example-main/src => simple}/data.ipynb (100%) rename docs/{great_ai_example-main/src => simple}/deploy.ipynb (99%) rename docs/{great_ai_example-main/src => simple}/train.ipynb (100%) rename docs/{simple-mag/mag => tutorial/data}/dev.txt (100%) rename docs/{simple-mag/mag => tutorial/data}/test.txt (100%) rename docs/{simple-mag/mag => tutorial/data}/train.txt (100%) create mode 100644 docs/tutorial/deploy.ipynb create mode 100644 docs/tutorial/index.md create mode 100644 docs/tutorial/train.ipynb delete mode 100644 docs/tutorials.md rename {docs => tests/large_file/data}/example_secrets.ini (100%) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f22140e..c6db301 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,9 +4,9 @@ { "label": "Format and lint", "type": "shell", - "command": "source .env/bin/activate && scripts/format-python.sh great_ai tests", + "command": "source .env/bin/activate && scripts/format-python.sh great_ai docs tests", "windows": { - "command": ".env\\bin\\activate.bat; scripts\\format-python.sh great_ai tests" + "command": ".env\\bin\\activate.bat; scripts\\format-python.sh great_ai docs tests" }, "group": "test", "presentation": { diff --git a/README.md b/README.md index 8d77a36..6f4a8b0 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ -# GreatAI +# ![logo](docs/media/favicon.ico) GreatAI + + > GreatAI helps you easily transform your prototype AI code into production-ready software. -**work in progress, do not use!** - -[![Test](https://github.com/schmelczer/great-ai/actions/workflows/test.yml/badge.svg)](https://github.com/schmelczer/great-ai/actions/workflows/check.yml) +[![Test](https://github.com/schmelczer/great-ai/actions/workflows/test.yml/badge.svg)](https://github.com/schmelczer/great-ai/actions/workflows/test.yml) [![Quality Gate Status](https://sonar.scoutinscience.com/api/project_badges/measure?project=great-ai&metric=alert_status)](https://sonar.schmelczer.com/dashboard?id=great-ai) [![Publish on PyPI](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml/badge.svg)](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml) [![Publish on DockerHub](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml/badge.svg)](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml) [![Downloads](https://pepy.tech/badge/great-ai/month)](https://pepy.tech/project/great-ai) +[Check out the documentation here](https://great-ai.scoutinscience.com/). + ## Find `great-ai` on [DockerHub](https://hub.docker.com/repository/docker/schmelczera/great-ai) @@ -33,8 +35,10 @@ def hello_world(name: str) -> str: ``` > Create a new file called `main.py` -Deploy by executing `python3 -m great-ai main.py` -> Or: `python3 -m great-ai main.py` +Deploy by executing `great-ai main.py` +> Or: `great_ai main.py` + +> Or: `python3 -m great_ai main.py` Find the dashboard at [http://localhost:6060](http://localhost:6060/dashboard/). diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 2ef2e77..0000000 --- a/docs/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# **S**coutinScience **U**tilitie**S** for text processing [![Lint and test ScoutinScience utilities](https://github.com/ScoutinScience/platform/actions/workflows/sus-general.yaml/badge.svg)](https://github.com/ScoutinScience/platform/actions/workflows/sus-general.yaml) - -## Exports - -- [clean](src/sus/clean.py) -- [language](src/sus/clean.py) -- [unique](src/sus/unique.py) -- [parallel_map](src/sus/parallel_map.py) -- [evaluate_ranking](src/sus/evaluate_ranking/evaluate_ranking.py) -- [get_sentences](src/sus/get_sentences.py) - -## Development - -- Optional booleans must have a default value of `False`. -- No imports in top-level `__init__.py`, in order to not load anything unnecessary automatically -- Should only be updated through a PR diff --git a/docs/explanation.md b/docs/explanation.md index e69de29..5f30f0a 100644 --- a/docs/explanation.md +++ b/docs/explanation.md @@ -0,0 +1,7 @@ +# Explanation + +A lot more details and discussion about the problem context and approaches of GreatAI can be found in my thesis. + +
+[::fontawesome-solid-graduation-cap: Download](thesis/main.py){ .md-button .md-button--primary } +
diff --git a/docs/great_ai_example-main/.dockerignore b/docs/great_ai_example-main/.dockerignore deleted file mode 100644 index ccbef6a..0000000 --- a/docs/great_ai_example-main/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -.venv -.env -**/.cache -.git -**/__pycache__ -.dockerignore diff --git a/docs/great_ai_example-main/.gitignore b/docs/great_ai_example-main/.gitignore deleted file mode 100644 index cdadf66..0000000 --- a/docs/great_ai_example-main/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.env -.venv -.DS_Store -__pycache__ -.cache -.mypy_cache -.pytest_cache -**/.ipynb_checkpoints -**/tracing_database.json -*.egg-info diff --git a/docs/great_ai_example-main/.vscode/settings.json b/docs/great_ai_example-main/.vscode/settings.json deleted file mode 100644 index 9a47044..0000000 --- a/docs/great_ai_example-main/.vscode/settings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "files.exclude": { - "**/__pycache__": true, - "**/.ipynb_checkpoints": true, - "**/.mypy_cache": true, - "**/.pytest_cache": true - }, - "notebook.output.textLineLimit": 400, - "python.defaultInterpreterPath": ".env/bin/python" -} diff --git a/docs/great_ai_example-main/.vscode/tasks.json b/docs/great_ai_example-main/.vscode/tasks.json deleted file mode 100644 index 17c41ee..0000000 --- a/docs/great_ai_example-main/.vscode/tasks.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Format and lint", - "type": "shell", - "command": "source .env/bin/activate; ./format.sh .", - "windows": { - "command": ".env\\bin\\activate.bat; .\\format.sh ." - }, - "group": "test", - "presentation": { - "reveal": "always", - "panel": "new" - }, - "options": { - "cwd": "${workspaceFolder}" - } - } - ] -} diff --git a/docs/great_ai_example-main/Dockerfile b/docs/great_ai_example-main/Dockerfile deleted file mode 100644 index bd5c6cc..0000000 --- a/docs/great_ai_example-main/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM test - -COPY requirements.txt . -RUN pip install --no-cache-dir ./great_ai - -COPY mongo.ini . -COPY deploy.ipynb . - -# RUN python3 -m large_file --backend s3 -secrets ~/.aws/credentials --cache my_first_file.json:3 my_second_file my_folder:0 - -CMD ["deploy.ipynb"] diff --git a/docs/great_ai_example-main/README.md b/docs/great_ai_example-main/README.md deleted file mode 100644 index d52e649..0000000 --- a/docs/great_ai_example-main/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Train a domain classifier on the [semantic scholar dataset](https://api.semanticscholar.org/corpus) - -![steps](diagrams/scope.svg) - -## Install - -### System dependencies - -Make sure you have `python3`, `pip`, and `venv` installed. -> On Ubuntu, execute: `sudo apt install -y python3 python3-pip python3-venv` - -### Install dependencies -```sh -python3 -m venv --copies .env -source .env/bin/activate - -pip install -r requirements.txt -``` -## Execute - -- [Part 1](src/data.ipynb) -- [Part 2](src/train.ipynb) -- [Part 3](src/deploy.ipynb) diff --git a/docs/great_ai_example-main/format.sh b/docs/great_ai_example-main/format.sh deleted file mode 100755 index 737a2b9..0000000 --- a/docs/great_ai_example-main/format.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -set -e - -echo "Installing dependencies if necessary" -python3 -m pip install --upgrade autoflake isort black[jupyter] mypy flake8 - -echo "Formatting and checking $1" - -cd $1 - -echo Running autoflake -python3 -m autoflake --expand-star-imports --remove-all-unused-imports --ignore-init-module-imports --remove-unused-variables --in-place -r . - -echo Running isort -python3 -m isort --profile black --skip .env . - -echo Running black -python3 -m black . --exclude .env - -if ls *.py 1> /dev/null 2>&1; then - echo Running mypy - python3 -m mypy --namespace-packages --ignore-missing-imports --install-types --non-interactive --disallow-untyped-defs --disallow-incomplete-defs --pretty --follow-imports=silent --exclude=external/ --exclude=/build/ . -fi - -echo Running Flake8 -python3 -m flake8 . --count --show-source --statistics --exclude=__init__.py,.env,external --ignore=E501,E722,E402,W503,E203 - -cd - - -echo "Finished formatting" diff --git a/docs/great_ai_example-main/requirements.txt b/docs/great_ai_example-main/requirements.txt deleted file mode 100644 index dfcc2e6..0000000 --- a/docs/great_ai_example-main/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -great_ai -notebook -nbformat -nbconvert \ No newline at end of file diff --git a/docs/great_ai_example-main/src/mongo.ini b/docs/great_ai_example-main/src/mongo.ini deleted file mode 100644 index 8d22e1c..0000000 --- a/docs/great_ai_example-main/src/mongo.ini +++ /dev/null @@ -1,2 +0,0 @@ -mongo_connection_string=mongodb://localhost:27017/ # change this -mongo_database=great_ai_example # this will be automatically created diff --git a/docs/how-to-guides.md b/docs/how-to-guides/index.md similarity index 100% rename from docs/how-to-guides.md rename to docs/how-to-guides/index.md diff --git a/docs/how-to-guides/scraping.ipynb b/docs/how-to-guides/scraping.ipynb new file mode 100644 index 0000000..54f0992 --- /dev/null +++ b/docs/how-to-guides/scraping.ipynb @@ -0,0 +1,29 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import httpx\n", + "\n", + "transport = httpx.AsyncHTTPTransport(retries=2)\n", + "limits = httpx.Limits(max_connections=None)\n", + "timeout = httpx.Timeout(connect=60.0, read=300, write=60, pool=None)\n", + "async with httpx.AsyncClient(\n", + " transport=transport, limits=limits, timeout=timeout\n", + ") as client:\n", + " pass" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/ideas.drawio b/docs/ideas.drawio deleted file mode 100644 index 380b835..0000000 --- a/docs/ideas.drawio +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 2fb1815..d24e689 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,29 +1,30 @@ -# Overview of GreatAI +
+

Overview of GreatAI

+ +
+ [![Test](https://github.com/schmelczer/great-ai/actions/workflows/test.yml/badge.svg)](https://github.com/schmelczer/great-ai/actions/workflows/check.yml) [![Quality Gate Status](https://sonar.scoutinscience.com/api/project_badges/measure?project=great-ai&metric=alert_status)](https://sonar.schmelczer.com/dashboard?id=great-ai) [![Publish on PyPI](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml/badge.svg)](https://github.com/schmelczer/great-ai/actions/workflows/publish.yaml) [![Publish on DockerHub](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml/badge.svg)](https://github.com/schmelczer/great-ai/actions/workflows/docker.yaml) [![Downloads](https://pepy.tech/badge/great-ai/month)](https://pepy.tech/project/great-ai) - Applying AI is becoming increasingly easier but many case studies have shown that these applications are often deployed poorly. This may lead to suboptimal performance and to introducing [unintended biases](https://en.wikipedia.org/wiki/Weapons_of_Math_Destruction){ target=_blank }. To extend the list of available solutions, ==GreatAI helps you easily transform your prototype AI code into production-ready software.== ??? quote "Case studies" "There is a need to consider and adapt well established SE practices which have been ignored or had a very narrow focus in ML literature." - — [John et al.](https://ieeexplore.ieee.org/abstract/document/9359253) + — [John et al.](https://ieeexplore.ieee.org/abstract/document/9359253){ target=_blank } - "Finally, we have found that existing tools to aid Machine Learning development do not address the specificities of different projects, and thus, are seldom adopted by teams." — [Haakman et al.](https://link.springer.com/article/10.1007/s10664-021-09993-1) - - "Because a mature system might end up being (at most) 5% machine learning code and (at least) 95% glue code, it may be less costly to create a clean native solution rather than re-use a generic package." — [Sculley et al.](https://www.researchgate.net/profile/Todd-Phillips/publication/319769912_Hidden_Technical_Debt_in_Machine_Learning_Systems/links/61e716d68d338833e37a7fd6/Hidden-Technical-Debt-in-Machine-Learning-Systems.pdf) - - "For example, practice 25 is very important for “Traceability", yet relatively weakly adopted. We expect that the results from this type of analysis can, in the future, provide useful guidance for practitioners in terms of aiding them to assess their rate of adoption for each practice and to create roadmaps for improving their processes. — [Serban et al.](https://dl.acm.org/doi/abs/10.1145/3382494.3410681?casa_token=uCFz0dtDR6gAAAAA:4_8OMJ-5njwopYkB1KSGAu9JfbNq4nfa8LRE0fj84ckjfo-GgtcYQivZTGxal3M4haoA8r_xwpw) + "Finally, we have found that existing tools to aid Machine Learning development do not address the specificities of different projects, and thus, are seldom adopted by teams." — [Haakman et al.](https://link.springer.com/article/10.1007/s10664-021-09993-1){ target=_blank } + "Because a mature system might end up being (at most) 5% machine learning code and (at least) 95% glue code, it may be less costly to create a clean native solution rather than re-use a generic package." — [Sculley et al.](https://www.researchgate.net/profile/Todd-Phillips/publication/319769912_Hidden_Technical_Debt_in_Machine_Learning_Systems/links/61e716d68d338833e37a7fd6/Hidden-Technical-Debt-in-Machine-Learning-Systems.pdf){ target=_blank } + "For example, practice 25 is very important for “Traceability", yet relatively weakly adopted. We expect that the results from this type of analysis can, in the future, provide useful guidance for practitioners in terms of aiding them to assess their rate of adoption for each practice and to create roadmaps for improving their processes. — [Serban et al.](https://dl.acm.org/doi/abs/10.1145/3382494.3410681?casa_token=uCFz0dtDR6gAAAAA:4_8OMJ-5njwopYkB1KSGAu9JfbNq4nfa8LRE0fj84ckjfo-GgtcYQivZTGxal3M4haoA8r_xwpw){ target=_blank } ## Features - [x] Save prediction traces of each prediction including arguments and model versions -- [x] Save feedback and merge it into a ground-truth database +- [x] Save feedback and merge it into a ground-truth database *:arrow_right: quasi-shadow deployment* - [x] Version and store models and data on shared infrastructure *(MongoDB GridFS, S3-compatible storage, shared local-volume)* - [x] Automatically scaffolded custom REST API (and OpenAPI schema) for easy integration - [x] Input validation @@ -33,11 +34,11 @@ Applying AI is becoming increasingly easier but many case studies have shown tha - [x] Built-in parallelisation (with support for multiprocessing, async, and mixed modes) for batch processing - [x] Well-tested utilities for common NLP tasks (cleaning, language-tagging, sentence-segmentation, etc.) - [x] A simple, unified configuration interface -- [x] Fully-typed API for IntelliSense support +- [x] Fully-typed API for [Pylance](https://github.com/microsoft/pylance-release){ target=_blank } and [MyPy](http://mypy-lang.org){ target=_blank } support - [x] Auto-reload for development +- [x] Deployable Jupyter Notebooks - [x] Docker support for deployment - [x] Dashboard for high-level overview and searching traces -- [ ] Shadow deployment ## Hello world @@ -66,7 +67,7 @@ def hello_world(name: str) -> str: #(2) ```sh title="terminal" great-ai hello-world.py ``` -> Navigate to [localhost:6060](http://127.0.0.1:6060/) in your browser. +> Navigate to [localhost:6060](http://127.0.0.1:6060) in your browser.
![](media/hello-world-dashboard.png){ loading=lazy } @@ -75,14 +76,13 @@ great-ai hello-world.py
!!! success - Your GreatAI service is ready for production use. Many of the [SE4ML best-practices](https://se-ml.github.io/){ target=_blank } are configured and implemented automatically. To have full control over your service and to understand what else you might need to do in your use case, continue reading this documentation. - + Your GreatAI service is ready for production use. Many of the [SE4ML best-practices](https://se-ml.github.io){ target=_blank } are configured and implemented automatically. To have full control over your service and to understand what else you might need to do in your use case, continue reading this documentation. ## Why is this GREAT? -![scope of GreatAI](scope-simple.drawio.svg) +![scope of GreatAI](media/scope-simple.drawio.svg) -GreatAI fits between the prototype and deployment phase of your (or your organisation's) AI development lifecycle. This is highlighted with blue in the diagram. Here, a number of best practices can be automatically implemented concerning the following 5 aspects: +GreatAI fits between the prototype and deployment phase of your (or your organisation's) AI development lifecycle. This is highlighted with blue in the diagram. Here, a number of best practices can be automatically implemented aiming to achieve the following attributes: - **G**eneral: use any Python library without restriction - **R**obust: have error-handling and well-tested utilities out-of-the-box @@ -92,13 +92,20 @@ GreatAI fits between the prototype and deployment phase of your (or your organis ## Why GreatAI? -There are other, existing solutions aiming to facilitate this phase. [Amazon SageMaker](https://aws.amazon.com/sagemaker/){ target=_blank } and [Seldon Core](https://www.seldon.io/solutions/open-source-projects/core){ target=_blank } provide the most comprehensive suite of features. If you have the opportunity use those, do that because they're great. +There are other, existing solutions aiming to facilitate this phase. [Amazon SageMaker](https://aws.amazon.com/sagemaker){ target=_blank } and [Seldon Core](https://www.seldon.io/solutions/open-source-projects/core){ target=_blank } provide the most comprehensive suite of features. If you have the opportunity use those, do that because they're great. -However, research indicates that professionals rarely use them. This may be due to their inherent setup and operating complexity. GreatAI is designed to be as simple to use as possible. Its clear, high-level API and sensible default configuration makes it extremely easy to start using. Despite its relative simplicity over Seldon Core, it still implements many [best-practices](https://se-ml.github.io/){ target=_blank }, and thus, can meaningfully improve your deployment without requiring prohibitively large effort. +However, research indicates that professionals rarely use them. This may be due to their inherent setup and operating complexity. GreatAI is designed to be as simple to use as possible. Its clear, high-level API and sensible default configuration makes it extremely easy to start using. Despite its relative simplicity over Seldon Core, it still implements many [best-practices](https://se-ml.github.io){ target=_blank }, and thus, can meaningfully improve your deployment without requiring prohibitively large effort.
-[:fontawesome-brands-python: Find it on PyPI](https://pypi.org/project/great-ai/){ .md-button .md-button--primary } +[:fontawesome-brands-python: Find it on PyPI](https://pypi.org/project/great-ai){ .md-button .md-button--primary } [:fontawesome-brands-docker: Find it on DockerHub](https://hub.docker.com/repository/docker/schmelczera/great-ai){ .md-button .md-button--primary }
+ +## Production use + +GreatAI has been battle-tested on the core platform services of [ScoutinScience](https://www.scoutinscience.com/){ target=_blank }. + +![ScoutinScience logo](media/scoutinscience.svg#only-light) +![ScoutinScience logo](media/scoutinscience-white.svg#only-dark) diff --git a/docs/media/favicon.ico b/docs/media/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d0a6efaa4ed5420e95bebddee850f3ab1111949d GIT binary patch literal 15086 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 + @@ -18,7 +18,7 @@ - + Preprocessed data @@ -50,13 +50,13 @@ - +
-
-
+
+
Exploration & @@ -70,21 +70,21 @@
- + Exploration &... - - + +
-
-
+
+
Trained models  & prototype inference code @@ -92,7 +92,7 @@
- + Trained models  & protot... @@ -151,13 +151,13 @@ - +
-
-
+
+
Transforming into
@@ -169,7 +169,7 @@
- + Transforming into... @@ -178,14 +178,14 @@ - - + +
-
-
+
+
Artifact combining the model with deplyoment best-practices @@ -193,7 +193,7 @@
- + Artifact combining the mod... diff --git a/docs/great_ai_example-main/diagrams/scope-data.svg b/docs/media/scope-data.svg similarity index 100% rename from docs/great_ai_example-main/diagrams/scope-data.svg rename to docs/media/scope-data.svg diff --git a/docs/great_ai_example-main/diagrams/scope-deploy.svg b/docs/media/scope-deploy.svg similarity index 100% rename from docs/great_ai_example-main/diagrams/scope-deploy.svg rename to docs/media/scope-deploy.svg diff --git a/docs/scope-simple.drawio.svg b/docs/media/scope-simple.drawio.svg similarity index 100% rename from docs/scope-simple.drawio.svg rename to docs/media/scope-simple.drawio.svg diff --git a/docs/great_ai_example-main/diagrams/scope-train.svg b/docs/media/scope-train.svg similarity index 100% rename from docs/great_ai_example-main/diagrams/scope-train.svg rename to docs/media/scope-train.svg diff --git a/docs/great_ai_example-main/diagrams/scope.svg b/docs/media/scope.svg similarity index 100% rename from docs/great_ai_example-main/diagrams/scope.svg rename to docs/media/scope.svg diff --git a/docs/media/scoutinscience-white.svg b/docs/media/scoutinscience-white.svg new file mode 100644 index 0000000..626ed27 --- /dev/null +++ b/docs/media/scoutinscience-white.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/media/scoutinscience.svg b/docs/media/scoutinscience.svg new file mode 100644 index 0000000..2f40d52 --- /dev/null +++ b/docs/media/scoutinscience.svg @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/great_ai_example-main/src/data.ipynb b/docs/simple/data.ipynb similarity index 100% rename from docs/great_ai_example-main/src/data.ipynb rename to docs/simple/data.ipynb diff --git a/docs/great_ai_example-main/src/deploy.ipynb b/docs/simple/deploy.ipynb similarity index 99% rename from docs/great_ai_example-main/src/deploy.ipynb rename to docs/simple/deploy.ipynb index a8acbfe..c2972fa 100644 --- a/docs/great_ai_example-main/src/deploy.ipynb +++ b/docs/simple/deploy.ipynb @@ -185,7 +185,10 @@ " X = [d.input for d in data]\n", " y_actual = [d.feedback for d in data]\n", "\n", - " y_predicted = [d.output.labels[0].label for d in predict_domain.process_batch(X, do_not_persist_traces=True)]\n", + " y_predicted = [\n", + " d.output.labels[0].label\n", + " for d in predict_domain.process_batch(X, do_not_persist_traces=True)\n", + " ]\n", " y_actual_aligned = [p if p in a else a[0] for p, a in zip(y_predicted, y_actual)]\n", "\n", " import matplotlib.pyplot as plt\n", diff --git a/docs/great_ai_example-main/src/train.ipynb b/docs/simple/train.ipynb similarity index 100% rename from docs/great_ai_example-main/src/train.ipynb rename to docs/simple/train.ipynb diff --git a/docs/simple-mag/mag/dev.txt b/docs/tutorial/data/dev.txt similarity index 100% rename from docs/simple-mag/mag/dev.txt rename to docs/tutorial/data/dev.txt diff --git a/docs/simple-mag/mag/test.txt b/docs/tutorial/data/test.txt similarity index 100% rename from docs/simple-mag/mag/test.txt rename to docs/tutorial/data/test.txt diff --git a/docs/simple-mag/mag/train.txt b/docs/tutorial/data/train.txt similarity index 100% rename from docs/simple-mag/mag/train.txt rename to docs/tutorial/data/train.txt diff --git a/docs/tutorial/deploy.ipynb b/docs/tutorial/deploy.ipynb new file mode 100644 index 0000000..010add1 --- /dev/null +++ b/docs/tutorial/deploy.ipynb @@ -0,0 +1,214 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Harden and deploy your app\n", + "\n", + "Finally, it's time to deploy your model. But before you have to make sure you follow AI deployment [best-practices](https://se-ml.github.io/). In the past, this step was too often either the source of unexpected struggles, or worse, simply ignored.\n", + "\n", + "With `GreatAI`, it has become a matter of 2 lines of code." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[38;5;226m2022-07-09 22:38:56 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:38:56 | WARNING | Cannot find credentials files, defaulting to using ParallelTinyDbDriver\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:38:56 | WARNING | The selected tracing database (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:38:56 | WARNING | Cannot find credentials files, defaulting to using LargeFileLocal\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | GreatAI (v0.1.0): configured ✅\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | 🔩 tracing_database: ParallelTinyDbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | 🔩 large_file_implementation: LargeFileLocal\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | 🔩 is_production: False\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | 🔩 should_log_exception_stack: True\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | 🔩 prediction_cache_size: 512\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | 🔩 dashboard_table_size: 20\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:38:56 | WARNING | You still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:38:56 | WARNING | > Find out more at https://se-ml.github.io/practices\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | Fetching cached versions of my-domain-predictor\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | Latest version of my-domain-predictor is 5 (from versions: 0, 1, 2, 3, 4, 5)\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:56 | INFO | File my-domain-predictor-5 found in cache\u001b[0m\n" + ] + } + ], + "source": [ + "from great_ai import GreatAI, use_model\n", + "from great_ai.utilities import clean\n", + "\n", + "\n", + "@GreatAI.create\n", + "@use_model(\"my-domain-predictor\")\n", + "def predict_domain(sentence, model):\n", + " inputs = [clean(sentence)]\n", + " return str(model.predict(inputs)[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Trace[str]({ 'created': '2022-07-09T20:38:56.394746',\n", + " 'exception': None,\n", + " 'feedback': None,\n", + " 'logged_values': { 'arg:sentence:length': 29,\n", + " 'arg:sentence:value': 'Mountains are just big rocks.'},\n", + " 'models': [{'key': 'my-domain-predictor', 'version': 5}],\n", + " 'original_execution_time_ms': 4.999,\n", + " 'output': 'geography',\n", + " 'tags': ['predict_domain', 'online', 'development'],\n", + " 'trace_id': 'aad1f83d-a81f-4b8b-898e-d02f8076616f'})" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "predict_domain(\"Mountains are just big rocks.\")\n", + "# the original return value is under the 'output' key" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[38;5;39m2022-07-09 22:38:58 | INFO | Converting notebook to Python script\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:58 | INFO | Found `predict_domain` to be the GreatAI app \u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:38:58 | INFO | Uvicorn running on http://0.0.0.0:6060 (Press CTRL+C to quit)\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:39:00 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:39:00 | WARNING | Cannot find credentials files, defaulting to using ParallelTinyDbDriver\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:39:00 | WARNING | The selected tracing database (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:39:00 | WARNING | Cannot find credentials files, defaulting to using LargeFileLocal\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | GreatAI (v0.1.0): configured ✅\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | 🔩 tracing_database: ParallelTinyDbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | 🔩 large_file_implementation: LargeFileLocal\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | 🔩 is_production: False\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | 🔩 should_log_exception_stack: True\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | 🔩 prediction_cache_size: 512\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | 🔩 dashboard_table_size: 20\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:39:00 | WARNING | You still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:39:00 | WARNING | > Find out more at https://se-ml.github.io/practices\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | Fetching cached versions of my-domain-predictor\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | Latest version of my-domain-predictor is 5 (from versions: 0, 1, 2, 3, 4, 5)\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | File my-domain-predictor-5 found in cache\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | Started server process [882179]\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | Waiting for application startup.\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:00 | INFO | Application startup complete.\u001b[0m\n", + "^C\n", + "\u001b[38;5;39m2022-07-09 22:39:04 | INFO | Shutting down\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:04 | INFO | Waiting for application shutdown.\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:04 | INFO | Application shutdown complete.\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:39:04 | INFO | Finished server process [882179]\u001b[0m\n" + ] + } + ], + "source": [ + "!great-ai deploy.ipynb\n", + "# leave this running and open http://127.0.0.1:6060" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that you've made sure your application is hardened enough for the intended use case, it is time to deploy it. The responsibilities of GreatAI end when it wraps your inference function and model into a production-ready service. You're given the freedom and responsibility to deploy this service. Fortunately, you (or your organisation) probably already has an established routine for deploying services.\n", + "\n", + "There are three main approaches to deploy a GreatAI service.\n", + "\n", + "### Manual deployment\n", + "\n", + "Simply run `ENVIRONMENT=production great-ai deploy.ipynb` in the command-line of a production machine.\n", + "> This is the crudest approach, however, it might be fitting for some contexts.\n", + "\n", + "### Containerised deployment\n", + "\n", + "Run the notebook directly in a container or create a service for it using your favourite orchestrator.\n", + "\n", + "```sh\n", + "docker run \\\n", + " -p 6060:6060 \\\n", + " --volume `pwd`:/app \\\n", + " --rm \\\n", + " schmelczera/great-ai deploy.ipynb\n", + "```\n", + "> You can replace ``pwd`` with the path to your code's folder.\n", + "\n", + "#### Use a Platform-as-a-Service\n", + "\n", + "Similarly to the previous approach, your code will run in a container. However, instead of manually managing it, you can just choose from a plethora of PaaS providers that take a Docker image as a source and handle the rest of the deployment.\n", + "\n", + "To this end, you can also create a custom Docker image. It is especially useful if you have third-party dependencies, such as pytorch or tensorflow.\n", + "\n", + "```Dockerfile\n", + "FROM schmelczera/great-ai:latest\n", + "\n", + "# Remove this block if you don't have a requirements.txt\n", + "COPY requirements.txt ./ \n", + "RUN pip install --no-cache-dir --requirement requirements.txt\n", + "\n", + "# If you store your models in S3 or GridFS, it may be a \n", + "# good idea to # cache them in the image so that you don't\n", + "# have to download it each time a container starts\n", + "# RUN large-file --backend s3 --secrets s3.ini --cache my-domain-predictor\n", + "\n", + "COPY . .\n", + "\n", + "CMD [\"deploy.ipynb\"]\n", + "\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### [Go back to the summary](/tutorial)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.4 ('.env': venv)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "02dd6d3afbfa9fbbe1037d64ad9014965528a1ccad21929d6e72f466389a68ad" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/tutorial/index.md b/docs/tutorial/index.md new file mode 100644 index 0000000..8417e5d --- /dev/null +++ b/docs/tutorial/index.md @@ -0,0 +1,70 @@ +# Train and deploy a SOTA model + +## Overview + +You are going to train a field of study (domain) classifier for scientific sentences. The exact task was proposed by the [SciBERT paper](https://arxiv.org/abs/1903.10676) in which SciBERT [achieved an F1-score of 0.6571](https://paperswithcode.com/sota/sentence-classification-on-paper-field). We are going to outperform it using a trivial text classification model: a [Linear SVM](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html). + +We use the same synthetic dataset derived from the [Microsoft Academic Graph](https://www.microsoft.com/en-us/research/project/microsoft-academic-graph/). The dataset is [available here](https://github.com/allenai/scibert/tree/master/data/text_classification/mag). + +## Objectives + +1. You will see how the `great_ai.utilities` can integrate into your Data Science workflow. +2. You will use `great_ai.large_file` to version and store your trained model +3. You will use `GreatAI` to prepare your model for a robust and responsible deployment + +!!! success + You are ready to start the tutorial. Feel free to come back to the [summary](#summary) section once you're finished. + +
+[:fontawesome-solid-chart-simple: Train it](train.ipynb){ .md-button .md-button--primary } + +[:material-cloud-tags: Deploy it](deploy.ipynb){ .md-button .md-button--secondary } +
+ + +## Summary + +### The [training notebook](train.ipynb) + +We load and preprocess the dataset while relying on `great_ai.utilities.clean` for the heavy-lifting. Additionally, the preprocessing is parallelised using `great_ai.utilities.simple_parallel_map`. + +After training and evaluating a model, it is exported using `great_ai.save_model`. + +??? tip "Using the cloud" + To store your model remotely, you need to set your credentials before calling `save_model`. + + For example, to use [AWS S3](https://aws.amazon.com/s3/): + ```python + from great_ai.large_file import LargeFileS3 + + LargeFileS3.configure( + aws_region_name='eu-west-2', + aws_access_key_id='MY_AWS_ACCESS_KEY', + aws_secret_access_key='MY_AWS_SECRET_KEY', + large_files_bucket_name='my_bucket_for_models' + ) + + from great_ai import save_model + + save_model(model, key='my-domain-predictor') + ``` + +### The [deployment notebook](deploy.ipynb) + +We create an inference function that can be hardened by wrapping it in a `great_ai.GreatAI` instance. + +```python +from great_ai import GreatAI, use_model +from great_ai.utilities import clean + +@GreatAI.create +@use_model('my-domain-predictor') #(1) +def predict_domain(sentence, model): + inputs = [clean(sentence)] + return str(model.predict(inputs)[0]) +``` + +1. `@use_model` loads and injects your model into the `predict_domain` function's `model` argument. + You can freely reference it knowing that it is always given to the function. + +Finally, we deploy the model, inference function, and the GreatAI wrapping all of these. For that we either use: `great-ai deploy.ipynb` or build a Docker image. diff --git a/docs/tutorial/train.ipynb b/docs/tutorial/train.ipynb new file mode 100644 index 0000000..3e2ac8e --- /dev/null +++ b/docs/tutorial/train.ipynb @@ -0,0 +1,318 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Train your model\n", + "\n", + "The first step is, of course, to install `great-ai` in your Python environment." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%pip install great-ai" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "First, we have to get some data. After downloading it [from here](https://github.com/allenai/scibert/tree/master/data/text_classification/mag), we might notice that the dataset is in [JSON Lines](https://jsonlines.org/) format (each line is a seperate JSON). \n", + "\n", + "Let's write a function which takes a single line, and returns the sentence and the corresponding label from it. Before returning, the sentence is also cleaned to remove any LaTeX, XML, unicode, PDF-extraction artifacts." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "from great_ai.utilities import clean\n", + "\n", + "\n", + "def preprocess(line):\n", + " data_point = json.loads(line)\n", + "\n", + " sentence = data_point[\"text\"]\n", + " label = data_point[\"label\"]\n", + "\n", + " return clean(sentence), label" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we can load the dataset and extract the *training* samples from it. Since we're impatient, we can do it in parallel using the `simple_parallel_map` function." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 84000/84000 [00:09<00:00, 8705.41it/s] \n" + ] + } + ], + "source": [ + "from great_ai.utilities import simple_parallel_map\n", + "\n", + "with open(\"data/train.txt\", encoding=\"utf-8\") as f:\n", + " training_data = simple_parallel_map(preprocess, f.readlines())\n", + "\n", + "X_train = [d[0] for d in training_data]\n", + "y_train = [d[1] for d in training_data]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's do the same for the *test* data." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 22399/22399 [00:02<00:00, 7963.06it/s] \n" + ] + } + ], + "source": [ + "with open(\"data/test.txt\", encoding=\"utf-8\") as f:\n", + " test_data = simple_parallel_map(preprocess, f.readlines())\n", + "\n", + "X_test = [d[0] for d in test_data]\n", + "y_test = [d[1] for d in test_data]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After obtaining some clean data, it's time to create and train a model on it. We are going to use [scikit-learn](https://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html) for this purpose.\n", + "\n", + "In this case, we opted for a [linear Support Vector Machine](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html) because it's known to be an adequate baseline for simple classification tasks." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Pipeline(steps=[('tfidfvectorizer', TfidfVectorizer()),\n",
+       "                ('linearsvc', LinearSVC())])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "Pipeline(steps=[('tfidfvectorizer', TfidfVectorizer()),\n", + " ('linearsvc', LinearSVC())])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from sklearn.pipeline import make_pipeline\n", + "from sklearn.feature_extraction.text import TfidfVectorizer\n", + "from sklearn.svm import LinearSVC\n", + "\n", + "model = make_pipeline(TfidfVectorizer(), LinearSVC())\n", + "# todo: hyperparameter-optimisation\n", + "model.fit(X_train, y_train)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It's already finished. Let's see how well it performs. But first, we need to configure matplotlib to make the charts more legible. \n", + "> `ConfusionMatrixDisplay` relies on `matplotlib` for rendering." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "%matplotlib inline\n", + "plt.rcParams[\"figure.figsize\"] = (30, 15)\n", + "plt.rcParams[\"font.size\"] = 12" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we check the quality of the model on the `test` split. We can use the classification report to check the common metrics, such as the macro F1-score. We also draw the confusion matrix to get some insights into the types of mistakes being made by the model." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " business 0.67 0.69 0.68 3198\n", + " economics 0.69 0.71 0.70 3189\n", + " geography 0.70 0.73 0.72 3207\n", + " medicine 0.90 0.91 0.90 3187\n", + " politics 0.63 0.57 0.60 3169\n", + " psychology 0.73 0.73 0.73 3252\n", + " sociology 0.51 0.51 0.51 3197\n", + "\n", + " accuracy 0.69 22399\n", + " macro avg 0.69 0.69 0.69 22399\n", + "weighted avg 0.69 0.69 0.69 22399\n", + "\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "from sklearn import metrics\n", + "\n", + "y_predicted = model.predict(X_test)\n", + "\n", + "print(metrics.classification_report(y_test, y_predicted))\n", + "metrics.ConfusionMatrixDisplay.from_predictions(y_test, y_predicted)\n", + "None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Great work, we can be rightfully satisfied with our model. Seeing the results, we achieved an F1-score of 0.69 which is about **5% better than SciBERT's** 0.6571!\n", + "\n", + "You might wonder that \"this is great, but besides some utility functions (`clean`, `simple_parallel_map`, ...) what more value does GreatAI add?\". This would be a valid argument because the scope of GreatAI actually only starts here.\n", + "\n", + "> Not coincidentally, this is the point where the scope of Data Science ends but it's still a grey-zone for software engineering.\n", + "\n", + "In order to use this model in production, we have to make it accessible on some possibly shared infrastructure." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[38;5;226m2022-07-09 22:33:18 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:33:18 | WARNING | Cannot find credentials files, defaulting to using ParallelTinyDbDriver\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:33:18 | WARNING | The selected tracing database (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:33:18 | WARNING | Cannot find credentials files, defaulting to using LargeFileLocal\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | GreatAI (v0.1.0): configured ✅\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | 🔩 tracing_database: ParallelTinyDbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | 🔩 large_file_implementation: LargeFileLocal\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | 🔩 is_production: False\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | 🔩 should_log_exception_stack: True\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | 🔩 prediction_cache_size: 512\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | 🔩 dashboard_table_size: 20\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:33:18 | WARNING | You still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n", + "\u001b[38;5;226m2022-07-09 22:33:18 | WARNING | > Find out more at https://se-ml.github.io/practices\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:18 | INFO | Fetching cached versions of my-domain-predictor\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:19 | INFO | Copying file for my-domain-predictor-5\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:19 | INFO | Compressing my-domain-predictor-5\u001b[0m\n", + "\u001b[38;5;39m2022-07-09 22:33:20 | INFO | Model my-domain-predictor uploaded with version 5\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "'my-domain-predictor:5'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from great_ai import save_model\n", + "\n", + "save_model(model, key=\"my-domain-predictor\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### [Let's continue by finishing the deployment in the next notebook.](/tutorial/deploy)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.10.4 ('.env': venv)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "02dd6d3afbfa9fbbe1037d64ad9014965528a1ccad21929d6e72f466389a68ad" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/tutorials.md b/docs/tutorials.md deleted file mode 100644 index e69de29..0000000 diff --git a/mkdocs.yaml b/mkdocs.yaml index aaac6ed..1f730a2 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -9,6 +9,8 @@ edit_uri: edit/main/docs/ theme: name: "material" custom_dir: docs/overrides + homepage: https://great-ai.scoutinscience.com + favicon: media/favicon.ico features: - content.code.annotate - content.tooltips @@ -33,10 +35,6 @@ plugins: - search - mkdocs-jupyter: include_source: true - # allow_errors: false - # execute: false - # execute_ignore: "my-secret-files/*.ipynb" - # theme: dark markdown_extensions: - pymdownx.highlight: @@ -62,8 +60,15 @@ markdown_extensions: nav: - Overview: index.md - - tutorials.md - - How-To Guides: how-to-guides.md + - Tutorial: + - tutorial/index.md + - tutorial/train.ipynb + - tutorial/deploy.ipynb + - User Guides: + - Simple AI lifecycle with classification: + - "Step 1: data": simple/data.ipynb + - "Step 2: train": simple/train.ipynb + - "Step 3: deploy": simple/deploy.ipynb - reference.md - explanation.md - - Notebook page: simple-mag/train.ipynb + diff --git a/docs/example_secrets.ini b/tests/large_file/data/example_secrets.ini similarity index 100% rename from docs/example_secrets.ini rename to tests/large_file/data/example_secrets.ini diff --git a/tests/large_file/test_large_file.py b/tests/large_file/test_large_file.py index 70b5292..87571fa 100644 --- a/tests/large_file/test_large_file.py +++ b/tests/large_file/test_large_file.py @@ -110,7 +110,7 @@ def test_initialized_with_file(client: Any) -> None: boto3.client = Mock(return_value=s3) - LargeFileS3.configure_credentials_from_file(PATH / "../../docs/example_secrets.ini") + LargeFileS3.configure_credentials_from_file(PATH / "data/example_secrets.ini") lf = LargeFileS3("test-file") boto3.client.assert_called_once_with(