diff --git a/README.md b/README.md index f956fd9..da6fc32 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -# ModelPlane - -Develop new evaluators / annotators. +# modelplane - an AI evaluator development platform ## ⚠️ Content warning @@ -12,41 +10,68 @@ These data come with the following warning: >Consider carefully whether you need to view the prompts and responses, limit exposure to what's necessary, take regular breaks, and stop if you feel uncomfortable. >For more information on the risks, see [this literature review](https://www.zevohealth.com/wp-content/uploads/2024/07/lit_review_IN-1.pdf) on vicarious trauma. -## Get Started +## Quickstart -You must have docker installed on your system. The -given docker-compose.yaml file will start up: +You must have a docker engine installed on your system. The given +docker-compose.yaml file has definitions for running the following services +locally: * mlflow tracking server + postgres * jupyter -1. Clone the repository: - ```bash - git clone https://github.com/mlcommons/modelplane.git - cd modelplane - ``` -1. Environment: - 1. Adjust the .env file as needed. The committed .env / - docker-compose.yaml will bring up mlflow, postgres, jupyter, set up - mlflow to use a local disk for artifact storage. - 1. Set up secrets for accessing SUTs, as needed in - `modelplane/flightpaths/config/secrets.toml`. See [modelbench](https://github.com/mlcommons/modelbench) for more details. - 1. Stage your input data in `modelplane/flightpaths/data`. You can get a - sample input file [here](https://github.com/mlcommons/ailuminate/tree/main). -1. Bring up the services: - ```bash - ./start_services.sh -d - ``` - If you are using the cli only, and not using jupyter, you must pass the `no-jupyter` option: - ```bash - ./start_services.sh -d --no-jupyter - ``` -1. Visit the [Jupyter Server](http://localhost:8888/?token=changeme). The +First, clone this repo: +```bash +git clone https://github.com/mlcommons/modelplane.git +cd modelplane +``` + +If you plan to share notebooks, clone +[modelplane-flights](https://github.com/mlcommons/modelplane-flights) as well. Both `modelplane` +and `modelplane-flights` should be in the same directory. + +Finally, set up secrets for accessing SUTs, as needed in +`modelplane/flightpaths/config/secrets.toml`. See [modelbench](https://github.com/mlcommons/modelbench) for more details. + + +### Running jupyter locally against the MLCommons mlflow server. + +1. Ensure you have access to the MLCommons mlflow tracking +and artifact server. If not, email +[airr-engineering@mlcommons.org](mailto:airr-engineering@mlcommons.org) +for access. +1. Modify `.env.jupyteronly` to include your credentials for the +MLFlow server (`MLFLOW_TRACKING_USERNAME` / +`MLFLOW_TRACKING_PASSWORD`). + * Alternatively, put the credentials in `~/.mlflow/credentials` as described [here](https://mlflow.org/docs/latest/ml/auth/#credentials-file). +1. To access `modelbench-private` code (assuming you have +access), you must also set `USE_MODELBENCH_PRIVATE=true` in `.env.jupyteronly`. This will forward your ssh agent to the container +allowing it to load the private repository to build the image. +1. Start jupyter with `./start_jupyter.sh`. (You can add the +`-d` flag to start in the background.) + +### Running jupyter and mlflow locally. + +1. Adjust the `.env` file as needed. The committed `.env` / +`docker-compose.yaml` will bring up mlflow, postgres, jupyter, and set up mlflow to use a local disk for artifact storage. +1. Start services with `./start_services.sh`. (You can add the +`-d` flag to start in the background.) + + * If you are using the cli only, and not using jupyter, you must pass the `--no-jupyter` option: + `./start_services.sh -d` + +## Getting started in JupyterLab. + +1. Visit the [Jupyter Server](http://localhost:8888/lab?token=changeme). The token is configured in the .env file. You shouldn't need to enter it more than once (until the server is restarted). You can get started with the template notebook or create a new one. -1. The runs can be monitored in MLFlow wherever you have that set up. If - local with the default setup, http://localhost:8080. +1. You should see the `flights` directory, which leads to the +`modelplane-flights` repository. Create a user directory +for yourself (`flights/users/{username}`) and either +copy an existing flightpath there or create a notebook from +scratch. + * You can manage branches and commits for + `modelplane-flights` directly from jupyter. ## CLI @@ -54,7 +79,7 @@ You can also interact with modelplane via CLI. Run `poetry run modelplane --help for more details. *Important:* You must set the `MLFLOW_TRACKING_URI` environmental variable. -For example, if you've brought up MLFlow using the docker compose process above, +For example, if you've brought up MLFlow using the fully local docker compose process above, you could run: ``` MLFLOW_TRACKING_URI=http://localhost:8080 poetry run modelplane get-sut-responses --sut_id {sut_id} --prompts tests/data/prompts.csv --experiment expname diff --git a/docker-compose.yaml b/docker-compose.yaml index 9d0364a..fa35443 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -73,6 +73,8 @@ services: - "8888:8888" volumes: - ./flightpaths:/app/flightpaths + # Volume not needed if not using modelplane-flights for sharing notebooks + - ../modelplane-flights:/app/flightpaths/flights # Volume not needed if using cloud storage for artifacts - ./mlruns:/mlruns # Below needed for dvc (via git) support (backed by GCP) diff --git a/poetry.lock b/poetry.lock index 8501d71..a20fcf0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3679,6 +3679,23 @@ websocket-client = ">=1.7" docs = ["ipykernel", "jinja2", "jupyter-client", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] +[[package]] +name = "jupyter-server-mathjax" +version = "0.2.6" +description = "MathJax resources as a Jupyter Server Extension." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyter_server_mathjax-0.2.6-py3-none-any.whl", hash = "sha256:416389dde2010df46d5fbbb7adb087a5607111070af65a1445391040f2babb5e"}, + {file = "jupyter_server_mathjax-0.2.6.tar.gz", hash = "sha256:bb1e6b6dc0686c1fe386a22b5886163db548893a99c2810c36399e9c4ca23943"}, +] + +[package.dependencies] +jupyter-server = ">=1.1" + +[package.extras] +test = ["jupyter-server[test]", "pytest"] + [[package]] name = "jupyter-server-terminals" version = "0.5.3" @@ -3732,6 +3749,30 @@ docs-screenshots = ["altair (==5.5.0)", "ipython (==8.16.1)", "ipywidgets (==8.1 test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] upgrade-extension = ["copier (>=9,<10)", "jinja2-time (<0.3)", "pydantic (<3.0)", "pyyaml-include (<3.0)", "tomli-w (<2.0)"] +[[package]] +name = "jupyterlab-git" +version = "0.51.2" +description = "A JupyterLab extension for version control using git" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_git-0.51.2-py3-none-any.whl", hash = "sha256:1150edabd844f9a5a3c7ba676409b18b8cc95b1a7bb171f357318f4075db2263"}, + {file = "jupyterlab_git-0.51.2.tar.gz", hash = "sha256:ad91d56f0298fd70e7d8f8cd1ee76d261f0dfb940cc490717a31d64df4b7d562"}, +] + +[package.dependencies] +jupyter-server = ">=2.0.1,<3" +nbdime = ">=4.0.1,<4.1.0" +nbformat = "*" +packaging = "*" +pexpect = "*" +traitlets = ">=5.0,<6.0" + +[package.extras] +dev = ["black", "jupyterlab (>=4.0,<5.0)", "pre-commit"] +test = ["coverage", "jupytext", "pytest", "pytest-asyncio", "pytest-cov", "pytest-jupyter[server] (>=0.6.0)"] +ui-tests = ["jupyter-archive"] + [[package]] name = "jupyterlab-pygments" version = "0.3.0" @@ -4758,6 +4799,32 @@ serve = ["tornado (>=6.1)"] test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] webpdf = ["playwright"] +[[package]] +name = "nbdime" +version = "4.0.2" +description = "Diff and merge of Jupyter Notebooks" +optional = false +python-versions = ">=3.6" +files = [ + {file = "nbdime-4.0.2-py3-none-any.whl", hash = "sha256:e5a43aca669c576c66e757071c0e882de05ac305311d79aded99bfb5a3e9419e"}, + {file = "nbdime-4.0.2.tar.gz", hash = "sha256:d8279f8f4b236c0b253b20d60c4831bb67843ed8dbd6e09f234eb011d36f1bf2"}, +] + +[package.dependencies] +colorama = "*" +gitpython = "<2.1.4 || >2.1.4,<2.1.5 || >2.1.5,<2.1.6 || >2.1.6" +jinja2 = ">=2.9" +jupyter-server = "*" +jupyter-server-mathjax = ">=0.2.2" +nbformat = "*" +pygments = "*" +requests = "*" +tornado = "*" + +[package.extras] +docs = ["recommonmark", "sphinx", "sphinx-rtd-theme"] +test = ["jsonschema", "jupyter-server[test]", "mock", "notebook", "pytest (>=6.0)", "pytest-cov", "pytest-timeout", "pytest-tornado", "requests", "tabulate"] + [[package]] name = "nbformat" version = "5.10.4" @@ -8310,4 +8377,4 @@ modelbench-private = ["modelbench-private"] [metadata] lock-version = "2.0" python-versions = ">=3.10,!=3.12.5,<3.13" -content-hash = "f28ad6ef1be39cdee175d7f278f6f5a09cfeb6fa2a76a932e1461e4255e8554b" +content-hash = "2da3a294b9467fac2b22afdd669f1d6de24b333c3b054de05f03eec75b6427f0" diff --git a/pyproject.toml b/pyproject.toml index e11da31..4116981 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,7 @@ jsonlines = "^4" numpy = "^2" matplotlib = "^3" jupyter = "^1" +jupyterlab-git = "*" scikit-learn = "^1.5.0" pandas = "^2.2.2" # plugins (would like to figure out a better way to manage these)