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

feat: ChatGPTGenerator #5692

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0fc2bac
add generators module
ZanSara Aug 30, 2023
7f6325c
add tests for module helper
ZanSara Aug 30, 2023
47b6799
add chatgpt generator
ZanSara Aug 30, 2023
4e8fcb3
add init and serialization tests
ZanSara Aug 30, 2023
cbf7701
test component
ZanSara Aug 30, 2023
419f615
reno
ZanSara Aug 30, 2023
49ff654
Merge branch 'main' into generators-module
ZanSara Aug 30, 2023
4edeb8e
Merge branch 'generators-module' into chatgpt-generator
ZanSara Aug 30, 2023
08e9c62
reno
ZanSara Aug 30, 2023
a984e67
more tests
ZanSara Aug 30, 2023
612876a
add another test
ZanSara Aug 31, 2023
ec8e14a
Merge branch 'generators-module' of github.com:deepset-ai/haystack in…
ZanSara Aug 31, 2023
366b0ff
Merge branch 'generators-module' into chatgpt-generator
ZanSara Aug 31, 2023
e9c3de7
chat token limit
ZanSara Aug 31, 2023
725fabe
move into openai
ZanSara Aug 31, 2023
4d4f9d4
Merge branch 'generators-module' into chatgpt-generator
ZanSara Aug 31, 2023
c3bef8f
fix test
ZanSara Aug 31, 2023
c1a7696
improve tests
ZanSara Aug 31, 2023
246ca63
Merge branch 'generators-module' into chatgpt-generator
ZanSara Aug 31, 2023
ec809e4
add e2e test and small fixes
ZanSara Aug 31, 2023
5d946f8
linting
ZanSara Aug 31, 2023
aa9ce33
Add ChatGPTGenerator example
vblagoje Aug 31, 2023
9310057
review feedback
ZanSara Aug 31, 2023
7c36db1
Merge branch 'chatgpt-generator' of github.com:deepset-ai/haystack in…
ZanSara Aug 31, 2023
b2e421d
support for metadata
ZanSara Aug 31, 2023
6d81d79
Merge branch 'main' into chatgpt-generator
ZanSara Aug 31, 2023
2895697
mypy
ZanSara Aug 31, 2023
1538d61
mypy
ZanSara Sep 1, 2023
02cd61f
extract backend from generator and make it accept chats
ZanSara Sep 1, 2023
84332c6
fix tests
ZanSara Sep 1, 2023
329b54d
mypy
ZanSara Sep 4, 2023
5ee2aac
query->complete
ZanSara Sep 4, 2023
429a3ae
mypy
ZanSara Sep 4, 2023
c0b237d
Merge branch 'main' into chatgpt-generator
ZanSara Sep 4, 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
Prev Previous commit
Next Next commit
test component
  • Loading branch information
