mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
(installer) copy launch/update scripts to the root dir; improve launch 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
This commit is contained in:
parent
d047e070b8
commit
71733bcfa1
@ -1,234 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# ensure we're in the correct folder in case user's CWD is somewhere else
|
||||
scriptdir=$(dirname "$0")
|
||||
cd "$scriptdir"
|
||||
|
||||
# This version number will be replaced by the one supplied to create_installers.sh.
|
||||
# Do not change it here - change it in create_installers.sh.
|
||||
INVOKEAI_VERSION="latest"
|
||||
#!/bin/bash
|
||||
|
||||
# make sure we are not already in a venv
|
||||
# (don't need to check status)
|
||||
deactivate >/dev/null 2>&1
|
||||
|
||||
INVOKE_AI_SRC=https://github.com/invoke-ai/InvokeAI/archive/refs/tags/${INVOKEAI_VERSION}.zip
|
||||
INSTRUCTIONS=https://invoke-ai.github.io/InvokeAI/installation/INSTALL_AUTOMATED/
|
||||
TROUBLESHOOTING=https://invoke-ai.github.io/InvokeAI/installation/INSTALL_AUTOMATED/#troubleshooting
|
||||
MINIMUM_PYTHON_VERSION=3.9.0
|
||||
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
function _err_exit {
|
||||
if test "$1" -ne 0
|
||||
then
|
||||
echo -e "Error code $1; Error caught was '$2'"
|
||||
if [ "$OS_NAME" == "osx" ]; then
|
||||
echo "Something went wrong while installing InvokeAI and/or its requirements."
|
||||
echo "You may need to use the Xcode command line tools to proceed. See step number 3 of"
|
||||
echo "https://invoke-ai.github.io/InvokeAI/INSTALL_SOURCE#walk_through for"
|
||||
echo "installation instructions and then run this script again."
|
||||
else
|
||||
echo "Something went wrong while installing InvokeAI and/or its requirements."
|
||||
echo "See https://invoke-ai.github.io/InvokeAI/INSTALL_SOURCE#troubleshooting for troubleshooting"
|
||||
echo "tips, or visit https://invoke-ai.github.io/InvokeAI/#installation for alternative"
|
||||
echo "installation methods"
|
||||
fi
|
||||
read -p "Press any key to exit..."
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
function readinput() {
|
||||
local CLEAN_ARGS=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
local i="$1"
|
||||
case "$i" in
|
||||
"-i")
|
||||
if read -i "default" 2>/dev/null <<< "test"; then
|
||||
CLEAN_ARGS="$CLEAN_ARGS -i \"$2\""
|
||||
fi
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
"-p")
|
||||
CLEAN_ARGS="$CLEAN_ARGS -p \"$2\""
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
CLEAN_ARGS="$CLEAN_ARGS $1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
eval read $CLEAN_ARGS
|
||||
}
|
||||
|
||||
|
||||
function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
|
||||
|
||||
echo "InvokeAI simple installer..."
|
||||
echo ""
|
||||
echo "Some of the installation steps take a long time to run. Please be patient."
|
||||
echo "If the script appears to hang for more than 10 minutes, please interrupt with control-C and retry."
|
||||
read -n 1 -s -r -p "<Press any key to start the install>"
|
||||
echo ""
|
||||
|
||||
OS_NAME=$(uname -s)
|
||||
case "${OS_NAME}" in
|
||||
Linux*) OS_NAME="linux";;
|
||||
Darwin*) OS_NAME="osx";;
|
||||
*) echo "Unknown OS: $OS_NAME! This script runs only on Linux or Mac" && exit
|
||||
esac
|
||||
|
||||
OS_ARCH=$(uname -m)
|
||||
case "${OS_ARCH}" in
|
||||
x86_64*) OS_ARCH="64";;
|
||||
arm64*) OS_ARCH="arm64";;
|
||||
*) echo "Unknown system architecture: $OS_ARCH! This script runs only on x86_64 or arm64" && exit
|
||||
esac
|
||||
|
||||
echo "Installing for $OS_NAME-$OS_ARCH"
|
||||
# confirm that python is installed and is up to date
|
||||
|
||||
PYTHON=""
|
||||
for candidate in python3.10 python3.9 python3 python python3.11 ; do
|
||||
if ppath=`which $candidate`; then
|
||||
python_version=$($ppath -V | awk '{ print $2 }')
|
||||
if [ $(version $python_version) -ge $(version "$MINIMUM_PYTHON_VERSION") ]; then
|
||||
PYTHON=$ppath
|
||||
echo Python $python_version found at $PYTHON
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$PYTHON" ]; then
|
||||
echo "A suitable Python interpreter could not be found"
|
||||
echo "Please install Python 3.9 or higher before running this script. See instructions at $INSTRUCTIONS for help."
|
||||
read -p "Press any key to exit"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
|
||||
ROOTDIR=""
|
||||
while [ "$ROOTDIR" == "" ]
|
||||
do
|
||||
echo
|
||||
readinput -e -p "Select your preferred location for the 'invokeai' directory [$HOME]: " -i $HOME input
|
||||
ROOTDIR=${input:=$HOME}/invokeai
|
||||
|
||||
# This is surprisingly hard to do in plain Bash; easier in ZSH. Just running python in subshell is easiest.
|
||||
ROOTDIR=$($PYTHON -c "from pathlib import Path; print(Path('${ROOTDIR}').expanduser().resolve())")
|
||||
|
||||
read -e -p "InvokeAI will be installed into $ROOTDIR. OK? [y]: " input
|
||||
RESPONSE=${input:='y'}
|
||||
if [ "$RESPONSE" == 'y' ]; then
|
||||
if [ -e "$ROOTDIR" ]; then
|
||||
echo
|
||||
read -e -p "Directory "$ROOTDIR" already exists. Do you want to resume an interrupted install? [y]: " input
|
||||
RESPONSE=${input:='y'}
|
||||
if [ "$RESPONSE" != 'y' ]; then
|
||||
ROOTDIR=""
|
||||
fi
|
||||
else
|
||||
mkdir -p "$ROOTDIR"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Could not create "$ROOTDIR". Try again with a different install location."
|
||||
ROOTDIR=""
|
||||
fi
|
||||
fi
|
||||
else
|
||||
ROOTDIR=""
|
||||
fi
|
||||
done
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
echo
|
||||
echo "** Creating Virtual Environment for InvokeAI **"
|
||||
|
||||
$PYTHON -mvenv "$ROOTDIR"/.venv
|
||||
_err_exit $? "Python failed to create virtual environment "$ROOTDIR"/.venv. Please see $TROUBLESHOOTING for help."
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
echo
|
||||
echo "** Activating Virtual Environment for InvokeAI **"
|
||||
|
||||
source "$ROOTDIR"/.venv/bin/activate
|
||||
_err_exit $? "Failed to activate virtual evironment "$ROOTDIR"/.venv. Please see $TROUBLESHOOTING for help."
|
||||
|
||||
PYTHON="$ROOTDIR"/.venv/bin/python
|
||||
$PYTHON -mensurepip --upgrade
|
||||
$PYTHON -mpip install --upgrade pip
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
echo
|
||||
echo "*** Installing InvokeAI Dependencies ***"
|
||||
|
||||
if [ "$OS_NAME" == "osx" ]; then
|
||||
echo "macOS detected. Installing MPS and CPU support."
|
||||
egrep -v '^-e .' environments-and-requirements/requirements-mac-mps-cpu.txt >requirements.txt
|
||||
else
|
||||
if (lsmod | grep amdgpu) &>/dev/null ; then
|
||||
readinput -e -p "Linux system with AMD GPU driver detected. Install ROCm AMD accelerated support? (Otherwise, CUDA support will be installed) [n]: " input
|
||||
RESPONSE=${input:='n'}
|
||||
if [ "$RESPONSE" != "n" ]; then
|
||||
echo "Installing ROCm (AMD) support"
|
||||
egrep -v '^-e .' environments-and-requirements/requirements-lin-amd.txt >requirements.txt
|
||||
else
|
||||
echo "Installing CUDA support"
|
||||
egrep -v '^-e .' environments-and-requirements/requirements-lin-cuda.txt >requirements.txt
|
||||
fi
|
||||
else
|
||||
echo "Linux system detected. Installing CUDA and CPU support."
|
||||
egrep -v '^-e .' environments-and-requirements/requirements-lin-cuda.txt >requirements.txt
|
||||
fi
|
||||
fi
|
||||
|
||||
$PYTHON -mpip install --prefer-binary -r requirements.txt
|
||||
_err_exit $? "Failed to install InvokeAI's dependencies."
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
echo
|
||||
echo "*** Installing InvokeAI Modules and Executables ***"
|
||||
$PYTHON -mpip install $INVOKE_AI_SRC
|
||||
_err_exit $? "Installation of InvokeAI failed."
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
echo " *** Setting Up Root Directory "$ROOTDIR" *** "
|
||||
cp -pr templates/rootdir/* "$ROOTDIR"/
|
||||
cp templates/invoke.sh.in "$ROOTDIR"/invoke.sh
|
||||
chmod a+rx "$ROOTDIR"/invoke.sh
|
||||
cp templates/update.sh.in "$ROOTDIR"/update.sh
|
||||
chmod a+rx "$ROOTDIR"/update.sh
|
||||
|
||||
# This allows the updater to work!
|
||||
cp -pr environments-and-requirements requirements.txt "$ROOTDIR/"
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
echo
|
||||
echo "*** Confguring InvokeAI ***"
|
||||
pushd "$ROOTDIR" >/dev/null
|
||||
$PYTHON ./.venv/bin/configure_invokeai.py --root="$ROOTDIR"
|
||||
_err_exit $? "Initial configuration failed. Please see above error messages and $TROUBLESHOOTING for help."
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
popd
|
||||
cp templates/invoke.sh.in "$ROOTDIR"/invoke.sh
|
||||
chmod a+rx "$ROOTDIR"/invoke.sh
|
||||
|
||||
cp templates/update.sh.in "$ROOTDIR"/update.sh
|
||||
chmod a+rx "$ROOTDIR"/update.sh
|
||||
|
||||
echo "You may now run InvokeAI by entering the directory $ROOTDIR and running invoke.sh:"
|
||||
echo
|
||||
echo " ${ROOTDIR}/invoke.sh"
|
||||
echo
|
||||
|
||||
read -e -p "Run InvokeAI now? [y]:" input
|
||||
RESPONSE=${input:='y'}
|
||||
if [ "$RESPONSE" == 'y' ]; then
|
||||
exec ${ROOTDIR}/invoke.sh
|
||||
fi
|
||||
exec python3 $(dirname $0)/main.py ${@}
|
||||
|
@ -4,6 +4,7 @@ InvokeAI installer script
|
||||
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import venv
|
||||
@ -160,10 +161,15 @@ class Installer:
|
||||
|
||||
self.instance = InvokeAiInstance(runtime=self.dest, venv=self.venv)
|
||||
|
||||
# create the venv, install dependencies and the application
|
||||
self.instance.deploy(extra_index_url=get_torch_source())
|
||||
|
||||
# run the configuration flow
|
||||
self.instance.configure()
|
||||
|
||||
# install the launch/update scritps into the runtime directory
|
||||
self.instance.install_user_scripts()
|
||||
|
||||
|
||||
class InvokeAiInstance:
|
||||
"""
|
||||
@ -206,7 +212,7 @@ class InvokeAiInstance:
|
||||
### until we continuously build wheels
|
||||
|
||||
import messages
|
||||
from plumbum import local, FG
|
||||
from plumbum import FG, local
|
||||
|
||||
# pre-installing Torch because this is the most reliable way to ensure
|
||||
# the correct version gets installed.
|
||||
@ -253,7 +259,7 @@ class InvokeAiInstance:
|
||||
Install PyTorch
|
||||
"""
|
||||
|
||||
from plumbum import local, FG
|
||||
from plumbum import FG, local
|
||||
|
||||
extra_index_url_arg = "--extra-index-url" if extra_index_url is not None else None
|
||||
|
||||
@ -284,6 +290,19 @@ class InvokeAiInstance:
|
||||
|
||||
configure_invokeai.main()
|
||||
|
||||
def install_user_scripts(self):
|
||||
"""
|
||||
Copy the launch and update scripts to the runtime dir
|
||||
"""
|
||||
|
||||
ext = 'bat' if OS == 'Windows' else 'sh'
|
||||
|
||||
for script in ["invoke", "update"]:
|
||||
src = Path(__file__).parent / "templates" / f"{script}.{ext}.in"
|
||||
dest = self.runtime / f"{script}.{ext}"
|
||||
shutil.copy (src, dest)
|
||||
os.chmod(dest, 0o0755)
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
|
@ -1,5 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
####
|
||||
# This launch script assumes that:
|
||||
# 1. it is located in the runtime directory,
|
||||
# 2. the .venv is also located in the runtime directory and is named exactly that
|
||||
#
|
||||
# If both of the above are not true, this script will likely not work as intended.
|
||||
# Activate the virtual environment and run `invoke.py` directly.
|
||||
####
|
||||
|
||||
set -eu
|
||||
|
||||
# ensure we're in the correct folder in case user's CWD is somewhere else
|
||||
@ -23,16 +32,41 @@ if [ "$0" != "bash" ]; then
|
||||
echo "4. merge models (diffusers type only)"
|
||||
echo "5. open the developer console"
|
||||
echo "6. re-run the configure script to download new models"
|
||||
read -p "Please enter 1, 2, 3, 4 or 5: [1] " yn
|
||||
echo "7. command-line help "
|
||||
echo ""
|
||||
read -p "Please enter 1, 2, 3, 4, 5, 6 or 7: [2] " yn
|
||||
choice=${yn:='2'}
|
||||
case $choice in
|
||||
1 ) printf "\nStarting the InvokeAI command-line..\n"; invoke $*;;
|
||||
2 ) printf "\nStarting the InvokeAI browser-based UI..\n"; invoke --web $*;;
|
||||
3 ) printf "\nStarting Textual Inversion:\n"; textual_inversion --gui $*;;
|
||||
4 ) printf "\nMerging Models:\n"; merge_models --gui $*;;
|
||||
5 ) printf "\nDeveloper Console:\n"; file_name=$(basename "${BASH_SOURCE[0]}"); bash --init-file "$file_name";;
|
||||
6 ) printf "\nRunning configure_invokeai.py:\n"; configure_invokeai $*;;
|
||||
* ) echo "Invalid selection"; exit;;
|
||||
1)
|
||||
echo "Starting the InvokeAI command-line..."
|
||||
exec invokeai $@
|
||||
;;
|
||||
2)
|
||||
echo "Starting the InvokeAI browser-based UI..."
|
||||
exec invokeai --web $@
|
||||
;;
|
||||
3)
|
||||
echo "Starting Textual Inversion:"
|
||||
exec textual_inversion --gui $@
|
||||
;;
|
||||
4)
|
||||
echo "Merging Models:"
|
||||
exec merge_models --gui $@
|
||||
;;
|
||||
5)
|
||||
echo "Developer Console:"
|
||||
file_name=$(basename "${BASH_SOURCE[0]}")
|
||||
bash --init-file "$file_name"
|
||||
;;
|
||||
6)
|
||||
exec invokeai-config --root ${INVOKEAI_ROOT}
|
||||
;;
|
||||
7)
|
||||
exec invokeai --help
|
||||
;;
|
||||
*)
|
||||
echo "Invalid selection"
|
||||
exit;;
|
||||
esac
|
||||
else # in developer console
|
||||
python --version
|
||||
|
@ -71,23 +71,30 @@ Config_preamble = '''# This file describes the alternative machine learning mode
|
||||
#--------------------------------------------
|
||||
def postscript(errors: None):
|
||||
if not any(errors):
|
||||
message='''
|
||||
message=f'''
|
||||
** Model Installation Successful **
|
||||
|
||||
You're all set!
|
||||
|
||||
If you installed using one of the automated installation scripts,
|
||||
execute 'invoke.sh' (Linux/macOS) or 'invoke.bat' (Windows) to
|
||||
start InvokeAI.
|
||||
---
|
||||
|
||||
If you installed manually, activate the 'invokeai' environment
|
||||
(e.g. 'conda activate invokeai'), then run one of the following
|
||||
commands to start InvokeAI.
|
||||
If you installed manually from source or with 'pip install': activate the virtual environment
|
||||
then run one of the following commands to start InvokeAI.
|
||||
|
||||
Web UI:
|
||||
python scripts/invoke.py --web # (connect to http://localhost:9090)
|
||||
invoke.py --web # (connect to http://localhost:9090)
|
||||
invoke.py --web --host 0.0.0.0 # (connect to http://your-lan-ip:9090 from another computer on the local network)
|
||||
|
||||
Command-line interface:
|
||||
python scripts/invoke.py
|
||||
invoke.py
|
||||
|
||||
---
|
||||
|
||||
If you installed using an installation script, run:
|
||||
|
||||
{Globals.root}/invoke.{"bat" if sys.platform == "win32" else "sh"}
|
||||
|
||||
Add the '--help' argument to see all of the command-line switches available for use.
|
||||
|
||||
Have fun!
|
||||
'''
|
||||
@ -277,7 +284,7 @@ The license terms are located here:
|
||||
print(f"Login failed due to invalid token found in cache")
|
||||
|
||||
if not (yes_to_all or token_found):
|
||||
print(''' You may optionally enter your Huggingface token now. InvokeAI
|
||||
print(f''' You may optionally enter your Huggingface token now. InvokeAI
|
||||
*will* work without it but you will not be able to automatically
|
||||
download some of the Hugging Face style concepts. See
|
||||
https://invoke-ai.github.io/InvokeAI/features/CONCEPTS/#using-a-hugging-face-concept
|
||||
@ -285,8 +292,10 @@ for more information.
|
||||
|
||||
Visit https://huggingface.co/settings/tokens to generate a token. (Sign up for an account if needed).
|
||||
|
||||
Paste the token below using Ctrl-V on macOS/Linux, or Ctrl-Shift-V or right-click on Windows.
|
||||
Alternatively press 'Enter' to skip this step and continue.
|
||||
Paste the token below using {"Ctrl+Shift+V" if sys.platform == "linux" else "Command+V" if sys.platform == "darwin" else "Ctrl+V, right-click, or Edit>Paste"}.
|
||||
|
||||
Alternatively, press 'Enter' to skip this step and continue.
|
||||
|
||||
You may re-run the configuration script again in the future if you do not wish to set the token right now.
|
||||
''')
|
||||
again = True
|
||||
|
Loading…
Reference in New Issue
Block a user