Skip to content
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

Add support for Ollama, Palm, Claude-2, Cohere, Replicate Llama2, CodeLlama, Hugging Face (100+LLMs) - using LiteLLM #95

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e966ae8
v0 litellm
ishaan-jaff Oct 4, 2023
2ca2087
Merge remote-tracking branch 'upstream/main'
Oct 5, 2023
a7b258f
clean up using litellm.completion+passing tests
ishaan-jaff Oct 5, 2023
df09d24
litellm as a dep
ishaan-jaff Oct 5, 2023
d9336e1
keep openai as a dep
ishaan-jaff Oct 5, 2023
ffd7764
ADD - mapping to complete.py
Oct 5, 2023
6f714c6
UPDATE - autogen.Completion
Oct 5, 2023
7c93170
add example using PaLM to sample
ishaan-jaff Oct 5, 2023
c056dd8
add hf + cohere samples
ishaan-jaff Oct 5, 2023
562cf46
try/except cache check
ishaan-jaff Oct 5, 2023
345631e
Remove - old notebook
Oct 5, 2023
2152325
Merge branch 'main' into main
AaronWard Oct 5, 2023
db2cf1e
Merge branch 'main' of https://github.com/ishaan-jaff/autogen
Oct 5, 2023
a530aba
ADD - llm_lite_mapping to rename models
Oct 5, 2023
f31850d
UPDATE - tests, not fully working yet. Added testing notebook
Oct 5, 2023
adb6465
ADD - testing notebook explaining the problem with the outputs of the…
Oct 6, 2023
ebfa941
use openai for gpt models
ishaan-jaff Oct 8, 2023
8b5146e
remove mapping added
ishaan-jaff Oct 8, 2023
c8d02ae
remove edit to config list
ishaan-jaff Oct 8, 2023
461aa5b
default openai utils.py
ishaan-jaff Oct 8, 2023
0d401b9
use openai_completion again
ishaan-jaff Oct 8, 2023
6d4b901
default test_utils
ishaan-jaff Oct 8, 2023
e5244e0
add extra line to openai utils.py
ishaan-jaff Oct 8, 2023
c90da93
update OAI_CONFIG sample
ishaan-jaff Oct 8, 2023
6fdf762
fixes to PR
ishaan-jaff Oct 8, 2023
47cf3e4
Merge branch 'main' into main
AaronWard Oct 8, 2023
b54240d
Merge branch 'main' into main
AaronWard Oct 8, 2023
da8b59c
Merge branch 'main' into main
AaronWard Oct 9, 2023
438d76b
Merge branch 'main' into main
AaronWard Oct 9, 2023
35408d7
Merge branch 'main' into main
AaronWard Oct 10, 2023
bacef0d
Merge branch 'main' into main
AaronWard Oct 10, 2023
b7767bc
Merge branch 'main' into main
AaronWard Oct 11, 2023
19b4ab2
Merge branch 'main' into main
AaronWard Oct 15, 2023
f433e33
Merge branch 'main' into main
AaronWard Oct 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions OAI_CONFIG_LIST_sample
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,22 @@
"api_base": "<your Azure OpenAI API base here>",
"api_type": "azure",
"api_version": "2023-07-01-preview"
},
{
"model": "command-nightly",
"api_key": "<your Cohere API key here>"
},
{
"model": "palm/chat-bison",
"api_key": "<your PaLM API key here>"
},
{
"model": "huggingface/glaiveai/glaive-coder-7b",
"api_key": "<your hugging face API key here>"
},
{
"model": "huggingface/glaiveai/glaive-coder-7b",
"api_key": "<your hugging face API key here>",
"api_base": "<your hugging face inference endpoint here>"
}
]
52 changes: 39 additions & 13 deletions autogen/oai/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

try:
import openai
import litellm
from openai.error import (
ServiceUnavailableError,
RateLimitError,
Expand Down Expand Up @@ -102,6 +103,28 @@ class Completion(openai_Completion):
"prompt": "{prompt}",
}

llm_lite_mapping = {
ishaan-jaff marked this conversation as resolved.
Show resolved Hide resolved
'code-davinci-002': 'davinci-002',
'gpt-3.5-turbo': 'gpt-3.5-turbo',
'gpt-3.5-turbo-0301': 'gpt-3.5-turbo-0301',
'gpt-3.5-turbo-0613': 'gpt-3.5-turbo-0613',
'gpt-3.5-turbo-16k': 'gpt-3.5-turbo-16k',
'gpt-3.5-turbo-16k-0613': 'gpt-3.5-turbo-16k-0613',
'gpt-35-turbo': 'gpt-3.5-turbo-instruct',
'gpt-4': 'gpt-4',
'gpt-4-0314': 'gpt-4-0314',
'gpt-4-0613': 'gpt-4-0613',
'gpt-4-32k': 'gpt-4-32k',
'gpt-4-32k-0314': 'gpt-4-32k-0314',
'gpt-4-32k-0613': 'gpt-4-32k-0613',
'text-ada-001': 'text-ada-001',
'text-babbage-001': 'text-babbage-001',
'text-curie-001': 'text-curie-001',
'text-davinci-002': 'davinci-002',
'text-davinci-003': 'text-davinci-003'
}