ZanSara committed Aug 30, 2023
commit cbf77019d96ebb54fc9e0e57077a676aa3a3c8c5
5 changes: 2 additions & 3 deletions haystack/preview/components/generators/openai/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
OPENAI_TIMEOUT = float(os.environ.get("HAYSTACK_REMOTE_API_TIMEOUT_SEC", 30))
OPENAI_BACKOFF = int(os.environ.get("HAYSTACK_REMOTE_API_BACKOFF_SEC", 10))
OPENAI_MAX_RETRIES = int(os.environ.get("HAYSTACK_REMOTE_API_MAX_RETRIES", 5))
TOKENIZERS = {
OPENAI_TOKENIZERS = {
**tiktoken.model.MODEL_TO_ENCODING,
"gpt-35-turbo": "cl100k_base", # https://github.com/openai/tiktoken/pull/72
}
TOKENIZERS_TOKEN_LIMITS = {
OPENAI_TOKENIZERS_TOKEN_LIMITS = {
"gpt2": 2049, # Ref: https://platform.openai.com/docs/models/gpt-3
"text-davinci": 4097, # Ref: https://platform.openai.com/docs/models/gpt-3
"gpt-35-turbo": 2049, # Ref: https://platform.openai.com/docs/models/gpt-3-5
Expand All @@ -39,7 +39,6 @@
"gpt-3": 4096, # Ref: https://platform.openai.com/docs/models/gpt-3
"gpt-4-32k": 32768, # Ref: https://platform.openai.com/docs/models/gpt-4
"gpt-4": 8192, # Ref: https://platform.openai.com/docs/models/gpt-4
"": 2049, # Default
}


Expand Down
96 changes: 56 additions & 40 deletions haystack/preview/components/generators/openai/chatgpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
default_streaming_callback,
query_chat_model,
query_chat_model_stream,
TOKENIZERS,
TOKENIZERS_TOKEN_LIMITS,
OPENAI_TOKENIZERS,
OPENAI_TOKENIZERS_TOKEN_LIMITS,
)


Expand Down Expand Up @@ -110,20 +110,20 @@ def __init__(
self.api_base_url = api_base_url

self.tokenizer = None
for model_prefix in TOKENIZERS:
for model_prefix in OPENAI_TOKENIZERS:
if model_name.startswith(model_prefix):
self.tokenizer = tiktoken.get_encoding(TOKENIZERS[model_prefix])
self.tokenizer = tiktoken.get_encoding(OPENAI_TOKENIZERS[model_prefix])
break
if not self.tokenizer:
raise ValueError(f"Tokenizer for model {model_name} not found.")
raise ValueError(f"Tokenizer for model '{model_name}' not found.")

self.max_tokens_limit = None
for model_prefix in TOKENIZERS_TOKEN_LIMITS:
for model_prefix in OPENAI_TOKENIZERS_TOKEN_LIMITS:
if model_name.startswith(model_prefix):
self.max_tokens_limit = TOKENIZERS_TOKEN_LIMITS[model_prefix]
self.max_tokens_limit = OPENAI_TOKENIZERS_TOKEN_LIMITS[model_prefix]
break
if not self.max_tokens_limit:
raise ValueError(f"Max tokens limit for model {model_name} not found.")
raise ValueError(f"Max tokens limit for model '{model_name}' not found.")

def to_dict(self) -> Dict[str, Any]:
"""
Expand Down Expand Up @@ -162,23 +162,23 @@ def from_dict(cls, data: Dict[str, Any]) -> "ChatGPTGenerator":
def run(
self,
prompts: List[str],
api_key: str,
model_name: str = "gpt-3.5-turbo",
system_prompt: Optional[str] = "You are a helpful assistant.",
max_reply_tokens: Optional[int] = 500,
temperature: Optional[float] = 0.7,
top_p: Optional[float] = 1,
n: Optional[int] = 1,
api_key: Optional[str] = None,
model_name: Optional[str] = None,
system_prompt: Optional[str] = None,
max_reply_tokens: Optional[int] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stop: Optional[List[str]] = None,
presence_penalty: Optional[float] = 0,
frequency_penalty: Optional[float] = 0,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[Dict[str, float]] = None,
moderate_content: bool = True,
api_base_url: str = "https://api.openai.com/v1",
moderate_content: Optional[bool] = None,
api_base_url: Optional[str] = None,
openai_organization: Optional[str] = None,
stream: bool = False,
stream: Optional[bool] = None,
streaming_callback: Optional[Callable] = None,
streaming_done_marker: str = "[DONE]",
streaming_done_marker: Optional[str] = None,
):
"""
Queries the LLM with the prompts to produce replies.
Expand Down Expand Up @@ -217,32 +217,48 @@ def run(

See OpenAI documentation](https://platform.openai.com/docs/api-reference/chat) for more details.
"""
if not api_key and not self.api_key:
api_key = api_key if api_key is not None else self.api_key
model_name = model_name if model_name is not None else self.model_name
system_prompt = system_prompt if system_prompt is not None else self.system_prompt
max_reply_tokens = max_reply_tokens if max_reply_tokens is not None else self.max_reply_tokens
temperature = temperature if temperature is not None else self.temperature
top_p = top_p if top_p is not None else self.top_p
n = n if n is not None else self.n
stop = stop if stop is not None else self.stop
presence_penalty = presence_penalty if presence_penalty is not None else self.presence_penalty
frequency_penalty = frequency_penalty if frequency_penalty is not None else self.frequency_penalty
logit_bias = logit_bias if logit_bias is not None else self.logit_bias
moderate_content = moderate_content if moderate_content is not None else self.moderate_content
stream = stream if stream is not None else self.stream
streaming_callback = streaming_callback if streaming_callback is not None else self.streaming_callback
streaming_done_marker = (
streaming_done_marker if streaming_done_marker is not None else self.streaming_done_marker
)
api_base_url = api_base_url or self.api_base_url
openai_organization = openai_organization if openai_organization is not None else self.openai_organization

if not api_key:
raise ValueError("OpenAI API key is missing. Please provide an API key.")

stream = stream or self.stream
parameters = {
"model": model_name or self.model_name,
"max_reply_tokens": max_reply_tokens or self.max_reply_tokens,
"temperature": temperature or self.temperature,
"top_p": top_p or self.top_p,
"n": n or self.n,
"model": model_name,
"max_reply_tokens": max_reply_tokens,
"temperature": temperature,
"top_p": top_p,
"n": n,
"stream": stream,
"stop": stop or self.stop,
"presence_penalty": presence_penalty or self.presence_penalty,
"frequency_penalty": frequency_penalty or self.frequency_penalty,
"logit_bias": logit_bias or self.logit_bias,
"moderate_content": moderate_content or self.moderate_content,
"stop": stop,
"presence_penalty": presence_penalty,
"frequency_penalty": frequency_penalty,
"logit_bias": logit_bias,
"moderate_content": moderate_content,
}

headers = {"Authorization": f"Bearer {api_key or self.api_key}", "Content-Type": "application/json"}
if openai_organization or self.openai_organization:
headers["OpenAI-Organization"] = openai_organization or self.openai_organization

url = f"{api_base_url or self.api_base_url}/chat/completions"
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
if openai_organization:
headers["OpenAI-Organization"] = openai_organization
url = f"{api_base_url}/chat/completions"
Copy link
Contributor Author

@ZanSara ZanSara Aug 31, 2023

Choose a reason for hiding this comment

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

@vblagoje We're using the chat completion endpoint for ChatGPT: https://platform.openai.com/docs/api-reference/chat/create


replies = []
streaming_callback = streaming_callback or self.streaming_callback
for prompt in prompts:
payload = {
**parameters,
Expand Down
Loading