Skip to content

Installer rewrite in Python#2338

Closed
ebr wants to merge 32 commits into
mainfrom
dev/installer
Closed

Installer rewrite in Python#2338
ebr wants to merge 32 commits into
mainfrom
dev/installer

Conversation

@ebr

@ebr ebr commented Jan 16, 2023

Copy link
Copy Markdown
Contributor

Summary

This PR rewrites the core of the installer in Python for cross-platform compatibility. Filesystem path manipulation, platform/arch decisions and various edge cases are handled in a more convenient fashion. The original install.bat.in/install.sh.in scripts are kept as entrypoints for their respective OSs, but only serve as thin wrappers to the Python module.

TL;DR

Test the "happy path":

$ python3 installer/main.py --root <path_to_somewhere> --yes

Remove the --yes for interactive testing.

Details

Downloading of specific .zip bundles (refs) from Github is not yet implemented; this right now functions as a more polished "source" installer. The pip-based install and ability to place the virtualenv outside of the runtime dir are not yet implemented, may be added to this or a future PR.

Introduces a new ldm/invoke/config module and moves the configure_invokeai script into it. Note: this supports a separate set of changes I'm almost ready to push to the config module, which improve runtime directory management and validation. They are not a part of this PR yet, but will be soon™. Omitted for now for better testability and to keep rebasing to a minimum.

more testing

Because the installer isn't yet standalone and doesn't pull the source tree from Github, it needs to be tested from a cloned copy of this repo, with this branch checked out.

See TODO checklist in a comment below for things that are known broken . The "happy path" should be very reliable. Changing filesystem paths should also be reliable. Please test "weird" scenarios (delete the configs dir after installation? etc), in addition to the "happy path".

Test the shell script wrappers as well:

  1. Copy or rename the installer/install.*.in (as appropriate for your OS) such that it doesn't have the .in extension
  2. Run this install script. Try running it by absolute path after cd to somewhere else on your system. It should work regardless of your CWD.

The install script accepts the --root <path> argument to install in a location that is different from the default, and --yes for a hands-off install (this does not yet work on Windows!!).

The install script should go through the entire process of creating the venv, installing the dependencies and the app, and then handing over to the config script.

There are still many bugs! Checklist posted as a separate comment.

@ebr ebr requested a review from tildebyte as a code owner January 16, 2023 08:16
@ebr ebr marked this pull request as draft January 16, 2023 08:18
@ebr ebr requested review from hipsterusername and lstein January 16, 2023 08:18
@ebr

ebr commented Jan 16, 2023

Copy link
Copy Markdown
Contributor Author

Task list (still to be done)

TODO (some blocking):

  • properly install torch
  • add configs to package so that they can be easily distributed
  • Windows: failure to delete temp venv on exit raises an exception
    • suppression of installer error is only possible on python 3.10 or above...
    • python 3.9 will still display the error
    • is it even possible to catch this exception? should we just recommend 3.10? can we catch it if we use TemporaryDirectory() as a context manager? worth the effort?
  • emit launch scripts
    • *nix
    • Windows
  • support updaters
    • fix/debug current, OR
    • implement updating as a function of the installer
  • Windows: handle Visual C++ redistrib absence
    • a: Detect VC++ redist missing (how?), display message (offer to download?) and/or gracefully exit
    • b: just display a message (already in .bat wrapper)
  • test on MacOS
  • macOS: Detect missing xcode CLI tools
  • macOS: Tab completion is broken when selecting destination dir
  • macOS (possibly Linux): ~ not expanded to $HOME when selecting dest dir
  • Windows: do the registry long paths fix
    • a: actually apply it with confirimation
    • b: just display a message (already in bat wrapper)
  • Windows: janky text in all terminals (Terminal > cmd > powershell)
    • can anything even be done about that?
    • prefer just using cmd, because venv can't be activated in Terminal????
  • Windows only? (probably not; test this): when no prior HF token exists (not even invalid), pressing Enter on HF token request fails with OSError
  • fix report_model_error (aka emergency_model_reconfigure)

debt (non-blockers):

  • use console.print() for all standard printing
  • use prompt_toolkit for all freeform or multiple-choice selection prompts?
    • or only where autocomplete is needed?
  • consider also replacing Console.ask() with prompt_toolkit? just so we have one approach
  • can we make models.yaml a list instead of a mapping? (should we?)

known bugs:

  • if hf token is already set, it can't be reset by rerunning the script, even if invalid
  • if configs dir does not exist, models.yaml is not created
  • if you skip model dl initially, models.yaml is not created (maybe fixed? confirm)
  • user is not given the opportunity to auth to HF if they skip model download
  • clip model gets downloaded to ~/.cache/clip on first run

