Coder Social home page Coder Social logo

spcl / graph-of-thoughts Goto Github PK

View Code? Open in Web Editor NEW
1.9K 20.0 126.0 12.35 MB

Official Implementation of "Graph of Thoughts: Solving Elaborate Problems with Large Language Models"

Home Page: https://arxiv.org/pdf/2308.09687.pdf

License: Other

Python 100.00%
graph-structures graphs large-language-models llm prompt-engineering prompting graph-of-thoughts

graph-of-thoughts's Introduction

Graph of Thoughts (GoT)

This is the official implementation of Graph of Thoughts: Solving Elaborate Problems with Large Language Models.
This framework gives you the ability to solve complex problems by modeling them as a Graph of Operations (GoO), which is automatically executed with a Large Language Model (LLM) as the engine.
This framework is designed to be flexible and extensible, allowing you to not only solve problems using the new GoT approach, but also to implement GoOs resembling previous approaches like CoT or ToT.

Setup Guide

In order to use this framework, you need to have a working installation of Python 3.8 or newer.

Installing GoT

Before running either of the following two installation methods, make sure to activate your Python environment (if any) beforehand.
If you are a user and you just want to use graph_of_thoughts, you can install it directly from PyPI:

pip install graph_of_thoughts

If you are a developer and you want to modify the code, you can install it in editable mode from source:

git clone https://github.com/spcl/graph-of-thoughts.git
cd graph-of-thoughts
pip install -e .

Configuring the LLM

In order to use the framework, you need to have access to an LLM. Please follow the instructions in the Controller README to configure the LLM of your choice.

Quick Start

The following code snippet shows how to use the framework to solve the sorting problem for a list of 32 numbers using a CoT-like approach.
Make sure you have followed the Setup Guide before running the code.

from examples.sorting.sorting_032 import SortingPrompter, SortingParser, utils
from graph_of_thoughts import controller, language_models, operations

# Problem input

to_be_sorted = "[0, 2, 6, 3, 8, 7, 1, 1, 6, 7, 7, 7, 7, 9, 3, 0, 1, 7, 9, 1, 3, 5, 1, 3, 6, 4, 5, 4, 7, 3, 5, 7]"

# Create the Graph of Operations
gop = operations.GraphOfOperations()
gop.append_operation(operations.Generate())
gop.append_operation(operations.Score(scoring_function=utils.num_errors))
gop.append_operation(operations.GroundTruth(utils.test_sorting))

# Configure the Language Model (Assumes config.json is in the current directory with OpenAI API key)
lm = language_models.ChatGPT("config.json", model_name="chatgpt")

# Create the Controller
ctrl = controller.Controller(
  lm, 
  gop, 
  SortingPrompter(), 
  SortingParser(),
  # The following dictionary is used to configure the initial thought state
  {
    "original": to_be_sorted,
    "current": "",
    "method": "cot"
  }
)

# Run the Controller and generate the output graph
ctrl.run()
ctrl.output_graph("output_cot.json")

To run the more sophisticated GoT approach, you can use the following code snippet.

from examples.sorting.sorting_032 import SortingPrompter, SortingParser, got, utils
from graph_of_thoughts import controller, language_models, operations

# Problem input

to_be_sorted = "[0, 2, 6, 3, 8, 7, 1, 1, 6, 7, 7, 7, 7, 9, 3, 0, 1, 7, 9, 1, 3, 5, 1, 3, 6, 4, 5, 4, 7, 3, 5, 7]"

# Retrieve the Graph of Operations
gop = got()

# Configure the Language Model (Assumes config.json is in the current directory with OpenAI API key)
lm = language_models.ChatGPT("config.json", model_name="chatgpt")

# Create the Controller
ctrl = controller.Controller(
  lm, 
  gop, 
  SortingPrompter(), 
  SortingParser(),
  # The following dictionary is used to configure the initial thought state
  {
    "original": to_be_sorted,
    "current": "",
    "phase": 0,
    "method": "got"
  }
)

# Run the Controller and generate the output graph
ctrl.run()
ctrl.output_graph("output_got.json")

You can compare the two results by inspecting the output graphs output_cot.json and output_got.json.
The final thought states' scores indicate the number of errors in the sorted list.

Documentation

The paper gives a high-level overview of the framework and its components.
In order to understand the framework in more detail, you can read the documentation of the individual modules.
Especially the Controller and Operations modules are important for understanding how to make the most out of the framework.
We took extra care to fully document the code, so that you can easily understand how it works and how to extend it.

Examples

The examples directory contains several examples of problems that can be solved using the framework, including the ones presented in the paper.
It is a great starting point for learning how to use the framework to solve real problems.
Each example contains a README.md file with instructions on how to run it and play with it. The code is fully documented and should be easy to follow. You can also run the examples straight from the main directory. Note that the results will be stored in the respective examples sub-directory.

