diff --git a/aiserver.py b/aiserver.py index 913bea5c..85523734 100644 --- a/aiserver.py +++ b/aiserver.py @@ -120,15 +120,14 @@ def new_init(self, *args, **kwargs): self.ncols = 99 tqdm.__init__ = new_init -# Fix some issues with the OPT tokenizer +# Add _koboldai_header support for some optional tokenizer fixes +# This used to be an OPT tokenizer fix, this has been moved search for "# These are model specific overrides if a model has bad defaults" for the new section from transformers import PreTrainedTokenizerBase old_pretrainedtokenizerbase_from_pretrained = PreTrainedTokenizerBase.from_pretrained.__func__ @classmethod def new_pretrainedtokenizerbase_from_pretrained(cls, *args, **kwargs): tokenizer = old_pretrainedtokenizerbase_from_pretrained(cls, *args, **kwargs) - tokenizer._koboldai_header = tokenizer.encode("") - tokenizer.add_bos_token = False - tokenizer.add_prefix_space = False + tokenizer._koboldai_header = [] return tokenizer PreTrainedTokenizerBase.from_pretrained = new_pretrainedtokenizerbase_from_pretrained @@ -3387,10 +3386,14 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal # koboldai_vars.badwordsids.append([vocab[key]]) # These are model specific overrides if a model has bad defaults + tokenizer._koboldai_header = [] if koboldai_vars.model_type == "llama": tokenizer.decode_with_prefix_space = True tokenizer.add_bos_token = False - + if koboldai_vars.model_type == "opt": + tokenizer._koboldai_header = tokenizer.encode("") + tokenizer.add_bos_token = False + tokenizer.add_prefix_space = False logger.info(f"Pipeline created: {koboldai_vars.model}") else: @@ -3626,7 +3629,8 @@ def is_allowed_ip(): client_ip = request.remote_addr if request.path != '/genre_data.json': print("Connection Attempt: " + request.remote_addr) - print("Allowed?: ", request.remote_addr in allowed_ips) + if allowed_ips: + print("Allowed?: ", request.remote_addr in allowed_ips) return client_ip in allowed_ips @@ -4325,7 +4329,8 @@ def execute_outmod(): @socketio.on('connect') def do_connect(): print("Connection Attempt: " + request.remote_addr) - print("Allowed?: ", request.remote_addr in allowed_ips) + if allowed_ips: + print("Allowed?: ", request.remote_addr in allowed_ips) if request.args.get("rely") == "true": return logger.info("Client connected! UI_{}".format(request.args.get('ui'))) @@ -7588,13 +7593,13 @@ def loadRequest(loadpath, filename=None): if not loadpath: return - + #Original UI only sends the story name and assumes it's always a .json file... here we check to see if it's a directory to load that way - if not os.path.exists(loadpath): + if not isinstance(loadpath, dict) and not os.path.exists(loadpath): if os.path.exists(loadpath.replace(".json", "")): loadpath = loadpath.replace(".json", "") - if os.path.isdir(loadpath): + if not isinstance(loadpath, dict) and os.path.isdir(loadpath): if not valid_v3_story(loadpath): raise RuntimeError(f"Tried to load {loadpath}, a non-save directory.") koboldai_vars.update_story_path_structure(loadpath) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index c6c1e5ba..3c6b9706 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -39,8 +39,6 @@ "\n", "For more information about KoboldAI check our our Github readme : https://github.com/KoboldAI/KoboldAI-Client/blob/main/readme.md\n", "\n", - "For the larger AI models (That are typically more coherent) check out our **[TPU edition](https://colab.research.google.com/github/KoboldAI/KoboldAI-Client/blob/main/colab/TPU.ipynb)**!\n", - "\n", "---\n", "## How to load KoboldAI: Everything you need to know\n", "1. On a phone? First put your browser in desktop mode because of a Google Colab bug. Otherwise nothing will happen when you click the play button. Then tap the play button next to \"<-- Tap This if you play on Mobile\", you will see an audio player. Keep the audio player playing so Colab does not get shut down in the background.\n", @@ -210,22 +208,6 @@ "| [Fairseq Dense](https://huggingface.co/KoboldAI/fairseq-dense-2.7B) | Generic | Trained by Facebook Researchers this model stems from the MOE research project within Fairseq. This particular version has been converted by us for use in KoboldAI. It is known to be on par with the larger models from EleutherAI and considered as better for pop culture and language tasks. Because the model has never seen a new line (enter) it may perform worse on formatting and paragraphing. Compared to other models the dataset focuses primarily on literature and contains little else. |\n", "| [Neo](https://huggingface.co/EleutherAI/gpt-neo-2.7B) by EleutherAI | Generic | This is the base model for all the other 2.7B models, it is best used when you have a use case that we have no other models available for, such as writing blog articles or programming. It can also be a good basis for the experience of some of the softprompts if your softprompt is not about a subject the other models cover. |\n", "\n", - "# [TPU Edition Model Descriptions](https://colab.research.google.com/github/KoboldAI/KoboldAI-Client/blob/main/colab/TPU.ipynb)\n", - "\n", - "| Model | Style | Description |\n", - "| --- | --- | --- |\n", - "| [Nerys](https://huggingface.co/KoboldAI/fairseq-dense-13B-Nerys) by Mr Seeker | Novel/Adventure | Nerys is a hybrid model based on Pike (A newer Janeway), on top of the Pike dataset you also get some Light Novels, Adventure mode support and a little bit of Shinen thrown in the mix. The end result is a very diverse model that is heavily biased towards SFW novel writing, but one that can go beyond its novel training and make for an excellent adventure model to. Adventure mode is best played from a second person perspective, but can be played in first or third person as well. Novel writing can be done best from the first or third person. |\n", - "| [Erebus](https://huggingface.co/KoboldAI/OPT-13B-Erebus) by Mr Seeker | NSFW | Erebus is our community's flagship NSFW model, being a combination of multiple large datasets that include Literotica, Shinen and erotic novels from Nerys and featuring thourough tagging support it covers the vast majority of erotic writing styles. This model is capable of replacing both the Lit and Shinen models in terms of content and style and has been well received as (one of) the best NSFW models out there. If you wish to use this model for commercial or non research usage we recommend choosing the 20B version as that one is not subject to the restrictive OPT license. |\n", - "| [Janeway](https://huggingface.co/KoboldAI/fairseq-dense-13B-Janeway) by Mr Seeker | Novel | Janeway is a model created from Picard's dataset combined with a brand new collection of ebooks. This model is trained on 20% more content than Picard and has been trained on literature from various genres. Although the model is mainly focussed on SFW, romantic scenes might involve a degree of nudity. |\n", - "| [Shinen](https://huggingface.co/KoboldAI/fairseq-dense-13B-Shinen) by Mr Seeker | NSFW | Shinen is an NSFW model trained on a variety of stories from the website Sexstories it contains many different kinks. It has been merged into the larger (and better) Erebus model. |\n", - "| [Skein](https://huggingface.co/KoboldAI/GPT-J-6B-Skein) by VE\\_FORBRYDERNE | Adventure | Skein is best used with Adventure mode enabled, it consists of a 4 times larger adventure dataset than the Adventure model making it excellent for text adventure gaming. On top of that it also consists of light novel training further expanding its knowledge and writing capabilities. It can be used with the You filter bias if you wish to write Novels with it, but dedicated Novel models can perform better for this task. |\n", - "| [Adventure](https://huggingface.co/KoboldAI/GPT-J-6B-Adventure) by VE\\_FORBRYDERNE | Adventure | Adventure is a 6B model designed to mimick the behavior of AI Dungeon. It is exclusively for Adventure Mode and can take you on the epic and wackey adventures that AI Dungeon players love. It also features the many tropes of AI Dungeon as it has been trained on very similar data. It must be used in second person (You). |\n", - "| [Lit](https://huggingface.co/hakurei/lit-6B) by Haru | NSFW | Lit is a great NSFW model trained by Haru on both a large set of Literotica stories and high quality novels along with tagging support. Creating a high quality model for your NSFW stories. This model is exclusively a novel model and is best used in third person. |\n", - "| [OPT](https://huggingface.co/facebook/opt-13b) by Metaseq | Generic | OPT is considered one of the best base models as far as content goes, its behavior has the strengths of both GPT-Neo and Fairseq Dense. Compared to Neo duplicate and unnecessary content has been left out, while additional literature was added in similar to the Fairseq Dense model. The Fairseq Dense model however lacks the broader data that OPT does have. The biggest downfall of OPT is its license, which prohibits any commercial usage, or usage beyond research purposes. |\n", - "| [Neo(X)](https://huggingface.co/EleutherAI/gpt-neox-20b) by EleutherAI | Generic | NeoX is the largest EleutherAI model currently available, being a generic model it is not particularly trained towards anything and can do a variety of writing, Q&A and coding tasks. 20B's performance is closely compared to the 13B models and it is worth trying both especially if you have a task that does not involve english writing. Its behavior will be similar to the GPT-J-6B model since they are trained on the same dataset but with more sensitivity towards repetition penalty and with more knowledge. |\n", - "| [Fairseq Dense](https://huggingface.co/KoboldAI/fairseq-dense-13B) | Generic | Trained by Facebook Researchers this model stems from the MOE research project within Fairseq. This particular version has been converted by us for use in KoboldAI. It is known to be on par with the larger 20B model from EleutherAI and considered as better for pop culture and language tasks. Because the model has never seen a new line (enter) it may perform worse on formatting and paragraphing. Compared to other models the dataset focuses primarily on literature and contains little else. |\n", - "| [GPT-J-6B](https://huggingface.co/EleutherAI/gpt-j-6B) by EleutherAI | Generic | This model serves as the basis for most other 6B models (Some being based on Fairseq Dense instead). Being trained on the Pile and not biased towards anything in particular it is suitable for a variety of tasks such as writing, Q&A and coding tasks. You will likely get better result with larger generic models or finetuned models. |\n", - "\n", "| Style | Description |\n", "| --------- | ------------------------------------------------------------ |\n", "| Novel | For regular story writing, not compatible with Adventure mode or other specialty modes. |\n", diff --git a/colab/TPU.ipynb b/colab/TPU.ipynb index 48fc7bdc..20d0aba9 100644 --- a/colab/TPU.ipynb +++ b/colab/TPU.ipynb @@ -2,30 +2,7 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "id": "view-in-github", - "colab_type": "text" - }, "source": [ - "\"Open" - ] - }, - { - "cell_type": "markdown", - "source": [ - "# GOOGLE HAS BROKEN SUPPORT FOR MESH TRANSFORMERS JAX IN THEIR DRIVER, THIS MESSAGE WILL BE REMOVED ONCE THE NOTEBOOK WORKS AGAIN\n", - "---\n", - "Are you a developer familair with Jax? We could use some help.\n", - "Our Mesh Transformers Jax fork resides here (but unfortunately VE-Forbryderne has gone missing) : https://github.com/VE-FORBRYDERNE/mesh-transformer-jax\n", - "\n", - "This is combined with the TPU backend code you can find here: https://github.com/KoboldAI/KoboldAI-Client/blob/main/tpu_mtj_backend.py\n", - "\n", - "So far we know the driver initialization issues can be resolved when a newer version of Jax is used combined with a slight edit to tpu_mtj_backend.py to use Jax's built in code for driver intialization (Which is not present in the older version we currently use, hence that part being in our file).\n", - "\n", - "As far as we understand the issue is that xmap was broken in newer versions, and MTJ makes use of it. If someone can port this part of the code to be compatible with the newer Jax versions you can save this notebook!\n", - "\n", - "(Or Google, if you are reading this. Please reintroduce the old 0.1 compatibility since you broke an entire ecosystem of Mesh Transformers Jax users, which has historic value because it is the original implementation of GPT-J. There also do not seem to be alternatives that have the same amount of performance and model compatibility).\n", - "\n", "# Welcome to KoboldAI on Google Colab, TPU Edition!\n", "KoboldAI is a powerful and easy way to use a variety of AI based text generation experiences. You can use it to write stories, blog posts, play a text adventure game, use it like a chatbot and more! In some cases it might even help you with an assignment or programming task (But always make sure the information the AI mentions is correct, it loves to make stuff up).\n", "\n", @@ -258,8 +235,7 @@ "colab": { "name": "ColabKobold TPU", "provenance": [], - "private_outputs": true, - "include_colab_link": true + "private_outputs": true }, "kernelspec": { "display_name": "Python 3", diff --git a/commandline-rocm.sh b/commandline-rocm.sh index 5c9a54aa..d34ca445 100755 --- a/commandline-rocm.sh +++ b/commandline-rocm.sh @@ -1 +1,3 @@ +export CONDA_AUTO_ACTIVATE_BASE=false +export PYTHONNOUSERSITE=1 bin/micromamba run -r runtime -n koboldai-rocm bash diff --git a/commandline.sh b/commandline.sh index 72338169..80cf9868 100755 --- a/commandline.sh +++ b/commandline.sh @@ -1 +1,3 @@ +export CONDA_AUTO_ACTIVATE_BASE=false +export PYTHONNOUSERSITE=1 bin/micromamba run -r runtime -n koboldai bash diff --git a/install_git_transformers.bat b/install_git_transformers.bat index 3e154b80..8c6257cc 100644 --- a/install_git_transformers.bat +++ b/install_git_transformers.bat @@ -1,6 +1,10 @@ @echo off cd /D %~dp0 + +:Isolation SET CONDA_SHLVL= +SET PYTHONNOUSERSITE=1 +SET PYTHONPATH= TITLE KoboldAI - Git Transformers Installer ECHO This script will replace the Transformers version with the latest Git Transformers which may contain breaking changes. diff --git a/install_requirements.bat b/install_requirements.bat index 2a4534c1..69e4a47a 100644 --- a/install_requirements.bat +++ b/install_requirements.bat @@ -8,7 +8,11 @@ echo. Reg add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v "LongPathsEnabled" /t REG_DWORD /d "1" /f 2>nul cd /D %~dp0 + +:Isolation SET CONDA_SHLVL= +SET PYTHONNOUSERSITE=1 +SET PYTHONPATH= if exist miniconda3\ ( echo Delete existing installation? diff --git a/install_requirements.sh b/install_requirements.sh index 6f0e0dfd..6e37c7e9 100755 --- a/install_requirements.sh +++ b/install_requirements.sh @@ -1,13 +1,14 @@ #!/bin/bash +export PYTHONNOUSERSITE=1 git submodule update --init --recursive -if [[ $1 = "cuda" ]]; then +if [[ $1 = "cuda" || $1 = "CUDA" ]]; then wget -qO- https://micromamba.snakepit.net/api/micromamba/linux-64/latest | tar -xvj bin/micromamba bin/micromamba create -f environments/huggingface.yml -r runtime -n koboldai -y # Weird micromamba bug causes it to fail the first time, running it twice just to be safe, the second time is much faster bin/micromamba create -f environments/huggingface.yml -r runtime -n koboldai -y exit fi -if [[ $1 = "rocm" ]]; then +if [[ $1 = "rocm" || $1 = "ROCM" ]]; then wget -qO- https://micromamba.snakepit.net/api/micromamba/linux-64/latest | tar -xvj bin/micromamba bin/micromamba create -f environments/rocm.yml -r runtime -n koboldai-rocm -y # Weird micromamba bug causes it to fail the first time, running it twice just to be safe, the second time is much faster diff --git a/koboldai_settings.py b/koboldai_settings.py index 2c9ac9db..65b88b87 100644 --- a/koboldai_settings.py +++ b/koboldai_settings.py @@ -1203,14 +1203,15 @@ class undefined_settings(settings): class system_settings(settings): local_only_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', - 'lua_koboldcore', 'regex_sl', 'acregex_ai', 'acregex_ui', 'comregex_ai', - 'comregex_ui', 'sp', '_horde_pid', 'inference_config', 'image_pipeline', - 'summarizer', 'summary_tokenizer', 'tts_model', 'rng_states'] + 'lua_koboldcore', 'regex_sl', 'acregex_ai', 'acregex_ui', 'comregex_ai', 'comregex_ui', + 'sp', '_horde_pid', 'inference_config', 'image_pipeline', + 'summarizer', 'summary_tokenizer', 'tts_model', 'rng_states', 'comregex_ai', 'comregex_ui'] no_save_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', 'lua_koboldcore', 'sp', 'sp_length', '_horde_pid', 'horde_share', 'aibusy', 'serverstarted', 'inference_config', 'image_pipeline', 'summarizer', 'summary_tokenizer', 'use_colab_tpu', 'noai', 'disable_set_aibusy', 'cloudflare_link', 'tts_model', - 'generating_image', 'bit_8_available', 'bit_4_available', 'host', 'hascuda', 'usegpu', 'rng_states'] + 'generating_image', 'bit_8_available', 'bit_4_available', 'host', 'hascuda', 'usegpu', 'rng_states', + 'comregex_ai', 'comregex_ui'] settings_name = "system" def __init__(self, socketio, koboldai_var): self._socketio = socketio @@ -1252,8 +1253,8 @@ class system_settings(settings): self.regex_sl = re.compile(r'\n*(?<=.) *\n(.|\n)*') # Pattern for limiting the output to a single line self.acregex_ai = re.compile(r'\n* *>(.|\n)*') # Pattern for matching adventure actions from the AI so we can remove them self.acregex_ui = re.compile(r'^ *(>.*)$', re.MULTILINE) # Pattern for matching actions in the HTML-escaped story so we can apply colouring, etc (make sure to encase part to format in parentheses) - self.comregex_ai = re.compile(r'(?:\n<\|(?:.|\n)*?\|>(?=\n|$))|(?:<\|(?:.|\n)*?\|>\n?)') # Pattern for matching comments to remove them before sending them to the AI - self.comregex_ui = re.compile(r'(<\|(?:.|\n)*?\|>)') # Pattern for matching comments in the editor + self.comregex_ai = re.compile(r'(?:\n\[<\|(?:.|\n)*?\|>\](?=\n|$))|(?:\[<\|(?:.|\n)*?\|>\]\n?)') # Pattern for matching comments to remove them before sending them to the AI + self.comregex_ui = re.compile(r'(\[<\|(?:.|\n)*?\|>\])') # Pattern for matching comments in the editor self.host = False self.flaskwebgui = False self.quiet = False # If set will suppress any story text from being printed to the console (will only be seen on the client web page) diff --git a/play-rocm.sh b/play-rocm.sh index 6cf2794a..e0753edc 100755 --- a/play-rocm.sh +++ b/play-rocm.sh @@ -1,4 +1,5 @@ #!/bin/bash +export PYTHONNOUSERSITE=1 if [ ! -f "runtime/envs/koboldai-rocm/bin/python" ]; then ./install_requirements.sh rocm fi diff --git a/play.sh b/play.sh index 10f3c8aa..8ce7b781 100755 --- a/play.sh +++ b/play.sh @@ -1,4 +1,5 @@ #!/bin/bash +export PYTHONNOUSERSITE=1 if [ ! -f "runtime/envs/koboldai/bin/python" ]; then ./install_requirements.sh cuda fi diff --git a/requirements_mtj.txt b/requirements_mtj.txt index 37b76a23..19da3910 100644 --- a/requirements_mtj.txt +++ b/requirements_mtj.txt @@ -2,9 +2,9 @@ torch >= 1.9, < 1.13 numpy tqdm requests -dm-haiku == 0.0.5 -jax == 0.2.21 -jaxlib >= 0.1.69, <= 0.3.7 +dm-haiku==0.0.9 +jax==0.3.25 +jaxlib==0.3.25 transformers == 4.28.0 chex == 0.1.5 huggingface_hub==0.12.1 diff --git a/tpu_mtj_backend.py b/tpu_mtj_backend.py index 02754d95..d8edb92f 100644 --- a/tpu_mtj_backend.py +++ b/tpu_mtj_backend.py @@ -1095,7 +1095,7 @@ def read_neox_checkpoint(state, path, config, checkpoint_shards=2): koboldai_vars.status_message = "" -def load_model(path: str, driver_version="tpu_driver0.1_dev20210607", hf_checkpoint=False, socketio_queue=None, initial_load=False, logger=None, **kwargs) -> None: +def load_model(path: str, driver_version="tpu_driver_20221109", hf_checkpoint=False, socketio_queue=None, initial_load=False, logger=None, **kwargs) -> None: global thread_resources_env, seq, tokenizer, network, params, pad_token_id if "pad_token_id" in kwargs: @@ -1270,11 +1270,6 @@ def load_model(path: str, driver_version="tpu_driver0.1_dev20210607", hf_checkpo logger.message(f"KoboldAI has finished loading and is available at the following link for UI 1: {koboldai_vars.cloudflare_link}") logger.message(f"KoboldAI has finished loading and is available at the following link for UI 2: {koboldai_vars.cloudflare_link}/new_ui") - - global shard_xmap, batch_xmap - shard_xmap = __shard_xmap() - batch_xmap = __batch_xmap(shard_dim=cores_per_replica) - global badwords # These are the tokens that we don't want the AI to ever write badwords = jnp.array(koboldai_vars.badwordsids).squeeze() @@ -1401,19 +1396,20 @@ def load_model(path: str, driver_version="tpu_driver0.1_dev20210607", hf_checkpo #if "no_transpose" not in transforms and tensor.ndim == 2: # tensor = tensor.T tensor.unsqueeze_(0) - if tensor.dtype is torch.float16 or tensor.dtype is torch.float32: - tensor = tensor.bfloat16() + # Shard the tensor so that parts of the tensor can be used # on different TPU cores + tensor = reshard_reverse( + tensor, + params["cores_per_replica"], + network.state["params"][spec["module"]][spec["param"]].shape, + ) + tensor = jnp.array(tensor.detach()) + if tensor.dtype is torch.float16 or tensor.dtype is torch.float32: + tensor = tensor.bfloat16() network.state["params"][spec["module"]][spec["param"]] = move_xmap( - jax.dlpack.from_dlpack(torch.utils.dlpack.to_dlpack( - reshard_reverse( - tensor, - params["cores_per_replica"], - network.state["params"][spec["module"]][spec["param"]].shape, - ) - )).copy(), + tensor, np.empty(params["cores_per_replica"]), ) @@ -1506,3 +1502,6 @@ def load_model(path: str, driver_version="tpu_driver0.1_dev20210607", hf_checkpo model = GPTNeoForCausalLM.from_pretrained(koboldai_vars.model, revision=koboldai_vars.revision, cache_dir="cache") #network.state = network.move_xmap(network.state, np.zeros(cores_per_replica)) + global shard_xmap, batch_xmap + shard_xmap = __shard_xmap() + batch_xmap = __batch_xmap(shard_dim=cores_per_replica)