From c4cb55a0c561a71f4f0502b653964e0d631ab9b8 Mon Sep 17 00:00:00 2001 From: Zander Chase <130414180+vowelparrot@users.noreply.github.com> Date: Mon, 1 May 2023 20:42:45 -0700 Subject: [PATCH] [Breaking] Migrate GPT4All to use PyGPT4All (#3934) Seems the pyllamacpp package is no longer the supported bindings from gpt4all. Tested that this works locally. Given that the older models weren't very performant, I think it's better to migrate now without trying to include a lot of try / except blocks --------- Co-authored-by: Nissan Pow Co-authored-by: Nissan Pow --- .../models/llms/integrations/gpt4all.ipynb | 342 +++++++++--------- langchain/llms/gpt4all.py | 10 +- tests/integration_tests/llms/test_gpt4all.py | 13 +- 3 files changed, 178 insertions(+), 187 deletions(-) diff --git a/docs/modules/models/llms/integrations/gpt4all.ipynb b/docs/modules/models/llms/integrations/gpt4all.ipynb index 73bbd9b9..c67670e3 100644 --- a/docs/modules/models/llms/integrations/gpt4all.ipynb +++ b/docs/modules/models/llms/integrations/gpt4all.ipynb @@ -1,173 +1,173 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# GPT4All\n", - "\n", - "[GitHub:nomic-ai/gpt4all](https://github.com/nomic-ai/gpt4all) an ecosystem of open-source chatbots trained on a massive collections of clean assistant data including code, stories and dialogue.\n", - "\n", - "This example goes over how to use LangChain to interact with `GPT4All` models." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "%pip install pyllamacpp > /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from langchain import PromptTemplate, LLMChain\n", - "from langchain.llms import GPT4All\n", - "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "template = \"\"\"Question: {question}\n", - "\n", - "Answer: Let's think step by step.\"\"\"\n", - "\n", - "prompt = PromptTemplate(template=template, input_variables=[\"question\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Specify Model\n", - "\n", - "To run locally, download a compatible ggml-formatted model. For more info, visit https://github.com/nomic-ai/pyllamacpp\n", - "\n", - "For full installation instructions go [here](https://gpt4all.io/index.html).\n", - "\n", - "The GPT4All Chat installer needs to decompress a 3GB LLM model during the installation process!\n", - "\n", - "Note that new models are uploaded regularly - check the link above for the most recent `.bin` URL" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "local_path = './models/gpt4all-lora-quantized-ggml.bin' # replace with your desired local file path" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Uncomment the below block to download a model. You may want to update `url` to a new version." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# import requests\n", - "\n", - "# from pathlib import Path\n", - "# from tqdm import tqdm\n", - "\n", - "# Path(local_path).parent.mkdir(parents=True, exist_ok=True)\n", - "\n", - "# # Example model. Check https://github.com/nomic-ai/pyllamacpp for the latest models.\n", - "# url = 'https://the-eye.eu/public/AI/models/nomic-ai/gpt4all/gpt4all-lora-quantized-ggml.bin'\n", - "\n", - "# # send a GET request to the URL to download the file. Stream since it's large\n", - "# response = requests.get(url, stream=True)\n", - "\n", - "# # open the file in binary mode and write the contents of the response to it in chunks\n", - "# # This is a large file, so be prepared to wait.\n", - "# with open(local_path, 'wb') as f:\n", - "# for chunk in tqdm(response.iter_content(chunk_size=8192)):\n", - "# if chunk:\n", - "# f.write(chunk)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Callbacks support token-wise streaming\n", - "callbacks = [StreamingStdOutCallbackHandler()]\n", - "# Verbose is required to pass to the callback manager\n", - "llm = GPT4All(model=local_path, callbacks=callbacks, verbose=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "llm_chain = LLMChain(prompt=prompt, llm=llm)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "question = \"What NFL team won the Super Bowl in the year Justin Bieber was born?\"\n", - "\n", - "llm_chain.run(question)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GPT4All\n", + "\n", + "[GitHub:nomic-ai/gpt4all](https://github.com/nomic-ai/gpt4all) an ecosystem of open-source chatbots trained on a massive collections of clean assistant data including code, stories and dialogue.\n", + "\n", + "This example goes over how to use LangChain to interact with `GPT4All` models." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install pygpt4all > /dev/null" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from langchain import PromptTemplate, LLMChain\n", + "from langchain.llms import GPT4All\n", + "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "template = \"\"\"Question: {question}\n", + "\n", + "Answer: Let's think step by step.\"\"\"\n", + "\n", + "prompt = PromptTemplate(template=template, input_variables=[\"question\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Specify Model\n", + "\n", + "To run locally, download a compatible ggml-formatted model. For more info, visit https://github.com/nomic-ai/pygpt4all\n", + "\n", + "For full installation instructions go [here](https://gpt4all.io/index.html).\n", + "\n", + "The GPT4All Chat installer needs to decompress a 3GB LLM model during the installation process!\n", + "\n", + "Note that new models are uploaded regularly - check the link above for the most recent `.bin` URL" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "local_path = './models/ggml-gpt4all-l13b-snoozy.bin' # replace with your desired local file path" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Uncomment the below block to download a model. You may want to update `url` to a new version." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# import requests\n", + "\n", + "# from pathlib import Path\n", + "# from tqdm import tqdm\n", + "\n", + "# Path(local_path).parent.mkdir(parents=True, exist_ok=True)\n", + "\n", + "# # Example model. Check https://github.com/nomic-ai/pygpt4all for the latest models.\n", + "# url = 'http://gpt4all.io/models/ggml-gpt4all-l13b-snoozy.bin'\n", + "\n", + "# # send a GET request to the URL to download the file. Stream since it's large\n", + "# response = requests.get(url, stream=True)\n", + "\n", + "# # open the file in binary mode and write the contents of the response to it in chunks\n", + "# # This is a large file, so be prepared to wait.\n", + "# with open(local_path, 'wb') as f:\n", + "# for chunk in tqdm(response.iter_content(chunk_size=8192)):\n", + "# if chunk:\n", + "# f.write(chunk)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Callbacks support token-wise streaming\n", + "callbacks = [StreamingStdOutCallbackHandler()]\n", + "# Verbose is required to pass to the callback manager\n", + "llm = GPT4All(model=local_path, callbacks=callbacks, verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "llm_chain = LLMChain(prompt=prompt, llm=llm)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "question = \"What NFL team won the Super Bowl in the year Justin Bieber was born?\"\n", + "\n", + "llm_chain.run(question)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 } diff --git a/langchain/llms/gpt4all.py b/langchain/llms/gpt4all.py index ff3a6a5d..845f9018 100644 --- a/langchain/llms/gpt4all.py +++ b/langchain/llms/gpt4all.py @@ -12,7 +12,7 @@ from langchain.llms.utils import enforce_stop_tokens class GPT4All(LLM): r"""Wrapper around GPT4All language models. - To use, you should have the ``pyllamacpp`` python package installed, the + To use, you should have the ``pygpt4all`` python package installed, the pre-trained model file, and the model's config information. Example: @@ -126,19 +126,19 @@ class GPT4All(LLM): def validate_environment(cls, values: Dict) -> Dict: """Validate that the python package exists in the environment.""" try: - from pyllamacpp.model import Model as GPT4AllModel + from pygpt4all.models.gpt4all import GPT4All as GPT4AllModel llama_keys = cls._llama_param_names() model_kwargs = {k: v for k, v in values.items() if k in llama_keys} values["client"] = GPT4AllModel( - ggml_model=values["model"], + model_path=values["model"], **model_kwargs, ) except ImportError: raise ValueError( - "Could not import pyllamacpp python package. " - "Please install it with `pip install pyllamacpp`." + "Could not import pygpt4all python package. " + "Please install it with `pip install pygpt4all`." ) return values diff --git a/tests/integration_tests/llms/test_gpt4all.py b/tests/integration_tests/llms/test_gpt4all.py index f338355d..c61792de 100644 --- a/tests/integration_tests/llms/test_gpt4all.py +++ b/tests/integration_tests/llms/test_gpt4all.py @@ -7,21 +7,12 @@ from langchain.llms import GPT4All def _download_model() -> str: - """Download model. - From https://the-eye.eu/public/AI/models/nomic-ai/gpt4all/gpt4all-lora-quantized.bin, - convert to new ggml format and return model path.""" - model_url = "https://the-eye.eu/public/AI/models/nomic-ai/gpt4all/gpt4all-lora-quantized.bin" - tokenizer_url = "https://huggingface.co/decapoda-research/llama-7b-hf/resolve/main/tokenizer.model" - conversion_script = "https://github.com/nomic-ai/pyllamacpp/blob/main/pyllamacpp/scripts/convert_gpt4all.py" + """Download model.""" + model_url = "http://gpt4all.io/models/ggml-gpt4all-l13b-snoozy.bin" local_filename = model_url.split("/")[-1] - if not os.path.exists("convert_gpt4all.py"): - urlretrieve(conversion_script, "convert_gpt4all.py") - if not os.path.exists("tokenizer.model"): - urlretrieve(tokenizer_url, "tokenizer.model") if not os.path.exists(local_filename): urlretrieve(model_url, local_filename) - os.system(f"python convert_gpt4all.py.py . tokenizer.model") return local_filename