Update embeddings server: return HTTP 400 for invalid embedding requests - #29060
Conversation
|
Hi @SamMalayek, thanks for your contribution! Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:
Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below. |
This is a false positive (it says Contributor in my post headings -- example merge: #16541). And as with all my PRs after I became familiar with llama.cpp & OSS, this is a clean and optimal change that is simply needed. |
|
Could a maintainer rerun the failed + cancelled CI jobs, please? We've got 503, cancelled, and similar failures that appear transient. Furthermore, the 3x self-hosted jobs have been queued for hours (update: are now auto-cancelled). Is there an issue with runner availability? Thanks. |
|
CI restarted for failed jobs |
|
@ServeurpersoCom : Server / ubuntu still appears to be the original Hugging Face 503 failure and was never rerun. The 3x Intel self-hosted jobs also timed out after 24h without getting runners. Could you rerun Server / ubuntu? Also, is anything needed for the unavailable Intel runners? |
|
Hi, returning 400 is legit per the OpenAI spec, since the SDK retries every 5xx and a malformed request ends up sent three times. This needs a rebase on master, and at first read I think the fix can be much more targeted: common_json_error is the only reason for the try block, so could you catch it once in ex_wrapper as invalid_request_error? That keeps the C++ side to that catch plus the two invalid_argument changes, and covers every route that parses the body. The test can also be lighter, a single parametrize over the invalid bodies asserting the 400, like the rest of test_embedding.py. |
Thanks for the guidance. I’ve implemented the ex_wrapper approach and simplified the tests (removing edge case testing, but following guidance and convention). One implication of this ex_wrapper change is that an uncaught common_json_error arising during internal/response-side JSON processing could theoretically & incorrectly be classified as a 400 rather than a 500 (unlikely if high caution is utilized by all devs). I’m proceeding with this approach as suggested. ex_wrapper can’t reliably distinguish client vs internal common_json_error without broader changes, so again, I’m following the centralized 400 handling you suggested. My original code had the same issue, but much narrower scope and blast radius (also better position to iterate towards a narrow 100% accurate solution, but you could argue that the best solution is to broaden the scope of ex_wrapper... might come back to this later). TLDR: My original solution was more surgical and better in the short term but this new one is more broad (since ex_wrapper is used by so many endpoints) and better positioned for the long term. Both solutions are better than leaving the code as it was. |
72b074a to
b139644
Compare
|
Closing and reopening to retrigger the CI, this run still uses the cmake-pkg workflow from before #29299 which lands on runners that only accept container jobs, no action needed on your side. Closing and reopening makes the CI redo the clone rebased on current master on its side, so as long as there is no conflict there is no need to rebase. |
@ServeurpersoCom All 17 CI checks are passing now. Could you take another look at the updated PR? |
ServeurpersoCom
left a comment
There was a problem hiding this comment.
LGTM, thanks for reworking it around ex_wrapper: malformed bodies now get a proper 400 instead of a 500, so OpenAI-compatible clients stop retrying them.
Upstream ggml-org#29060 maps common_json_error to HTTP 400. Requests prepared by the engine reported them as preparation_failed (500), which failed the new test_embedding_invalid_request case for a non-string encoding_format. Malformed bodies now return 400 as upstream: update test_sleep accordingly.
Upstream ggml-org#29060 maps common_json_error to HTTP 400. Requests prepared by the engine reported them as preparation_failed (500), which failed the new test_embedding_invalid_request case for a non-string encoding_format. Malformed bodies now return 400 as upstream: update test_sleep accordingly.
Overview
invalid_request_errorinstead of HTTP 500 for malformed embedding requests that fail during request parsing or validation.std::invalid_argumentinstead ofstd::runtime_errorfor clearly client-caused tokenizer failures.common_json_errorduring embedding request preparation./v1/embeddingsrequests and/embeddingscases.Requirements