future/feat:

  • feat: ability to reconfigure various aspects, like the outdir
  • feat: add HF_HOME to Paths
  • feat: there should be a way to skip all downloads
  • feat: config fallback (report_model_error, bail out from CLI failure) tries to run through the whole workflow for any issue (i.e. "missing initfile? download models!"). Currently refactoring it to fix only what needs fixin'.

decisions (fyi / to discuss):

  • keep using bash/cmd wrapper scripts (however now very thin) to maintain the same release process (will reinvent the wheel another time!)
  • use prompt_toolkit for interaction instead of readline/pyreadline3 - why?
    • pure python (does not require readline)
    • works great on Windows - a successor of pyreadline3
    • unlike readline, doesn't break the console after formatted text was displayed (this is a known GNU readline bug!)
    • has excellent autocompletion/validation capabilities
    • formatting/layout tools are worse than rich
      • but they integrate nicely: prompt_toolkit for interaction, rich for presentation

WRITE TESTS 😭

  • when model download is skipped
    • and config file doesn't exist
      • config file should be created
      • just with defaults
    • and configs dir is missing
      • configs dir should be reinitialized
    • and there are no models
      • do what?
  • when configs dir is missing
    • create a new configs folder
    • create a default models.yaml
    • do not download models!
  • when models dir is missing
    • offer to download models
    • ussual flow
  • when init file is missing
    • only ask enough to populate initfile contents
    • skip downloads etc unless needed
  • when a model fails to load
    • list currently installed models
    • offer to download models (follow usual flow)
    • this is already somewhat the case, but offers to run the config script

Might spin these out into separate issues......

@ebr ebr requested review from mauwii and netsvetaev January 16, 2023 16:53
@hipsterusername

Copy link
Copy Markdown
Member

My experience with the installer on windows has been nothing short of pleasant. Extremely nice work.

I haven’t tried latest version - what feedback/input do you need?

@lstein

lstein commented Jan 17, 2023 via email

Copy link
Copy Markdown
Collaborator

@ebr ebr force-pushed the dev/installer branch 2 times, most recently from fdb516b to 2264f9c Compare January 19, 2023 20:34
@ebr

ebr commented Jan 20, 2023

Copy link
Copy Markdown
Contributor Author

My experience with the installer on windows has been nothing short of pleasant. Extremely nice work.

I haven’t tried latest version - what feedback/input do you need?

Thank you <3

I'm interested to know if any path aside from the "happy path" (i.e. "yes to all" on a brand-new runtime dir) breaks in any way. For example, does selection of paths on a different drive work? Destination with spaces in the path name? those kind of edge cases. I tested a lot of it on Linux, but my Windows VM is way too slow (and lacks GPU) for any meaningful testing.

Thanks!

@Lycantant

Copy link
Copy Markdown

Downloading of specific .zip bundles (refs) from Github is not yet implemented; this right now functions as a more polished "source" installer. The pip-based install and ability to place the virtualenv outside of the runtime dir are not yet implemented, may be added to this or a future PR.

Still patiently waiting for this one 😁

@ebr ebr force-pushed the dev/installer branch 3 times, most recently from 95b849a to 1044fc5 Compare January 28, 2023 07:43
ebr added 20 commits January 28, 2023 17:39
This allows reliable distribution of the initial 'configs' directory
with the Python package, and enables the configuration script to be running
from anywhere, as long as the virtual environment is available on the sys.path
the 'setup.py install' method is deprecated in favour of a
build-system independent format: https://peps.python.org/pep-0517/

this is needed to install dependencies that don't have a pyproject.toml
file (only setup.py) in a forward-compatible way
if the config directory is missing, initialize it using the standard
process of copying it over, instead of failing to create the config file

this can happen if the user is re-running the config script in a directory which
already has the init file, but no configs dir
…h experience on Linux/Mac

- install.sh is now a thin wrapper around the pythonized install script
- install.bat not done yet - to follow
- user messaging is tailored to the current platform (paste shortcuts, file paths, etc)
- emit invoke.sh/invoke.bat scripts to the runtime dir
- improve launch scripts (add help option, etc)
- only emit the platform-specific scripts
- remove redundant options (unchanged from defaults)
- don't test 3rd party code
- omit fully covered files from coverage report
- gitignore junit (xml) test output directory
- add torch MPS fallback directly to CLI.py
- rename CLI scripts with `invoke-...` prefix
- delete long-deprecated scripts
- add a missing package dependency
- delete setup.py as obsolete
… the wheel

reduces wheel size to 3MB from 27MB
@ebr

ebr commented Jan 28, 2023

Copy link
Copy Markdown
Contributor Author

The commit log for this has gotten ridiculous. Opening a new PR for sanity.

@ebr ebr closed this Jan 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants