Skip to content

Commit

Permalink
[Bug] Fix Regex for identifying OpenAI models (#778)
Browse files Browse the repository at this point in the history
Addresses the issue with the model naming convention used by Azure's OpenAI API. Completion models are recognised strictly through the `-instruct` suffix on their names.

Additionally, the deployment path check has been changed to handle scenarios where ```pathlib.parts``` does not include the deployment path, ensuring more robust path validation during Azure deployments.

Closes #761
  • Loading branch information
alexander-brady authored May 1, 2024
1 parent 92afe33 commit acb38d1
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 25 deletions.
26 changes: 13 additions & 13 deletions guidance/models/_azure_openai.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pathlib
import re

from typing import Type
from urllib.parse import parse_qs, urlparse
Expand All @@ -11,8 +10,7 @@
from ._openai import (
OpenAIChatEngine,
OpenAICompletionEngine,
OpenAIInstructEngine,
chat_model_pattern,
OpenAIInstructEngine
)

try:
Expand Down Expand Up @@ -73,18 +71,15 @@ def __init__(
if api_key is None and azure_ad_token_provider is None:
raise ValueError("Please provide either api_key or azure_ad_token_provider")

parsed_url = urlparse(azure_endpoint)

# if we are called directly (as opposed to through super()) then we convert ourselves to
# a more specific subclass if possible
if self.__class__ is AzureOpenAI:
# Default to a completion model
found_subclass: Type[AzureOpenAI] = AzureOpenAICompletion
# Now see if we should be using a chat model
if parsed_url.path.endswith("/chat/completions"):
found_subclass = AzureOpenAIChat
elif re.match(chat_model_pattern, model):
found_subclass = AzureOpenAIChat
found_subclass: Type[AzureOpenAI] = (
AzureOpenAICompletion
if model.endswith("-instruct")
else AzureOpenAIChat
)

# convert to any found subclass
self.__class__ = found_subclass
Expand All @@ -101,9 +96,14 @@ def __init__(
**kwargs,
)
return

parsed_url = urlparse(azure_endpoint)

if azure_deployment is None:
azure_deployment = pathlib.Path(parsed_url.path).parts[3]
parts = pathlib.Path(parsed_url.path).parts
if len(parts) > 2:
azure_deployment = parts[3]

parsed_query = parse_qs(parsed_url.query)
api_version = (
version
Expand Down Expand Up @@ -159,4 +159,4 @@ def get_role_end(self, name):
else:
raise ValueError(
f"The OpenAIInstruct model does not know about the {name} role type!"
)
)
18 changes: 6 additions & 12 deletions guidance/models/_openai.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import re
import typing

import diskcache as dc
Expand All @@ -18,8 +17,6 @@
except ImportError:
client_class = None

chat_model_pattern = r"^(ft:)?(gpt-3\.5-turbo|gpt-4)(?:(?!-instruct$)(-\w+)+)?(:[\w-]+(?:[:\w-]+)*)?(::\w+)?$"


class OpenAIEngine(GrammarlessEngine):
def __init__(
Expand Down Expand Up @@ -92,19 +89,16 @@ def __init__(

# if we are called directly (as opposed to through super()) then we convert ourselves to a more specific subclass if possible
if self.__class__ is OpenAI:
found_subclass = None

# chat
if re.match(chat_model_pattern, model):
found_subclass = OpenAIChat

# instruct
# elif "instruct" in model: # All current OpenAI instruct models behave as Completion models.
# found_subclass = OpenAIInstruct

# regular completion
else:
found_subclass = OpenAICompletion

found_subclass: typing.Type[OpenAI] = (
OpenAICompletion
if model.endswith("-instruct")
else OpenAIChat
)

# convert to any found subclass
self.__class__ = found_subclass
Expand Down

0 comments on commit acb38d1

Please sign in to comment.