Skip to content

Commit 29fc5ea

Browse files
authored
Merge pull request #18 from microsoft/experimental
Upgrade to version 0.1.3
2 parents ea4f19f + 549c7ca commit 29fc5ea

File tree

12 files changed

+1497
-909
lines changed

12 files changed

+1497
-909
lines changed

docs/_toc.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ parts:
1212
- file: quickstart/quick_start_2
1313
- file: quickstart/virtualhome
1414

15+
- caption: FAQ
16+
numbered: false
17+
chapters:
18+
- file: faq/faq
19+
1520
- caption: 📚Tutorials
1621
chapters:
1722
- file: tutorials/basic_tutorial

docs/faq/faq.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# FAQ
2+
3+
### Difference to Libraries like TextGrad
4+
5+
TextGrad is both a library and an optimizer algorithm. Currently, we support three optimizers:
6+
7+
- OPRO: [Large Language Models as Optimizers](https://arxiv.org/abs/2309.03409)
8+
- TextGrad: [TextGrad: Automatic "Differentiation" via Text](https://arxiv.org/abs/2406.07496)
9+
- OptoPrime: [Our proposed algorithm](https://arxiv.org/abs/2406.16218) -- using the entire computational graph to perform parameter update. It is 2-3x
10+
faster than TextGrad.
11+
12+
Using our framework, you can seamlessly switch between different optimizers:
13+
14+
```python
15+
optimizer1 = OptoPrime(strange_sort_list.parameters())
16+
optimizer2 = OPRO(strange_sort_list.parameters())
17+
optimizer3 = TextGrad(strange_sort_list.parameters())
18+
```
19+
20+
Here is a summary of the optimizers:
21+
22+
| | Computation Graph | Code as Functions | Library Support | Supported Optimizers | Speed | Large Graph |
23+
|-----------------------------------|-------------------|-------------------|------------------|---------------------------|-------------|-------------|
24+
| OPRO |||| OPRO | ⚡️ ||
25+
| TextGrad |||| TextGrad | 🐌 ||
26+
| Trace |||| OPRO, OptoPrime, TextGrad |||
27+
28+
The table evaluates the frameworks in the following aspects:
29+
30+
- Computation Graph: Whether the optimizer leverages the computation graph of the workflow.
31+
- Code as Functions: Whether the framework allows users to write actual executable Python functions and not require
32+
users to wrap them in strings.
33+
- Library Support: Whether the framework has a library to support the optimizer.
34+
- Speed: TextGrad is about 2-3x slower than OptoPrime (Trace). OPRO has no concept of computational graph, therefore is very fast.
35+
- Large Graph: OptoPrime (Trace) represents the entire computation graph in context, therefore, might have issue with graphs that have more than hundreds of operations. TextGrad does not have the context-length issue, however, might be very slow on large graphs.
36+
37+
We provide a comparison to validate our implementation of TextGrad in Trace:
38+
39+
<p align="center">
40+
<img src="https://github.com/microsoft/Trace/blob/main/docs/images/compare_to_textgrad3.png" alt="drawing" width="100%"/>
41+
</p>
42+
43+
To produce this table, we ran the TextGrad pip-installed repo on 2024-10-30, and we also include the numbers reported in the TextGrad paper.
44+
The LLM APIs are called around the same time to ensure a fair comparison. TextGrad paper's result was reported in 2024-06.
45+
46+
### Difference to Libraries like AutoGen, AG2, OpenAI Swarm, Llama Stack
47+

opto/optimizers/optoprime.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1+
12
from typing import Any, List, Dict, Union, Tuple
23
from dataclasses import dataclass, asdict
3-
from opto.trace.nodes import ParameterNode, Node, MessageNode
4-
from opto.optimizers.optimizer import Optimizer
5-
6-
from opto.trace.propagators import TraceGraph, GraphPropagator
74
from textwrap import dedent, indent
8-
from opto.trace.propagators.propagators import Propagator
9-
from opto.optimizers.buffers import FIFOBuffer
105
import autogen
116
import warnings
127
import json
13-
148
import re
159
import copy
10+
from opto.trace.nodes import ParameterNode, Node, MessageNode
11+
from opto.trace.propagators import TraceGraph, GraphPropagator
12+
from opto.trace.propagators.propagators import Propagator
13+
from opto.optimizers.optimizer import Optimizer
14+
from opto.optimizers.buffers import FIFOBuffer
15+
from opto.utils.llm import AutoGenLLM
1616

1717

1818
def get_fun_name(node: MessageNode):
@@ -252,7 +252,7 @@ class OptoPrime(Optimizer):
252252
def __init__(
253253
self,
254254
parameters: List[ParameterNode],
255-
config_list: List = None, # autogen config_dict
255+
LLM: AutoGenLLM = None,
256256
*args,
257257
propagator: Propagator = None,
258258
objective: Union[None, str] = None,
@@ -267,11 +267,7 @@ def __init__(
267267
):
268268
super().__init__(parameters, *args, propagator=propagator, **kwargs)
269269
self.ignore_extraction_error = ignore_extraction_error
270-
if config_list is None:
271-
config_list = autogen.config_list_from_json("OAI_CONFIG_LIST")
272-
if filter_dict is not None:
273-
config_list = autogen.filter_config_list(config_list, filter_dict)
274-
self.llm = autogen.OpenAIWrapper(config_list=config_list)
270+
self.llm = LLM or AutoGenLLM()
275271
self.objective = objective or self.default_objective
276272
self.example_problem = ProblemInstance.problem_template.format(
277273
instruction=self.default_objective,
@@ -510,13 +506,13 @@ def call_llm(
510506
messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}]
511507

512508
try: # Try tp force it to be a json object
513-
response = self.llm.create(
509+
response = self.llm(
514510
messages=messages,
515511
response_format={"type": "json_object"},
516512
max_tokens=max_tokens,
517513
)
518514
except Exception:
519-
response = self.llm.create(messages=messages, max_tokens=max_tokens)
515+
response = self.llm(messages=messages, max_tokens=max_tokens)
520516
response = response.choices[0].message.content
521517

522518
if verbose:

opto/optimizers/utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
def print_color(message, color=None, logger=None):
2+
colors = {
3+
'red': '\033[91m',
4+
'green': '\033[92m',
5+
'yellow': '\033[93m',
6+
'blue': '\033[94m',
7+
'magenta': '\033[95m',
8+
'cyan': '\033[96m'
9+
}
10+
print(f"{colors.get(color, '')}{message}\033[0m") # Default to no color if invalid color is provided
11+
12+
if logger is not None:
13+
logger.log(message)

0 commit comments

Comments
 (0)