seed = 41
cache_path = f".cache/{seed}"
# retry after this many seconds
Expand Down Expand Up @@ -185,28 +208,31 @@ def _get_response(cls, config: Dict, raise_on_ratelimit_or_timeout=False, use_ca
"""
config = config.copy()
openai.api_key_path = config.pop("api_key_path", openai.api_key_path)

model_name = config.get("model")
mapped_model_name = cls.llm_lite_mapping.get(model_name, model_name) # Fallback to original if not found
config["model"] = mapped_model_name

key = get_key(config)
if use_cache:
ishaan-jaff marked this conversation as resolved.
Show resolved Hide resolved
response = cls._cache.get(key, None)
if response is not None and (response != -1 or not raise_on_ratelimit_or_timeout):
# print("using cached response")
cls._book_keeping(config, response)
return response
openai_completion = (
ishaan-jaff marked this conversation as resolved.
Show resolved Hide resolved
openai.ChatCompletion
if config["model"] in cls.chat_models or issubclass(cls, ChatCompletion)
else openai.Completion
)
try:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try/ excepting checking cache. If checking cache raises an exception it should still make the LLM API call

response = cls._cache.get(key, None)
if response is not None and (response != -1 or not raise_on_ratelimit_or_timeout):
# print("using cached response")
cls._book_keeping(config, response)
return response
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catch a more specific exception.

pass
start_time = time.time()
request_timeout = cls.request_timeout
max_retry_period = config.pop("max_retry_period", cls.max_retry_period)
retry_wait_time = config.pop("retry_wait_time", cls.retry_wait_time)
while True:
try:
if "request_timeout" in config:
response = openai_completion.create(**config)
response = litellm.completion(**config)
ishaan-jaff marked this conversation as resolved.
Show resolved Hide resolved
Copy link

@legraphista legraphista Oct 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some sanitization should be done on the config dict.
Now, it's sending api_type = 'litellm' down to litellm.completion which doesn't sanitize it's inputs to each llm service.

For example, Anthropic's Claude API doesn't work due to:

litellm.exceptions.InvalidRequestError: AnthropicException - {'type': 'invalid_request_error', 'message': 'api_type: extra fields not permitted'}

Copy link

@legraphista legraphista Oct 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subject: [PATCH] sanitize config
---
Index: autogen/oai/completion.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/autogen/oai/completion.py b/autogen/oai/completion.py
--- a/autogen/oai/completion.py	(revision b54240d1d7b94f78a18d9b6766d680aaaa13391e)
+++ b/autogen/oai/completion.py	(date 1696849131483)
@@ -210,11 +210,15 @@
             try:
                 if "request_timeout" not in config:
                     config["request_timeout"] = request_timeout
+
                 api_type = config.get("api_type", None)
+                sanitized_config = config.copy()
+                if 'api_type' in sanitized_config:
+                   del sanitized_config["api_type"]
+
                 if api_type and re.sub(r'[^a-zA-Z0-9]', '', api_type).lower() == "litellm":
-                    response = litellm.completion(**config)
+                    response = litellm.completion(**sanitized_config)
                 else:
-                    response = openai_completion.create(**config)
+                    response = openai_completion.create(**sanitized_config)
             except (
                 ServiceUnavailableError,
                 APIConnectionError,

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Thanks!

else:
response = openai_completion.create(request_timeout=request_timeout, **config)
response = litellm.completion(request_timeout=request_timeout, **config)
except (
ServiceUnavailableError,
APIConnectionError,
Expand Down Expand Up @@ -1121,4 +1147,4 @@ class ChatCompletion(Completion):

default_search_space = Completion.default_search_space.copy()
default_search_space["model"] = tune.choice(["gpt-3.5-turbo", "gpt-4"])
openai_completion_class = not ERROR and openai.ChatCompletion
openai_completion_class = not ERROR and openai.ChatCompletion
21 changes: 12 additions & 9 deletions autogen/oai/openai_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ def config_list_from_dotenv(
FileNotFoundError: If the specified .env file does not exist.
TypeError: If an unsupported type of configuration is provided in model_api_key_map.
"""

if dotenv_file_path:
dotenv_path = Path(dotenv_file_path)
if dotenv_path.exists():
Expand All @@ -328,14 +329,14 @@ def config_list_from_dotenv(
# Ensure the model_api_key_map is not None to prevent TypeErrors during key assignment.
model_api_key_map = model_api_key_map or {}

# Ensure default models are always considered
default_models = ["gpt-4", "gpt-3.5-turbo"]

for model in default_models:
# Only assign default API key if the model is not present in the map.
# If model is present but set to invalid/empty, do not overwrite.
if model not in model_api_key_map:
model_api_key_map[model] = "OPENAI_API_KEY"
if not model_api_key_map:
# Ensure default models are always considered
default_models = ["gpt-4", "gpt-3.5-turbo"]
for model in default_models:
# Only assign default API key if the model is not present in the map.
# If model is present but set to invalid/empty, do not overwrite.
if model not in model_api_key_map:
model_api_key_map[model] = "OPENAI_API_KEY"

env_var = []
# Loop over the models and create configuration dictionaries
Expand All @@ -344,7 +345,9 @@ def config_list_from_dotenv(
api_key_env_var = config
config_dict = get_config(api_key=os.getenv(api_key_env_var))
elif isinstance(config, dict):
api_key = os.getenv(config.get("api_key_env_var", "OPENAI_API_KEY"))
api_key = os.getenv(config.get("api_key_env_var", None))
if api_key is None:
api_key = config.get("api_key_default", "") # Use the default API key if not found in environment
config_without_key_var = {k: v for k, v in config.items() if k != "api_key_env_var"}
config_dict = get_config(api_key=api_key, **config_without_key_var)
else:
Expand Down
Loading
Loading