Apply LLM To SDXL Adapter
The bridge that turns LLM embeddings into SDXL conditioning
- llm_hidden_states
- llm_adapter
- conditioning
- info
Everything up to this node produces a weird intermediate thing (LLM hidden states) in a shape SDXL has never seen. ApplyLLMToSDXLAdapter is the translator. It takes the LLM_HIDDEN_STATES from LLMTextEncoder plus the LLM_ADAPTER from LLMAdapterLoader, pushes both through the trained adapter network, and outputs a standard CONDITIONING tensor you can plug straight into a KSampler. This is the node where the "adapter" in the pack's name does its job.
How the adapter actually works
This isn't a LoRA or a merge - it's a small trainable transformer that reshapes LLM embeddings into SDXL's expected layout. The pipeline in the source is worth knowing because it explains the defaults you'll see elsewhere in the pack:
- Project the LLM's hidden states (1152 dims for Gemma-3-1b) up to SDXL's 2048 sequence dimension.
- Wide attention blocks process the full token sequence.
- Compress the sequence from up to 512 tokens down to 308 using cross-attention with learnable query tokens - this is the trick that maps an LLM's long, variable output onto SDXL's fixed prompt-embedding budget.
- Narrow attention blocks refine the compressed sequence.
- Pool it into a 1280-dim vector for SDXL's vector conditioning.
The node then returns two things as one: the compressed sequence becomes the conditioning tensor, and the pooled vector gets tucked into the metadata as pooled_output - which is exactly the {pooled_output: ...} dict shape SDXL's sampler expects from its CLIP encoders. That's the compatibility trick that makes a modern LLM drop into a 2023 model's pipeline without any changes downstream.
The two inputs and what to do with them
llm_hidden_states- straight fromLLMTextEncoder. Nothing to configure here.llm_adapter- fromLLMAdapterLoader. The type you picked there (gemmavst5gemma) must match the model that produced the hidden states, or the shapes won't line up and you'll get a linear-projection mismatch at step one.
Outputs: conditioning (CONDITIONING, the only one you'll use) and info (STRING with the resulting shape, handy for debugging a mismatched chain).
Wiring it in
The minimal working chain the README sketches:
LLMModelLoader → LLMTextEncoder → ApplyLLMToSDXLAdapter → KSampler
↑
LLMAdapterLoader ─┘
Two honest caveats, both from the LLM-encoder reality the community has hammered out. First, prompt weighting ((tag:1.4)) is dead on this path - the adapter never learned CLIP's emphasis syntax. Second, if you want a negative prompt for CFG, you have to run this whole chain twice (once per text) and feed the negative conditioning to the sampler - and reports on how much a negative actually helps on an LLM-encoded path are mixed. Start with the positive chain alone.
Install
ApplyLLMToSDXLAdapter ships in the ComfyUI LLM SDXL Adapter pack. ComfyUI Manager → search "ComfyUI LLM SDXL Adapter", or git clone https://github.com/NeuroSenko/ComfyUI_LLM_SDXL_Adapter.git into ComfyUI/custom_nodes/, then restart. Its real prerequisites are the model files: the trained RouWei-Gemma adapter (from the pack's CivitAI/HuggingFace links) in ComfyUI/models/llm_adapters/ and gemma-3-1b-it in ComfyUI/models/llm/.
Troubleshooting
- Shape mismatch at apply time: adapter
typeand the model that made the hidden states don't agree. Re-pick the adapter type. - Conditioning looks huge in the preview: the compressed sequence is 308 tokens, not SDXL's familiar CLIP shape - that's normal.
- Completely blank/washed output: check you're feeding the sampler this conditioning, not a stock
CLIPTextEncodeoutput mixed in by muscle memory.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| llm_hidden_states | LLM_HIDDEN_STATES | — | |
| llm_adapter | LLM_ADAPTER | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| conditioning | CONDITIONING | — |
| info | STRING | — |