Try for instance:

python -m examples.sorting.sorting_032
python -m examples.keyword_counting.keyword_counting

Paper Results

You can run the experiments from the paper by following the instructions in the examples directory.
However, if you just want to inspect and replot the results, you can use the paper directory.

Citations

If you find this repository valuable, please give it a star!
Got any questions or feedback? Feel free to reach out to [email protected] or open an issue.
Using this in your work? Please reference us using the provided citation:

@misc{besta2023got,
  title = {{Graph of Thoughts: Solving Elaborate Problems with Large Language Models}},
  author = {Besta, Maciej and Blach, Nils and Kubicek, Ales and Gerstenberger, Robert and Gianinazzi, Lukas and Gajda, Joanna and Lehmann, Tomasz and Podstawski, Micha{\l} and Niewiadomski, Hubert and Nyczyk, Piotr and Hoefler, Torsten},
  year = 2023,
  eprinttype = {arXiv},
  eprint = {2308.09687}
}

graph-of-thoughts's People

Contributors

aleskubicek avatar eltociear avatar nblach avatar rgersten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graph-of-thoughts's Issues

Use with Local Model

Is there a way to use Graph-of-Thoughts with local model, such as donwloaded Vicuna or LLama?

Use with retrieval augmented generation?

First of all, thank you for making this code public and for coming up with such a clever extension of tree-of-thoughts. I'm building a Q&A system over a set of documents, and I'm wondering if there are any examples out there of using graph-of-thoughts in a RAG (retrieval augmented generation) pipeline?

llama7b-hf sorts numbers

I tried to use llama7b-hf to sort numbers according to the code in readme by changing chatGPT to llama7b-hf

lm = controller.Llama2HF(
"graph_of_thoughts/controller/config.json",
model_name="llama7b-hf"
)

But I got the following results

WARNING:root:Could not parse step answer: Sure, I'd be happy to help you sort the list of numbers! Can you please provide the list of numbers for me to work with?. Returning empty list.

May I know whether this is a correct outcome?

Dynamically generate nodes

It's unclear looking at the code if there is a way to dynamically generate new "successors" and add it into the execution queue. It would of course be pushed to the front of the queue and not the back. Say you have a node A that has the thought that it should explore certain direction of thoughts, say thought B and C.

The initial graph structure may look simple: generate node A -> score node.
Is there a way that after running node A, it will be then explore an arbitrary number of nodes due to its thoughts so it looks like:
generate node A -> generate node B -> generate node C -> score node

Currently it seems like the initial graph structure is fixed?

huggingface pipeline compatibility

hi! this is great work and super interesting!! - looking to experiment and implement this approach using the llama-2 huggingface api. I was wondering if there is a sample implementation as i'm struggling to import the library, therefore need to rely on locally defining it on my cloud notebook.

This is my training loop if that helps (it's not generating a response, i believe it's not connecting to the api)

import json

prompter = SortingPrompter()

# Access the got_merge_prompt attribute
merge_prompt = prompter.got_merge_prompt

# Create an instance of Controller with the SortingPrompter's merge_prompt
controller = Controller(lm, graph, merge_prompt, parse)



# Initialize an empty list to store the generated responses
generated_responses = []

# Set the save frequency and the number of epochs
save_frequency = 5
num_epochs = 1

for epoch in range(num_epochs): 
    for data_point in known_data["examples"]: 
        prompts = data_point['input'].split('\n') 
        for prompt in prompts: 
            response = controller.run(prompt) 
            
            print(f"Instruction: {prompt}") 
            print(f"Response: {response}")

            # Append the response to the list
            generated_responses.append(response)

            # Check if it's time to save the responses
            if len(generated_responses) % save_frequency == 0:
                # Save the responses to a file (e.g., JSON)
                with open('known-got.json', 'w') as json_file:
                    json.dump(generated_responses, json_file)

# Save the responses to a final JSON file after all epochs are done
with open('known-got.json', 'w') as json_file:
    json.dump(generated_responses, json_file)

Thanks again!

Controller README

Dear authors,

I don't quite understand the Controller Instantiation part in graph_of_thoughts/controller/README.md.

How to instantiate Prompter, Parser, GraphOfOperations, and AbstractLanguageModel respectively? Do I need to paste the code block into a Python file and run the Python file? Could you please further explain it?

I didn't complete this part and ran from examples.sorting.sorting_032 import SortingPrompter, SortingParser, utils. As a result, I got an error

File "/home/weijie/graph-of-thoughts/graph_of_thoughts/language_models/chatgpt.py", line 104, in ChatGPT
    backoff.expo, openai.error.OpenAIError, max_time=10, max_tries=6
                  ^^^^^^^^^^^^
AttributeError: module 'openai' has no attribute 'error'

Best regards,
Weijie Liu

How to use the GoT frame through local LLM?

