Lumina Gemma Text Encode
Your prompt's secret handshake with a 2B LLM
- gemma_model
- latent
- lumina_embeds
If you've built an SDXL or Flux workflow, this is your CLIP Text Encode - the node that turns words into something the diffusion model can read. But "Lumina Gemma Text Encode" is the point where that mental model breaks: there is no CLIP here, and no T5. The encoder is Google's Gemma-2b, a real 2B-parameter LLM, and this node is the handshake between it and Lumina's 2B flow-matching backbone. Same shape you're used to, completely different plumbing underneath.
It's the mandatory middle step of any Lumina-Next workflow. Chain it as DownloadAndLoadGemmaModel → LuminaGemmaTextEncode → LuminaT2ISampler and you're 80% of the way to a working T2I graph.
How it works
The node runs your prompt (and your negative) through Gemma's transformer and grabs hidden_states[-2] - the second-to-last hidden layer - as the text embedding. That's a deliberate choice: Lumina-Next was trained on that layer, not on Gemma's final logits. It tokenizes with pad_to_multiple_of=8 and truncates at 256 tokens, which is plenty for a paragraph-length prompt.
Two details matter more than they look. First, it reads the batch size off the latent you feed in, then duplicates your prompt across that batch (and your n_prompt too). Second, the "negative prompt" isn't used the SD way - flow-matching models do their classifier-free guidance inside the sampler, so this node just encodes both strings and lets LuminaT2ISampler handle the CFG arithmetic. A flow-matching model's negative does far less than SD's, so don't be surprised when it barely moves the image.
The inputs that matter
gemma_model- theGEMMAODELout ofDownloadAndLoadGemmaModel. Yes, it's the model, not a path.latent- used only for batch size and resolution. Feed it the same empty latent you'll sample from.prompt/n_prompt- plain multiline strings.n_promptcan stay empty if you're experimenting.keep_model_loaded- defaults to false, meaning the node offloads Gemma to RAM the moment it's done. If you're doing several encodes in a row (say, for the area nodes), set this true or every encode pays a reload tax.
Output: one lumina_embeds, wired straight into LuminaT2ISampler's lumina_embeds input. Nothing else to decode - this isn't conditioning, it's a bag of hidden states.
Installing
Grab the pack via ComfyUI Manager (search "ComfyUI-LuminaWrapper") or:
cd ComfyUI/custom_nodes
git clone https://github.com/kijai/ComfyUI-LuminaWrapper
Then install deps and restart:
pip install -r requirements.txt # torchdiffeq, accelerate, tqdm, transformers>=4.38.0
Where people get burned
The Gemma model is gated on HuggingFace - you need to accept Google's terms once (instant), or the download fails. See the DownloadAndLoadGemmaModel article for the full story. Also: bf16 needs an Ampere-or-newer GPU, and without flash_attn this encode runs on torch SDP attention, which is at least twice as slow. On Windows, grab a prebuilt flash-attention wheel from the bdashore3 releases page rather than trying to compile it.
One more thing worth knowing: because keep_model_loaded defaults to false, every encode unloads and reloads Gemma. If your first run feels oddly slow, that's usually it - set the toggle and rerun.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| gemma_model | GEMMAODEL | — | |
| latent | LATENT | — | |
| prompt | STRING | — | |
| n_prompt | STRING | — | |
| keep_model_loadedopt | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| lumina_embeds | LUMINATEMBED | — |