Skip to content

Commit e3247fe

Browse files
alonsosilvaallenderlouf
authored andcommitted
Add chain of thought example
1 parent 951b020 commit e3247fe

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

docs/cookbook/chain_of_thought.md

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Chain of thought
2+
3+
4+
Chain of thought is a prompting technique introduced in the paper [``Chain-of-Thought Prompting Elicits Reasoning in Large Language Models''](https://arxiv.org/abs/2201.11903) where throught prompting the authors generate a series of intermediate reasoning steps which improves the ability of LLMs to perform complex reasoning.
5+
6+
In this guide, we use [outlines](https://outlines-dev.github.io/outlines/) to apply chain of thought through structured output.
7+
8+
We use [llama.cpp](https://github.com/ggerganov/llama.cpp) using the [llama-cpp-python](https://github.com/abetlen/llama-cpp-python) library. Outlines supports llama-cpp-python, but we need to install it ourselves:
9+
10+
```shell
11+
pip install llama-cpp-python
12+
```
13+
14+
We pull a quantized GGUF model, in this guide we pull [Hermes-2-Pro-Llama-3-8B](https://huggingface.co/NousResearch/Hermes-2-Theta-Llama-3-8B-GGUF) by [NousResearch](https://nousresearch.com/) from [HuggingFace](https://huggingface.co/):
15+
16+
```shell
17+
wget https://hf.co/NousResearch/Hermes-2-Pro-Llama-3-8B-GGUF/resolve/main/Hermes-2-Pro-Llama-3-8B-Q4_K_M.gguf
18+
```
19+
20+
We initialize the model:
21+
22+
```python
23+
from llama_cpp import Llama
24+
from outlines import generate, models
25+
26+
llm = Llama(
27+
"/path/to/model/Hermes-2-Pro-Llama-3-8B-Q4_K_M.gguf",
28+
tokenizer=llama_cpp.llama_tokenizer.LlamaHFTokenizer.from_pretrained(
29+
"NousResearch/Hermes-2-Pro-Llama-3-8B"
30+
),
31+
n_gpu_layers=-1,
32+
flash_attn=True,
33+
n_ctx=8192,
34+
verbose=False
35+
)
36+
model = models.LlamaCpp(llm)
37+
```
38+
39+
## Chain of thought
40+
41+
We first define our Pydantic class for a reasoning step:
42+
43+
```python
44+
from pydantic import BaseModel, Field
45+
46+
class Reasoning_Step(BaseModel):
47+
reasoning_step: str = Field(..., description="Reasoning step")
48+
```
49+
50+
We then define the Pydantic class for reasoning which will consist on a list of reasoning steps and a conclusion, and we get its JSON schema:
51+
52+
```python
53+
from typing import List
54+
55+
from typing import List
56+
57+
class Reasoning(BaseModel):
58+
reasoning: List[Reasoning_Step] = Field(..., description="List of reasoning steps")
59+
conclusion: str = Field(..., description="Conclusion")
60+
61+
json_schema = Reasoning.model_json_schema()
62+
```
63+
64+
We could generate using the json schema but for a change we will use the regex:
65+
66+
```python
67+
from outlines.integrations.utils import convert_json_schema_to_str
68+
from outlines.fsm.json_schema import build_regex_from_schema
69+
70+
json_schema = Reasoning.model_json_schema()
71+
schema_str = convert_json_schema_to_str(json_schema=json_schema)
72+
regex_str = build_regex_from_schema(schema_str)
73+
```
74+
75+
We then need to adapt our prompt to the [Hermes prompt format for JSON schema](https://github.com/NousResearch/Hermes-Function-Calling?tab=readme-ov-file#prompt-format-for-json-mode--structured-outputs):
76+
77+
```python
78+
def generate_hermes_prompt(user_prompt):
79+
return (
80+
"<|im_start|>system\n"
81+
"You are a world class AI model who answers questions in JSON "
82+
f"Here's the json schema you must adhere to:\n<schema>\n{schema}\n</schema><|im_end|>\n"
83+
"<|im_start|>user\n"
84+
+ user_prompt
85+
+ "<|im_end|>"
86+
+ "\n<|im_start|>assistant\n"
87+
"<schema>"
88+
)
89+
```
90+
91+
For a given user prompt, for example:
92+
93+
```python
94+
user_prompt = "9.11 and 9.9 -- which is bigger?"
95+
```
96+
97+
We can use `generate.regex` by passing the Pydantic class we previously defined, and call the generator with the Hermes prompt:
98+
99+
```python
100+
generator = generate.regex(model, regex_str)
101+
prompt = generate_hermes_prompt(user_prompt)
102+
response = generator(prompt, max_tokens=1024, temperature=0, seed=42)
103+
```
104+
105+
We obtain the reasoning steps as well as the conclusion
106+
107+
```python
108+
import json
109+
110+
json_response = json.loads(response)
111+
112+
print(json_response["reasoning"])
113+
print(json_response["conclusion"])
114+
# [{'reasoning_step': 'Both 9.11 and 9.9 are decimal numbers.'},
115+
# {'reasoning_step': 'When comparing decimal numbers, we look at the numbers after the decimal point.'},
116+
# {'reasoning_step': 'In this case, 9.11 has the number 1 after the decimal point, while 9.9 has the number 9.'},
117+
# {'reasoning_step': 'Since 1 is greater than 9, 9.11 is greater than 9.9.'}]
118+
# '9.11 is bigger.'
119+
```
120+
121+
We notice that the 4th reasoning step is wrong ``Since 1 is greater than 9, 9.11 is greater than 9.9.'', so we could probably give the model some examples for this particular task.
122+
123+
This example was originally contributed by [Alonso Silva](https://github.com/alonsosilvaallende).

docs/cookbook/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
- [SimToM](simtom.md): Improve LLMs' Theory of Mind capabilities with perspective-taking prompting and JSON-structured generation.
99
- [Q&A with Citations](qa-with-citations.md): Answer questions and provide citations using JSON-structured generation.
1010
- [Knowledge Graph Generation](knowledge_graph_extraction.md): Generate a Knowledge Graph from unstructured text using JSON-structured generation.
11+
- [Chain Of Thought (CoT)](chain_of_thought.md): Generate a series of intermediate reasoning steps using regex-structured generation.

mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ nav:
108108
- Perspective-taking prompting: cookbook/simtom.md
109109
- Question-answering with citations: cookbook/qa-with-citations.md
110110
- Knowledge Graph Extraction: cookbook/knowledge_graph_extraction.md
111+
- Chain of Thought (CoT): cookbook/chain_of_thought.md
111112
- Run on the cloud:
112113
- BentoML: cookbook/deploy-using-bentoml.md
113114
- Cerebrium: cookbook/deploy-using-cerebrium.md

0 commit comments

Comments
 (0)