feat: add embedded adapters (granite switch) to openai backend#881
Conversation
Enable calling intrinsics on Granite Switch models via the OpenAI backend. Granite Switch models embed adapter weights directly in the checkpoint and activate them via chat template control tokens, so no PEFT loading is needed. - Add EmbeddedIntrinsicAdapter class that carries only I/O config (no weights) with factory methods to load from a model directory or HuggingFace Hub - Add register_granite_switch_model() and add_embedded_adapter() to OpenAIBackend - Add _generate_from_intrinsic() that reuses IntrinsicsRewriter/ResultProcessor and injects intrinsic_name into chat_template_kwargs for the switch model - Ensure serialized messages always include 'role' (latent issue in rewriter instruction messages, newly exposed by OpenAI API serialization path) - Add unit tests for adapter loading, registration, and rewriting Signed-off-by: lastrasl <lastrasl@us.ibm.com>
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
|
The PR description has been updated. Please fill out the template for your PR to be reviewed. |
|
I'm still in the process of testing some of these changes from an e2e perspective. I also still need to add documentation for how to use embedded models along with examples. These changes do seem to work though and allow utilizing intrinsics with an embedded adapter / granite switch model. |
|
Bug: The Fix: mirror the if ModelOption.TEMPERATURE in model_options:
api_params["temperature"] = model_options[ModelOption.TEMPERATURE]Verified: with this fix, 5 back-to-back pipeline runs (guardian → rewrite → answerability → QC → base model, no sleep between calls) produce bit-for-bit identical outputs including long-form base model answers. Without the fix, outputs vary run-to-run despite |
|
@lastras Your comment states that all model options get dropped but that the fix is to add (another) special case for It sounds from your comment like there's an underlying bug here that should be fixed. Can you clarify? |
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
c0b163c to
3227a5b
Compare
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
|
I fixed a few random issues and also the issues we talked about (call_intrinsic and seed/temperature setting). I'm working on adding some documentation and minor examples. The functional parts of the code should be stable now. I have additional things that I'd like to clean up, but I will delay them until after we make sure everything is working as intended and post-release, so I don't impact any functionality. |
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
|
Updated the PR description. Fixed a few additional errors / bugs. Added documentation and examples. We should be good to start reviewing. I need to run one more round of tests with the latest from the granite-switch team. I have plans to open a few additional issues to clean things up after this PR is merged. Additional changes that should be made before the official release:
|
Docs should not be a blocker for merging this btw, just something we should have in advance of the release. |
82c11c2 to
fb957fe
Compare
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
fb957fe to
caec848
Compare
Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS
Assisted-by: CLAUDE:OPUS Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
…r from where the adapters are loaded from Assisted-by: CLAUDE:OPUS Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com>
planetf1
left a comment
There was a problem hiding this comment.
LGTM - I know there's some placeholders here such as for the repo -- but I wonder if the doc update should be deferred until later, since this will get published on our next minor release (Wed) and would have a dead line (openai.md and glossary.md) ?
|
We can defer doc updates. There was concern about the model_identifier being left in with the placeholder value. I'm open to merging with both the docs and placeholder model (Grizlee-Ber/...) in the code, but was hoping we could fix those before merging. |
I agree that waiting for the fixes was my preference, but if leaving this unmerged is causing code drift we may want to merge now then fix those before the next release |
|
We have a name already. We can talk in slack. I believe the name will be
stable, and all will be ok.
…On Mon, Apr 27, 2026 at 2:38 PM Alex Bozarth ***@***.***> wrote:
*ajbozarth* left a comment (generative-computing/mellea#881)
<#881 (comment)>
I'm open to merging with both the docs and placeholder model
(Grizlee-Ber/...) in the code, but was hoping we could fix those before
merging.
I agree that waiting for the fixes was my preference, but if leaving this
unmerged is causing code drift we may want to merge now then fix those
before the next release
—
Reply to this email directly, view it on GitHub
<#881 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACYZ5XAQFFK5A4GPLFDAOVL4X6SLLAVCNFSM6AAAAACX5ODHBOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DGMRZGU2DONJQGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
@planetf1 @ajbozarth @avinash2692, can I please get a review from one (or more) of y'all? We are going to merge as is (assuming you don't spot any issues with the code). Then, pre-release, we will update the model id and doc links. |
ajbozarth
left a comment
There was a problem hiding this comment.
Two non-blocking nits below, otherwise LGTM.
| Returns: | ||
| list[str]: Names of the registered intrinsics. | ||
| """ | ||
| import os |
There was a problem hiding this comment.
import os is never used inside this function (os is already imported at module level on line 7). Ruff will flag this as F401 — safe to remove.
There was a problem hiding this comment.
Will address in a follow up PR. Thank you.
| if len(model_options.items()) > 0: | ||
| MelleaLogger.get_logger().info( | ||
| "passing in model options when generating with an intrinsic; only temperature and seed are kept from model options" |
There was a problem hiding this comment.
This fires even when the caller passes only recognized options like {ModelOption.TEMPERATURE: 0.0}. Consider narrowing to unrecognized options only so it's not a false alarm:\npython\nrecognized = {ModelOption.TEMPERATURE, ModelOption.SEED}\nif any(k not in recognized for k in model_options):\n MelleaLogger.get_logger().info(...)\n
There was a problem hiding this comment.
Will address in a follow up PR. Thank you.
- Title and prose shift to "adapter" as primary term; "intrinsic" noted as legacy vocabulary with a rename-scope decision in Part I §5 Q6. - Reality B clarified: weights ship in the same HF repo as the base model (not "baked in"); both LoRA and aLoRA supported via the technology field on each embedded adapter. - Reality C reframed: OpenAI-compatible support is already kept for embedded (PR generative-computing#881); the gap is non-embedded server-mediated, which may or may not re-land in 0.6.0. - Add §10.1 "Why adapters need bespoke observability" with four concrete failure modes, two already seen in production. - Goals elevate customer-built adapters as a first-class target. - Tests section adds an optional per-adapter qualitative effectiveness suite (opt-in via @pytest.mark.qualitative). Assisted-by: Claude Code Signed-off-by: Nigel Jones <jonesn@uk.ibm.com>
…ative-computing#881) * feat: add Granite Switch embedded intrinsic support to OpenAI backend Enable calling intrinsics on Granite Switch models via the OpenAI backend. Granite Switch models embed adapter weights directly in the checkpoint and activate them via chat template control tokens, so no PEFT loading is needed. - Add EmbeddedIntrinsicAdapter class that carries only I/O config (no weights) with factory methods to load from a model directory or HuggingFace Hub - Add register_granite_switch_model() and add_embedded_adapter() to OpenAIBackend - Add _generate_from_intrinsic() that reuses IntrinsicsRewriter/ResultProcessor and injects intrinsic_name into chat_template_kwargs for the switch model - Ensure serialized messages always include 'role' (latent issue in rewriter instruction messages, newly exposed by OpenAI API serialization path) - Add unit tests for adapter loading, registration, and rewriting Signed-off-by: lastrasl <lastrasl@us.ibm.com> * feat: refactor embedded adapters Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: issues with qualitative openai intrinsics tests Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: minor refactoring Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> * fix: call_intrinsic function to work with other adapter types Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: more improvements to adapters and call_intrinsic Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: explicitly extract seed and temp from model options for intrinsics Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: add tests specifically for openai backend and call_intrinsic flow Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: rename openai init param to load_embedded_adapters Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> * fix: pre-commit issues Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * feat: add model id for granite switch Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> * feat: add examples and documentation for granite-switch in mellea Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: update pyproject dependencies for openai to support granite-switch Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: pre-commit issues Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: pr issues Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: changes to granite-switch structure Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: allow call_intrinsic to use any type of adapter Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> * fix: test_openai_intrinsics expected results Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> * fix: add tests cases and fix missed function signature changes Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Assisted-by: CLAUDE:OPUS * fix: auto-loading embedded adapters for local model dirs Assisted-by: CLAUDE:OPUS Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> * fix: allow specifying an adapter_source so that model names can differ from where the adapters are loaded from Assisted-by: CLAUDE:OPUS Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> --------- Signed-off-by: lastrasl <lastrasl@us.ibm.com> Signed-off-by: Jake LoRocco <jake.lorocco@ibm.com> Co-authored-by: lastrasl@us.ibm.com;4A8621897;Luis Lastras <lastrasl@p6-r05-n3.bluevela.rmf.ibm.com>
Misc PR
Type of PR
Description
Adds support for granite switch models for OpenAIBackends.
Changes:
load_embedded_adapters=Trueat init.IBM_GRANITE_SWITCH_4_1_8Bthat points to the temp repo for now.Please see most recent comment below for additional context: #881 (comment)
Testing
Attribution