CoolFace
Apppublic

forestcalled/text-generation-webui

sourceHugging Faceupdated 3y agoView on Hugging Face
0likes
one_click.py416 linesDownload Raw Back to root
1import argparse2import glob3import hashlib4import os5import platform6import re7import signal8import site9import subprocess10import sys11 12script_dir = os.getcwd()13conda_env_path = os.path.join(script_dir, "installer_files", "env")14 15# Remove the '# ' from the following lines as needed for your AMD GPU on Linux16# os.environ["ROCM_PATH"] = '/opt/rocm'17# os.environ["HSA_OVERRIDE_GFX_VERSION"] = '10.3.0'18# os.environ["HCC_AMDGPU_TARGET"] = 'gfx1030'19 20# Command-line flags21cmd_flags_path = os.path.join(script_dir, "CMD_FLAGS.txt")22if os.path.exists(cmd_flags_path):23    with open(cmd_flags_path, 'r') as f:24        CMD_FLAGS = ' '.join(line.strip().rstrip('\\').strip() for line in f if line.strip().rstrip('\\').strip() and not line.strip().startswith('#'))25else:26    CMD_FLAGS = ''27 28flags = f"{' '.join([flag for flag in sys.argv[1:] if flag != '--update'])} {CMD_FLAGS}"29 30 31def signal_handler(sig, frame):32    sys.exit(0)33 34 35signal.signal(signal.SIGINT, signal_handler)36 37 38def is_linux():39    return sys.platform.startswith("linux")40 41 42def is_windows():43    return sys.platform.startswith("win")44 45 46def is_macos():47    return sys.platform.startswith("darwin")48 49 50def is_x86_64():51    return platform.machine() == "x86_64"52 53 54def cpu_has_avx2():55    try:56        import cpuinfo57 58        info = cpuinfo.get_cpu_info()59        if 'avx2' in info['flags']:60            return True61        else:62            return False63    except:64        return True65 66 67def cpu_has_amx():68    try:69        import cpuinfo70 71        info = cpuinfo.get_cpu_info()72        if 'amx' in info['flags']:73            return True74        else:75            return False76    except:77        return True78 79 80def torch_version():81    site_packages_path = None82    for sitedir in site.getsitepackages():83        if "site-packages" in sitedir and conda_env_path in sitedir:84            site_packages_path = sitedir85            break86 87    if site_packages_path:88        torch_version_file = open(os.path.join(site_packages_path, 'torch', 'version.py')).read().splitlines()89        torver = [line for line in torch_version_file if '__version__' in line][0].split('__version__ = ')[1].strip("'")90    else:91        from torch import __version__ as torver92    return torver93 94 95def is_installed():96    site_packages_path = None97    for sitedir in site.getsitepackages():98        if "site-packages" in sitedir and conda_env_path in sitedir:99            site_packages_path = sitedir100            break101 102    if site_packages_path:103        return os.path.isfile(os.path.join(site_packages_path, 'torch', '__init__.py'))104    else:105        return os.path.isdir(conda_env_path)106 107 108def check_env():109    # If we have access to conda, we are probably in an environment110    conda_exist = run_cmd("conda", environment=True, capture_output=True).returncode == 0111    if not conda_exist:112        print("Conda is not installed. Exiting...")113        sys.exit(1)114 115    # Ensure this is a new environment and not the base environment116    if os.environ["CONDA_DEFAULT_ENV"] == "base":117        print("Create an environment for this project and activate it. Exiting...")118        sys.exit(1)119 120 121def clear_cache():122    run_cmd("conda clean -a -y", environment=True)123    run_cmd("python -m pip cache purge", environment=True)124 125 126def print_big_message(message):127    message = message.strip()128    lines = message.split('\n')129    print("\n\n*******************************************************************")130    for line in lines:131        if line.strip() != '':132            print("*", line)133 134    print("*******************************************************************\n\n")135 136 137def calculate_file_hash(file_path):138    p = os.path.join(script_dir, file_path)139    if os.path.isfile(p):140        with open(p, 'rb') as f:141            return hashlib.sha256(f.read()).hexdigest()142    else:143        return ''144 145 146def run_cmd(cmd, assert_success=False, environment=False, capture_output=False, env=None):147    # Use the conda environment148    if environment:149        if is_windows():150            conda_bat_path = os.path.join(script_dir, "installer_files", "conda", "condabin", "conda.bat")151            cmd = "\"" + conda_bat_path + "\" activate \"" + conda_env_path + "\" >nul && " + cmd152        else:153            conda_sh_path = os.path.join(script_dir, "installer_files", "conda", "etc", "profile.d", "conda.sh")154            cmd = ". \"" + conda_sh_path + "\" && conda activate \"" + conda_env_path + "\" && " + cmd155 156    # Run shell commands157    result = subprocess.run(cmd, shell=True, capture_output=capture_output, env=env)158 159    # Assert the command ran successfully160    if assert_success and result.returncode != 0:161        print("Command '" + cmd + "' failed with exit status code '" + str(result.returncode) + "'.\n\nExiting now.\nTry running the start/update script again.")162        sys.exit(1)163 164    return result165 166 167def install_webui():168    # Select your GPU, or choose to run in CPU mode169    if "GPU_CHOICE" in os.environ:170        choice = os.environ["GPU_CHOICE"].upper()171        print_big_message(f"Selected GPU choice \"{choice}\" based on the GPU_CHOICE environment variable.")172    else:173        print()174        print("What is your GPU?")175        print()176        print("A) NVIDIA")177        print("B) AMD (Linux/MacOS only. Requires ROCm SDK 5.6 on Linux)")178        print("C) Apple M Series")179        print("D) Intel Arc (IPEX)")180        print("N) None (I want to run models in CPU mode)")181        print()182 183        choice = input("Input> ").upper()184        while choice not in 'ABCDN':185            print("Invalid choice. Please try again.")186            choice = input("Input> ").upper()187 188    if choice == "N":189        print_big_message("Once the installation ends, make sure to open CMD_FLAGS.txt with\na text editor and add the --cpu flag.")190 191    # Find the proper Pytorch installation command192    install_git = "conda install -y -k ninja git"193    install_pytorch = "python -m pip install torch torchvision torchaudio"194 195    use_cuda118 = "N"196    if any((is_windows(), is_linux())) and choice == "A":197        if "USE_CUDA118" in os.environ:198            use_cuda118 = "Y" if os.environ.get("USE_CUDA118", "").lower() in ("yes", "y", "true", "1", "t", "on") else "N"199        else:200            # Ask for CUDA version if using NVIDIA201            print("\nDo you want to use CUDA 11.8 instead of 12.1? Only choose this option if your GPU is very old (Kepler or older).\nFor RTX and GTX series GPUs, say \"N\". If unsure, say \"N\".\n")202            use_cuda118 = input("Input (Y/N)> ").upper().strip('"\'').strip()203            while use_cuda118 not in 'YN':204                print("Invalid choice. Please try again.")205                use_cuda118 = input("Input> ").upper().strip('"\'').strip()206        if use_cuda118 == 'Y':207            print("CUDA: 11.8")208        else:209            print("CUDA: 12.1")210 211        install_pytorch = f"python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/{'cu121' if use_cuda118 == 'N' else 'cu118'}"212    elif not is_macos() and choice == "B":213        if is_linux():214            install_pytorch = "python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm5.6"215        else:216            print("AMD GPUs are only supported on Linux. Exiting...")217            sys.exit(1)218    elif is_linux() and (choice == "C" or choice == "N"):219        install_pytorch = "python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu"220    elif choice == "D":221        install_pytorch = "python -m pip install torch==2.1.0a0 torchvision==0.16.0a0 intel_extension_for_pytorch==2.1.10+xpu --extra-index-url https://pytorch-extension.intel.com/release-whl/stable/xpu/us/"222 223    # Install Git and then Pytorch224    print_big_message("Installing PyTorch.")225    run_cmd(f"{install_git} && {install_pytorch} && python -m pip install py-cpuinfo==9.0.0", assert_success=True, environment=True)226 227    # Install CUDA libraries (this wasn't necessary for Pytorch before...)228    if choice == "A":229        print_big_message("Installing the CUDA runtime libraries.")230        run_cmd(f"conda install -y -c \"nvidia/label/{'cuda-12.1.1' if use_cuda118 == 'N' else 'cuda-11.8.0'}\" cuda-runtime", assert_success=True, environment=True)231 232    # Install the webui requirements233    update_requirements(initial_installation=True)234 235 236def update_requirements(initial_installation=False):237    # Create .git directory if missing238    if not os.path.isdir(os.path.join(script_dir, ".git")):239        git_creation_cmd = 'git init -b main && git remote add origin https://github.com/oobabooga/text-generation-webui && git fetch && git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main && git reset --hard origin/main && git branch --set-upstream-to=origin/main'240        run_cmd(git_creation_cmd, environment=True, assert_success=True)241 242    files_to_check = [243        'start_linux.sh', 'start_macos.sh', 'start_windows.bat', 'start_wsl.bat',244        'update_linux.sh', 'update_macos.sh', 'update_windows.bat', 'update_wsl.bat',245        'one_click.py'246    ]247 248    before_pull_hashes = {file_name: calculate_file_hash(file_name) for file_name in files_to_check}249    run_cmd("git pull --autostash", assert_success=True, environment=True)250    after_pull_hashes = {file_name: calculate_file_hash(file_name) for file_name in files_to_check}251 252    # Check for differences in installation file hashes253    for file_name in files_to_check:254        if before_pull_hashes[file_name] != after_pull_hashes[file_name]:255            print_big_message(f"File '{file_name}' was updated during 'git pull'. Please run the script again.")256            exit(1)257 258    # Extensions requirements are installed only during the initial install by default.259    # That can be changed with the INSTALL_EXTENSIONS environment variable.260    install = initial_installation261    if "INSTALL_EXTENSIONS" in os.environ:262        install = os.environ["INSTALL_EXTENSIONS"].lower() in ("yes", "y", "true", "1", "t", "on")263 264    if install:265        print_big_message("Installing extensions requirements.")266        skip = ['superbooga', 'superboogav2', 'coqui_tts']  # Fail to install on Windows267        extensions = [foldername for foldername in os.listdir('extensions') if os.path.isfile(os.path.join('extensions', foldername, 'requirements.txt'))]268        extensions = [x for x in extensions if x not in skip]269        for i, extension in enumerate(extensions):270            print(f"\n\n--- [{i+1}/{len(extensions)}]: {extension}\n\n")271            extension_req_path = os.path.join("extensions", extension, "requirements.txt")272            run_cmd("python -m pip install -r " + extension_req_path + " --upgrade", assert_success=False, environment=True)273    elif initial_installation:274        print_big_message("Will not install extensions due to INSTALL_EXTENSIONS environment variable.")275 276    # Detect the Python and PyTorch versions277    torver = torch_version()278    is_cuda = '+cu' in torver279    is_cuda118 = '+cu118' in torver  # 2.1.0+cu118280    is_cuda117 = '+cu117' in torver  # 2.0.1+cu117281    is_rocm = '+rocm' in torver  # 2.0.1+rocm5.4.2282    is_intel = '+cxx11' in torver  # 2.0.1a0+cxx11.abi283    is_cpu = '+cpu' in torver  # 2.0.1+cpu284 285    if is_rocm:286        if cpu_has_avx2():287            requirements_file = "requirements_amd.txt"288        else:289            requirements_file = "requirements_amd_noavx2.txt"290    elif is_cpu:291        if cpu_has_avx2():292            requirements_file = "requirements_cpu_only.txt"293        else:294            requirements_file = "requirements_cpu_only_noavx2.txt"295    elif is_macos():296        if is_x86_64():297            requirements_file = "requirements_apple_intel.txt"298        else:299            requirements_file = "requirements_apple_silicon.txt"300    else:301        if cpu_has_avx2():302            requirements_file = "requirements.txt"303        else:304            requirements_file = "requirements_noavx2.txt"305 306    print_big_message(f"Installing webui requirements from file: {requirements_file}")307    print(f"TORCH: {torver}\n")308 309    # Prepare the requirements file310    textgen_requirements = open(requirements_file).read().splitlines()311    if is_cuda117:312        textgen_requirements = [req.replace('+cu121', '+cu117').replace('+cu122', '+cu117').replace('torch2.1', 'torch2.0') for req in textgen_requirements]313    elif is_cuda118:314        textgen_requirements = [req.replace('+cu121', '+cu118').replace('+cu122', '+cu118') for req in textgen_requirements]315    if is_windows() and (is_cuda117 or is_cuda118):  # No flash-attention on Windows for CUDA 11316        textgen_requirements = [req for req in textgen_requirements if 'jllllll/flash-attention' not in req]317 318    with open('temp_requirements.txt', 'w') as file:319        file.write('\n'.join(textgen_requirements))320 321    # Workaround for git+ packages not updating properly.322    git_requirements = [req for req in textgen_requirements if req.startswith("git+")]323    for req in git_requirements:324        url = req.replace("git+", "")325        package_name = url.split("/")[-1].split("@")[0].rstrip(".git")326        run_cmd("python -m pip uninstall -y " + package_name, environment=True)327        print(f"Uninstalled {package_name}")328 329    # Make sure that API requirements are installed (temporary)330    extension_req_path = os.path.join("extensions", "openai", "requirements.txt")331    if os.path.exists(extension_req_path):332        run_cmd("python -m pip install -r " + extension_req_path + " --upgrade", environment=True)333 334    # Install/update the project requirements335    run_cmd("python -m pip install -r temp_requirements.txt --upgrade", assert_success=True, environment=True)336    os.remove('temp_requirements.txt')337 338    # Check for '+cu' or '+rocm' in version string to determine if torch uses CUDA or ROCm. Check for pytorch-cuda as well for backwards compatibility339    if not any((is_cuda, is_rocm)) and run_cmd("conda list -f pytorch-cuda | grep pytorch-cuda", environment=True, capture_output=True).returncode == 1:340        clear_cache()341        return342 343    if not os.path.exists("repositories/"):344        os.mkdir("repositories")345 346    os.chdir("repositories")347 348    # Install or update ExLlama as needed349    if not os.path.exists("exllama/"):350        run_cmd("git clone https://github.com/turboderp/exllama.git", environment=True)351    else:352        os.chdir("exllama")353        run_cmd("git pull", environment=True)354        os.chdir("..")355 356    if is_linux():357        # Fix JIT compile issue with ExLlama in Linux/WSL358        if not os.path.exists(f"{conda_env_path}/lib64"):359            run_cmd(f'ln -s "{conda_env_path}/lib" "{conda_env_path}/lib64"', environment=True)360 361        # On some Linux distributions, g++ may not exist or be the wrong version to compile GPTQ-for-LLaMa362        gxx_output = run_cmd("g++ -dumpfullversion -dumpversion", environment=True, capture_output=True)363        if gxx_output.returncode != 0 or int(gxx_output.stdout.strip().split(b".")[0]) > 11:364            # Install the correct version of g++365            run_cmd("conda install -y -k conda-forge::gxx_linux-64=11.2.0", environment=True)366 367    clear_cache()368 369 370def download_model():371    run_cmd("python download-model.py", environment=True)372 373 374def launch_webui():375    run_cmd(f"python server.py {flags}", environment=True)376 377 378if __name__ == "__main__":379    # Verifies we are in a conda environment380    check_env()381 382    parser = argparse.ArgumentParser(add_help=False)383    parser.add_argument('--update', action='store_true', help='Update the web UI.')384    args, _ = parser.parse_known_args()385 386    if args.update:387        update_requirements()388    else:389        # If webui has already been installed, skip and run390        if not is_installed():391            install_webui()392            os.chdir(script_dir)393 394        if os.environ.get("LAUNCH_AFTER_INSTALL", "").lower() in ("no", "n", "false", "0", "f", "off"):395            print_big_message("Install finished successfully and will now exit due to LAUNCH_AFTER_INSTALL.")396            sys.exit()397 398        # Check if a model has been downloaded yet399        if '--model-dir' in flags:400            # Splits on ' ' or '=' while maintaining spaces within quotes401            flags_list = re.split(' +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)|=', flags)402            model_dir = [flags_list[(flags_list.index(flag)+1)] for flag in flags_list if flag == '--model-dir'][0].strip('"\'')403        else:404            model_dir = 'models'405 406        if len([item for item in glob.glob(f'{model_dir}/*') if not item.endswith(('.txt', '.yaml'))]) == 0:407            print_big_message("WARNING: You haven't downloaded any model yet.\nOnce the web UI launches, head over to the \"Model\" tab and download one.")408 409        # Workaround for llama-cpp-python loading paths in CUDA env vars even if they do not exist410        conda_path_bin = os.path.join(conda_env_path, "bin")411        if not os.path.exists(conda_path_bin):412            os.mkdir(conda_path_bin)413 414        # Launch the webui415        launch_webui()416