-
Notifications
You must be signed in to change notification settings - Fork 545
autogen subpackage #968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
autogen subpackage #968
Changes from 17 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
bc3c2fb
math utils in autogen
sonichi 6c92d56
cleanup
sonichi 54bf87b
code utils
sonichi 23197a6
Merge branch 'main' into autogen
sonichi a224279
remove check function from code response
sonichi c277d36
comment out test
sonichi dabf96a
Merge branch 'main' into autogen
sonichi 1878981
GPT-4
sonichi 0b56c4d
increase request timeout
sonichi 99609a8
name
sonichi 1d249e2
logging and error handling
sonichi 2485ea4
better doc
sonichi 5a3658f
Merge branch 'main' into autogen
sonichi 50b39d1
doc
sonichi d099eb5
Merge branch 'main' into autogen
liususan091219 b2f7361
codegen optimized
sonichi d61f1fb
GPT series
sonichi 1b91c1f
text
sonichi 0024b85
no demo example
sonichi 4d4db9a
math
sonichi ab0c90e
import openai
sonichi 9976da6
import openai
sonichi a292e16
azure model name
sonichi 1da255e
azure model name
sonichi c71ecbc
openai version
sonichi 11b9a9a
generate assertion if necessary
sonichi d925ed8
condition to generate assertions
sonichi ab0ee96
init region key
sonichi ff8126b
rename
sonichi c653b22
comments about budget
sonichi c845c69
prompt
sonichi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| import signal | ||
| import subprocess | ||
| import sys | ||
| from typing import List, Dict, Tuple, Optional, Union, Callable | ||
| from flaml import oai | ||
|
|
||
|
|
||
| def timeout_handler(signum, frame): | ||
| raise TimeoutError("Timed out!") | ||
|
|
||
|
|
||
| def execute_code(code: str, max_exec_time: Optional[int] = 3): | ||
| signal.signal(signal.SIGALRM, timeout_handler) | ||
| code = code.strip() | ||
| with open("codetest.py", "w") as fout: | ||
| fout.write(code) | ||
| try: | ||
| signal.alarm(max_exec_time) | ||
| result = subprocess.run( | ||
| [sys.executable, "codetest.py"], | ||
| stdout=subprocess.DEVNULL, | ||
| stderr=subprocess.PIPE, | ||
| ) | ||
| signal.alarm(0) | ||
| except TimeoutError: | ||
| return 0 | ||
| return int(result.returncode == 0) | ||
|
|
||
|
|
||
| def generate_assertions( | ||
| definition: str, model: Optional[str] = "gpt-3.5-turbo" | ||
| ) -> Tuple[str, float]: | ||
| """Generate assertions for a function. | ||
|
|
||
| Args: | ||
| definition (str): The function definition, including the signature and docstr. | ||
| model (str): The model used for generation. | ||
|
|
||
| Returns: | ||
| str: The generated assertions. | ||
| float: The cost of the generation. | ||
| """ | ||
| prompt = """Given the signature and docstring, write the exactly same number of assertion(s) for the provided example(s) in the docstring, without assertion messages. | ||
|
|
||
| func signature: | ||
| {definition} | ||
| assertions:""" | ||
| response = oai.Completion.create( | ||
| {"definition": definition}, | ||
| model=model, | ||
| prompt=prompt, | ||
| max_tokens=256, | ||
| stop="\n\n", | ||
| ) | ||
| cost = oai.Completion.cost(model, response) | ||
| assertions = oai.Completion.extract_text(response)[0] | ||
| return assertions, cost | ||
|
|
||
|
|
||
| def _remove_check(response): | ||
| """Remove the check function from the response.""" | ||
| # find the position of the check function | ||
| pos = response.find("def check(") | ||
| if pos == -1: | ||
| return response | ||
| return response[:pos] | ||
|
|
||
|
|
||
| def success_metrics( | ||
| responses: List[str], | ||
| definition: str, | ||
| test: Optional[str] = None, | ||
| entry_point: Optional[str] = None, | ||
| assertions: Optional[Union[str, Callable[[str], Tuple[str, float]]]] = None, | ||
| ) -> Dict: | ||
| """Check if the task is successful. | ||
|
|
||
| Args: | ||
| responses (list): The list of responses. | ||
| definition (str): The input definition. | ||
| test (Optional, str): The test code. | ||
| entry_point (Optional, str): The name of the function. | ||
| assertions (Optional, str or Callable): The assertion code which serves as a filter of the responses, or an assertion generator. | ||
| When provided, only the responses that pass the assertions will be considered for the actual test (if provided). | ||
|
|
||
| Returns: | ||
| dict: The success metrics. | ||
| """ | ||
| n = len(responses) | ||
| if assertions is None: | ||
| # no assertion filter | ||
| success_list = [] | ||
| for i in range(n): | ||
| response = _remove_check(responses[i]) | ||
| code = ( | ||
| f"{response}\n{test}\ncheck({entry_point})" | ||
| if response.startswith("def") | ||
| else f"{definition}{response}\n{test}\ncheck({entry_point})" | ||
| ) | ||
| success = execute_code(code) | ||
| success_list.append(success) | ||
| return { | ||
| "expected_success": 1 - pow(1 - sum(success_list) / n, n), | ||
| "success": any(s for s in success_list), | ||
| } | ||
| if callable(assertions) and n > 1: | ||
| # assertion generator | ||
| assertions, gen_cost = assertions(definition) | ||
| else: | ||
| gen_cost = 0 | ||
| if n > 1 or test is None: | ||
| for i in range(n): | ||
| response = responses[i] = _remove_check(responses[i]) | ||
| code = ( | ||
| f"{response}\n{assertions}" | ||
| if response.startswith("def") | ||
| else f"{definition}{response}\n{assertions}" | ||
| ) | ||
| succeed_assertions = execute_code(code) | ||
| if succeed_assertions: | ||
| break | ||
| else: | ||
| # just test, no need to check assertions | ||
| succeed_assertions = False | ||
| i, response = 0, responses[0] | ||
| if test is None: | ||
| # no test code | ||
| return { | ||
| "index_selected": i, | ||
| "succeed_assertions": succeed_assertions, | ||
| "gen_cost": gen_cost, | ||
| } | ||
| code_test = ( | ||
| f"{response}\n{test}\ncheck({entry_point})" | ||
| if response.startswith("def") | ||
| else f"{definition}{response}\n{test}\ncheck({entry_point})" | ||
| ) | ||
| success = execute_code(code_test) | ||
| return { | ||
| "index_selected": i, | ||
| "succeed_assertions": succeed_assertions, | ||
| "success": success, | ||
| "gen_cost": gen_cost, | ||
| } | ||
|
|
||
|
|
||
| def implement(definition: str, configs: List[Dict]) -> Tuple[str, float]: | ||
| """Implement a function. | ||
|
|
||
| Args: | ||
| definition (str): The function definition, including the signature and docstr. | ||
| configs (list): The list of configurations for completion. | ||
|
|
||
| Returns: | ||
| str: The implementation. | ||
| float: The cost of the implementation. | ||
| int: The index of the configuration which generates the implementation. | ||
| """ | ||
| assertions, cost = generate_assertions(definition) | ||
| for i, config in enumerate(configs): | ||
| response = oai.Completion.create({"definition": definition}, **config) | ||
| cost += oai.Completion.cost(config["model"], response) | ||
| responses = oai.Completion.extract_text(response) | ||
| metrics = success_metrics(responses, definition, assertions=assertions) | ||
| if metrics["succeed_assertions"] or i == len(configs) - 1: | ||
| return responses[metrics["index_selected"]], cost, i |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chatGPT and GPT-4 are not exclusive.