Hi! Much appreciated for the excellent work!
I would like to use the GoT frame to do vision-QA task. I have already prepared the FLAN-T5 LLM model. I wonder if it's possible to employ the GoT in my model to do inference?
And does GoT frame support multimodel LM, such as BLIP2?

Too many tokens

Dear authors,

When I run the example in Quick Start, I have the following error:

Traceback (most recent call last):
  File "/home/weijie/graph-of-thoughts/graph_of_thoughts/quick_start.py", line 32, in <module>
    ctrl.run()
  File "/home/weijie/graph-of-thoughts/graph_of_thoughts/controller/controller.py", line 77, in run
    current_operation.execute(
  File "/home/weijie/graph-of-thoughts/graph_of_thoughts/operations/operations.py", line 120, in execute
    self._execute(lm, prompter, parser, **kwargs)
  File "/home/weijie/graph-of-thoughts/graph_of_thoughts/operations/operations.py", line 453, in _execute
    lm.query(prompt, num_responses=self.num_branches_response)
  File "/home/weijie/graph-of-thoughts/graph_of_thoughts/language_models/chatgpt.py", line 79, in query
    response = self.chat([{"role": "user", "content": query}], num_responses)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/weijie/miniconda3/envs/aca/lib/python3.11/site-packages/backoff/_sync.py", line 105, in retry
    ret = target(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/weijie/graph-of-thoughts/graph_of_thoughts/language_models/chatgpt.py", line 121, in chat
    response = openai.ChatCompletion.create(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/weijie/miniconda3/envs/aca/lib/python3.11/site-packages/openai/api_resources/chat_completion.py", line 25, in create
    return super().create(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/weijie/miniconda3/envs/aca/lib/python3.11/site-packages/openai/api_resources/abstract/engine_api_resource.py", line 153, in create
    response, _, api_key = requestor.request(
                           ^^^^^^^^^^^^^^^^^^
  File "/home/weijie/miniconda3/envs/aca/lib/python3.11/site-packages/openai/api_requestor.py", line 298, in request
    resp, got_stream = self._interpret_response(result, stream)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/weijie/miniconda3/envs/aca/lib/python3.11/site-packages/openai/api_requestor.py", line 700, in _interpret_response
    self._interpret_response_line(
  File "/home/weijie/miniconda3/envs/aca/lib/python3.11/site-packages/openai/api_requestor.py", line 765, in _interpret_response_line
    raise self.handle_error_response(
openai.error.InvalidRequestError: This model's maximum context length is 4097 tokens. However, you requested 5715 tokens (1619 in the messages, 4096 in the completion). Please reduce the length of the messages or completion.

Note that I saved the example as quick_start.py. How should this be fixed?

Thank you for your time and consideration.

Best regards,
Weijie Liu

Question about backtracking and looping over thoughts in GoT

Hi there,

First of all, great work on implementing GoT and the publication of your paper---really appreciate you guys making your source code publicly available!

  1. I have a question regarding how one implements backtracking procedures in the Graph of Operations? Technically, you cannot do this (otherwise it wouldn't be a DAG). Thus, is the idea that you define all possible paths and then have Operations effectively halt their execution for paths that fail to meet some criteria?
  2. Second question is regarding looping over thoughts. How does one refine a single Operation? Or does the paper only mean that one can refine over Thoughts and not Operations?

Segmentation fault

I tried to modify the GoT framework using data multi-threading, but a segmentation fault occurred. Is there any solution?
image

Tips for architecting Graphs of Operations?

Firstly, thanks a lot for your work and sharing this code!

I'd like to try applying this approach to my own cognitive tasks, but I'm having trouble grasping how one should design a Graph of Operations for a given task. Are there different categories of cognitive tasks that would each tend to call for a certain architecture of GoO?

Or am I maybe misunderstanding, and perhaps the implemented example (document merging) showcases what a typical GoO would be for a language-based cognitive task, and not much variation is necessarily needed or expected?

In the paper you say the following which are nice tips I think, but I don't understand how to apply them to building a GoO:

The overall goal when conducting graph decomposition is
to break down a task to the point, where the LLM can solve
it correctly for the majority of time using a single prompt
(or with a few additional improvement steps). This signifi-
cantly lowers the number of improvement/refinement steps
needed during the later stages of the graph exploration. Fur-
thermore, as indicated by our results, combining or concate-
nating sub-results is usually an easier task than solving large
task instances from scratch. Hence, the LLM is often suc-
cessful when aggregating the final solution.

Any further tips or insight would be greatly appreciated!

Package circular import error

Why I quote your demo and got error that "ImportError: cannot import name 'GraphOfOperations' from partially initialized module 'graph_of_thoughts.operations' (most likely due to a circular import)"?

I read the partly source code and found after from graph_of_thoughts import operations and controller.py quote this package again.

But I dont know how to fix it

config

sorry it wasn't an issue

thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.