Repository navigation
fix(sagemaker): support multi-byte UTF-8 split across streaming event frames - #46887
aakash1552005 wants to merge 2 commits into
Conversation
… frames (BerriAI#46876) Use codecs incremental UTF-8 decoder in AWSEventStreamDecoder so partial multi-byte UTF-8 sequences are buffered across PayloadPart frames instead of raising UnicodeDecodeError or dropping events. Also ensure non-200 endpoint errors propagate in async stream to match sync behavior. Signed-off-by: AAKASH S S <aakash1552005@gmail.com>
|
Automatic reviews are disabled for this repository. |
Merging this PR will not alter performance
|
BrickerP
left a comment
There was a problem hiding this comment.
Direction looks right (incremental UTF-8 decoder + flush on exhaust, and dropping the broad except Exception so non-200 SageMaker events can surface).
CI is red though: Ruff PT012 on tests/unit/llms/sagemaker/test_sagemaker_common_utils.py (~320) — pytest.raises() is wrapping a multi-statement async def + async for block. Tighten that test (e.g. pull the async iteration into a single statement / helper) so lint can go green before merge.
Also note _parse_message_from_event(..., final=) is added but call sites still use the default final=False; the flush path relies on the separate utf8_decoder.decode(b"", final=True) — fine if intentional, just worth a one-line comment so it does not look unfinished.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Signed-off-by: AAKASH S S <aakash1552005@gmail.com>
|
Thanks for the review @BrickerP!
Updated in commit c5d6b25. |
|
Thanks @aakash1552005, #47495 now raises async ModelStreamErrors the way this PR did, and it is merged. Closing this as covered there |
TLDR
Problem this solves:
How it solves it:
AWSEventStreamDecoderinstances.except Exceptioninaiter_bytesso non-200 errors propagate matching sync.User Flow
Before: A caller streaming from a SageMaker endpoint receives partial responses or unhandled decode errors when tokens contain accented or multi-byte characters split across frames.
litellm.completion(model="sagemaker/<endpoint>", messages=[{"role": "user", "content": "Reply with café"}], stream=True).0xc3,0xa9) divided across consecutivePayloadPartevent frames.UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 29: unexpected end of data, or the async path drops both chunks and silently loses the token.After: Both sync and async streams cleanly reconstruct split multi-byte UTF-8 sequences and report endpoint errors faithfully.
litellm.completion(model="sagemaker/<endpoint>", messages=[{"role": "user", "content": "Reply with café"}], stream=True).PayloadPartevent frames."café"without error.ValueErrorwith the response details.Relevant issues
Fixes #46876
Pre-Submission checklist
uv run pytest tests/unit/<your_test_file>.py -v.Screenshots / Proof of Fix
Before (2dc6aaf)
PayloadPartevents:After (4b720b5)