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 tolerance for empty choices #4311

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ async def create_stream(
json_output: Optional[bool] = None,
extra_create_args: Mapping[str, Any] = {},
cancellation_token: Optional[CancellationToken] = None,
max_consecutive_empty_chunk_tolerance: int = 0,
) -> AsyncGenerator[Union[str, CreateResult], None]:
"""
Creates an AsyncGenerator that will yield a stream of chat completions based on the provided messages and tools.
Expand All @@ -566,6 +567,7 @@ async def create_stream(
json_output (Optional[bool], optional): If True, the output will be in JSON format. Defaults to None.
extra_create_args (Mapping[str, Any], optional): Additional arguments for the creation process. Default to `{}`.
cancellation_token (Optional[CancellationToken], optional): A token to cancel the operation. Defaults to None.
max_consecutive_empty_chunk_tolerance (int): The maximum number of consecutive empty chunks to tolerate before raising a ValueError. This seems to only be needed to set when using `AzureOpenAIChatCompletionClient`. Defaults to 0.

Yields:
AsyncGenerator[Union[str, CreateResult], None]: A generator yielding the completion results as they are produced.
Expand Down Expand Up @@ -636,13 +638,29 @@ async def create_stream(
full_tool_calls: Dict[int, FunctionCall] = {}
completion_tokens = 0
logprobs: Optional[List[ChatCompletionTokenLogprob]] = None
empty_chunk_count = 0

while True:
try:
chunk_future = asyncio.ensure_future(anext(stream))
if cancellation_token is not None:
cancellation_token.link_future(chunk_future)
chunk = await chunk_future

# This is to address a bug in AzureOpenAIChatCompletionClient. OpenAIChatCompletionClient works fine.
# https://github.com/microsoft/autogen/issues/4213
if len(chunk.choices) == 0:
Copy link
Member

Choose a reason for hiding this comment

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

Do the chunks with no choices have other data set on other fields of the delta?

Copy link
Contributor Author

@MohMaz MohMaz Nov 23, 2024

Choose a reason for hiding this comment

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

I can't see anything int the chunk.__dict__. In the consecutive chunks, the choices gets populated properly and has all the expected fields.

{'id': '', 'choices': [], 'created': 0, 'model': '', 'object': '', 'service_tier': None, 'system_fingerprint': None, 'usage': None}

This has been happening only for the first 1-2 chunks to me, not sure if it's reproducible to all models. I've tried gpt-4o

empty_chunk_count += 1
if max_consecutive_empty_chunk_tolerance == 0:
raise ValueError(
"Consecutive empty chunks found. Change max_empty_consecutive_chunk_tolerance to increase empty chunk tolerance"
)
elif empty_chunk_count >= max_consecutive_empty_chunk_tolerance:
raise ValueError("Exceeded the threshold of receiving consecutive empty chunks")
continue
else:
empty_chunk_count = 0

# to process usage chunk in streaming situations
# add stream_options={"include_usage": True} in the initialization of OpenAIChatCompletionClient(...)
# However the different api's
Expand Down
Loading