Repository navigation
Map top_p to topP in the Bedrock Titan and AI21 completions adapters - #25795
Conversation
Install mlflow from this PR
Install mlflow from this PR# mlflow
pip install git+https://github.com/mlflow/mlflow.git@refs/pull/25795/merge
# mlflow-skinny
pip install git+https://github.com/mlflow/mlflow.git@refs/pull/25795/merge#subdirectory=libs/skinnyFor Databricks, use the following command: %sh curl -LsSf https://raw.githubusercontent.com/mlflow/mlflow/HEAD/dev/install-skinny.sh | sh -s pull/25795/mergePR author's recent activityIn the last 14 days, @Yash-Chindam opened 15 PRs across 4 repos:
|
Both adapters built their request body with `rename_payload_keys`, which passes through any key absent from its mapping unchanged. Neither mapping covered `top_p`, so a caller-supplied value was forwarded to Bedrock as the literal key `top_p`. Titan's `textGenerationConfig` and Jurassic's request body both name the field `topP`, so Bedrock did not recognise it and silently ignored it: the request succeeded and returned a normal completion, just without the nucleus sampling the caller asked for. `top_k` is deliberately left unmapped. Titan's `textGenerationConfig` accepts only maxTokenCount, stopSequences, temperature and topP, and Jurassic's `topKReturn` controls how many alternative tokens are reported rather than top-k sampling. Renaming `top_k` to `topK` would swap one key Bedrock ignores for another while making the code look like it handles the parameter. The Converse path in this same file omits topK from `inferenceConfig` for the same reason. Both TODO comments are replaced with notes recording this. Relates to mlflow#25571. Deliberately not "Closes": the `top_k` half of that issue is a question for the maintainers, so the issue should not auto-close on merge. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yash-Chindam <[email protected]>
797bea3 to
e559cdf
Compare
|
Documentation preview for 2d1bda8 is available at: More info
|
There was a problem hiding this comment.
@Yash-Chindam Thanks for spliting the PR and the careful analysis. The top_p mappings and regression tests look correct, and I agree that mapping top_k to either topK or topKReturn would be incorrect.
One boundary case should be handled before landing: MLflow accepts top_p=0, but Titan requires topP to be strictly greater than zero. With this change, that request reaches Bedrock and can surface as an uncaught provider validation error. Could you add Titan-specific validation returning 422 and a test for top_p=0?
Titan's `textGenerationConfig` requires `topP` to be strictly greater than zero, but MLflow's request schema accepts `top_p=0`. Now that `top_p` is actually forwarded as `topP`, such a request reaches Bedrock and surfaces as an uncaught provider validation error, so reject it up front with a 422 the way the adapter already does for `n != 1`. Co-Authored-By: Claude Opus 5 <[email protected]> Signed-off-by: Yash-Chindam <[email protected]>
tanghaoji
left a comment
There was a problem hiding this comment.
LGTM! Thanks for addressing the comment
Related Issues/PRs
Relates to #25571
What changes are proposed in this pull request?
Both
AWSTitanAdapter.completions_to_modelandAI21Adapter.completions_to_modelbuild their Bedrock request body withrename_payload_keys, which passes through any key absent from its mapping unchanged. Neither mapping coveredtop_p, so a caller-supplied value reached Bedrock under the literal keytop_p. Titan'stextGenerationConfigand Jurassic's request body both name that fieldtopP, so Bedrock did not recognise the key and silently ignored it — the request succeeded and returned a normal completion, just without the nucleus sampling the caller asked for.This adds
"top_p": "topP"to both mappings. The outbound body, produced by running the adapters:textGenerationConfig){'maxTokenCount': 1000, 'top_p': 0.9}{'maxTokenCount': 1000, 'topP': 0.9}{'maxTokens': 1000, 'top_p': 0.9}{'maxTokens': 1000, 'topP': 0.9}On
top_k— flagging a deviation from the triage note so it is cheap to redirectThe triage note on #25571 suggested mapping
top_k->topKalongsidetop_p. I did not, because I could not find atopKfield on either model family to map onto:textGenerationConfigaccepts onlymaxTokenCount,stopSequences,temperatureandtopP.topKReturn, which controls how many alternative tokens are reported, not top-k sampling. Mappingtop_konto it would change the response payload rather than the sampling behaviour.inferenceConfigfromtemperature/topP/maxTokens/stopSequencesand omitstopK(bedrock.py:408-421), and no Bedrock code path in the repo mapstopKanywhere.GeminiAdapterdoes maptop_k->topK, because Gemini genuinely supports it.Renaming
top_k->topKhere would swap one key Bedrock ignores for another while making the code look like it handles the parameter — the same silent-drop failure mode the issue is about. So instead of deleting the two# TODO handle top_p, top_k, etc.comments as though they were fully addressed, I replaced them with notes recording whytop_kand the penalty parameters stay unmapped.That leaves a decision I would rather you make than guess at.
top_kis currently accepted and ignored; the alternative is to reject it with a 422, which this file already does forn != 1on Titan (andAnthropicAdapterdoes forn, and fortemperature+top_ptogether). I left that out because it turns a currently-succeeding request into a hard error and CONTRIBUTING.md asks for backwards-compatible changes — but it is a small follow-up in either direction, and I am happy to add it here if you prefer. I have kept this as "Relates to" rather than "Closes" so #25571 does not auto-close while that is open.How is this PR tested?
Two new cases in
bedrock_model_provider_fixtures(Titan and Jurassic, each sendingtop_p). These run through the existingtest_bedrock_request_response, which drives the realAmazonBedrockProvider.completionsand asserts the exact body handed to Bedrock viamock_request.assert_called_once_with(model_request)— so they pin the outbound key name, not just the adapter's return value. Each fixture runs against all fourbedrock_aws_configs.I also confirmed the new tests actually catch the bug, by reverting only the two mapping entries and re-running. They fail with exactly the right message, and the six pre-existing cases still pass:
A note on my local verification, in the interest of transparency
I could not run the suite through pytest locally. Every test in
tests/gateway/providers/test_bedrock.pyerrors at setup withRuntimeError: Failed to start server, including tests this PR does not touch. The cause is environmental and specific to my machine:mlflowis not registered as an installed distribution in my interpreter, soIS_TRACING_SDK_ONLYis true, which makes the session fixture attests/conftest.py:815autouse; it shells out touv run ... mlflow server, and myuvbuild cannot parseexclude-newer = "P7D"inpyproject.toml.So I verified by importing the real fixture table and reproducing the exact assertions from
test_bedrock_request_responsewithout the conftest in the way. All 8 applicable fixtures x 4 AWS configs pass (32/32; Cohere skipped, as it is in the suite):CI is the real check for the pytest run.
ruff checkandruff format --checkpass on both changed files. Commits are DCO signed off.Does this PR require documentation update?
Does this PR require updating the MLflow Skills repository?
Release Notes
Is this a user-facing change?
Fixed
top_pbeing silently ignored for Amazon Titan and AI21 Jurassic models on the AI Gateway'sllm/v1/completionsendpoint. The parameter was forwarded to Bedrock under its OpenAI-styletop_pname instead of thetopPname those models expect, so requests succeeded while ignoring the caller's nucleus-sampling setting.What component(s), interfaces, languages, and integrations does this PR affect?
Components
area/gateway: MLflow AI Gateway client APIs, server, and third-party integrationsHow should the PR be classified in the release notes? Choose one:
rn/bug-fix- A user-facing bug fix worth mentioning in the release notesIs this PR a critical bugfix or security fix that should go into the next patch release?
Disclosure: I used an AI assistant (Claude) to help trace the call paths, implement the fix, and draft this description. Every file/line reference and every result above was produced by running the code, and I reviewed the change before submitting.
🤖 Generated with Claude Code